Контролер для двух двигателей

Тема в разделе "Arduino & Shields", создана пользователем sanik, 19 янв 2013.

  1. sanik

    sanik Гик

    Помогите пожалуйста написать код я совсем зашел в тупик...
    Полное описание
    1ч.)Режим "Analog" При включение питания на экране загорается приветствие чере 1 скунду вывод на дисплей "Analog", при повороте
    потенциометра Y от среднего положения вправо двигатель Y начинает вращаться в право чем больше угол поворота потенциометра
    тем быстрее скорость, при повороте в лево от среднего положения двигатель вращается влево, тоже с регулировкой скорости.
    Двигатель Х работает аналогично от потенциометра X.

    2ч.) Режим Programm При нажатии кнопки selekt первый раз,отключается режим Analog, на дисплей выводится setup, в этом режиме кнопками + и - выставляется
    количество импульсов поступающих с датчика Y с шагом +/-1 отображающих на дисплее в нижней строке, ( setup )
    ( Y+1 X+3 )
    следующее нажатие selekt устанавливается количество импульсов с датчика Х.
    ( setup )
    ( Y+1 X+3 )
    третье нажатие selekt вывод на дисплей Programm, при нажатие кнопки Start вывод на дисплей Program start идет ожидание сигнала
    с кнопки Sunhro при поступлении сигнала, двигателя срабатывают на количество импульсов с датчиков и останавливается, снова идет
    ожидание Sunhro.
    Если количество импульсов в setup выставлено ноль для Y илиХ то соответствующий двигатель остается на одном месте не зависимо от поступления импульсов.

    При нажатии кнопки stop вывод на дисплей Programm stop процесс останавливается , при повторном нажатии переход в режим
    аналог вывод на дисплей Analog
    Моторы управляются контролером с ШИМ выводами, джойстик обычный грибок

    Untitled Sketch1к_bb.jpg

    Код (Text):
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x27,16,2); //установка адреса жк 0х27
     
      // установка установка джойстика (потенциометров)
    #define axis_Y 1    // Ось Y подключена к Analog 1
    #define axis_X 0    // Ось X подключена к Analog 0
    int value, value_Y, value_X = 0;    // Переменные для хранения значений осей
    int ENA = 11;
    int IN1 = 12;
    int IN2 = 13;
    int ENB = 11;
    int IN3 = 16;                  
    int IN4 = 17;
     
     
    void setup()
    {
      Serial.begin(9600); //открываем порт устанавливаем скорость передачи
      lcd.init(); //инциализация жк
      lcd.backlight(); // включаем подсветку
      lcd.clear();// очистка дисплея
    pinMode(IN1, OUTPUT);
    pinMode(IN2, OUTPUT);
    pinMode(IN3, OUTPUT);
    pinMode(IN4, OUTPUT);
     
        //установка pin моторов
     
     
    }
     
      void loop()
                  {
     
      if (Serial.available()) //Ожидание с порта
     
          lcd.setCursor(0, 0); //установка курсора на первую строку
          lcd.print("Hello"); //вывод первой строки приветствия
          delay(200);
          lcd.setCursor(0, 1); //установка курсора на вторую стоку
          lcd.print("SlideUno");  //вывод второй строки приветствия
          delay(200);
    // прочитать все доступные символы
          while (Serial.available() > 0)
            // выводим каждый символ на ЖК
            lcd.write(Serial.read());
            delay(1500);
            // очистить экран
          lcd.clear();
              lcd.setCursor(0, 0);
          lcd.print("Analog"); //вывод аналогово режима
          delay(200);
    // прочитать все доступные символы
          while (Serial.available() > 0)
            // выводим каждый символ на ЖК
            lcd.write(Serial.read());
     
          {
      value_Y = analogRead(axis_Y); // Считываем аналоговое значение оси Y
      if(value_Y >= 0 && value_Y < 100) value = value - 10; //если значение больше или равно 0 истина меньше 100 значение -10
      if(value_Y > 100 && value_Y < 300) value = value - 5;
      if(value_Y > 300 && value_Y < 520) value = value - 1;
      if(value_Y > 535 && value_Y < 700) value = value + 1;
      if(value_Y > 700 && value_Y < 900) value = value + 5;
      if(value_Y > 900) value = value + 10;
     
      value_X = analogRead(axis_X); // Считываем аналоговое значение оси X
      if(value_X >= 0 && value_Y < 100) value = value - 10;
      if(value_X > 100 && value_Y < 300) value = value - 5;
      if(value_X > 300 && value_Y < 520) value = value - 1;
      if(value_X > 535 && value_Y < 700) value = value + 1;
      if(value_X > 700 && value_Y < 900) value = value + 5;
      if(value_X > 900) value = value + 10;
     
      Serial.println(value, DEC);  // Выводим значение в Serial Port
     
      delay(50);                      // Задержка
    }
                  }
     
  2. sanik

    sanik Гик

  3. nailxx

    nailxx Официальный Нерд Администратор

    Собственно с чем загвоздка? У вас заводятся двигатели? Судя по скетчу к ним обращения нет вовсе.

    Попробуйте перед последним delay добавить:

    digitalWrite(ENA, HIGHT);
    analogWrite(IN1, (value_X - 512) / 2);

    И не забудьте в setup() добавить:

    pinMode(ENA, OUTPUT);
     
  4. sanik

    sanik Гик

    В том то и загвоздка я вовсе не понимаю как сделать обращение к моторам.
     
  5. nailxx

    nailxx Официальный Нерд Администратор

    А гляньте примеры с Ardumoto. Управляется стандартно: на один канал — два пина. Первый пин: цифровой, управляет направлением вращения; второй пин: ШИМ’овый, управляет скоростью.

    Как для примера запустить один из двигателей я написал в предыдущем ответе.
     
  6. sanik

    sanik Гик

     
  7. sanik

    sanik Гик

    А вы можете объяснить откуда взято вот это? (value_X - 512) / 2) пожалуйста а то я что то не пойму?
     
  8. Unixon

    Unixon Оракул Модератор

    Это преобразование отображает значение value_X из интервала [0, 1023] в интервал [-256, +255].
    Только это потом в analogWrite() отправлять то нельзя в таком виде...
     
  9. sanik

    sanik Гик

    Ошибку выдает
    sketch_jan21a.ino: In function 'void loop()':
    sketch_jan21a:82: error: 'HIGHT' was not declared in this scope
     
  10. sanik

    sanik Гик

    Попробовал так ошибок нету :) А со вторым двигателем то же самое?

    Код (Text):
          {
      value_Y = analogRead(axis_Y); // Считываем аналоговое значение оси Y
      if(value_Y >= 0 && value_Y < 100) value = value - 10; //если значение больше или равно 0 истина меньше 100 значение -10
      if(value_Y > 100 && value_Y < 300) value = value - 5;
      if(value_Y > 300 && value_Y < 520) value = value - 1;
      if(value_Y > 535 && value_Y < 700) value = value + 1;
      if(value_Y > 700 && value_Y < 900) value = value + 5;
      if(value_Y > 900) value = value + 10;
     
      value_X = analogRead(axis_X); // Считываем аналоговое значение оси X
      if(value_X >= 0 && value_X < 100) value = value - 10;
      if(value_X > 100 && value_X < 300) value = value - 5;
      if(value_X > 300 && value_X < 520) value = value - 1;
      if(value_X > 535 && value_X < 700) value = value + 1;
      if(value_X > 700 && value_X < 900) value = value + 5;
      if(value_X > 900) value = value + 10;
     
      Serial.println(value, DEC);  // Выводим значение в Serial Port
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    analogWrite(ENA, (value_X - 512) / 2);
      delay(50);
     
  11. sanik

    sanik Гик

    Приедет железо надо будет попробовать, как по вашему? Должны моторы работать от джойстиков..?
     
  12. nailxx

    nailxx Официальный Нерд Администратор

    Должны, куда они денутся.

    С `(value_X - 512) / 2` я чуть погорячился. Как сказал Unixon, это приведение от одного диапазона к другому. analogRead возвращает чиселку от 0 до 1023, а в analogWrite нужно передать от 0 до 255. Поэтому правильно брать `abs(((value_X ? value_X : 1) - 512) / 2)` или `abs(map(value_X, 0, 1023, -255, 255))`
     
  13. sanik

    sanik Гик

    Хорошо спасибо! Приедет железка испытаю разные варианты А можно спросит что это за зверь такой map я в примерах его уже не первый раз встречаю... Я так думаю с помощью его отправляются данные в сериал порт? Так а второй движок так же только вместо X поставить Y ?
     
  14. nailxx

    nailxx Официальный Нерд Администратор

    Встроенная функция `map` — отображает входное значение из одного интервала в другой. Кажись в математике это биекцией зовётся.
     
  15. Unixon

    Unixon Оракул Модератор

    Еще одно маленькое, но важное замечание: встроенный map() целочисленный, не только по интерфейсу, но и по внутренним вычислениям, следовательно, он будет всегда просто безбожно врать из-за ошибок округления. Выход: переписать map() для типа float или double, обратно в int конвертировать через floor(x+0.5) .
     
  16. sanik

    sanik Гик

    Так я понял нужно преобразовать это 0, 1023, -255, 255 в это - 512) / 2?
     
  17. sanik

    sanik Гик

    А подробнее ? Это обязательно в моем случае? Что то я запутался... Могу ли я оставить просто это преобразование? abs(((value_X ? value_X : 1) - 512) / 2)
     
  18. sanik

    sanik Гик

    Я тут примерно накидал как будет выполнение во второй части скетча нажатие кнопки старт как на ваш взгляд ( valueHall будет задавать датчик холла) ?
    Код (Text):
     //действие при нажатие кнопки start
      int value_s;for(value_s=0; value_s<=256; value_s+=30);// плавное ускорение мотора
    {
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    analogWrite(ENA, (value_s));
    delay(valueHall)
     
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    analogWrite(ENB, (value_s));
     
  19. sanik

    sanik Гик

    Спасибо вам огромное за помощь!!! У меня снова ступор, помогите пожалуйста разобраться каким способом управлять переменными с кнопок +и- ? Как получить обновленные данные для вывода на ЖК и как их выводить? И как разделить loop на две части?

    Код (Text):
           
            //*********************Первая часть***************
     
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x27,16,2); //установка адреса жк 0х27 указание количество символов и строк
     
      // установка установка джойстика (потенциометров)
    #define axis_Y 1    // Ось Y подключена к Analog 1
    #define axis_X 0    // Ось X подключена к Analog 0
    int value, value_Y, value_X = 0;    // Переменные для хранения значений осей
              //установка датчиков холла
    const int hallyPin = 9;
    int hallStatey = 0;  // переменная для считывания состояния датчика Y
    const int hallxPin = 10;
    int hallStatex = 0; // переменная для считывания состояния датчика X
     
    int pinSelect = 5;
    int pinStop = 2;
    int pinStart = 4;
    int pinPl = 7;  //кнопка+
    int pinMin = 6; //кнопка-
    int pinSun = 8; // кнопка sunhro
    int regims=1; //переменая кнопки select
    int flag=0; // переменая "knopka"
     
    int ENA = 11; // драйвер А2 НЕХ
    int IN1 = 12;
    int IN2 = 13;
    int ENB = 11;
    int IN3 = 16;              
    int IN4 = 17;
     
     
    void setup()
    {
      Serial.begin(9600); //открываем порт устанавливаем скорость передачи
      lcd.init(); //инциализация жк
      lcd.backlight(); // включаем подсветку
      lcd.clear();// очистка дисплея
    pinMode(hallyPin, INPUT);
    pinMode(hallxPin, INPUT);
                  // установка pin кнопок
    pinMode(pinSelect, OUTPUT);
    pinMode(pinStop, OUTPUT);
    pinMode(pinStart, OUTPUT);
    pinMode(pinPl, OUTPUT);
    pinMode(pinMin, OUTPUT);
    pinMode(pinSun , OUTPUT);
        //установка pin моторов
    pinMode(IN1, OUTPUT);
    pinMode(IN2, OUTPUT);
    pinMode(ENA, OUTPUT);
    pinMode(IN3, OUTPUT);
    pinMode(IN4, OUTPUT);
    pinMode(ENB, OUTPUT);
     
    }
     
    void loop()
    {
    if (Serial.available()) //Ожидание с порта
    lcd.setCursor(0, 0); //установка курсора на первую строку
    lcd.print("Hello"); //вывод первой строки приветствия
    delay(200);
    lcd.setCursor(0, 1); //установка курсора на вторую стоку
    lcd.print("SlideUno");  //вывод второй строки приветствия
    delay(200);
    // прочитать все доступные символы
    while (Serial.available() > 0)
    lcd.write(Serial.read()); // выводим каждый символ на ЖК
    delay(1500);
    // очистить экран
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Analog"); //вывод аналогово режима
    delay(200);
    // прочитать все доступные символы
    while (Serial.available() > 0)
            // выводим каждый символ на ЖК
    lcd.write(Serial.read());
    {
      value_Y = analogRead(axis_Y); // Считываем аналоговое значение оси Y
      if(value_Y >= 0 && value_Y < 100) value = value - 10; //если значение больше или равно 0 истина меньше 100 значение -10
      if(value_Y > 100 && value_Y < 300) value = value - 5;
      if(value_Y > 300 && value_Y < 520) value = value - 1;
      if(value_Y > 535 && value_Y < 700) value = value + 1;
      if(value_Y > 700 && value_Y < 900) value = value + 5;
      if(value_Y > 900) value = value + 10;
    value_Y = value_Y/4; // конвектация 0-1023 в 0-255
    {
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    analogWrite(ENA, value_Y);
      delay(50);
    }
      value_X = analogRead(axis_X); // Считываем аналоговое значение оси X
      if(value_X >= 0 && value_X < 100) value = value - 10;
      if(value_X > 100 && value_X < 300) value = value - 5;
      if(value_X > 300 && value_X < 520) value = value - 1;
      if(value_X > 535 && value_X < 700) value = value + 1;
      if(value_X > 700 && value_X < 900) value = value + 5;
      if(value_X > 900) value = value + 10;
      value_Y = value_Y/4; // конвектация 0-1023 в 0-255
    {
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    analogWrite(ENB, value_X );
      delay(50); // Задержка
    }
      // отслеживание нажатия кнопки select переход во 2ю часть
      // здесь должно быть что то что зацикливает 1 ую часть
     
            //*********************Вторая часть***************
     
    //действие первого нажатия select
      if(digitalRead( pinSelect )==HIGH&&flag==0)//если кнопка нажата
        // и перемення flag равна 0 , то ...
      {
        regims++;  // установка одного действия на каждое нажатие
        flag=1;
        if(regims>3)//ограничим количество режимов
        {
        regims=1;//цыкличное переключение режимов
        }
     
        }
        if(digitalRead(pinSelect)==LOW&&flag==1)//если кнопка НЕ нажата
        //и переменная flag равна  1 ,то ...
        {
        flag=0;//обнуляем переменную "knopka"
        }
      if(regims==1)//первый режим
        {
      if (Serial.available()) //Ожидание с порта
    lcd.setCursor(0, 0); //установка курсора на первую строку
    lcd.print("Setup"); //вывод первой строки
    delay(200);
    lcd.setCursor(0, 1); //установка курсора на вторую стоку
    lcd.print("Y ");  //вывод второй строки +функция обновления экрана
    delay(200);
    // прочитать все доступные символы
    while (Serial.available() > 0)
    lcd.write(Serial.read()); // выводим каждый символ на ЖК
     
          //Установка количества импульсов для датчика Y???
     
        }
    if(regims==2)//второй режим
        {
    if (Serial.available()) //Ожидание с порта
    lcd.setCursor(0, 0); //установка курсора на первую строку
    lcd.print("Setup"); //вывод первой строки
    delay(200);
    lcd.setCursor(0, 1); //установка курсора на вторую стоку
    lcd.print("X ");  //вывод второй строки +функция обновления экрана
    delay(200);
    // прочитать все доступные символы
    while (Serial.available() > 0)
    lcd.write(Serial.read()); // выводим каждый символ на ЖК
        }
      if(regims==3)//третий режим
        {
    if (Serial.available()) //Ожидание с порта
    lcd.setCursor(0, 0); //установка курсора на первую строку
    lcd.print("Programm"); //вывод первой строки
    delay(200);
          // прочитать все доступные символы
    while (Serial.available() > 0)
    lcd.write(Serial.read()); // выводим каждый символ на ЖК
     
        }
     
    // нажатие кнопки start запуск второй части
     
    //действие при нажатие кнопки sunhro
     
    int i = 0;
      i = digitalRead(pinSun);  // считать значение на входе кнопки sunhro
      if (i == HIGH) {          // если на входе HIGH
      hallStatey = digitalRead(hallyPin);// считывания значения состояния датчика Y
      int value_s;for (value_s=0; value_s<=256; value_s+=30);// плавное ускорение мотора с шагом 30
     
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    analogWrite(ENA, value_s);
    delay(hallStatey); //задержка на заданное количество импульсов датчика Y
                      }
      i = digitalRead(pinSun);  // считать значение на входе кнопки sunhro
      if (i == HIGH) {          // если на входе HIGH
      hallStatex = digitalRead(hallxPin);// считывания значения состояния датчика X
      int value_c;for(value_c=0; value_c<=256; value_c+=30); // плавное ускорение мотора с шагом 30
     
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    analogWrite(ENB, value_c);
    delay(hallStatex); // задержка на заданное количество импульсов датчика Х
     
    if (Serial.available()) //Ожидание с порта
    lcd.setCursor(0, 0); //установка курсора на первую строку
    lcd.print("Programm"); //вывод первой строки
    delay(200);
    lcd.setCursor(0, 1); //установка курсора на вторую стоку
    lcd.print("Start");  //вывод второй строки
    delay(200);
    // прочитать все доступные символы
    while (Serial.available() > 0)
    lcd.write(Serial.read()); // выводим каждый символ на ЖК
     
    // отслеживание кнопки stop
                      }
    }
    }
     
    Схема меню Sketch1к_bb.jpg
     
  20. Unixon

    Unixon Оракул Модератор

    А в чем проблема? Вы же логику то в принципе правильно написали, продолжайте в том же духе.
    Силь оформления кода, однако, оставляет желать лучшего... ну, потом научитесь...

    Вы весь раздел вики про программирование прочитали? В частности, статью про автоматы?