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   461 / 839
(#) tbarath válasza vargham hozzászólására (») Júl 16, 2018 /
 
Lehet hogy az arduino lassú és korlátozott, de nekem ide pont elég lenne. Maga a kód nagyjából ennyi lenne:
  1. x = analogRead(pin1);
  2. //x-ből matekozok egy y-t
  3. analogWrite(pin2, y);

Vagyis pontosabban:
  1. if (LOW == pin3){
  2.   x = analogRead(pin1);
  3.   //x-ből matekozok egy y-t
  4.   analogWrite(pin2, y);
  5. }

Ahol pin3 és pin1 ugyanarra a jelre van rákötve, de 1v1 referenciával mérek, és hasznos jel esetén 1v1 alatt vagyok, egyébként pedig vcc közelében, amivel foglalkozni se érdemes.
Arra gondoltam, hogy először megírom "arduinóban" a dolgot, aztán ha ez kevés (vagy csak kedvem van hozzá), akkor akkor átírom a kritikus részeket. De még az elején elakadtam.

Szóval nem tudom, hogy az arduino IDE/lib/whatever mennyire piszkál bele a beállításokba, regiszterekbe, de az analogWrite fv érdemi része kb. így néz ki:
  1. switch(digitalPinToTimer(pin))
  2. {
  3.   // XXX fix needed for atmega8
  4.   #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__)
  5.   case TIMER0A:
  6.     // connect pwm to pin on timer 0
  7.     sbi(TCCR0, COM00);
  8.     OCR0 = val; // set pwm duty
  9.     break;
  10.   #endif

Innen: ~/arduino/arduino-1.6.5/hardware/arduino/avr/cores/arduino/wiring_analog.c

És ez alapján nem értem...
A hozzászólás módosítva: Júl 16, 2018
(#) tbarath válasza berkesandor hozzászólására (») Júl 16, 2018 / 1
 
Nem "matematikailag", de írtam valamit.
Az alapötlet az, hogy meghatározok egy max. különbséget, amit semmiképp se érhet el 2 mérés között. Erre belőttem 180 fokot, mert ha ettől nagyobb előfordulhat akkor semmiben se lehetsz biztos. A diff adja vissza az eltérést fokban, a dir pedig az irány (signed: ha + irányba mentünk akkor +1, ha - irányba akkor -1, ha nem mozdult akkor 0.
  1. maxdiff = 180;
  2. regi = ...;
  3. uj = méred;
  4. if (uj > régi){
  5.         diff = uj -regi;
  6.         dir = 1;
  7. }
  8. elseif (regi > uj){
  9.         if (uj +maxdiff < regi){
  10.                 diff = uj +360 -regi;
  11.                 dir = 1;
  12.         }
  13.         else{
  14.                 diff = regi -uj;
  15.                 dir = -1;
  16. }
  17. else{
  18.         diff = 0;
  19.         dir = 0;
  20. }
(#) david10 hozzászólása Júl 16, 2018 /
 
Sziasztok,
Lenne egy gyors kérdésem:

Egy ESP32 modullal szeretnék LCD kijelzőt, érintőkijelzőt, infra ledet, bluetooth-ot, wifi-t, CAN buszt, meg egy csomó mindent vezérelni, viszont a projekt negyede sincs kész, máris 538 sornál tart a forráskód, van kb. 21 függvény, amikor a 403-adik sorból kell a 120-adikra visszaugrani, modosítani, majd megint visszamenni a 403-adikra, olyankor teljesen összezavarodok.
Már így is olyan hosszú sorok is vannak, amik egy full HD-s kijelzőn se férnek ki, a forráskód olvashatóságáról nem is beszélve.

Hogyan lehetne a függvényeket külön fájlba átteni, annélkül, hogy könyvtárat kellene írni? A könyvtár írással egyedül az a bajom, hogy sok idő és energia kell hozza, de ha nincs más alternatíva, akkor nekifogok annak.

A választ előre is köszönöm!
A hozzászólás módosítva: Júl 16, 2018
(#) sargarigo válasza krauszkrisztian14 hozzászólására (») Júl 16, 2018 /
 
A kettes és hetes lábát úgy kapcsolod be, beleírod egy char változóba hogy 0b01000010, és küldöd a shiftOuttal a regiszterre ahogyan a példa mutatta. Vársz egy másodpercet, aztán a 0b00010100 bájtot küldöd ki. Ennyi.
(#) kapu48 válasza tbarath hozzászólására (») Júl 16, 2018 /
 
Csináltam tesztet.
A program:
  1. void myFok(int regi, int uj);
  2.  
  3. void setup() {
  4.   Serial.begin(115200);
  5.  
  6.     myFok(357, 3);    // jobbra 6
  7.     myFok(357, 347);  // balra 10
  8.  
  9.     myFok(3, 357);    // balra 6
  10. }
  11.  
  12. void loop() {
  13.   // put your main code here, to run repeatedly:
  14.  
  15. }
  16.  
  17.  
  18. void myFok(int regi, int uj){
  19.   int maxdiff = 180;
  20.   //int regi = 357;
  21.   //int uj = 3;
  22.   int diff, dir;
  23.  
  24.   if (uj > regi){
  25.         diff = uj - regi;
  26.         dir = 1;
  27.   } else if (regi > uj){
  28.         if (uj + maxdiff < regi){
  29.                 diff = uj + 360 - regi;
  30.                 dir = 1;
  31.         }
  32.         else{
  33.                 diff = regi - uj;
  34.                 dir = -1;
  35.         }
  36.   } else{
  37.         diff = 0;
  38.         dir = 0;
  39.   }
  40.   Serial.print("diff = ");
  41.   Serial.print(diff);
  42.   Serial.print(", dir = ");
  43.   Serial.println(dir);
  44. }

Az eredmény:
diff = 6, dir = 1
diff = 10, dir = -1
diff = 354, dir = 1

Alkúl! A 2 első adat már jó.
A balra mozgás még nem OK!
A hozzászólás módosítva: Júl 16, 2018
(#) sargarigo válasza berkesandor hozzászólására (») Júl 16, 2018 /
 
Ezt én ugy csinálnám, hogy írnék egy segéd függvényt, ami ellenőrzi hogy a művelet elvégzése után az eredmény belefér-e a 0-360 fokba. Ha nem, akkor kivonnék a 353 fokból 180—ot, ezzel biztosan elvégezhető a művelet, lehet tesztelni. Egyszer már megoldottam ezt a problémát, csak most nem vagyok otthon egy hétig, próbálom felidézni

Szerk: látom kapu kolléga is hasonló megoldással próbálkozik..
A hozzászólás módosítva: Júl 16, 2018
(#) kapu48 válasza kapu48 hozzászólására (») Júl 16, 2018 / 1
 
Ez lessz a végleges megoldás:
  1. void myFok(int regi, int uj);
  2.  
  3. void setup() {
  4.   Serial.begin(115200);
  5.  
  6.     myFok(357, 3);    // jobbra 6
  7.     myFok(357, 347);  // balra 10
  8.     myFok(347, 357);  // jobbra 10    
  9.     myFok(3, 357);    // balra 6
  10. }
  11.  
  12. void loop() {
  13.   // put your main code here, to run repeatedly:
  14.  
  15. }
  16.  
  17. void myFok(int regi, int uj){
  18.   int maxdiff = 180;
  19.   //int regi = 357;
  20.   //int uj = 3;
  21.   int diff, dir;
  22.  
  23.   if(uj > regi){
  24.       if (uj - maxdiff > regi){
  25.                 diff = 360 - uj + regi;
  26.                 dir = -1;
  27.         }else{    
  28.                 diff = uj - regi;
  29.                 dir = 1;
  30.         }
  31.   }else if (regi > uj){
  32.         if (uj + maxdiff < regi){
  33.                 diff = uj + 360 - regi;
  34.                 dir = 1;
  35.         }else{
  36.                 diff = regi - uj;
  37.                 dir = -1;
  38.         }
  39.   }else{
  40.         diff = 0;
  41.         dir = 0;
  42.   }
  43.   Serial.print("diff = ");
  44.   Serial.print(diff);
  45.   Serial.print(", dir = ");
  46.   Serial.println(dir);
  47. }

diff = 6, dir = 1
diff = 10, dir = -1
diff = 10, dir = 1
diff = 6, dir = -1
Most jó az eredmény!
A hozzászólás módosítva: Júl 16, 2018
(#) tbarath válasza kapu48 hozzászólására (») Júl 16, 2018 /
 
Lusta voltam letesztelni, csak érzésből írtam. Ezek szerint érzésből erre a tesztesetre nem gondoltam. Na mindegy, majd nekiállok egyszer ha addig nem oldja meg valaki.

Szerk: köszi a javítást.
A hozzászólás módosítva: Júl 16, 2018
(#) kapu48 válasza tbarath hozzászólására (») Júl 16, 2018 /
 
Köszi a segítséget!
Meg érdemled a mancsot érte!

A többit már megoldottam, a te nyomdokodban!
A hozzászólás módosítva: Júl 16, 2018
(#) tbarath válasza kapu48 hozzászólására (») Júl 16, 2018 / 1
 
Szívesen, félig működő, trehányan tesztelt algoritmusok írásában jó vagyok
(#) Kovidivi válasza tbarath hozzászólására (») Júl 16, 2018 / 1
 
Az analogWrite nem.lehet probléma, viszont ha a timer regisztereit piszkálod, figyelembe kell venned, hogy azoknak már van egy kezdő értéke Arduino alatt, ami nem biztos, hogy nulla! Én mindig kinullázom, és utána állítom be. De ki is írathatod soros portra indulás után közvetlenül, és látni fogod a kezdő értéket. Ebbe a high speed timer-be még nem akadtam bele jobban, de érdekesen hangzik. Adatlapot kellene átolvasni rendesen, hogyan tud nagyobb frekin menni a timer1, ha az órajel 1MHz. PLL van használatban? A PLL-t konfiguráltad?
A hozzászólás módosítva: Júl 16, 2018
(#) szeg76 hozzászólása Júl 16, 2018 / 2
 
Még egy változat az irányprobléma megoldására:

  1. int     szogkulonbseg(int a, int b)
  2. {
  3. int     diff;
  4.  
  5. if(a>359) a-=360; else if(a<0) a+=360;
  6. if(b>359) b-=360; else if(b<0) b+=360;
  7.  
  8. diff=b-a;
  9.  
  10. if(diff>180) diff-=360; else if(diff<-179) diff+=360;
  11.        
  12. return( diff );
  13. }


'a' a kiindulási szög
'b' az új szög
visszatérési érték b-a, -180..+180° tartományra korlátozva, óramutató járása a pozitív irány

Ha a és b értéke garantáltan a 0..359 tartományba esik, az első két if else if szerkezet elhagyható.
A hozzászólás módosítva: Júl 16, 2018
(#) tbarath válasza Kovidivi hozzászólására (») Júl 17, 2018 /
 
A timer regisztereknek szerintem elég egyértelműen adok értéket, nem hiszem hogy a nullázás ezen sokat segítene, de majd kipróbálom. A soros port attiny esetén nem triviális, de majd arra is ránézek. A datasheet triviális megoldás, de bő 200 oldalt elolvasni, megérteni és megjegyezni, hát ahhoz kicsit kevés az agykapacitásom mostanában.
A PLL-t nem piszkáltam, annyi a kód amit írtam, de ennek még utánanézek, kösz a tippet. Remélem holnap (ma) kicsit könnyebb napom lesz mint ma (tegnap), hátha lesz kis időm ennek utánanézni.
(#) berkesandor válasza kapu48 hozzászólására (») Júl 17, 2018 /
 
Köszönöm.
(#) berkesandor válasza szeg76 hozzászólására (») Júl 17, 2018 /
 
Köszönöm.
(#) kistee válasza kapu48 hozzászólására (») Júl 17, 2018 /
 
Ezt lehet, hogy nem gondoltam végig eléggé... Régebben két abszolút szöghelyzetadó forgását kellett szinkronizálnom, beállítható szögeltéréssel, ott volt valami hasonló a megoldás. Csak már nem emlékeztem pontosan...

De úgy látom, azóta már megoldódott.
(#) kapu48 válasza szeg76 hozzászólására (») Júl 17, 2018 /
 
Idézet:
„if(a>359)”
Méréskor sosem kapsz nagyobb számot.

Ezzel az a gond, hogy az iránytűn nincsen nagyobb szám! 0 - 359, és kezdi elölröl a 360 = 0.

Idézet:
„diff=b-a;”
És mi van ha másik irányba fordulsz? B < A?
A gond akkor jön elő mikor valamelyik irányba átlépjuk a bűvős 360 fokot.
A hozzászólás módosítva: Júl 17, 2018
(#) Bell válasza kapu48 hozzászólására (») Júl 17, 2018 /
 
Ha 240 foknál nagyobb mérési eredményt követően kapunk 120 foknál kisebbet, akkor az aktuális szög 360-al nagyobb, mint a mért érték.
Hasonlóan a másik irányban.
(#) kapu48 válasza szeg76 hozzászólására (») Júl 17, 2018 /
 
Bocsi az értetlenkedésért!
Úgy tűnik, mégis működik a teszt:
  1. int  szogkulonbseg(int a, int b);
  2.  
  3. void setup() {
  4.   Serial.begin(115200);
  5.  
  6.     Serial.println(szogkulonbseg(357, 3));    // jobbra 6
  7.     Serial.println(szogkulonbseg(357, 347));  // balra 10
  8.     Serial.println(szogkulonbseg(347, 357));  // jobbra 10    
  9.     Serial.println(szogkulonbseg(3, 357));    // balra 6
  10. }
  11.  
  12. void loop() {
  13.   // put your main code here, to run repeatedly:
  14.  
  15. }
  16.  
  17. int szogkulonbseg(int a, int b)
  18. {
  19.   int     diff;
  20.  
  21.   //if(a>359) a-=360; else if(a<0) a+=360;
  22.   //if(b>359) b-=360; else if(b<0) b+=360;
  23.  
  24.   diff=b-a;
  25.  
  26.   if(diff>180) diff-=360; else if(diff<-179) diff+=360;
  27.        
  28.   return( diff );
  29. }

Eredmény:
6
-10
10
-6
OK!

Köszönöm a segítséget!
Így talán már nem bolondul meg a dronom.
(#) kapu48 válasza david10 hozzászólására (») Júl 17, 2018 /
 
Szia!

Lehet, hogy most szívesebben választanád a könnyebbik utat, a spagetti kód átfaragására.

De én inkább ajánlanám ezt a módszert: Bővebben: Link

Meg fogod köszönni, hogy megfogadtad, a későbbi könnyebb hibakeresések alkalmával!
(#) tbarath válasza Kovidivi hozzászólására (») Júl 17, 2018 /
 
Köszönöm a segítséget, Te vezettél nyomra.
A PLL beállítás hiányzott, miután ez megvan a TCCR1 és az OCRC1 regiszterek piszkálásával szépen be tudtam állítani 250 kHz és 20 kHz PWM frekit is.

Hátha valakinek hasznoslesz, iderakom a kódot kommentekkel:
  1. #define LED_PIN_PWM 4
  2.  
  3. #include <avr/io.h>
  4. #include <util/delay.h>
  5.  
  6. void setup() {
  7.   /*
  8.   PLL Control and Status Register
  9.   • Bit 7 – LSM: Low Speed Mode
  10.   The high speed mode is enabled as default and the fast peripheral clock is 64 MHz, but the low speed mode can
  11.   be set by writing the LSM bit to one. Then the fast peripheral clock is scaled down to 32 MHz.
  12.   • Bit 2 – PCKE: PCK Enable
  13.   The PCKE bit change the Timer/Counter1 clock source. When it is set, the asynchronous clock mode is enabled
  14.   and fast 64 MHz (or 32 MHz in Low Speed Mode) PCK clock is used as Timer/Counter1 clock source.
  15.   • Bit 1 – PLLE: PLL Enable
  16.   When the PLLE is set, the PLL is started
  17.   • Bit 0 – PLOCK: PLL Lock Detector
  18.   When the PLOCK bit is set, the PLL is locked to the reference clock. The PLOCK bit should be ignored during ini-
  19.   tial PLL lock-in sequence when PLL frequency overshoots and undershoots, before reaching steady state. The
  20.   steady state is obtained within 100 μs. After PLL lock-in it is recommended to check the PLOCK bit before enabling
  21.   PCK for Timer/Counter1.
  22.   */
  23.  
  24.   //PLLCSR = 0<<LSM | 1<<PCKE | 1<<PLLE;
  25.   PLLCSR = 1<<PCKE | 1<<PLLE;
  26.  
  27.   delay(1);
  28.   while (! PLLCSR & PLOCK){
  29.   }
  30.  
  31.   /*
  32.   TCCR1 – Timer/Counter1 Control Register
  33.   • Bits 3:0 - CS1[3:0]: Clock Select Bits 3, 2, 1, and 0
  34.   The Clock Select bits 3, 2, 1, and 0 define the prescaling source of Timer/Counter1.
  35.   ---
  36.   OCR1C – Timer/Counter1 Output Compare Register C
  37.   The Timer/Counter Output Compare Register C contains data to be continuously compared with Timer/Counter1.
  38.   A compare match does only occur if Timer/Counter1 counts to the OCR1C value. A software write that sets TCNT1
  39.   and OCR1C to the same value does not generate a compare match. If the CTC1 bit in TCCR1 is set, a compare
  40.   match will clear TCNT1.
  41.   */
  42.  
  43.   // 250 kHz
  44.   //TCCR1 = 0<<PWM1A | 0<<COM1A0 | 1<<CS10;
  45.   TCCR1 = 1<<CS10;
  46.   OCR1C = 255;
  47.  
  48.   // 20 kHz
  49.   //TCCR1 = 0<<PWM1A | 0<<COM1A0 | 1<<CS12 | 1<<CS10;
  50.   //TCCR1 = 1<<CS12 | 1<<CS10;
  51.   //OCR1C = 199;
  52.  
  53.   pinMode(LED_PIN_PWM, OUTPUT);
  54. }
  55.  
  56. void loop() {
  57.   analogWrite(LED_PIN_PWM, 128);
  58. }


További kérdés még: a uC-re nézve van valami előnye/hátránya annak, ha kisebb vagy nagyobb PWM frekvenciát használok?
A hozzászólás módosítva: Júl 17, 2018
(#) Kovidivi válasza tbarath hozzászólására (») Júl 17, 2018 /
 
Szívesen. Nem csak neked volt hasznos, régebben én is "rácsodáltam", hogy a kis IC milyen szuper PWM-et tud produkálni, aztán feledésbe merült.
Szerintem az uC-nek teljesen mindegy, mekkora frekin ketyeg a timer-je, egyedül instabilitásra hívja fel a figyelmet az adatlap nagyon magas frekvenciákon.
A hozzászólás módosítva: Júl 17, 2018
(#) KoblogPerGyok válasza tbarath hozzászólására (») Júl 17, 2018 /
 
Üdv mindenkinek!

A PWM kérdéseiteket válaszotokat figyeltem, utána is olvastam, de ez mindenképpen kell?

analogWrite(LED_PIN_PWM, 128);


Mármint a loop-ba? Nem elég, ha a Setup-ban be van állítva? A 128 az 50% körüli kitöltést adja meg nem? (A frekvenciát nem változtatja) Rosszul gondolom?

Mert ha igen, akkor minek kell minden egyes-loop-ban kiadni ezt? Ha több kódot írok a loop-ba akkor ráadásul nem azonos időközönként megy ki ez a parancs. A gondom az, hogy ez a parancs nem befolyásolja a PWM-jelet? Gondolom a timer counter-t nullázza egy ilyen nem? (Ok nem biztos)

Mert ha igen akkor teljesen felesleges kiadni ezt az utasítást ennyiszer, elég csak akkor, ha az változik.
(#) proba válasza tbarath hozzászólására (») Júl 17, 2018 /
 
Fogyasztás?
(#) devilke3000 válasza tbarath hozzászólására (») Júl 17, 2018 /
 
Mért nem használsz ezt?
Tök egyszerü!
A hozzászólás módosítva: Júl 17, 2018
(#) Kovidivi válasza devilke3000 hozzászólására (») Júl 17, 2018 /
 
Szerintem ez nem tud PLL beállítást, pl. ezért nem használja.
(#) devilke3000 válasza Kovidivi hozzászólására (») Júl 17, 2018 /
 
Frekit is akart nem csak kitöltést ahogy látom...
(#) tbarath válasza KoblogPerGyok hozzászólására (») Júl 17, 2018 /
 
Igazad van, most hülyeség odatenni. A későbbi kód egy analóg feszültségszintet fog ADC-vel vizsgálni, és ettől függően fog PWM-et állítani, ha szükséges, másodpercenként max. 2-3 frissítést tervezek. Akkor pedig már a loop()-ban lesz rá szükség, szerintem ezért tettem tesztelésnél is oda. Ma nekem is kiszúrta szemem, de annyira nem zavart hogy érdemben belenyúljak. Most még csak a pwm működésénél tartok, illetve - hála a segítségeteknek - azon már talán túl is vagyok
(#) tbarath válasza proba hozzászólására (») Júl 17, 2018 /
 
A fogyasztás most lényegtelen. Egy jobb pillanataiban 70 Wattot fogyasztó, hálózati táplálású eszközhöz készül egy mérőmodul.
(#) tbarath válasza devilke3000 hozzászólására (») Júl 17, 2018 /
 
Köszi,

Ezt két dolog miatt nem használtam, az egyik hogy nem tudtam róla.
A másik pedig az, hogy ez egy _nagyon_ egyszerű kód, de tényleg: a loop-ban ADC mérés után PWM beállítás esetleg egy delay utána, és ennyi. Ez annyira alap dolog, hogy jó feladatnak találtam az attiny-val való ismerkedésre (ami ügyes kis cucc egyébként). Ezen kívül annyi (volt) a "nehézség", hogy egy nagyobb PWM frekit kihozzak a uC-ből, amit egyébként adatlap szerint simán tud, csak én voltam béna.
Nem akarom mindig újra feltalálni a kereket, de az indokolatlan lib-használatnak sem vagyok nagy barátja. Itt konkrétan 3 darab regisztert kell beállítani ahhoz amit akarok (jó, tettem bele egy delay-t és egy vizsgálatot is), a linkelt lib-nek csak a header file-ja 4,7 kB, még ha a nagyja komment is. Szerintem az egész kódom nem lesz ennyi, kommentekkel együtt sem.

És még egy probléma van, ezt írja a header file-ban:
Idézet:
„/*
This library is built to support two of the AVR Architecture 'groups' that Arduino uses
a) ATmega48/88/168/328,
b) ATmega640/1280/1281/2560/2561
*/”

Én pedig ATtiny85-tel játszok, bár a kódnak az Attiny25 is elég lenne szerintem.
Következő: »»   461 / 839
Bejelentkezés

Belépés

Hirdetés
Lapoda.hu     XDT.hu     HEStore.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