Rilevare il fronte di un segnale con Arduino


Ciao!

oggi affronterò un tema all'apparenza banale,
ma che spero possa tornarvi utile.

Vedremo infatti come rilevare il fronte di salita di un pulsante.
Questo risultato può essere ottenuto anche con l'uso di un interrupt (link reference),
ma questa funzione non può essere utilizzata su tutti i pin (almeno nell'Arduino Uno)




Per questo motivo ho scritto questo semplice programma, esso contiene la funzione "ReadRiseEdge" che restituisce il valore "1" al rilevamento del fronte di salita del segnale.

Per la funzione ho utilizzato i puntatori, puoi trovare maggiori info a riguardo qui.




Qui sotto puoi trovare l'esempio realizzato con TinkerCad, cliccando su "Avvia simulazione" potrai cliccare sui tasti per accendere i led.
Potrai anche accedere al serial monitor per vedere i contatori incrementare di uno ad ogni click.

Per vedere il codice poi è sufficiente cliccare sul tasto "Codice".
Ecco il link a cui puoi trovare collegamenti, codice e simulare il progetto

Qui sotto invece il codice da poter copiare

  1. #define NumOut  3
  2. #define NumIn   3
  3.  
  4. #define Led0    2
  5. #define Led1    3
  6. #define Led2    4
  7.  
  8. #define Puls0   11
  9. #define Puls1   12
  10. #define Puls2   13
  11.  
  12. #define WaitBetwReadPuls 50
  13.  
  14. bool StatePuls0, StatePuls1, StatePuls2;
  15. bool MemStatePuls0, MemStatePuls1, MemStatePuls2;
  16. bool RiseEdgePuls0, RiseEdgePuls1, RiseEdgePuls2;
  17.  
  18. unsigned int Out[NumOut] = {Led0, Led1, Led2};
  19. unsigned int In[NumIn] = {Puls0, Puls1, Puls2};
  20. unsigned int Count0, Count1, Count2;
  21. unsigned long TimeNow;
  22. unsigned long TimerPuls0, TimerPuls1, TimerPuls2;
  23.  
  24. void setup()
  25. {
  26.   Serial.begin(9600);
  27.  
  28.   //Configurazione ingressi/uscite
  29.   for (int i = 0; i < NumIn; i++)
  30.   {
  31.     pinMode(In[i], INPUT_PULLUP);
  32.   }
  33.   for (int i = 0; i < NumOut; i++)
  34.   {
  35.     pinMode(Out[i], OUTPUT);
  36.   }
  37.  
  38.   TimeNow = 0;
  39. }
  40.  
  41. void loop()
  42. {
  43.   TimeNow = millis();
  44.  
  45.   //funzione che restituisce 1 al rilevamento del fronte di salita del pulsante (livello logico del segnale che passa da 1 a 0)
  46.   RiseEdgePuls0 = ReadRiseEdge(Puls0, &MemStatePuls0, &StatePuls0, &TimerPuls0);
  47.   RiseEdgePuls1 = ReadRiseEdge(Puls1, &MemStatePuls1, &StatePuls1, &TimerPuls1);
  48.   RiseEdgePuls2 = ReadRiseEdge(Puls2, &MemStatePuls2, &StatePuls2, &TimerPuls2);
  49.  
  50.   //quando rilevo il fronte accendo il led ed incremento il contatore
  51.   if (RiseEdgePuls0) {
  52.     digitalWrite(Out[0], HIGH);
  53.     Count0++;
  54.   }
  55.   if (RiseEdgePuls1) {
  56.     digitalWrite(Out[1], HIGH);
  57.     Count1++;
  58.   }
  59.   if (RiseEdgePuls2) {
  60.     digitalWrite(Out[2], HIGH);
  61.     Count2++;
  62.   }
  63.  
  64.   Serial.println();
  65.   Serial.print ("Count0: ");
  66.   Serial.println(Count0);
  67.   Serial.print ("Count1: ");
  68.   Serial.println(Count1);
  69.   Serial.print ("Count2: ");
  70.   Serial.println(Count2);
  71.   Serial.println();
  72.  
  73.   delay(10);
  74. }
  75.  
  76. //Funzione per leggere i fronti, vengono utilizzati i puntatori per passare delle memorie alla funzione
  77. //inoltre viene utilizzato il tempo ottenuto tramite la funzione "millis" per non avere ritardi nel programma
  78. bool ReadRiseEdge(unsigned int InPin, bool *MemState, bool *StatePuls, unsigned long *MemTime)
  79. {
  80.   bool RiseEdge;
  81.  
  82.   *MemState = *StatePuls;
  83.  
  84.   if (TimeNow > (*MemTime + WaitBetwReadPuls))
  85.   {
  86.     *StatePuls = digitalRead(InPin);
  87.     *MemTime = TimeNow;
  88.   }
  89.  
  90.   if (*StatePuls == *MemState)
  91.   {
  92.     RiseEdge = 0;
  93.   }
  94.   if (*StatePuls != *MemState)
  95.   {
  96.     if (*StatePuls == 0)
  97.     {
  98.       RiseEdge = 1;
  99.     }
  100.     if (*StatePuls == 1)
  101.     {
  102.       RiseEdge = 0;
  103.     }
  104.   }
  105.  
  106.   return RiseEdge;
  107. }

Questo è tutto, ciao!
Seguimi sulle mie pagine per rimanere sempre aggiornato sui nuovi post!

Nessun commento:

Posta un commento

Lascia un commento qui sotto, ti risponderò il prima possibile!

Altri Post