147 lines
5.8 KiB
Markdown
147 lines
5.8 KiB
Markdown
# 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.
|
|
|
|

|
|
|
|
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:
|
|
|
|

|
|
|
|
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
|