mani Postat Decembrie 8, 2018 Partajează Postat Decembrie 8, 2018 (editat) Buna ziua la toata lumea. Eu sunt un cititor al acestui forum de unde am invatat foarte multe lucruri ,sunt autodidact si doresc sa actulizez ceea ce am facut mai demult,asa ca va rog sa ma ajutati daca vreti cu o automatizare pentru o centrala caruia i-am scris codul din recopilari de alte lucrari din internet. Trebuie sa monitorizez doua temperaturi si o fotocelula sa le imprim intr-un Lcd si in functie de acesti parametri arduino comanda: un snec cu timp ciclic, cu diferiti timpi de on si off, un ventilator la diferite turatii, o bujie de aprindere a focului , o pompa de circulare a apei. Problema e ca atunci cand chem functiile respective in" loop" arduino " ingheata" si pe ecran parametrii monitorizati la fel si nu pot intra nici in meniu sa-i reglez in timp real. Doresc ca cineva sa ma ajute sa scap de a folosi acest "WHILE" care i-mi da probleme . Sunt un incepator cu arduino ,am incercat cu libraria <pt.h> si am reusit doar snecul sa nu mai opreasca arduino atat timp cat merge la incarcare,celelate functii nu reusesc sa le adaptez la aceasta librarie. Codul e lung si nu-l pot posta tot ca nu ma lasa ,am pus doar o parte unde am eu problema cu timpul.Am inceput sa studiez TimeOne dar nu inteleg cum pot aplica eu intreruperile in cazul meu pentru o fuctie, pentru o iesire digitala am inteles cum se face dar restul ma depaseste si nu sunt capabil sa-i dau de capat. Va rog daca puteti sa ma indrumati cu un exemplu de cum pot solutiona problema.Invat mai repede din exemple aplicate la cod. Va multumesc pentru rabdarea de a citi tot acest pomelnic . Atasez o parte din cod. O zi buna va doresc. #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <thermistorFun.h> #include <pt.h> //Inicializacion LCD LiquidCrystal_I2C lcd(0x38,20,4); struct pt raspador; struct pt relanti; struct pt lento; struct pt medio; struct pt rapido; //Temporales para conversion float Caldera; float Humos; int LDR; int termostat; #define sensorCaldera 1 #define sensorHumos 2 #define sensorLDR 3 #define ventilador 5 #define resistencia 6 #define sinfin 9 #define actuador_adelante 11 #define actuador_atras 12 #define thermostat 14 //Variables temp caldera byte prog_tc = 33; byte prog_th= 160; //Variables menu tiempos byte prog_TL = 5; byte prog_TC = 5; byte prog_TN1 = 10; //Variables menu relanti byte prog_dr = 2; byte prog_cr = 10; byte prog_vr = 32; //Variables menu nivel-1 byte prog_d1 = 3; byte prog_c1 = 6; byte prog_v1 = 65; //Variables menu nivel-2 byte prog_d2 = 3; byte prog_c2 = 4; byte prog_v2 = 127; //Variables menu nivel-3 byte prog_d3 = 2; byte prog_c3 = 2; byte prog_v3 = 255; byte cheie; //Variable para tiempos unsigned long periodStart, periodFinished, periodElapsed; char temp_str[10]; ////////////////////////////////////////////////////////////////////////////////////// void setup() { lcd.init(); //Iniciamos el LCD lcd.backlight(); //Iniciamos la retroiluminacion PT_INIT(&raspador); PT_INIT(&relanti); PT_INIT(&lento); PT_INIT(&medio); PT_INIT(&rapido); pinMode(actuador_adelante,OUTPUT); pinMode(actuador_atras,OUTPUT); pinMode(resistencia, OUTPUT); pinMode(ventilador, OUTPUT); pinMode(sinfin, OUTPUT); pinMode(thermostat, INPUT_PULLUP); pinMode(LDR,INPUT); bool flag = HIGH; } //////////////////////////////////////////////////////////////////////////////////// void loop() { monstrar_sensores(); leer_sensores(); //mmenu(); termostat=digitalRead(thermostat); while(termostat==LOW) { leer_sensores(); borrar(0,9,0); borrar(0,9,1); termostat=digitalRead(thermostat); limpiador(); limpInit(); cargaInit(); // encendidoBujia(); //quemado_inicial(); // modulacion(); //modulacion_inversaTC(); //quemador_paradoTC(); } } /////////////////////////////////////////////////////////////////////////////////// ////////////////////Funcion borrado Caracteres//////////////////////// void borrar(int first, int last, int row){ for (first ; first < last+1 ; first++){ lcd.setCursor(first,row); lcd.print(" "); } } void timeElapsed(){ periodFinished= millis(); periodElapsed = (periodFinished - periodStart); } //////////////////////////////////////////////////////////////////// void limpiador() { lcd.setCursor(0,0); lcd.print("Limpieza"); borrar(0,8,2); lcd.setCursor(0,3); lcd.print("Raspa"); digitalWrite(actuador_adelante,HIGH); // motor limpiador hacia delante digitalWrite(actuador_atras, LOW); // pin rele desactivado analogWrite(ventilador, 255); periodStart = millis(); timeElapsed(); while(periodElapsed <5000) { leer_sensores(); timeElapsed(); lcd.setCursor(1,2); lcd.print(">>>"); digitalWrite(actuador_adelante,LOW ); // motor limpiador hacia atras digitalWrite(actuador_atras,HIGH); // pin rele activado if(Humos>=prog_th) break; } digitalWrite(actuador_adelante,LOW ); // motor limpiador hacia atras digitalWrite(actuador_atras,HIGH); // pin rele activado } void limpiador_atras() { periodStart = millis(); //tiempo_limpiador= millis(); timeElapsed(); while(periodElapsed <5000) { leer_sensores(); //monstrar_sensores(); lcd.setCursor(1,2); lcd.print("<<<"); timeElapsed(); // if(Humos>=prog_th) break; digitalWrite(actuador_adelante,LOW ); // motor limpiador hacia delante pero parado por digitalWrite(actuador_atras, LOW); } borrar(0,4,2); borrar(0,4,3); } //////////////////////////////////////////////////////////////////// void limpInit () { //limpieza inicial lcd.setCursor(0,3); lcd.print("Aire"); lcd.setCursor(1,2); lcd.write(7); lcd.write(8); analogWrite(ventilador, 255); //ventilator maximo periodStart = millis(); timeElapsed(); while(periodElapsed < prog_TL*1000){ //un timpo de 5 segundos //monstrar_sensores(); leer_sensores(); timeElapsed(); if(Humos>=prog_th) break; } analogWrite(ventilador, 0); //aqui se para borrar(0,4,2); borrar(0,4,3); } ////////////////////////////////////////////////////////// void cargaInit () { //carga inicial peletts long counter=0; lcd.setCursor(0,0); lcd.print("Carga >>"); lcd.setCursor(0,3); lcd.print("Pelet"); lcd.setCursor(1,2); lcd.write(6); lcd.write(6); lcd.write(6); digitalWrite(sinfin, HIGH); // motor sinfin en marcha periodStart = millis(); timeElapsed(); while(periodElapsed < prog_TC*1000){ //un timpo de 5 segundos monstrar_sensores(); timeElapsed(); LDR=analogRead(sensorLDR); if (LDR >= 200){ // Alimentación parada Si se detecta una llama estable. delay(100); counter++; if (counter >= 60) { digitalWrite(sinfin, LOW); break; } } else { counter=0; } //if (termostat==HIGH){ // break; // } //if(Humos>=prog_th) break; } digitalWrite(sinfin, LOW); //aqui se para borrar(0,4,2); borrar(0,4,3); } ///////////////////////////////////////////////////////////// void monstrar_sensores(){ //lcd.setCursor(0,3); //lcd.print("Nivel"); lcd.setCursor(11,0); lcd.print("Ldr:"); lcd.setCursor(15,0); lcd.print(LDR,1); lcd.setCursor(11,1); lcd.print("Fum:"); lcd.setCursor(15,1); lcd.print(Humos,1); lcd.setCursor(11,2); lcd.print("Tur:"); lcd.setCursor(15,2); lcd.print(Caldera,1); } //////////////////////////////////////////////////////////////// void leer_sensores() { LDR=analogRead(sensorLDR); String dataString = "sensor1,"; dataString += temp_str; Caldera = thermistorRead(1); dtostrf(Caldera,6,2,temp_str); dataString += "\nsensor2,"; dataString += temp_str; Humos = thermistorRead(2); dtostrf(Humos,6,2,temp_str); dataString += "\nsensor3,"; dataString += temp_str; } // Va multumesc mult. Editat Decembrie 10, 2018 de nico_2010 Link spre comentariu
Vizitator Postat Decembrie 8, 2018 Partajează Postat Decembrie 8, 2018 (editat) Incearca daca mai ai timp sa reeditezi postul, si sa postezi codul folosind buttonul Cod. Nici eu nu sunt programator, dar am folosit functia millis() pentru temperaturi sau timer1. Editat Decembrie 8, 2018 de Vizitator Link spre comentariu
mani Postat Decembrie 8, 2018 Autor Partajează Postat Decembrie 8, 2018 Buna ,prea tarziu nu pot sa-l mai reeditez postul Am incercat si cu functia millis() dar nu-mi iese,sunt multe solutii dar pentru cei care sunt in domeniu ,eu invat programare la 49 de ani si ma poticnesc un pic de aceea am rugat sa mi se dea un ajutor pe baza de exemplu . Codul merge dar se poate face mult mai bun decat am putut eu sa-l gandesc . Multumesc mult. Link spre comentariu
rlodina Postat Decembrie 8, 2018 Partajează Postat Decembrie 8, 2018 Doar i-mi dau cu parerea - si in final nu vreau decat sa te incurajez sa nu abandonezi. Metoda de a invata programare prin "compilare" cod din diverse surse fara sa intelegi conceptual modul de functionare nu-i cel mai recomandat ... Probabil o idee ar fi sa "rupi" aplicatia in mici module pe care sa le dezvolti (si sa le intelegi) separat ... Deduc din postarea ta: Input: - Temp1 - Temp2 - Foto-cell Out: - sneck t1->ON|OFF, t2->ON|OFF, ... - ventilator -> turatie variabila - bujie - pompa -> ON|OFF Idei: - am putea sa ne facem un pic ordine "in minte" folosind o diagrama de stari (state machine) - acele etape prin care trece mica noastra automatizare. - Timer.h -> probabil fiecare actiune ai putea sa o implementezi intr-o functie si cu ajutorul clasei Timer sa le apelezi la intervalele sau pe perioada dorita Succes Link spre comentariu
mani Postat Decembrie 8, 2018 Autor Partajează Postat Decembrie 8, 2018 Inteleg fiecare lucru din codul care l-am scris si stiu fiecare parte cum functioneaza ,problema e ca nu am lucrat cu timers pana acum . Am cerut un exemplu de cum se aplica un timer la o functie , pentru o iesire digitala stiu sa o fac. Codul nu l-am putut posta tot ca are vreo 7000 de linii si e impartit tot in rutine si subrutine . Multumesc oricum de initiativa. Link spre comentariu
mani Postat Decembrie 9, 2018 Autor Partajează Postat Decembrie 9, 2018 Buna dimineata ,cred ca nu ma exprim corect in ceea ce priveste limbajul de programator si atunci am sa postez din nou o parte din cod in romana cu ce as vrea eu sa faca in timpii respectivi fara sa-mi "paralizeze" arduino. Eu pot intra in meniu si sa reglez parametrii doar cand contactele termostatului sunt deschise prin miscare encoderului, cat timp se deruleaza programul nu am acces la meniu si nici senzorii nu se actualizeaza. Sper sa nu deranjez pe nimeni ca pun iarasi o bucata de cod . Multumesc ,o zi buna va doresc. void setup() { // put your setup code here, to run once: } void loop() { imprima_senzori(); //arata senzorii citeste_senzori(); // meniu(); //se intra in meniu prin rotirea encoderului termostat=digitalRead(thermostat); while(termostat==LOW) { //cat timp contactul este inchis la termostat //se deruleaza programul citeste_senzori(); sterge(0,9,0); sterge(0,9,1); termostat=digitalRead(thermostat); actuador_in_fata(); //aici trebuie ca acesta functie sa ruleze 5 secunde si sa se opreasca actuador_in_spate(); //si sa inceapa aceasta sa ruleze 5 secunde si sa se opreasca curatire_cu_aer(); // urmand sa inceapa aceasta sa ruleze 7 secunde si sa se opreasca prima_incarcare(); //la randul ei acesta functie sa ruleze un timp reglabil intre 5 si 10 secunde } } void actuador_in_fata() { lcd.setCursor(0,0); lcd.print("Limpieza"); sterge(0,8,2); lcd.setCursor(0,3); lcd.print("Raspa"); lcd.setCursor(1,2); lcd.print(">>>"); analogWrite(ventilador, 255); digitalWrite(actuador_inainte,HIGH); digitalWrite(actuador_inapoi,LOW); } void actuador_in_spate() { lcd.setCursor(0,0); lcd.print("Limpieza"); sterge(0,8,2); lcd.setCursor(0,3); lcd.print("Raspa"); lcd.setCursor(1,2); lcd.print("<<<"); analogWrite(ventilador, 255); digitalWrite(actuador_inainte,LOW); digitalWrite(actuador_inapoi,HIGH); } void curatire_cu_aer() { lcd.setCursor(0,3); lcd.print("Aire"); lcd.setCursor(1,2); lcd.write(7); //caracter ventilator lcd.write(8); //caracter ventilator analogWrite(ventilador, 255); sterge(0,4,2); sterge(0,4,3); } void prima_incarcare() { lcd.setCursor(0,0); lcd.print("Carga >>"); lcd.setCursor(0,3); lcd.print("Pelet"); lcd.setCursor(1,2); lcd.write(6); //caracter snec lcd.write(6); //caracter snec lcd.write(6); //caracter snec digitalWrite(sinfin, HIGH); } void imprima_senzori(){ lcd.setCursor(11,0); lcd.print("Ldr:"); lcd.setCursor(15,0); lcd.print(LDR,1); lcd.setCursor(11,1); lcd.print("Fum:"); lcd.setCursor(15,1); lcd.print(Humos,1); lcd.setCursor(11,2); lcd.print("Tur:"); lcd.setCursor(15,2); lcd.print(Caldera,1); } void citeste_senzori() { LDR=analogRead(sensorLDR); String dataString = "sensor1,"; dataString += temp_str; Caldera = thermistorRead(1); dtostrf(Caldera,6,2,temp_str); dataString += "\nsensor2,"; dataString += temp_str; Humos = thermistorRead(2); dtostrf(Humos,6,2,temp_str); dataString += "\nsensor3,"; dataString += temp_str; } void sterge(int first, int last, int row){ for (first ; first < last+1 ; first++){ lcd.setCursor(first,row); lcd.print(" "); } } Link spre comentariu
informer Postat Decembrie 9, 2018 Partajează Postat Decembrie 9, 2018 Ca s-o spunem pe a dreapta, Arduino nu poate face 2 lucruri in acelasi timp... :). Dar, din ce inteleg eu, tu vrei ca indiferent UNDE in program esti sa vezi daca de ex. utilizatorul vrea sa faca ceva... de ex. sa intre in meniu sau orice altceva. Primul lucru pe care ai nevoie sa-l stii este CE FACE USERUL atunci cand vrea ce vrea... de ex. poate apasa un buton.... Pasul urmator este sa te uiti la acel buton, daca a fost apasat sau nu, de peste tot... asta faci setand o intrerupere de timer. In felul asta, din X in X micro/mili/secunde, "programul se uita" daca a fost apasat butonul iar in caz ca da, face vreo actiune. Un exemplu de setare a timerului este asta si-l pui in setup : void setup() { //...................... //set timer1 interrupt every 10ms cli(); TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; OCR1A = 2499; //(16.000.000MHz * 10ms) / 64 -1 TCCR1B |= (1 << WGM12); //CTC mode TCCR1B |= (1 << CS11) | (1 << CS10); //prescaler 64 TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt sei(); //....................... } Asta va avea ca efect ca la fiecare 10ms o sa se execute functia de mai jos: ISR(TIMER1_COMPA_vect) { //aici pui codul pe care vrei sa-l execute periodic //........... } Link spre comentariu
deejay2k1 Postat Decembrie 9, 2018 Partajează Postat Decembrie 9, 2018 trebuie sa renunti la buclele cu while(), sunt ceea ce se numeste blocking functions. incearca sa rescrii programul astfel incat, de exemplu, in loc de while(termostat==LOW) { //cat timp contactul este inchis la termostat //se deruleaza programul citeste_senzori(); sterge(0,9,0); sterge(0,9,1); /* restul functiilor */ } sa scrii ceva de genul if(termostat==LOW && meniuActiv == false) { //cat timp contactul este inchis la termostat si NU esti in meniu, defineste o variabila care sa tina cont de asta ... //se deruleaza programul citeste_senzori(); sterge(0,9,0); sterge(0,9,1); /* retul functiilor */ } rezultatul final ar fi cam acelasi, cu diferenta ca acum nu mai ramai blocat in while() ... relativ la lcd, poti incerca sa-ti definesti un buffer de 2 string-uri x 16 caractere pe care sa-l modifici pe parcursul codului si sa-l scrii o singura data la finalul buclei in lcd. ar scurta semnificativ durata de executie a codului Link spre comentariu
mani Postat Decembrie 9, 2018 Autor Partajează Postat Decembrie 9, 2018 Va multumesc mult , incerc sa modific codul si sa studiez timerele la arduino. Link spre comentariu
mani Postat Decembrie 9, 2018 Autor Partajează Postat Decembrie 9, 2018 Asta cu crearea buferului pentru lcd nu o prea inteleg ,daca esti amabil sa postezi un exemplu. Cum fac sa temporizez o functie 5 secunde de exemplu si sa se opreasca si apoi sa temporizez alta si sa se opreasca . Poate plictisesc cu insistenta mea , asa ca ma scuzati. Link spre comentariu
informer Postat Decembrie 9, 2018 Partajează Postat Decembrie 9, 2018 31 minutes ago, mani said: Cum fac sa temporizez o functie 5 secunde de exemplu si sa se opreasca si apoi sa temporizez alta si sa se opreasca . Poate plictisesc cu insistenta mea , asa ca ma scuzati. In ideea anterioara cu intreruperile, sa zicem ca generezi una la fiecare 100ms. Creezi o variabila pe care o denumesti de ex. timeCounter si pe care o incrementezi la fiecare intrerupere... adica de 10 ori pe secunda pt. exemplul ales. Cand intri in functie aduci la zero contorul (timeCounter = 0) dupa care incepi sa executi ce ai de executat dar te mai uiti din cand in cand la contor in bucla aia de executie... cand asta ajunge la 50, termini functia. La a 2-a functie, reiei procedura... s.a.m.d. Link spre comentariu
mani Postat Decembrie 9, 2018 Autor Partajează Postat Decembrie 9, 2018 Multumesc ,ma apuc de treaba. Link spre comentariu
mihaicozac Postat Decembrie 10, 2018 Partajează Postat Decembrie 10, 2018 (editat) Dacă nu vrei să foloseşti funcţia millis() care e cel mai simplu de folosit, cum au spus colegii foloseşti o variabilă contor care se incrementează la fiecare tură de loop. Dar pt. asta ai nevoie ca acea variabilă să fie iniţializată în funcţia setup(). De ex. ai în setup() counter1 = 0; apoi în loop() counter1++; asta creşte valoarea variabilei cu 1 la fiecare reiterare, iar dacă scrii o condiţie if (counter1) > 100 {......}, după 101 de ture loop() se creeaza condiţia şi se execută ce vrei tu.după care poţi reseta contorul în funcţia condiţiei, de ex. counter1 = 0; şi procesul se reia. Uite de ex. cum am rezolvat eu o funcţie multiplă ca apăsarea unui buton, o apăsare scurtă opreşte un program, una lungă schimbă conţinutul unui display: if (a_6 < 300) { // BUTON STOP stop_prog = true; start_timer = 0; standby_timer = 0; display_timer++; if (display_timer == 10 && stop_prog) { display_status++; //LA APASAREA PRELUNGITA PE STOP SE SCHIMBA CONTINUTUL AFISAJULUI } if (display_timer > 10) { display_timer = 0; } } else { display_timer = 0; } În acest caz variabila contorizată este display_timer. Editat Decembrie 10, 2018 de mihaicozac Link spre comentariu
mani Postat Decembrie 11, 2018 Autor Partajează Postat Decembrie 11, 2018 Buna ,incerc tot ce mi-au propus colegii ,acum intru la munca si saptamana asta nu pot face nimic . Acum am inteles si tema cu display ul.. Multumesc .O zi buna. Link spre comentariu
Liviu M Postat Decembrie 14, 2018 Partajează Postat Decembrie 14, 2018 (editat) Sorry, am sters postul ca tot ce-am zis eu au zis deja colegii mai sus. Cred c-am ratat un refresh de pagina. Editat Decembrie 14, 2018 de Liviu M Link spre comentariu
Postări Recomandate
Creează un cont sau autentifică-te pentru a adăuga comentariu
Trebuie să fi un membru pentru a putea lăsa un comentariu.
Creează un cont
Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!
Înregistrează un nou contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum