Ένα ιστολόγιο για όσους αγαπούν τις ηλεκτρονικές κατασκευές...

Σάββατο 20 Οκτωβρίου 2018

Arduino Παίζοντας με θερμοκρασίες [3].

Στο προ-προηγούμενο άρθρο μου σας έδειξα πως να κάνετε ένα πολύ απλό αλλά ακριβές θερμόμετρο.
Στο προηγούμενο άρθρο μου σας έδειξα πως να αυξήσουμε τις δυνατότητες του θερμομέτρου προσθέσουμε ένδειξη μέγιστης και ελάχιστης θερμοκρασίας .
Σε αυτό το άρθρο θα προσθέσουμε ένα μικρό relay module και θα μετατρέψουμε το θερμόμετρο σε θερμοστάτη.




Αρχικά θα δηλώσουμε τα νέα πιν που χρησιμοποιούμε σαν εισόδους για τα πλήκτρα και το πιν γιά έξοδο στο relay.

  pinMode(5, INPUT_PULLUP);  // ----- Πλήκτρο (+)
  pinMode(6, INPUT_PULLUP);  // ----- Πλήκτρο (-)
  pinMode(7, INPUT_PULLUP);   // ---- Πλήκτρο SET
  pinMode(4, OUTPUT);   //-------------- Εντολή relay

Το relay module  που θα χρησιμοποιήσω είναι 12V οπότε θα το τροφοδοτήσουμε από εξωτερική πηγή με +12V στο (+) θα δώσουμε κοινή γή με το υπόλοιπο κύκλωμα και το trigger του module θα το συνδέσουμε στο πιν D4 που ορίσαμε σαν έξοδο. Όταν συνδέουμε modules με το arduino πρέπει να προσέχουμε τι ρεύμα τραβάνε γιατί το arduino μπορεί να δώσει μόνο μικρά ρεύματα μέχρι 20mA στις ακίδες του και έως .... mA από το σταθεροποιητή του. Στην περίπτωση μας το module τροφοδοτείται εξωτερικά οπότε δεν έχουμε κανένα πρόβλημα τροδοσίας.

Στη συνέχεια θα δηλώσουμε τρεις μεταβλητές, για την θερμοκρασία, την υστέρηση και την κατάσταση ρύθμισης καθώς και τις προκαθορισμένες τιμές που θέλουμε να έχουν.  Τις προκαθορισμένες τιμές θα μπορούμε στη συνέχεια να αλλάξουμε από τα πλήκτρα. Η υστέρηση είναι απαραίτητη διότι όταν η θερμοκρασία φτάνει στο κρίσιμο σημείο δεν είναι απόλυτα σταθερή και κάνει το relay να ανοιγοκλείνει πολυ γρήγορα κάτι που είναι προβληματικό. Με την υστέρηση ουσιαστικά δίνουμε ένα μικρό περιθώριο (ρυθμιζόμενη τιμή) που πρέπει η θερμοκρασία να πέσει για να ενεργοποιηθεί πάλι το relay.

float set_temp = 25;  
float hysterisis = 1;
int set_status = 0;

Παρακάτω είναι ο κώδικας που χειρίζεται το relay. Εάν η θερμοκρασία είναι μικρότερη από την προκαθορισμένη τιμή μείον την υστέρηση τότε το relay ενεργοποιείται. Όταν η θερμοκρασία φτάσει τους 25 βαθμούς (προκαθορισμένη τιμή) το relay απενεργοποιείται.
Η λειτουργία αυτή είναι σωστή για την περίπτωση που χειριζόμαστε ένα θερμαντικό στοιχείο. Αν θέλουμε να χειριστούμε ένα στοιχείο ψύξης π.χ. έναν ανεμιστήρα θα πρέπει να αντιστρέψουμε το LOW σε HIGH και το αντίστροφο στις παρακάτω εντολές αντίστοιχα.

 if(tempC >= set_temp) { digitalWrite(4, LOW);}
 if(tempC < set_temp - hysterisis) { digitalWrite(4, HIGH);} 

