DC motor a dva mikrospínače

jirrka
Příspěvky: 12
Registrován: 01 bře 2019, 12:40
Reputation: 0

DC motor a dva mikrospínače

Příspěvek od jirrka » 01 bře 2019, 12:57

Dobrý den,

Předem bych rád podotknul, že Andruino se teprve učím a mám jen kusé informace.
Každopádně bych rád nějak začal a proto bych rád zprovoznil jednoduchý systém jednoho DC motoru a dvou mikrospínačů.

Mělo by to fungovat takto: při zapnutí se bude motor otáčet jedním směrem. Jakmile se zmáčkne ( nemyslím držet, jen krátce zmáčknout ) první spínač, motor pojede opačným směrem tak dlouho, dokud se nezmáčkne druhý spínač, který směr zase otočí.

Zkusil jsem něco vymyslet podle youtube, ale určitě to bude špatně.

Kód: Vybrat vše

// Pin 2 a 3 ovládají motor
// Pin 4 přední tlačítko
// Pin 5 zadní tlačítko
// Pin 9 rychlost motoru

int in1 = 2;
int in2 = 3;
int in3 = 4;
int in4 = 5;
int enA = 9;
boolean on = false;
int buttonState = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, INPUT);
  pinMode(in4, INPUT);
  pinMode(enA, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:

  //Výchozí hodnota předního tlačítka
  byte ButtonState = digitalRead(in3);

  //Výchozí hodnota zadního tlačítka
  byte ButtonState1 = digitalRead(in4);

  //Když není vysoká hodnota
  if (ButtonState == HIGH) {
    if (on == true) {
      on = false;
    } else {
      on = true;
    }
  }

  if (on == true) {

    // Motor dopředu
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    //Rychlost motoru ( possible range 0~255 )
    analogWrite(enA, 200);
  }

  else {

    // Opačný směr
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);

    //Rychlost motoru ( possible range 0~255 )
    analogWrite(enA, 200);
  }



  //Druhý spínač
  if (ButtonState1 == HIGH) {
    if (on == true) {
      on = false;
    } else {
      on = true;
    }
  }

  if (on == true) {

    // Motor dopředu
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    //Rychlost motoru ( possible range 0~255 )
    analogWrite(enA, 200);
  }

  else {

    // Opačný směr
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);

    //Rychlost motoru ( possible range 0~255 )
    analogWrite(enA, 200);
  }
  }
Poraďte mi prosím správný kód.

Za odpovědí předem děkuji
Jirka

jirrka
Příspěvky: 12
Registrován: 01 bře 2019, 12:40
Reputation: 0

Re: DC motor a dva mikrospínače

Příspěvek od jirrka » 01 bře 2019, 13:03

Zapoměl jsem dodat, že součástí bude Modul ovladače L298N

jankop
Příspěvky: 1029
Registrován: 06 zář 2017, 20:04
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

Re: DC motor a dva mikrospínače

Příspěvek od jankop » 01 bře 2019, 13:29

Podle tvého zadání jsou dvě tlačítka zbytečné. Stačí jedno. Po zapnutí se motor točí na definovanou stranu a každým stiskem tlačítka změníš směr.

jirrka
Příspěvky: 12
Registrován: 01 bře 2019, 12:40
Reputation: 0

Re: DC motor a dva mikrospínače

Příspěvek od jirrka » 01 bře 2019, 13:44

Dvě tlačítka tam mám cíleně. Bude ten kód fungovat?

jankop
Příspěvky: 1029
Registrován: 06 zář 2017, 20:04
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

Re: DC motor a dva mikrospínače

Příspěvek od jankop » 01 bře 2019, 14:17

Řekl bych, že fungovat nebude, protože tlačítka nejsou správně ošetřena.
1. Obvykle mám tlačítka aktivní v nule, ty to nijak nespecifikuješ, tak nevím
2. Řekl bych, že při stisku tlačítka ti začne motor bleskově přepínat sem a tam cca 100 000x za vteřinu
3. V rozporu se zadáním se mi jeví, že směr můžeš měnit opakovaným stiskem jednoho a téhož tlačítka.
Tvůj program je sice jednoduchý, ale přesto je docela nepřehledný
Tato sekvence

Kód: Vybrat vše

byte ButtonState1 = digitalRead(in4);
if (ButtonState1 == HIGH) {
    if (on == true) {
      on = false;
    } else {
      on = true;
    }
  }
se dá nahradit tímhle

Kód: Vybrat vše

if (digitalRead(in4) == HIGH) on=!on;

jirrka
Příspěvky: 12
Registrován: 01 bře 2019, 12:40
Reputation: 0

Re: DC motor a dva mikrospínače

Příspěvek od jirrka » 01 bře 2019, 14:30

Díky, vyzkouším a dám vědět.

jankop
Příspěvky: 1029
Registrován: 06 zář 2017, 20:04
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

Re: DC motor a dva mikrospínače

Příspěvek od jankop » 01 bře 2019, 16:18

Nezkoušej nic. Ten fragment není řešení, jen jsem ti chtěl ukázat, jak zpřehlednit program.
Odpověz:
1. Po zapnutí se má motor automaticky roztočit na definovanou stranu nebo se má roztočit až po prvním stisku tlačítka?
2. Jedno tlačítko má zapnout jeden konkrétní směr nebo má směr každým stiskem reverzovat, o což se pokoušíš v programu?
3. Co se má stát, když se stisknou obě tlačítka současně?
3. Jak máš zapojena tlačítka? Proti zemi, proti Vcc? Jakou hodnotu mají PullUp/PullDown rezistory v tvém zapojení?

jirrka
Příspěvky: 12
Registrován: 01 bře 2019, 12:40
Reputation: 0

Re: DC motor a dva mikrospínače

Příspěvek od jirrka » 01 bře 2019, 21:57

Díky za odpověď. Pokusím se odpovědět.

1. Bylo by lepší, kdyby se motor roztočil až po zmáčknutí tlačítka.

2. Každé tlačítko by mělo svůj směr.

3. Nad tím jsem neuvažoval, ale pokud by se motor zastavil, tak by to byla úžasné.

4. Proti VCC. Mám v plánu připojit 330ohm rezistory.

jankop
Příspěvky: 1029
Registrován: 06 zář 2017, 20:04
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

Re: DC motor a dva mikrospínače

Příspěvek od jankop » 01 bře 2019, 22:15

Tenhle kód by měl fungovat.
1. Po restartu motor stojí, teprve stiskem jednoho z tlačítek se rozběhne na jednu nebo druhou stranu
2. Tlačítka jsou zapojena proti zemi, tedy při stisku je detekována úroveň 0 respektive false.
Obojí lze pochopitelně snadno změnit.
Nezbytnou knihovnu Interval si musíš nainstalovat do Arduino IDE, přikládám ji sem ve formě zip.
Interval-master.zip
(5.27 KiB) Staženo 136 x
Tato koncepce programu má tu výhodu, že není použita žádná funkce delay(), která by zbytečně blokovala procesor. Ten udělá jen to, co je nezbytné a pak lelkuje. Snažil jsem se prezentovat i efektivní využití paměti. Z toho plyne, že když hodlám program následně rozšiřovat a dělám to dobře, tak nemusím mít problém ani s operační pamětí a ani s výkonem. Všechny funkce "Serial" je možné zakomentovat, protože mi sloužily pouze pro odzkoušení programu. I direktivy #define dokáží ušetřit paměť a naprosto zadarmo zpřehlednit program a umožňují snadnou a přehlednou změnu parametrů. Jak vidno, celý program je vlastně jen snaha o poctivé ošetření tlačítek, jinak nic. Asi nejtěžší na programování je psaní komentářů k nim :D

Kód: Vybrat vše

