Odeslat nové téma Odpovědět na téma  [ Příspěvků: 32 ]  Přejít na stránku 1, 2, 3  Další
Autor Zpráva
PříspěvekNapsal: úte 19.02.2019 8:02 
Moderátor serveru
Moderátor serveru
Uživatelský avatar

Registrován: 28.2.2005
Příspěvky: 20822
Bydliště: Rakovník, CZ
Obrázky: 0
V souvislosti se synkovo projektem RC tanku jsem se nechal vtáhnout do problematiky řízení některých funkcí tanku, dost času mi (jako samoukovi amatérovi) zabralo řízení krokového motoru pro (kontinuální) otáčení věže.
Po řadě víceméně (spíš méně) fungujících pokusů jsem konečně z jedné stránky o Arduinu plagiátorsky použil příklady ohledně interních časovačů, konkrétně se mi líbí tahle kalkulačka pro CTC režim časovačů.
Trocha mordování a výsledekem je konečně celkem uspokojivě fungující sketch pro řízení krokového motoru klasickým servosignálem:
Kód:
// impulzy pro step driver @ Arduino nano
// rizeni otaceni veze tanku RC impulzy PWM
// AVR Timer CTC Interrupts Calculator
// v. 8
// http://www.arduinoslovakia.eu/application/timer-calculator

namespace {
  #define pin_PWM 3 // vstup PWM @ pin
  #define pin 4 // vystup
  #define pin_smer 6 // pin DIR
  #define pin_krok 7 // pin STEP
  #define pin_en 8 // pin ENABLE
  #define pin_Vcc 9 // pin napajeni pro driver
  int hystereze = 30;
  int neutral_uS = 1500;
  int min_uS = 1000;
  int max_uS = 2000;
  int cislo;
  int timer;
  int min_cislo = 40;
  int max_cislo = 6000;
  int inp_uS = 1500;
  long int new_uS;
}     

void setupTimer1() {
  noInterrupts();
  // Clear registers
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  TIMSK1 = 0;  // Clear the interrupt mask
 
  // Hz (16000000/((OCR1A + 1) * 256))
  OCR1A = 1249;
  // CTC
  TCCR1B |= (1 << WGM12);
  // Prescaler 256
  TCCR1B |= (1 << CS12);
  // Output Compare Match A Interrupt Enable
  TIMSK1 |= (1 << OCIE1A);
  interrupts();
}


void setup() {
  pinMode(pin_krok, OUTPUT); // signál STEP
  pinMode(pin_smer, OUTPUT); // signál DIR
  pinMode(pin_PWM, INPUT_PULLUP);
  pinMode(pin_en, OUTPUT);
  pinMode(pin, OUTPUT);
  pinMode(pin_Vcc, OUTPUT);
  digitalWrite(pin_Vcc, LOW);
  // Serial.begin(115200);
  delay(500);
  attachInterrupt(1, puls_start, RISING);
  delay(500);
  setupTimer1();
  digitalWrite(pin_en, LOW);
  }

void loop(){
  set_timer(); 
  // tisk();
}

void puls_start() {
  new_uS = micros();
  attachInterrupt(1, puls_end, FALLING); 
  }

void puls_end() {
  new_uS = micros() - new_uS;
  attachInterrupt(1, puls_start, RISING);
  new_uS = min(new_uS, max_uS);
  new_uS = max(new_uS, min_uS);
  cislo = abs(new_uS - neutral_uS); 
  if (new_uS > neutral_uS){ // načtení směru
    digitalWrite(pin_smer, 1);
    }
  else {
    digitalWrite(pin_smer, 0);
    }
}

void set_timer() { 
  timer = 6000 - 12 * cislo;
  timer = min(timer, max_cislo);
  timer = max(timer, min_cislo);
}

ISR(TIMER1_COMPA_vect) {
  if (cislo > hystereze) {
    OCR1A = timer;
    digitalWrite(13, HIGH);
    digitalWrite(pin_krok, HIGH);
    delayMicroseconds(5);
    digitalWrite(pin_krok, LOW);
    }
    else {
    digitalWrite(13, LOW); 
    }
}

void tisk() {
  // Serial.print(inp_uS);
  // Serial.print("  ");
  Serial.println(timer);
}

