Код, из-за которого серводвигатель не работает!

Мой скетч компилируется и загружается, но при запуске программы серводвигатель не работает. Кнопки работают, светодиод работает, пьезо-зуммер играет мелодию, шаговый двигатель работает, но не стабильно. Серводвигатели/шаговые двигатели и светодиод работали до тех пор, пока я не ввел код для пьезозуммера для воспроизведения мелодии. Я новичок в программировании и хочу конструктивно учиться у других. Я надеюсь, что этот форум — место, где люди всех уровней знаний и опыта хотят протянуть руку помощи. Вот мой набросок:

#include <Stepper.h>
#include <Servo.h>

/*ARDUINO MOTOR SHIELD
 * The pin breakdown is as follows:
 * Function          Channel A   Channel B
 * Direction         Digital 12  Digital 13
 * Speed (PWM)       Digital 3   Digital 11
 * Brake             Digital 9   Digital 8
 * Current Sensing   Analog 0  Analog 1
 */

const int stepsPerRevolution = 200;  // 1,8 град. угол шага (200 шагов/360 град. об.)
const int dirChA = 12;     // присвоение имени "dirChA" пину 12
const int dirChB = 13;     // присвоение имени "dirChB" пину 13
const int pwmChA = 3;      // присвоение имени "pwmChA" пину 3
const int pwmChB = 11;     // присвоение имени "pwmChB" пину 11
const int brkChA = 9;      // присвоение имени "бркЧА" пину 9
const int brkChB = 8;      // присвоение имени "brkChB" пину 8

const int srvoMtr = 10;    // присвоение имени "srvoMtr" пину 10

const int pButton1 = 4;    // присвоение имени "pButton1" контакту 4
const int pButton2 = 5;    // присвоение имени "pButton2" контакту 5
const int pButton3 = 6;    // присвоение имени "pButton3" пину 6
const int pButton4 = 7;    // присвоение имени "pButton4" пину 7

const int ledLight = 2;    // присвоение имени "ledLight" пину 2

Stepper myStepper(stepsPerRevolution, dirChA, dirChB);  // инициализируем библиотеку шаговых двигателей на контактах 12 и amp; 13
Servo myServo;  // инициализируем библиотеку сервоприводов логическим именем myServo

int pButton1State = 0;     // переменная для чтения состояния pButton1 как LOW или HIGH
int pButton2State = 0;     // переменная для чтения состояния pButton2 как LOW или HIGH
int pButton3State = 0;     // переменная для чтения состояния pButton3 как LOW или HIGH
int pButton4State = 0;     // переменная для чтения состояния pButton4 как LOW или HIGH

int pButtonFlag = 0;     // переменная, когда кнопка 1 была нажата и отпущена

int myServoPos = 0;      // переменная для того, когда сервопривод достиг своей позиции
int myServoFlag = 0;     // переменная для сервопривода при нажатии любой из 4 кнопок

int tonePin = A3;        //переменная для зуммера

void midi() {
    tone(tonePin, 233, 203.992851562);
    delay(226.658723958);
    delay(4.82252604167);
    tone(tonePin, 184, 412.325976562);
    delay(458.139973958);
    delay(4.82252604167);
    tone(tonePin, 184, 99.8262890625);
    delay(110.918098958);
    delay(4.82252604167);
    tone(tonePin, 155, 99.8262890625);
    delay(110.918098958);
    delay(4.82252604167);
    tone(tonePin, 184, 203.992851562);
    delay(226.658723958);
    delay(4.82252604167);
    tone(tonePin, 184, 203.992851562);
    delay(226.658723958);
    delay(236.303776042);
    tone(tonePin, 184, 99.8262890625);
    delay(110.918098958);
    delay(4.82252604167);
    tone(tonePin, 155, 99.8262890625);
    delay(110.918098958);
    delay(4.82252604167);
    tone(tonePin, 184, 203.992851562);
    delay(226.658723958);
    delay(4.82252604167);
    tone(tonePin, 184, 203.992851562);
    delay(226.658723958);
    delay(236.303776042);
    tone(tonePin, 184, 203.992851562);
    delay(226.658723958);
    delay(236.303776042);
    tone(tonePin, 233, 555.555);
    delay(617.283333333);
    delay(77.1604166667);
    tone(tonePin, 233, 203.992851562);
    delay(226.658723958);
    delay(4.82252604167);
    tone(tonePin, 184, 412.325976562);
    delay(458.139973958);
    delay(4.82252604167);
    tone(tonePin, 184, 99.8262890625);
    delay(110.918098958);
    delay(4.82252604167);
    tone(tonePin, 155, 99.8262890625);
    delay(110.918098958);
    delay(4.82252604167);
    tone(tonePin, 184, 203.992851562);
    delay(226.658723958);
    delay(4.82252604167);
    tone(tonePin, 184, 203.992851562);
    delay(226.658723958);
    delay(236.303776042);
    tone(tonePin, 184, 99.8262890625);
    delay(110.918098958);
    delay(4.82252604167);
    tone(tonePin, 155, 99.8262890625);
    delay(110.918098958);
    delay(4.82252604167);
    tone(tonePin, 184, 203.992851562);
    delay(226.658723958);
    delay(4.82252604167);
    tone(tonePin, 184, 203.992851562);
    delay(226.658723958);
    delay(236.303776042);
    tone(tonePin, 184, 203.992851562);
    delay(226.658723958);
    delay(236.303776042);
    tone(tonePin, 233, 555.555);
}

