Files
zjui-ece445/stm32/Src/run.c

201 lines
7.4 KiB
C

#include "run.h"
#include "sensors/run_bme680.h"
#include "main.h"
#include <stdio.h>
#include <math.h>
extern ADC_HandleTypeDef hadc1;
extern CRC_HandleTypeDef hcrc;
extern I2C_HandleTypeDef hi2c1;
extern RTC_HandleTypeDef hrtc;
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart3;
uint32_t adc_dma[5];
volatile uint32_t adc_dma_finished;
measure_value_t measure_value;
void setup_pms5003();
void loop_pms5003();
void loop_adc();
void loop_bme680();
void loop_print();
float voltage_to_resistor_value(uint32_t voltage, uint32_t resistor);
void setup() {
if(0 != bme680_my_init()) {
while(1) {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
HAL_Delay(100);
}
}
}
void loop() {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
measure_value.valid.pms5003 = 0;
measure_value.valid.bme680 = 0;
measure_value.valid.mics6814 = 0;
for(int i = 0; i < 3 && !measure_value.valid.pms5003; i++) {
loop_pms5003();
}
loop_adc();
bme680_my_loop();
loop_print();
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
RTC_TimeTypeDef rtc_time;
rtc_time.Hours = 0;
rtc_time.Minutes = 0;
rtc_time.Seconds = 0;
RTC_AlarmTypeDef rtc_alarm;
rtc_alarm.Alarm = RTC_ALARM_A;
rtc_alarm.AlarmTime.Hours = 0;
rtc_alarm.AlarmTime.Minutes = 0;
rtc_alarm.AlarmTime.Seconds = 5;
HAL_RTC_SetTime(&hrtc, &rtc_time, RTC_FORMAT_BCD);
HAL_RTC_SetAlarm_IT(&hrtc, &rtc_alarm, RTC_FORMAT_BCD);
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
extern volatile uint32_t uwTick;
uwTick += rtc_alarm.AlarmTime.Seconds * 1000;
}
#define UART_PMS5003 huart2
void loop_pms5003() {
uint8_t buf[32];
int ret;
// Timeout = 100ms, so cannot get mixed data of 2 transmissions
if(HAL_OK != (ret = HAL_UART_Receive(&UART_PMS5003, buf, 32, 100))) {
if(HAL_TIMEOUT == ret) {
// Previous attempt timeout, so we got half data from last transmission
// Now we can wait longer for the next transmission
if(HAL_OK != HAL_UART_Receive(&UART_PMS5003, buf, 32, 1000)) return;
} else {
return;
}
}
// Verify packet header and frame length (fixed)
if(buf[0] != 0x42 || buf[1] != 0x4d || buf[2] != 0 || buf[3] != 28) return;
// Verify packet sum
uint16_t sum = 0;
for(int i = 0; i < 30; i++) sum += buf[i];
uint16_t sum_expected = (((uint32_t) buf[30]) << 8) | buf[31];
if(sum != sum_expected) return;
measure_value.pms5003.pm1 = (((uint32_t) buf[4]) << 8) | buf[5];
measure_value.pms5003.pm2_5 = (((uint32_t) buf[6]) << 8) | buf[7];
measure_value.pms5003.pm10 = (((uint32_t) buf[8]) << 8) | buf[9];
measure_value.valid.pms5003 = 1;
}
#define RESISTOR_VALUE_CO 47000
#define RESISTOR_VALUE_NH3 47000
#define RESISTOR_VALUE_NO2 47000
#define MICS6814_BASE_RESISTANCE_CO 1000000
#define MICS6814_BASE_RESISTANCE_NH3 1000000
#define MICS6814_BASE_RESISTANCE_NO2 10000
// #define MICS6814_BASE_ANALOG_CO (1.0 * MICS6814_BASE_RESISTANCE_CO / (MICS6814_BASE_RESISTANCE_CO + RESISTOR_VALUE_CO))
// #define MICS6814_BASE_ANALOG_NH3 (1.0 * MICS6814_BASE_RESISTANCE_NH3 / (MICS6814_BASE_RESISTANCE_NH3 + RESISTOR_VALUE_NH3))
// #define MICS6814_BASE_ANALOG_NO2 (1.0 * MICS6814_BASE_RESISTANCE_NO2 / (MICS6814_BASE_RESISTANCE_NO2 + RESISTOR_VALUE_NO2))
#define MICS6814_1X_PPM_CO 4.5
#define MICS6814_1X_PPM_NH3 0.7
#define MICS6814_1X_PPM_NO2 0.15
#define MICS6814_LOG_SLOPE_CO -0.8
#define MICS6814_LOG_SLOPE_NH3 -0.55
#define MICS6814_LOG_SLOPE_NO2 1.0
#define STM32_VREFINT_VALUE 1.20f
#define STM32_TEMPERATURE_VOLTAGE_SLOPE 0.0043f
#define STM32_TEMPERATURE_VOLTAGE_25C 1.43f
void loop_adc() {
adc_dma_finished = 0;
HAL_ADC_Start_DMA(&hadc1, adc_dma, 5);
while(!adc_dma_finished);
HAL_Delay(100);
HAL_ADC_Stop_DMA(&hadc1);
// See __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS for temperature formula.
measure_value.stm32.vrefint = 4096.0 / adc_dma[4] * STM32_VREFINT_VALUE;
measure_value.stm32.temp = (STM32_TEMPERATURE_VOLTAGE_25C - adc_dma[3] * measure_value.stm32.vrefint / 4096) / STM32_TEMPERATURE_VOLTAGE_SLOPE + 25;
// MICS-6814 formula from:
// https://github.com/noorkhokhar99/MICS6814/blob/master/MICS6814.cpp
// measure_value.mics6814.co = 1.0 * adc_dma[0] / MICS6814_BASE_ANALOG_CO * (1 - MICS6814_BASE_ANALOG_CO) / (4096.0 - adc_dma[0]);
// measure_value.mics6814.nh3 = 1.0 * adc_dma[1] / MICS6814_BASE_ANALOG_NH3 * (1 - MICS6814_BASE_ANALOG_NH3) / (4096.0 - adc_dma[1]);
// measure_value.mics6814.no2 = 1.0 * adc_dma[2] / MICS6814_BASE_ANALOG_NO2 * (1 - MICS6814_BASE_ANALOG_NO2) / (4096.0 - adc_dma[2]);
// measure_value.mics6814.co = pow(measure_value.mics6814.co, -1.179) * 4.385;
// measure_value.mics6814.nh3 = pow(measure_value.mics6814.nh3, -1.67) * 1.47;
// measure_value.mics6814.no2 = pow(measure_value.mics6814.no2, 1.007) * 6.855;
measure_value.mics6814.co = voltage_to_resistor_value(adc_dma[0], RESISTOR_VALUE_CO);
measure_value.mics6814.nh3 = voltage_to_resistor_value(adc_dma[1], RESISTOR_VALUE_NH3);
measure_value.mics6814.no2 = voltage_to_resistor_value(adc_dma[2], RESISTOR_VALUE_NO2);
measure_value.mics6814.co = MICS6814_1X_PPM_CO * powf(10, log10f(measure_value.mics6814.co / MICS6814_BASE_RESISTANCE_CO) / MICS6814_LOG_SLOPE_CO);
measure_value.mics6814.nh3 = MICS6814_1X_PPM_NH3 * powf(10, log10f(measure_value.mics6814.nh3 / MICS6814_BASE_RESISTANCE_NH3) / MICS6814_LOG_SLOPE_NH3);
measure_value.mics6814.no2 = MICS6814_1X_PPM_NO2 * powf(10, log10f(measure_value.mics6814.no2 / MICS6814_BASE_RESISTANCE_NO2) / MICS6814_LOG_SLOPE_NO2);
measure_value.valid.mics6814 = 1;
}
void loop_print() {
if(measure_value.valid.pms5003) {
printf("PMS5003 PM1.0 %d\r\n", measure_value.pms5003.pm1);
printf("PMS5003 PM2.5 %d\r\n", measure_value.pms5003.pm2_5);
printf("PMS5003 PM10 %d\r\n", measure_value.pms5003.pm10);
} else {
printf("PMS5003 Measure Error\r\n");
}
if(measure_value.valid.bme680) {
printf("BME680 Tmp %.4f\r\n", measure_value.bme680.temperature);
printf("BME680 Prs %.4f\r\n", measure_value.bme680.pressure);
printf("BME680 Hum %.4f\r\n", measure_value.bme680.humidity);
printf("BME680 TVOC %.4f\r\n", measure_value.bme680.tvoc);
printf("BME680 CO2 %.4f\r\n", measure_value.bme680.co2);
printf("BME680 IAQ %.4f\r\n", measure_value.bme680.air_quality);
} else {
printf("BME680 Measure Error\r\n");
}
if(measure_value.valid.mics6814) {
printf("MICS CO %.4f\r\n", measure_value.mics6814.co);
printf("MICS NH3 %.4f\r\n", measure_value.mics6814.nh3);
printf("MICS NO2 %.4f\r\n", measure_value.mics6814.no2);
} else {
printf("MICS Measure Error\r\n");
}
printf("STM32 Tmp %.4f\r\n", measure_value.stm32.temp);
printf("STM32 Vrf %.4f\r\n", measure_value.stm32.vrefint);
printf("\r\n");
}
float voltage_to_resistor_value(uint32_t voltage, uint32_t resistor) {
return 1.0 * resistor * voltage / (4096 - voltage);
}