[Risolto] Non posso comandare LED esterno

Buongiorno a tutti,
sto costruendo un datalogger umidità e temperatura con Arduino UNO R3.
Il datalogger è composto da:

  • DHT22 sensore umidità e temperatura
  • Modulo shield RTC DS1307 + SD integrato (vi allego la scheda di questo prodotto)
  • Display OLED 128x64 U8G2

dopo un po' di peripezie per risparmiare qualche byte, il datalogger funziona correttamente, ho messo anche un minimo di gestione errori con allarme inviato al monitor seriale per valori RH e T fuori un dato limite.

ora vorrei sostituire l'avviso del monitor seriale con l'accensione di un LED.
ho installato il LED al PIN 12 con una resistenza da 10K.

sono quasi sicuro che il codice sia corretto perché il monitor seriale mi da gli output che mi aspetto e solo quando dovrebbe, tuttavia il led rimane sempre acceso anche se i valori non sono fuori range.

nel dubbio che fosse un problema HW, ho testato il led ed il circuito con uno dei mille skecth blinking che si trovano in rete e funziona esattamente come dovrebbe.

Mi potete aiutare? ecco il codice.

Gigi

/*
 * Temprature & Humidity Data Logger 
 * using DHT22, 0.96 OLED Display, RTC DS1307, SD Card & Led alarm
 * 
 * 
 * Luigi Bensoni May 2020
 * 
 */

#include <Arduino.h>
#include <U8x8lib.h>
//#include <u8g2lib.h>
#include "DHT.h"
#include "RTClib.h"
#include <SPI.h>
#include <SD.h>
#include <Wire.h>

#define LED 13
#define DHTPIN 2     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)
DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 rtc;
const int chipSelect = 10;
int ledPin = 12; //SOSTITUIRE CON DIGITAL PIN UTILIZZATO PER LED ESTERNO
//int ledState = 0;
int hAlmMax = 60;
int tAlmMin = 20;
unsigned long previousMillis = 0; //will store last time LED was updated
unsigned long interval = 20000; //interval at which to blink (milliseconds)


  U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8( /* reset=*/ U8X8_PIN_NONE);

void setup(void) {
  pinMode(ledPin, OUTPUT);
  digitalWrite(LED, LOW);
  dht.begin();
  delay(2000);
  u8x8.begin();  
  Serial.begin(57600);
  while (!Serial); // for Leonardo/Micro/Zero
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  Serial.print("Initializing SD card...");
  if (! SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
  
  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    //digitalWrite(LED, HIGH);
    }
    Serial.println("RTC running.");

  
// following line sets the RTC to the date & time this sketch was compiled
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
//Serial.println("RTC set to the date & time this sketch was compiled");
}

void memorizza() {
  //unsigned long time; 
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  delay(2000);
  String StrDati= "";
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    DateTime now = rtc.now();
    StrDati += (now.day()); // + '/' + (now.month()) + '/' + (now.year()) + ';' + (now.hour()) + ':' + (now.minute()) + ';' + t + ';' + "°C;" + h + "%RH;";
    StrDati += ('/');
    StrDati += (now.month());
    StrDati += ('/');
    StrDati += (now.year());
    StrDati += ";";
    StrDati += (now.hour());
    StrDati += (':');
    StrDati += (now.minute());
    StrDati += ";";
    StrDati += t;
    StrDati += " DEG C;";
    StrDati += h;
    StrDati += "%RH;";
    Serial.println(StrDati);

    //delay(1000);
    
    File dataFile = SD.open("THLog.csv", FILE_WRITE);
    if (dataFile) {
      dataFile.println(StrDati);
      dataFile.close();
      }
//  if the file isn't open, pop up an error:
    else {
      Serial.println("Err open THLog.csv");
    }
  }
}

void draw() {
  float h = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit
  delay(2000);
  DateTime now = rtc.now();
  u8x8.setFont(u8x8_font_7x14B_1x2_r);
  u8x8.setCursor(0, 0);
  u8x8.print(now.day(), DEC);
  u8x8.print('/');
  u8x8.print(now.month(), DEC);
  u8x8.print('/');
  u8x8.print(now.year(), DEC);
  u8x8.print(" ");
  u8x8.print(now.hour(), DEC);
  u8x8.print(':');
  u8x8.print(now.minute(), DEC);
  //u8x8.print(")");
    
  u8x8.setFont(u8x8_font_8x13B_1x2_r);
  u8x8.setCursor(0, 3);
  u8x8.print("T= "); u8x8.print(t); u8x8.print(" DEG.C");
  u8x8.setCursor(0, 6);
  u8x8.print("RH= "); u8x8.print(h); u8x8.print("%");

 //digitalWrite(LED, LOW);
 if (hAlmMax<h || tAlmMin>t){
      //ledState ^= 1;
      digitalWrite(ledPin, HIGH);   // accende il led (presente su arduino @ PIN 12) su allarme environment out of range
      Serial.println("Environment parameters out of range");
 }
digitalWrite(ledPin, LOW);
  
}

