Autor |
Zpráva |
ddano007
|
Napsal: úte 04.09.2018 9:39 |
|
Mecenáš serveru
|
|
|
Registrován: 18.3.2010 Příspěvky: 2881 Bydliště: Zavar, SK
|
Páni, čo viete robiť s Arduinom, poprosím Vás o radu: Spravil som s Arduino Mini Pro displej + klávesnicu + nejaké analógové merania a potrebujem s tým komunikovať cez RS422 na 115 200 Baud, pričom na zbernici je aj hafo iných zariadení. Keďže to má aj displej, ktorý je príšerne pomalý, dal som prerušenie na Timer1 500us a v prerušení obsuhujem sériovú linku, lebo komunikácia po RS422 musí mať najvyššiu prioritu. Všetko je funguje super ... až na to, že po čase program zamrzne Nejaký pokec k programu/ nekorektnosti o ktorých viem: 1, vzhľadom na časové pomery na zbernici mi stačí prerušenie 500us, za ten čas príde max. 6 - 7 Bytov, ktoré načítavam na začiatku prerušenia. Komunikácia na RS422 beží v ASCII znakoch, paket začína "#" + dva znaky adresa + nejaký príkaz + končí to CR LF, keď zistím LF ( 0x0a ), analyzujem, či je to adresa displeja a aký povel, vtedy zastavím Timer1. 2, Ak je displej zaadresovaný, potrebujem odpovedať Master zariadeniu cez Serial.print/ Serial.println a vtedy povolím prerušenia, pošlem odpoveď pre Master a prerušenia zase zakážem. Toto vidím ako potenciálne ako problém, ale bez povolenia prerušenia mi Serial.print neprejde. Neviete dať tip, ako sa dopátrať problému? Či pretečie zásobník, alebo je tam nejaký časový hazard alebo či čo? inicializácia Timer1 píše: void setup(void){
// set up Timer 1 TCCR1A = 0;// set entire TCCR1A register to 0 TCCR1B = 0;// same for TCCR1B TCNT1 = 0;//initialize counter value to 0 TCCR1B |= (1 << WGM12); // režim CTC TCCR1B |= (1 << CS11) | (1 << CS10); //prescaler 64 = 250kHz = 4us OCR1A = 125; // 500us interrupt // OCR1A = 100; // 400us interrupt // OCR1A = 9; // 40us interrupt // OCR1A = 14; // 60us interrupt TIMSK1 |= (1 << OCIE1A); // interrupt on Compare A Match
Začiatok obsluhy prerušenia píše: //******************************************************************************************** // TIMER1 interrupt 500us //********************************************************************************************
ISR(TIMER1_COMPA_vect) { // zaciatok prerusenia
... do { incomingByte = Serial.read(); InSerial[InSerialPointer] = incomingByte; InSerialPointer++; } while ( ( Serial.available() > 0) && (incomingByte != 10) && ( InSerialPointer < 32 ) ) ;
...
vysielanie po RS422 píše: // ***************************************************** // *** RS422 serial output *** // *****************************************************
int RS422Print ( String RS422String , volatile int CRLF ) { // TransmittDelay = 46*( RS422String.length() + 2); TransmittDelay = 5 + 87*RS422String.length(); if ( MyAddress == true ) interrupts();
// TransmittTime = micros() + TransmittDelay ;
digitalWrite(TxOutputEnable, HIGH); if ( CRLF == 1 ) { Serial.println (RS422String); TransmittDelay = TransmittDelay + 2*87; } if ( CRLF == 0 ) Serial.print (RS422String);
TransmittDelay = TransmittDelay/10 + 1; do {
delayMicroseconds(10); TransmittDelay--; } while ( TransmittDelay > 0 );
noInterrupts();
digitalWrite(TxOutputEnable, LOW);
return (0); }
Příloha:
H2DISP_18.ino [39.16 KiB]
243 krát
_________________ X9D & T16Pro & TX16S & nejaké lietadlá, heli a koptéry www.rcmodelytt.sk
|
|
Nahoru |
|
|
|
|
|
sky59
|
Napsal: úte 04.09.2018 11:23 |
|
Mazák
|
|
Registrován: 21.9.2015 Příspěvky: 991
|
Pokial tam budu taketo riadky nikdy to poriadne fungovat nebude:
TransmittDelay = 5 + 87*RS422String.length(); TransmittDelay = TransmittDelay + 2*87; TransmittDelay = TransmittDelay/10 + 1;
|
|
Nahoru |
|
|
ddano007
|
Napsal: úte 04.09.2018 12:35 |
|
Mecenáš serveru
|
|
|
Registrován: 18.3.2010 Příspěvky: 2881 Bydliště: Zavar, SK
|
Má to nejaký "vliv na funkci rostlináře"? Skús vysvetliť.
_________________ X9D & T16Pro & TX16S & nejaké lietadlá, heli a koptéry www.rcmodelytt.sk
|
|
Nahoru |
|
|
sky59
|
Napsal: úte 04.09.2018 14:19 |
|
Mazák
|
|
Registrován: 21.9.2015 Příspěvky: 991
|
Co na tom vysvetlovat? Preco tam nie je 2*86 ?
Taketo casovania nemozu nikdy fungovat, neviem kto to pisal ale bol jasne v koncoch ked sa uchylil k tomuto sadomasochizmu.....
|
|
Nahoru |
|
|
ddano007
|
Napsal: úte 04.09.2018 14:56 |
|
Mecenáš serveru
|
|
|
Registrován: 18.3.2010 Příspěvky: 2881 Bydliště: Zavar, SK
|
A prečo by tam malo byť 2*86 ?!? Prenos 10 bitov pri 115 200 Baud trvá 86.8us, čo je 87us. Aspoň nás tak učili zaokrúhľovať. Daj tip, ako to vyriešiť čistejšie, budem Ti povďačný... A kôli tomu to zamrzne?
_________________ X9D & T16Pro & TX16S & nejaké lietadlá, heli a koptéry www.rcmodelytt.sk
|
|
Nahoru |
|
|
BoŠ
|
Napsal: úte 04.09.2018 16:59 |
|
Mazák
|
|
|
Registrován: 26.5.2013 Příspěvky: 1538 Bydliště: Brno
|
Ten timer stopneš a znova pustíš, nebo jede pořád, a každých 500 ms znovu spouští obslužnou rutinu? V tom druhém případě by mohlo dojít k k rozsynchronizaci a případnému zablokování procesu.
_________________ MC-20HOTT,DS-16,X10S,14SG,S-trino MkII,SpeedFire, Extra 102",MiniCorado,LOGO550SE,Goblin570
|
|
Nahoru |
|
|
ddano007
|
Napsal: úte 04.09.2018 19:54 |
|
Mecenáš serveru
|
|
|
Registrován: 18.3.2010 Příspěvky: 2881 Bydliště: Zavar, SK
|
Ten Timer1 beží stále, len keď je zaadresovaný displej, t.j. každých cca 300ms, ho zastavím, odpoviem po zbernici Master-ovi a zase Timer1 pustím. Doplňujúca otázka: nie je Timer1 využívaný nejakými systémovými procesmi? Pre delay, millis, microdelay alebo tak niečo? Pýtam sa preto, že na konci hlavného cyklu mám delay (1), ale keď som skúšal tam dať povedzme delay (500), tak sa mi zdá, že to nefungovalo - skončilo to skôr ako za 500ms. Ako keby interupt od Timer1, alebo sériová linka alebo čosi ten delay zrušilo...
_________________ X9D & T16Pro & TX16S & nejaké lietadlá, heli a koptéry www.rcmodelytt.sk
|
|
Nahoru |
|
|
sky59
|
Napsal: úte 04.09.2018 20:39 |
|
Mazák
|
|
Registrován: 21.9.2015 Příspěvky: 991
|
Nemam cas studovat detailne co je tam napisane /a ani chut ked su tam casove slucky/ program musi byt napisany bez akehokolvek cakania kdekolvek a potom to funguje za kazdych podmienok, nechapem naco pocitas cas bitov, to nema hardwarovu seriovu linku?
|
|
Nahoru |
|
|
ddano007
|
Napsal: úte 04.09.2018 20:46 |
|
Mecenáš serveru
|
|
|
Registrován: 18.3.2010 Příspěvky: 2881 Bydliště: Zavar, SK
|
sky59 píše: ... nechapem naco pocitas cas bitov, to nema hardwarovu seriovu linku? Má, veď aj používam Serial.print. Ale RS422 je trojstavová zbernica. Pred vysielaním musím aktivovať budič zbernice a odoslaní všetkých Bytov ho zase zablokovať, preto to počítam...
_________________ X9D & T16Pro & TX16S & nejaké lietadlá, heli a koptéry www.rcmodelytt.sk
|
|
Nahoru |
|
|
sky59
|
Napsal: stř 05.09.2018 5:15 |
|
Mazák
|
|
Registrován: 21.9.2015 Příspěvky: 991
|
ddano007 píše: Má, veď aj používam Serial.print. Ale RS422 je trojstavová zbernica. Pred vysielaním musím aktivovať budič zbernice a odoslaní všetkých Bytov ho zase zablokovať, preto to počítam... Tam je zrejme pes zakopany, uz chapem o co ti ide.. musis riadit smer 422.... Nikde nie je napisane ze medzi vyslanymi bytami nie je pauza sposobena bohvie cim, prerusenim atd.. A neda sa z original hw seriovej linky vycitat ci uz skoncila vysielat? To sa snazis pre kazdy jednotlivy byte riadit 422 alebo tam mas nejake sprsvy a robis tu snahu pre celu spravu? Nakolko je regulerne tu 422 zhadzovat do idle stavu a potom 'beztrestne' pokracovat znova vo vysielani? interrupts() a nointerrupts() povoluje/zakazuje interrupty? Vsetky? Alebo to ma iba jeden intr? To vidim ako dalsi problem zakazovat intr, to nie je dovod robit, to sa robi iba vo vynimocnych pripadoch nepr, potrebujes precitat 2 byty v rovnakom okamihu, tak na par cyklov zakazes interrupty aby ziaden proces pocas robenia ich kopie ich nezmodifikoval
|
|
Nahoru |
|
|
BoŠ
|
Napsal: stř 05.09.2018 5:45 |
|
Mazák
|
|
|
Registrován: 26.5.2013 Příspěvky: 1538 Bydliště: Brno
|
ddano007 píše: Ten Timer1 beží stále, len keď je zaadresovaný displej, t.j. každých cca 300ms, ho zastavím, odpoviem po zbernici Master-ovi a zase Timer1 pustím. Doplňujúca otázka: nie je Timer1 využívaný nejakými systémovými procesmi? Pre delay, millis, microdelay alebo tak niečo? Pýtam sa preto, že na konci hlavného cyklu mám delay (1), ale keď som skúšal tam dať povedzme delay (500), tak sa mi zdá, že to nefungovalo - skončilo to skôr ako za 500ms. Ako keby interupt od Timer1, alebo sériová linka alebo čosi ten delay zrušilo... Jestli si dobře vzpomínám, tak to tak asi je - delay je odvozena od timer1. Nicméně si myslím, že k problému dojde v situaci, kdy se vzhledem k postupnému časovému posunu potká přerušení od Timeru a jeho obsluha s přerušením od Serial.Print.
_________________ MC-20HOTT,DS-16,X10S,14SG,S-trino MkII,SpeedFire, Extra 102",MiniCorado,LOGO550SE,Goblin570
|
|
Nahoru |
|
|
sky59
|
Napsal: stř 05.09.2018 5:58 |
|
Mazák
|
|
Registrován: 21.9.2015 Příspěvky: 991
|
BoŠ píše: Jestli si dobře vzpomínám, tak to tak asi je - delay je odvozena od timer1. Nicméně si myslím, že k problému dojde v situaci, kdy se vzhledem k postupnému časovému posunu potká přerušení od Timeru a jeho obsluha s přerušením od Serial.Print.
Pokial sa nerobia nejake hluposti, tak prerusenia mozu prist naraz, prerusenie moze byt prerusene inym s vyssou prioritou, az pokial nepretecie stack Treba sa zbavit 'manualneho' casovania cez delay a napisat to korektne nech to bezi samo a je po probleme, akykolvek program zavisly od delay je odsideny na problemy pocas runtime
|
|
Nahoru |
|
|
BoŠ
|
Napsal: stř 05.09.2018 6:56 |
|
Mazák
|
|
|
Registrován: 26.5.2013 Příspěvky: 1538 Bydliště: Brno
|
sky59 píše: Pokial sa nerobia nejake hluposti, tak prerusenia mozu prist naraz, prerusenie moze byt prerusene inym s vyssou prioritou, az pokial nepretecie stack
Treba sa zbavit 'manualneho' casovania cez delay a napisat to korektne nech to bezi samo a je po probleme, akykolvek program zavisly od delay je odsideny na problemy pocas runtime
Souhlas. Jakákoliv čekací smyčka, nejen odvozená od delay, je při použití v obslužných rutinách přerušení problém. Co se týká priorit, nevím, zda u jednočipu atmelu je tu nastavena hiearchie přerušení, mám dojem, že mě právě někdo upozorňoval na zbytečnost zákazu přerušení při obsluze přerušení (jak jsem byl zvyklý z normálních počítačů), protože do příkazu návratu z přerušení RETI jsou jiná přerušení zakázána, a měl pravdu. Obsluha přerušení by měla být striktně lineární. Kdysi něco podobného řešil Jyrry, možná by se to vlákno dalo ještě najít, a inspirovat se tam. Edit: Tuto je to vlákno viewtopic.php?f=41&t=80225&start=15
_________________ MC-20HOTT,DS-16,X10S,14SG,S-trino MkII,SpeedFire, Extra 102",MiniCorado,LOGO550SE,Goblin570
|
|
Nahoru |
|
|
ddano007
|
Napsal: stř 05.09.2018 7:52 |
|
Mecenáš serveru
|
|
|
Registrován: 18.3.2010 Příspěvky: 2881 Bydliště: Zavar, SK
|
K RS422: neriadim smer, len aktivujem výstupný budič pred vysielaním a po odoslaní všetkých znakov ho deaktivujem. Toto chodí korektne, keď som povedal, že po čase program zmrzne, znamená, že zmrzne komplet, nielen komunikácia po RS422. K interuptom: pri prerušení od Timer1 nejde serial.print, ergo minimálne prerušenie od sériovej linky. Preto pri vysielaní povolujem prerušenia. Pri MSC51 procesoroch interupt od jedného zdroja zakázal všetky preušenia až po reti, pri Atmele to asi bude podobné. Priorita prerušení pri MCS51 znamenala, že pri súčasnej požiadavke na preušenie z dvoch zdrojov vyhral ten s vyššou prioritou, ale počas obsluhy nižššieho prerušenia ho vyššie prerušenie neprerušilo. Timer1 a delay: mne sa práve kdesi marí, že systém by mal používať Timer0, ak používa Timer1, to by som radšej prekopal to prerušenie na niečo, čo systém nepoužíva. V assembleri si človek všetko naprogramoval sám, ergo som vedel, čo mi kde beží, v Arduine akosi neviem, čo beží kde v systéme A keďže programovať obsuhu grafického displeja v asembleri sa mi nechce, tak skúšam toto Ale vnukli ste mi dobrý nápad, skúsim prekopať ten interupt na 88us a ovládať výstupný budič priamo pri prerušení, nemusel by som používať microdelay, ani povolovať interupty a podobné humusáctva. Len neviem, či tak pôjde serial.print. Každopádne vďaka.
_________________ X9D & T16Pro & TX16S & nejaké lietadlá, heli a koptéry www.rcmodelytt.sk
|
|
Nahoru |
|
|
JirkaA
|
Napsal: stř 05.09.2018 8:10 |
|
Moderátor serveru
|
|
|
Registrován: 17.8.2008 Příspěvky: 6902 Bydliště: Moravský kras ČR
|
Jen myšlenka bez hlubšího studia, ale co takhle ten driver 422 povolit, poslat string a pro shození driveru si pohlídat flag prázdnýho bufferu na té sériovce? Klidně v hlavní smyčce naprosto asynchronně, ono bude jedno jestli ho shodíš o trochu později...
_________________ OK2WY
|
|
Nahoru |
|
|
Kdo je online |
Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 15 návštevníků |
|
Nemůžete zakládat nová témata v tomto fóru Nemůžete odpovídat v tomto fóru Nemůžete upravovat své příspěvky v tomto fóru Nemůžete mazat své příspěvky v tomto fóru Nemůžete přikládat soubory v tomto fóru
|
|
|