Jump to content
Sign in to follow this  
Preoteasa Andrei

Arduino - relee si ventilatoare amplificator cu afisaj lcd 20x4.

Recommended Posts

Folosind unul sau mai multi senzori DS18B20, conectati pe un singur fir, relee si un display LCD 20x4 i2c. Am creat si un loading screen / bar, timpii se pot modifica in functie de necesitate, Mai intai se cauta adresa senzorilor cu onewire dev address finder (si al display-ului, in cazul in care display-ul nu este detectat - cu i2c scanner ). Se pot modifica temperaturile in functie de parametrii amplificatorului. Astept comentarii si / sau imbunatatiri ale codului, mentionand ca este primul meu proiect cu arduino, combinand multiple coduri din diferite tutoriale.

 

#include <Wire.h>                                                                                                                  //#include <LCD.h>                                                                                                                   //#include <LiquidCrystal_I2C.h>                                                                                                     //#include <OneWire.h>                                                                                                               //#include <DallasTemperature.h>                                                                                                     ////---------------------------------------------------------------------------------------------------------------------------------//#define ONE_WIRE_BUS 13                                                                                         //sensor data pin  //LiquidCrystal_I2C  lcd(0x3F,2,1,0,4,5,6,7,3,POSITIVE);                                                                             //OneWire oneWire(ONE_WIRE_BUS);                                                                                                     //DallasTemperature sensors(&oneWire);                                                                                               //  DeviceAddress Probe01 = { 0x28, 0xEE, 0x23, 0xA3, 0x1D, 0x16, 0x02, 0x13 };             // write your own device address           //DeviceAddress Probe02 = {};                                                             // write your own device address           ////---------------------------------------------------------------------------------------------------------------------------------//int sensor = 12;                          // sensor power pin (+)int tempMin = 22;                         // the temperature to start the fansint tempMax = 26;                         // the maximum temperature when fans are at 100%int tempOFF = 30;                         // the temperature to cut off the main power of amplifierint fanSpeed = 0; int fanLCD;int fan = 2;                              //fan speed PWM - connects to 1k resistor fan boardint powerrelay = 3;                       //the ssr relay on the main power of amplifierint speakersrelay = 4;                    //the relay powering speaker protection boardfloat temp1;                              //float value of first sensorfloat temp2;                              //float value of second sensorfloat tempC = 0;                          //float average valuefloat tempF = 0;byte degree[8]       = { B00010, B00101, B00010, B00000, B00000, B00000, B00000, B00000 };byte percentage_1[8] = { B10000, B10000, B10000, B10000, B10000, B10000, B10000, B10000 };byte percentage_2[8] = { B11000, B11000, B11000, B11000, B11000, B11000, B11000, B11000 };byte percentage_3[8] = { B11100, B11100, B11100, B11100, B11100, B11100, B11100, B11100 };byte percentage_4[8] = { B11110, B11110, B11110, B11110, B11110, B11110, B11110, B11110 };byte percentage_5[8] = { B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111 };//-----------------------------------------------------------------------------------------//              void setup(){             sensors.begin();             sensors.setResolution(Probe01, 10);              sensors.setResolution(Probe02, 10);                // set the resolution to 10 bit (Can be 9 to 12 bits .. lower is faster)             pinMode(2, OUTPUT);             pinMode(3, OUTPUT);             pinMode(4, OUTPUT);             pinMode(9, OUTPUT);             pinMode(12, OUTPUT);             Serial.begin(9600);             digitalWrite (sensor, HIGH);             lcd.begin (20,4);  // lcd screen type, mine is 20x4.             lcd.createChar(6, degree);             lcd.createChar(1, percentage_1);             lcd.createChar(2, percentage_2);             lcd.createChar(3, percentage_3);             lcd.createChar(4, percentage_4);             lcd.createChar(5, percentage_5);             lcd.setBacklight(HIGH);             lcd.setCursor(0,0);             lcd.print ("       SYSTEM       ");             lcd.setCursor(0,1);             lcd.print ("         IS         ");             lcd.setCursor(0,2);             lcd.print ("    INITIALISING    ");             lcd.setCursor(0,3);             for (int i=0; i<20; ++i ){for(int j=0; j<5;j++)                                      {lcd.setCursor(i,3);                                       lcd.write(j);                                       delay(10);}}} //-----------------------------------------------------------------------------------------//void loop(){            sensors.requestTemperatures();            temp1 = sensors.getTempC(Probe01);            temp2 = sensors.getTempC(Probe02);            tempC = (temp1+temp2)/2;            tempF = sensors.toFahrenheit(tempC);            Serial.println(tempC,0);            if (tempC >= tempOFF){digitalWrite(speakersrelay,LOW);             //this will cutoff the speakers protection boards ->no signal in speakers                                     delay(200);                                  //delay half second                                  digitalWrite(powerrelay,LOW);}               //cut the main power of the amp.                                  else {digitalWrite(powerrelay,HIGH);                                        digitalWrite(speakersrelay,HIGH);}                                                                 delay(250);            lcd.setCursor(0,0);            lcd.print("AMPLIFIER MONITOR");            lcd.print("   ");            lcd.setCursor(0,1);            lcd.print("Heatsink temp:");            lcd.print(tempC,0);            lcd.write(6);            lcd.print("C");            if(tempC < tempMin){                                                                // if temp is lower than minimum temp                                fanSpeed = 0; // fan is not spinning                                lcd.setCursor (0,2);                                lcd.print ("Fans not running");                                lcd.setCursor (0,3);                                lcd.print ("ALL SYSTEMS GOOD!");                                lcd.print ("   ");                                digitalWrite(fan, LOW);}                                                      if((tempC >= tempMin) && (tempC <= tempMax)) {                                  //if temp is higher than the minimum range                                                          fanSpeed = map(tempC, tempMin, tempMax, 32, 255); // the actual speed of fan                                                          fanLCD = map(tempC, tempMin, tempMax, 0, 100);  // speed of fan to display on LCD                                                          lcd.setCursor(0,2);                                                          lcd.print("Fans Speed:");  // display the fan speed                                                          lcd.print(fanLCD);                                                          lcd.print("%");                                                          lcd.print("    ");                                                          lcd.setCursor (0,3);                                                          lcd.print ("ALL SYSTEMS GOOD!");                                                          lcd.print ("   ");                                                          analogWrite(fan, fanSpeed);} // spin the fan at the fanSpeed speed                if (tempC > tempMax) {                                 // if temp is higher than tempMax                                  lcd.setCursor (0,3);                                  lcd.print ("HIGH TEMP REACHED!");                                  lcd.print (" ");                                  analogWrite(fan, 255);                                     fanLCD = 100;                                  lcd.setCursor(0,2);                                  lcd.print("Fans Speed:");  // display the fan speed                                  lcd.print(fanLCD);                                  lcd.print("%");                                  lcd.print("    ");}            if (tempC >= tempOFF){                                  lcd.setCursor (0,3);                                  lcd.print ("THERMAL THROTTLING!");                                  lcd.print (" ");}            }

 

 

