Vai al contenuto
PLC Forum


Arduino e relè SSR


Robe60

Messaggi consigliati

Ciao a tutti, sto realizzando un piccolo circuito costituito da un Arduino UNO, un sensore di umidità dht11, un relè ssr25da e da un display LCD ed un umidificatore.

In pratica , impostato un certo valore di umidità , si vuole che Arduino tramite SSR avvii l'umidificatore se il valore rilevato è inferiore, oppure spenga  nel caso il valore venga superato.

Con lo sketch che ho realizzato non riesco ad attivare l'SSR.

Chiedo se possibile postare lo sketch che utilizzo per avere dei pareri/consigli o meglio ancora, una soluzione.

Grazie e buona giornata!
 

Link al commento
Condividi su altri siti



Tu posta il codice dentro ai TAG code quello con il simbolo <>, poi qualcuno magari si occuperà di analizzare lo sketch...

 

ESEMPIO selezionando il linguaggio C:

 

#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

void setup() {
      // initialize serial communications at 9600 bps:
      Serial.begin(9600);
      // set up the LCD's number of columns and rows:
      lcd.begin(16, 2);
      lcd.print ("    ...");
}

void loop() {
    ...
}

 

Link al commento
Condividi su altri siti

#include <LiquidCrystal_I2C.h>
#include <dht11.h>
dht11 DHT;
#define DHT11_PIN 4
LiquidCrystal_I2C lcd(0x27,20,4);
int rele = 11;

void setup(){
  Serial.begin(9600);
  lcd.begin();
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.println("Hum(%), Temp(C)");
}

void loop(){
  int chk;
 // Serial.print("DHT11, \t");
  chk = DHT.read(DHT11_PIN);    // READ DATA
  switch (chk){
    case DHTLIB_OK:  
                Serial.print("OK,\t"); 
                break;
    case DHTLIB_ERROR_CHECKSUM: 
                Serial.print("Checksum error,\t"); 
                break;
    case DHTLIB_ERROR_TIMEOUT: 
                Serial.print("Time out error,\t"); 
                break;
    default: 
                Serial.print("Unknown error,\t"); 
                break;
  }
  
  //comandi relè
  digitalRead(DHT.humidity);
  if(DHT.humidity > 82) digitalWrite(rele, LOW);
  if(DHT.humidity < 78) digitalWrite(rele, HIGH);
                       
 // DISPLAY DATA
 lcd.setCursor(0,1);
  lcd.print(DHT.humidity,1);
 // lcd.print(",\t");
  lcd.setCursor(8,1);
  lcd.println(DHT.temperature,1);

  delay(1000);
}

Grazie GiRock , questo è lo sketch.

Link al commento
Condividi su altri siti

1 ora fa, ilguargua scrisse:

Così a prima vista direi che intanto manca un pinMode(rele,OUTPUT) nel setup.

 

Ciao, Ale.

Non ho parole.................Grazie!

Ammetto che i pinMode me li scordo regolarmente.........ed infatti così funziona.

 

Ora ho aggiunto 4 pulsanti per impostare i valori di umidità max e min .

Questi due parametri vengono confrontati con quello rilevato dal sensore e tramite due condizioni "IF" avviene il controllo del relè.

Di seguito riporto lo sketch completo.

#include <LiquidCrystal_I2C.h>
#include <dht11.h>
dht11 DHT;
#define DHT11_PIN 4
LiquidCrystal_I2C lcd(0x27,20,4);

int rele = 11;

int p1 = 5, p2 = 6;   /*pulsanti per umidità max (+/-)*/  int leggo_p1 = 0, leggo_p2 = 0;  int umi_max = 0;
int p3 = 7, p4 = 8;   /*pulsanti per umidità min (+/-)*/  int leggo_p3 = 0, leggo_p4 = 0;  int umi_min = 0; 

void setup(){
  pinMode(rele, OUTPUT);

  pinMode(p1, INPUT);
  pinMode(p2, INPUT);
  pinMode(p3, INPUT);
  pinMode(p4, INPUT);

//stampa su lcd
  Serial.begin(9600);
  lcd.begin();
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.println("Hum(%), Temp(C)");
  
  //umidità max e min impostata
  lcd.setCursor(0,2);
  lcd.println("h_max");
  lcd.setCursor(8,2);
  lcd.println("h_min");
//  
}

