Ciao a tutti, sono alle prese con un puiccolo grande progetto. Un contametri montato su una bobina che mi calcola i metri di filo e si aggiorna quando lo spessore del filo si sovrappone e sfalsa il conteggio.
Su d4 ho inserito un pulsante che salva i metri se premuto per 3 secondi. se premuto per 4 resetta i metri e se premuto una volta cambia il diametro del filo.
su d4 ho il pulsante, su d3 e d2 i sensori di prossimita' che funionano coin la calamita.
di sefguito il codice che ho usato.
Cosa sbaglio?
#include <U8g2lib.h>
#include <Wire.h>
// --- DISPLAY OLED
U8G2_SH1106_128X64_NONAME_F_HW_I2C display(U8G2_R0, U8X8_PIN_NONE);
// --- PIN
const int pulsantePin = 4;
const int sensore1Pin = 3;
const int sensore2Pin = 2;
// --- FILI SELEZIONABILI
float fili[] = {0.10,0.20,0.30,0.40,0.50,0.60,0.70,0.80,0.90,100.0,110.0,120.0,130.0,140.0};
int filoCorrente = 0;
// --- VARIABILI
volatile long contatore1 = 0;
volatile long contatore2 = 0;
volatile unsigned long lastImpulse1 = 0;
volatile unsigned long lastImpulse2 = 0;
const unsigned long debounceTime = 10; // tempo in millisecondi
// --- METRI
float metriTotali = 0;
float metriVisuali = 0;
// --- DIAMETRI MANUALI
float diametri[] = {0.10,0.20,0.30,0.40,0.50,0.60,0.70,0.80,0.90,100.0,110.0,120.0,130.0,140.0};
int diametroCorrenteIndex = 0;
float larghezzaBobina = 128.0;
// --- SMOOTHING
const float metriVelocita = 0.5;
// --- PULSANTE LUNGA
unsigned long pressStart = 0;
bool buttonLongPressed = false;
bool saved = false;
void setup() {
pinMode(pulsantePin, INPUT_PULLUP);
pinMode(sensore1Pin, INPUT_PULLUP);
pinMode(sensore2Pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(sensore1Pin), conta1, RISING);
attachInterrupt(digitalPinToInterrupt(sensore2Pin), conta2, RISING);;
display.begin();
display.clearBuffer();
Serial.begin(9600);
}
void loop() {
gestisciPulsante();
aggiornaMetri();
aggiornaDisplay();
delay(50);
}
void gestisciPulsante() {
int statoPulsante = digitalRead(pulsantePin);
if (statoPulsante == LOW) {
// Pulsante premuto
if (!buttonLongPressed) {
pressStart = millis();
buttonLongPressed = true;
}
} else {
// Pulsante rilasciato
if (buttonLongPressed) {
unsigned long durata = millis() - pressStart;
// Breve pressione (<2s) → cambia diametro
if (durata < 2000) {
diametroCorrenteIndex++;
if(diametroCorrenteIndex >= (sizeof(diametri)/sizeof(diametri[0])))
diametroCorrenteIndex = 0;
// Reset totale e contatori prima di iniziare
metriTotali = 0;
metriVisuali = 0;
contatore1 = 0;
contatore2 = 0;
}
// Pressione 2-4s → salva
else if (durata >= 2000 && durata < 4000 && !saved) {
salvaMetri();
}
// Pressione ≥4s → reset se salvato
else if (durata >= 4000 && saved) {
resetMetri();
}
buttonLongPressed = false;
}
}
}
// --- CALCOLO METRI
void aggiornaMetri() {
long giriTotali = contatore1 + contatore2;
contatore1 = 0;
contatore2 = 0;
float spessore = fili[filoCorrente];
float diametroCorrente = diametri[diametroCorrenteIndex];
float metriPerGiro = 3.1416 * (diametroCorrente / 10.0);
metriTotali += giriTotali * metriPerGiro;
if(metriTotali < 0) metriTotali = 0;
// smoothing
if(metriVisuali < metriTotali) metriVisuali += metriVelocita;
if(metriVisuali > metriTotali) metriVisuali -= metriVelocita;
}
// --- DISPLAY
void aggiornaDisplay() {
display.clearBuffer();
int shiftX = 5;
// --- METRI CENTRALI
display.setFont(u8g2_font_fub35_tr);
char bufferMetri[10];
dtostrf(metriVisuali,4,1,bufferMetri);
int w = display.getStrWidth(bufferMetri);
display.drawStr((128 - w)/2 + shiftX, 40, bufferMetri);
// --- DIAMETRO IN BASSO CENTRATO
float diametroCorrente = diametri[diametroCorrenteIndex];
display.setFont(u8g2_font_ncenB08_tr);
char bufferD[6];
dtostrf(diametroCorrente,4,1,bufferD);
int wD = display.getStrWidth(bufferD);
display.drawStr((128 - wD)/2, 62, bufferD);
display.sendBuffer();
}
// --- INTERRUPT
void conta1() {
unsigned long now = millis();
if (now - lastImpulse1 > debounceTime) {
contatore1++;
lastImpulse1 = now;
}
}
void conta2() {
unsigned long now = millis();
if (now - lastImpulse2 > debounceTime) {
contatore2--;
lastImpulse2 = now;
}
}
// --- SALVA / RESET
void salvaMetri() {
saved = true;
Serial.print("Salvato: ");
Serial.println(metriTotali);
// TODO: aggiungi qui SD/EEPROM
}
void resetMetri() {
metriTotali = 0;
metriVisuali = 0;
contatore1 = 0;
contatore2 = 0;
saved = false;
Serial.println("Reset effettuato!");
}