Servoreverz s ATtiny85

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

Moderátor: Moderátoři

Zpráva
Autor
Uživatelský avatar
Celeron
Příspěvky: 20508
Registrován: 02 dub 2011, 00:00
Bydliště: Nový Bydžov

#31 Příspěvek od Celeron »

Tak nevím, kolikrát to tady mám napsat. Servu stačí ±2 us na to, aby bylo neklidný v středový poloze. A jak chceš časovačem, kterej se plní periodou 1us něco přesně u takovýhleho signálu měřit? Vzorkovací kmitočet jak známo musí být cca 10x vyšší než měřený.
Mám tady vzorek vývojový desky Silabs C8051F392. 16 bitů časovač by se plnil kmitočtem 25MHz, což by dalo při měření až 2,65ms, z obsahu spočítat reverz, v druhým časovači odečítat dýlku výstupního signálu. V asembleru je u F392 většina instrukcí jenocyklových na kmitočtu 50MHz. Šváb je o trochu větší než ATtiny a kolem nepotřebuje vůbec žádný součástky. Výzva si zopáknout A51, s kterým jsem dělal už před 30 lety. :)
Jirka

Proč mi nemůže všechno chodit hned ?!!
Uživatelský avatar
Atlan
Příspěvky: 4514
Registrován: 10 kvě 2004, 00:00
Bydliště: Košice

#32 Příspěvek od Atlan »

No ked to pise pod arduinom tak sa necudujem ze sa to cuka. Tam totiz uP robi veci o ktorych uzivatel nevie.

Ch32v003 stoji centy a maclkom potencial. https://pallavaggarwal.in/2023/09/23/ch ... utput/amp/
Uživatelský avatar
samec
Příspěvky: 6670
Registrován: 19 pro 2017, 00:00

#33 Příspěvek od samec »

ATtiny85 má až 64MHz counter, ale za 2 dni intenzívneho hľadania sa mi nepodarilo nájsť kompletne prehľadnú dokumentáciu ku všetkým režimom. Takže stále netuším, či okrem generovania rýchleho PWM dokáže aj presné meranie krátkych časov. Možno externým hradlovaním, ale to už je jednoduchšie použiť 555.
Uživatelský avatar
Dumitru
Příspěvky: 254
Registrován: 11 pro 2015, 00:00
Bydliště: Slovensko,Bratislava
Kontaktovat uživatele:

#34 Příspěvek od Dumitru »

Celeron píše:A jak chceš časovačem, kterej se plní periodou 1us něco přesně u takovýhleho signálu měřit?


Možno blba otázka ale mne nie je jasne prečo 1us(1Mhz) ? ak máš 8Mhz čo je 125ns, 125*256(8bit)=32000ns alebo 32us , počas 1us vieš napočítať do 8

Vidím že tam máš prerušenie treba tam v SW počítať s týmto , vbehnúť do prerušenia trvá dlhšie ako z neho vyjsť von

Kód: Vybrat vše

3.8.1 Interrupt Response Time
The interrupt execution response for all the enabled AVR® interrupts is four clock cycles minimum. After four clock cycles the
program vector address for the actual interrupt handling routine is executed. During this four clock cycle period, the program
counter is pushed onto the stack. The vector is normally a jump to the interrupt routine, and this jump takes three clock
cycles. If an interrupt occurs during execution of a multi-cycle instruction, this instruction is completed before the interrupt is
served. If an interrupt occurs when the MCU is in sleep mode, the interrupt execution response time is increased by four
clock cycles. This increase comes in addition to the start-up time from the selected sleep mode.
A return from an interrupt handling routine takes four clock cycles. During these four clock cycles, the program counter (two
bytes) is popped back from the stack, the stack pointer is incremented by two, and the I-bit in SREG is set.



Píšeš že tam maš 8Mhz kryštál predpokladám že externý a nefunguješ od interných hodín inak je to potrebne kalibrovať , mne bez kalibrácie ani UART na 9600baud nefungoval .

No a nakoniec z datasheetu prvá strana Attiny môže ísť až do 20Mhz.
Uživatelský avatar
Celeron
Příspěvky: 20508
Registrován: 02 dub 2011, 00:00
Bydliště: Nový Bydžov

#35 Příspěvek od Celeron »

Atlan píše:No ked to pise pod arduinom tak sa necudujem ze sa to cuka. Tam totiz uP robi veci o ktorych uzivatel nevie.

Od kdy je ATtiny85 Arduino? Procesor bez ničeho kolem, poslední verze v asembleru a stejně cuká.
Jirka

Proč mi nemůže všechno chodit hned ?!!
Uživatelský avatar
Celeron
Příspěvky: 20508
Registrován: 02 dub 2011, 00:00
Bydliště: Nový Bydžov

#36 Příspěvek od Celeron »

Dumitru píše:Možno blba otázka ale mne nie je jasne prečo 1us(1Mhz) ? ak máš 8Mhz čo je 125ns, 125*256(8bit)=32000ns alebo 32us , počas 1us vieš napočítať do 8

Ano, můžeš nastavit TCCRB na xxxxx001, tedy vstup přímo CLKi/o (No prescaling) od hodin 8MHz ale pak s 8 bitama TC0 napočítáš jen jak píšeš do 32us. Jenže měřený signál může mít až 2,2ms. Tak si spočítej, kolikrát bys musel nechat TC0 vygenerovat přerušení od přetečení TC0 a přičíst 1 v registru, kterej by nahrazoval vyšších 8 bitů pro pseudočasovač 16 bitů. Skoro 70 krát. Jak se časově zpracovává přerušení jsi tu popsal. S jakou přesností by to asi měřilo? Prostě na ATtiny85 s časovačema 8 bitů to nejde s dostatečnou přesností a stabilitou realizovat.
Jirka

Proč mi nemůže všechno chodit hned ?!!
Uživatelský avatar
samec
Příspěvky: 6670
Registrován: 19 pro 2017, 00:00

#37 Příspěvek od samec »

ATtiny85 má dva 8-bitové časovače. Ak jednému nastavíš prescaler na /1 a druhému na /256, tak máš v podstate jeden 16-bitový časovač.
Uživatelský avatar
Celeron
Příspěvky: 20508
Registrován: 02 dub 2011, 00:00
Bydliště: Nový Bydžov

#38 Příspěvek od Celeron »

Jako myslíš je zřetězit za sebou? To by ale ten druhej musel být čítač a né časovač. A je tam ten samej problém, při měření 2,2ms bude přerušení od přetečení potřeba kolikrát? Vzhledem k "náhodnýmu" počtu cyklů při zpracování přerušení to bude přesný jak přesýpací hodiny.
Jirka

Proč mi nemůže všechno chodit hned ?!!
Uživatelský avatar
Ruprecht
Příspěvky: 1494
Registrován: 28 zář 2005, 00:00
Bydliště: ZČ + JM

#39 Příspěvek od Ruprecht »

Ne, prostě oba časovače spustíš s náběžnou hranou a při skončení pulsu oba zastavíš a přečteš stavy obou čítačů jako 16-bit údaj, MSB a LSB.
Když promluví, tak buď kňučí, nebo lže.
Uživatelský avatar
Celeron
Příspěvky: 20508
Registrován: 02 dub 2011, 00:00
Bydliště: Nový Bydžov

#40 Příspěvek od Celeron »

Hmm, tak to mě nikdy nenapadlo. Díky za tip, vyzkouším.
Jirka

Proč mi nemůže všechno chodit hned ?!!
Uživatelský avatar
Celeron
Příspěvky: 20508
Registrován: 02 dub 2011, 00:00
Bydliště: Nový Bydžov

#41 Příspěvek od Celeron »

Tak jsme s kámošem zjistili, že přes ATtiny 85 dělat reverz serva je cesta do pekel. Prostě jak do toho vstoupí měření vstupního signálu časovačem, tak je výstupní reverz signál nestabilní. A je úplně vuřt, jestli se používá na měření funkce micros, nebo přímý vyčítání hodnoty z časovače. A největší neklid má ta zde doporučovaná verze udělat ze dvou 8 bitů jeden 16 bitů za pomocí prescaleru 256 u jednoho z nich.
Ten procák prostě není na měření kolem 1us dost rychlej a nepřítomnost 16 bit časovače to ještě umocňuje.
Zkusil jsem napsat test časovače aby se na portu změnila hodnota při každým přetečení časovače a k tomu jsem dával prescalery, co Tiny 85 nabízí.
A už tady byl problém, ten signál na PB1 se náhodně chvěl o cca ± 2us. Takže je vidět, že tudy cesta nevede kvůli nepředvídatelnýmu chování časovačů při intervenci. Jestli si někdo myslíte, že víte kde je problém, tak sem s tím, budu docela vděčný.

Kód: Vybrat vše


// Přerušení při přetečení časovače
ISR(TIMER1_OVF_vect) {
  // Přepnout stav na výstupním pinu
  PORTB ^= (1 << PB1);
}
//-------------------------
void setup() {
  // Nastavit PB1 jako výstup
  DDRB |= (1 << PB1);

  // Inicializace časovače1
  TCCR1 = 0; // Zastavit časovač
  TCNT1 = 0; // Vynulovat časovač

  // Nastavit prescaler na 1,2,4,8,16,32,64,128,256,512,1024...)
  TCCR1 |= (1 << CS13); // CS13 na 1 pro prescaler 128

  // Povolit přerušení při přetečení časovače
  TIMSK |= (1 << TOIE1);

  // Globálně povolit přerušení
  sei();
}
//-----------------------
void loop() {
}
Jirka

