1. В сообществе нашего форума Вконтакте создан раздел по продаже электронных компонентов.
    Каждый может продать в нем свои залежавшиеся детали. Подробности здесь.

Машинка на инфракрасном управлении

Тема в разделе "Arduino", создана пользователем major_jacks, 9 июн 2016.

  1. major_jacks

    major_jacks Гость

    Сообщения:
    21
    Симпатии:
    3
    Как-то, копавшись в кладовке на даче, нашел машинку на инфракрасном управлении, пульт от которой был безвозвратно утерян. Убедившись в работоспособности моторчиков, было решено реанимировать её, привязав к ней пульт от телевизора. Старые мозги были выпаяны, их место займет Arduino Nano v3, которая будет заменена на идущую из Поднебесной Pro Mini. Управлять двигателями доверено драйверу L298N, приобретенному здесь из-за небольшого отличия в цене и экономии времени. К сожалению, слабые ноунейм двигатели никак не хотели нормально работать с ШИМ, поэтому все движения и повороты реализованы просто - вкл и выкл :) Подключение переферии к ардуинке - INA,INB,INC,IND драйвера к портам 2,3,4,5, сигнальный выход ИК-диода к 6-му порту, питание диода от выходов +5 и GND. Общее питание ардуины и драйвера может быть от 4-х 1,5-вольтовых АА батареек, или кроны. Так как родной батарейный отсек расчитан на три АА батарейки, было решено запитать всё от двух 3,7-вольтовых АА LiPo аккумуляторов. При питании драйвера от ардуины не хватало мощности у двигателей, при питании ардуины от драйвера - плата начинала глючить и перегружаться. Поэтому было решено подключить всё параллельно. Ну и самое основное - код. Через монитор порта ардуины были отловлены сигналы с пульта и после нескольких версий родился такой код:
    Код:
    #include <IRremote.h>
    
    int RECV_PIN = 6, stateL = 0, stateR = 0;
    IRrecv irrecv(RECV_PIN);
    decode_results results;
    unsigned long lastres;
    
    int IN1 = 2;
    int IN2 = 3;
    int IN3 = 5;
    int IN4 = 4;
    
    void setup() {
      pinMode (IN4, OUTPUT);
      pinMode (IN3, OUTPUT);
      pinMode (IN2, OUTPUT);
      pinMode (IN1, OUTPUT);
     
      irrecv.enableIRIn();
    }
    int leftF() {
      if (digitalRead(IN1 != HIGH)) { digitalWrite(IN1, HIGH); }
      if (digitalRead(IN2 != LOW)) { digitalWrite(IN2, LOW); }
      return 1;
    }
    int rightF() {
      if (digitalRead(IN3 != HIGH)) { digitalWrite(IN3, HIGH); }
      if (digitalRead(IN4 != LOW)) { digitalWrite(IN4, LOW); }
      return 1;
    }
    int leftB() {
      if (digitalRead(IN1 != LOW)) { digitalWrite(IN1, LOW); }
      if (digitalRead(IN2 != HIGH)) { digitalWrite(IN2, HIGH); }
      return -1;
    }
    int rightB() {
      if (digitalRead(IN3 != LOW)) { digitalWrite(IN3, LOW); }
      if (digitalRead(IN4 != HIGH)) { digitalWrite(IN4, HIGH); }
      return -1;
    }
    int stopR() {
      if (digitalRead(IN4 != LOW)) { digitalWrite(IN4, LOW); }
      if (digitalRead(IN3 != LOW)) { digitalWrite(IN3, LOW); }
      return 0;
    }
    int stopL() {
      if (digitalRead(IN2 != LOW)) { digitalWrite(IN2, LOW); }
      if (digitalRead(IN1 != LOW)) { digitalWrite(IN1, LOW); }
      return 0;
    }
     
    void loop() {
     
      unsigned long currentMillis = millis();
     
      if (irrecv.decode(&results)) {
        if (results.value != 0xFFFFFFFF) { lastres = results.value; }
    
        if (lastres == 0x20DF02FD) {
          if (stateL == -1) { stopL(); stateL = leftF(); }
          if (stateL == 0) { stateL = leftF(); }
          if (stateR == -1) { stopR(); stateR = rightF(); }
          if (stateR == 0) { stateR = rightF(); }
        } else if (lastres == 0x20DF827D) {
          if (stateL == 1) { stopL(); stateL = leftB(); }
          if (stateL == 0) { stateL = leftB(); }
          if (stateR == 1) { stopR(); stateR = rightB(); }
          if (stateR == 0) {stateR = rightB(); }
        } else if (lastres == 0x20DFE01F) {
          if (stateL != 0 && stateR != 0) {
           stateR = stopR();
           } else {
             stateL = leftF();
           }     
        } else if (lastres == 0x20DF609F) {
          if (stateR != 0 && stateR != 0) {
            stateL = stopL();
          } else {
            stateR = rightF();
          }
        } else {
          stateL = stopL();
          stateR = stopR();
        }
    
        delay(300);
        irrecv.resume();
      }
    }
    Не знаю чем, но код меня смущает... Критика и улучшайзинг приветствуется.
    RADmir нравится это.
     
    : arduino, L298N
  2. Buba_Chkhadze

    Buba_Chkhadze Модератор Команда форума

    Сообщения:
    4.354
    Симпатии:
    326
    Адрес:
    Талгар
    в каждой строчке прописана одна и та же нога,
    если (прочитать(вход1 не равно 1)) {записать 1 во вход1 } :eek:
    мож я неправильно понял,

    и состояния наверное лучше в процедуры вынести
    вместо
    int leftF()
    {
    if (digitalRead(IN1 != HIGH)) { digitalWrite(IN1, HIGH); }
    if (digitalRead(IN2 != LOW)) { digitalWrite(IN2, LOW); }
    return 1;
    }

    void leftF()
    {
    if (digitalRead(IN1 != HIGH)) { digitalWrite(IN1, HIGH); }
    if (digitalRead(IN2 != LOW)) { digitalWrite(IN2, LOW); }
    return 1;
    }

    или у ардуинщиков это и есть процедура , int leftF(){} ?
  3. major_jacks

    major_jacks Гость

    Сообщения:
    21
    Симпатии:
    3
    4 ноги - 4 строчки, проверка для того, чтобы лишний раз не писать в порт, если на нем уже единица или ноль.
    void нельзя использовать вместе с return.
  4. Buba_Chkhadze

    Buba_Chkhadze Модератор Команда форума

    Сообщения:
    4.354
    Симпатии:
    326
    Адрес:
    Талгар
    а код то работает ?
  5. .ctor

    .ctor В доску свой

    Сообщения:
    712
    Симпатии:
    200
    Род занятий:
    парогенератор
    Адрес:
    Алматы
    Эта лишняя проверка. Лишняя трата процессорного времени. И 2 вызова процедуры можно поменять на один.
  6. major_jacks

    major_jacks Гость

    Сообщения:
    21
    Симпатии:
    3
    Конечно.
    Возможно. Надо попробовать без проверок.
    2 вызова процедуры. Если имеется ввиду вызов через stopR() stopL(), сам не придумал как по другому. Если сразу включать реверс, не через стоп - появляется глюк на двигателях.
  7. Buba_Chkhadze

    Buba_Chkhadze Модератор Команда форума

    Сообщения:
    4.354
    Симпатии:
    326
    Адрес:
    Талгар
    может надо было конечный автомат делать и прописывать в нем все варианты состояний и все состояния входов
  8. major_jacks

    major_jacks Гость

    Сообщения:
    21
    Симпатии:
    3
    Изначально такая задумка и была, но движки ШИМ не потянули, а из-за двух состояний вкл-выкл писать автомат отказался.
  9. Buba_Chkhadze

    Buba_Chkhadze Модератор Команда форума

    Сообщения:
    4.354
    Симпатии:
    326
    Адрес:
    Талгар
    зато там ты прописал бы переходы из любых состояний, и глюков бы не было в ненужных местах
  10. major_jacks

    major_jacks Гость

    Сообщения:
    21
    Симпатии:
    3
    Нашел на даче пульт от игрушки с двумя стиками управления - вперед-назад и вправо-влево. На каждый стик по 6 сигналов управления, три на направление плюс один общий при нулевом положении. Всё-таки решил использовать ШИМ, иначе машинке и домашней мебели грозил бы косметический ремонт. В итоге родился такой вот код:
    Код:
    #include <IRremote.h>
    
    int RECV_PIN = 6, stateL = 0, stateR = 0;
    IRrecv irrecv(RECV_PIN);
    decode_results results;
    unsigned long lastres;
    
    int IN1 = 2;
    int IN2 = 3;
    int IN3 = 4;
    int IN4 = 5;
    int DR1 = 9;
    int DR2 = 10;
    
    int spd = 0;
    int slow = 100;
    int middle = 150;
    int fast = 250;
    
    void setup() {
      pinMode (IN1, OUTPUT);
      pinMode (IN2, OUTPUT);
      pinMode (IN3, OUTPUT);
      pinMode (IN4, OUTPUT);
      pinMode (DR1, OUTPUT);
      pinMode (DR2, OUTPUT);
      irrecv.enableIRIn();
    }
    void leftF(int spd) {
      digitalWrite(IN1, HIGH);
      digitalWrite(IN2, LOW);
      analogWrite(DR1, spd);
    }
    void rightF(int spd) {
      digitalWrite(IN3, HIGH);
      digitalWrite(IN4, LOW);
      analogWrite(DR2, spd);
    }
    void leftB(int spd) {
      digitalWrite(IN1, LOW);
      digitalWrite(IN2, HIGH);
      analogWrite(DR1, spd);
    }
    void rightB(int spd) {
      digitalWrite(IN3, LOW);
      digitalWrite(IN4, HIGH);
      analogWrite(DR2, spd);
    }
    void stopR() {
      analogWrite(DR2, 0);
    }
    void stopL() {
      analogWrite(DR1, 0);
    }
    
    void loop() {
     
      if (irrecv.decode(&results)) {
        switch(results.value) {
          case 0x5E35659B: leftF(fast); rightF(fast); break;
          case 0xFA83A083: leftF(middle); rightF(middle); break;
          case 0x1C94AD23: leftF(slow); rightF(slow); break;
          case 0xB87755C9: leftB(fast); rightB(fast); break;
          case 0xA5A3A361: leftB(middle); rightB(middle); break;
          case 0x14899129: leftB(slow); rightB(slow); break;
          case 0xB7E37CBD: stopL(); rightF(fast); break;
          case 0xBB7EE175: stopL(); rightF(middle); break;
          case 0x679040B5: stopL(); rightF(slow); break;
          case 0x9F4F514F: stopR(); leftF(fast); break;
          case 0x55A5CFE3: stopR(); leftF(middle); break;
          case 0xA057CA3: stopR(); leftF(slow); break;
    
          case 0xAA155177: leftF(slow); stopR(); break;
          case 0x646BD655: leftF(slow); stopR(); break;
          case 0x60D0719D: leftF(slow); stopR(); break;
          case 0x88EBC7E1: leftF(middle); stopR(); break;
          case 0x67AB225: leftF(middle); rightF(slow); break;
          case 0x8F953E83: leftF(middle); rightF(slow); break;
          case 0xEBB609EF: leftF(fast); stopR(); break;
          case 0xA20C8883: leftF(fast); rightF(middle); break;
          case 0x566C3543: leftF(fast); rightF(slow); break;
         
          case 0x6BE9D1A3: rightF(slow); stopL(); break;
          case 0x2B782ABD: rightF(slow); stopL(); break;
          case 0x15C2C6FD: rightF(slow); stopL(); break;
          case 0xA9695B43: rightF(middle); stopL(); break;
          case 0x6853BD6D: rightF(middle); leftF(slow); break;
          case 0x95DDB9D5: rightF(middle); leftF(slow); break;
          case 0x5363792B: rightF(fast); stopL(); break;
          case 0x2113EE63: rightF(fast); leftF(middle); break;
          case 0xF58F78A3: rightF(fast); leftF(slow); break;
         
          case 0x5FDEAF5F: rightB(slow); stopL(); break;
          case 0x3654B941: rightB(slow); stopL(); break;
          case 0xBF6F459F: rightB(slow); stopL(); break;
          case 0xF4F8C7E1: rightB(middle); leftB(slow); break;
          case 0x44E76257: rightB(middle); leftB(slow); break;
          case 0xF9470F17: rightB(middle); stopL(); break;
          case 0x74DDD509: rightB(fast); stopL(); break;
          case 0x174929DF: rightB(fast); leftB(middle); break;
          case 0xBBC78577: rightB(fast); leftB(slow); break;
         
          case 0xD0362DAD: stopL(); stopR(); break;
         
          default: stopL(); stopR();
       
        }
    
        delay(100);
        irrecv.resume();
      }
    }

Поделиться этой страницей