Stránka 1 z 1

Arduino PWM regulátor

Napsal: 07 lis 2022, 12:54
od stanix1
dobrý den. Postavil jsem si PWM regulátor k řízení modelové železnice s použitím Arduino Nano, PWM-modul s L298N a s OLED displejem 0,96" žluto-modrý I2C. Zapojení používá páku zrychlení - jízda - brzda a 2 tlačítka pro směnu směru, pokud je PWM na Stop. Zařízení funguje, bohužel v nepravidelných intervalech zamrzá displej a řízení rychlosti nebo brzdy je jakoby zrychlené. Interval této chyby je velice náhodný, někdy je to i po několika minutách a nemá to nic společného s rušením (asi), zkoušel jsem samotné Arduino Nano pouze s přepínačem jízda-brzda a s displejem OLED. Nastává stejná chybová situace. Vyzkoušeno již druhé Arduino Nano - dnes nové. precizní klon. Je možné, že je to chybou v programu? Kód je v příloze.

Napsal: 07 lis 2022, 16:17
od Mahoney
Těžko říct, je to tak trochu věštění z křišťálové koule, může být chyba třeba v té grafické knihovně, ale spíš to vypadá jako by přímo na ten displej… Zkus mu dát víc času (o něco snížit obnovovací frekvenci), a/nebo mu dát více času mezi jednotlivými grafickými povely (pár milisekund, oko si toho nevšimne, ale mu to může stačit). Dej pak vědět.

Napsal: 07 lis 2022, 16:19
od petrfilipi
Pokud tam máš volné vývody, uprav program a rozsvěcuj na nich LEDky. Pak uvidíš, kde se program zakousne. Budou to takové pastičky.
U standardních mikrořadičů (třeba PIC) je watchdog, který je schopen zresetoval procesor. Ale není to řešení příčiny, nýbrž následku. Je-li watchdog i u Arduina, to nevím - nikdy jsem to nepotřeboval. Ale určitě tuto informaci někde najdeš.

PF

Napsal: 07 lis 2022, 18:18
od samec
Toto je koncepčný problém tvojho kódu

Kód: Vybrat vše

  while(oled_1.nextPage());
A ďalší problém môže byť v hociktorej funkcii displejovej knižnice.

Preto je lepšie si naštudovať povely pre displej a napísať vlastné funkcie.

Mimochodom, s takto napísanou podmienkou to funguje len náhodou

Kód: Vybrat vše

if (Duty_Cycle < 255) 
      Duty_Cycle=Duty_Cycle+5;
Ale pre vláčiky to nie je zlé. Horšie, keby to bolo pre cirkulár alebo ohňostroje.

Napsal: 07 lis 2022, 18:19
od pocitujlasku
prva vec, nikdy nepouzivaj delay. nahrad ho kontrolou na millis. dalej si pozri, ake casovace a prerusenia kniznice pouzivaju - ci sa navzajom nebiju.

Napsal: 08 lis 2022, 17:50
od bdn
Ten dlouhý loop() lze rozdělit na menší kousky, které lze lépe odladit. Např. dočasně zakomentovat "//". Ideově nějak takto:

Kód: Vybrat vše

void my_control (void);
void my_display (void);

loop()
{
   my_control();
   // my_display(); tady to je zakomentováno, dočasně se neprovádí
}

void my_control (void)
{
   ...
   ...
   ...
}

void my_display (void)
{
   ...
   ...
   ...
}

Jak psal "pocitujlasku", delay() ve funkci loop() nahradit za millis(). Vysvětlení: delay() je pasivní čekání, kdy MCU stojí a nic nedělá. V mnoha případech je lepší mít "časový flag" a např. funkci pro display volat jen co 500ms. Ideově nějak takto:

Kód: Vybrat vše

void my_control (void);
void my_display (void);

int16_t time_is, time_mem1;

