Jump to content
ELFORUM - Forumul electronistilor

Marin1960

Membru activ
  • Posts

    128
  • Joined

  • Last visited

About Marin1960

  • Birthday 08/04/1960

Profile Fields

  • Location
    Bucuresti

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

Marin1960's Achievements

Enthusiast

Enthusiast (6/14)

  • First Post
  • Collaborator
  • Conversation Starter
  • Week One Done
  • One Month Later

Recent Badges

  1. In urma cu doi ani am facut un ceas cu sincronizare prin GPS. Am ales GPS-ul pentru ca in locatia respectiva nu aveam internet si voiam sa sincronizez simultan mai multe ceasuri (aveam cate un ceas in fiecare camera). Ceasul este facut cu un arduino pro mini, radio nrf24l01 pentru sincronizare, rtc DS3231 si senzori de temperatura: DS18B20, LM75, DHT11 sau 22 cu selectare automata. Sincronizarea se face la cerere sau la ora fixa. Prototipul nu avea radio nici rtc, faceam sincronizarea permanent prin seriala. Asta era posibil datorita distantei mici de la fereastra unde era GPS-ul si locul unde era amplasat ceasul.
  2. Varianta cu blocking minim pentru fiecare masuratoare (delay-ul din loop si durata functiei pulseIn(), aproximativ 3ms pentru 1 metru): ... byte i = 0; ... void loop() { start_echo(); pulse_in(i); i++; if(i>2) i=0; delay(100); } //-------------------------------------- void pulse_in(byte i){ duration[i] = pulseIn(echoPin[i],HIGH); distance[i] = duration[i]*cst_vs; } Problema mare eu o vad la partea de if-uri care actioneaza la atingerea unui anume nivel (de la 25% la 100%). Un bazin cu apa se umple destul de incet, ca sa nu mai spun ca la suprafata apei se vor face valuri, indiferent de metoda de umplere (pe sus, apar valuri mari, pe jos, valuri mai mici). Pe de alta parte, un senzor HC-04 nu este foarte stabil, in concluzie ar trebui introdus un histerezis la fiecare nivel, pentru o actionare ferma si stabila. Ceva ca mai jos: //a0 este un nivel prestabilit (a0=80) //a = a0 void nivel(){ if(distance >= a){ a = a0 - histerezis; //actiune, Led on } else{ a = a0 + histerezis; //actiune, Led off } }
  3. O alta idee fara atatea if-uri: /* * examplu cu 3 HC-SR04 */ //-------------------------------------- const int trigPin = 8; //const int echoPin1 = 9, echoPin2 = 10, echoPin3 = 11; const int echoPin[3] = {9,10,11}; const float cst_vs = 0.01715; unsigned long duration[3]; float distance[3]; //-------------------------------------- void setup() { pinMode(trigPin, OUTPUT); pinMode(echoPin[0], INPUT_PULLUP); pinMode(echoPin[1], INPUT_PULLUP); pinMode(echoPin[2], INPUT_PULLUP); Serial.begin(9600); } //-------------------------------------- void loop() { pulse_3in(); } //-------------------------------------- void pulse_3in(){ for(byte i=0;i<3;i++){ start_echo(); duration[i] = pulseIn(echoPin[i],HIGH); distance[i] = duration[i]*cst_vs; Serial.print(distance[i]); Serial.print(" "); delay(100); } Serial.println(); } //-------------------------------------- void start_echo(){ digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); } //-------------------------------------- Ambele variante au fost testate.
  4. O idee care sa foloseasca mai putini pini, ar fi sa folosesti trigPin comun pentru toti cei 3 senzori si sa citesti cu o functie care emuleaza functia pulseIn, dar pentru toate cele 3 intrari: [code] /* * examplu cu 3 HC-SR04 */ //-------------------------------------- const int trigPin = 8; const int echoPin1 = 9, echoPin2 = 10, echoPin3 = 11; float duration1, duration2,duration3,distance1,distance2,distance3; //-------------------------------------- void setup() { pinMode(trigPin, OUTPUT); pinMode(echoPin1, INPUT_PULLUP); pinMode(echoPin2, INPUT_PULLUP); pinMode(echoPin3, INPUT_PULLUP); Serial.begin(9600); } //-------------------------------------- void loop() { start_echo(); pulse_3in(); distance1 = (duration1*.0343)/2; distance2 = (duration2*.0343)/2; distance3 = (duration3*.0343)/2; Serial.print(distance1); Serial.print(" "); Serial.print(distance2); Serial.print(" "); Serial.println(distance3); delay(250); } //-------------------------------------- void start_echo(){ digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); } //-------------------------------------- void pulse_3in(){ byte start1 = 0, end1 = 0; byte start2 = 0, end2 = 0; byte start3 = 0, end3 = 0; unsigned long s1, e1, s2, e2, e3, s3, w; w = millis(); //timeout while(millis()-w<500){ if(digitalRead(echoPin1) && !start1) { start1=1; s1=micros(); } if(!digitalRead(echoPin1) && start1==1) { start1=2; e1=micros(); } //------- if(digitalRead(echoPin2) && !start2) { start2=1; s2=micros(); } if(!digitalRead(echoPin2) && start2==1) { start2=2; e2=micros(); } //------- if(digitalRead(echoPin3) && !start3) { start3=1; s3=micros(); } if(!digitalRead(echoPin3) && start3==1) { start3=2; e3=micros(); } if(start1+start2+start3==6) break; } duration1 = e1-s1; duration2 = e2-s2; duration3 = e3-s3; } [/code] Ce faci apoi cu distantele respective (adancimea apei din fiecare bazin) e o alta poveste...
  5. De cand Microchip a cumparat Atmel si a iesit pe piata cu noile avr-uri, mi-am dorit sa lucrez cu ele. Proiectul asta a fost tocmai in acest scop: o aplicatie simpla, pentru un procesor de generatie noua, attiny1614 (attiny814). Am utilizat mediul IDE Arduino, ca-i simplu si printr-o simpla apasare, transferi programul in procesor! Revenind la aplicatie, am modificat programul sa recunoasca automat ce driver led este pe placa: TM1637 (afisare anod comun) sau TM1638 (afisare catod comun) prin utilizarea semnalului ack pe care TM1637 il genereaza la fiecare comanda/data. Daca nu e montat sau semnalele nu ajung la procesor, rezultatul va fi, probabil un dezastru... Pentru asta vezi fisier ino si h. Recitind postul mi-am dat seama ca ceasul nu este bine descris din punct de vedere al functionalitatii. Afisarea se face pe 4 digiti, ore:min. Afisajul dedicat mi-a permis sa utilizez ledurile din mijloc pentru "bataia" secundelor si ledul din dreapta jos pentru afisarea dst (ora de vara/iarna activa). Ledurile din stanga ar putea fi utilizate pentru alarma, intr-o dezvoltare ulterioara. Pentru potrivire sunt 3 butoane, Set, Down si Up. La apasarea butonului Set se intra intr-un meniu circular, unde potrivirea se face din butonele Down si/sau Up. 1 - set minute, secundele se reseteaza 2 - set ore 3 - set an 4 - set luna 5 - set data (data maxima este in functie de luna aleasa si an bisect sau nu) 6 - set dst ("dst 0", nu este activ, "dst 1", ajusteaza automat ora de vara/iarna) 7 - set bright ( 0...7, a. "a" luminozitatea este pe automat) 8 - set option (1...6) 9 - set offset temperatura (-9...9) 10-set aging (-99...99) Option este in functie de tipul de senzor folosit: 1 - timp (sau fara senzor) 2 - 8 sec timp + 2 sec temperatura 3 - 8 sec timp + 2 sec umiditate (daca senzor este DHT11 sau DHT22) 4 - 8 sec timp +2 sec temperatura + 8 sec timp + 2 sec umiditatea (daca senzor este DHT11 sau DHT22) 5 - temperatura 6 - umiditatea (daca senzor este DHT11 sau DHT22) Daca se alege o optiune pentru care senzorul utilizat nu este capabil sau nu exista, se va afisa timpul. Temperatura afisata se poate ajusta, prin introducerea unui offset (-9...9 grade celsius). Pentru precizia ceasului se poate modifica frecventa oscilatorului din DS3231, in domeniul -99...99. La 25 grade celsius, fiecare LSB modifica aproximativ 0,1 ppm din frecventa. In starea afisare timp, daca se apasa Up, se afiseaza pentru 5 secunde versiunea ceasului "cr 2" (ceas revizia 2), urmat pentru 5 secunde de tipul de driver de led existent "dr 0" pentru TM1637 (1 pentru TM1638). Apasarea pe butonul Down, afiseaza pentru 5 secunde data, urmata de afisarea pentru 5 secunde a anului. Versiunea 2 atasata are un meniu restrans (1-7). CeasTM163x_v2.zip
  6. One Wire are delayMicroseconds(), dar le poti inlocui cu micros() sau millis(), astfel incat programul tau sa nu aiba intarzieri. Fiind un 1wire personalizat, poti avea timinguri mai flexibile, un reset urmat de 3-4 biti (asta iti ofera deja 8-16 stari transmise) fiind suficient, cred, pentru ceea ce vrei. One Wire este destul de usor de implementat, fie cu delay-uri, fie cu micros sau millis.
  7. Acum ca am prezentat cat de cat proiectul, asi vrea sa am un singur soft pentru toate variantele. In acest moment, din schita, se alege varianta de driver dorita. Ca cele doua drivere sa coexiste in soft ar trebui sa decid intr-un fel ce driver hard este pe placa, sa pot alege driverul soft corect. Informatia asta ar putea sa fie pe un pin (0 pentruTM1637 si 1 pentru TM1638, un strap la Gnd sau Vdd). Ma intreb, insa, daca nu ar fi posibil doar soft. Pentru TM1637 ar fi destul de simplu, la fiecare octet scris (comanda sau data), el raspunde cu un ACK. Daca am ack inseamna ca TM1637 este prezent, daca nu, ar putea fi TM1638? Dar cum pot sa fiu sigur de asta? Aici m-am blocat.
  8. Da, rezolvarea prin soft era posibila, dar... Mi-a placut tare mult ideea din libraria https://github.com/avishorp/TM1637, in care starile HIGH si LOW ale pinului de date sunt realizate doar prin schimbarea starii pinului din INPUT in OUTPUT in timp ce portul respectiv este tot timpul LOW! Sa ma explic: - se initializeaza pinul de date in INPUT si portul aferent in LOW (pinul va fi HIGH datorita rezistentei externe) void tm163x_init(){ .... pinMode(pinDio,INPUT); digitalWrite(pinDio, LOW); .... } -starea HIGH a pinului de date va fi prin "tragerea" de catre rezistenta externa de pullup. void pinDioHigh(){ pinMode(pinDio, INPUT); tm_delay(); } -starea LOW a pinului de date va fi facuta prin trecerea pinului in stare de iesire (portul fiind deja configurat in stare LOW) void pinDioLow(){ pinMode(pinDio, OUTPUT); tm_delay(); } Ideea m-a cucerit si am preferat lipirea unei rezistente. Similar pentru pinul de Clock.
  9. Schema utilizata are cateva erori, dar asa am trimis-o chinezului, si este functionala: Principala eroare e ca am uitat rezistentele de pullup pentru Date si Clock (testele pe modulele chinezesti au functionat bine, ca aveau rezistentele puse). Rezolvarea se vede in imaginea de mai jos, o rezistenta pusa pe linia de Date, intre doua treceri (via) existente. Un cablaj populat cu attiny1634 si tm1638. In fundal rtc-ul DS3231. Alimentarea se face de la 9-12V printr-o sursa in comutatie model "Modul DC-DC Step-Down MP1584EN" sau "Modul DC-DC Step Down Mini-360". Driverele TM1637 si TM1638 sunt de la chinezi si sunt foarte ieftine. Softul este facut compact, singurele librarii sunt de "WIRE", "EEPROM" si "INTERRUPT" (vezi schita ino). Nu am utilizat librarii pentru TM163x, am facut drivere personalizate pentru aplicatia asta.
  10. Ceasul este construit pe platforma arduino megaTinyCore dezvoltata de Spence Konde. Mai multe amanunte gasiti pe https://github.com/SpenceKonde/megaTinyCore. Am utilizat un attiny din seria 1, ATTiny 1614, produs de Microchip si ca driver pentru display cu anod comun, TM1637 si TM1638 pentru display cu catod comun. Afisorul utilizat este dedicat: https://www.lucklight.com/UploadFiles/pdf_2013112413853445751.pdf. Driverele TM1637 si TM1638 sunt destul de populare, in afara de foile de catalog, m-am inspirat si din http://www.microcontroller.it/mC_tutor.htm. Ceasul realizat arata ca mai jos: in afara de cei 4 digiti, ledul din dreapta il folosesc pentru afisarea dst, ledurile din mijloc, "bat" secunda, iar cele din stanga pentru o dezvoltare ulterioara (probabil, alarma). Deasupra digitului din dreapta este montat senzorul de lumina. Butoanele Set, Down, Up sunt montate in partea dreapta pe spate (sa intru in dimensiunea chinezului). Ca RTC, am utilizat popularul DS3231, iar ca senzor de temperatura, poate fi folosit senzorul intern al DS3231 (destul de imprecis), senzor pe i2c din seria LM75, senzor 1Wire din seria DS18B20 sau DS18S20, senzor de temperatura si umiditate din seria DHT11 sau DHT22. Senzorii sunt recunoscuti automat, suporta doar un singur senzor atasat (in afara de cel din rtc). Pentru programarea procesorului, am construit mai multe programatoare care suporta UPDI, cum ar fi "jtag2UPDI" sau "mEDBG", etc. Amanunte pentru "jtag2UPDI" pe care-l folosesc cel mai des, gasiti pe https://github.com/SpenceKonde/AVR-Guidance/blob/master/UPDI/jtag2updi.md. Versiunea 1 atasata, are doar functia de ceas, dar poate fi folosita pentru oricare din driverele TM163x. CeasTM163x_v1.zip
  11. A sosit pachetul, T470 merge perfect. Multumesc!
  12. Letconul JBC T470 pentru mine, va rog! Adresa o aveti pe privat.
  13. Codul postat (calcul_zi_saptamana.asm) vad ca e scris pentru AVR, desi eu, nu stiu de ce, am ramas cu impresia ca este scris pentru Z80! Elegant cod si bine comentat! Felicitari! Cat despre senzorul de temperatura, pentru ca l-am pus direct pe cablaj, imi arata o temperatura putin mai mare (nu am verificat cu cat) din cauza incalzirii cablajului de la afisaj si de la regulatorul 7805. Din acest motiv, foarte aproape de terminalele care sunt la masa, am lipit o tabla de Cu de 0,7mm grosime, 3mm latime si 30mm lungime ca radiator si stabilizator termic ca in imaginea de mai jos: Temperatura este stabila si foarte aproape de un termometru "etalon" cu 18B20.
  14. Cu alte cuvinte, pentru secolul 21, avem dow = (Date + YY + YY/4 + Mcode)%7, unde YY=ultimele doua cifre din an (2018 => YY=18), Date este data din luna (1...28/29/30/31), Mcode, codul corespunzator de la punctul 2. Am verificat codul si, intr-adevar "merge" foarte bine in intervalul 2000-2099. In aplicatia mea am nevoie doar de o anume zi din luna si anume pentru data de 31 Martie, respectiv Octombrie. Daca stiu ce zi este in acea data, in functie de an, prin scaderea zilei din 31, aflu data pentru ultima duminica din luna respectiva a acelui an, necesara pentru calculul dst. Exemplu pentru Martie 2018, data de 31 Martie cade intr-o sambata (31+18+4+2)%7=6, (numerotarea 0=duminica, 1=luni, 2=marti, etc) si ultima duminica va fi in data de 31-6=25 Martie (la fel pentru Octombrie). Cei doi algoritmi sunt similari, al tau este chiar mai bun pentru ca valorile calculate pentru dow, sunt pozitive pe tot intervalul, la mine pentru primii doi ani din secol devin negative. Cred ca voi utiliza pentru urmatoarele versiuni ale ceasurilor mele, algoritmul tau. Multumesc! PS. Am lucrat si eu cu Z80 acu mai bine de 25 de ani si cu fratele mai mare Z80180 acu cativa ani... ce vremuri:) Obs. Vezi ca la punctul 5, ar trebui 28%7=0 si ziua este duminica, nu miercuri.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.Terms of Use si Guidelines