Autor |
Zpráva |
jyrry
|
Napsal: ned 11.02.2018 4:28 |
|
Moderátor serveru
|
|
|
Registrován: 28.2.2005 Příspěvky: 20846 Bydliště: Rakovník, CZ Obrázky: 0
|
Zkusím stvořit stejné udělátko jako mám v B-25; vstup je jeden kanál a ovládá to 3 serva - vrata pumovnice a odhozy celkem čtyř pum v libovolném počtu na jedno otevření vrat. Ona syntaxe je jakoby jiná ale ta struktura se mi začíná osvětlovat, ono to jinak ani snad být nemůže... u PICBasicu jsem si s přerušením už zahrával; u serv až tak o moc nejde ale u časovačů to chci mít tak trochu "zkalibrované" i když nakonec si letový čas každý nastavuje individuálně a je jedno zda má "delší" nebo "kratší" vteřinu... Hlavně mně baví naučit se něco nového, i když to jen bliká LEDkou
_________________ jyrry.webnode.cz
|
|
Nahoru |
|
|
|
|
|
ellet
|
Napsal: ned 11.02.2018 12:38 |
|
Mazák
|
|
|
Registrován: 12.2.2016 Příspěvky: 1986 Bydliště: Vysočina, ČR
|
Cykly (počítaný, s podmínkou na začátku nabo na konci), větvení (if,case..), skoky....vše jako basic, jen to trochu jinak vypadá. Určitě bude ale dobrý trochu kouknout na procesory avr (a když už tě to přerušení láká, tak na př. každý typ přerušení má vlastní vektor - rozíl od picu).
|
|
Nahoru |
|
|
jyrry
|
Napsal: pon 12.02.2018 0:43 |
|
Moderátor serveru
|
|
|
Registrován: 28.2.2005 Příspěvky: 20846 Bydliště: Rakovník, CZ Obrázky: 0
|
Ještě nadhodím myšlenku - v PICech někdy z lenosti používám na čtení servosignálu fci PULSIN; v té knihovně "servo.h" nejspíš bude něco podobného ale zatím to chci obejít. Předpokládám změřit dobu trvání impulzu na vstupu pomocí čtení časovače micros() a HW přerušení RISING a FALLING, snad to dám dohromady. Pomocí spouštěných timerů jako to mám u PICů to ale asi nejde, nenašel jsem pro to příkazy Je tam ten jeden stále běžící timer v ms a us, tak snad to bude rozumně fungovat.
_________________ jyrry.webnode.cz
|
|
Nahoru |
|
|
BoŠ
|
Napsal: pon 12.02.2018 6:35 |
|
Mazák
|
|
|
Registrován: 26.5.2013 Příspěvky: 1538 Bydliště: Brno
|
jyrry píše: Ještě nadhodím myšlenku - v PICech někdy z lenosti používám na čtení servosignálu fci PULSIN; v té knihovně "servo.h" nejspíš bude něco podobného ale zatím to chci obejít. Předpokládám změřit dobu trvání impulzu na vstupu pomocí čtení časovače micros() a HW přerušení RISING a FALLING, snad to dám dohromady. Pomocí spouštěných timerů jako to mám u PICů to ale asi nejde, nenašel jsem pro to příkazy Je tam ten jeden stále běžící timer v ms a us, tak snad to bude rozumně fungovat. U atmelu používám příkazy dle datasheetu pro daný procesor, jen je třeba přilinkovat při překladu i příslušnou knihovnu dodávanou výrobcem. Potom lze plně programovat a obsluhovat procesor, tak jako je člověk zvyklý. Např.: Citace: // >>>>>>>>>>>>>>>>>>>>>> ATtiny45 Pouziti Timeru IV a ISR od BUTTON II <<<<<<<<<<<<<<<<<<<<<<<<<< // Achtung,achtung - aby fungovalo millis a micros a delay, // musi byt povolen overflow timer0, proto masku oruj pro nastaven9 // a anduj pro vymazani // Vse funkcni // Dalsi pokusy - on/off blikac // ATMEL ATTINY 25/45/85 / ARDUINO // // +-\/-+ // Ain0 (D 5) PB5 1| |8 Vcc // Ain3 (D 3) PB3 2| |7 PB2 (D 2) Ain1 // Ain2 (D 4) PB4 3| |6 PB1 (D 1) pwm1 // GND 4| |5 PB0 (D 0) pwm0 // +----+ // Aktualni zapojeni // _____ // +-\/-+ +------o o-------------+--- Vcc // PB5 1| |8 Vcc | | // Vcc---XXXXXX----|>|-----2| |7 PB2 ---+ 220R | // 220R PB4 3| |6 PB1 ---|---|<|-------XXXXXX-----+ // + GND 4| |5 PB0 ---|---|<|-------XXXXXX-----+ // | +----+ | 220R // +-------XXXXXX----------+ // 5k /* LED1 LOW, LED2 HIGH, LED4 LOW ovladana (OCR1A), LED2 LOW, LED4 HIGH ovladana (OCR1B) a LED1 LOW ovladana od timeru 1 */ #define DEBOUNCE_DELAY 300 const byte LED1 = 0; const byte LED2 = 1; const byte LED4 = 3; const byte BUTTON = 2; volatile unsigned char state = 0; ISR(TIMER1_COMPA_vect) { digitalWrite (LED2, HIGH); digitalWrite (LED4, LOW); } ISR(TIMER1_COMPB_vect) { digitalWrite (LED2, LOW); digitalWrite (LED4, HIGH); OCR1B>=255?OCR1B=0:++OCR1B; } ISR(INT0_vect) { static unsigned long last_millis = 0; unsigned long m = millis(); if (m - last_millis > DEBOUNCE_DELAY ) // ignoruj preruseni { cli(); state=!state; digitalWrite (LED1, state); sei(); } last_millis = m; GIFR = bit (INTF0); // clear flag for interrupt 0 } void setup () { pinMode (LED1, OUTPUT); pinMode (LED2, OUTPUT); pinMode (LED4, OUTPUT); pinMode (BUTTON, INPUT); // set up ISR MCUCR &= ~3; // clear existing flags// sense 0-low, 1- change, 2-falling, 3-rising MCUCR |= 3; // set wanted flags (falling level interrupt) //GIMSK = bit (6);//| bit(5); // enable it bit 6 INT0, bit 5 PCIE GIMSK= 0b01000000; // PCMSK; bit 0 az 6 / maska na change, pokud povoleno GIMSK PCIE bit 5 // GIFR = bit (INTF0); // clear flag for interrupt 0 // set up Timer 1 TCCR1 = 0b00001111; // normal operation, delicka 8 GTCCR = 0b00000000; // reset prescaler OCR1A = 0b00000001; // compare A register value (1000 * clock speed) OCR1B = 0b00000001; OCR1C = 0b01111111; TIMSK |= 0b01100000; /* ORuj !!! Jinak nefunguje millis, micros a delay, ktere pouzivaji Timer0 a jeho overflow interupt interrupt on Compare A Match BIT 6 1A, 5 JE 1B, 2 JE 1C*/ GIFR = bit (INTF0); // clear flag for interrupt 0 sei(); } // end of setup void loop () { if(state) { digitalWrite (LED1, HIGH); delay(500); digitalWrite (LED1, LOW); delay(500); digitalWrite (LED1, HIGH); } }
_________________ MC-20HOTT,DS-16,X10S,14SG,S-trino MkII,SpeedFire, Extra 102",MiniCorado,LOGO550SE,Goblin570
|
|
Nahoru |
|
|
jyrry
|
Napsal: pon 12.02.2018 8:05 |
|
Moderátor serveru
|
|
|
Registrován: 28.2.2005 Příspěvky: 20846 Bydliště: Rakovník, CZ Obrázky: 0
|
Jooo, to je jiná liga, zkusím se tím prolouskat, díky. Timer1 vidím, pak ty příkazy kolem přerušení... ono je to fakt docela podobné, jdu stáhnout datasheet No a pochroupnout syntaxi
_________________ jyrry.webnode.cz
|
|
Nahoru |
|
|
BoŠ
|
Napsal: pon 12.02.2018 9:19 |
|
Mazák
|
|
|
Registrován: 26.5.2013 Příspěvky: 1538 Bydliště: Brno
|
Syntaxe je Céčková, názvy registrů jsou čip od čipu odlišné, ale vždy v souladu s datasheet, a výrobce je vždy definuje v dodané knihovně, resp. v header file. V Datasheet jsou obvykle také příklady použití registrů a instrukcí v assembleru a v jazyku C. Pro programování čipů používám arduinovské prostředí, kde není problém header fily a knihovny přilinkovat, akorát si pak nechám program pro daný typ čipu zkompilovat, a do čipu už nahrávám binárku pomocí programátoru Presto. Vlastní vývojový kit Arduina používám minimálně, většinou s nějakými shieldy - ethernet, wifi, apod, který se mě nechce pro vývoj drátovat na nepájivém poli. Pokud používám nějaké opensource arduino knihovny, tak se podívám, jak jsou udělány, protože úroveň programátorů je různá, a občas si knihovny navzájem nechtěně zablokují funkce, nebo jsou udělány ne moc efektivně.
_________________ MC-20HOTT,DS-16,X10S,14SG,S-trino MkII,SpeedFire, Extra 102",MiniCorado,LOGO550SE,Goblin570
|
|
Nahoru |
|
|
jyrry
|
Napsal: pon 12.02.2018 21:36 |
|
Moderátor serveru
|
|
|
Registrován: 28.2.2005 Příspěvky: 20846 Bydliště: Rakovník, CZ Obrázky: 0
|
Tak momentálně mi uspokojivě funguje tohle (klíč k úspěchu bylo nalézt kde přerušení povolit a kde zakázat; no a je to takový... strojařskoamatérský ): Kód: // cteni a generovani PWM servosignalu: int neutral_uS = 1500; int hystereze = 100; int puls_uS; int ramec_uS = 20000; const byte LED = 1; const byte PWM = 2; const byte servo1 = 3; const byte servo2 = 4; void setup() { pinMode(LED, OUTPUT); // LEDka pinMode(PWM, INPUT); // vstup PWM pinMode(servo1, OUTPUT); // servo 1 pinMode(servo2, OUTPUT); // servo 2 attachInterrupt(0, ctipuls, RISING); }
void loop() { noInterrupts(); ledka(); pulz(puls_uS, servo1); interrupts(); delayMicroseconds(ramec_uS - puls_uS); } void ledka() { if (puls_uS > neutral_uS + hystereze) digitalWrite(LED, HIGH); if (puls_uS < neutral_uS - hystereze) digitalWrite(LED, LOW); }
void pulz(int pulz_uS, byte servo) { digitalWrite(servo, HIGH); delayMicroseconds(pulz_uS); digitalWrite(servo, LOW); }
void ctipuls() { unsigned long aktual_uS = micros(); long newpuls_uS; while (digitalRead(2) == HIGH) { } newpuls_uS = micros() - aktual_uS; if (newpuls_uS < 400) newpuls_uS = puls_uS; // osetreni delky if (newpuls_uS > 2600) newpuls_uS = puls_uS; // osetreni delky puls_uS = newpuls_uS; }
_________________ jyrry.webnode.cz
|
|
Nahoru |
|
|
ellet
|
Napsal: pon 12.02.2018 22:16 |
|
Mazák
|
|
|
Registrován: 12.2.2016 Příspěvky: 1986 Bydliště: Vysočina, ČR
|
jyrry píše: Tak momentálně mi uspokojivě funguje tohle .... No je vidět, že se snažíš . Chtělo by to ale ošetřit proměnnou puls_uS. Dokud nepřijde regulérní pulz, tak je (asi) nulová (jestli teda dobře vidím)
|
|
Nahoru |
|
|
jyrry
|
Napsal: úte 13.02.2018 6:24 |
|
Moderátor serveru
|
|
|
Registrován: 28.2.2005 Příspěvky: 20846 Bydliště: Rakovník, CZ Obrázky: 0
|
Jojo, chytlo mně to Je to polotovar, teď to začnu oblepovat dalšími funkcionalitami; ten puls_uS bude první. Zatím jsem se trápil záškuby serva a poblikáváním LEDky až mně napadlo zakázat přerušení tam kde to teď je a naprosto se to zklidnilo tak můžu pokračovat. Ono to ošetření nepřišlých/nesprávných impulzů je dobré ale na druhou stranu, v aplikaci kde to třeba bude pokud nepřijdou impulzy tak už to stejně bude jedno
_________________ jyrry.webnode.cz
|
|
Nahoru |
|
|
BoŠ
|
Napsal: úte 13.02.2018 6:48 |
|
Mazák
|
|
|
Registrován: 26.5.2013 Příspěvky: 1538 Bydliště: Brno
|
Bývá dobrým zvykem při obsluze přerušení další přerušení zakázat a na konci obsluhy zase povolit ( v mém příkladu funkce cli() a sei()), pokud ovšem cíleně nepotřebuješ další přerušení zpracovat. Další věc je ta, že čekání na konec akce ve smyčce nebo pomocí delay se projeví zpožděním obsluhy dalších funkcí, které tam přidáš - třeba obsluha displeje, komunikace atd. Tato úloha je jako stvořená pro obsluhu pomocí přerušení bez čekacích smyček, nebo bez přerušení v rámci jedné hlavní programové smyčky Loop, kdy stále dokola čteš vstup PWM a posíláš stav na výstupy, případně se provedou i další části programu (tento způsob lineárního programování se používá v řídících počítačích), a místo delay si pomocí čtení času zapamatuješ čas průchodu programem při počátku zpoždění, a každým průchodem si hlídáš uplynulý čas tak že od aktuálního času si odečteš čas zapamatovaný. Tím je zajištěno, že obsloužíš všechny funkce programu. Tvůj program by šel takto upravit snadno, protože to už částečně máš naprogramováno, stačilo by jen lehce upravit kód tak, aby zmizel delay. Btw. stačilo by v hlavní smyčce kopírovat stav vstupu 2 do výstupu pro servo s ošetření minimální a maximální délky pulsu. Pokud program dělaš pro AtTiny, pro ovládání serva by šel použít vestavěný PWM a časovače. Jinak se mi líbí, jak ses do toho pustil
_________________ MC-20HOTT,DS-16,X10S,14SG,S-trino MkII,SpeedFire, Extra 102",MiniCorado,LOGO550SE,Goblin570
Naposledy upravil BoŠ dne úte 13.02.2018 7:21, celkově upraveno 1
|
|
Nahoru |
|
|
jyrry
|
Napsal: úte 13.02.2018 7:21 |
|
Moderátor serveru
|
|
|
Registrován: 28.2.2005 Příspěvky: 20846 Bydliště: Rakovník, CZ Obrázky: 0
|
BoŠ píše: ... pomocí čtení času zapamatuješ čas průchodu programem při počátku zpoždění, a každým průchodem si hlídáš uplynulý čas ... Jojo, to jsem u PICů nezkoušel, tady to zatím mám jen v tom čtení pulzu ale zkusím to cvičně překopat, abych věděl co to dělá. Ono se to ale zdrží okolními příkazy než to zase při dalším průchodu načte stav timeru a porovná ho, ne? To si asi neumím spočítat o kolik to bude ale změřit to zpoždění půjde na osciloskopu změřením výsledné délky generovaného servoimpulzu... Používám ATtiny85 v téhle destičce a Arduino IDE (poslední verzi), zkusil jsem do něj nakopírovat tvůj zdroják a řadu příkazů to vůbec neznalo, nejspíš pro tuhle destičku...
_________________ jyrry.webnode.cz
|
|
Nahoru |
|
|
BoŠ
|
Napsal: úte 13.02.2018 7:27 |
|
Mazák
|
|
|
Registrován: 26.5.2013 Příspěvky: 1538 Bydliště: Brno
|
jyrry píše: Jojo, to jsem u PICů nezkoušel, tady to zatím mám jen v tom čtení pulzu ale zkusím to cvičně překopat, abych věděl co to dělá. Ono se to ale zdrží okolními příkazy než to zase při dalším průchodu načte stav timeru a porovná ho, ne? To si asi neumím spočítat o kolik to bude ale změřit to zpoždění půjde na osciloskopu změřením výsledné délky generovaného servoimpulzu... Používám ATtiny85 v téhle destičce a Arduino IDE (poslední verzi), zkusil jsem do něj nakopírovat tvůj zdroják a řadu příkazů to vůbec neznalo, nejspíš pro tuhle destičku... Předpokládám, že při hodinách cca 8Mhz by těch pár příkazů mělo být relativně rychlých, ale to lze snadno ověřit tím, že si změříš čas trvání průchodu smyčkou. Pokud by kód byl rozsáhlejší, tak by pak bylo řešením využití časovačů a přerušení. Co se týká prostředí, zvolil jsi v Nástroje/Vývojová deska desku AtTiny25/45/85 ? Je pravda, že knihovny pro AtTiny jsem do prostředí Arduina dohrával, nepoužívám bootloader, protože to flashuji Presto programátorem přímo do čipu bez jakékoliv pomoci Arduina.
_________________ MC-20HOTT,DS-16,X10S,14SG,S-trino MkII,SpeedFire, Extra 102",MiniCorado,LOGO550SE,Goblin570
|
|
Nahoru |
|
|
ellet
|
Napsal: úte 13.02.2018 12:47 |
|
Mazák
|
|
|
Registrován: 12.2.2016 Příspěvky: 1986 Bydliště: Vysočina, ČR
|
BoŠ píše: Bývá dobrým zvykem při obsluze přerušení další přerušení zakázat a na konci obsluhy zase povolit... Ano, to se často píše, jen nevím proč. Citát z literatury (Matoušek): "Když je přerušení aktivováno, je bit I (reg SREG) automaticky vynulován a tak je příjem všech přerušení zakázán. Řízení programu přechází do rutiny přerušení.....Provedením instrukce RETI (návrat z obsluhy přerušení) je bit I automaticky nastaven, takže se příjem přerušení povolí." Ostatně je to jen překlad z datasheetu. Že by překladeč měnil inplicitní chování?....
|
|
Nahoru |
|
|
jyrry
|
Napsal: úte 13.02.2018 12:59 |
|
Moderátor serveru
|
|
|
Registrován: 28.2.2005 Příspěvky: 20846 Bydliště: Rakovník, CZ Obrázky: 0
|
BoŠ píše: ... Co se týká prostředí, zvolil jsi v Nástroje/Vývojová deska desku AtTiny25/45/85 ? ... Ne, dohrál jsem tam přímo tu desku Digispark, našel jsem to v nějakém popisu k té destičce.
_________________ jyrry.webnode.cz
|
|
Nahoru |
|
|
BoŠ
|
Napsal: úte 13.02.2018 13:37 |
|
Mazák
|
|
|
Registrován: 26.5.2013 Příspěvky: 1538 Bydliště: Brno
|
ellet píše: Ano, to se často píše, jen nevím proč. Citát z literatury (Matoušek): "Když je přerušení aktivováno, je bit I (reg SREG) automaticky vynulován a tak je příjem všech přerušení zakázán. Řízení programu přechází do rutiny přerušení.....Provedením instrukce RETI (návrat z obsluhy přerušení) je bit I automaticky nastaven, takže se příjem přerušení povolí." Ostatně je to jen překlad z datasheetu. Že by překladeč měnil inplicitní chování?.... Ano, máš pravdu, že pro AtTiny platí, že při přerušení je bit I nulován, a voláním RETI opět nastaven, takže cli a sei je zde pravděpodobně zbytečný, pokud to překladač takto přeloží. Obecně ale platí, že z obslužné rutiny přerušení se dá vrátit různým způsobem( tedy pokud člověk programuje v assembleru), takže se tímto předcházím i případným odlišným interpretacím kódu překladačem. Já to ošetření pomocí zákazu a povolení přerušení používám standartně, protože ne všechny procesory mají tak jednoduchý přerušovací systém, jako AtTiny, a je to i pro mě jakési upozornění, že provádím část programu kritickou vůči přerušení, a navíc se jedná maximálně o dvě dvoucyklové zbytečné instrukce. Další věcí je, že subrutinu občas volám přímo z programu. Tolik za mě.
_________________ MC-20HOTT,DS-16,X10S,14SG,S-trino MkII,SpeedFire, Extra 102",MiniCorado,LOGO550SE,Goblin570
|
|
Nahoru |
|
|
Kdo je online |
Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 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
|
|
|