Fórum témák

» Több friss téma
Fórum » Arduino
A klónok CH340 Soros-USB illesztőjének drivere (Letöltés)
Lapozás: OK   763 / 850
(#) DJozso hozzászólása Jan 18, 2023 /
 
Sajnos ismét elakadtam, és mint mindig hozzátok fordulok segítségért. Előre is köszönöm. Adott egy aksi figyelő , aminek van 2 db RS485-öt használó kommunikációs csatlakozója. Egyiket a kijelzője használja adat kiolvasásra. A másikat szerettem volna használni, hasonló célra, viszont a két csati nem független egymástól. A szabad csatlakózóra rákötött RS485 TTL fordító Tx lábán folyamatosan jön az adatcsomag úgy 500-700ms-onként. Az adatcsomag tartalmazza a parancsot, illetve az erre adott választ is, összesen olyan 300 byte méretben. Csak hogy ez nem fér bele a ESP32 soros bufferébe. A buffer túlcsordulásánál az első 128 byte marad meg, vagy az utolsó? Amennyiben kihúzom a kijelző csatlakozóját, akkor tudok parancsot küldeni, adatot fogadni, ami nincs 128byte. Arra gondoltam, hogy kiűriteném a buffert, majd a fordító tápját bekapcsolná az ESP, mondjuk várna addig, míg adat lesz a bufferbe, majd mondjuk 200ms később (hogy mind a 128 byte megérkezzen) kikapcsolná a fordító tápját. Így megmaradna az üzenet első 128 byte-ja. Nekem ezen bájtokban van a szükséges adat. A többi az beállítás, arra nekem nincs szükségem, nem baj, ha elveszik. Vagy létezik olyan IC amivel az RS485 A,B pontjait lehet ki-be kapcsolgatni, így ki tudom kapcsolni a kijelző kommunikációját?! Ti, hogyan oldanátok meg?
U.i: Köszönöm, hogy felhívtátok a figyelmem a 3,3V és 5V közti buktatókra, de ezzel tísztába voltam.
(#) pipi válasza DJozso hozzászólására (») Jan 18, 2023 /
 
De miért az esp "soros" bufferét használod, mikor van többszáz K ram? Ha van akár 1db soros vett karakter vedd el, tedd a jó nagy ramodba, vagy dolgozd fel.
(#) Bakman válasza DJozso hozzászólására (») Jan 18, 2023 /
 
Nem ismerem a rendszert, de nincs olyan, hogy csak úgy, eldobsz egy, több, sok karaktert? Ha másként nem megy a dolog, a ki- és bekapcsolás könnyen megoldható egy RS485-TTL konverter IC-vel, lásd melléklet. Az adatlapban megtalálható, mik a típusok közötti különbségek.
(#) DJozso válasza pipi hozzászólására (») Jan 18, 2023 /
 
Ha jól értem: Ahogy jön az adat, rögtön kezdjem feldolgozni, Stringbe tölteni, majd ezt a Stringet szerkeszteni. Vagy akkor akár azt is lehetne, hogy feldolgozásnál addig "eldobja" a beolvasott adatot, amíg a kívánt sor nem érkezik... Leírom mire gondolok:
500 ms-onként kapott "adatcsomag" kb így épül fel:
Idézet:

:R50=1,2,1,
:r50=2,215,2056,200,5408,4592,9437,14353,134,4112,0,0,162,3068,2,
:R51=1,2,1
:r51=1,211,3000,100,2000,2000,10000,151,10,7,200,120,90,101,0,0,2,12,13,

Ebből nekem a ":r50=" sor megadott számai kellenének unsigned int változókba.
Annyit még hozzá tennék, hogy a számok helyiértékei változhatnak! Tehát szerintem a vesszők poziciójához kellene tartanom.
Szóval, én így gondolom a megoldást:
-Bejövő buffer adat ellenőrzés, ha a karakter nem 'r', eldobás
-Ha 'r' kötkező 3 karakter olvasás, ha az is stimmel (r50=), további adatok írása Adat.String-be, míg nem lesz a karakter "soremelés". Ha nem igaz "r50=", adatok eldobása, kezdés előről.
-Adat.String feldolgozása:
-Vesszők pózicióinak megkeresése indexOf(',',from) paranccsal , ezen poziciók mentése poz1, poz2 stb...
- Mentés valahogy így: ElsoString = AdatString.substring(0, (poz1)-1) és így tovább
- Majd a ElsoString konvertálása unsigned int változóra.
Lehet ez így jó? Mi a véleményetek?

U.i.: utána nézek ennek a max485 fordító icének... Köszönöm.
A hozzászólás módosítva: Jan 18, 2023
(#) pipi válasza DJozso hozzászólására (») Jan 18, 2023 /
 
így van.
megszakításban: Én az első kettőspontig hajigálnám el a "szemetet", adatot tárolnám az 1-es tömbbe. Sorvégnél a átkapcsolnám hogy a megszakítás a 2. tömbbe tárolja az adatot, és az előző komplett tömböt addig bőven van idő feldolgozni....
Persze a vesszőket is lehetne figyelni a megszakításban, és akkor eltenni minden köztes adatot a helyére, de akkor a megszakításban több időt tölt a progi...
Ha kiélezettek az idők, nem használnám ezeket a spéci string műveleteket, egy pointerrel sokkal gyorsabban végig lehet szaladni a tömbön, kikapkodni belőle a lényeget
(#) DJozso válasza pipi hozzászólására (») Jan 18, 2023 /
 
Értem, hogy megszakításnál a legrövidebb kód kell, de az általad mondott megoldás legalább két, de inkább 4 tömböt ír.... Ebből nekem három "szemét". PIC-es korszakból az maradt meg, hogy a memóriával csínyán kell bánni. De ez a leggyorsabb, utána lehet elemezgetni.
"egy pointerrel sokkal gyorsabban végig lehet szaladni a tömbön, kikapkodni belőle a lényeget"
Ez nekem még így teljesen kínai. Elmondanád dióhéjban az elvet, vagy küldenél egy "tanuló linket"?
(#) DJozso válasza DJozso hozzászólására (») Jan 18, 2023 /
 
Google barát dobott fel néhány oldalt, ahol ezt tárgyalják, így már csak tanulmányozni kell... Köszönöm.
(#) wbt válasza DJozso hozzászólására (») Jan 18, 2023 / 1
 
Lehet, én vagyok figyelmetlen, de milyen gyorsan jönnek az adatok? bps? Szerintem 9600bps-ig az ESP röptében megeszi az egészet.
A hozzászólás módosítva: Jan 18, 2023
(#) vargham válasza DJozso hozzászólására (») Jan 19, 2023 / 2
 
Idézet:
„Stringbe tölteni, majd ezt a Stringet”

Nem használnék sztringet, nagy az erőforrásigénye.
(#) asch válasza DJozso hozzászólására (») Jan 19, 2023 / 1
 
Az UART olvasást mi csinálja a mikrovezérlőn? Mivel Arduino topikban vagyunk, elsőre arra asszociáltam volna, hogy az Arduino lib Serial objektumáról van szó. De az írásod alapján az adatlap alapján programozva a hardvert magad valósítottad meg az UART olvasást.
Az Arduino Serial egy ringbufferbe olvassa az UART bájtokat, és ezt a főprogram loop-jából illik periodikusan olvasgatni. Én pontosan így valósítanám meg még akkor is ha valamilyen okból saját serial illesztőt írnék (Például az ATMega328 alapú Arduino lib küldő puffere összesen 1 bájt, én emiatt szoktam saját UART libet használni, amivel nem blokkoló módon lehet például debug üzeneteket küldeni.). Már csak azért is, mert ez egy jól bevált megoldás, amiken csak akkor érdemes változtatni, ha muszáj. (Egyszer csináltam GPS serial feldolgozást interruptban és ... megbántam. Azért legvégül működött, de nagyon kellemetlen bugokat néztem be elsőre, mert ez többszálú programozásnak minősül, ráadásul real-time.)
A Serial buffere itt már nem a hardveres buffer hanem egy a RAM-ban foglalt buffer. A méretét úgy kell belőni, hogy a loop legrosszabb elképzelhető periódusideje alatt se csordulhasson túl. (Ez többnyire gondolkodás nélkül is teljesül, ha nem blokkoló loop függvényt írunk, azaz nem használunk például delay-t időzítésre. Az Arduino serial buffer mérete csak az Arudino lib újrafordításával állítható, de mivel open source szabad szoftver az újafordítást is megtehetjük, ha kell.)
Az adatfolyam feldolgozását pedig egy állapotgéppel csinálnám meg a loop-ban:
* Karakterek olvasása a serialról egyesével
* A karaktereket egy tömbbe gyűjtjük a sor elejétől 0-val indexelve (túlcsordulás elkerülésére figyeljünk, ha túlcsordulna egy sor, akkor azt ignoráljuk egy hibaállapotot megjegyezve amit csak a következő újsor töröl)
* Ha újsor karakter jön, akkor foldolgozzuk az előző sort - ha nem volt túlcsordulás, majd reszeteljük az állapotot és várjuk a következő sor első bájtját.
Ha megnézed ez minden sor alapú protokollnak az általános megoldása, csak indokolt esetben érdemes eltérni tőle. Látható, hogy a serial puffer a loop tempójával ürítve van, tehát nem a sorhossztól függ, hogy mekkora serial puffer kell, hanem csak a loop periódusidejétől és a baud rate-től. A sor puffert kell akkorára választani amekkora a leghosszabb sor lehet.
A hozzászólás módosítva: Jan 19, 2023
(#) Kovács Tibor válasza Jonni hozzászólására (») Jan 21, 2023 /
 
Kigyomláltam és kiegészítettem úgy hogy két vízórát is tud figyelni és számolni, köszi.
Egy 2*16-os LCD-t hajt meg.
Most tovább szeretném fejleszteni úgy hogy ebből számoljon m3/óra mennyiséget amit kiíratnék az LCD-re és naponta naplózza (pl. éjfélkor) egy SD-re. Milyen elven lehetne ezt megvalósítani? Számoljam hogy egy perc alatt mennyi impulzust kap, ez nagyon pontatlan lesz mert ritkán kapok jelet. Vagy azt meg lehet oldani hogy 1óra alatti impulzusokat számolja (mindig az utolsó egy órányi idő kellene eltolva, ez még rosszabb. Vagy kitöltési arány lenne jó? Nézegettem példaprogramokat de ezek mind 20-40 imp/liter közelei jeladókkal működött.
Majd később tervezem az internet kapcsolatot (8266 vagy ESP32 modulokkal).
(#) Jonni válasza Kovács Tibor hozzászólására (») Jan 21, 2023 /
 
Maradhatsz az eredeti elképzelésnél de van más módszer is. Lehet kapni átfolyásmérőt is amihez ITT van egy komplett leirás. Liter/órába mér de át lehet váltani. Ha éjjfélkor akarod irni az adatot sd-re akkor kellhet egy RTC mert ez pontos és áramkimaradásnál sem veszti el az időt.
(#) asch válasza Kovács Tibor hozzászólására (») Jan 21, 2023 /
 
Általában a legésszerűbb úgy logolni, hogy a lehető legközvetlenebbül azt írjuk le ami történik. Ha van sd kártya, akkor akár minden ticket is logolhatsz: időbélyeg, hányadik tick. Vagy adott időközönként: 6:20 ->619. tick. És utána megjelenítéskor számolod ki, hogy ez mit is jelent. Általában ezt a legkönnyebb felfogni és a legnehezebb elrontani.
Az ilyen hosszú időn át működő rendszereknél trükkös kérdés, hogy mi van ha elmegy az áram? nyilván a tickek azalatt nem lesznek számlálva, de legalább ne nullázzuk a számlálót! Lehetőségek:
* MCU EEPROMjába is beírjuk az állapotot és induláskor onnét kivesszük
* SD kártya log alapján újrainicializáljuk a rendszert induláskor. (És magát az áramszünetet is loggolhatjuk akkor már)
Az SD kártya kezelésére csináltam már olyan trükköt, hogy "nyersen" blokkonként írtam a logot, fájlrendszer nélkül. Minden blokk meg van jelölve, hogy az már volt használva és bináris kereséssel pillanatok alatt megtalálja a rendszer, hogy honnan kell folytatni. Ennek az az előnye, hogy a fájlrendszerhez képest sokkal egyszerűbb kezelni és tetszőleges hosszú log mellett is kiszámítható az elindulás ideje. Linux alatt az egész SD egyetlen fájlként látszik, és nagyon egyszerű eszközökkel ki lehet szedni a logot, ami úgy van kitalálva, hogy szövegfájlként is értelmes. Windows-zal nem ennyire egyszerű sajnos az SD tartalmának a direkt elérése.
Az RTC valóban nagyon hasznos, ha valós időben el akarod tudni helyezni, hogy mi mikor történt. De ha úgyis hálózatra teszed később, akkor meg lehet gondolni, hogy kihagyod az RTC-t (az áramszünetek hossza nem fog kiderülni a logból, de minden más pontos lehet) és amikor netre teszed, akkor majd a netről kapod a pontos időt. Ennek előnye, hogy soha nem kell állítgatni később se, és megspórolod az RTC áramkört.
A hozzászólás módosítva: Jan 21, 2023
(#) sargarigo válasza asch hozzászólására (») Jan 21, 2023 /
 
Menjünk tovább! Ha neten van, akkor semmilyen idő nem kell! A szerveren futó php szkript fogadja a ticket, és egy sql táblába eltárolja a rendszeridőt. Online elérhetőek az adatok, bármikor le tudod kérdezni, nem kell fizikailag az eszközhöz nyúlni. Én így oldottam meg a hőmérőimet. Amúgy az sd kártya/eeprom se szereti a túl sok írást, én hanyagolnám ezt a vonalat, mivel rendszeresen irkálnád.
(#) Kovács Tibor válasza sargarigo hozzászólására (») Jan 22, 2023 /
 
Tovább szeretnék menni, de egyenlőre nincsenek moduljaim ehhez.
Addig (meg hogy gyakoroljam, mert 0.1 szinten járok) az SD kártyára írást preferálom.
Most ott tartok hogy van két óraállás számlálásom az impulzusok alapján és megy az SD-re írás de állandóan fut.
Két kérdésem van:
1.Hogy lehet beállítani a kártyára írás időpontját?
2.Hogy lehet beállítani a DS3231 modul időpontot? (2000.01.01-et mutat.)

Az alábbi módszerrel próbáltam de hibát írt...

rtc.setDOW(SATURDAY); // Hét beállítása
rtc.setTime(14, 03, 00); // Idő beállítása 12:00:00 (24hr formátum)
rtc.setDate(01, 21, 2023); // Dátum beállítása to JAn 21rd, 2023
(#) Josi777 válasza Kovács Tibor hozzászólására (») Jan 22, 2023 /
 
Ez a használt librarytól függ. Általában a következő formátum működik:
  1. rtc.Day    = 22;
  2. rtc.Month  = 1;
  3. rtc.Year   = 23;
  4. rtc.Hour   = 15;
  5. rtc.Minute = 59;
  6. rtc.Second = 46;

szerk:
Majd ezt írd ki az RTC-be.
A hozzászólás módosítva: Jan 22, 2023
(#) Jonni válasza Kovács Tibor hozzászólására (») Jan 22, 2023 /
 
Ezzel a kóddal beállitja a számitógéped idejét (az hogy ds1307-hez van az ne zavarjon ds3231-hez is jó)

  1. [code=c]
  2. // igy jelenik meg a kijelzön
  3. //    Wed ,17/6/2020
  4. //    9.7.59
  5. // Date and time functions using a DS1307 RTC connected via I2C and Wire lib
  6. #include <Wire.h>
  7. #include <LiquidCrystal.h>
  8. #include "RTClib.h"
  9.  
  10. RTC_DS1307 rtc;
  11. LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
  12.  
  13. char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
  14.  
  15. void setup ()
  16. {
  17.   Serial.begin(9600);
  18.   lcd.begin(16, 2);
  19.  
  20.   if (! rtc.begin())
  21.   {
  22.     lcd.print("Couldn't find RTC");
  23.     while (1);
  24.   }
  25.  
  26.   if (! rtc.isrunning())
  27.   {
  28.     lcd.print("RTC is NOT running!");
  29.   }
  30.  
  31.     rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));//auto update from computer time
  32.     //rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));// to set the time manualy
  33.  
  34. }
  35.  
  36. void loop ()
  37. {
  38.     DateTime now = rtc.now();
  39.    
  40.     lcd.setCursor(0, 1);
  41.     lcd.print(now.hour());
  42.     lcd.print(':');
  43.     lcd.print(now.minute());
  44.     lcd.print(':');
  45.     lcd.print(now.second());
  46.     lcd.print(' ');
  47.  
  48.     lcd.setCursor(0, 0);
  49.     lcd.print(daysOfTheWeek[now.dayOfTheWeek()]);
  50.     lcd.print(" ,");
  51.     lcd.print(now.day());
  52.     lcd.print('/');
  53.     lcd.print(now.month());
  54.     lcd.print('/');
  55.     lcd.print(now.year());
  56.    
  57. }
[/code]
A hozzászólás módosítva: Jan 22, 2023
(#) Kovács Tibor válasza Jonni hozzászólására (») Jan 22, 2023 /
 
Nekem DS3131 van, hibát dob a fordításnál.
(#) Jonni válasza Kovács Tibor hozzászólására (») Jan 22, 2023 /
 
Na akkor most melyik?
Idézet:
„2.Hogy lehet beállítani a DS3231 modul időpontot? (2000.01.01-et mutat.)”


Milyen hibaüzenetet ad?
(#) Kovács Tibor válasza Josi777 hozzászólására (») Jan 22, 2023 /
 
beírtam, hibát ír a fordításnál
(#) Kovács Tibor válasza Jonni hozzászólására (») Jan 22, 2023 /
 
Bocs, elütöttem, DS3231
a hibaüzenet:
(#) Skori hozzászólása Jan 22, 2023 /
 
Az arduino IDE az utóbbi időben rettenetesen belassult nekem. Simán a mentésre kattintva is eltelik vagy 20 másodperc (még egy kicsi fájl esetén is).
Víruskereső semmit se talál, és más program nem lassult be a PC-n.
Az a durva, hogy korábbi mentést visszamásolva (ami biztosan jó volt) az is ugyanilyen lassú.
Amit még észrevettem, hogy STM32-re sokkal lassabban fordít, mint eddig, és a lefordított .bin fájl kisebb lesz, mint régebben ugyanarról a forrásról (tehát valószínűleg valamit másképp optimalizál a fordító).

Mi okozhatja a durva lassulást, van rá megoldás?
(#) Jonni válasza Kovács Tibor hozzászólására (») Jan 22, 2023 /
 
Kommenteld ki azt a sort amit rózsaszinnel jelöl ki a forditó és próbáld ujra.
(#) Jonni válasza Skori hozzászólására (») Jan 22, 2023 /
 
A kérdésedre nem tudom a választ de nekem nucleo van hogy 40-50mp allat tölt fel egy kódot
(#) Jonni válasza Kovács Tibor hozzászólására (») Jan 22, 2023 /
 
Próbáld meg igy

  1. // igy jelenik meg a kijelzön
  2. //    Wed ,17/6/2020
  3. //    9.7.59
  4. // Date and time functions using a DS1307 RTC connected via I2C and Wire lib
  5. #include <Wire.h>
  6. #include <LiquidCrystal.h>
  7. #include "RTClib.h"
  8.  
  9. RTC_DS1307 rtc;
  10. LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
  11.  
  12. //char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
  13.  
  14. void setup ()
  15. {
  16.   Serial.begin(9600);
  17.   lcd.begin(16, 2);
  18.  
  19.   if (! rtc.begin())
  20.   {
  21.     lcd.print("Couldn't find RTC");
  22.     while (1);
  23.   }
  24.  
  25.   if (! rtc.isrunning())
  26.   {
  27.     lcd.print("RTC is NOT running!");
  28.   }
  29.  
  30.     rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));//auto update from computer time
  31.     //rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));// to set the time manualy
  32.  
  33. }
  34.  
  35. void loop ()
  36. {
  37.     DateTime now = rtc.now();
  38.    
  39.     lcd.setCursor(0, 1);
  40.     lcd.print(now.hour());
  41.     lcd.print(':');
  42.     lcd.print(now.minute());
  43.     lcd.print(':');
  44.     lcd.print(now.second());
  45.     lcd.print(' ');
  46.  
  47.     lcd.setCursor(0, 0);
  48.     //lcd.print(daysOfTheWeek[now.dayOfTheWeek()]);
  49.     lcd.print(" ,");
  50.     lcd.print(now.day());
  51.     lcd.print('/');
  52.     lcd.print(now.month());
  53.     lcd.print('/');
  54.     lcd.print(now.year());
  55.    
  56. }
(#) Kovács Tibor válasza Jonni hozzászólására (») Jan 22, 2023 /
 
Így már lefordítja, feltöltöttem de hülyeséget ír az LCD-re és marad az eredeti idő.
Az viszont érdekes hogy mióta csatlakoztattam a modult azóta elkezdte számolni az időt, most kb 2000.01.01 . 02.41. tehát az óra szépen számol.

Az első kérdésre?
(#) Jonni válasza Kovács Tibor hozzászólására (») Jan 22, 2023 /
 
Az LCD-den van I2C modul?
(#) Jonni válasza Kovács Tibor hozzászólására (») Jan 22, 2023 /
 
Ha marad az eredeti idő akkor valami nem jó mert át kellett volna irja az időt.
(#) Kovács Tibor válasza Jonni hozzászólására (») Jan 22, 2023 /
 
Nincs, anélkül használom...
(#) Josi777 válasza Kovács Tibor hozzászólására (») Jan 22, 2023 /
 
Akkor leírom egy kicsit részletesebben. 2 külön dologról van szó. Az egyik a dátum/idő formátum, a másik pedig az RTC könyvtára és azok függvényei. Még mindig nem tudom, hogy melyik könyvtárat használod, így ismét csak általánosságban írom. Először létre kell hozni egy dátum/idő típusú változót, majd azok elemeit tudod írni, olvasni. Ha ebben beállítottad a neked megfelelő időpontot, akkor ezt a dátum/idő típusú változót iratod át az RTC könyvtár függvényével.
Tehát először létrehozod a RTC osztályt a könyvtáradnak megfelelő formátumban, pl.:
  1. DS3231 Clock;

Majd a Setup() alatt meghívod:
  1. Clock.begin();

Ez után létrehozod az dátum/idő formátumú változót:
  1. DateTime rtc;

Ez után tudod írni a korábban leírt fomában:
  1. rtc.Day    = 22;
  2. rtc.Month  = 1;
  3. rtc.Year   = 23;
  4. rtc.Hour   = 15;
  5. rtc.Minute = 59;
  6. rtc.Second = 46;
majd magát a dátum/idő formátumú változót íratod ki az RTC-be a könyvtáradnak megfelelő formátumban, pl.:
  1. Clock.write(rtc);

Remélem, ez alapján menni fog
Következő: »»   763 / 850
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem