sabato 22 settembre 2018

Sensore di livello pellet per stufe con arduino

Salve a tutti, oggi vorrei proporvi un semplice progetto per la creazione di un sensore di livello del pellet per le stufe che ne sono sprovviste, iniziamo subito.

Materiale occorrente

  • Arduino nano  Ebay
  • Sensore ad ultrasuoni HC-SR04  Ebay
  • Buzzer
  • Led bar 10 segmenti Ebay  

  • 4 batterie AA

Lo schema è molto semplice, di seguito un riassunto dei collegamenti

BUZZER +    -->    pin 6
BUZZER -     -->   gnd

HC-SR04 TRIGGER    -->    pin 3
HC-SR04 ECHO           -->    pin 4

Pulsante     -->    pin 2

Led bar CLK    -->    pin 11
Led bar DIO     -->    pin 12


Funzionamento

Per poter compilare il codice sono necessarie alcune librerie

TM1651    Per il funzionamento della barra led
NewPing   Per il funzionamento del sensore ad ultrasuoni
EEPROM  Libreria inclusa in Arduino usata per il salvataggio dei dati all' interno della eeprom

Il sensore è stato pensato per essere attaccato alla parete interna del coperchio del pellet.
Il pulsante serve per settare il livello minimo del pellet all' interno della stufa, premendo il pulsante per 5 secondi si entra nel "setup mode" viene emesso un segnale luminoso tramite la barra led ed acustico, da quando si entra nel setup si hanno 30 secondi (Variabile TempoAttesa) per chiudere il coperchio e lasciare che il sensore venga calibrato con il livello minimo di pellet all' interno del serbatoio.
Passati i 30 secondi viene emesso un nuovo segnale luminoso ed acustico ed il valore letto viene salvato nella eeprom di Arduino, a questo punto sulla barra led vedremo il livello del pellet, la barra piena indica il livello massimo la barra vuota indica che il serbatoio è vuoto.

Ecco il codice:
Il codice è abbastanza commentato ma per qualsiasi chiarimento non esitate a contattarmi.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include <TM1651.h>
#include <NewPing.h>
#include <EEPROM.h>

int MemoryAddress = 1;
int ValoreSalvato = 0;

#define PIN_PULSANTE  2
#define PIN_BUZZER  6
#define PIN_TRIGGER  3
#define PIN_ECHO 4

#define TM1651_CLK 12//pins definitions for TM1651 and can be changed to other ports       
#define TM1651_DIO 11

int PulsanteState = 0;

unsigned long MomentoPressione = 0;
boolean SetupMode = false;

//tempo di attesa per il savataggio del valore minimo del sensore
int TempoAttesa = 30000;

NewPing sonar(PIN_TRIGGER, PIN_ECHO,500);

TM1651 batteryDisplay(TM1651_CLK, TM1651_DIO);

void setup()
{
 /*Imposto i pin della scheda*/
 pinMode(PIN_PULSANTE, INPUT);
 pinMode(PIN_BUZZER, OUTPUT);
 
 batteryDisplay.init();

 /*Imposto la porta seriale*/
 Serial.begin(9600);
 batteryDisplay.set(2);//BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;
 batteryDisplay.displayLevel(7);
 /*Leggo dalla memoria non volatile il valore della cella di memoria
 dove viene salvato il valore della distanza dell' allarme*/
 /*Il valore viene salvato diviso 10 quindi il valore recuperato deve essere moltiplicato * 10 */
 ValoreSalvato = EEPROM.read(MemoryAddress)*10; 
}

