Odeslat nové téma Odpovědět na téma  [ Příspěvků: 20 ]  Přejít na stránku 1, 2  Další
Autor Zpráva
 Předmět příspěvku: Arduino s seriova linka cez prerusenie
PříspěvekNapsal: úte 04.09.2018 8:39 
Mecenáš serveru
Mecenáš serveru
Uživatelský avatar

Registrován: 18.3.2010
Příspěvky: 2878
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]
241 krát

_________________
X9D & T16Pro & TX16S & nejaké lietadlá, heli a koptéry www.rcmodelytt.sk


Nahoru
 Profil  
 
 
PříspěvekNapsal: úte 04.09.2018 10:23 
Mazák
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
 Profil  
 
PříspěvekNapsal: úte 04.09.2018 11:35 
Mecenáš serveru
Mecenáš serveru
Uživatelský avatar

Registrován: 18.3.2010
Příspěvky: 2878
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
 Profil  
 
PříspěvekNapsal: úte 04.09.2018 13:19 
Mazák
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
 Profil  
 
PříspěvekNapsal: úte 04.09.2018 13:56 
Mecenáš serveru
Mecenáš serveru
Uživatelský avatar

Registrován: 18.3.2010
Příspěvky: 2878
Bydliště: Zavar, SK
A prečo by tam malo byť 2*86 ?!? 8O 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
 Profil  
 
PříspěvekNapsal: úte 04.09.2018 15:59 
Mazák
Mazák
Uživatelský avatar

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
 Profil  
 
PříspěvekNapsal: úte 04.09.2018 18:54 
Mecenáš serveru
Mecenáš serveru
Uživatelský avatar

Registrován: 18.3.2010
Příspěvky: 2878
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
 Profil  
 
PříspěvekNapsal: úte 04.09.2018 19:39 
Mazák
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
 Profil  
 
PříspěvekNapsal: úte 04.09.2018 19:46 
Mecenáš serveru
Mecenáš serveru
Uživatelský avatar

Registrován: 18.3.2010
Příspěvky: 2878
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
 Profil  
 
PříspěvekNapsal: stř 05.09.2018 4:15 
Mazák
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
 Profil  
 
PříspěvekNapsal: stř 05.09.2018 4:45 
Mazák
Mazák
Uživatelský avatar

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
 Profil  
 
PříspěvekNapsal: stř 05.09.2018 4:58 
Mazák
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
 Profil  
 
PříspěvekNapsal: stř 05.09.2018 5:56 
Mazák
Mazák
Uživatelský avatar

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
 Profil  
 
PříspěvekNapsal: stř 05.09.2018 6:52 
Mecenáš serveru
Mecenáš serveru
Uživatelský avatar

Registrován: 18.3.2010
Příspěvky: 2878
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 :roll:
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
 Profil  
 
PříspěvekNapsal: stř 05.09.2018 7:10 
Moderátor serveru
Moderátor serveru
Uživatelský avatar

Registrován: 16.8.2008
Příspěvky: 6893
Bydliště: Moravský kras
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
 Profil  
 
Zobrazit příspěvky za předchozí:  Seřadit podle  
Odeslat nové téma Odpovědět na téma  [ Příspěvků: 20 ]  Přejít na stránku 1, 2  Další

 


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 1 návštěvní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

Hledat:
Přejít na:  

 

  Powered by phpBB® Forum Software © phpBB Group  Český překlad – phpBB.cz 

 

NAVRCHOLU.cz