Gestione rack

Salve ragazzi, sono alle prime armi con arduino e sto cercando di realizzare il controllo di un server rack.

Viene gestito un LCD 16x2, un RTC 1307, un sensore di temperatura LM35 e 4 pin digitali ai quali sono collegati 3 mosfet IRF 520.

Il funzionamento è molto semplice; quando la temperatura è al di sotto dei 20 °C ho una strip led blu, quando la temp sale oltre i 20°C i led blu si spengono e si accendono le ventole collegate al pin 9, una strip led rossa ha un effetto fade ed un buzzer si accende e spegne.

L’effetto che volevo dare al rack è molto semplice quanto carino da vedere però ci sono dei piccoli problemi che sicuramente qualcuno di voi saprà risolvere.

Quando il pin 9 è in LOW cè comunque un voltaggio e provando a mettere un led al posto delle ventole, questo si accende, al contrario quando il pin 9 è in HIGH il led si spegne. Succede la stessa cosa con i mosfet, però a differenza del led questi funzionano correttamente pur avendo una tensione in LOW.
La mia domanda è… ma non dovrebbe essere al contrario??? Dove sbaglio???

Altra cosa… quando il sensore LM35 rileva in modo ripetitivo l’intervallo di temperatura tra i 19.90 e 20.90 è un continuo di ON/OFF delle ventole ed ho un effetto tipo lampeggianti della polizia BLU/ROSSO :D… si può risolvere in qualche modo???

Lo vorrei rendere più snello e performante possibile, sia la parte software che hardware.

grazie

#include <Wire.h>
#include <LiquidCrystal.h> //include la libreria per LCD
#include "RTClib.h"

RTC_DS1307 RTC;
LiquidCrystal lcd(8, 7, 5, 4, 3, 2); //uscite LCD
const int inPin = 0;
const int fan = 9;
int ledRosso = 10;
int speaker = 12;
int ledBlu = 11;
int fanState = 0;
int lastFanState = 0;

void setup() {
  
  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
  
  lcd.begin(16, 2); //numero righe e colonne LCD
  pinMode (ledRosso, OUTPUT);
  pinMode (speaker, OUTPUT);
  pinMode (ledBlu, OUTPUT);
  pinMode (fan, OUTPUT);
  
  if (! RTC.isrunning()) {
    Serial.print("RTC assente!");
    // Decommentare la seguente riga per la memorizzazione della data e dell'ora sul DS1307
    //RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  
}

void loop() {
  
  //converte i mV in °C e stampa la temperatura su lcd
  
  int value = analogRead(inPin);
  lcd.setCursor(0, 1);
  float millivolts = (value / 1024.0) * 5000;
  float celsius = millivolts / 10;
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print(celsius);
  lcd.print("  Celsius");
  
  //legge lo stato del pin 9 e se il valore è HIGH stampa su lcd la voce "VENTOLA ON"
  
  fanState = digitalRead(fan);
  
  if (fanState != lastFanState) {
    if (fanState == HIGH) {
      lcd.setCursor(0, 1);
      lcd.print("  VENTOLE   ON");
      
      }
    }

//variabile di temperatura
  
  if (celsius >20)
  
  {
    
        digitalWrite(ledBlu, LOW);
        digitalWrite(fan, HIGH);
        
        {
        
        digitalWrite(speaker, LOW);
        delay(400);
        digitalWrite(speaker, HIGH);
        delay(100);
        
       }
       
             for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5)
       
             {
               analogWrite(ledRosso, fadeValue);
               delay(30);
             }
       
             for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5)
       
             {
               analogWrite(ledRosso, fadeValue);
               delay(30);
             }
   
      Serial.print("  WARNING!!!    ");
  }
  
  else
  
  {
    
    digitalWrite(ledRosso, LOW);
    digitalWrite(ledBlu, HIGH);
    digitalWrite(fan, LOW);
    
    //qui lo stato del pin 9 sarà LOW, quindi stampa su lcd "VENTOLA OFF"
    
    lcd.setCursor(0, 1);
    lcd.print("  VENTOLE  OFF");
  
  }

// Serial print
  
DateTime now =RTC.now();

Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(' ');
Serial.print(now.day(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.year(), DEC);
Serial.print(' ');
Serial.print(" Temperatura ");  
Serial.print(celsius);

Serial.println();
  
delay(500);
  
}

Intanto vedo un errore di logica.
Usi una variabile per memorizzare lo stato precedente del pin 9 ma non la aggiorni mai:

if (fanState != lastFanState) {
    if (fanState == HIGH) {
      lcd.setCursor(0, 1);
      lcd.print("  VENTOLE   ON");
    }
}

