Progetto di datalogger arduino con aggiunta di shield relè comandati da sensori

Salve a tutti, ho un problema con lo sketch per gestire quanto in oggetto.
Lo sketch funziona in tutto e per tutto, si tratta di un datalogger che registra temperatura e umidità rilevati da un sensore DHT11 ad un determinato intervallo di tempo, fin qui tutto ok. Dovendo poi aggiungere una funzione di comando di alcune apparecchiature in base alle condizioni di umidità e temperatura ho aggiunto uno shield da 4 relè. Sono riuscito ad implementare le funzioni che desideravo, l’unico problema è che i 4 relè ogni secondo effettuano un doppio cambio di stato istantaneo, per poi comunque eseguire le funzioni relative a umidità e temperatura da me programmate.

Qualcuno ha idea del perchè i relè continuino a scattare? Io pensavo ad un problema di ciclo dello shield orologio RTC ma anche cercando di escludere i relè da quel ciclo il “tic tac” ogni secondo avviene comunque.

Allego lo sketch, ringrazio anticipatamente chiunque mi possa dare una mano.

Datalogger + Relè.ino (4.21 KB)

Non trovo nello sketch le istruzioni per i relè.

Ops…sbagliato file :o

qui c’è quello “corretto”

Programma-con-rele.ino (5.27 KB)

C’erano alcuni errori.

#include <Wire.h>
#include "RTClib.h"
#include <SD.h>
#include <dht11.h>
#include <LiquidCrystal.h>

#define CS 10
#define DHT11_PIN  15
#define BUTTON     A0
#define relePin1    2
#define relePin2    3

int SELECT[] = {
  720, 760};
int LEFT[] = {
  480, 520};
int RIGTH[] = {
  0, 20};
int UP[] = {
  120, 160};
int DOWN[] = {
  300, 350};

RTC_DS1307 RTC;
dht11 DHT;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
char buffer[50];
char lcdBuffer[16];

File myFile;

void setup () {
  Serial.begin(57600);
  Serial.print("Initializing SD card...");
  pinMode(CS, OUTPUT);
  pinMode(relePin1, OUTPUT);
  pinMode(relePin2, OUTPUT);
  pinMode(relePin3, OUTPUT);
  pinMode(relePin4, OUTPUT);
  pinMode(relePin5, OUTPUT);

  digitalWrite(relePin1, LOW);
  digitalWrite(relePin2, LOW);
  digitalWrite(relePin3, LOW);
  digitalWrite(relePin4, LOW);
  digitalWrite(relePin5, LOW);

  lcd.begin(16, 2);

  lcd.setCursor(0, 0);
  lcd.print("DataLogger LCD ");
  lcd.setCursor(0,1);
  lcd.print("Fede e Fabio");

  delay(3000);

  lcd.clear();  
  lcd.setCursor(0, 0);
  lcd.print("Init SD Card...");
  lcd.setCursor(0,1);

  if (!SD.begin(CS)) {
    Serial.println("initialization failed!");
    lcd.print("... Failed   ");
    return;
  }
  Serial.println("initialization done.");
  lcd.print("... Ready    ");

  delay(2000);

  lcd.clear(); 
  Wire.begin();
  RTC.begin();
  RTC.sqw(1);     //0 Led off - 1 Freq 1Hz - 2 Freq 4096kHz - 3 Freq 8192kHz - 4 Freq 32768kHz
  if (!RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // RTC.adjust(DateTime(2015,05,05,11,50,00));
  }
}

void loop () {
  DateTime now = RTC.now();
  lcd.clear(); 
  sprintf(lcdBuffer, "%02d/%02d/%04d", now.day(), now.month(), now.year() );
  lcd.setCursor(0,0);
  lcd.print(lcdBuffer);
  sprintf(lcdBuffer, "%02d:%02d:%02d", now.hour(), now.minute(), now.second() );
  lcd.setCursor(0,1);
  lcd.print(lcdBuffer);

  if (now.minute() == 00 && now.second() == 00 || now.minute() == 10 && now.second() == 00 || now.minute() == 20 && now.second() == 00 || now.minute() == 30 && now.second() == 00 || now.minute() == 40 && now.second() == 00 || now.minute() == 50 && now.second() == 00 ) {
    saveData(now);
  }   

  if (ctrlButton( analogRead( BUTTON ) ) != 0 || now.second() == 00 || now.second() == 30) {  
    readSensor(now);
  }

  if (now.minute() == 00) {
    if (DHT.humidity < 60) digitalWrite(relePin2, HIGH);
    else digitalWrite(relePin2, LOW);

    if (DHT.temperature < 25) digitalWrite(relePin1,HIGH);
    else digitalWrite(relePin1, LOW);
  }
  delay(500);
}

