Mini CNC osa Z

Odpovědět
Uživatelský avatar
kiRRow
Příspěvky: 1151
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Mini CNC osa Z

Příspěvek od kiRRow » 16 srp 2019, 16:10

Točí se ti dvounásobně delší čas, protože v jednom cyklu while obsluhuješ to servo 2x.

Kód: Vybrat vše

      /*TADY SE KONTROLUJE KRAJNÍ POZICE MOTORU*/
      if (pos <= 0) {     // zkontroluji si jestli je pozice 0 nebo méně
           step = 1;        // nastavím step na 1 (TOHLE JE ZMĚNA SMĚRU)
      }
      if (pos >= 180) {    // zkontroluji si jestli je pozice 180 nebo více
           step = -1;        // nastavím step na -1 (TOHLE JE ZMĚNA SMĚRU)
      }
      /*TADY KONČÍ KONTROLA POZICE*/
      
      /*TADY SE OBSLUHUJE SERVO*/
      pos += step;       // k pozici motoru přičtu step (TA JE BUĎ 1 A POS SE ZVYŠUJE, NEBO -1 A POS SE SNIŽUJE)
      myservo.write(pos);     // nastavení serva na pozici
      delay(10);     // nějaký ten delay, aby se to stihlo natočit
      /*KONEC OBSLUHY SERVA*/
https://cs.wikipedia.org/wiki/Styl_z%C3%A1pisu_programu

Hanz
Příspěvky: 262
Registrován: 25 dub 2019, 23:52
Reputation: 0

Re: Mini CNC osa Z

Příspěvek od Hanz » 19 srp 2019, 15:46

v rámci učení jsem přidal Led1,Led2 pro krajní polohy serva + Led pro signalizaci vrtění serva. Nad tím jak servo rozchodit, aby se mi netočilo hned po nahrání do Arduina nebo přivedení napájení se pokouším. Nicméně nestojím ale koumám, děkuju za link "jak psát sketche".
tady je ten s přidanýma Led :

Kód: Vybrat vše

#include <Servo.h>                // zahrnutí knihovny pro ovládání servo motoru
Servo myservo;                // každý motor má svou instanci třídy Servo
int buttonPin = 3;                // číslo pinu tlačítka

int pos = 0;               // proměnná obsahující pozici motoru (úhel natočení)
int buttonState;                // nejnovější hodnota načtená ze vstupního pinu tlačítka
int lastButtonState = LOW;            // předchozí hodnota načtení ze vstupního pinu tlačítka
int reading;                // stav tlacitka
int step = 1;                // ukládá se do ní hodnotu jednoho kroku serva

int Led1 = 10;                // číslo pinu Led1
int Led2 = 11;                // číslo pinu Led2
int Led = 12;                // číslo pinu Led


                // Následné proměnné jsou typu long, jelikož čas měřený v milisekundách se
                //rychle změní na větší číslo, jež nemůže být uloženo v int
long lastDebounceTime = 0;                // čas posledního změny výstupního pinu
long debounceDelay = 50;                // čas debounce prodlevy
long buttonTime;                // čas začátku stisknutí tlačítka tj. začátek vrtění serva


void setup() {
  myservo.attach(9);                // servo je připojeno na pin 9
  pinMode(buttonPin, INPUT);                // nastavení tlačítka jako vstup
  myservo.write(pos);                // nastavení počátečního stavu serva
  
  pinMode(Led1, OUTPUT);                // nastavení Led1 jako výstup
  pinMode(Led2, OUTPUT);                // nastavení Led2 jako výstup
  pinMode(Led, OUTPUT);                // nastavení Led jako výstup
}