void setup() {
// Serial.begin(9600); // инициализируем последовательный порт для обмена сообщениями & Поиск неисправностей

 // 1 шаговый двигатель
 pinMode(dirChA, OUTPUT);   // инициализируем вывод 12 как ВЫХОД
 digitalWrite(dirChA, LOW);   //инициализируем контакт 12 как НИЗКИЙ (напряжение на контакте равно 0 В)

 pinMode(dirChB, OUTPUT);   // инициализируем вывод 13 как ВЫХОД
 digitalWrite(dirChB, LOW);   //инициализируем контакт 13 как НИЗКИЙ (напряжение на контакте равно 0 В)

 pinMode(pwmChA, OUTPUT);   // инициализируем контакт 3 как ВЫХОД
 digitalWrite(pwmChA, LOW);   //инициализируем контакт 3 как НИЗКИЙ (напряжение на контакте равно 0 В)

 pinMode(pwmChB, OUTPUT);   // инициализируем вывод 11 как ВЫХОД
 digitalWrite(pwmChB, LOW);   //инициализируем контакт 11 как НИЗКИЙ (напряжение на контакте равно 0 В)

 pinMode(brkChA, OUTPUT);   // инициализируем контакт 9 как ВЫХОД
 digitalWrite(brkChA, LOW);   //инициализируем контакт 9 как НИЗКИЙ (напряжение на контакте равно 0 В)

 pinMode(brkChB, OUTPUT);   // инициализируем контакт 8 как ВЫХОД
 digitalWrite(brkChB, LOW);   //инициализируем контакт 8 как НИЗКИЙ (напряжение на контакте равно 0 В)

 myStepper.setSpeed(60);   // устанавливаем скорость шагового двигателя на 60 об/мин

 // 4 кнопки
 pinMode(pButton1, INPUT);   // инициализируем контакт 4 как ВХОД
 digitalWrite(pButton1, LOW);   // инициализируем контакт 4 как НИЗКИЙ (напряжение на контакте менее 1,5 В)

 pinMode(pButton2, INPUT);   // инициализируем контакт 5 как ВХОД
 digitalWrite(pButton2, LOW);   // инициализируем контакт 5 как НИЗКИЙ (напряжение на контакте менее 1,5 В)

 pinMode(pButton3, INPUT);   // инициализируем контакт 6 как ВХОД
 digitalWrite(pButton3, LOW);   // инициализируем контакт 6 как НИЗКИЙ (напряжение на контакте менее 1,5 В)

 pinMode(pButton4, INPUT);   // инициализируем контакт 7 как ВХОД
 digitalWrite(pButton4, LOW);   // инициализируем контакт 7 как НИЗКИЙ (напряжение на контакте менее 1,5 В)

 // 1 светодиод
 pinMode(ledLight, OUTPUT);   // инициализируем контакт 2 как ВЫХОД
 digitalWrite(ledLight, LOW);   // инициализируем контакт 2 как НИЗКИЙ (напряжение на контакте равно 0 В)
}