Αν δεν χρειαζόταν να αλλάξουμε τις προκαθορισμένες τιμές ποτέ θα είχαμε τελειώσει εδώ. Θα προσθέσουμε όμως τρία πλήκτρα για να μπορούμε να ρυθμίσουμε τις τιμές set_temp και hysterisis.
Σε κάποιες εφαρμογές όπως π.χ. μια κλωσσομηχανή χρειαζόμαστε λεπτομέρεια στη ρύθμιση και έχουμε σφιχτά περιθώρια διακύμανσης της θερμοκρασίας. Για αυτό το λόγο έδωσα στις μεταβλητές αυτές τύπο float ώστε να μπορούμε να κάνουμε ρύθμιση μικρότερη της μονάδος.

Με τον παρακάτω κώδικα διαβάζουμε την είσοδο D7 (πάτημα πλήκτρου SET) και εφόσον έχει πατηθεί το πλήκτρο αλλάζουμε την κατάσταση ρύθμισης κατά 1. Η μεταβλητή μπορεί να πάρεις τις τιμές 0 (προκαθορισμένη) λειτουργία θερμομέτρου, 1 = ρύθμιση θερμοκρασίας, 2 = ρύθμιση υστέρησης. Όταν η τιμή υπεβεί το 2 επανέρχεται στο 0.

  if(digitalRead(7) == 0 ) {
    set_status++;
    if (set_status > 2) { set_status = 0; }
  }

Στη συνέχεια θα μετατρέψουμε την ένδειξη της δεύτερης γραμμής ώστε να αλλάζει η ένδειξη από τα μέγιστα - ελάχιστα που δείχνει φυσιολογικά σε ένδειξη των ρυθμίσεων ανάλογα με το set_status.
Αν είναι 0 τρέχει ο αρχικός κώδικας που εμφανίζει την ελάχιστη και την μέγιστη θερμοκρασία.

  if(set_status == 0){
    lcd.print(tempCmin);
    lcd.print("\337");
    lcd.print(" - ");
    lcd.print(tempCmax);
    lcd.print("\337   ");  
  }


Αν είναι 1 τότε η δεύτερη σειρά εμφανίζει την θερμοκρασία SET που έχουμε ορίσει. Μέσα στην ίδια συνθήκη ελέγχουμε τα πλήκτρα (+) και (-) εάν πατηθούν οπότε αλλάζει αντίστοιχα προς τα πάνω ή προς τα κάτω η προκαθορισμένη τιμή της μεταβλητής.

  else if(set_status == 1) {
    lcd.print("set temp: ");
    lcd.print(set_temp);  
    lcd.print("\337   ");   
    if(digitalRead(5) == 0 ){ set_temp = set_temp + 1; }
    if(digitalRead(6) == 0 ){  set_temp = set_temp - 1}   
  } 

Το ίδιο και εδώ με την τιμή της υστέρησης.

  else if(set_status == 2) {
    lcd.print("Hysterisis: ");
    lcd.print(hysterisis);  
    lcd.print("\337   ");  
    if(digitalRead(5) == 0 ){ hysterisis = hysterisis + 0.10; }
    if(digitalRead(6) == 0 ){ hysterisis = hysterisis - 0.10; }   
  }

Όπως φαίνεται παραπάνω η θερμοκρασία αυξομειώνεται κατά 1 βαθμό ενώ η υστέρηση με βήμα 0.1 βαθμό. Μπορεί να επιλεχτεί διαφορετικό βήμα αλλαγής των τιμών ανάλογα με την εφαρμογή και την επιθυμία σας.

Παρατηρήστε ότι η αλλαγή τιμής γίνεται με τα ίδια πλήκτρα για τις δύο τιμές και μόνο όταν είναι σε κατάσταση ρύθμισης. Όταν η set_status είναι 0 τα πλήκτρα αυτά δεν αποκρίνονται. Επίσης οι ρυθμίσεις μπορούν να γίνουν κατά την διάρκεια που το κύκλωμα λειτουργεί. Αν μειώσουμε την θερμοκρασία κάτω από την τρέχουσα τιμή θερμοκρασίας τότε το relay θα απενεργοποιηθεί και αντίστροφα.
Με τον τρόπο που λειτουργεί ο κώδικας μας δίνει την δυνατότητα όταν κρατάμε πατημένο πλήκτρο αύξησης ή μείωσης της θερμοκρασίας να αυξάνει ή να μειώνεται συνεχώς η τιμή μέχρι να αφήσουμε το πλήκτρο.

