# Barometric pressure test ## Goals 1. Read barometric pressure from two sensors. One connected to the MCU with SPI and the other connected with I2C bus. 2. The reading must be done in real time and data should be checked for validity. 3. The output should be sent to a serial port. 4. In case of reading error the LED should be turned on for 1 second. Each sensor has its own LED. ## Hardware - MCU - STM32F042K6T6 (Nucleo-32, board MB1180) - 32 KB flash, 6 KB RAM - Barometric pressure sensor - 2x GY-63 (MS5611) ## Wiring Pin assignments follow ST UM1956 Table 10 and the MB1180 C.2 schematic, and match the STM32duino defaults for this variant, so `Wire.begin()` and `SPI.begin()` need no explicit pin overrides. ![Wiring diagram](docs/wiring.png) Vector source: [`docs/wiring.svg`](docs/wiring.svg). Pins there are grouped by function, not by physical header order. The same wiring drawn physically, with the real header order from UM1956 Table 10, so it is clear which hole each jumper goes into: ![Physical wiring diagram](docs/wiring-physical.png) Vector source: [`docs/wiring-physical.svg`](docs/wiring-physical.svg). Note that SPI is split across both connectors: MOSI, MISO and CS are on CN3, while SCK is CN4 pin 15. ### Baro0 - I2C (GY-63 <=> STM32F042) | GY-63 | Nucleo | STM32 | Note | |-------|--------|-------|------| | VCC | 3V3 | - | | | GND | GND | - | | | PS | 3.3V | - | high selects I2C | | SDA | A4 | PB7 | `PIN_WIRE_SDA`, reaches the A4 pad through SB18 | | SCL | A5 | PB6 | `PIN_WIRE_SCL`, reaches the A5 pad through SB16 | | CSB | GND | - | sets address `0x77`; tie to VCC for `0x76` | The MS5611 address is `1110 11Cx`, where C is the **complement** of CSB (datasheet p.12). `CSB` must not be left floating. If you strap it high, change `BARO_I2C_ADDRESS` in [`include/config.h`](include/config.h). ### Baro1 - SPI (GY-63 <=> STM32F042) | GY-63 | Nucleo | STM32 | Note | |-------|--------|-------|------| | VCC | 3V3 | - | | | GND | GND | - | | | PS | GND | - | low selects SPI | | SCLK | D13 | PB3 | SPI1_SCK | | SDI | D11 | PB5 | SPI1_MOSI | | SDO | D12 | PB4 | SPI1_MISO | | CSB | D10 | PA11 | chip select, `BARO_SPI_CS_PIN` | SPI1 has to stay on this pin group. The alternative group (PA5/PA6/PA7) is unusable while I2C is active: with the factory-default solder bridges SB16 and SB18 closed, PA6 shares a net with PB6 (SCL) and PA5 shares a net with PB7 (SDA). ### Error LEDs Two external LEDs, one per sensor, each in series with roughly 510 R to GND. | Signal | Nucleo | STM32 | |--------|--------|-------| | I2C sensor error | D3 | PB0 | | SPI sensor error | D6 | PB1 | Both pins are set in [`include/config.h`](include/config.h). ## Build and run ```sh pio run # build pio run -t upload # flash over ST-LINK pio device monitor # 115200 baud, ST-LINK Virtual COM Port ``` `Serial` is USART2 on PA2/PA15, wired to the ST-LINK VCP, so no USB-serial adapter is needed. The image is close to the flash ceiling (about 89% of 32 KB). `-flto` and `-fsingle-precision-constant` in [`platformio.ini`](platformio.ini) are required, not cosmetic: both MS5611 drivers write their compensation maths with unsuffixed double literals, which otherwise links roughly 5 KB of double soft-float helpers and overflows flash. ## Output CSV at 10 Hz on the serial port, with a header line printed once at startup: ``` ms,i2c_status,i2c_p_mbar,i2c_t_c,spi_status,spi_p_mbar,spi_t_c 1043,OK,1013.24,24.31,OK,1013.19,24.44 1143,OK,1013.25,24.31,ERR_READ,1013.19,24.44 ``` Pressure is in mbar, temperature in degrees C, both to two decimals. The status column is authoritative: when it is not `OK`, the two values next to it are the last ones successfully computed, not fresh readings. | Status | Meaning | |--------|---------| | `INIT` | not initialised yet | | `OK` | reading passed every check | | `ERR_INIT` | reset / PROM handshake did not complete | | `ERR_CRC` | factory calibration failed CRC-4, or is all-zero / all-ones | | `ERR_READ` | driver reported a bus or ADC failure | | `ERR_RANGE` | value outside the MS5611 operating envelope | | `ERR_STALE` | sensor still answers but stopped producing new samples | Sensors are polled continuously, as fast as the ADC conversions allow (roughly 90 Hz per sensor at OSR 1024); the serial report is throttled to 10 Hz. ## Validation Neither driver library detects every failure on its own, so the checks live in [`BaroChannel`](src/baro_channel.cpp): - **PROM CRC-4** at init, per datasheet p.13 / AN520. Neither library verifies it. - **All-zero / all-ones PROM screening**, because an absent part reads back as one of those, `0xFFFF` is accepted by both libraries' `reset()`, and an all-zero PROM satisfies the CRC. - **Driver return code** on every read. - **Range check** against 10..1200 mbar and -40..+85 C. This is the one that catches the failure the I2C driver misses entirely: an ADC read taken before the conversion completes returns 0 (datasheet p.11), and `MS5611::read()` still reports `MS5611_READ_OK` for it. - **Stale detection** - bit-identical pressure *and* temperature for 32 consecutive polls means the part stopped converting while still acknowledging. Any failure lights that sensor's LED for 1 second (non-blocking, extended if further errors follow). After 10 consecutive failures the channel is taken back through the full reset and PROM handshake, so a sensor that was unplugged and reconnected recovers on its own. The CRC-4 implementation was verified differentially on the host against the independent NuttX reference over 200000 randomised PROM images. ## References - [Barometric Pressure Sensor MS5611](docs/datasheets/ENG_DS_MS5611-01BA03_B3.pdf) - [STM32F042K6T6 Nucleo](docs/datasheets/DS_stm32f042k6.pdf) - [STM32 Nucleo-32 boards (MB1180)](https://www.st.com/resource/en/user_manual/um1956-stm32-nucleo32-boards-mb1180-stmicroelectronics.pdf) - UM1956, LED and connector tables