post-241436-0-74367000-1483525714_thumb.jpg

post-241436-0-09222700-1483525721_thumb.png

Share this post


Link to post
Share on other sites

ai un Uno sau un Nano? :)pentru că nu ştiu câţi au să se îndure să blocheze un Mega într-un amplificator numai pentru aşa ceva! :)

Share this post


Link to post
Share on other sites

@Mifty: Nu te opreste nimeni sa adaptezi codul pentru porturile Uno/Nano si sa il folosesti.

Idea este interesanta si se poate adapta/folosi pe Arduino Uno/Nano.

Share this post


Link to post
Share on other sites

Salut, am un mega (clona), dar cum a spus si nico_2010, se poate adapta usor insa pentru ce va urma nu cred ca nano are pini deajuns. mi-au venit si ceilalti senzori insa nu am avut timp sa mai postez, am modificat putin codul, am pus doi senzori south/north pe fiecare canal, face media si il afiseaza pe lcd media senzorilor, individual channel A si channel B. Ca pret cred ca m-a costat tot in jur a 50 lei. Pe startup am pus un keypad, urmeaza codul pentru pin code, pentru pornirea amplificatorului (stiu ca este prea mult dar am tot incercat sa cumpar on off switch-uri cu cheie, din cate am cumparat nu am gasit unul safe, se pot porni usor si fara cheie), iar daca tot e mega in amplificator de ce nu? :d