loop()
{
   time_is = (int16_t) millis();

   my_control();

   if ((signed)(time_is-time_mem1-1000)>=0)
   {
      time_mem1 = time_is;
      // tento kód běží 1x za sekundu
      my_display();
   }

}

void my_control (void)
{
   ...
   ...
   ...
}

void my_display (void)
{
   ...
   ...
   ...
}

Napsal: 08 lis 2022, 18:38
od samec
delay() nemusí byť problém, ak sa zvyšná časť programu vykonáva v vždy v rovnakých intervaloch. Ale on tam čaká na nejakú odpoveď od displeja a nie že čaká, ale vykonáva kód medzi do a while, kým sa nestrafí do nejakej nulovej odpovede z oled_1.nextPage(). Nechce sa mi študovať, čo tá funkcia robí a vracia, ale nezdá sa mi, že je to v poriadku. Takže celý chod programu je závislý od nejakých nálad displeja.

Napsal: 08 lis 2022, 21:54
od pocitujlasku

Kód: Vybrat vše

unsigned long akcia1=0;
unsigned long aktcas=0;

loop()
{
  aktcas=millis();
   if (akcia1<akcas)
   {
      akcia1=aktcas+1000;
      vykonaj akciu;
   }
}

delay caka, toto bezi stale a tak napr. reaguje na tlacidla hned. v pripade delay by si ho musel drzat min. taky cas ako je delay, aby prebehol cyklus a precital si stav tlacidla.
a tymto vyriesis aj to, ak ti napr. display neodpoveda. tak jednoducho ti na chvilu zatuhne, ale zbytok programu pobezi dalej.
Este take upozornenie, ten millis pretecie za necelych 50 dni. s tym je potrebne pocitat v programe. idealne obcas ten procak resetnut.

Napsal: 09 lis 2022, 00:22
od samec
pocitujlasku píše:ak ti napr. display neodpoveda. tak jednoducho ti na chvilu zatuhne, ale zbytok programu pobezi dalej.
Ak "vykonaj akciu" obsahuje while(1), tak sa vykonania zbytku programu nedočkáš a ani keď tam dáš millis() miesto delay().

Napsal: 09 lis 2022, 07:45
od bdn
...millis pretecie za necelych 50 dni.

Existuje fix tohoto problému. Pokud se číslo v podmínce if(...) porovnává jako signed int potom přetečení proměnné "integer" není problém. Lze to dohledat na webu. Kdysi jsem to zkoušel v debugeru na int16_t a fungovalo to.

Napsal: 09 lis 2022, 08:39
od pocitujlasku
samec: tak samozrejme, nedavat tam nikde while, ale kontrolu cez if. To som bral ako samozrejmost, ze nedam nikde while (nieco bude pripravene), ale if (nieco je pripravene)
while jedine v setup, kedy cakam, kym sa inicializuju vsetky komponenty, aby sa program spustil az ked bude vsetko ok.

bdn: to som neskusal, arduino pouzivam skor na take doplnkove veci, kde nevadi, ze sa obcas restartne, na napr. riadenie kurenia by som ho urcite nepouzil.

Napsal: 10 lis 2022, 21:42
od stanix31
Děkuji všem za odborné rady, bohužel s Arduinem teprve začínám, takže mnoha věcem ještě nerozumím. Pákový ovladač jsem zatím odložil a bleskově jsem vyrobil PWM s potenciometrem, Arduino Nano zůstalo, OLED jsem nahradil LCD 16x2 I2C. Vše funguje bez problémů, velice pomalá jízda vlaků je skvělá. Zítra zde dám pár fotek.

Napsal: 11 lis 2022, 15:44
od stanix31
Posílám slíbené fotky nového ovládače

Napsal: 16 lis 2022, 07:02
od elnovy
Rozhodně zde chybí schéma a výpis celého programu a jake vládáni chce mít zadavatel aby fachalo !!!!
potom by bylo snadné napsat jednoduchý program i pro nováčka . :?: :idea: :arrow: :|