#include <U8g2lib.h>
#include <SPI.h>
// Constants
#define ADC_RESOLUTION 1024.0F
#define ADC_VREF 5.0F
#define MIN_VOLTAGE 0.0F
#define MAX_VOLTAGE 5.0F
// GPIO
#define INPUT_AFR A0
// Filter
#define FILTER_AFR 100 // Filter range 0 to 255
// Timers
#define INTERVAL_AFR 0.01
// AFR - LAMBDA Constants
#define MAX_AFR 22.39F
#define MIN_AFR 7.35F
// Helpers
#define FILTER_LOWPASS(input, alpha, prior) (((long)input * (256 - alpha) + ((long)prior * alpha))) >> 8
// Prototype functions
float map_f(float x, float in_min, float in_max, float out_min, float out_max);
// Variables
bool flagUpdateAFR = false;
uint16_t ADC_AFR = 0;
uint32_t oldTimeLecture_AFR = 0;
float last_AFR = 0.0f; // Store the last AFR value
// Constructor for SH1106 using software SPI
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SH1106_128X64_NONAME_1_4W_SW_SPI u8g2(U8G2_R0, 13, 11, 10, 9, 8);
void setup() {
u8g2.begin();
uint8_t contrastValue = 255; // Ajuste de brillo intermedio (rango 0 a 255)
u8g2.setContrast(contrastValue);
}
void loop() {
uint32_t currentTime = millis();
// Check if it's time to read the sensor
if (currentTime - oldTimeLecture_AFR >= INTERVAL_AFR) {
uint16_t rawADC = analogRead(INPUT_AFR);
ADC_AFR = FILTER_LOWPASS(rawADC, FILTER_AFR, ADC_AFR);
oldTimeLecture_AFR = currentTime;
// Set flag to update display
flagUpdateAFR = true;
}
if (flagUpdateAFR) {
flagUpdateAFR = false;
float voltageOxygenSensor = (ADC_AFR * ADC_VREF) / ADC_RESOLUTION;
float value_AFR = map_f(voltageOxygenSensor, MIN_VOLTAGE, MAX_VOLTAGE, MIN_AFR, MAX_AFR);
// Update display only if value has changed significantly
if (abs(value_AFR - last_AFR) > 0.01) { // Small threshold to avoid tiny updates
last_AFR = value_AFR; // Store the new AFR value
char afrString[10];
dtostrf(value_AFR, 6, 1, afrString); // Convert float to string
u8g2.firstPage(); // Start the page update
do {
u8g2.setFont(u8g2_font_logisoso46_tn); // Set the font
u8g2.drawStr(-50, 45, afrString); // Draw the AFR value
u8g2.setFont(u8g2_font_bubble_tr); // Static text u8g2_font_bubble_tr
//u8g2.drawUTF8(40, 64, "λ");
u8g2.drawStr(28, 64, " AFR");
} while (u8g2.nextPage()); // Only update the display once the full page is drawn
}
}
}
float map_f(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}