Fórum témák
» Több friss téma |
A klónok CH340 Soros-USB illesztőjének drivere (Letöltés)
Sziasztok!
Nem rég óta foglalkozom Arduinoval, és rendkívül meg vagyok vele elégedve. Borzasztó jól programozható, de most belefutottam egy olyan problémába, amire nem tudom a megoldást, pedig biztosan egyszerű. A feladat: Adott egy nyomógomb, amelynek a megnyomása elindít egy folyamatot. Ha a gombot ismét megnyomják, akkor egy másik folyamat indul el, ha ismét megnyomják, akkor egy harmadik, és így tovább. Összesen 6 folyamat van, amelyeket el kell indítani, a hatodik folyamat után ismét az első következik, és így tovább. A PIC-nél ezt a Flowcode-ban viszonylag egyszerűen, egy többszörös feltételes elágazással meg lehetett oldani, itt azonban elakadtam. Létrehoztam egy globális változót, "gombertek" névvel. Fiygelem a gomb lenyomását, és ha lenyomják a gombot, akkor a változó értékét eggyel növelem. A következő lépésben egy "if" felétel-vizsgálattal megnézem, hogy a változó elérte-e a 6-os értéket, ha igen, nullázom. Az ezt követő részben vizsgálom (szintén "if" feltételvizsgálattal), hogy a változó 1, 2, 3, ... értékű-e, és ennek megfelelően hajtatom végre a folyamatokat. Azonban a fordítás során a fordító hibajelzést ad, mindig az utolsó "if"-nél, mondván, a változó abban a periódusban nincs definiálva. Mit ronthatok el vajon? Illetőleg van-e ennél jobb megoldás a feladat végrehajtására? A segítséget előre is köszönöm. (A kódot most nem tudom bemásolni, mert az az otthoni gépen van, de ha kell, a hétvégén felteszem.)
Én akkor szoktam így járni, ha valahová a kelleténél eggyel több "}" kerül, így azzal a void loop() záródik, a hibajelzést adó rész előtt.
Használd az "else if" változatot: Bővebben: Link
Itt elvileg korlátlan számú feltételt vizsgálhatsz.
Ráadásul gyorsabb is, mert az első találtat után a többi ágat már nem vizsgálja. A hozzászólás módosítva: Jan 24, 2020
A 'switch...case' is használható ilyenre (Flowcode-ban többirányú elágazás néven fut): Bővebben: Link.
Mindhármótoknak köszönöm a segítséget, ki fogom próbálni a "switch...case"-t is, az "else if"-et is. És persze megnézem, nincs-e véletlenül tényleg fölös "}" jel...
Igen, a switch case előnye, hogy kicsit átláthatóbb, mint egy csomó if/else if/else, és ha a feltétlek "tömören" jönnek, akkor a fordító ugrótáblává tudja optimalizálni, ami még gyorsabb végrehajtást tud biztosítani. Ha túl nagy számok a case-ek, és táblát nem tud csinálni, akkor is felezve keresős megoldást tud csinálni, ami sok case esetén megintcsak gyorsabb. Persze ezek a különbségek akkor számítanak csak, ha valamit gyorsan kell ismételgetni.
Igen, igazából ez volt az a megoldás, amit kerestem. Mivel jelen projektben a sebesség nem kritikus, így vélhetően ez lesz a megoldás most, de ettől függetlenül az "if...else if" párosokat is fejben tartom majd.
Ht én még nem néztem az Arduino hogy fordítja, de úgy emlékszem a PIC-es XC fordítók if-nek fordíották, úgyhogy ebből a szempontból nem számított, csak átláthatóbb volt.
Pont mostanában néztem rá, az avr-gcc kimenetére, és ugrótáblát csinált. Pár felesleges ellenőrzést tett csak bele pluszban, amit ASM-ben ki tudtam volna optimalizálni.
De ha sima if-eket csinál a fordító, az is lehet hatékony, ha kisebb-nagyobb intervallumfelezős megoldást csinál. Ez ugye N esetet logN lépésben ki tud keresni, míg a lineáris keresés N lépés lesz. Persze ezt is meg lehet csinálni kézzel, de sok esetre macerás, és ha bárhol belenyúlunk, lehet előről kezdeni. Kevés esetre viszont lehet a legegyszerűbb lineáris if-es megoldás a leggyorsabb, lehet, hogy azért hagyja úgy a fordító. Azt is el tudom képzelni, hogy egy if-else if -es szerkezetben fel tudja ismerni a switch-case-t és akként tudja optimalizálni azt is. Ha fontos, akkor meg kell nézni a disassemblyt.
Arduino Nano-t és Adxl345 használnék egyben.
Adxl345 adatlap Cél az volna, hogy a nanó interrupt lábára "jelet" adjon az adxl, koppintása vagy mozgásra. Ime a kód ami tökéletesen működik:
De.. Ezt a részt egy másik programba illeszteném be, ahol osztott interrupt van, és minden eszköz LOW interrupttal működik. Ennek is úgy kellene. Ha a FALLING-ot LOW-ra cserélem az interrupt nem törlődik, beragad az első riasztás után. (a láb alacsony marad). Mi okozzhatja ezt?
Szia!
Mit jelent, hogy osztott interrupt? Az, hogy adott eseményre több mindennek kellene lefutnia? Mert akkor annyi is lehet a megoldás, hogy a jó kódba bemásolod ezeket a függvényeket és az ottani interruptos függvényből meghívod ezeket az új interrupt0() és interrupt2() függvényeket. Ezzel felszabadulna egy-két láb is pluszban. Ez nem járható út? Illetve a 0 és 1 ábra van kötve, de nem látom, hogy az milyen pin mód? pinMode(4, OUTPUT); //set LED pins to output pinMode(5, OUTPUT); pinMode (2, INPUT_PULLUP); pinMode (3, INPUT_PULLUP);
Ismét a korábbi (előzőleg ismertetett) problémával küzdök. Valószínű, hogy valamilyen logikai hiba van a kódomban.
Elvileg azt kellene tennie, hogy a gomb megnyomására kigyújt előbb 1, majd 2, 3, 4 LED-et (3-6 kimenetek). Az alapértelmezése pedig, hogy valamennyi sötét. A gomb a 13 kimenetre van kötve. Íme a kód:
E helyett azonban az indítás után valamennyi LED-et bekapcsolja. (Technikai okokból a LED-ek "közös kivezetése" a pozitív tápra van kötve, tehát ahhoz, hogy bekapcsoljuk, a kimenetnek "LOW" értéket kell felvennie, a kikapcsoláshoz pedig "HIGH" értékűnek kell lennie a kimenetnek.)
Osztott interruptnál erre gondoltam:
Bővebben: Link Közben beszéltem mateatek -al és a következőt okoskodtuk ki. Az adxl folymaotosan alacsonyan tartja a pin-t és ezért folyamatosan fenáll a megszakítás. Lényegében nem tudnak lefutni a kikapcsoló parancsok. Igy leegyszerűsítve müködik a dolog már félig :
Ha másodpercenként pöckölgetem az adxl-t működik is a dolog, ennél sűrűbben akkor lefagy. Kiirja, hogy "Nullaz" és vége. Következő kérdés, mi okoza a fagyást?
Sajnos a logikában még annyira nem vagyok otthon, de én kipróbálnám más bemenetre tenni a gombot, mert a 13-as làb trükkös lehet a rajta levő ellenállás és led miatt.
" NOTE: Digital pin 13 is harder to use as a digital input than the other digital pins because it has an LED and resistor attached to it that's soldered to the board on most boards. If you enable its internal 20k pull-up resistor, it will hang at around 1.7V instead of the expected 5V because the onboard LED and series resistor pull the voltage level down, meaning it always returns LOW. If you must use pin 13 as a digital input, set its pinMode() to INPUT and use an external pull down resistor."
Ha a 13-as lábnak nincs lehúzó ellenállása, akkor simán magasba mehet magától is. Lehet, hogy benyomva "érzi" a program. Gombot bekötni a legegyszerűbb úgy, hogy a pint INPUT_PULLUP-ra állítod - egy alapból magas lesz a bemeneten, és a benyomott gombbal a GND-re húzod le. Így stabilan jól fog működni, és nem kell plusz ellenállást se bekötni - mivel a csipbe beépítettet tudjuk használni. Annyi más, hogy a LOW-ra kell reagálni, nem a high-ra.
Olvasd ki valamelyik adatregisztert (0x32..0x37), vagy a megszakítás forrását tároló regisztert (0x30), ezek törlik az ADXL megszakítás kimenetét.
"The interrupt functions are latched and cleared by either reading the data registers (Address 0x32 to Address 0x37) until the interrupt condition is no longer valid for the data-related interrupts or by reading the INT_SOURCE register (Address 0x30) for the remaining interrupts. This section describes the interrupts that can be set in the INT_ENABLE register and monitored in the INT_SOURCE register. A kódban az interrupt() fv-ben ne használj olyan utasítást, aminek végrehajtása hosszú időt vesz igénybe, pl. serial.println("...");. Látom, hogy most ki van kommentelve, de ez általános tanács, minden megszakításra.
Olvassa az adxl 0x30 -as regisztert.
Ez a kód tökéletesen működik, valószínűsíthetően azért mert folyamotos fut az interrupt újra indítás. (és ez igy nem igazán tetszik nekem)
A ronin75 és asch által is leírt 13-as lábra tett nyomógomb az egyik oka a hibás működésnek. Állandó magas szint esetén "gert" értéke állandóan pörög egytől négyig, mindig aktívra állítva egy újabb kimenetet.
A nyomógomb kezeléséhez még egy észrevétel: nem tudod olyan rövid időre lenyomni, hogy ne kerüljön rá többször a futás, tehát egy lenyomás szinte biztosan többször végigpörgeti "gert"-et. Használj valamiféle késleltetést. A másik ok az, hogy ebben a programban jól kezelt gombbal sem lesznek soha kikapcsolva a ledek. A switch default esetében kapcsolnád ki őket, de sosem kerül rá a futás. Ha "gert"-nek mondjuk 0 kezdőértéket adsz ( és nem lenyomott gombbal indítod az eszközt), akkor a default esetre legalább egyszer sor kerülhet. Érdemes inkább a setup részben magasra állítani a kimeneteket, a default esetet pedig kihagyni. A hozzászólás módosítva: Jan 26, 2020
Az Arduino nano-n, pro-n és uno-n biztosan a 13-as pin-en van egy soros ellenállás-LED együttes a GND-re, szóval ezt a pin-t, mint bemenet használni körülményes.
Neked is, ronin75-nek is köszönöm a tanácsot. Más projektekben kipróbálva a 13 lábra kötött ugyan ezen nyomógomb kitűnően tette a dolgát, de persze az Általatok javasolt megoldásokat is ki fogom próbálni.
Köszönöm az észrevételt. Igen, az időzítés kérdése az én fejemben is megfordult.
Azt az észrevételt külön köszönöm, hogy a setup részben állítsam be a kimeneteket magasra, és akkor nem kell a default eset. Ezek szerint tehát nem logikai bukfencet követtem el. (Ez azért megnyugtat. )
Sziasztok
Van egy kis balhém. Egy berendezés vezérlését épitettem meg. Gyönyörüen müködik addig amig.... Egy Arduino Uno, egy rádugott L293-s Motoshielddel. Ahhoz van kapcsolva egy DC motor egy szervo, két érzékelö az A0/1 portokra meg 4 LED a A2..5 portokra. Az egész vezérlés 5 állapot: motor oda -vissza, szervo, motor oda- vissza. Közben meg kapcsolodnak a LEDek. Amig fejlesztettem minden 5 Voltrol ment a motorshieldre kötve. Hetekig ment hibátlanul. Amikor beépitettem a rendszerbe és 12 V-rol az Arduino 12 V-s bemenetéröl hajtom, akkor a lefut 2 ciklus majd megáll, a feszültségek voltméterrel mérve rendben vannak (5V az arduino kártyán, 11,6V a motorshielden) a kod látszolag megáll mert a LEDek ugy maradnak ahogy az adott lépésben kell. A fogyasztás alig 0,5 A ha megy a motor, ha áll alig 30 mA. Ha viszont bedugom az USB kábelt ( program nélkül csak feszültség van rajta, akkor viszont hibátlanul megy egész nap. Mintha a fedélzeti 5 V-l lenne valami zür, de semmit nem látni - na jo a szkopot még nem vettem elö. Mi lehet a kinja?. A stabilizátor nem melegszik, és fejlesztés közben eredetileg 2 motorral ment ( késöbb a második nem kellett.) igaz, hogy külsö 5 V-rol. A táp 12 V/1A. Kösz! A hozzászólás módosítva: Jan 27, 2020
A motorról nem szed össze valami zajt?
Helló!
A tápot kellene megnézni, mert lehet onnan kap zavart. Azonban szerintem az érzékelők körül lesz a gond. Először próbáld azok nélkül ki a rendszert, pl egy kapcsolóval. Ha úgy megy akkor van egy ötletem még.
Az érzékelökkel nem lehet, azok optokapuk és minden 5 V-rol megy kivéve azt az egyetlen motort. De lehet hogy azt is átszerelem 5 V-ra és akkor külsö 5 V-rol hajtom. A stabi az ami az arduino lapon van.
Olyankor ragad be amikor a motor áll és a szervo megteszi a programozott mozgást. Ezután még 5 másodpercig csak a LED-k mennek és csak ezután indulna a motor. De ahogy irom 2 ciklust megtesz mielött megáll, azaz a kod rendben van ( meg akkor megy ha USB-n is kap áramot.)
|
Bejelentkezés
Hirdetés |