Поезд Arduino для детей с управлением со смартфона

Делаем редизайн дешевого набора детской железной дороги в интеллектуальный поезд с управлением с устройства на ОС Android. Проект обновлен. Добавлен датчик.

Компоненты

Нам нужно не так много деталей для встраивания в наш детский поезд Ардуино:

  • Arduino Nano R3
  • Мотор L9110s
  • Bluetooth HC-06 модуль
  • ИК-датчик Arduino

Программное обеспечение

Описание проекта

Собственная и управляемая «взрослая» железнодорожная модель, безусловно, хороша. Но если у вас есть дети, их энтузиазм к вашей «игрушке» обойдется вам дорого!

Поэтому разработчики придумал приложение, которое объединит вас. Достаточно взять любую детскую железную дорогу, главное, чтобы у локомотива был мотор и он имел место для батарей.

Вы даже можете купить несколько простых комплектов с пластиковыми рельсами и одновременно управлять несколькими поездами. Хороший пример - Lego Train, Big Thomas Coal Steam и т.д.

Несмотря на то, что интерфейс приложения создан для детей, само приложение поддерживает версию протокола 2 проекта URB. А это означает, что одним и тем же приложением моно управлять и железнодорожными компонентами.

Также приложение поддерживает установку датчиков Arduino, благодаря чему поезд ведет себя как робот.

Перед запуском приложения подключите свое устройство и модуль Bluetooth HC-06 через настройки Android приложения.

Схема проекта

Принципиальная схема нашего железнодорожного локомотива выглядит так:

Код поезда Ардуино

Скетч для Ардуино вы можете скачать или скопировать ниже:

#define SENSOR_IR 2
#define L9110S_AIA 3
#define L9110S_AIB 5
#define GND1 8
#define LED1 9
#define LED2 10
#define FLOODLIGHT 11
#define GND2 12

static unsigned long preMillis;
String inputString = "";
boolean stringComplete = false;
int locoSpeed, counter = 0;
bool tick, directionForward, directionBackward;
bool sensorActive = false, alarm_allRed = false;


void setup() {
  // Initialize serial
  Serial.begin(9600);
  inputString.reserve(4);

  // Pins
  pinMode(GND1, OUTPUT);
  pinMode(GND2, OUTPUT);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(FLOODLIGHT, OUTPUT);
  pinMode(L9110S_AIA, OUTPUT);
  pinMode(L9110S_AIB, OUTPUT);
  pinMode(SENSOR_IR, INPUT);

  digitalWrite(GND1, LOW);
  digitalWrite(GND2, LOW);
  digitalWrite(FLOODLIGHT, HIGH);
  delay(300);
  digitalWrite(FLOODLIGHT, LOW);
}

void loop() {

  if (stringComplete) {

    // TRAIN CONTROL
    if (inputString.charAt(0) =='a') {

      // TROTTLE
      if (inputString.charAt(1) =='0') {
        if (inputString.charAt(2) =='0') locoSpeed = 0; // Stop
        if (inputString.charAt(2) =='2') locoSpeed = 80;
        if (inputString.charAt(2) =='4') locoSpeed = 110;
        if (inputString.charAt(2) =='6') locoSpeed = 140;
        if (inputString.charAt(2) =='8') locoSpeed = 170;
      }
      if (inputString.charAt(1) =='1') locoSpeed = 200;

      // MOVE DIRECTION
      if (inputString.charAt(1) =='d') {
        if (inputString.charAt(2) =='f') {
          directionForward = true;
          directionBackward = false;
        }
        if (inputString.charAt(2) =='b') {
          directionForward = false;
          directionBackward = true;
        }
        if (inputString.charAt(2) =='s') {
          locoSpeed = 0;
          directionForward = false;
          directionBackward = false;
          // DC motor conflict prevention
          digitalWrite(L9110S_AIA, LOW);
          digitalWrite(L9110S_AIB, LOW);
          delay(400);
        }
      }        
    }

    // LIGHT
    if (inputString.charAt(0) =='l') {
    	if (inputString.charAt(2) =='0') digitalWrite(FLOODLIGHT, LOW);
      if (inputString.charAt(2) =='1') digitalWrite(FLOODLIGHT, HIGH);
    }

    // SENSOR ON/OFF
    if (inputString.charAt(0) =='s') {
      if (inputString.charAt(2) =='0') sensorActive = false;
      if (inputString.charAt(2) =='1') sensorActive = true;
    }

    inputString = "";
    stringComplete = false;
  }

  if (digitalRead(SENSOR_IR) == HIGH || !sensorActive) {

    if (directionBackward) {
      digitalWrite(L9110S_AIB, LOW);    	
      analogWrite(L9110S_AIA, locoSpeed);
    }
    if (directionForward) {
      digitalWrite(L9110S_AIA, LOW);
      analogWrite(L9110S_AIB, locoSpeed);
    }
    alarm_allRed = false;

  }
  else { // STOP at IR sensor

    digitalWrite(L9110S_AIA, LOW);
    digitalWrite(L9110S_AIB, LOW);
    Serial.println("alarmz");
    alarm_allRed = true;
  }

  if (locoSpeed > 0 && !alarm_allRed) {
    static unsigned long blinkMillis;
    if (millis() > (blinkMillis + 300)) {
      tick = !tick;
      blinkMillis = millis();
    }
    digitalWrite(LED1, tick);
    digitalWrite(LED2, !tick);
  }
  else if (alarm_allRed) {
    digitalWrite(LED1, HIGH);
    digitalWrite(LED2, HIGH);
  }
  else {
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
  }
}

// FUNCTIONS
void serialEvent() {
  while (Serial.available()) {
    char inChar = (char)Serial.read();
    inputString += inChar;
    if (inChar == 'z') {
    stringComplete = true;
    }
  }
}

На этом всё. Хороших вам проектов.

Ардуино+