Εδώ έχουμε ολοκληρώσει τον θερμοστάτη αλλά επειδή κάθε φορά που διακόπτουμε την τροφοδοσία η προκαθορισμένη τιμή θα επανέρχεται στο 25 (που έχουμε ορίσει στην αρχή) θα τροποποιήσουμε τον κώδικα ώστε να κρατάει τις ρυθμίσεις ακόμη και όταν κλείνουμε την τροφοδοσία και την επόμενη φορά που το λειτουργούμε να έχει τις τελευταίες τιμές.
Για το σκοπό αυτό θα περάσουμε τις τιμές σε δύο θέσεις τις μνήμης EEPROM που διαθέτει ο arduino  και κάθε φορά που ξεκινάει το πρόγραμμα θα τις διαβάζει από την μνήμη.


Προσθέτουμε την βιβλιοθήκη
#include <EEPROM.h>
προσθέτουμε στην setup() τις εντολές για ανάγνωση των μεταβλητών από την μνήμη.
  set_temp = EEPROM.get(0, set_temp);
  hysterisis = EEPROM.get(4, hysterisis);
Και προσθέτουμε και τις παρακάτω εντολές για εγγραφή των μεταβλητών στην μνήμη.
EEPROM.put(0, set_temp);   
EEPROM.put(4, hysterisis);   
Οι μεταβλητές καταγράφονται αμέσως μετά από κάθε αλλαγή οπότε δεν χρειάζεται κάποιου είδους καταχώρηση (save).

===========================================
παρακάνω είναι ολόκληρος ο κώδικας ενημερωμένος.
===========================================
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>

LiquidCrystal_I2C lcd(0x3F,16,2);

#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float tempC = 0;
float tempCmin = 100;
float tempCmax;
float set_temp = 25;
float hysterisis = 1;
int set_status = 0;


void setup() {
// EEPROM.put(0, set_temp); 
// EEPROM.put(4, hysterisis);

  set_temp = EEPROM.get(0, set_temp);
  hysterisis = EEPROM.get(4, hysterisis);
  pinMode(3, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);   
  pinMode(4, OUTPUT);
  sensors.begin();
  lcd.init(); 
  lcd.home();
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("DIY electronics");
  lcd.setCursor(0,1);
  lcd.print("   blogspot.com"); 
  delay(2000);
  lcd.clear();
}

void loop() {
  sensors.requestTemperatures();
  tempC = sensors.getTempCByIndex(0);

  if(tempCmin >= tempC) {tempCmin = tempC; }
  if(tempCmax <= tempC) {tempCmax = tempC; }

 if(digitalRead(3) == 0 ) {
  tempCmin = tempC;
  tempCmax = tempC;
 }

  if(digitalRead(7) == 0 ) {
    set_status++;
    if (set_status > 2) { set_status = 0; }
  }

 if(tempC >= set_temp) { digitalWrite(4, LOW);}
 if(tempC < set_temp - hysterisis) { digitalWrite(4, HIGH);}
 
  lcd.setCursor(0,0);
  lcd.print("TEMP: ");
  lcd.print(tempC);
  lcd.print("\337C  ");
  lcd.setCursor(0,1);

  if(set_status == 0){
    lcd.print(tempCmin);
    lcd.print("\337");
    lcd.print(" - ");
    lcd.print(tempCmax);
    lcd.print("\337   ");
  }
  else if(set_status == 1) {
    if(digitalRead(5) == 0 ){ set_temp = set_temp + 1; }
    if(digitalRead(6) == 0 ){ set_temp = set_temp - 1; } 
    EEPROM.put(0, set_temp); 
    lcd.print("set temp: ");
    lcd.print(set_temp);
    lcd.print("\337   "); 
  }
  else if(set_status == 2) {
    if(digitalRead(5) == 0 ){ hysterisis = hysterisis + 0.10; }
    if(digitalRead(6) == 0 ){ hysterisis = hysterisis - 0.10; }
    EEPROM.put(4, hysterisis);   
    lcd.print("Hysterisis: ");
    lcd.print(hysterisis);
    lcd.print("\337   ");
  }

  delay(10);
}

//----------------------------------


Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

Count down timer - χρονικό αντίστροφης μέτρησης

Μια απλή κατασκευή χρονομέτρου με αντίστροφη μέτρηση. Μπορεί να μετρήσει μέχρι 100 λεπτά με βήμα του ενός δευτερολέπτου. Είναι ιδανικό για ...