Načítání délky PWM servoimpulzu jsem měl již dříve přes přerušení na vstupu, časovač přinesl inteligentnější časování kroků pro driver. Kolem je pár výpočtů, ty možná ještě doladím, týkají se hlavně omezení max. a min. rychlosti otáčení a přepočtu délky impulzu na čas mezi kroky; lineární převod není úplně to malinové, i když to funguje již uspokojivě. Zkusím asi nějakou např. expo funkci/vzoreček.

Co mi ještě včera hrabalo do slušného fungování bylo ošetření nekorektní délky PWM impulzu. Původně tam byla řádka
Kód:
  if (new_uS > min_uS and new_uS < max_uS) inp_uS = new_uS; // osetreni delky
a to nevím proč dost zlobilo; převod vynechával, nešlo přejít rychle z jedné polohy kniplu na jinou, muselo se pomalu.
Nahradil jsem to jinými funkcemi a najednou se to umoudřilo a funguje to jak má:
Kód:
  new_uS = min(new_uS, max_uS);
  new_uS = max(new_uS, min_uS);

_________________
jyrry.webnode.cz


Nahoru
 Profil  
 
 
PříspěvekNapsal: úte 19.02.2019 8:55 
Mazák
Mazák

Registrován: 7.5.2015
Příspěvky: 7414
Bydliště: ČR
Obrázky: 8
Už je to léta co jsem se podobným jazykům věnoval. Proto možná LAMA dotaz: "int inp_uS = 1500"
Je definice konstanty, nebo dosazení počáteční hodnoty proměnné, nebo zde je to jedno.
(Ty úseky ošetření mimo interval <1000, 2000> si ještě musím rozepsat "po svém".)
(KONSTANTY se obecně mohou vyskytovat jen na pravé straně dosazovacího příkazu "=" .)
Podivné chování programů (kdysi dávno) bylo spojeno s chybami převodu zdrojového kódu do následné
formy "JAZYKA" . Stávalo se (i když výjimečně), že za jistých okolností v převodu "překladač" udělal chybu(-y).


Nahoru
 Profil Soukromé album  
 
PříspěvekNapsal: úte 19.02.2019 10:22 
Mazák
Mazák
Uživatelský avatar

Registrován: 12.2.2016
Příspěvky: 1975
Bydliště: Vysočina, ČR
jyrry píše:
..Co mi ještě včera hrabalo do slušného fungování bylo ošetření nekorektní délky PWM impulzu. Původně tam byla řádka
Kód:
  if (new_uS > min_uS and new_uS < max_uS) inp_uS = new_uS; // osetreni delky
a to nevím proč dost zlobilo; převod vynechával..]
Taky nejsem profík a když něco dělám tak zjistím, že jsem polovinu věcí zapomněl ale tady bych vsadil na prioritu operátorů (platí závorkovat, závorkovat a závorkovat). Tak možná takhle:
if ((new_uS > min_uS) && (new_uS < max_uS)) inp_uS = new_uS;


Nahoru
 Profil  
 
PříspěvekNapsal: úte 19.02.2019 11:44 
Moderátor serveru
Moderátor serveru
Uživatelský avatar

Registrován: 28.2.2005
Příspěvky: 20822
Bydliště: Rakovník, CZ
Obrázky: 0
ellet píše:
... možná takhle:
if ((new_uS > min_uS) && (new_uS < max_uS)) inp_uS = new_uS;

Jo, to by asi šlo, dík. Já ty zdvojený a i jiný podivný operátory neumím... :oops:
Možná tam nechám to co tam mám - blbou hodnotu to nahradí mezní hodnotou; tohle nechá předchozí hodnotu... no, ještě to promyslím co bude vhodnější :-)

_________________
jyrry.webnode.cz


Nahoru
 Profil  
 
PříspěvekNapsal: úte 19.02.2019 11:45 
Moderátor serveru
Moderátor serveru
Uživatelský avatar

Registrován: 28.2.2005
Příspěvky: 20822
Bydliště: Rakovník, CZ
Obrázky: 0
guchar píše:
... "int inp_uS = 1500"
... dosazení počáteční hodnoty proměnné..
Myslím si že tohle.

Pro definici neměnných prvků by asi šlo použít tohle - https://www.arduino.cc/reference/en/lan ... ers/const/