void loop() {
  //Чтение состояния кнопки (нажата или не нажата?)
  pButton1State = digitalRead(pButton1);   // прочитать состояние pButton1 как LOW или HIGH
  pButton2State = digitalRead(pButton2);   // прочитать состояние pButton2 как LOW или HIGH
  pButton3State = digitalRead(pButton3);   // прочитать состояние pButton3 как LOW или HIGH
  pButton4State = digitalRead(pButton4);   // прочитать состояние pButton4 как LOW или HIGH

  // проверяем, нажата ли кнопка. Если это так, pbuttonState имеет значение HIGH:
  if (pButton1State == HIGH) {
     pButtonFlag=1;  // изменить переменную pButton1Flag
  }
     if (pButtonFlag == 1){
        digitalWrite(pwmChA, HIGH);   // включить питание шагового двигателя
        digitalWrite(pwmChB, HIGH);   // включить питание шагового двигателя
        myStepper.step(40);          // шаг вперед на 40 шагов до позиции 1
        digitalWrite(pwmChA, LOW);    // отключаем питание шагового двигателя
        digitalWrite(pwmChB, LOW);    // отключаем питание шагового двигателя

        myServoFlag=1;             // меняем переменную ServoFlag для дозирования шоколада

        if (myServoFlag == 1){
           myServo.attach(srvoMtr);   // подключаем библиотеку сервоприводов к контакту 10
           for (myServoPos = 0; myServoPos <= 100; myServoPos += 1) { // переходим от 0 градусов к 100 градусам с шагом в 1 градус
               myServo.write(myServoPos);    // сообщаем сервоприводу перейти в позицию в переменной 'myServoPos'
               delay(15);                    // ждем 15 миллисекунд, пока сервопривод достигнет позиции
           }
           myServo.detach();   // отсоединяем библиотеку сервоприводов от контакта 10
           delay(2000); // удерживаем положение ОТКРЫТО 2 секунды

           myServo.attach(srvoMtr);   // подключаем библиотеку сервоприводов к контакту 10
           for (myServoPos = 100; myServoPos >= 0; myServoPos -= 1) { // переход от 100 градусов к 0 градусам с шагом в 1 градус
               myServo.write(myServoPos);    // сообщаем сервоприводу перейти в позицию в переменной 'pos
               delay(15);
           }
           myServo.detach();   // отсоединяем библиотеку сервоприводов от контакта 10
        }    

        myServoFlag=0;         // изменяет значение myServoFlag обратно на ноль (0)
        digitalWrite(ledLight, HIGH);   // включаем свет, чтобы показать, что шоколад выдан
        midi();

        digitalWrite(pwmChA, HIGH);   // включить питание шагового двигателя
        digitalWrite(pwmChB, HIGH);   // включить питание шагового двигателя
        myStepper.step(-40);          // шаг назад на 40 шагов до позиции 0
        digitalWrite(pwmChA, LOW);    // отключаем питание шагового двигателя
        digitalWrite(pwmChB, LOW);    // отключаем питание шагового двигателя

        digitalWrite(pButton1, LOW);   // инициализируем контакт 4 как НИЗКИЙ (напряжение на контакте менее 1,5 В)
        digitalWrite(ledLight, LOW);   // выключает свет, чтобы показать, что последовательность завершена

        pButtonFlag=0;                // изменяет значение pButtonFlat обратно на ноль (0)
        delay(2000); 
     }

  // позиция 2
  if (pButton2State == HIGH) {
     pButtonFlag=1;  // изменить переменную pButtonFlag
  }
     if (pButtonFlag == 1){
        digitalWrite(pwmChA, HIGH);   // включить питание шагового двигателя
        digitalWrite(pwmChB, HIGH);   // включить питание шагового двигателя
        myStepper.step(80);          // шаг вперед на 80 шагов до позиции 2
        digitalWrite(pwmChA, LOW);    // отключаем питание шагового двигателя
        digitalWrite(pwmChB, LOW);    // отключаем питание шагового двигателя
        delay(2000);

        myServoFlag=1;    // меняем переменную ServoFlag для дозирования шоколада

        if (myServoFlag == 1){
           myServo.attach(srvoMtr);   // подключаем библиотеку сервоприводов к контакту 10
           for (myServoPos = 0; myServoPos <= 100; myServoPos += 1) { // переходим от 0 градусов к 100 градусам с шагом в 5 градусов
               myServo.write(myServoPos);    // сообщаем сервоприводу перейти в позицию в переменной 'myServoPos'
               delay(15);                    // ждем 15 миллисекунд, пока сервопривод достигнет позиции
           }
           myServo.detach();   // отсоединяем библиотеку сервоприводов от контакта 10
           delay(2000);

           myServo.attach(srvoMtr);   // подключаем библиотеку сервоприводов к контакту 10
           for (myServoPos = 100; myServoPos >= 0; myServoPos -= 1) { // переход от 100 градусов к 0 градусам с шагом в 1 градус
               myServo.write(myServoPos);    // сообщаем сервоприводу перейти в позицию в переменной 'pos
               delay(15);
           }
           myServo.detach();   // отсоединяем библиотеку сервоприводов от контакта 10
        }    
        myServoFlag=0;                // изменяет значение myServoFlag обратно на ноль (0)
        digitalWrite(ledLight, HIGH);    // включаем свет, чтобы показать, что шоколад выдан
        midi();

        digitalWrite(pwmChA, HIGH);   // включить питание шагового двигателя
        digitalWrite(pwmChB, HIGH);   // включить питание шагового двигателя
        myStepper.step(-80);          // шаг назад на 80 шагов до позиции 0
        digitalWrite(pwmChA, LOW);    // отключаем питание шагового двигателя
        digitalWrite(pwmChB, LOW);    // отключаем питание шагового двигателя

        digitalWrite(pButton2, LOW);   // инициализируем контакт 5 как НИЗКИЙ (напряжение на контакте менее 1,5 В)
        digitalWrite(ledLight, LOW);   // выключает свет, чтобы показать, что последовательность завершена

        pButtonFlag=0;   // изменяет значение pButton2Flag обратно на ноль (0)
        delay(2000); 
    }

    // позиция 3
    if (pButton3State == HIGH) {
       pButtonFlag=1;   // изменить переменную pButtonFlag
    }
       if (pButtonFlag == 1){
          digitalWrite(pwmChA, HIGH);   // включить питание шагового двигателя
          digitalWrite(pwmChB, HIGH);   // включить питание шагового двигателя
          myStepper.step(120);          // шаг вперед на 120 шагов до позиции 3
          digitalWrite(pwmChA, LOW);    // отключаем питание шагового двигателя
          digitalWrite(pwmChB, LOW);    // отключаем питание шагового двигателя
          delay(2000);

          myServoFlag=1;   // меняем переменную ServoFlag для дозирования шоколада

          if (myServoFlag == 1){
             myServo.attach(srvoMtr);   // подключаем библиотеку сервоприводов к контакту 10
             for (myServoPos = 0; myServoPos <= 100; myServoPos += 1) { // переходим от 0 градусов к 100 градусам с шагом в 5 градусов
                 myServo.write(myServoPos);    // сообщаем сервоприводу перейти в позицию в переменной 'myServoPos'
                 delay(15);                    // ждем 3 секунды, пока сервопривод не достигнет позиции
             }
             myServo.detach();   // отсоединяем библиотеку сервоприводов от контакта 10
             delay(2000);

             myServo.attach(srvoMtr);   // подключаем библиотеку сервоприводов к контакту 10
             for (myServoPos = 100; myServoPos >= 0; myServoPos -= 1) { // переход от 100 градусов к 0 градусам с шагом в 1 градус
               myServo.write(myServoPos);    // сообщаем сервоприводу перейти в позицию в переменной 'pos
               delay(15);
             }
             myServo.detach();   // отсоединяем библиотеку сервоприводов от контакта 10
          }    
          myServoFlag=0;                // изменяет значение myServoFlag обратно на ноль (0)
          digitalWrite(ledLight, HIGH);   // включаем свет, чтобы показать, что шоколад выдан
          midi();

          digitalWrite(pwmChA, HIGH);   // включить питание шагового двигателя
          digitalWrite(pwmChB, HIGH);   // включить питание шагового двигателя
          myStepper.step(-120);         // шаг назад на 120 шагов до позиции 0
          digitalWrite(pwmChA, LOW);    // отключаем питание шагового двигателя
          digitalWrite(pwmChB, LOW);    // отключаем питание шагового двигателя

          digitalWrite(pButton3, LOW);   // инициализируем контакт 6 как НИЗКИЙ (напряжение на контакте менее 1,5 В)
          digitalWrite(ledLight, LOW);   // выключает свет, чтобы показать, что последовательность завершена

          pButtonFlag=0;   // изменяет значение pButton3Flag обратно на ноль (0)
          delay(2000); 
     }
    // позиция 4
    if (pButton4State == HIGH) {
       pButtonFlag=1;   // изменить переменную pButtonFlag
    }
       if (pButtonFlag == 1){
          digitalWrite(pwmChA, HIGH);   // включить питание шагового двигателя
          digitalWrite(pwmChB, HIGH);   // включить питание шагового двигателя
          myStepper.step(160);          // шаг вперед на 160 шагов до позиции 3
          digitalWrite(pwmChA, LOW);    // отключаем питание шагового двигателя
          digitalWrite(pwmChB, LOW);    // отключаем питание шагового двигателя
          delay(2000);

          myServoFlag=1;   // меняем переменную ServoFlag для дозирования шоколада
          Serial.println("\nServo Flag = 1 - Dispense Chocolate");

          if (myServoFlag == 1){
             myServo.attach(srvoMtr);   // подключаем библиотеку сервоприводов к контакту 10
             for (myServoPos = 0; myServoPos <= 100; myServoPos += 1) { // переходим от 0 градусов к 100 градусам с шагом в 5 градусов
                 myServo.write(myServoPos);    // сообщаем сервоприводу перейти в позицию в переменной 'myServoPos'
                 delay(15);                    // ждем 3 секунды, пока сервопривод не достигнет позиции
             }
             myServo.detach();   // отсоединяем библиотеку сервоприводов от контакта 10
             delay(2000);

             myServo.attach(srvoMtr);   // подключаем библиотеку сервоприводов к контакту 10
             for (myServoPos = 100; myServoPos >= 0; myServoPos -= 1) { // переход от 100 градусов к 0 градусам с шагом в 1 градус
               myServo.write(myServoPos);    // сообщаем сервоприводу перейти в позицию в переменной 'pos
               delay(15);
             }
             myServo.detach();   // отсоединяем библиотеку сервоприводов от контакта 10
          }    
          myServoFlag=0;   // изменяет значение myServoFlag обратно на ноль (0)
          digitalWrite(ledLight, HIGH);   // включаем свет, чтобы показать, что шоколад выдан
          midi();

          digitalWrite(pwmChA, HIGH);   // включить питание шагового двигателя
          digitalWrite(pwmChB, HIGH);   // включить питание шагового двигателя
          myStepper.step(-160);         // шаг назад на 160 шагов до позиции 0
          digitalWrite(pwmChA, LOW);    // отключаем питание шагового двигателя
          digitalWrite(pwmChB, LOW);    // отключаем питание шагового двигателя

          digitalWrite(pButton3, LOW);   // инициализируем контакт 6 как НИЗКИЙ (напряжение на контакте менее 1,5 В)
          digitalWrite(ledLight, LOW);   // выключает свет, чтобы показать, что последовательность завершена

          pButtonFlag=0;   // изменяет значение pButton3Flag обратно на ноль (0)
          delay(2000);          
       }
}  

