Go Down

Topic: Sensore co2 mh-z14a  (Read 2421 times) previous topic - next topic

zoomx


megaciro

amicissimi, di seguito trovate il codice con cui sto giocando; date un occhiata alla parte dei comandi affidati ai pulsanti perchè anche se funzionano non sono reattivi, cioe il set poin varia ma devo tenere premuto, stessa cosa la retroilluminazione; pensavo ad un antirimbalzo ma come si fa con un lcd keypad?
Code: [Select]
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>

#define pwmPin 11// pin pwm sensore



SoftwareSerial mySerial(A2, A1); // RX, TX

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


byte cmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
unsigned char response[9];
unsigned long th, tl,ppm, ppm2, ppm3 = 0;
const int RELAY=12; //Lock Relay or motor


int SetPoint=1000;
int luce=10;//luce display
int analogPin = A0;// pin dei pulsanti


int lcd_key     = 0;
int adc_key_in  = 0;

#define dx  0
#define su   1
#define giu   2
#define sx   3
#define SELECT 4
#define btnNONE   5


int read_buttons() {
 
 int adc_key_in = analogRead(0);
 
 if (adc_key_in > 1000) return btnNONE;
 if (adc_key_in < 50)   return dx; 
 if (adc_key_in < 195)  return su;
 if (adc_key_in < 380)  return giu;
 if (adc_key_in < 555)  return sx;
 if (adc_key_in < 790)  return SELECT;   
}






void setup() {

  lcd.begin(16,2);
  Serial.begin(9600);
  mySerial.begin(9600);
  pinMode(pwmPin, INPUT);
  pinMode(luce,OUTPUT);
  pinMode(RELAY,OUTPUT);
  //digitalWrite(su,HIGH);
  //digitalWrite(giu,HIGH);
 
  digitalWrite(RELAY,LOW);   
 
}

void loop() {


  mySerial.write(cmd,9);
  mySerial.readBytes(response, 9);
  unsigned int responseHigh = (unsigned int) response[2];
  unsigned int responseLow = (unsigned int) response[3];
  ppm = (256*responseHigh)+responseLow;


  //CO2 via pwm
  do {
    th = pulseIn(pwmPin, HIGH, 1004000) / 1000;
    tl = 1004 - th;
    ppm2 = 2000 * (th-2)/(th+tl-4);
    ppm3 = 5000 * (th-2)/(th+tl-4);
  } while (th == 0);

 
  lcd.setCursor(0,0);
  lcd.print("CO2:");    //Do not display entered keys
  lcd.print(ppm);
 
  int buttons = read_buttons();

  if(buttons==giu)
 
  {
    if(SetPoint>0)
    {
      SetPoint--;   
    }
  }
  if(buttons==su)
  {
    if(SetPoint<2000)
    {
      SetPoint++;
    }
  }
 
//Display Set point on LCD
  lcd.setCursor(0,1);
  lcd.print("Set Point:");
  lcd.print(SetPoint);
  lcd.print("ppm   ");
 
 
 
 
  if(ppm > SetPoint) digitalWrite(RELAY,LOW);    //Turn off heat


     

else digitalWrite(RELAY,HIGH);    //Turn on heater
   

 
 
 
 
 
 
 
 
 
  Serial.println(ppm);

 
  Serial.println(th);
  Serial.println(ppm2);
  Serial.println(ppm3);
 
 
 if(buttons == dx)   digitalWrite(luce,LOW);
 


 
 else if(buttons == sx)  digitalWrite(luce,HIGH);
 
   
 

delay(100); //Update at every 100mSeconds

 
}


 


 ;)

zoomx

Per quello shield ci sono delle librerie apposite che gestiscono anche la pulsanteria.
Puoi usarle oppure vedere come agiscono.
Ad esempio
https://github.com/dzindra/LCDKeypad

megaciro