void loop() {
  /*TOHLE JE ZAČÁTEK BLOKU KDE OŠETŘUJI TLAČÍTKO*/
  reading = digitalRead(buttonPin);

  if (reading != lastButtonState) { // kmita to, od minule se to zmenilo, zacnu debounce cas pocitat znovu (tedy od posledni zmeny, ktera je ted)
    lastDebounceTime = millis();
  };

  lastButtonState = reading; // tady si to ulozim, v dalsim pruchodu loop() to zase porovnam s novym reading, zda se to mezi tim nezmenilo

  if ((millis() - lastDebounceTime) > debounceDelay) { // jo, uz se to dlouho nezmenilo, tak je to stabilni a spravna hodnota
    if (reading != buttonState) {  // Pokud se stav tlačítka změnil
      
      /*TADY SE ZAČÍNAJÍ DÍT VĚCI PŘI STISKNUTÍ/PUŠTĚNÍ TLAČÍTKA, NÁSLEDNĚ SE VYUŽIJÍ POZDĚJI V PROGRAMU*/
      buttonState = reading;   // zapamatuju si novy stav
    }
  }
  /*TOHLE JE KONEC BLOKU KDE OŠETŘUJI TLAČÍTKO*/

  /*TOHLE JE ZAČÁTEK BLOKU KDE NA ZÁKLADĚ DŘÍVE ZJIŠTĚNÝCH INFORMACÍ OBSLUHUJI SERVO*/
  // a tady (treba) budu neco delat

  if (buttonState == HIGH) {   // je stisknuto tlačítko??
    buttonTime = millis();     // příkazy, které si zapamatují čas, kdy bylo tlačítko stisknuto
  }

  /* podmínka = od toho času, kdy bylo tlačítko stisknuto, uběhlo méně než 30000ms ??
    (Pokud ano, udělej jeden cykl, pokud ne, ukonči cyklování a pokračuj dále v programu) */
   while (millis() - buttonTime <= 15000) {    // podmínka
        
 /*TADY SE KONTROLUJE KRAJNÍ POZICE MOTORU*/
      if (pos <= 0) {     // zkontroluji si jestli je pozice 0 nebo méně
           step = 1;        // nastavím step na 1 (TOHLE JE ZMĚNA SMĚRU
      }
      if (pos >= 180) {    // zkontroluji si jestli je pozice 180 nebo více
           step = -1;        // nastavím step na -1 (TOHLE JE ZMĚNA SMĚRU)
      }
      /*TADY KONČÍ KONTROLA POZICE*/
      
      /*TADY SE OBSLUHUJE SERVO*/
      pos += step;       // k pozici motoru přičtu step (TA JE BUĎ 1 A POS SE ZVYŠUJE, NEBO -1 A POS SE SNIŽUJE)
         digitalWrite(Led1,pos>=175);
         digitalWrite(Led2,pos<=5);
      myservo.write(pos);     // nastavení serva na pozici
           delay(10);     // nějaký ten delay, aby se to stihlo natočit
      /*KONEC OBSLUHY SERVA*/
   }
      /*TADY SE OBSLUHUJE LED - SIGNALIZACE VRTENI SERVA*/
      if (buttonTime <= 15000)  {
           digitalWrite(Led,HIGH);     // Led svítí servo stojí
      } 
      if (buttonTime = 15000)  {
           digitalWrite(Led,LOW);      // Led nesvítí servo se vrtí v nastaveném čase
      }  
  }
  
při chvilce přidám i video

Uživatelský avatar
kiRRow
Příspěvky: 1151
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Mini CNC osa Z

Příspěvek od kiRRow » 19 srp 2019, 17:06

oprav prvně zásadní chyby v špatně napsaném kódu ...
Ten středník za závorkou } nemá co dělat.

Kód: Vybrat vše

  if (reading != lastButtonState) { // kmita to, od minule se to zmenilo, zacnu debounce cas pocitat znovu (tedy od posledni zmeny, ktera je ted)
    lastDebounceTime = millis();
  };
místo = patří ==
znak "=" znamená "přiřaď" ... a = 10 znamená "do proměné a přiřaď hodnotu 10"
znak "==" znamená "rovná se" ... a == 10 znamená "proměná a rovná se 10"

Kód: Vybrat vše

      if (buttonTime = 15000)  {
           digitalWrite(Led,LOW);      // Led nesvítí servo se vrtí v nastaveném čase
      } 
Tipy pro zjednodušení kódu :
Jak je ten IF, kde se testuje poloha serva ... tam je i místo kde můžeš napsat rovnou příkaz pro rožnutí ledky signalizující jeden směr a zhasnutí té druhé. Hned pod ním je druhej IF testující druhou polohu serva a tam můžeš napsat zase rovnou příkaz pro ovládání LEDek, akorát zhasneš tu první a rožneš tu druhou. Příkaz který rožne LED která signalizuje běh serva můžeš zapsat hned rovnou za ten WHILE. Příkaz, který LEDku zase zhasne pak příjde za tu složenou závorku, která ten WHILE ukončuje.

K tomu vrtění se hned po startu ... zkus definovat buttonState
int buttonState = LOW; // nejnovější hodnota načtená ze vstupního pinu tlačítka
jo a používáš u tlačítka rezistor ? připoj 10Kohm odpor (klidně i vyžší ... s nižším opatrně, ale s klidem tam dej i 4k7) mezi pin arduina a GND ... pokud ho tam nemáš, tak ten PIN v podstatě visí ve vzduchu nikde nepřipojen a je velmi náchylný na rušení v podstatě čímkoliv ... i přiblížením ruky.

Hanz
Příspěvky: 262
Registrován: 25 dub 2019, 23:52
Reputation: 0

Re: Mini CNC osa Z

Příspěvek od Hanz » 20 srp 2019, 21:16