void loop() {
    memorizza();
    draw();
}

DatenLogger_Englisch.pdf (437 KB)

Benvenuto,
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 tutto il su citato REGOLAMENTO ... Grazie. :slight_smile:

nid69ita

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione, nessuno ti potrà rispondere, quindi ti consiglio di farla al più presto. :wink:

La risposta è semplice, ma attendiamo la tua presentazione.
Benvenuto! :slight_smile:

Come lo hai collegato il led?
A naso direi con la resistenza verso Vcc, giusto?

Ad un certo punto scrivi:

if (hAlmMax<h || tAlmMin>t){
  //ledState ^= 1;
  digitalWrite(ledPin, HIGH);   // accende il led (presente su arduino @ PIN 12) su allarme environment out of range
  Serial.println("Environment parameters out of range");
}
digitalWrite(ledPin, LOW);

Praticamente tieni sempre l'uscita a LOW tranne quando entra nell'IF, ma in quel caso va HIGH per pochissimo, il tempo di scrivere sulla seriale e poi torna LOW.

Quindi, se dici che il led resta sempre acceso, significa che si accende quando l'uscita è LOW e quindi l'altro pin è verso Vcc con la resistenza.

EDIT: Mi sono espresso da cani, ma spero si sia capito.

Maurizio

maubarzi:
Come lo hai collegato il led?
A naso direi con la resistenza verso Vcc, giusto?

Beh io direi di iniziare da questo:

ho installato il LED al PIN 12 con una resistenza da 10K.

Che dici, 10k Ohm non sono un pochino troppe per un led? :wink:

@benso80, la resistenza la devi mettere da 220 Ohm, in serie al led, e quindi il tutto a GND.

Se il led fosse stato collegato così, sarebbe risultato sempre spendo :wink: tranne un micro lampeggio.
Poi, una resistenza da 10K ci potrebbe anche stare se l'intento è di avere poca luminosità e non abbagliare.
In un ambiente scuro si dovrebbe vedere benone lo stesso.

Comunque, si, hai perfettamente ragione quando dici:

docdoc:
Beh io direi di iniziare da questo:...

cioè da come è stato collegato effettivamente il led.
Il valore della resistenza che indichi tu, è perfetto, ma non penso sia il nocciolo della questione.

Poi, smarcato questo e dopo aver individuato il problema, ci sarebbe il discorso delle String... :stuck_out_tongue: ma ce lo teniamo come dolce alla fine :wink:

Maurizio

All'interno di draw{} non c'è un digitalWrite(ledPin, LOW);. Lo vedo fuori, ma non è nemmeno nel loop{}!

maubarzi:
Se il led fosse stato collegato così, sarebbe risultato sempre spendo :wink: tranne un micro lampeggio.
Poi, una resistenza da 10K ci potrebbe anche stare se l'intento è di avere poca luminosità e non abbagliare.
In un ambiente scuro si dovrebbe vedere benone lo stesso.

Comunque, si, hai perfettamente ragione quando dici:

cioè da come è stato collegato effettivamente il led.
Il valore della resistenza che indichi tu, è perfetto, ma non penso sia il nocciolo della questione.

Poi, smarcato questo e dopo aver individuato il problema, ci sarebbe il discorso delle String... :stuck_out_tongue: ma ce lo teniamo come dolce alla fine :wink:

Maurizio