#include <interval.h>
#define MOTOR1       2  // L298N
#define MOTOR2       3  // L298N
#define BUTTONP      4  // tlacitko predni - spinac proti zemi !!!!!!!!!
#define BUTTONZ      5  // tlacitko zadni  - spinac proti zemi !!!!!!!!!
#define MOTORPWM     9  // pin rizeni vykonu motoru
#define POWER      200  // vykon/otacky motoru
#define BUTTONTIMER 50  // interval cteni tlacitek [ms]
//****************** Globalni promenne *******************************************
//bool MOTOR1State = false; 
//bool Motor2State = false; 
bool ButtonP = true;      // tlacitko P - zapojeno proti zemi, stisknuto = false
bool ButtonZ = true;      // tlacitko Z - zapojeno proti zemi, stisknuto = false
bool ReleaseP = false;    // priznak uvolneni tlacitka P, uvolneno = true
bool ReleaseZ = false;    // priznak uvolneni tlacitka Z, uvolneno = true
uint8_t ButtonPCount = 0; // citac doby stisku tlacitka P
uint8_t ButtonZCount = 0; // citac doby stisku tlacitka Z
//********************************************************************************
Interval ButtonsInterval;
void setup() {
  /* nastaveni vstupu/vystupu */
  Serial.begin(9600);
  pinMode(MOTOR1, OUTPUT);
  pinMode(MOTOR2, OUTPUT);
  pinMode(BUTTONP, INPUT_PULLUP);
  pinMode(BUTTONZ, INPUT_PULLUP);
  pinMode(MOTORPWM, OUTPUT);
  analogWrite(MOTORPWM, POWER);
}
void loop() {
  if (ButtonsInterval.expired()) {
    ButtonsInterval.set(BUTTONTIMER);
    /* pokud je tlacitkoP drzeno vice jak dva casove intervaly
       BUTTONTIMER, pak se přepne motor do pozadovaneho smeru. */
    if (!digitalRead(BUTTONP) && ReleaseP) {
      ButtonPCount++;     // citani doby stisku tlacitka1
      if (ButtonPCount > 1) {
        // Motor dopředu
        Serial.println("Motor dopredu");
        digitalWrite(MOTOR1, HIGH);
        digitalWrite(MOTOR2, LOW);
        ButtonPCount = 0; // nuluj  citac doby stisku tlacitkaP
        ReleaseP = false; // nuluj priznak uvolneni tlacitkaP
      }
    }
    /* ceka na uvolneni tlacitkaP vice jak po dobu tri period BUTTONTIMER */
    if (digitalRead(BUTTONP)&& !ReleaseP) {
      ButtonPCount++;    // citani doby uvolneni tlacitkaP
      if (ButtonPCount > 2) {
        Serial.println("Uvolneno tlacitko dopredu");
        ButtonPCount = 0;// nuluj  citac doby uvolneni tlacitkaP
        ReleaseP = true; // nastav priznak uvolneni tlacitkaP
      }
    }
    /* pokud je tlacitkoZ drzeno vice jak dva casove intervaly
       BUTTONTIMER, pak se přepne motor do pozadovaneho smeru. */
    if (!digitalRead(BUTTONZ) && ReleaseZ) {
      ButtonZCount++;     // citani doby stisku tlacitkaZ
      if (ButtonZCount > 1) {
        // Motor dozadu
        Serial.println("Motor dozadu");
        digitalWrite(MOTOR1, LOW);
        digitalWrite(MOTOR2, HIGH);
        ButtonZCount = 0; // nuluj  citac doby stisku tlacitkaZ
        ReleaseZ = false; // nastav priznak uvolneni tlacitkaZ
      }
    }
    /* ceka na uvolneni tlacitkaZ vice jak po dobu tri period BUTTONTIMER */
    if (digitalRead(BUTTONZ)&& !ReleaseZ) {
      ButtonZCount++;    // citani doby uvolneni tlacitkaZ
      if (ButtonZCount > 2) {
        Serial.println("Uvolneno tlacitko dozadu");
        ButtonZCount = 0;// nuluj  citac doby uvolneni tlacitkaZ
        ReleaseZ = true; // nastav priznak uvolneni tlacitkaZ
      }
    }
  }
}
Tenhle kód by měl fungovat s tlačítky na Vcc.

Kód: Vybrat vše

