Contatore Geiger - Led di status

Buongiorno a tutti!
Ho appena terminato un piccolo progetto che prevede l’interfacciamento di un contatore geiger in kit con un Arduino Nano.
Il codice (adattato da uno trovato in rete), prevede il conteggio delle impulsi provenienti dal geiger in uno specifico lasso di tempo, attivando il corrispondente led di stato (verde, giallo e rosso) con indicazione del valore della radiazione in uSv/h sul display 16x2 .
Vorrei ora implementare una modifica che preveda che nel caso venisse registrato un evento in cui il conteggio degli impulsi sia superiore a 200 al minuto, il corrispondente led di allarme (giallo o rosso) lampeggi (il lampeggiamento segnalerebbe un evento passato), a prescindere dal ritorno allo status di normalità (verde).
In altre parole, nel caso fosse stato stata superata la soglia di 200 impulsi al minuto, ma nel frattempo la situazione fosse tornata normale, il led verde sarebbe accesso mentre quello giallo lampeggerebbe.
E questo, sino al reset dell’Arduino.
il codice sinora implementato (perdonate la “crudezza” dovuta alla mia ignoranza abissale in programmazione) è il seguente:

#include <LiquidCrystal.h>

LiquidCrystal lcd(3,4,5,6,7,8);

const int CPM100pin=9;
const int CPM300pin=10;
const int CPM600pin=11;

// fattore di conversione - da impulsi al minuto a uSV/h
#define CONV_FACTOR 0.00812

// Variabili
int geiger_input = 2;
long count = 0;
long countPerMinute = 0;
long timePrevious = 0;
long timePreviousMeasure = 0;
long time = 0;
long countPrevious = 0;
float radiationValue = 0.0;


void setup() {

pinMode(LED_BUILTIN, OUTPUT);
pinMode(CPM100pin, OUTPUT);
pinMode(CPM300pin, OUTPUT);
pinMode(CPM600pin, OUTPUT);
attachInterrupt(digitalPinToInterrupt(2), countPulse, RISING);

Serial.begin(9200);

  lcd.begin(16, 2);
  lcd.clear();
  
...omissis

  delay(10000);

}

void loop() {
  
ShowCPMandSv();

}

void countPulse() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(100);
  digitalWrite(LED_BUILTIN, LOW);
  count++;
}

void ShowCPMandSv() {
  if (millis()-timePreviousMeasure > 10000){
    float elapsedmillis = millis ();
    int elapsedSec = round ((elapsedmillis)/1000);
    countPerMinute = 6*count;
    radiationValue = countPerMinute * CONV_FACTOR;
    timePreviousMeasure = millis();
    Serial.print("CPM = ");
    Serial.print(countPerMinute,DEC);
    Serial.print("  -  ");
    Serial.print("uSv/h = ");
    Serial.println(radiationValue,4);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("CPM = ");
    lcd.setCursor(6,0);
    lcd.print(countPerMinute);
    lcd.setCursor(0,1);
    lcd.print(radiationValue,4);
    lcd.setCursor(6,1);
    lcd.print(" uSv/h");
    count = 0;
    delay(3000);
    }
  if ((countPerMinute >= 0)&&(countPerMinute <= 200)) {
      digitalWrite(CPM100pin, HIGH);
      }
    else {
      digitalWrite(CPM100pin, LOW);
  }
  if ((countPerMinute >= 200)&&(countPerMinute < 400)) { 
      digitalWrite(CPM300pin, HIGH);
      }
    else {
      digitalWrite(CPM300pin, LOW);
  }
 if ((countPerMinute >= 400)&&(countPerMinute <= 600)) { 
      digitalWrite(CPM600pin, HIGH);
      }
    else {
      digitalWrite(CPM600pin, LOW);
  }
}

Qualcuno potrebbe gentilmente indicarmi quale soluzione adottare per implementare questa “memoria” dell’allarme?
Grazie a tutti e buona giornata!

