/*
* SkyEar - STM32 dummy pressure sensor readout
* Wokwi simulation: potentiometer stands in for the differential
* pressure sensor. Prints to the built-in Serial Plotter.
*
* Note: deliberately does NOT call analogReadResolution() or
* pinMode(..., INPUT_ANALOG) - Wokwi's STM32 ADC simulation is a
* partial implementation and those calls can hang the sketch before
* it ever reaches Serial output.
*
* A synthetic 0.5 Hz infrasound wave is generated in software and
* combined with the potentiometer reading, so the plotted output
* looks like a live microbarometer trace instead of a flat line.
*
* OUTLIER GUARD: Wokwi's STM32 serial/float-printing simulation has
* known glitches that can corrupt an occasional sample into a huge
* garbage number (seen: 83968072.000) even though our own math can
* only ever produce a value in roughly +/-15 Pa. Rather than chase
* the simulator's internal bug, we clamp the value actually sent to
* Serial: anything outside a generous plausible range is replaced
* with the last known-good value, so one bad sample can't wreck the
* plotter's Y-axis scale.
*/
#include <math.h>
#define POT_PIN PA0
const float ADC_MAX = 1023.0; // stm32duino default ADC resolution (10-bit)
const float PRESSURE_RANGE_PA = 50.0; // simulated full-scale, +/- 50 Pa
const unsigned long SAMPLE_INTERVAL_MS = 10; // 100 Hz sampling
unsigned long lastSample = 0;
// Synthetic infrasound parameters
const float INFRASOUND_FREQ_HZ = 0.5; // 0.5 Hz = one cycle every 2 seconds
const float INFRASOUND_AMPLITUDE_PA = 5.0;
// Outlier guard
const float MAX_PLAUSIBLE_PA = 30.0; // true max is ~15 Pa, this leaves margin
float lastGoodValue = 0;
void setup() {
Serial.begin(115200);
// No unlabeled prints here - keeps the plotter's Y-axis clean.
}
void loop() {
unsigned long now = millis();
if (now - lastSample >= SAMPLE_INTERVAL_MS) {
lastSample = now;
// Potentiometer -> sensor baseline reading
int raw = analogRead(POT_PIN);
raw = constrain(raw, 0, (int)ADC_MAX); // guard against ADC glitches
float pressure_pa = ((raw / ADC_MAX) * 2.0 - 1.0) * PRESSURE_RANGE_PA;
// Synthetic infrasound wave, injected in software
float timeSeconds = now / 1000.0;
float infrasound_pa =
INFRASOUND_AMPLITUDE_PA * sin(2.0 * PI * INFRASOUND_FREQ_HZ * timeSeconds);
// Combine: pot sets the slow baseline/offset, the sine wave is the
// "detected" infrasonic signal riding on top of it
float combined_pa = pressure_pa * 0.2 + infrasound_pa;
// Reject implausible/corrupted samples before they ever reach Serial
if (isnan(combined_pa) || isinf(combined_pa) || fabs(combined_pa) > MAX_PLAUSIBLE_PA) {
combined_pa = lastGoodValue;
} else {
lastGoodValue = combined_pa;
}
Serial.print("Pressure_Pa:");
Serial.println(combined_pa, 3);
}
}
Loading
stm32-bluepill
stm32-bluepill