void loop(){
  //controllo e lettura dati
  int chk;
   chk = DHT.read(DHT11_PIN);    // READ DATA
  switch (chk){
    case DHTLIB_OK:  
                Serial.print("OK,\t"); 
                break;
    case DHTLIB_ERROR_CHECKSUM: 
                Serial.print("Checksum error,\t"); 
                break;
    case DHTLIB_ERROR_TIMEOUT: 
                Serial.print("Time out error,\t"); 
                break;
    default: 
                Serial.print("Unknown error,\t"); 
                break;
  }

/******************************************************************/

  //settaggio dati:
    //umidità max
  leggo_p1 = digitalRead(p1);
  if (leggo_p1 == 1) {umi_max = umi_max + 1; delay(150);}

  leggo_p2 = digitalRead(p2);
  if (leggo_p2 == 1) {umi_max = umi_max - 1; delay(150);}

    //umidità min
  leggo_p3 = digitalRead(p3);
  if (leggo_p3 == 1) {umi_min = umi_min + 1; delay(150);}

  leggo_p4 = digitalRead(p4);
  if (leggo_p4 == 1) {umi_min = umi_min - 1; delay(150);}

/******************************************************************/

  //comandi relè
   digitalRead(umi_max);
  if(DHT.humidity > umi_max) digitalWrite(rele, LOW);
   digitalRead(umi_min);
  if(DHT.humidity < umi_min) digitalWrite(rele, HIGH);

/******************************************************************/
  
 // DISPLAY DATA
 lcd.setCursor(0,1);
  lcd.print(DHT.humidity,1);
  lcd.setCursor(8,1);
  lcd.println(DHT.temperature,1);

  //umidità max e min impostata
  lcd.setCursor(0,3);
  lcd.println(umi_max);
  lcd.setCursor(8,3);
  lcd.println(umi_min);
  
/******************************************************************/
  
  delay(500);
}

In conclusione ci sono 2 difetti:

1) Sul display Lcd appaiono dei simboli (righe orizzontali) a fianco dei numeri riportati.

2) Alla pressione dei pulsanti non si ha una immediata risposta a video. 

Questo secondo problema è  il meno grave, dato che ho utilizzato la funzione delay(), preferirei eliminare le righe che appaiono a video.

Grazie ancora. 

  

Link al commento
Condividi su altri siti

18 minuti fa, Robe60 scrisse:

Sul display Lcd appaiono dei simboli (righe orizzontali) a fianco dei numeri riportati.

 

Prima di scrivere sul display devi "pulirlo" in modo che nei caratteri non usati non compaia alcunchè.

 

20 minuti fa, Robe60 scrisse:

Alla pressione dei pulsanti non si ha una immediata risposta a video

 

Andrebbe riorganizzato tutto il programmino.

Come prima cosa non si dovrebbero usare le funzioni "delay" perchè sono bloccanti. In genere i tempi si fanno con un interrupt su timer. Io uso timer1 proprio allo scopo e scedulo i vari tasks su questo.

Link al commento
Condividi su altri siti

20 minuti fa, Robe60 scrisse:

digitalRead(umi_max); 

digitalRead(umi_min);

 

Qui mi sa che quel che accade non è quello che intendi : umi_max e umi_min dovrebbero essere valori di umidità, che senso ha leggerli come ingressi con  digitalRead()??

Per quanto riguarda il display, prova con un lcd.clear() prima di scrivere, e chiaramente riscrivi tutto. Poi cerca di aggiornare il display solo quando è necessario, cioè se qualche valore è cambiato. Non è la soluzione ottimale (intendo quella del clear()), meglio sarebbe usare un buffer che contenga tutta la riga, scriverci il contenuto e poi scriverlo sul display, sempre se va aggiornato. Il ritardo dei pulsanti è dovuto al quel delay(500) alla fine del loop, ma questo già lo sai.

 

Ciao, Ale.

Link al commento
Condividi su altri siti

Solitamente le righe sui display non sono solo causate da una scrittura incorretta, a me è capitato alcune volte che in maniera random si formassero da sole, ho dovuto filtrare e stabilizzare per benino l'alimentazione con alcuni condensatori e bloccare per bene i cavetti soprattutto se si utilizza la breadboard...

 

Puoi fare così per dare priorità ai pulsanti, io però farei il debounce hardware e toglierei i delay:

 

#include <LiquidCrystal_I2C.h>
#include <dht11.h>
dht11 DHT;
#define DHT11_PIN 4
LiquidCrystal_I2C lcd(0x27,20,4);

int rele = 11;

int p1 = 5, p2 = 6;   /*pulsanti per umidità max (+/-)*/  int leggo_p1 = 0, leggo_p2 = 0;  int umi_max = 0;
int p3 = 7, p4 = 8;   /*pulsanti per umidità min (+/-)*/  int leggo_p3 = 0, leggo_p4 = 0;  int umi_min = 0; 