Share this post


Link to post
Share on other sites

... atunci profită de Mega: are mai mult flash, mai mulţi pini, faci un "electronic lock" cu cod numeric introdus de la tastatură! :)eventual, faci asta pe un nano sau mini, care să se ocupe doar de asta, şi să-i trimită lui Mega ok-ul...mă cam bate şi pe mine gândul să iau un Mega, mai ales că cipul lui nu există decât în capsulă SMD, aşa că mai bine iau "plăcuţa" gata făcută decât să mă chinui cu lipitul "gândăcelului", dar nu sunt foarte convins că mai rămân mult timp la joaca cu Arduino...revenind la subiectul "lock"... există o poveste veche: impedanţa mânii fiecăruia e o variabilă, nu o constantă... aşa că ai putea să suplimentezi protecţia astfel încât să nu răspundă la cheie decât dacă e în mâna ta! :)singura mică-mare problemă e că şi impedanţa personală variază după cum eşti de transpirat, nemâncat, stresat, etc... :))))(m-am jucat o vreme cu ideea asta, dar la nivel analogic... mai safe era să fac ceva să răspundă la fluierat! :))))))) )

Share this post


Link to post
Share on other sites

cu referire la cod...cred ca ar trebui implementat un HISTERIZIS..

nu de alta dar o sa fie cam nehotărât dispozitivul in practica...

Edited by Aw Genetix

Share this post


Link to post
Share on other sites

Nu stiu sigur ce este HISTERIZIS, daca este o modalitate de a pastra valorile precedente la verificari, cu siguranta trebuie implementat asa ceva.

 

Eu am facut ceva similar folosind LM335 si din cand in cand variaza rezultatele cam aiurea, am rezolvat pastrand valorile pe ultimele 20 citiri si facand media.

Edited by dany_cta

Share this post


Link to post
Share on other sites

Eu am facut ceva similar folosind LM335 si din cand in cand variaza rezultatele cam aiurea, am rezolvat pastrand valorile pe ultimele 20 citiri si facand media.

La fel am făcut și eu în trecut toto cu un 335 și un modul de senzor de umiditate la un ceas de cameră, dar există și o altă variantă. Tocmai de aceea intervin, pentru că mi se pare o variantă mai bună, e vorba de o filtrare digitală mai simplă decît păstrarea ultimelor n valori întro variabilă tip tablou de n valori.

Pentru o mediere de 10 valori, se citește valoarea curentă și se face următorul calcul: (valoarea anterioară x 9 + valoarea curentă) / 10.

Presupunînd că valoarea anterioară a fost corectă iar cea curentă deplasată, aceeasta va influența foarte puțin în mod negativ valoarea finală avînd o pondere de 10% din suma ce se divide cu 10.

Am folosit această filtrare, comparativ cu cea veche (mediere ultime n valori păstrate) la ultimul meu proiect (driver letcon JBC) și s-a dovedit o soluție mai bună.

Share this post


Link to post
Share on other sites

Deci solutia ta este sa cari media dupa tine din cate inteleg ? Cred ca da, ar merge bine desi ma gandesc ca ar fi destul de greu sa progreseze valoarea odata cu temperatura daca nu faci citiri foarte frecvente, o sa fie destul de greu sa urce media generala.

Mai e si posibilitatea sa fi inteles gresit si de fapt sa cari doar ultimele doua valori ceea ce are rata mare de eroare.

Nu ar fi mare problema la un ventilator dar cand faci shutdown la un echipament cu eroare de protectie e problema.

Share this post


Link to post
Share on other sites

va urca la fel de repede ca și medierea ultimelor 10 valori citite, din acest punct de vedere nu are nici un dezavantaj, însă valoarea afișată e mai stabilă și dacă ai o citire pe secundă de exemplu nu trebuie să aștepți 10 secunde să crească valoarea după pornire.

Eu am folosit varianta pe un sistem instabil, nu zic teoretic.

Share this post


Link to post
Share on other sites

histerezis.

Pe scurt, "drumuri" diferite la crestere fata de descrestere.