, 👍-1

Обсуждение

Как и ожидалось, вы хотите управлять сервоприводом с помощью контакта 3, но в других вопросах было объяснено, что «тон ()» мешает ШИМ на контактах 3 и 11. Сервоприводы управляются сигналами ШИМ., @jose can u c

Я использую моторный щит. Я использую контакт 10 для подачи сигнала на сервопривод. Разве это не должно работать? Штырьки 3 и 11 используются степпером., @Stevie_D

Код, из-за которого серводвигатель не работает! ..... отсоедините сервопривод от arduino... держу пари, что он все равно не будет работать.... это не код, из-за которого он не работает, @jsotola

@jsotola это именно тот код, из-за которого он не работает, @Roberto Lo Giacco

@RobertoLoGiacco, это неправда .... вам вообще не нужен код, чтобы двигатель не работал ...... «код не заставляет двигатель работать» - правильное утверждение .... .. другими словами, код не запускает двигатель, @jsotola


1 ответ


0

Как уже сообщалось в комментариях, библиотека Tone использует Timer2 — аппаратный модуль микроконтроллера Atmega328P, который также отвечает за генерацию ШИМ-сигнала на контактах 3 и 11. Поскольку контакты 3 и 11 используются вашим кодом для управления серводвигателем, неудивительно, что двигатель начинает работать хаотично после того, как вы добавили код для воспроизведения тонов на зуммере.

Решением было бы не использовать контакты 3 и 11 ШИМ в качестве ШИМ (вы все равно можете использовать их, просто чтобы не генерировать сигналы ШИМ)

Об этом ясно сообщается в документации:

Частоты ШИМ соединены парами контактов. Если один в паре изменен, другой также изменяется, чтобы соответствовать:

  • Контакты 5 и 6 подключены к таймеру 0.
  • Контакты 9 и 10 подключены к таймеру 1.
  • Контакты 3 и 11 подключены к таймеру 2.

А также:

Использование функции tone() будет мешать выходу ШИМ на контактах 3 и 11 (на платах, отличных от Mega).

,