ho provato ad inserire questo:
Code: [Select]
int buttons = read_buttons();
  if (buttons != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    lastButtonState=buttons;

ma è peggio...
devo tenere premuto a lungo per far variare il valore.... come se ci fosse un ritardo alla lettura del pulsante o un ritardo ad eseguire il comando dopo aver premuto il pulsante....

megaciro

ho provato ad inserire un pulsante estero per comandare il set point, giusto per capire se fosse il lcd keypad a rompere ... ma fa lo stesso: a momente devo tenerlo premuto per 3 secondi prica che il valore cambi...
cosa può essere??

megaciro

ho provato anche questo codice
Code: [Select]

int button;   // Declares a fresh button variable
button = evaluateButton(readKey);

readKey = analogRead(0);            // Reads the analog signal from A0 and saves it to readKey
//if (readKey < 790) {                // If the signal drops below 790 that means a button was
                                    // pressed. The if statement delays the program for 100 microseconds
                                    // to debounce the button press and let voltage stabilize
  //delay(10);
  //readKey = analogRead(0);          // Once the voltage has stabilized read the signal again
//}
switch (button) {
      case 4:  // When button returns as 0
       digitalWrite(luce,LOW);
       
        break;
      case 1:  // When button returns as 1
        digitalWrite(luce,HIGH);
        break;     
      case 2:  // When button returns as 2
         if(SetPoint<2000){
      SetPoint++;}
       
        break;
      case 3:  // When button returns as 3
   if(SetPoint>0) {
      SetPoint--; };
       
        break;
 


funziona, come gli altri, ma il valore cambia dopo circa 1 secondo che ho premuto il pulsante.. :smiley-confuse:  :smiley-confuse:  :smiley-confuse:  :smiley-confuse:

megaciro

tutti i codici prova che inserisco sono reattivi, provo a modificarli mettendo quello che mi serve e ridiventa lento...

Standardoil

#37
Apr 28, 2019, 08:16 am Last Edit: Apr 28, 2019, 08:17 am by Standardoil
hai guardato sul datasheet del sensore quando tempo richiede una lettura?
che lettura fai in pwm?
Prima legge di Nelson (che sono io): Se vuoi il mio aiuto dimostrami almeno che hai letto il nostro "aiutateCi ad aiutarVi"

Non bado a studenti, che copino altrove

Tu hai problema-Io ti domando-Tu non mi rispondi: vuol dire che non ti serve più

megaciro

hai guardato sul datasheet del sensore quando tempo richiede una lettura?
che lettura fai in pwm?

Buongiorno  carissimo, grazie per l'interesse,  la lettura  la faccio sia in pwm che uart.
Dici che in pwm richiede più tempo per fare il calcolo perciò risponde piano... provo a togliere dal codice.

maubarzi

come si fa una lettura in pwm?
Nessuna buona azione resterà impunita!

Preistoria -> medioevo -> rinascimento -> risorgimento -> rincoglionimento!

megaciro

carissimi compagni di codice è con immenso piacere e smisurata soddisfazione che vi comunico l'esito positivo!!!
ebbene si tutto funziona come si deve!!
grazie al buon Standardoil che mi ha illuminato!!
hai guardato sul datasheet del sensore quando tempo richiede una lettura?
che lettura fai in pwm?

come si fa una lettura in pwm?
carissimo mauro nei codici che ho inoltrato trovi la lettura con pwm...
cmq è questa:
Code: [Select]
//CO2 via pwm
  do {
    th = pulseIn(pwmPin, HIGH, 1004000) / 1000;
    tl = 1004 - th;
    ppm2 = 2000 * (th-2)/(th+tl-4);
    ppm3 = 5000 * (th-2)/(th+tl-4);
  } while (th == 0);

maubarzi

Nessuna buona azione resterà impunita!

Preistoria -> medioevo -> rinascimento -> risorgimento -> rincoglionimento!

megaciro

Code: [Select]


String Str1[]={"ON"};
String Str2[]= {"OFF"};


statorele=digitalRead(RELAY);
if(statorele==1)statorele=Str1;
else statorele=Str2;

   lcd.print (" Stato Rele"); lcd.print("   "); lcd.print(statorele);lcd.print("  ");




ho riassunto un pochino il codice...
volevo chiedere come mai sul dispay lcd mi compare il numero anziche la scritta in base allo stato del relè??
ho provato pure con char...

Standardoil

non mi è chiaro come faccia ad andare, una cosa del genere
hai cgreato due variabili puntatore a stringa, inizializzato in una maniera fantasiosa, ma fantasiosa forte
ammenocche' non siano due array di Stringa, con un solo elemento, inizializzati a stringa costante
e le usi per assegnarle a una variabile che non sappiamo di che tipo sia, ma presumo bool o int
due domande:
ma compila, sta roba?
intendo sul serio, guarda bene cosa ti dice in compilazione, che magari imparo qualcosa di nuovo
comunque se compilasse e statorele fosse boolean forse qualcosa avviene, nel senso che Str1 ed Str2 sono nomi di array, quindi puntatori, che se non NULL, ovvero sono validi, vengono interpretati come true
quindi assegnano 1 alla variabile
dovrebbe uscirti sempre scritto "StatoRele   1"
ti torna?
metti il codcie completo, dai
Prima legge di Nelson (che sono io): Se vuoi il mio aiuto dimostrami almeno che hai letto il nostro "aiutateCi ad aiutarVi"

Non bado a studenti, che copino altrove

Tu hai problema-Io ti domando-Tu non mi rispondi: vuol dire che non ti serve più

megaciro

dovrebbe uscirti sempre scritto "StatoRele   1"
ti torna?
questo mi tornava... ma poi invece di leggere 1 volevo leggere on..

non mi è chiaro come faccia ad andare, una cosa del genere
hai cgreato due variabili puntatore a stringa, inizializzato in una maniera fantasiosa, ma fantasiosa forte
ammenocche' non siano due array di Stringa, con un solo elemento, inizializzati a stringa costante
e le usi per assegnarle a una variabile che non sappiamo di che tipo sia, ma presumo bool o int
due domande:
ma compila, sta roba?
intendo sul serio, guarda bene cosa ti dice in compilazione, che magari imparo qualcosa di nuovo
comunque se compilasse e statorele fosse boolean forse qualcosa avviene, nel senso che Str1 ed Str2 sono nomi di array, quindi puntatori, che se non NULL, ovvero sono validi, vengono interpretati come true

avevo scritto che era un riassunto..

metti il codcie completo, dai
eccolo
Code: [Select]
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>

#define pwmPin 11// pin pwm sensore



SoftwareSerial mySerial(A2, A1); // RX, TX

LiquidCrystal lcd(8, 9, 4, 5, 6,7);
byte schermatainiziale = 0;



byte cmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
unsigned char response[9];
unsigned long th, tl,ppm, ppm2, ppm3 = 0;
const int RELAY=12; //Lock Relay or motor

const int pulsante = 13 ;
int buttonState= LOW;            // the current reading from the input pin
int lastButtonState = 0;   // the previous reading from the input pin

boolean RS1 = false;
boolean RS2 = false;
boolean RSok = false;

long previousMillis = 0;
long interval = 6000;

unsigned long mymillis;
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 30;    // the debounce time; increase if the output flickers


int SetPoint=1000;
int luce=10;//luce display
int analogPin = A0;// pin dei pulsanti


int statorele     = 0;
int adc_key_in  = 0;

#define dx      0
#define su      1
#define giu     2
#define sx      3
#define SELECT  4
#define btnNONE 5
int val = 1;

int read_buttons() {
 
 int adc_key_in = analogRead(0);
 
 if (adc_key_in > 1000) return btnNONE;
 if (adc_key_in < 50)   return dx; 
 if (adc_key_in < 195)  return su;
 if (adc_key_in < 380)  return giu;
 if (adc_key_in < 555)  return sx;
 if (adc_key_in < 790)  return SELECT;   
}
char on[]= "ON" ;
char off[]= "OFF";


void setup() {
 Serial.begin(9600);

 

  // Initializes and clears the LCD screen
  lcd.begin(16, 2);
  lcd.clear();

  mySerial.begin(9600);
 
  pinMode(pwmPin, INPUT);
  pinMode(luce,OUTPUT);
  pinMode(RELAY,OUTPUT);
  pinMode (pulsante,INPUT);
 
  //digitalWrite(su,LOW);
  //digitalWrite(giu,LOW);
digitalWrite(RELAY,LOW);   
digitalWrite(luce,HIGH);

lcd.clear();
lcd.setCursor (0,0);
lcd.print( "CONTROLLORE CO2");
lcd.setCursor(0,1) ;
lcd.print( "CIRO MATACENA" );

delay(1000);

lcd.clear();
lcd.setCursor(0,0);
lcd.print("PRERISCALDAMENTO");
lcd.setCursor(0,1) ;
lcd.print( "SENSORE CO2");

delay(1000);
lcd.clear();

}


void loop() {
if (millis() - previousMillis > 30000 & schermatainiziale == 0) {lcd.clear(); lcd.home(); schermatainiziale = 1;}
statorele=digitalRead(RELAY);
if(statorele==1)statorele=on;
else statorele=off;

 
 
 
 
 
 if (millis()- previousMillis < interval){
  lcd.setCursor(0,0);
  lcd.print(" Inizializzazione "); // viene eseguita una sola volta
  lcd.setCursor(1,2);
  lcd.print("Elapse Time : ");
  lcd.print(millis()/1000.0);
 
  RS1 = true; // Suggerimento Orso2001 indispensabile per la commutazione
  delay(2000);
  }
 
lcd.setCursor(0,0);
lcd.print("CO2:");
lcd.print(ppm  );lcd.print(" ");
lcd.print("ppm");
lcd.setCursor(0,1);
lcd.print("SetPoint:");
lcd.print(SetPoint);
lcd.print("ppm   ");
  //**deve entrare in loop da questo punto commutando 2 e 3 schermata senza interferire a livello di delay
  //con la lettura di vari sensori presenti nel programma esteso, codice omesso per brevità.
 
  if (millis()- previousMillis >interval) {
   
     

  if (RS1 == true && RSok == false) {
    //disegna seconda schermata
     lcd.setCursor(0,1);
     lcd.print (" Stato Rele"); lcd.print("   "); lcd.print(statorele);lcd.print("  ");
delay(2000);
 
    RSok = true;
    mymillis = millis();
  }
 if (RS2 == true && RSok == false) {
    //disegna terza schermata
   

   
    RSok = true;
    mymillis = millis();
  } 
  if (millis() - mymillis >= 8000) { //ogni 4 secondi eseguo....
    RS1 = !RS1;
    RS2 = !RS2;
    RSok = false;
    }
}



 
 int buttons = read_buttons();
// buttonState= digitalRead(pulsante);

 /*if(Serial.available()){
    char comando = Serial.read();

   if(comando == 'a'){
      digitalWrite(RELAY, HIGH);
     Serial.println("LED acceso");
    }
    else if(comando == 's'){
      digitalWrite(RELAY, LOW);
      Serial.println("LED spento");
    }
    else{
   Serial.println("Comando non riconosciuto");
    }
 
  //delay(10);
}
/*

 /*if (buttons != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    lastButtonState=buttons;

    }*/
  mySerial.write(cmd,9);
  mySerial.readBytes(response, 9);
  unsigned int responseHigh = (unsigned int) response[2];
  unsigned int responseLow = (unsigned int) response[3];
  ppm = (256*responseHigh)+responseLow;


  //CO2 via pwm
//do {
  //  th = pulseIn(pwmPin, HIGH, 1004000) / 1000;
 //   tl = 1004 - th;
 //   ppm2 = 2000 * (th-2)/(th+tl-4);
  //  ppm3 = 5000 * (th-2)/(th+tl-4);
//  } while (th == 0);

 
 
 
 
 
if(ppm > SetPoint){
   digitalWrite(RELAY,LOW);
    }
else digitalWrite(RELAY,HIGH);    //Turn on heater
   

 
   
 
  if(buttons==giu)
  //if(buttonState==HIGH)
  {
    if(SetPoint>0)
    {
      SetPoint--;   
    }
  }
  if(buttons==su)
  {
    if(SetPoint<2000)
    {
      SetPoint= SetPoint+val;
    }
  }
 
 
 
 
 
 
 
 
  Serial.println(ppm);

 
  Serial.println(th);
  Serial.println(ppm2);
  Serial.println(ppm3);
 
 
 if(buttons == dx)   digitalWrite(luce,LOW);
 


 
 else if(buttons == sx)  digitalWrite(luce,HIGH);
 
   
 

delay(100); //Update at every 100mSeconds

 
}


 

 

Go Up