GeoMar Postat Martie 11, 2018 Autor Partajează Postat Martie 11, 2018 Am reusit o afisare satisfacatoare a temperaturii citita de DS, in defavoarea stralucirii afisajului. sper ca aceasta deficienta sa o pot corecta prin alimentarea digitilor prin tranzistori, nu direct din pinii Arduino. Momentan asa arata codul folosit, nu stiu cat de bun/corect este, l-am creeat asa cum m-am priceput eu, ca un incepator: // // Sample of using Async reading of Dallas Temperature Sensors // #include <OneWire.h> #include <DallasTemperature.h> #include <SevenSeg.h> // Data wire is plugged into port 2 on the Arduino #define ONE_WIRE_BUS 2 // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); DeviceAddress tempDeviceAddress; SevenSeg disp (8, 10, 6, 4, 3, 9, 7); const int numOfDigits = 4; int digitPins [ numOfDigits ] = { A2, A3, A4, A5}; int resolution = 9; unsigned long lastTempRequest = 0; int delayInMillis = 0; float temperature = 0.0; int idle = 0; // // SETUP // void setup(void) { disp . setDigitPins ( numOfDigits , digitPins ); disp . setDPPin (5) ; disp.setRefreshRate(6000); sensors.begin(); sensors.getAddress(tempDeviceAddress, 0); sensors.setResolution(tempDeviceAddress, resolution); sensors.setWaitForConversion(false); sensors.requestTemperatures(); delayInMillis = 750 / (1 << (9 - resolution)); lastTempRequest = millis(); } void loop(void) { if (millis() - lastTempRequest >= delayInMillis) // waited long enough?? { sensors.requestTemperatures(); temperature = sensors.getTempCByIndex(0); disp. write ((temperature), 1); disp. setRefreshRate(6000); } } Asa arata acum afisarea temperaturii citita de la DS18B20 pe afisajul LED cu 3 digiti. In realitate acel licarit/flicar nu mai este sesizabil/suparator cum era inainte. Vreau acum sa testez inserarea mai multor senzori DS (eventual identificarea lor automata) si afisarea lor ciclic, ca in clipul postat de mine cateva posturi mai sus. Sper sa si reusesc. Link spre comentariu
modoran Postat Martie 11, 2018 Partajează Postat Martie 11, 2018 Nu ar merge un alt doilea microcontroller slave ( ceva foarte ieftin ) care sa citeasca datele de la senzor si sa le puna in memoria RAM ? Astfel procesorul principal doar citeste informatia de acolo ( o data pe secunda sa zicem ). Daca se intampla sa fie "ocupat" procesorul slave doar se face abort si se afiseaza temperatura anterioara. Asa nu va mai exista nici o palpaire. Link spre comentariu
Elison Postat Martie 11, 2018 Partajează Postat Martie 11, 2018 Initial n-am verificat daca libraria folosita suporta intreruperi, mai tarziu am vazut ca pentru pentru ATmega 168 si 328 sunt suportate intreruperile generat de timerul 0,1 si 2. Am modificat putin codul din prima postare astfel incat sa se foloseasca, pentru multiplexare, intreruperea generata de timer 2. Pe display la fiecare secunda este incrementat un contor incepand de la valoarea 1000. Verificati daca mai aveti acea palpaire. #include <SevenSeg.h> //#include <OneWire.h> //#include <DallasTemperature.h> SevenSeg disp (8, 10, 6, 4, 3, 9, 7); const int numOfDigits = 4; int digitPins [ numOfDigits ] = { A2, A3, A4, A5}; //#define ONE_WIRE_BUS 2 //OneWire oneWire(ONE_WIRE_BUS); //DallasTemperature sensors(&oneWire); void setup() { disp . setDigitPins ( numOfDigits , digitPins ); disp . setDPPin (5) ; // sensors.begin(); disp.setDutyCycle(100); disp.setRefreshRate(100); disp . setTimer (2) ; disp . startTimer () ; } void loop() { for ( int i=1000;i <=9999; i ++) { disp . write (i); delay (1000) ; } } ISR ( TIMER2_COMPA_vect ){ disp . interruptAction () ; } Link spre comentariu
GeoMar Postat Martie 11, 2018 Autor Partajează Postat Martie 11, 2018 Multumesc pentru implicare. Maine seara dupa servici testez codul postat si revin cu informatii Dupa cate imi amintesc eu, am testat si ceva afisari cu aceste intreruperi, tot apare fliker. Cred ca este vorba de citirea DS-ului care baga intarzieri si apare acel fliker. La testarea cu un counter afisat pe digiti, nu se sesizeaza acel fliker suparator. Link spre comentariu
cimitavita Postat Martie 11, 2018 Partajează Postat Martie 11, 2018 poti rezolva usor cu 74373, 74374, 74573 sau 74574 daca afisajul e facut din digiti separati. Cu 74573 sau 74574 cablajul se face mai usor deoarece au intrarile intr-o parte si iesirile in cealalta parte. Este nevoie de cate un circuit si 8 rezistente pentru fiecare digit. In felul asta se multiplica un port. Afisarea se face pe toti digitii odata si ia timp foarte scurt deoarece 74573 sau 574 merg la frecvente de minim 40MHz. Link spre comentariu
deejay2k1 Postat Martie 12, 2018 Partajează Postat Martie 12, 2018 (editat) incearca sa folosesti un modul dedicat, sunt relativ ieftine la 1.5 USD, si scapi de toata bataia de cap cu multiplexarea. Dacă vrei sa continui cu multiplexarea în Arduino, va trebui sa modifici toate funcțiile tale sa nu folosească delay(), adică non-blocking. Este destul de complicat, dar se poate face cu (multă) răbdare ... Editat Martie 12, 2018 de deejay2k1 Link spre comentariu
Ionut Remus Postat Martie 12, 2018 Partajează Postat Martie 12, 2018 http://www.qsl.net/yo6pir/rtc.html Vezi in link cei 4 tranzistori pentru fiecare digit in parte si fa o adaptare pt ce ai nevoie, in principiu ar trebui sa ajute dar nu stiu cat! Link spre comentariu
GeoMar Postat Martie 12, 2018 Autor Partajează Postat Martie 12, 2018 (editat) Acum 22 ore, Elison a spus: Initial n-am verificat daca libraria folosita suporta intreruperi, mai tarziu am vazut ca pentru pentru ATmega 168 si 328 sunt suportate intreruperile generat de timerul 0,1 si 2. Am modificat putin codul din prima postare astfel incat sa se foloseasca, pentru multiplexare, intreruperea generata de timer 2. Pe display la fiecare secunda este incrementat un contor incepand de la valoarea 1000. Verificati daca mai aveti acea palpaire. Am testat codul, apare contorul, DAR si acel fliker. Acum 19 ore, cimitavita a spus: poti rezolva usor cu 74373, 74374, 74573 sau 74574 daca afisajul e facut din digiti separati. Cu 74573 sau 74574 cablajul se face mai usor deoarece au intrarile intr-o parte si iesirile in cealalta parte. Este nevoie de cate un circuit si 8 rezistente pentru fiecare digit. In felul asta se multiplica un port. Afisarea se face pe toti digitii odata si ia timp foarte scurt deoarece 74573 sau 574 merg la frecvente de minim 40MHz. Poate incerc ceva cu 74HC595. Acum 11 ore, deejay2k1 a spus: incearca sa folosesti un modul dedicat, sunt relativ ieftine la 1.5 USD, si scapi de toata bataia de cap cu multiplexarea. Acele module au pret mic, intradevar, dar au digitii prea mici, parca de 0,39 inch, am sa incerc cu 4 matrici 8x8 LED cu MAX7219 Acum 3 ore, Ionut Remus a spus: http://www.qsl.net/yo6pir/rtc.html Vezi in link cei 4 tranzistori pentru fiecare digit in parte si fa o adaptare pt ce ai nevoie, in principiu ar trebui sa ajute dar nu stiu cat! Am sa testez, asa cum am scris si alimentarea digitilor, ori cu tranzistori, ori folosesc ceva integrate gen ULN2003 si ULN2803 Multumesc tuturor pentru implicare. Ramane sa testez serile urmatoare, un ceas-termometru folosind DS18B20 , cu 4 matrici 8x8 led - MAX7219 ( le am pe stoc deja) si un Arduino Nano sau Uno. Edit. Am conectat un afisaj de 4 afisaje matrix 8x8 led-uri cu MAX7219, am incarcat codul de mai jos, DAR (iar un dar) nu merge ok. Codul: // Use the MD_MAX72XX library to scroll text on the display // // Demonstrates the use of the callback function to control what // is scrolled on the display text. // // User can enter text on the serial monitor and this will display as a // scrolling message on the display. // Speed for the display is controlled by a pot on SPEED_IN analog in. #include <MD_MAX72xx.h> #include <SPI.h> #define USE_POT_CONTROL 1 #define PRINT_CALLBACK 0 #define PRINT(s, v) { Serial.print(F(s)); Serial.print(v); } // Define the number of devices we have in the chain and the hardware interface // NOTE: These pin numbers will probably not work with your hardware and may // need to be adapted #define MAX_DEVICES 8 #define CLK_PIN 13 // or SCK #define DATA_PIN 11 // or MOSI #define CS_PIN 10 // or SS // SPI hardware interface MD_MAX72XX mx = MD_MAX72XX(CS_PIN, MAX_DEVICES); // Arbitrary pins //MD_MAX72XX mx = MD_MAX72XX(DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES); // Scrolling parameters #if USE_POT_CONTROL #define SPEED_IN A5 #else #define SCROLL_DELAY 75 // in milliseconds #endif // USE_POT_CONTROL #define CHAR_SPACING 1 // pixels between characters // Global message buffers shared by Serial and Scrolling functions #define BUF_SIZE 75 char curMessage[BUF_SIZE]; char newMessage[BUF_SIZE]; bool newMessageAvailable = false; uint16_t scrollDelay; // in milliseconds void readSerial(void) { static uint8_t putIndex = 0; while (Serial.available()) { newMessage[putIndex] = (char)Serial.read(); if ((newMessage[putIndex] == '\n') || (putIndex >= BUF_SIZE-3)) // end of message character or full buffer { // put in a message separator and end the string newMessage[putIndex++] = ' '; newMessage[putIndex] = '\0'; // restart the index for next filling spree and flag we have a message waiting putIndex = 0; newMessageAvailable = true; } else if (newMessage[putIndex] != '\r') // Just save the next char in next location putIndex++; } } void scrollDataSink(uint8_t dev, MD_MAX72XX::transformType_t t, uint8_t col) // Callback function for data that is being scrolled off the display { #if PRINT_CALLBACK Serial.print("\n cb "); Serial.print(dev); Serial.print(' '); Serial.print(t); Serial.print(' '); Serial.println(col); #endif } uint8_t scrollDataSource(uint8_t dev, MD_MAX72XX::transformType_t t) // Callback function for data that is required for scrolling into the display { static char *p = curMessage; static uint8_t state = 0; static uint8_t curLen, showLen; static uint8_t cBuf[8]; uint8_t colData; // finite state machine to control what we do on the callback switch(state) { case 0: // Load the next character from the font table showLen = mx.getChar(*p++, sizeof(cBuf)/sizeof(cBuf[0]), cBuf); curLen = 0; state++; // if we reached end of message, reset the message pointer if (*p == '\0') { p = curMessage; // reset the pointer to start of message if (newMessageAvailable) // there is a new message waiting { strcpy(curMessage, newMessage); // copy it in newMessageAvailable = false; } } // !! deliberately fall through to next state to start displaying case 1: // display the next part of the character colData = cBuf[curLen++]; if (curLen == showLen) { showLen = CHAR_SPACING; curLen = 0; state = 2; } break; case 2: // display inter-character spacing (blank column) colData = 0; curLen++; if (curLen == showLen) state = 0; break; default: state = 0; } return(colData); } void scrollText(void) { static uint32_t prevTime = 0; // Is it time to scroll the text? if (millis()-prevTime >= scrollDelay) { mx.transform(MD_MAX72XX::TSL); // scroll along - the callback will load all the data prevTime = millis(); // starting point for next time } } uint16_t getScrollDelay(void) { #if USE_POT_CONTROL uint16_t t; t = analogRead(SPEED_IN); t = map(t, 0, 1023, 25, 250); return(t); #else return(SCROLL_DELAY); #endif } void setup() { mx.begin(); mx.setShiftDataInCallback(scrollDataSource); mx.setShiftDataOutCallback(scrollDataSink); #if USE_POT_CONTROL pinMode(SPEED_IN, INPUT); #else scrollDelay = SCROLL_DELAY; #endif strcpy(curMessage, "G E O M A R"); newMessage[0] = '\0'; Serial.begin(57600); Serial.print("\n[MD_MAX72XX Message Display]\nType a message for the scrolling display\nEnd message line with a newline"); } void loop() { scrollDelay = getScrollDelay(); readSerial(); scrollText(); } Afisajul folosit: De exemplu vreau sa afisez GEOMAR dar se vad in öglinda" literele ca in clip Editat Martie 12, 2018 de GeoMar Pentru a nu creea dublu post Link spre comentariu
cimitavita Postat Martie 12, 2018 Partajează Postat Martie 12, 2018 (editat) daca te uiti in datasheet o sa vezi ca MAX7219 are si iesire cu care poate comanda urmatorul MAX7219 s.a.m.d. Din film se vede ca programul care l-ai facut trimite GEOMAR doar la primul MAX7219. Apoi datele se duc la al doilea dar fara ultimii 8 biti. La fel se intampla si cu al treilea, dar fara ultimii 16 biti. Mai pe scurt: libraria folosita nu stie ca sunt legate 4 MAX7219 in serie ci crede ca e doar unul singur. Trebuie sa vezi daca libraria folosita permite legarea la mai multe MAX7219 in serie. Sau sa incerci sa trimita mai intai LSB si apoi MSB. Atat la biti cat si la octeti. In asamblare chestia asta e foarte usor de facut. Editat Martie 12, 2018 de cimitavita Link spre comentariu
deejay2k1 Postat Martie 13, 2018 Partajează Postat Martie 13, 2018 Incearca biblioteca MAX72xxPanel: https://github.com/markruys/arduino-Max72xxPanel Este scalabila si poti seta rotatia #include <SPI.h> #include <Adafruit_GFX.h> #include <Max72xxPanel.h> #define pinCS 10 // Attach CS to this pin, DIN to MOSI and CLK to SCK (cf http://arduino.cc/en/Reference/SPI ) #define numberOfHorizontalDisplays 4 #define numberOfVerticalDisplays 1 Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays); const String tape = "Ana are mere. Mici ! "; #define wait 20 // In milliseconds int spacer = 1; int width = 5 + spacer; // The font width is 5 pixels void setup() { matrix.setIntensity(1); // Use a value between 0 and 15 for brightness // Adjust to your own needs // matrix.setPosition(0, 0, 0); // The first display is at <0, 0> // matrix.setPosition(1, 1, 0); // The second display is at <1, 0> // matrix.setPosition(2, 2, 0); // The third display is at <2, 0> // matrix.setPosition(3, 3, 0); // And the last display is at <3, 0> // ... matrix.setRotation(0, 1); // The first display is position upside down matrix.setRotation(1, 1); matrix.setRotation(2, 1); matrix.setRotation(3, 1); // The same hold for the last display } void loop() { for ( int i = 0 ; i < width * tape.length() + matrix.width() - 1 - spacer; i++ ) { // matrix.fillScreen(LOW); // matrix.write(); // Send bitmap to display int letter = i / width; int x = (matrix.width() - 1) - i % width; int y = (matrix.height() - 8) / 2; // center the text vertically while ( x + width - spacer >= 0 && letter >= 0 ) { if ( letter < tape.length() ) { matrix.drawChar(x, y, tape[letter], HIGH, LOW, 1); } letter--; x -= width; } matrix.write(); // Send bitmap to display delay(wait); } } Link spre comentariu
GeoMar Postat Martie 13, 2018 Autor Partajează Postat Martie 13, 2018 Acum 10 ore, cimitavita a spus: daca te uiti in datasheet o sa vezi ca MAX7219 are si iesire cu care poate comanda urmatorul MAX7219 s.a.m.d. Din film se vede ca programul care l-ai facut trimite GEOMAR doar la primul MAX7219. Apoi datele se duc la al doilea dar fara ultimii 8 biti. La fel se intampla si cu al treilea, dar fara ultimii 16 biti. Mai pe scurt: libraria folosita nu stie ca sunt legate 4 MAX7219 .... Codul este preluat dupa net cu librariile aferente. De unde am luat codul afisa ok. Acum 3 ore, deejay2k1 a spus: Incearca biblioteca MAX72xxPanel: https://github.com/markruys/arduino-Max72xxPanel Este scalabila si poti seta rotatia Am sa testez diseara si acest cod. Multumesc la amandoi pentru ajutor. Link spre comentariu
GeoMar Postat Martie 13, 2018 Autor Partajează Postat Martie 13, 2018 Acum 10 ore, deejay2k1 a spus: Incearca biblioteca MAX72xxPanel: https://github.com/markruys/arduino-Max72xxPanel Este scalabila si poti seta rotatia Codul testat de mine este preluat de pe net, asa cum am mai mentionat, foloseste alte biblioteci, cu parere de rau nu am testat codul tau, am remediat defectul, remediu care il prezint mai jos, poate se lovesc si altii de aceasta situatie. Am folosit in codul meu (preluat) librariile: MD_Parola-master MD_MAX72XX-master Dupa ceva cautari pe net, am descoperit ca se poate remedia acea eroare de scrolling-afisare, prin simpla editare a unei singure linii din libraria MD_MAX72XX-master (probabil si alte librarii). Am editat fisierul "MD_MAX72xx.h" cu ajutorul lui Notepad++, apoi am salvat, din informatiile gasite pe net, se pare ca am depistat modulul folosit de mine, este "FC16". Aici am modificat in linia incercuita din foto, din "0"in "1"si acum scrollingul si afisarea este acum in regula: Am facut si un mic test video, unde am folosit 8 module, nu 4 module, dupa cum se vede in clip si merge ok scrollingul-afisarea: Ramane acum sa inteleg functionarea-afisarea cu MAX7219 si sa incerc sa adaug-afisez in cod un ceas cu RTC1307 si 2-3 temperaturi cu DS18B20. Orice sfat-idee, sunt binevenite, asa cum am mai scris sunt incepator, trebuie sa le iau pe rand ca sa invat ceva si sa iasa ceea ce imi doresc eu. Link spre comentariu
GeoMar Postat Martie 18, 2018 Autor Partajează Postat Martie 18, 2018 Revin cu ceva nelamuriri. Am reusit sa realizez un ceas-termometru cu 3 senzori DS cu ajutorul lui Niq_ro (ii multumesc de sprijin/ajutor), functioneaza ok partea de ceas si partea de temperatura. Astazi fiind ceva mai frig afara, am remarcat ca la temperaturi de sub 0 grade nu afiseaza corect. Nu vreu sa-l mai deranjez/stresez pe Niq_ro, de aceea apelez aici pe forum. Partea de cod care se ocupa de afisarea temperaturii pe afisaj dotmatrix este: [code] //====== Temperatura 2 ========= senzori.requestTemperatures(); t2 = senzori.getTempC(senzor2); Serial.print("Temp C: "); Serial.println(t2); int t2a = 10 * t2; int tz2 = t2a / 100; t2a = t2a - tz2 * 100; int tu2 = t2a / 10; int ts2 = t2a % 10; Serial.print("="); Serial.print(tz2); Serial.print(tu2); Serial.print(","); Serial.print(ts2); Serial.println(" C"); scrollMessage(temperatura2); if (t2a > 0) { loadBufferLong(43); // + } else { loadBufferLong(45); // + t2a = -t2a; } loadBufferLong(48 + tz2); // 2 loadBufferLong(48 + tu2); // 1 loadBufferLong(44); // , loadBufferLong(48 + ts2); // 7 loadBufferLong(0x7F); // degree sign loadBufferLong(67); // C delay(2000); [/code] Temperatura citita de la senzorul DS este salvata initial in : "float t1;" La temperaturi sub 0 grade asa afiseaza in comparatie cu alt ceas realizat de mine : Link spre comentariu
deejay2k1 Postat Martie 18, 2018 Partajează Postat Martie 18, 2018 (editat) Imi este greu sa inteleg bucata ta de cod fara context, dar mi se pare ca trebuia sa afiseze -01,3°C, dar ai gresit undeva cu schimbatul semnelor. Caracterul '/' este diametral opus fata de '0' (sau 48 in zecimal), la fel si '-' fata de '3' ASCII Table Presupun deci ca tz2 si tu2 sunt negative atunci cand le aduni cu 48 ca sa obtii codul ascii afisat incearca rapid modificarea asta: loadBufferLong(48 + abs(tz2)); // 2 loadBufferLong(48 + abs(tu2)); // 1 sau mai bine pune lucrurile in ordine //====== Temperatura 2 ========= senzori.requestTemperatures(); t2 = senzori.getTempC(senzor2); Serial.print("Temp C: "); Serial.println(t2); scrollMessage(temperatura2); if (t2 > 0.0f) { loadBufferLong(43); // + } else { loadBufferLong(45); // + t2 = -t2; } int t2a = 10 * t2; int tz2 = t2a / 100; t2a = t2a - tz2 * 100; int tu2 = t2a / 10; int ts2 = t2a % 10; Serial.print("="); Serial.print(tz2); Serial.print(tu2); Serial.print(","); Serial.print(ts2); Serial.println(" C"); loadBufferLong(48 + tz2); // 2 loadBufferLong(48 + tu2); // 1 loadBufferLong(44); // , loadBufferLong(48 + ts2); // 7 loadBufferLong(0x7F); // degree sign loadBufferLong(67); // C delay(2000); Editat Martie 18, 2018 de deejay2k1 Link spre comentariu
GeoMar Postat Martie 18, 2018 Autor Partajează Postat Martie 18, 2018 Am incercat asa, dupa ce citeste temperatura t1 de la senzor , am setat eu in cod temperatura senzorului ca t1= -11,9 (asta ca sa nu stau cu senzorul in frigider ca sa dea cu minus) si am testat pe serial. La valoarea lui t1 = -11.9 imi arata pe serial -1-1.0 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