void readSensor(DateTime now) {
  lcd.clear(); 
  lcd.setCursor(0,0);
  lcd.print("Lettura DHT11");
  lcd.setCursor(0,1);

  int chk;
  chk = DHT.read(DHT11_PIN);    // READ DATA

  switch (chk) {
  case DHTLIB_OK:  
    Serial.print("OK,\t"); 
    lcd.print("SUCCESS");
    break;
  case DHTLIB_ERROR_CHECKSUM: 
    Serial.print("Checksum error,\t"); 
    lcd.print("Checksum error");
    break;
  case DHTLIB_ERROR_TIMEOUT: 
    Serial.print("Time out error,\t"); 
    lcd.print("Time out error");
    break;
  default: 
    Serial.print("Unknown error,\t"); 
    lcd.print("Unknown error");
    break;
  }

  lcd.clear(); 
  lcd.setCursor(0, 0);
  sprintf(lcdBuffer,  "%s %02d", "Humidty     ", DHT.humidity );
  lcd.print(lcdBuffer);
  lcd.setCursor(0, 1);
  sprintf(lcdBuffer,  "%s %02d", "Temperatura ", DHT.temperature );
  lcd.print(lcdBuffer);
}

void saveData( DateTime now ) {
  int chk;
  chk = DHT.read(DHT11_PIN);    // READ DATA
  sprintf(buffer,  "%02d/%02d/%d %02d:%02d:%02d %d %d", now.day(), now.month(), now.year(), now.hour(), now.minute(), now.second(), DHT.humidity, DHT.temperature );
  Serial.println( buffer );

  myFile = SD.open("dati.log", FILE_WRITE);
  if (myFile) {
    myFile.println(buffer);
    myFile.close();
  } 
  else {
    Serial.println("error opening data.log");
    lcd.clear(); 
    lcd.setCursor(0, 0);
    lcd.print("Err SD Write");
  }
}

void readData(DateTime now) {
  int chk;
  chk = DHT.read(DHT11_PIN);    // READ DATA
}

int ctrlButton( int button ) {
  if ( SELECT[0] <= button && button <= SELECT[1] ) { 
    return 1; 
  }
  if ( LEFT[0] <= button && button <= LEFT[1] ) { 
    return 2; 
  }
  if ( RIGTH[0] <= button && button <= RIGTH[1] ) { 
    return 3; 
  }
  if ( UP[0] <= button && button <= UP[1] ) { 
    return 4; 
  }
  if ( DOWN[0] <= button && button <= DOWN[1] ) { 
    return 5; 
  }
  return 0;
}

Ciao, grazie per aver risposto ed aver cercato di risolvere il mio problema.
Ho provato a caricare lo sketch ma il problema persiste;
anzi, avendo impostato il delay a 500, il ticchettio avviene ogni mezzo secondo.
Il problema principale è che il relè scatta ogni volta che avviene il delay provocando così un ticchettio che alla lunga penso possa provocare problemi a livello meccanico della Relè Shield.

Essendo la prima volta che utilizzo una Relè Shield mi viene anche da pensare che possa essere normale il ticchettio, ma non penso debba farlo.

Ovviamente non ho controllato la logica dello schetch.

Ad esempio verifichi ogni 500ms se il minuto è zero ed attivi i relè:
if (now.minute() == 00) {
if (DHT.humidity < 60) digitalWrite(relePin2, HIGH);
else digitalWrite(relePin2, LOW);

if (DHT.temperature < 25) digitalWrite(relePin1,HIGH);
else digitalWrite(relePin1, LOW);
}

Ma dopo il primo confronto l’operazione viene rifatta (119 volte) sino a che il minuto diventa diverso da zero.

Ma forse il problema è l’alimentazione: i relè non assorbono molto, ma hai molti dispositivi collegati e può essere che Arduino si resetti: il setup riparte e porta i relè a LOW, sino al successivo confronto.

Manca anche un delta su umidità e temp

if (DHT.humidity < 60) digitalWrite(relePin2, HIGH);

l’umidità potrebbe oscillare tra 59,9…60,0…59,9…60,0
la temp tra 24,9…25,0…24,9…25,0

ti serve un range di almeno 1 grado