Proč mi nemůže všechno chodit hned ?!!
Uživatelský avatar
samec
Příspěvky: 6670
Registrován: 19 pro 2017, 00:00

#42 Příspěvek od samec »

Watchdog máš vypnutý?
Uživatelský avatar
Celeron
Příspěvky: 20508
Registrován: 02 dub 2011, 00:00
Bydliště: Nový Bydžov

#43 Příspěvek od Celeron »

Ten je snad po Resetu vypnutý. Vím, že se dá zapnout v Bootloaderu, ale ten nepoužívám, peču přes ISP. Taky jse zapnout ve Fuses, ale tam taky není povolený. Zkusil jsem ho pro sichr vypnout programově. Ale ten neklid cca 4us tam je stále. Zkusím ten test přetečení časovače napsat na Mega328P.

Kód: Vybrat vše

ISR(TIMER1_OVF_vect) {
  PORTB ^= (1 << PB1);
}

void setup() {
  DDRB |= (1 << PB1);
  // Zapsat do WDTCR registru pro povolení změny
  WDTCR |= (1 << WDCE) | (1 << WDE);
  // Vypnout WDT
  WDTCR = 0x00;
  TCCR1 = 0;
  TCNT1 = 0;
  TCCR1 |= (1 << CS13); // CS13 na 1 pro prescaler 128
  TIMSK |= (1 << TOIE1);
  sei();
}

void loop() {
}
Jirka

Proč mi nemůže všechno chodit hned ?!!
Uživatelský avatar
Celeron
Příspěvky: 20508
Registrován: 02 dub 2011, 00:00
Bydliště: Nový Bydžov

#44 Příspěvek od Celeron »

Převedl jsem to na Mega328P na časovač 8 bitů Timer 2. Výsledek je, že na osciloskopu HP1741 nepatrnej neklid je taky ale pod 0,1us, líp to změřit nejde. Na BM520 čítači, rozsah 0,1us na výstupním portu hodnota kolísá mezi 2049,2 až 2049,3. To je proti stejnýmu code na Tiny85 nebetyčnej rozdíl.

Kód: Vybrat vše

// Přerušení při přetečení časovače 2
ISR(TIMER2_OVF_vect) {
  // Přepnout stav na výstupním pinu
  PORTB ^= (1 << PB1);
}
void setup() {
  // Deaktivovat watchdog timer
  WDTCSR |= (1 << WDCE) | (1 << WDE);
  WDTCSR = 0x00;

  // Nastavit PB1 jako výstup (pin 9)
  DDRB |= (1 << PB1);

  // Inicializace časovače2
  TCCR2A = 0; // Normální režim
  TCCR2B = 0; // Zastavit časovač
  TCNT2 = 0;  // Vynulovat časovač

  // Nastavit prescaler na 64
  TCCR2B |= (1 << CS22); // CS22 na 1 pro prescaler 64

  // Povolit přerušení při přetečení časovače
  TIMSK2 |= (1 << TOIE2);

  // Globálně povolit přerušení
  sei();
}

void loop() {
}

Ještě zkusím Tiny85 převýst z interního oscilátoru na krystal. Ale musím s1 k programátoru USBASP udělat destičku s krystalem a kondíkama, protože jak bych jednou přepnul fuse na krystal, tak je procík bez krystalu nedobytnej. V nejhorším mám na Tiny85 HVresetátor, ten si s ním poradí.
Jirka

Proč mi nemůže všechno chodit hned ?!!
Uživatelský avatar
nostalcomp
Příspěvky: 169
Registrován: 09 lis 2022, 00:00

#45 Příspěvek od nostalcomp »

Celerone, já tomu nějak nerozumím. A jsem přesvědčen, že nejsem sám. Akorát většina to nepřizná. Asi z úcty k jednomu z největších tapetářů tohoto fóra. To prosím neber nijak zle a osobně, to je jen konstatování skutečnosti.

Takže:

Napíšeš, že máš hotovo (bez dalších podrobností) a přidáš fotku hotového reverzu, který údajně necuká. Fotka je pod textem o zapůjčeném továrním výrobku, což je přinejmenším matoucí. Jen o pár dní později už ale tvrdíš, že to s Attiny85 technicky nejde a vymejšlíš blbosti.