Buongiorno,
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie. :slight_smile:

Qui una serie di link utili, non inerenti al tuo problema:

Buongiorno Patrick.
Grazie per aver tirato le orecchie a questo vecchio marpione indisciplinato :wink:
Ho provveduto, come si conviene, a presentarmi nell’apposito thread.
Buona giornata!

grazie a te,
per il tuo problemino basta aggiungere una flag che indichi se è stato superato il valore che vuoi ed usarlo per accendere il led corrispondente.
Così dovrebbe funzionare :wink:

#include <LiquidCrystal.h>

LiquidCrystal lcd(3, 4, 5, 6, 7, 8);

const int CPM100pin = 9;
const int CPM300pin = 10;
const int CPM600pin = 11;

// fattore di conversione - da impulsi al minuto a uSV/h
#define CONV_FACTOR 0.00812

// Variabili
int geiger_input = 2;
long count = 0;
long countPerMinute = 0;
long timePrevious = 0;
long timePreviousMeasure = 0;
// long time = 0;                // questo non è usato...
long countPrevious = 0;
float radiationValue = 0.0;

//flag soglia di lampeggio led giallo
bool superatoSoglia = false;

void setup() {

   pinMode(LED_BUILTIN, OUTPUT);
   pinMode(CPM100pin, OUTPUT);
   pinMode(CPM300pin, OUTPUT);
   pinMode(CPM600pin, OUTPUT);
   attachInterrupt(digitalPinToInterrupt(2), countPulse, RISING);

   Serial.begin(9200);

   lcd.begin(16, 2);
   lcd.clear();

   ...omissis

   delay(10000);

}

void loop() {

   ShowCPMandSv();

}

void countPulse() {
   digitalWrite(LED_BUILTIN, HIGH);
   delay(100);
   digitalWrite(LED_BUILTIN, LOW);
   count++;
}

void ShowCPMandSv() {
   if (millis() - timePreviousMeasure > 10000) {
      float elapsedmillis = millis ();
      int elapsedSec = round ((elapsedmillis) / 1000);
      countPerMinute = 6 * count;
      radiationValue = countPerMinute * CONV_FACTOR;
      timePreviousMeasure = millis();
      Serial.print("CPM = ");
      Serial.print(countPerMinute, DEC);
      Serial.print("  -  ");
      Serial.print("uSv/h = ");
      Serial.println(radiationValue, 4);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("CPM = ");
      lcd.setCursor(6, 0);
      lcd.print(countPerMinute);
      lcd.setCursor(0, 1);
      lcd.print(radiationValue, 4);
      lcd.setCursor(6, 1);
      lcd.print(" uSv/h");
      count = 0;
      //    delay(3000);
   }

   // a prescindere se supero i 200 imposto la flag a vera
   // resettabile solo con reset arduino
   // volendo si può aggiungere un pulsante che resetta solo questa condizione
   // rimettendo superatoSoglia= false
   if (countPerMinute >= 200) {
      superatoSoglia = true;
   }
   if (superatoSoglia) {
      digitalWrite( CMP300, HIGH)
   }
   if ((countPerMinute >= 0) && (countPerMinute <= 200)) {
      digitalWrite(CPM100pin, HIGH);
   } else {
      digitalWrite(CPM100pin, LOW);
   }
   if ((countPerMinute >= 200) && (countPerMinute < 400)) {
      digitalWrite(CPM300pin, HIGH);
   } else if (!superatoSoglia) {
      digitalWrite(CPM300pin, LOW);
   }
   if ((countPerMinute >= 400) && (countPerMinute <= 600)) {
      digitalWrite(CPM600pin, HIGH);
   } else {
      digitalWrite(CPM600pin, LOW);
   }
}

Salve Patrick,
ho implementato il tuo suggerimento, diversificando gli stati di allarme in due categorie (giallo e rosso).
Funziona perfettamente!
Grazie per il tuo prezioso aiuto e per la rapidità della tua risposta.
Buona serata!