Проблема с кодом

Тема в разделе "Arduino & Shields", создана пользователем sqr93, 12 окт 2013.

  1. sqr93

    sqr93 Нерд

    Вообщем пытался написать код управления моторами.Но запутался. 1 мотор вкл в лево и потом сразо в право:(.
    Код (Text):
    int ldrlt = 0; //LDR top left
    int ldrrt = 1; //LDR top rigt
    int ldrld = 2; //LDR down left
    int ldrrd = 3; //ldr down rigt
    int i;
    void setup()
    {
      Serial.begin(9600);
      pinMode (9, OUTPUT); //enable 1
      pinMode (8, OUTPUT); //input 1| 1motor
      pinMode (7, OUTPUT); //input 2| 1motor
      pinMode (6, OUTPUT); //enable 2
      pinMode (4, OUTPUT); //input 3| 2motor
      pinMode (2, OUTPUT); //input 4| 2 motor
      delay (2000);
    }
    void loop()
    {
      int lt = analogRead(ldrlt); // top left
      int rt = analogRead(ldrrt); // top right
      int ld = analogRead(ldrld); // down left
      int rd = analogRead(ldrrd); // down rigt
      int avt = (lt + rt) / 2; // average value top
      int avd = (ld + rd) / 2; // average value down
      int avl = (lt + ld) / 2; // average value left
      int avr = (rt + rd) / 2; // average value right

      {
      if (avt < avd) //сравнение значений верх низ
    {
    if ((avt-avd)<15 ) //РАзница и промежуток 15
    {
      delay(200);
    }
    else
    {
      digitalWrite (4, LOW); //
      digitalWrite (2, HIGH); //  ЗАПУСК 2 МОТОРА В ПРАВО
      for (i = 50; i <= 100; ++i)//
      {                            //
          analogWrite(6, i);    //
          delay(30);            //
      }                            //
      analogWrite (6, 0);      //
    }                          
    }
    else
    {
      digitalWrite (4, HIGH);  //
      digitalWrite (2, LOW);    //
      for (i = 50; i <= 100; ++i)// ЗАПУСК 2 МОТРА В ЛЕВО
      {                        //
          analogWrite(6, i);    //
          delay(30);            //
      }                            //
      analogWrite (9, 0);        //
    }
      {
        if (avl > avr) //сравнение значений лево право
    {
    if ((avl-avr)<15 )//РАзница и промежуток 15
    {
      delay(200);
    }
    else
    {
      digitalWrite (8, HIGH);    //
      digitalWrite (7, LOW);      //
      for (i = 50; i <= 180; ++i)//
      {                            //
          analogWrite(9, i);    // ЗАПУСК 1 МОТОРА В ПРАВО
          delay(30);            //
      }                            //
      analogWrite (9, 0);        //
    }
    }
    else
    {
      digitalWrite (8, LOW);        //
      digitalWrite (7, HIGH);      //
      for (i = 50; i <= 100; ++i)    //
      {                                //
          analogWrite(9, i);        // ЗАПУСК 2 МОТОРА В ЛЕВО
          delay(30);                //
      }                                //
      analogWrite (9, 0);            //
    }                                //
        delay(500);                    //
      }}}
     
    Последнее редактирование: 13 окт 2013
  2. sqr93

    sqr93 Нерд

    Подскажите пожалуйста
     
  3. NR55RU

    NR55RU Гик

    Возможно проблема в этом куске ?
    Код (Text):
             
    for (i = 50; i <= 100; ++i)// ЗАПУСК 2 МОТРА В ЛЕВО
    {                        //
       analogWrite(6, i);    //
       delay(30);            //
    }                            //
    analogWrite (9, 0);        //
     
    В частности место analogWrite (9, 0);
    Как я заметил, у вас в коде, этот кусок повторяется 4 раза и в каждому куске в обоих функциях вы используется одинаковый номер пина, а тут получилось иначе в одной функции 6 а в следующей 9.
    Так же дальше в коде есть такая строка: for (i = 50; i <= 180; ++i)
    Опять же везде у вас используется 100 а тут 180, возможно тут тоже есть ошибка а может так и задумано.

    Вообще у вас много повторяющихся кусков, задумайтесь о вынесении повторяющегося кода в отдельные функции, это сделает код более читабельным, понятным и сократит шансы на ошибки.
     
    Последнее редактирование: 13 окт 2013
  4. sqr93

    sqr93 Нерд

    вот блок схема (если ее можно так назвать)К шиму l293d к пинам 9.8.7 это мотор 1.
    а 6.4.2 мотор 2
     

    Вложения:

    • блок.JPG
      блок.JPG
      Размер файла:
      25,2 КБ
      Просмотров:
      344
    Последнее редактирование: 13 окт 2013
  5. Megakoteyka

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

    Давайте попробуем избавиться от "магических" чисел в программе. Читать код и постоянно помнить, что к какой ножке подключено - не есть хорошо.
    Заведите константы с понятными именами.
    Например: MOTOR1_EN, MOTOR1_IN1, MOTOR1_IN2.
    Не стремитесь к излишним сокращениям и аббревиатурам, понятным только Вам. Через 2 месяца откроете код и не вспомните, кто там что обозначает. Сокращать нужно код, а длина имен переменных к длине кода никакого отношения не имеет, для компилятора любая переменная - адрес ячейки памяти, это мы для себя имена пишем.
    Советую прислушаться и принять данный совет за правило. Еще и память более эффективно использовать станете за счет вызова функций :)
     
  6. sqr93

    sqr93 Нерд

    Сделаем.совет ваш нужен как лучше мотором управлять?может у вас есть готовые решения? библиотеки?или лучше выбранным методом делать.Просто если не ставить плавный набор скорости.то повороты дерганные получаются. Да и почему то после выполнения условия поворота в лево сразо же поворачивается в право.мотор пищит:eek:
     
  7. Megakoteyka

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

    Делайте частями. Напишите функцию, которая поворачивает один мотор с заданной скоростью на заданный угол. Если функция будет работать правильно, оставьте ее в покое и начинайте заниматься следующим куском - реакцией на датчики.
    А что за устройство у Вас? Какие датчики? Может, алгоритм изначально неверно составлен?
     
  8. sqr93

    sqr93 Нерд

    Солнечный трекер.датчики-фоторезисторы 8-57LQkf8Tc.jpg rdrHwuUQyTI.jpg 51aoLHZFfBs.jpg
     
  9. NR55RU

    NR55RU Гик

    У меня была проблема с писком/гудением моторов.
    Проблема у меня была в том что шилда подавала мало напряжения на мотор.
    К примеру шилда принимает значения от 0 до 255 из которого она определяет какое напряжение будет подано на мотор от 0В (0) до максимума (255).
    К примеру к шилде подключено 6В питания для моторов, мы вписываем значение в пин скажем 100 это даже меньше 50% отсюда на мотор будет подано около 2В .. что маловато и мотор может вообще не крутится в зависимости от нагрузки на него а только гудеть.
    Таким образом моя платформа только трогаться начинала когда в пин попадало значение 120 из 255 возможных.
    Все что было ниже 120 было гудение и никакой движухи.
    Если я подавал питание для моторов в 9В ... тогда платформа начинала шевелится уже с 90 значения на пине.
    Таким образом вам надо определиться в зависимости от питания и нагрузки на моторы минимальное значение для пина когда мотор начинает шевелится, его принять за начальное значения для движения а промежуток от этого значения до 255 к примеру и будет тем промежутком в котором вы будите регулировать скорость поворота.
    Ну а НОЛЬ он всегда НОЛь, нулем будите делать СТОП.
     
  10. sqr93

    sqr93 Нерд

    Не стал создавать новую тему.Подскажите пожалуйста как лучше сделать этот кусок кода с условиями. ато уменя условия дальше if ((avl-avr)<15 ) не проходят(
    Код (Text):
      {
        if (avl > avr)
    {
    if ((avl-avr)<15 )
    {
      delay(200);
    }
    else
    {
      digitalWrite(en2, HIGH);  // turn the en1 on (HIGH is the voltage level)
      robot.motor_forward(2,150); // 1 вперёд :)
      delay(30);          // wait for a second
      digitalWrite(en2, LOW); // turn the en1 off by making the voltage L
    }
    }
    else
    {
    digitalWrite(en2, HIGH);  // turn the en1 on (HIGH is the voltage level)
    robot.motor_back(2,150); //
    delay(30);            // wait for a second
    digitalWrite(en2, LOW); // turn the en1 off by making the voltage LO
    }
        delay(500);
     
  11. Megakoteyka

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

    А если на каждую строчку поставить отладочный вывод - что оно покажет?
     
  12. sqr93

    sqr93 Нерд

    как это сделать?
     
  13. Megakoteyka

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

    Код (Text):
    if(avl > avr)
    {
      Serial.println("avl > avr: YES");
      ...
    }
    else
    {
      Serial.println("avl > avr: NO");
      ...
    }
    И далее в том же духе... Останется только проанализировать ход выполнения программы и сравнить с желаемым.
     
  14. sqr93

    sqr93 Нерд

    Все время avl- avr<20: YES
    HTML:
    #include <robocraft.h>
    MOTOR MOTOR1 = {
      3, 4, 1 };
    MOTOR MOTOR2 = {
      7, 8, 2};
    int ldrlt = 4; //LDR top left
    int ldrrt = 1; //LDR top rigt
    int ldrld = 2; //LDR down left
    int ldrrd = 3; //ldr down rigt
    int en1 = 6;
    int en2 = 7;
    void setup()
    {
      Serial.begin(9600);
      pinMode(en1, OUTPUT);
      pinMode(en2, OUTPUT);
    }
    RoboCraft robot(&MOTOR1, &MOTOR2);
    void loop()
    {
      int lt = analogRead(ldrlt); // top left
      int rt = analogRead(ldrrt); // top right
      int ld = analogRead(ldrld); // down left
      int rd = analogRead(ldrrd); // down rigt
      lt=lt/3;
      int avt = (lt + rt) / 2; // average value top
      int avd = (ld + rd) / 2; // average value down
      int avl = (lt + ld) / 2; // average value left
      int avr = (rt + rd) / 2; // average value right

      int dvert = avt - avd; // check the diffirence of up and down
      int dhoriz = avl - avr;// check the diffirence og left and rigt
      {

    if (avt < avd)
     {
    if ((avt-avd)<20 )
     {  Serial.println("avl- avr<20: YES");
     }
         else
     {
         digitalWrite(en1, HIGH);  // turn the en1 on (HIGH is the voltage level)
         robot.motor_back(1,250); // 1 вперёд :)
         delay(40);          // wait for a second
         digitalWrite(en1, LOW); // turn the en1 off by making the voltage LO
         Serial.println("avl < avr: YES");
     }
     }
         else
     {
         digitalWrite(en1, HIGH);  // turn the en1 on (HIGH is the voltage level)
         robot.motor_forward(1,250); //
         delay(40);            // wait for a second
         digitalWrite(en1, LOW); // turn the en1 off by making the voltage
         Serial.println("avl < avr: NO");
     }
     }
    }
     
  15. Megakoteyka

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

    Если avt < avd, то, вычитая из меньшего большее, всегда получим отрицательную величину, поэтому оно всегда будет меньше, чем 20.
    Код работает правильно, неправильно составлен алгоритм.
    Почему бы не дать переменным более читаемые имена? topLeft, topRight, bottomLeft, bottomRight, averageTop, averageBottom, averageLeft, averageRight - код будет читаться гораздо легче, по крайней мере на мой взгляд :)
    Есть поговорка: "хорошо написанный код в комментариях не нуждается". Она, конечно, весьма спорна, но зерно истины в ней определенно есть.
     
    Последнее редактирование: 18 окт 2013
  16. Megakoteyka

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

    Если верх освещен больше, чем низ, то поворачивать вверх.
    Если право право освещено больше, чем лево, то поворачивать вправо.
    Код (Text):
    if((top > bottom) && ((top - bottom) > 20)
      // повернуть вверх;
    if((left > right) && ((left - right) > 20)
      // повернуть влево;
    Так должно работать?
     
  17. sqr93

    sqr93 Нерд

    Да работает..Спасибо