#include <interval.h>
#define MOTOR1       2  // L298N
#define MOTOR2       3  // L298N
#define BUTTONP      4  // tlacitko predni - spinac proti Vcc !!!!!!!!!
#define BUTTONZ      5  // tlacitko zadni  - spinac proti Vcc !!!!!!!!!
#define MOTORPWM     9  // pin rizeni vykonu motoru
#define POWER      200  // vykon/otacky motoru
#define BUTTONTIMER 50  // interval cteni tlacitek [ms]
//****************** Globalni promenne *******************************************
//bool MOTOR1State = false; 
//bool Motor2State = false; 
bool ButtonP = false;     // tlacitko P - zapojeno proti Vcc, stisknuto = true
bool ButtonZ = false;     // tlacitko Z - zapojeno proti Vcc, stisknuto = true
bool ReleaseP = false;    // priznak uvolneni tlacitka P, uvolneno = true
bool ReleaseZ = false;    // priznak uvolneni tlacitka Z, uvolneno = true
uint8_t ButtonPCount = 0; // citac doby stisku tlacitka P
uint8_t ButtonZCount = 0; // citac doby stisku tlacitka Z
//********************************************************************************
Interval ButtonsInterval;
void setup() {
  /* nastaveni vstupu/vystupu */
  Serial.begin(9600);
  pinMode(MOTOR1, OUTPUT);
  pinMode(MOTOR2, OUTPUT);
  pinMode(BUTTONP, INPUT);
  pinMode(BUTTONZ, INPUT);
  pinMode(MOTORPWM, OUTPUT);
  analogWrite(MOTORPWM, POWER);
}
void loop() {
  if (ButtonsInterval.expired()) {
    ButtonsInterval.set(BUTTONTIMER);
    /* pokud je tlacitkoP drzeno vice jak dva casove intervaly
       BUTTONTIMER, pak se přepne motor do pozadovaneho smeru. */
    if (digitalRead(BUTTONP) && ReleaseP) {
      ButtonPCount++;     // citani doby stisku tlacitka1
      if (ButtonPCount > 1) {
        // Motor dopředu
        Serial.println("Motor dopredu");
        digitalWrite(MOTOR1, HIGH);
        digitalWrite(MOTOR2, LOW);
        ButtonPCount = 0; // nuluj  citac doby stisku tlacitkaP
        ReleaseP = false; // nuluj priznak uvolneni tlacitkaP
      }
    }
    /* ceka na uvolneni tlacitkaP vice jak po dobu tri period BUTTONTIMER */
    if (!digitalRead(BUTTONP)&& !ReleaseP) {
      ButtonPCount++;    // citani doby uvolneni tlacitkaP
      if (ButtonPCount > 2) {
        Serial.println("Uvolneno tlacitko dopredu");
        ButtonPCount = 0;// nuluj  citac doby uvolneni tlacitkaP
        ReleaseP = true; // nastav priznak uvolneni tlacitkaP
      }
    }
    /* pokud je tlacitkoZ drzeno vice jak dva casove intervaly
       BUTTONTIMER, pak se přepne motor do pozadovaneho smeru. */
    if (digitalRead(BUTTONZ) && ReleaseZ) {
      ButtonZCount++;     // citani doby stisku tlacitkaZ
      if (ButtonZCount > 1) {
        // Motor dozadu
        Serial.println("Motor dozadu");
        digitalWrite(MOTOR1, LOW);
        digitalWrite(MOTOR2, HIGH);
        ButtonZCount = 0; // nuluj  citac doby stisku tlacitkaZ
        ReleaseZ = false; // nastav priznak uvolneni tlacitkaZ
      }
    }
    /* ceka na uvolneni tlacitkaZ vice jak po dobu tri period BUTTONTIMER */
    if (!digitalRead(BUTTONZ)&& !ReleaseZ) {
      ButtonZCount++;    // citani doby uvolneni tlacitkaZ
      if (ButtonZCount > 2) {
        Serial.println("Uvolneno tlacitko dozadu");
        ButtonZCount = 0;// nuluj  citac doby uvolneni tlacitkaZ
        ReleaseZ = true; // nastav priznak uvolneni tlacitkaZ
      }
    }
  }
}

jankop
Příspěvky: 1029
Registrován: 06 zář 2017, 20:04
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

Re: DC motor a dva mikrospínače

Příspěvek od jankop » 02 bře 2019, 12:49

Tady jsem doplnil STOP.

1. Po zapnutí motor stojí
2. Roztočí se až stiskem patřičného tlačítka
3. Opakovaným stiskem jednoho tlačítka se zachová stávající směr otáčení
4. Stiskem obou tlačítek současně se motor zastaví

Kód: Vybrat vše

