#include <Arduino.h>
#define HEADER 0xAA55
#define WINDOW_SIZE 5
typedef struct __attribute__((packed)) {
uint16_t header;
int16_t temp_centi; // Temperature x100
uint16_t hum_centi; // Humidity x100
uint16_t volt_milli; // Voltage x1000
uint8_t checksum;
} SensorFrame;
/* Simulated sensor values */
int16_t tempSamples[5] = {2840, 2910, 2760, 3030, 2980};
uint16_t humSamples[5] = {5230, 5480, 5110, 5670, 5520};
uint16_t voltSamples[5] = {3610, 3540, 3470, 3290, 3180};
/* Moving average buffers */
int16_t tempBuffer[WINDOW_SIZE] = {0};
uint16_t humBuffer[WINDOW_SIZE] = {0};
uint16_t voltBuffer[WINDOW_SIZE] = {0};
int bufferIndex = 0;
int sampleCount = 0;
uint8_t calculateChecksum(uint8_t *data, int length) {
uint8_t sum = 0;
for (int i = 0; i < length; i++) {
sum += data[i];
}
return sum;
}
int32_t movingAverageTemp(int16_t value) {
tempBuffer[bufferIndex] = value;
int count = sampleCount < WINDOW_SIZE ? sampleCount + 1 : WINDOW_SIZE;
int32_t sum = 0;
for (int i = 0; i < count; i++) {
sum += tempBuffer[i];
}
return sum / count;
}
uint32_t movingAverageUint(uint16_t *buffer, uint16_t value) {
buffer[bufferIndex] = value;
int count = sampleCount < WINDOW_SIZE ? sampleCount + 1 : WINDOW_SIZE;
uint32_t sum = 0;
for (int i = 0; i < count; i++) {
sum += buffer[i];
}
return sum / count;
}
void printCenti(int32_t value) {
Serial.print(value / 100);
Serial.print(".");
if ((value % 100) < 10) {
Serial.print("0");
}
Serial.print(value % 100);
}
void printMilli(uint32_t value) {
Serial.print(value / 1000);
Serial.print(".");
uint32_t frac = value % 1000;
if (frac < 100) Serial.print("0");
if (frac < 10) Serial.print("0");
Serial.print(frac);
}
void generateSTM32Frame(int index) {
int16_t rawTemp = tempSamples[index];
uint16_t rawHum = humSamples[index];
uint16_t rawVolt = voltSamples[index];
int32_t filteredTemp = movingAverageTemp(rawTemp);
uint32_t filteredHum = movingAverageUint(humBuffer, rawHum);
uint32_t filteredVolt = movingAverageUint(voltBuffer, rawVolt);
bufferIndex = (bufferIndex + 1) % WINDOW_SIZE;
if (sampleCount < WINDOW_SIZE) {
sampleCount++;
}
SensorFrame frame;
frame.header = HEADER;
frame.temp_centi = filteredTemp;
frame.hum_centi = filteredHum;
frame.volt_milli = filteredVolt;
frame.checksum = calculateChecksum((uint8_t *)&frame, sizeof(SensorFrame) - 1);
Serial.println();
Serial.println("[STM32] New sensor values generated");
Serial.print("[STM32] Raw Data: Temp=");
printCenti(rawTemp);
Serial.print(" C, Hum=");
printCenti(rawHum);
Serial.print(" %, Volt=");
printMilli(rawVolt);
Serial.println(" V");
Serial.print("[STM32] Filtered Data: Temp=");
printCenti(filteredTemp);
Serial.print(" C, Hum=");
printCenti(filteredHum);
Serial.print(" %, Volt=");
printMilli(filteredVolt);
Serial.println(" V");
Serial.print("[STM32] FRAME_TO_COPY=");
Serial.print(frame.header, HEX);
Serial.print(",");
Serial.print(frame.temp_centi);
Serial.print(",");
Serial.print(frame.hum_centi);
Serial.print(",");
Serial.print(frame.volt_milli);
Serial.print(",");
Serial.println(frame.checksum, HEX);
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("STM32 Sensor Data Generator Started");
Serial.println("STM32 Arduino-style Wokwi Simulation");
Serial.println("Output format: <HEADER>,<TEMP>,<HUM>,<VOLT>,<CHECKSUM>");
}
void loop() {
static int index = 0;
generateSTM32Frame(index);
index++;
if (index >= 5) {
index = 0;
}
delay(1000);
}Loading
st-nucleo-l031k6
st-nucleo-l031k6