Tema: Padekit pagaut bug'a (Arduino)
Autorius: ig
Data: 2015-06-05 14:36:49
Paprasta programele seka variklio encoderio outputa, skaiciuoja 
"zingsniukus" ir kai padaromas pilnas apsisukimas (624 zingsniai), 
keiciama sukimosi kryptis. Ir taip "mojuoja" pirmyn atgal.

Taciau karts nuo karto (mazdaug vienas is desimt ciklu), atsitiktinai
variklis apsisuka maziau nei pilna apsisukima ir pradeda keisti krypti.
pabandziau su serial.println isvedineti "c" reiksme kai keiciasi kryptis 
(t.y. if viduje - uzkomentuota eilute).

Nuostaba tame, kad sutrikimo atveju visada buna c=512 (t.y. grazus 
binarinis skaicius, ar nesusije su duomenu tipais, overflowais kokiais 
ir pan., nors keiciau c tipa int, unsigned int, jokio skirtumo - visada 
512. (624-512 = 92)
(Pakeitus vienos krypties zingsniu skaiciu i belekoki kita pvz 1001, 
klaidos atveju metama visada 768 reiksme. 1001 - 768 = 233)

Nuostaba numeris du, kad c=512 viduje if(c>623) salygos !!! T.y. kaip i 
ta "if" isvis patenkama, jei netenkinama salyga.  O ji netenkinama 
tikrai, nes klaidos atveju, butent tiek (~20%) ir nedasisukes iki pilno 
apsisukimo pradeda suktis atgal ir tada sukiojasi pirmyn atgal jau nuo 
naujos pozicijos. Vienintelis paaiskinimas, kad po salygos ispildymo 
staiga ivyksta 64911+512 interruptu, kad "c" owerflowinasi iki 
512(624+64911 = 65535). Nu galima daleisti kad enkoderis kazkoki noisa 
ismeta ir sudurniuoja interuptai/skaiciavimas, bet kodel visa laika 
vienodai... o ne randomu.

Zodziu biski konfuze. Gal kas turi minciu ?



volatile unsigned int c = 0;  // counter
volatile boolean dir = 1;     // direction

int fwdrevPin = 9;

void setup() {
   attachInterrupt(0, tacho, CHANGE);
   pinMode(fwdrevPin, OUTPUT);
}

void loop() {

if (c > 623){

    // Serial.println(c);

    dir = !dir;                  // Switch direction
    c = 0;                       // Reset counter
    if (dir==0) {
      analogWrite(fwdrevPin, 140);
   }
    else {
      int t = 128 - torque;
      analogWrite(fwdrevPin, 100);
    }
}



}

void tacho()
{
   c++;
}