unsigned long TimeLapse = 0;
const unsigned long DELAYTIME = 1000; 


void DisplayData() {

  // DISPLAY DATA

  lcd.setCursor(0,1);
  lcd.print(DHT.humidity,1);
  lcd.setCursor(8,1);
  lcd.println(DHT.temperature,1);

  //umidità max e min impostata
  lcd.setCursor(0,3);
  lcd.println(umi_max);
  lcd.setCursor(8,3);
  lcd.println(umi_min);

  TimeLapse = millis();

}

void setup(){
  pinMode(rele, OUTPUT);

  pinMode(p1, INPUT);
  pinMode(p2, INPUT);
  pinMode(p3, INPUT);
  pinMode(p4, INPUT);

//stampa su lcd
  Serial.begin(9600);
  lcd.begin();
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.println("Hum(%), Temp(C)");
  
  //umidità max e min impostata
  lcd.setCursor(0,2);
  lcd.println("h_max");
  lcd.setCursor(8,2);
  lcd.println("h_min");
  
  DisplayData();
//  
}

void loop(){
  //controllo e lettura dati
  int chk;
   chk = DHT.read(DHT11_PIN);    // READ DATA
  switch (chk){
    case DHTLIB_OK:  
                Serial.print("OK,\t"); 
                break;
    case DHTLIB_ERROR_CHECKSUM: 
                Serial.print("Checksum error,\t"); 
                break;
    case DHTLIB_ERROR_TIMEOUT: 
                Serial.print("Time out error,\t"); 
                break;
    default: 
                Serial.print("Unknown error,\t"); 
                break;
  }

/******************************************************************/

  //settaggio dati:
    //umidità max
  leggo_p1 = digitalRead(p1);
  if (leggo_p1 == 1) {umi_max = umi_max + 1; delay(150);}

  leggo_p2 = digitalRead(p2);
  if (leggo_p2 == 1) {umi_max = umi_max - 1; delay(150);}

    //umidità min
  leggo_p3 = digitalRead(p3);
  if (leggo_p3 == 1) {umi_min = umi_min + 1; delay(150);}

  leggo_p4 = digitalRead(p4);
  if (leggo_p4 == 1) {umi_min = umi_min - 1; delay(150);}

/******************************************************************/

  //comandi relè
  // digitalRead(umi_max); ???
  if(DHT.humidity > umi_max) digitalWrite(rele, LOW);
  // digitalRead(umi_min); ???
  if(DHT.humidity < umi_min) digitalWrite(rele, HIGH);

/******************************************************************/
  

  // Legge ogni secondo senza delay
  if ((millis() - TimeLapse) > DELAYTIME) {
    DisplayData();
  }

}

 

 

Link al commento
Condividi su altri siti

Ho fatto una versione migliorata del codice, questo permette che ad ogni pressione dei pulsanti ci sia una visualizzazione quasi immediata dei valori, inoltre ho aggiunto alcuni valori che non erano presenti nella versione iniziale, così come il controllo della somma o della sottrazione, il DHT11 ha un intervallo di misura dal 20% al 90% di umidità, etc.. (vedi codice):

 

#include <LiquidCrystal_I2C.h>
#include <dht11.h>

#define DHT11_PIN 4
#define RELE 11
#define BUTTON1 5 // + Max
#define BUTTON2 6 // - Max
#define BUTTON3 7 // + Min
#define BUTTON4 8 // - Min
#define MIN_HUM 20 // Minimum Humidity Percentage DHT11
#define MAX_HUM 90 // Maximum Humidity Percentage DHT11
#define VALGAP  4  // Minimum Histereyis value between MIN and MAX

LiquidCrystal_I2C lcd(0x38, 16, 2); // My Dipslay Address 0x38 - 16x2

unsigned long TimeLapse;
const unsigned long DELAYTIME = 1000;

int chk;

dht11 DHT;

/*pulsanti per umidità max (+/-)*/ 
int leggo_p1 = 0, leggo_p2 = 0;  int umi_max = 82; // set max default
/*pulsanti per umidità min (+/-)*/  
int leggo_p3 = 0, leggo_p4 = 0;  int umi_min = 78; // set min default

void DisplayDHTData() {

  // DISPLAY DATA

  lcd.setCursor(1,1);
  lcd.print(DHT.humidity,1);
  lcd.setCursor(5,1);
  lcd.println(DHT.temperature,1);

  //umidità max e min impostata
  lcd.setCursor(10,1);
  lcd.println(umi_max);
  lcd.setCursor(14,1);
  lcd.println(umi_min);

  TimeLapse = millis();

}