"Histerezisurile" cel mai des intalnite de electronisti sunt intrarile schmitt-trigger ale diverselor circuite. La circuitele CMOS pragurile sunt, in general, 0.3 * VDD pentru comutarea High->Low si 0.7*VDD pentru comutarea Low -> High.

Share this post


Link to post
Share on other sites

Pt. cei care folosesc LM35 ca şi senzori de temperatură analogici, pt. evitarea instabilităţilor la fire lungi eu am preferat la o automatizarea unei instalaţii de încălzire cu sobă cu lemne şi centrală pe motorină modul "curent variabil", în care se folosesc doar 2 fire, ieşirea LM-ului fiind legată printr-un rezstor de 200 ohmi la masa lui. Astfel curentul prin dispozitiv variază cu 50uA/C, la care se adaugă cei 60uA consum propriu. La intrarea Ax de la Arduino se mai montează un rezistor de 1k spre masă, care converteşte curentul variabil de la senzor în tensiune. În acest caz avem şi o "mapare" automată a domeniului 0-100C, folosind astfel rezoluţia ADC-ului la maximum.

În Arduino se face apoi compensarea abaterilor cu ceva gen temp = temp * 1,05 - 60.

Cât priveşte histerezisul, la acelaşi sistem eu am folosit după comparatorul de mărime un numărător pe rol de temporizator de declanşare. Dacă valoarea trece de cea setată numărătorul incrementează, sau invers, sub valoarea setată decrementează, iar când ajunge la o anumită valoare declanşează mai departe evenimentul. Dacă valoarea comparată oscilează peste sau sub prag, numărătorul urcă sau coboară în interiorul ferestrei, şi ieşirea lui nu se schimbă imediat. Dezavantajul este că reacţionează mai greu la schimbări nete, pt. că numărătorul trece prin toate valorile până să declanşeze.

 

Din codul meu de la comanda centralei pe motorină când soba pe lemne începe să se răcească:

 

if ((power > 65) || (actual_T > 430)) {
counter--;}
else if (((power <= 60) || (forward_T < 400) && (exhaust_T < 100))) {
counter++;}
counter = constrain(counter, 0, 1023); //TEMPORIZAREA COMUTARII ARZATOR
if (counter < 1) {
digitalWrite(9, LOW);}
else if(counter > 1022) {
digitalWrite(9, HIGH);} //PORNESTE ARZATORUL PE MOTORINA.
Edited by mihaicozac

Share this post


Link to post
Share on other sites

Buna ziua,

Vreau sa realizez un circuit bazat pe un ATMEGA328 care sa monitorizeze un amplificator:

1. soft start transformator

2. control al ventilatorelor cu praguri turatie/temperatura eventual si afisarea lor

3. delay la cuplarea boxelor

4. detectie lipsa curent alternativ

5. protectie / detectie CC la iesirea amplificatorului.

 

La ultima pozitie am ceva dubii. Separarea AC de CC, defapt ignorarea AC-ul de la iesirea amplificatorului. Ma puteti ajuta in acest sens pentru a realiza acest modul interfatat cu un ATMEGA 328?

 

Va multumesc,

Share this post


Link to post
Share on other sites

idei:

1. rezistenta de putere serie cu primarul suntata dupa 0.x secunde de un releu ?

2. depinde de ce senzori vei folosi (analog sau digital). restul este trivial

3. simplu de facut, dupa delay-ul soft-start si confirmarea tensiunii joase AC (sau DC dupa filtrare)

4. optocuplor pe AC sau DC bus

5. aici Leco sau altcineva. ma gandeam sa prezinti la intrarea unui operational AC-ul si pe intrarea cealalta AC+DC, faci diferenta si actionezi in consecinta.

 

Deci, dupa mine sunt 2 'probleme': partea de interfata si partea de programare. Prima trebuie batuta in cuie inainte.

Share this post


Link to post
Share on other sites

Buna ziua, Va multumesc pentru raspuns. La primele 4 pozitii treaba e simplista.

La pozitia 5 e ceva mai complicat. Partea hardware e cea care imi da batai de cap. Partea software e simpla. Poate exista cineva care sa-mi prezinte o schema orientativa sau sa-mi dea cateva indicatii pentru realizarea ei.

Mai astept poate citeste cineva postul meu si ma va indruma.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

×