ta pati kintamaji access'ini is dvieju skirtingu kontekstu - interrupt ir user. sutvarkyk lock'inima ir problemos neliks. On 2015.06.05 14:36, ig wrote: > 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++; > }