ciao...

ti ringrazio per l'aiuto ma si comincia male :smiley:

non ho capito una mazza di quello che hai scritto... è bruttissimo essere alle prime armi e non riuscire a capire neanche chi ti aiuta...

quella variabile la uso solo per leggere lo stato delle ventole che quando sono in HIGH mi riporta sullo schermo "VENTOLE ON"

cosa significa "ma non la aggiorni mai"???

scusami ancora; non sai che sforzo ho fatto per scrivere quelle poche righe di codice e vedere che tuttosommato funziona è stata una grande gioia...

Il codice che hai postato è tuo o lo hai copiato?
Fai un confronto con lastFanState, che a logica contiene lo stato precedente della ventola. Ma se non riassegni a quella variabile lo stato attuale, al prossimo if il valore di lastFanState sarà uguale a quello iniziale, anche dopo 100 giorni di utilizzo.

Il codice che hai postato è tuo o lo hai copiato?

piccole parti di codice come questa indicata da te l'ho trovata in uno sketch su qualche forum, e facendo al caso mio sono riuscito ad integrarla nel mio sketch... a quanto pare è sbagliata, però fa quello che volevo...

Fai un confronto con lastFanState, che a logica contiene lo stato precedente della ventola. Ma se non riassegni a quella variabile lo stato attuale, al prossimo if il valore di lastFanState sarà uguale a quello iniziale, anche dopo 100 giorni di utilizzo.

in sostanza quella variabile serve solo per stampare "VENTOLE ON" sul display quando lo stato del pin 9 è su HIGH

//legge lo stato del pin 9 e se il valore è HIGH stampa su lcd la voce "VENTOLA ON"
  
  fanState = digitalRead(fan);
  
  if (fanState != lastFanState) {
    if (fanState == HIGH) {
      lcd.setCursor(0, 1);
      lcd.print("  VENTOLE   ON");
      
      }
    }

e quando è su LOW mi scriverà "VENTOLE OFF"...

//qui lo stato del pin 9 sarà LOW, quindi stampa su lcd "VENTOLA OFF"
    
    lcd.setCursor(0, 1);
    lcd.print("  VENTOLE  OFF");
  
  }

però da quanto mi scrivi, quella variabile è sbagliata per l'uso che ne faccio io giusto???

ti ripeto... fa tutto quello che gli dico di fare, quindi non capisco dov'è lo sbaglio su quella variabile

Ti chiedevo se era farina del tuo sacco perché mi pareva, visto lo sketch e le risposte che davi alla mia domanda, che non lo fosse :wink:

L'uso che ne fai è ovviamente sbagliato.

 if (fanState != lastFanState) {

In questo if ci entra solo se il contenuto delle 2 variabili è diverso. Però un tale controllo lo si usa se poi la variabile che contiene lo stato precedente tu la aggiorni, altrimenti che senso ha? :smiley:

Ragiona come.
Ad ogni ora ti affacci alla finestra e guardi il tempo perché vuoi vedere l'evoluzione meteo nell'arco della giornata. Decidi di operare così:

  • al primo "affaccio" scrivi su un quaderno lo stato meteo;
  • agli affacci successivi scrivi lo stato solo se questo è diverso dal precedente.

Al primo affaccio ti scordi di scrivere lo stato. Quando ti affacci, la seconda ora, con cosa confronti lo stato attuale? :wink:

Ciò significa che quella lastFanState in teoria dovrebbe essere aggiornata da qualche parte.
Se invece non ti serve perché vuoi solo controllare se la ventola è ON o OFF, allora eliminala del tutto e fai un controllo diretto con HIGH o LOW

credo che una spiegazione migliore non me la potevi fare :grin:

quindi così facendo elimino una funzione inutile al ciclo dello sketch...

lunedì faccio una prova e ti dico...

grazie

ciao...

ho ricaricato lo sketch togliendo quella funzione inutile... funziona perfettamente... all'apparenza come prima XD

posso migliorare altre cose?

vorrei sostituire lo schermo attuale con un lcd 20*4 HD HD44780 pilotato con IO/Expander PCF8574AP e collegarci anche l'rtc...

per quanto riguarda la temperatura, quando il sensore rileva in modo ripetitivo i stessi valori ed ho quindi sempre ON/OFF in continuo posso risolvere in qualche modo?

grazie

il tuo attacca-stacca lo hai perchè il range delle temp è troppo ristretto è di 0.2°C
19.9 = OFF
20.1 = ON

metti minore = a 19° off e maggiore = a 21°on … temp media 20°

ciao