Tedy v mém případě
Kód:
namespace {
  #define pin_PWM 3 // vstup PWM @ pin
  #define pin 4 // vystup
  #define pin_smer 6 // pin DIR
  #define pin_krok 7 // pin STEP
  #define pin_en 8 // pin ENABLE
  #define pin_Vcc 9 // pin napajeni pro driver
  const int hystereze = 30;
  const int neutral_uS = 1500;
  const int min_uS = 1000;
  const int max_uS = 2000;
  const int min_cislo = 40;
  const int max_cislo = 6000;
  int cislo;
  int timer;
  int inp_uS = 1500;
  long int new_uS;
}     


Ten pin 4 je tam na pokusy :-)

_________________
jyrry.webnode.cz


Nahoru
 Profil  
 
PříspěvekNapsal: úte 19.02.2019 12:22 
Mazák
Mazák
Uživatelský avatar

Registrován: 12.2.2016
Příspěvky: 1975
Bydliště: Vysočina, ČR
Prostě s const je to konstanta, bez const je to normální inicializovaná proměnná. (Konstantu lze i jinak.)


Nahoru
 Profil  
 
PříspěvekNapsal: úte 19.02.2019 15:00 
Mazák
Mazák

Registrován: 7.5.2015
Příspěvky: 7414
Bydliště: ČR
Obrázky: 8
@jyrry Že "Céčko" existuje ve více variantách jsem tušil. Že konkrétní JAZYK na Arduinu používaný
může být zcela specifický (tedy ne ČISTOKREVNÉ Cečko, jako třeba C++), ale "Wiring" jsem netušil.
POZNÁMKA: "Wiring je knihovna pro jazyk C++, která zjednodušuje programování Arduina."
Běžný uživatel Arduina většinou neví, jaká konstrukce pochází z C++ a jaká je specifická pro Wiring."
https://arduino.cz/forum/tema/jak-na-programovani-v-c/
Dotaz (další LAMA) k jyrry: Tvoje ukázky jsou podle (z) WIRING, nebo je to C, nebo je to C++ ?
MOŽNÁ SPÍŠ (pokud jsem to správně pochopi): Arduino nemusím programovat od "NULY", ale mohu užívat
cosi jako "LEGO KOSTKY", které si beru z "WIRING", a ty jsou napsané v C++ ?
==edit2 Trocha světla do "guláše": C++, Wiring, Java a IDE(Integrated Development Environment) Arduino
https://uart.cz/90/ide-a-programovani-arduina/


Nahoru
 Profil Soukromé album  
 
PříspěvekNapsal: úte 19.02.2019 18:46 
Moderátor serveru
Moderátor serveru
Uživatelský avatar

Registrován: 28.2.2005
Příspěvky: 20822
Bydliště: Rakovník, CZ
Obrázky: 0
guchar píše:
...
Dotaz (další LAMA) k jyrry: Tvoje ukázky jsou podle (z) WIRING, nebo je to C, nebo je to C++ ?
MOŽNÁ SPÍŠ (pokud jsem to správně pochopi): Arduino nemusím programovat od "NULY", ale mohu užívat
cosi jako "LEGO KOSTKY", které si beru z "WIRING", a ty jsou napsané v C++ ?
...

Tak to asi nevím na co se vlastně ptáš :-)
Prostě si pamatuju cosi z PICů (PIC-Basic), okoukávám jak co píší jiní a pokouším se to slepovat podle sebe. Někdy to pak začne dělat i to co chci :-D

_________________
jyrry.webnode.cz


Nahoru
 Profil  
 
PříspěvekNapsal: stř 20.02.2019 4:16 
Mazák
Mazák

Registrován: 7.5.2015
Příspěvky: 7414
Bydliště: ČR
Obrázky: 8
@jyrry Dík za odpověď. Pic Basic je jedna z dalších možných cest kterou jsem dosud neznal).
Zase existuje ve spoustě verzí možností. Jen tak pro info zkus mi dát odkaz na nějakou konkrétní tebou užívanou
www stránku(-y) s "PŘEKLADAČEM = Compiler" převádějí textový tvar na binární formu pro zápis do uP.
Jeden možný příklad
https://www.best-microcontroller-projects.com/pic-basic-gcbasic-ezine4.html
Diskuse mezi CESTAMI/variantami PICBasic a pravověrné (některé) "Céčko".
https://www.microchip.com/forums/m225236.aspx
-Výběr užívaných prostředků(mimo jiné)je svázán s uP kde bude výsledek používán. Nástroj může být jednoduchý
MELAB-X1 je vývojový kit pro mikropočítače Microchip (sice Code: LABX1A, Price: $199.95) ale umí
programovat a spouštět programy napsané v assembleru, C / C++ a PICBasic / PICBasic-Pro
http://www.jplabs.co.uk/cz/articles/melab-kit.html