void loop()
{
 Serial.println("..");
 /*Se sono in setup*/
 if (SetupMode == true) {
  /*Attendo n secondi per il posizionamento del sensore*/
  int attesa = TempoAttesa / 8;
  batteryDisplay.displayLevel(7);
  delay(attesa);
  batteryDisplay.displayLevel(6);
  delay(attesa);
  batteryDisplay.displayLevel(5);
  delay(attesa);
  batteryDisplay.displayLevel(4);
  delay(attesa);
  batteryDisplay.displayLevel(3);
  delay(attesa);
  batteryDisplay.displayLevel(2);
  delay(attesa);
  batteryDisplay.displayLevel(1);
  delay(attesa);
  batteryDisplay.displayLevel(0);
  delay(attesa);

  /*Leggo la distanza dal sensore ultrasonico e salvo il valore letto nella variabile ValoreSalvato 
  e salvo il valore nella memoria*/
  int Us = sonar.ping_median(10);
  Serial.print("Ping: ");
  ValoreSalvato = Us / US_ROUNDTRIP_CM;
  Serial.print(ValoreSalvato);
  Serial.println("cm");
  /*dato che la memoria si pu� scrivere solo 100000 volte mi assicuro che il valore di distanza letto sia utile*/
  /*il valore di una cella di memoria pu� contenere valori da 0 a 255, quindi salvo il valore di distanza / 10*/
  int DatoDaSalvare = ValoreSalvato / 10;

  if (DatoDaSalvare != 0) {
   EEPROM.write(MemoryAddress, DatoDaSalvare);
  }

  SetupMode = false;
  /*Emetto un segnale per la conferma della fine del SetupMode*/
  BuzzerSetupModeComplete();
 }

 PulsanteState = digitalRead(PIN_PULSANTE);
        
 Serial.println("Stato Pulsante: " + PulsanteState);

 /*Se premo il pulsante*/
 if (PulsanteState == HIGH) {
  /*Se il valore di MomentoPressione � = 0 devo impostare il time della pressione del pulsante*/
  if (MomentoPressione == 0) {
   MomentoPressione = millis();
   Serial.println("Momento Pressione " + MomentoPressione);
  }
  /*Se il pulsante � stato premuto per 5 secondi*/
  if (millis() - MomentoPressione >= 5000) {
   SetupMode = true;
   Serial.println("Pulsante Premuto per 5 secondi");
   /*Faccio un suono dal Buzzer*/
   BuzzerSetupMode();
   PulsanteState = 0;
  }
 }

 
 
    /*Leggo la distanza dal sensore Ultrasuoni, se la distanza � > del valore letto dalla memoria allora devo mandare un allarme*/
  int Us = sonar.ping_median(10);
  Serial.print("Ping: ");
  int Cm = Us / US_ROUNDTRIP_CM;
  Serial.print(Cm);
  Serial.println("cm");
  Serial.print("ValoreSalvato: ");
  Serial.println(ValoreSalvato,10);
  if (Cm > ValoreSalvato) {
   batteryDisplay.displayLevel(0);
   //digitalWrite(PIN_BUZZER, LOW);
   //digitalWrite(PIN_BUZZER, HIGH);
   //delay(250);
   //digitalWrite(PIN_BUZZER, LOW);
   //delay(250);
   //digitalWrite(PIN_BUZZER, HIGH);
   //delay(250);
   //digitalWrite(PIN_BUZZER, LOW);
                }
         else {
    int frazione = ValoreSalvato / 8;
    Serial.print("frazione: ");
    Serial.println(frazione, 10);
    int qLed = Cm / frazione;
    Serial.print("qLed: ");
    Serial.println(qLed, 10);
    if (qLed > 7)  qLed = 7 ;
    qLed = qLed - 7;
    qLed = abs(qLed);
    batteryDisplay.displayLevel(qLed);
   }
}

void BuzzerSetupMode() {
 digitalWrite(PIN_BUZZER, LOW);
 digitalWrite(PIN_BUZZER, HIGH);
 delay(500);
 digitalWrite(PIN_BUZZER, LOW);
 delay(200);
 digitalWrite(PIN_BUZZER, HIGH);
 delay(500);
 digitalWrite(PIN_BUZZER, LOW);
}

void BuzzerSetupModeComplete() {
 batteryDisplay.displayLevel(0);
 digitalWrite(PIN_BUZZER, LOW);
 digitalWrite(PIN_BUZZER, HIGH);
 batteryDisplay.displayLevel(7);
 delay(250);
 digitalWrite(PIN_BUZZER, LOW);
 batteryDisplay.displayLevel(0);
 delay(250);
 digitalWrite(PIN_BUZZER, HIGH);
 batteryDisplay.displayLevel(7);
 delay(250);
 digitalWrite(PIN_BUZZER, LOW);
 batteryDisplay.displayLevel(0);
 delay(250);
 digitalWrite(PIN_BUZZER, HIGH);
 batteryDisplay.displayLevel(7);
 delay(250);
 digitalWrite(PIN_BUZZER, LOW);
 batteryDisplay.displayLevel(0);
}

Nessun commento:

Posta un commento