Píšeš cosi o verzi v assembleru, ale dáváš sem pořád zdrojáky v Céčku a ani neuvedeš čím to překládáš. Pokud to překládáš v Arduino IDE, tak nezapomeň, že překladač do kódu dodá aktivaci Timeru 0 a jeho obslužnou ISR kvůli funkcím millis a micros. Ty jsou pro servoreverz zbytečné a jen zdržují vykonávání programu. Pokud by se to psalo v opravdovém assembleru, tak si to tam člověk přece zbytečně nedá. A bůhví co ještě se tam automaticky přidává. On ten Arduino překladač vůbec umí "pěkný věci". Doporučuji přečíst třeba toto: Arduino poťouchlost – funkce map(). Proto taky nepoužívám funkci MAP a vždy si přepočty dělám "ručně". Mimochodem, autor toho textu se prý ozval tvůrcům Arduino překladače, upozornil je na chybu a navrhl opravu. Dostal odpověď ve smyslu toho, že se o chybě ví, ale nelze přepisovat definice funkcní kvůli zpětné kompatibilitě. Podobně je třeba dávat bacha na servoknihovnu a taky na řetězce. A kdoví, jaké další chyby a "ďáblové" se v překladech zdrojáků vyskytují.

Zpočátku pořád uvádíš, že timer je taktován impulsy s periodou 1uS a také píšeš, že strojový cyklus při 8MHz trvá 1uS. Ten timer už tu byl vyvrácen. S prescalerem nastaveným na 1 mají vstupní impulsy timeru periodu 125nS. A co se týká jádra CPU, tak i to lze 8x zrychlit nastavením registru CLKPR, resp. shozením pojistky CLKDIV8 (z výroby je nastavena!). Pak bude i strojní takt 125nS. To se pak člověk nediví, když lidi, než aby si prostudovali datasheet, raději rovnou sáhnou po výkonnějším procesoru.

Pokud se to napíše opravdu efektivně a budou se vybírat primárně 1-cyklové instrukce, tak to chodit prostě musí. Já bych se držel toho algoritmu s odečítáním vstupního servopulsu od 3ms. A je jedno, jestli budou servopulsy 1-2mS, nebo 0,8-2,2mS nebo 0,6-2,4mS. Pokud to bude symetrické kolem středu 1,5mS, vždy je stačí odečíst od 3mS. Na celý program pak stačí jedna jediná proměnná typu byte, která bude suplovat horní byte časovače. Žádný wordy nebo dokonce longy. V mezidobí bude vždy nastavena na 0 a v ISR timeru pak inkrementována a v hlavní smyčce testována. Timer bude vždy spouštěn na náběžku servopulsu a bude nastaven na automatický HW autoreload po 240 taktech (30uS). Je úplně jedno, jak dlouho trvá obsluha přerušení (pokud nebude větší než těch 30uS, což asi nehrozí). V okamžiku jeho obsluhy už si timer pojede dál svým životem. Testování náběžky a sestupky servopulsu a testování dočítání 3mS bych dělal v hlavní smyčce. Viz. průběhy v mém předešlém příspěvku. Nějaká chyba tam bude vždy. Ale určitě ne 2uS a bude víceméně konstantní a je tak možno ji korigovat úpravami hodnot reload a prom. Zkoušel jsem si to napsat na papír v jakémsi "esperantoassembleru" x51 a je to na pár bajtů. Do 2KB Attiny25 se to musí vejít 20x. Snažil jsem se vybírat instrukce, které mají AVR ekvivalent. Bohužel nemám žádný vhodný (=jednoduchý, ideálně pro DOS) AVR assembler, jako je TASM. Nevíte o něčem?

Kód: Vybrat vše

;"x51 esperantoassembler"
;jedno z mnoha moznych reseni
Start:
      clr servo_out
      di
      timer stop, CLKcpu = CLKosc/1
      nastavení timeru, prescaler /1, autoreload (256-240 = 16)
      timer Interrupt enable
init:
      prom = #0               ;nastaveni pom. promenne (MOV, LDI apod.)
      jnb servo_in, $         ;cekani na nabezku
      timer start           
      jb servo_in, $          ;cekani na sestupku
      setb servo_out          ;inverzni servopuls start
cyk:                          ;cekani na dokonceni casovani 3 mS
      mov a, prom             ;lze resit mnoha zpusoby (AVR stejne nema akumulator)
      cjne a, #100, ($+3)
      jc cyk                  ;prom < 100, opakuj
      clr servo_out           ;inverzni servopuls stop
      timer stop
      ;spousta casu na stourani se v uchu ci nose...
      jmp init                ;jdeme cekat na dalsi nabezku
           
ISR_tim:                      ;obsluha preruseni od timeru (ma autoreload)
     inc prom
     reti           


Ještě mě napadlo pro sichr dát na ten servovýstup 1nF keramiku proti GND, jako se to doporučuje u výstupu 555 při vazbě na logické obvody. Ale asi (určitě) je to úplně zbytečné.
Odpovědět

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