opravil jsem středník, a vyzkoušel zjednodušení kódu. Ledky u směru pohybu serva, ale svítily po celou dobu natáčení a to Led1 tam a Led2 zpět, já mám původně jen bliknutí v krajní poloze, nevím snad jsem to pochopil dobře, jak psal kiRRow. Další Led, která svítí když servo stojí po vložení za While a pak za závorku, jak bylo doporučeno, malinko problikne zhruba v půlce točení serva, nepatrně,ale problikne. Taky jsem zkusil u buttonState nadefinovat LOW bohužel, servo se po nahrání programu nebo resetu vrtí od začátku, nečeká na povel od tlačítka. Přesto děkuju, zkusil jsem si co se při změnách stane, píšu z tabletu, ale kódy mám uloženy. Předřadné odpory 330 Ohm mám u led diod a u tlačítka používám 10 kOhm odpor.

Uživatelský avatar
kiRRow
Příspěvky: 1151
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Mini CNC osa Z

Příspěvek od kiRRow » 21 srp 2019, 18:43

Tak to se omlouvám. Myslel jsem, že ledky mají signalizovat směr otáčení serva a mají svítit po celou dobu, jestli to dělají, tak to máš správně :) . Co se týče ledky co signalizuje běh serva, asi bude někde něco špatně napsáno.

Jinak už tuším, proč se servo spouští hned na začátku programu. Když se spustí program po prvé, tak millis() se teprve začíná napočítávat od nuly ... a když program poprvé doběhne k tomuhle "while (millis() - buttonTime <= 15000)", tak v hodnotě buttonTime je uložena nula. millis() ještě nepřesáhnul hodnotu 15000. Když se od toho odečte ta nula, tak to prostě splní tu podmínku a rozběhne se cyklus na ovládání serva. Docela jednoduchým řešením by mohlo být to, že by se ta testovací podmínka rozšířila o testování jestli millis() není menší než 15000. Pak to ale bude ignorovat stisk tlačítka prvních 15000 milisekund po spuštění programu.

Kód: Vybrat vše

while ((millis() - buttonTime <= 15000) && (millis() > 15000)) {

Hanz
Příspěvky: 262
Registrován: 25 dub 2019, 23:52
Reputation: 0

Re: Mini CNC osa Z

Příspěvek od Hanz » 21 srp 2019, 20:07

tady je slíbené video : https://www.youtube.com/watch?v=r5_vdO0zsXs
na videu jedno tlačítko není zapojeno, mám ho na jiné testy a zkoušení

Vyzkoušel jsem doměnku od kiRRow a je to tak. Při spuštění Arduina se nejdříve rožne Led , která signalizuje zastavení serva, a to se natočí do polohy 0, pak se po 15s rožne Led, která oznamuje krajní polohu 0 serva. Tlačítko na stisk reaguje, až po rozsvícení led v poloze 0 serva. Ale v prvních 15s, když ho stisknu, tak po uplynutí doby / těch 15s / se servo rozjede a vrtí se nastavený čas. Video by bylo asi názornější, doufám, že to píšu srozumitelně ? dík

Uživatelský avatar
gilhad
Příspěvky: 778
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Mini CNC osa Z

Příspěvek od gilhad » 21 srp 2019, 20:23

urcite jde buttonTime inicializovat na -15001 pretypovane na unsigned long (cili dostatecnou dobu pred "pretecenim" counteru) a tim efektivne predstirat, ze to Arduino pri startu uz bezelo dost dlouho (asi 57 dni), aby prave pretekl cas. Takze bude

Kód: Vybrat vše

millis() - buttonTime > 15000

Hanz
Příspěvky: 262
Registrován: 25 dub 2019, 23:52
Reputation: 0

Re: Mini CNC osa Z

Příspěvek od Hanz » 22 srp 2019, 19:31

děkuji gilhad za příspěvek,

Kód: Vybrat vše

while (millis() - buttonTime > 15000) {   // podmínka
ale pokud to mělo být takto, tak se servo ihned po nahrátí natočí do 0 polohy, počká 15s a začne se vrtět, tj. bez stisknutí tlačítka a vrtí se pořád, nebere v potaz nastavený čas.

Uživatelský avatar
gilhad
Příspěvky: 778
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Mini CNC osa Z

Příspěvek od gilhad » 22 srp 2019, 21:45

Pouze pokud by ten buttonTime byl na zacatku nula, pokud bude -15001, tak ten while neprobehne

Kód: Vybrat vše

unsigned long buttonTime=(unsigned long) -15001;

Uživatelský avatar
kiRRow
Příspěvky: 1151
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Mini CNC osa Z

Příspěvek od kiRRow » 23 srp 2019, 17:05

jen tak ze zvědavosti :) zkoušel už jsis hrát stím číslem u step v téhle části ?

Kód: Vybrat vše

      if (pos <= 0) {     // zkontroluji si jestli je pozice 0 nebo méně
           step = 1;        // nastavím step na 1 (TOHLE JE ZMĚNA SMĚRU)
      }
      if (pos >= 180) {    // zkontroluji si jestli je pozice 180 nebo více
           step = -1;        // nastavím step na -1 (TOHLE JE ZMĚNA SMĚRU)
      }
moc velký číslo bych tam nedával ... ale třeba s 2 a -2 se bude vrtět rychleji :)

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 14 hostů