Agkz.ru - игровой новостной портал
Луноход Электроника на Arduino

Луноход Электроника на Arduino

  • Цена: $0.90
  • Доброго времени суток читатели Муськи!

    Сегодня я расскажу вам о второй жизни лунохода Электроника. Кому интересно прошу под cut:

    Восьмидесятые:

    В 1986 году на день рождения дядя подарил мне программируемый луноход Электроника. До конца восьмидесятых луноход исправно работал. Далее появились программные глюки луноход включал «лазер» по делу и без дела во время выполнения программы. Закончилось это дело тем, что любая программа выполнялась как бесконечная стрельба… Найти новый прошитый микроконтроллер «уу-1» не представлялось возможным и луноход был убран на дальнюю полку.

    Луноход Электроника на Arduino

    Луноход Электроника на Arduino

    Наши дни:

    Луноход был извлечён с дальней полки, разобран. Плата с дохлой уу-1 отправилась в коробку с золотосодержащими микросхемами (а золото там даже внешне видно ничего выкусыаать не надо). Контакты под 4*373 (D) и под крону были демонтированы.

    Собственно что имеем:

    Корпус в состоянии 5+

    Полностью исправные моторы (тип танк/трактор правый/левый мотор)

    Ведущие колёса с резиновыми кольцами. Резина как новая…

    Динамик

    Датчик наезда на препятствие в виде двух микриков и планки.

    В «бластере» лампочка накаливания была заменена на светодиод.

    Была изготовлена NI-CD батарея 8,4v 0,9Ач

    Луноход Электроника на Arduino

    Можно было конечно литиевую батарею сделать, но у меня от шуруповертов куча nicd. Выбрал лучшие банки, собрал батарею.

    Как показала практика данной батареи для этой игрушки за глаза…

    За основу решил взять какой нибудь открытый проект. Нашел на cxem.net

    Приложение на Android я взял без изменений.

    Программу для Arduino добавил от себя процентов 30.

    Было куплено:

    Arduino UNO (микросхема на панельке)+кабель

    aliexpress.com/item/igh-quality-One-set-UNO-R3-Official-Box-ATMEGA16U2-MEGA328P-Chip-For-Arduino-UNO-R3-Development/32948661593.html

    HC-06 Bluetooth

    aliexpress.com/item/HC-06-Bluetooth-Serial-Pass-through-Module-Wireless-Serial-Communication-HC06-Bluetooth-Module-for-arduino-Diy/32857133517.html

    motor shield

    aliexpress.com/item/New-Dual-H-Bridge-DC-Stepper-Motor-Drive-Controller-Board-Module-L298N-for-Arduino-Free-Shipping/32243752190.html

    Все было собрано в корпус. Возможность программирования через люк.

    Светодиод выведен от Bluetooth

    Луноход Электроника на Arduino

    Логика работы:

    Включаем луноход звучит сигнал, светодиод BT мигает. Запускаем программу на телефоне, BT диод горит. Если не управлять машиной более 10 мин включается сирена.

    Программой можно включать/выключать свет. Движение вперёд, назад, вправо, влево.

    Луноход Электроника на Arduino

    При наезде на препятствие reset ардуины, перезапуск программы.

    После отладки UNO в принципе можно было поменять на что нибудь другое на постоянку. Но смысла особого не вижу. Места в корпусе полно. Если, что добавлять uno удобнее. Да и бакс экономии погоды не сделает.

    Так что оставил uno на постоянку.

    Код программы (полностью отлаженная версия):

    Программа
    #include «EEPROM.h»

    #define D1 2 // направление вращение двигателя 1

    #define M1 3 // ШИМ вывод для управления двигателем 1 (левый)

    #define D2 4 // направление вращение двигателя 2

    #define M2 5 // ШИМ вывод для управления двигателем 2 (правый)

    #define HORN 11 // доп. канал 1

    //#define autoOFF 2500 // кол-во миллисекунд через которое робот останавливается при потери связи

    #define cmdL ‘L’ // команда UART для левого двигателя

    #define cmdR ‘R’ // команда UART для правого двигателя

    #define cmdH ‘H’ // команда UART для доп. канала 1 (к примеру сигнал Horn)

    #define cmdF ‘F’ // команда UART для работы с EEPROM памятью МК для хранения настроек

    #define cmdr ‘r’ // команда UART для работы с EEPROM памятью МК для хранения настроек (чтение)

    #define cmdw ‘w’ // команда UART для работы с EEPROM памятью МК для хранения настроек (запись)

    char incomingByte; // входящие данные

    char L_Data[4]; // строковый массив для данных левого мотора L

    byte L_index = 0; // индекс массива

    char R_Data[4]; // строковый массив для данных правого мотора R

    byte R_index = 0; // индекс массива

    char H_Data[1]; // строковый массив для доп. канала

    byte H_index = 0; // индекс массива H

    char F_Data[8]; // строковый массив данных для работы с EEPROM

    byte F_index = 0; // индекс массива F

    char command; // команда: передача координат R, L или конец строки

    //int button = 12; // датчик остановки (в текущей версии не используется)

    int i;

    unsigned long currentTime, lastTimeCommand, autoOFF, tm=1;

    void setup() {

    tone(9,100,500);

    Serial.begin(9600); // инициализация порта

    pinMode(HORN, OUTPUT); // дополнительный канал

    pinMode(D1, OUTPUT); // выход для задания направления вращения двигателя

    pinMode(D2, OUTPUT); // выход для задания направления вращения двигателя

    //pinMode(button, INPUT); // датчик остановки

    /*EEPROM.write(0,255);

    EEPROM.write(1,255);

    EEPROM.write(2,255);

    EEPROM.write(3,255);*/

    timer_init(); // инициализируем программный таймер

    }

    void timer_init() {

    uint8_t sw_autoOFF = EEPROM.read(0); // считываем с EEPROM параметр «включена ли ф-ия остановки машинки при потере связи»

    if(sw_autoOFF == ‘1’){ // если таймер останова включен

    char var_Data[3];

    var_Data[0] = EEPROM.read(1);

    var_Data[1] = EEPROM.read(2);

    var_Data[2] = EEPROM.read(3);

    autoOFF = atoi(var_Data)*100; // переменная автовыкл. для хранения кол-ва мс

    }

    else if(sw_autoOFF == ‘0’){

    autoOFF = 999999;

    }

    else if(sw_autoOFF == 255){

    autoOFF = 2500; // если в EEPROM ничего не записано, то по умолчанию 2.5 сек 2500

    }

    currentTime = millis(); // считываем время, прошедшее с момента запуска программы

    }

    void loop() {

    tm=tm+1; // 4 минуты=3000000

    if (tm>3500000){

    tone(9,199,999);

    digitalWrite(HORN, HIGH);

    tone(9,155,505);

    delay(700);

    digitalWrite(HORN, LOW);

    tone(9,253,601);

    delay(700);

    }

    if (Serial.available() > 0) { // если пришли UART данные

    tm=1;

    incomingByte = Serial.read(); // считываем байт

    if(incomingByte == cmdL) { // если пришли данные для мотора L

    command = cmdL; // текущая команда

    memset(L_Data,0,sizeof(L_Data)); // очистка массива

    L_index = 0; // сброс индекса массива

    }

    else if(incomingByte == cmdR) { // если пришли данные для мотора R

    command = cmdR;

    memset(R_Data,0,sizeof(R_Data));

    R_index = 0;

    }

    else if(incomingByte == cmdH) { // если пришли данные для доп. канала 1

    command = cmdH;

    memset(H_Data,0,sizeof(H_Data));

    H_index = 0;

    }

    else if(incomingByte == cmdF) { // если пришли данные для работы с памятью

    command = cmdF;

    memset(F_Data,0,sizeof(F_Data));

    F_index = 0;

    }

    else if(incomingByte == ‘r’) command = ‘e’; // конец строки

    else if(incomingByte == ‘t’) command = ‘t’; // конец строки для команд работы с памятью

    if(command == cmdL && incomingByte != cmdL){

    L_Data[L_index] = incomingByte; // сохраняем каждый принятый байт в массив

    L_index++; // увеличиваем текущий индекс массива

    }

    else if(command == cmdR && incomingByte != cmdR){

    R_Data[R_index] = incomingByte;

    R_index++;

    }

    else if(command == cmdH && incomingByte != cmdH){

    H_Data[H_index] = incomingByte;

    H_index++;

    }

    else if(command == cmdF && incomingByte != cmdF){

    F_Data[F_index] = incomingByte;

    F_index++;

    }

    else if(command == ‘e’){ // если приняли конец строки

    Control4WD(atoi(L_Data),atoi(R_Data),atoi(H_Data));

    delay(10);

    }

    else if(command == ‘t’){ // если приняли конец строки для работы с памятью

    Flash_Op(F_Data[0],F_Data[1],F_Data[2],F_Data[3],F_Data[4]);

    }

    lastTimeCommand = millis(); // считываем текущее время, прошедшее с момента запуска программы

    }

    if(millis() >= (lastTimeCommand + autoOFF)){ // сравниваем текущий таймер с переменной lastTimeCommand + autoOFF

    Control4WD(0,0,atoi(H_Data)); // останавливаем машинку

    }

    }

    Дети довольны игрушкой!