Nahoru
 Profil Soukromé album  
 
PříspěvekNapsal: stř 20.02.2019 6:23 
Moderátor serveru
Moderátor serveru
Uživatelský avatar

Registrován: 28.2.2005
Příspěvky: 20822
Bydliště: Rakovník, CZ
Obrázky: 0
guchar píše:
... zkus mi dát odkaz ...

http://store.melabs.com/cat/PBP.html
A vývojový kit jsem si uhňácal na nepájivém poli :mrgreen:
Příloha:
20190220_062740.jpg
20190220_062740.jpg
[ 76.21 KiB | Zobrazeno 11577 krát ]


_________________
jyrry.webnode.cz


Nahoru
 Profil  
 
PříspěvekNapsal: stř 20.02.2019 7:55 
Mazák
Mazák
Uživatelský avatar

Registrován: 13.11.2008
Příspěvky: 9866
Bydliště: Benátecká Vrutice, ČR
guchar píše:
Diskuse mezi CESTAMI/variantami PICBasic a pravověrné (některé) "Céčko".

Jen tě trochu popíchnu. Pravověrní programují v assembleru. :mrgreen:


Nahoru
 Profil  
 
PříspěvekNapsal: stř 20.02.2019 9:35 
Mazák
Mazák

Registrován: 7.5.2015
Příspěvky: 7414
Bydliště: ČR
Obrázky: 8
@Lark Výpisy pořízené přes úroveň de-assembling jsem (v dobách pravěku) zakládal leda jako dokumentaci.
A vlastní pořízení binární formy (tedy hlavně flastry oprav) jsem jel z pultu přímo do RAM. Kde že sálové P jsou.
Chtělo to jen mít v hlavě tabulku příslušných příkazů. I když ta tabulka se mnohdy vešla na kartičku A5 :)


Nahoru
 Profil Soukromé album  
 
PříspěvekNapsal: stř 20.02.2019 10:02 
Mazák
Mazák
Uživatelský avatar

Registrován: 12.2.2016
Příspěvky: 1975
Bydliště: Vysočina, ČR
jyrry píše:
......
Zkusils ten chybový řádek jen ozávorkovat a nechat původní and? Možná...
A díky za Timer Calculator, dobrá pomůcka (teda snad dobrá :) )


Nahoru
 Profil  
 
PříspěvekNapsal: stř 20.02.2019 10:24 
Moderátor serveru
Moderátor serveru
Uživatelský avatar

Registrován: 28.2.2005
Příspěvky: 20822
Bydliště: Rakovník, CZ
Obrázky: 0
Vecer jsem ten timer zkusil aplikovat na "servo jako krokac" - servo se hybe jen pri vychylce kniplu z neutralu, rychlost podle velikosti vychylky.
Dal jsem si vypis nacitanych hodnot sirky impulzu na com, chvili to funguje OK, pak tam proskoci treba 10-20 blbosti a pak zase OK. Kdyz zrusim ten timer, maka to zase dobre :?
No, jeste v tom tapu...

_________________
jyrry.webnode.cz


Nahoru
 Profil  
 
PříspěvekNapsal: stř 20.02.2019 11:36 
Mazák
Mazák
Uživatelský avatar

Registrován: 12.2.2016
Příspěvky: 1975
Bydliště: Vysočina, ČR
Nechtělo se mně to pitvat ale nedalo mně to. Používáš různý přerušení (čtení a gnerování pulzů). Ta se ale nesmí potkat a nevidím tam žádný ošetření (možná blbě koukám). V případě požadavku na přerušení, když je zakázáno druhým přerušením (nemusí se psát, je to implicitní chování AVR) je nastaven flag příslušného přerušení a přerušení bude provedeno opožděně "až na něj dojde řada". Bylo by asi dobrý na konci přerušení ošetřit flag druhého přerušení (aby se vynechalo při konfliktu). Ale když to chodí bez přerušení, bude jednodušší to neřešit :).(A proměnné plněné v přerušení by měly být volatile.)


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ů: 32 ]  Přejít na stránku 1, 2, 3  Další

 


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 5 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

Hledat:
Přejít na:  

 

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

 

NAVRCHOLU.cz