/*
Centralina Rilevazione Tempo di Apertura Flap
Design and code by Salvatore Vernò Nov 2024
rev00 : 21 Nov 2024 Prima Versione con supporto di Chatgpt
rev01 : 21 Nov 2024 Seconda versione, non funzionante
rev02 : 22 Nov 2024 A partire dalla demo Encoder_Interrupt_Display della libreria ESP32_Encoder, codice adattato per rilevare il tempo di volo
*/
#include <Arduino.h>
#include <ESP32Encoder.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "esp_task_wdt.h"
static IRAM_ATTR void enc_cb(void* arg) {
ESP32Encoder* enc = (ESP32Encoder*) arg;
//Serial.printf("enc cb: count: %d\n", enc->getCount());
static bool leds = false;
digitalWrite(LED_BUILTIN, (int)leds);
leds = !leds;
}
extern bool loopTaskWDTEnabled;
extern TaskHandle_t loopTaskHandle;
ESP32Encoder encoder(true, enc_cb);
// Definizione display OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
// Indirizzo I2C del display
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
// Definizione encoder
#define ENCODER_PIN_A 18 // BIANCO
#define ENCODER_PIN_B 19 // MARRONE
static const char* LOG_TAG = "main";
// Variabili
long previousPosition = -999;
unsigned long startTime = 0;
bool flapOpening = false;
unsigned long lastMovementTime = 0; // Tempo dell'ultimo movimento
long lastImpulseCount = 0; // Variabile per memorizzare gli impulsi dell'ultima corsa
const unsigned long movementTimeout = 500; // Timeout di 500ms
void setup(){
loopTaskWDTEnabled = true;
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
// Encoder A and B pins connected with 1K series resistor to pins 4 and 5, common pin to ground.
// |- A --- 1K --- pin 4 ENCODER_PIN_A
// >=[enc]|- GND
// |- B --- 1K --- pin 5 ENCODER_PIN_B
ESP32Encoder::useInternalWeakPullResistors = puType::up;
encoder.attachSingleEdge(ENCODER_PIN_A, ENCODER_PIN_B);
encoder.clearCount();
encoder.setFilter(1023);
if (! display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS))
{
for (;;) {
Serial.println("display init failed");
}
}
display.cp437(true);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.display();
esp_log_level_set("*", ESP_LOG_DEBUG);
esp_log_level_set("main", ESP_LOG_DEBUG);
esp_log_level_set("ESP32Encoder", ESP_LOG_DEBUG);
esp_task_wdt_add(loopTaskHandle);
}
void loop(){
long currentPosition = encoder.getCount();
unsigned long currentTime = millis();
// Se la posizione è cambiata, aggiorna e segnala movimento
if (currentPosition != previousPosition) {
Serial.print("Posizione encoder: ");
Serial.println(currentPosition);
if (!flapOpening) {
flapOpening = true;
startTime = currentTime;
}
// Resetta il tempo dell'ultimo movimento
lastMovementTime = currentTime;
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.print("Encoder Pos: ");
display.println(currentPosition);
display.setCursor(0, 20);
display.print("Movimento in corso...");
display.display();
previousPosition = currentPosition;
}
// Se non ci sono variazioni di posizione per più di movementTimeout, considera il movimento finito
if (flapOpening && (currentTime - lastMovementTime) > movementTimeout) {
unsigned long elapsedTime = currentTime - startTime;
// Calcola il numero di impulsi registrati nell'ultima corsa
lastImpulseCount = currentPosition - previousPosition;
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.print("Tempo apertura:");
display.setCursor(0, 20);
display.setTextSize(2);
if (elapsedTime<= movementTimeout+1) {
display.print("< ");
display.print(movementTimeout);
}else{
display.print(elapsedTime);
}
display.println(" ms");
display.setTextSize(1); // Dimensione minore per la corsa
display.setCursor(0, 40);
display.print("Corsa = ");
display.print(lastImpulseCount);
display.println(" imp");
display.display();
display.display();
// Serial print per debug
Serial.println("Tempo apertura:");
Serial.println(elapsedTime);
Serial.println(" ms");
Serial.print("Corsa registrata: ");
Serial.println(lastImpulseCount);
flapOpening = false; // Termina il movimento
}
}