void setup() {
  Serial.begin(9600);
  pinMode(RELE, OUTPUT);
  pinMode(BUTTON1, INPUT);
  pinMode(BUTTON2, INPUT);
  pinMode(BUTTON3, INPUT);
  pinMode(BUTTON4, INPUT);
  while (DHT.read(DHT11_PIN) != DHTLIB_OK); // check if DHT Module is running and wait data
  lcd.begin();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.println("H-% T-C  HMx HMn");
  DisplayDHTData();
}

void loop() {
bool buttonOK = false;
 
/******************************************************************/

  //settaggio dati:
  //umidità max
  leggo_p1 = digitalRead(BUTTON1);
  if (leggo_p1 == 0) {umi_max = (umi_max < MAX_HUM ? umi_max+=1 : MAX_HUM); delay(150); buttonOK = true;}

  leggo_p2 = digitalRead(BUTTON2);
  if (leggo_p2 == 0) {umi_max = (umi_max > MIN_HUM + VALGAP ? umi_max-=1 : MIN_HUM + VALGAP); delay(150); buttonOK = true;}

  //umidità min
  leggo_p3 = digitalRead(BUTTON3);
  if (leggo_p3 == 0) {umi_min = (umi_min < MAX_HUM - VALGAP ? umi_min+=1 : MAX_HUM - VALGAP); delay(150); buttonOK = true;}

  leggo_p4 = digitalRead(BUTTON4);
  if (leggo_p4 == 0) {umi_min = (umi_min > MIN_HUM ? umi_min-=1 : MIN_HUM); delay(150); buttonOK = true;}

  if (umi_min >= umi_max) {umi_min = umi_max - VALGAP;}

/******************************************************************/

  // Read every second without using delay function
  if (((millis() - TimeLapse) > DELAYTIME) || buttonOK == true) { // buttonOK == true bypass the DELAYTIME
    chk = DHT.read(DHT11_PIN);    // READ DHT11 DATA
    //while (!Serial.available()); // it doesn't work for me (???), program locked here
    Serial.print("DHT11,\t");
    switch (chk) {
      case DHTLIB_OK:
        Serial.print("OK\r\n");
        break;
      case DHTLIB_ERROR_CHECKSUM:
        Serial.print("Checksum error\r\n");
        break;
      case DHTLIB_ERROR_TIMEOUT:
        Serial.print("Time out error\r\n");
        break;
      default:
        Serial.print("Unknown error\r\n");
        break;
    }
    //comandi relè
    if (chk == DHTLIB_OK) { // only if DHT11 do not return an error
      if (DHT.humidity > umi_max) digitalWrite(RELE, LOW);
      if (DHT.humidity < umi_min) digitalWrite(RELE, HIGH);
      DisplayDHTData();
    }
  }

}

P.S. L'ho testato e funziona bene, ad ogni modo è sempre migliorabile...

Link al commento
Condividi su altri siti

7 ore fa, GiRock scrisse:

if (leggo_p1 == 0)

E' invertita la logica dei pulsanti (in meglio direi), a questo punto però meglio usare INPUT_PULLUP nel pinMode(), e sopratutto collegare i pulsanti di conseguenza. Tra l'altro sarebbe utile vedere anche lo schema, ma l'OP sembra volatilizzato...

 

Ciao, Ale.

Link al commento
Condividi su altri siti

Vero :thumb_yello:, ho invertito la logica e le pullup sono esterne sui pulsanti (mi sono dimenticato di segnalarlo), quindi niente codice...

 

P.S. Pare una moda degli ultimi anni chiedere e volatilizzarsi, attendiamo che il diretto interessato ci degni almeno di uno sguardo...:roflmao:

Link al commento
Condividi su altri siti

1 ora fa, GiRock scrisse:

Pare una moda degli ultimi anni chiedere e volatilizzarsi,

A casa mia si chiama in un tutt'altro modo , ed è sempre esistito , ma non credo sia questo il caso ...vedrette .:thumb_yello:

Link al commento
Condividi su altri siti

Salve,

posso chiedervi gentilmente di specificare come poter progettare**********

 

********* N. d. M. *******

Non ci si può accodare ad una discussione, devi aprirne un'altra per non creare confusione nelle risposte.

Link al commento
Condividi su altri siti

 

No dai non mi sono volatilizzato, semplicemente siamo stati impegnati con un'altro problemino....una stampante 3d che fa i capricci, e quindi avevamo focalizzato l'attenzione su di essa.

 

Però voglio proprio ringraziarvi del supporto alla risoluzione del problema ed al suo miglioramento.

 

@GiRock  grazie . Entro domani credo di poter riuscire a testare il tuo sketch , poi ti saprò dire al riguardo.

 

 

 

 

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...