Buona sera a tutti,
portate pazienza... sono proprio alle prime armi.
Ho collegato il pin lungo (+) del led al pin 12, poi il pin corto (-) ad una resistenza da 220 Ohm (accettando il buon suggerimento circa il valore della resistenza... 10 k era un po' esagerato come giustamente suggerito) e poi l'altro capo della resistenza al GND di arduino.

Ora ho un led più brillante, ma comunque sempre acceso.

Ho rivisto un pochino il codice, aggiungendo un else dopo l'IF di verifica delle variabili... ma non cambia nulla.

#include <Arduino.h>
#include <U8x8lib.h>
//#include <u8g2lib.h>
#include "DHT.h"
#include "RTClib.h"
#include <SPI.h>
#include <SD.h>
#include <Wire.h>

#define LED 13
#define DHTPIN 2     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)
DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 rtc;
const int chipSelect = 10;
int ledPin = 12; //SOSTITUIRE CON DIGITAL PIN UTILIZZATO PER LED ESTERNO
int hAlmMax = 80;
int tAlmMin = 20;
unsigned long previousMillis = 0; //will store last time LED was updated
unsigned long interval = 20000; //interval at which to blink (milliseconds)


  U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8( /* reset=*/ U8X8_PIN_NONE);

void setup(void) {
  pinMode(ledPin, OUTPUT);
  dht.begin();
  delay(2000);
  u8x8.begin();  
  Serial.begin(57600);
  while (!Serial); // for Leonardo/Micro/Zero
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  Serial.print("Initializing SD card...");
  if (! SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
  
  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    }
    Serial.println("RTC running.");

  
// following line sets the RTC to the date & time this sketch was compiled
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
//Serial.println("RTC set to the date & time this sketch was compiled");
}

void memorizza() {
  //unsigned long time; 
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  delay(2000);
  String StrDati= "";
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    DateTime now = rtc.now();
    StrDati += (now.day()); // + '/' + (now.month()) + '/' + (now.year()) + ';' + (now.hour()) + ':' + (now.minute()) + ';' + t + ';' + "°C;" + h + "%RH;";
    StrDati += ('/');
    StrDati += (now.month());
    StrDati += ('/');
    StrDati += (now.year());
    StrDati += ";";
    StrDati += (now.hour());
    StrDati += (':');
    StrDati += (now.minute());
    StrDati += ";";
    StrDati += t;
    StrDati += " DEG C;";
    StrDati += h;
    StrDati += "%RH;";
    Serial.println(StrDati);

    //delay(1000);
    
    File dataFile = SD.open("THLog.csv", FILE_WRITE);
    if (dataFile) {
      dataFile.println(StrDati);
      dataFile.close();
      }
//  if the file isn't open, pop up an error:
    else {
      Serial.println("Err open THLog.csv");
    }
  }
}

void draw() {
  float h = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit
  digitalWrite(ledPin, LOW);
  delay(2000);
  DateTime now = rtc.now();
  u8x8.setFont(u8x8_font_7x14B_1x2_r);
  u8x8.setCursor(0, 0);
  u8x8.print(now.day(), DEC);
  u8x8.print('/');
  u8x8.print(now.month(), DEC);
  u8x8.print('/');
  u8x8.print(now.year(), DEC);
  u8x8.print(" ");
  u8x8.print(now.hour(), DEC);
  u8x8.print(':');
  u8x8.print(now.minute(), DEC);
  //u8x8.print(")");
    
  u8x8.setFont(u8x8_font_8x13B_1x2_r);
  u8x8.setCursor(0, 3);
  u8x8.print("T= "); u8x8.print(t); u8x8.print(" DEG.C");
  u8x8.setCursor(0, 6);
  u8x8.print("RH= "); u8x8.print(h); u8x8.print("%");

  if (h > hAlmMax || t < tAlmMin){
      digitalWrite(ledPin, HIGH);   // accende il led (presente su arduino @ PIN 12) su allarme environment out of range
      Serial.println("Environment parameters out of range");
  }
  else {
      digitalWrite(ledPin, LOW);
    }

  
}

void loop() {
    memorizza();
    draw();
}

Nella versione precedente la resistenza era tra il PIN 12 ed il pin lungo del LED.

Non capisco dove sbaglio.

Ciao e grazie.

Gigi

Datman:
All'interno di draw{} non c'è un digitalWrite(ledPin, LOW);. Lo vedo fuori, ma non è nemmeno nel loop{}!

Ciao,
nell'ultima versione l'ho messo nel draw() molto a monte rispetto alla condizione IF, prova a vedere il post precedente.

Grazie.

Sì, hai ragione. Infatti ho cancellato il messaggio. Non avevo visto bene l'allineamento delle graffe e mi era sembrato fuori.

La libreria SD utilizza SPI per comunicare col arduino. Quindi i pin 11 12 e 13

savoriano:
La libreria SD utilizza SPI per comunicare col arduino. Quindi i pin 11 12 e 13

Grazie Savoriano!
spostato al pin 9 e funziona come dovrebbe!

Buona serata a tutti!