Initial commit.
This commit is contained in:
146
README.md
Normal file
146
README.md
Normal file
@@ -0,0 +1,146 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user