Arduino PWM regulátor

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Odpovědět
Zpráva
Autor
Uživatelský avatar
stanix1
Příspěvky: 3
Registrován: 06 říj 2016, 02:00

Arduino PWM regulátor

#1 Příspěvek 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.
Přílohy
photo_2022-11-06_11-33-06.jpg
pwm_oled.txt
(4.41 KiB) Staženo 83 x

Uživatelský avatar
Mahoney
Příspěvky: 347
Registrován: 26 říj 2019, 02:00

#2 Příspěvek 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.

petrfilipi
Příspěvky: 2551
Registrován: 13 zář 2005, 02:00

#3 Příspěvek 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

Uživatelský avatar
samec
Příspěvky: 3692
Registrován: 19 pro 2017, 01:00

#4 Příspěvek 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.

Uživatelský avatar
pocitujlasku
Příspěvky: 1757
Registrován: 12 pro 2005, 01:00

#5 Příspěvek 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.
No vidis, a tak si sa bal

Uživatelský avatar
bdn
Příspěvky: 436
Registrován: 16 led 2020, 01:00

#6 Příspěvek 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)
{
	...
	...
	...
}

Uživatelský avatar
samec
Příspěvky: 3692
Registrován: 19 pro 2017, 01:00

#7 Příspěvek 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.

Uživatelský avatar
pocitujlasku
Příspěvky: 1757
Registrován: 12 pro 2005, 01:00

#8 Příspěvek 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.
No vidis, a tak si sa bal

Uživatelský avatar
samec
Příspěvky: 3692
Registrován: 19 pro 2017, 01:00

#9 Příspěvek 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().

Uživatelský avatar
bdn
Příspěvky: 436
Registrován: 16 led 2020, 01:00

#10 Příspěvek 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.

Uživatelský avatar
pocitujlasku
Příspěvky: 1757
Registrován: 12 pro 2005, 01:00

#11 Příspěvek 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.
No vidis, a tak si sa bal

Uživatelský avatar
stanix31
Příspěvky: 10
Registrován: 01 zář 2013, 02:00

#12 Příspěvek 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.

Uživatelský avatar
stanix31
Příspěvky: 10
Registrován: 01 zář 2013, 02:00

#13 Příspěvek od stanix31 »

Posílám slíbené fotky nového ovládače
Přílohy
photo_2022-11-11_15-00-36.jpg
photo_2022-11-11_15-00-14.jpg
PWM s potenciometrem a LCD 16x2
PWM s potenciometrem a LCD 16x2

Uživatelský avatar
elnovy
Příspěvky: 769
Registrován: 04 črc 2010, 02:00
Bydliště: ČR - JČ
Kontaktovat uživatele:

#14 Příspěvek 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: :|
el.návrhář HW a SW a DPS

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“