#include <interval.h>
#define MOTOR1       2  // L298N
#define MOTOR2       3  // L298N
#define BUTTONP      4  // tlacitko predni - spinac proti Vcc !!!!!!!!!
#define BUTTONZ      5  // tlacitko zadni  - spinac proti Vcc !!!!!!!!!
#define MOTORPWM     9  // pin rizeni vykonu motoru
#define POWER      200  // vykon/otacky motoru
#define BUTTONTIMER 50  // interval cteni tlacitek [ms]
//****************** Globalni promenne *******************************************
bool ReleaseP = false;   // priznak uvolneni tlacitka P, uvolneno = true
bool ReleaseZ = false;   // priznak uvolneni tlacitka Z, uvolneno = true
bool ReleaseD = false;   // priznak uvolneni obou tlacitek, uvolneno = true
uint8_t ButtonPCount = 0; // citac doby stisku tlacitka P
uint8_t ButtonZCount = 0; // citac doby stisku tlacitka Z
uint8_t ButtonDCount = 0; // citac doby stisku tlacitka Z
//********************************************************************************
Interval ButtonsInterval;
void setup() {
  /* nastaveni vstupu/vystupu */
  Serial.begin(9600);
  pinMode(MOTOR1, OUTPUT);
  pinMode(MOTOR2, OUTPUT);
  pinMode(BUTTONP, INPUT);
  pinMode(BUTTONZ, INPUT);
  pinMode(MOTORPWM, OUTPUT);
  analogWrite(MOTORPWM, POWER);
}
void loop() {
  if (ButtonsInterval.expired()) {
    ButtonsInterval.set(BUTTONTIMER);
    /* pokud jsou obe tlacitka drzena vice jak dva casove intervaly
       BUTTONTIMER, pak se motor zastavi. */
    if (digitalRead(BUTTONP) && digitalRead(BUTTONZ) && ReleaseD) {
      ButtonDCount++;     // citani doby stisku obou tlacitek
      if (ButtonDCount > 1) {
        Serial.println("Motor stop");
        digitalWrite(MOTOR1, LOW);
        digitalWrite(MOTOR2, LOW);
        ButtonDCount = 0; // nuluj  citac doby stisku obou tlacitek
        ReleaseD = false; // nuluj priznak uvolneni obou tlacitek
      }
    }
    /* ceka na uvolneni tlacitek vice jak po dobu tri period BUTTONTIMER */
    if (!digitalRead(BUTTONP) && !digitalRead(BUTTONZ) && !ReleaseD) {
      ButtonDCount++;    // citani doby uvolneni tlacitkaP
      if (ButtonDCount > 2) {
        Serial.println("Uvolnena obe tlacitka");
        ButtonDCount = 0;// nuluj  citac doby uvolneni obou tlacitek
        ReleaseD = true; // nastav priznak uvolneni obou tlacitek
      }
    }
    /* pokud je tlacitkoP drzeno vice jak dva casove intervaly
       BUTTONTIMER, pak se přepne motor do pozadovaneho smeru. */
    if (digitalRead(BUTTONP) && ReleaseP && ReleaseD) {
      ButtonPCount++;     // citani doby stisku tlacitka1
      if (ButtonPCount > 1) {
        Serial.println("Motor dopredu");
        digitalWrite(MOTOR1, HIGH);
        digitalWrite(MOTOR2, LOW);
        ButtonPCount = 0; // nuluj  citac doby stisku tlacitkaP
        ReleaseP = false; // nuluj priznak uvolneni tlacitkaP
      }
    }
    /* ceka na uvolneni tlacitkaP vice jak po dobu tri period BUTTONTIMER */
    if (!digitalRead(BUTTONP) && !ReleaseP && ReleaseD) {
      ButtonPCount++;    // citani doby uvolneni tlacitkaP
      if (ButtonPCount > 2) {
        Serial.println("Uvolneno tlacitko dopredu");
        ButtonPCount = 0;// nuluj  citac doby uvolneni tlacitkaP
        ReleaseP = true; // nastav priznak uvolneni tlacitkaP
      }
    }
    /* pokud je tlacitkoZ drzeno vice jak dva casove intervaly
       BUTTONTIMER, pak se přepne motor do pozadovaneho smeru. */
    if (digitalRead(BUTTONZ) && ReleaseZ && ReleaseD) {
      ButtonZCount++;     // citani doby stisku tlacitkaZ
      if (ButtonZCount > 1) {
        Serial.println("Motor dozadu");
        digitalWrite(MOTOR1, LOW);
        digitalWrite(MOTOR2, HIGH);
        ButtonZCount = 0; // nuluj  citac doby stisku tlacitkaZ
        ReleaseZ = false; // nastav priznak uvolneni tlacitkaZ
      }
    }
    /* ceka na uvolneni tlacitkaZ vice jak po dobu tri period BUTTONTIMER */
    if (!digitalRead(BUTTONZ) && !ReleaseZ && ReleaseD) {
      ButtonZCount++;    // citani doby uvolneni tlacitkaZ
      if (ButtonZCount > 2) {
        Serial.println("Uvolneno tlacitko dozadu");
        ButtonZCount = 0;// nuluj  citac doby uvolneni tlacitkaZ
        ReleaseZ = true; // nastav priznak uvolneni tlacitkaZ
      }
    }
  }
}

Odpovědět

Kdo je online

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