Робот — спасатель «Муно» О проекте Возможности робота: • Движение по заданной программе • Предупреждение о пожаре • Предупреждение об утечке газа • Анимация глаз • Анимация улыбки • Проигрывание музыки • Используемые материалы: •Аппаратно-программная платформа «Arduino», •контроллер LEGO Mindstorms RCX, •пожарный извещатель ИП 212-50М, •датчик газа MQ5, •LED-матрицы 8х8, •светодиоды, •сдвиговые регистры 74НС595, •зуммер, •динамик, •звуковой музыкальный модуль «WTV020-microSD» с SD-flash картой, •трехколесная платформа с моторами-редукторами, батарейка «Крона», •6 батареек типа АА, •трехконтактная кнопка. Сайт проекта: МУНО.РФ Глаза Глаза робота сделаны из двух LED-матриц LED-матрица представляет собой модуль из 64 светодиодов: 8 по горизонтали и 8 по вертикали. Управляются светодиоды микросхемой MAX7219. Схема подключения LED-матриц к “Arduino uno” Программа анимации глаз. В программе использован скетч А.Кузнецовой, который был доработан (добавлены новые элементы анимации). //Определение разъемов контроллера, к которым подключены LED-матрицы #define Din 12 #define Load 10 #define Clk 11 int leds = 0; char inputString[2]; // Массив, описывающий какие светодиоды должны гореть в шестнадцатиричном виде // Каждая строка описывает одно из состояний char data[][8]= { {0x3C,0x7E,0xff,0xE7,0xE7,0xff,0x7E,0x3C}, // 0 - ГЛАЗ центр закрашенный. {0x3C,0x7E,0xff,0xCF,0xCF,0xff,0x7E,0x3C}, // 1 - ГЛАЗ вверх. {0x3C,0x7E,0xCF,0xCF,0xFF,0xff,0x7E,0x3C}, // 2 - ГЛАЗ еще вверх. {0x3C,0x7E,0x9F,0x9F,0xFF,0xff,0x7E,0x3C}, // 3 - ГЛАЗ еще вверх. {0x3C,0x1E,0x9F,0xFF,0xFF,0xff,0x7E,0x3C}, // 4 - ГЛАЗ еще вверх. //Обратно {0x3C,0x7E,0x9F,0x9F,0xFF,0xff,0x7E,0x3C}, // 5 - ГЛАЗ вниз. {0x3C,0x7E,0xCF,0xCF,0xFF,0xff,0x7E,0x3C}, // 6 - ГЛАЗ еще вниз. {0x3C,0x7E,0xff,0xCF,0xCF,0xff,0x7E,0x3C}, // 7 - ГЛАЗ вниз. {0x3C,0x7E,0xff,0xE7,0xE7,0xff,0x7E,0x3C}, // 8 - ГЛАЗ центр. //вниз {0x3C,0x7E,0xFF,0xF3,0xF3,0xff,0x7E,0x3C}, // 9 - ГЛАЗ вниз. {0x3C,0x7E,0xFF,0xFF,0xF3,0xF3,0x7E,0x3C}, // 10 - ГЛАЗ еще вниз. {0x3C,0x7E,0xff,0xFF,0xF9,0xf9,0x7E,0x3C}, // 11 - ГЛАЗ вниз. {0x3C,0x7E,0xff,0xFF,0xF9,0xf9,0x78,0x3C}, // 12 - ГЛАЗ вниз. //Обратно {0x3C,0x7E,0xff,0xFF,0xF9,0xf9,0x7E,0x3C}, // 13 - ГЛАЗ вверх. {0x3C,0x7E,0xFF,0xFF,0xF3,0xF3,0x7E,0x3C}, // 14 - ГЛАЗ еще вверх. {0x3C,0x7E,0xFF,0xF3,0xF3,0xff,0x7E,0x3C}, // 15 - ГЛАЗ еще вверх. {0x3C,0x7E,0xff,0xE7,0xE7,0xff,0x7E,0x3C}, // 16 - ГЛАЗ центр. {0xFF,0x81,0x81,0x81,0x81,0x81,0x81,0xFF}, // 17-КВАДРАТ {0xFF,0x81,0x81,0x99,0x99,0x81,0x81,0xFF}, // 18-КВАДРАТНЫЙ ГЛАЗ {0x3C,0x42,0x81,0x99,0x99,0x81,0x42,0x3C}, // 21 -ГЛАЗ центр. {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}, //22 - закрыт {0x3C,0x42,0xB1,0xB1,0x81,0x81,0x42,0x3C}, //23 - ВЕРХ левый угол. {0x3C,0x42,0x81,0x8D,0x8D,0x81,0x42,0x3C}, //24 - ВНИЗ среднее положение {0x3C,0x42,0x81,0x81,0x8D,0x8D,0x42,0x3C}, // 25 -ВНИЗ направо {0x3C,0x42,0x81,0x81,0xB1,0xB1,0x42,0x3C}, // 26 -ВЕРХ направо угол {0x3C,0x42,0x81,0xB1,0xB1,0x81,0x42,0x3C}, // 27 -ВЕРХ средне {0x3C,0x42,0x81,0xE1,0xE1,0x81,0x42,0x3C}, // 28 -ВЕРХ высоко {0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C}, //29 - моргание. }; void setup() { //Устанавливаем пины Din,Load,Clk в режим выхода pinMode(Din, OUTPUT); pinMode(Load, OUTPUT); pinMode(Clk, OUTPUT); //Устанавливаем Decode Mode, Intensity, Scan Limit, Shutdown и Display Test, но сначала digitalWrite (Clk, 0); //первый такт устанавливаем в 0 // настраиваем Data16sent(0x09,0x00); //Decode Mode - без декодирования. Data16sent(0x0A,0x08); //Intensity - среднее свечение 17 из 32 Data16sent(0x0B,0x07); //Scan Limit - Используем все 8 катодов. Data16sent(0x0C,0x01); //используем режим Shutdown в Normal Mode. Data16sent(0x0F,0x00); //Display Test - Normal Mode. } void loop() { //Анимация глаз, между разными состояниями делаем задержки delay(100); FlashNow(0); delay(1000); FlashNow(1); delay(100); FlashNow(2); delay(100); FlashNow(3); delay(100); FlashNow(4); delay(1000); FlashNow(5); delay(100); FlashNow(6); delay(100); FlashNow(7); delay(100); FlashNow(8); delay(1000); FlashNow(9); delay(100); FlashNow(10); delay(1000); FlashNow(11); delay(100); FlashNow(12); delay(100); FlashNow(13); delay(100); FlashNow(14); delay(250); FlashNow(15); delay(100); FlashNow(16); delay(1000); FlashNow(17); delay(100); FlashNow(18); delay(1000); FlashNow(19); delay(1000); FlashNow(20); delay(100); FlashNow(21); delay(100); FlashNow(22); delay(100); FlashNow(23); delay(1000); FlashNow(24); delay(100); FlashNow(25); delay(100); FlashNow(26); delay(100); FlashNow(27); delay(1000); } ////////////////////////////////////////////////////////////////////////////////////////////// //Функция зажигает определенную комбинацию светодиодов по ее номеру из двумерного //массива data[][] void FlashNow(int sost) { //заполняем 8 столбцов матрицы for(int i=0;i<8;i++){ //готовим столбец-катод №1(меняется только последняя цифра,начинаем с 1, поэтому i+1) char temp='0x0'+(i+1); //зажигаем один i-ый солбец-катод в соответствии с данными массива data[][] Data16sent(temp,data[sost][i]); } } //Функция принимает 8 бит адреса и 8 бит данных, //отправляет и защёлкивает 16 бит посылку в MAX7219 void Data16sent (char adress, char data ){ digitalWrite(Load, 0); shiftOut(Din, Clk, MSBFIRST, adress); //первым уходит старший байт shiftOut(Din, Clk, MSBFIRST, data); //вторым младший digitalWrite(Load, 1); } Воспроизведение музыки Для воспроизведения музыки робот использует звуковой музыкальный модуль «WTV020microSD» с SD-flash картой. Этот модуль представляет собой аудио плеер, который может управляться кнопками «Воспроизведение», «Стоп», «Перемотка» либо программно. В роботе «Муно» управление плеером производится с помощью кнопок. Для хранения аудио файлов используется стандартная Micro-SD flash карта. В роботе установлена карта емкостью 1Гб. Формат звуковых файлов — AD4. Файлы должны быть названы 0001.ad4, 0002.ad4, 0003 .ad4 и так далее. На выходе подключен 16-омный динамик. WTV020-microSD Схема подключения модуля WTV020-SD в кнопочном режиме Улыбка Улыбка у робота сделана из 16 зеленых светодиодов. Так как у робота 16 зубов из светодиодов, для подключения их всех, стандартных выходов Arduino uno не хватает. Поэтому пришлось использовать два сдвиговых регистра 74HC595, подключенных каскадом. При таком подключении светодиодами занято только 3 выхода контроллера. Сдвиговый регистр 74НС595 Расположение контактов 74HC595 Номер пина 1-7, 15 8 9 10 11 12 Q1-Q7, Q0 GND Q7′ Q7′ SH_CP ST_CP 13 OE 14 15 DS Vcc Обозначение Функция Цифровые выводы регистра Земля Выход для подключения регистров каскадом Сброс значений регистра (при подаче сигнала LOW) Вход тактовых импульсов Синхронизация выходов Переключение выходов из высокоомного состояния в рабочий режим (при подаче сигнала LOW) и обратно (при подаче сигнала HIGH) Вход последовательных данных Питание +5V Подключение светодиодов с помощью сдвиговых регистров Подключение контактов сдвигового регистра к Arduino Uno Пины 1-7 соединены с анодами (длинными ножками) светодиодов, начиная со 2-го светодиода Пин 8 соединен с землей Пин 9 ни с чем не соединен Пин 10 соединен с +5 V Пин 11 соединен с 4-м пином Arduino Пин 12 соединен с 3-м пином Arduino . Также пин 12 соединен с землей через конденсатор 0.1 мкФ Пин 13 соединен с землей Пин 14 соединен с 2-м пином Arduino Подключение контактов сдвигового регистра к Arduino Uno Пин 15 соединен с анодом (длинная ножка) первого светодиода Пин 16 соединен +5 V Подключение второго регистра такое-же как и первого. Регистры соединены между собой пинами Q7′ — DS. Предупреждение об утечке газа Для предупреждения об утечке газа у робота есть нос. Он умеет определять содержание пропана, метана и бутана в воздухе. Носом роботу служит датчик газа MQ5. Датчик газа MQ5 Этот датчик чувствителен к природному газу (пропан, метан, бутан). При превышении значения, выдаваемого датчиком определенной величины, робот выдает звуковой сигнал. Звуковой сигнал выдается зуммером, подключенным к цифровому выходу №6 Arduino. Зуммер Подключение датчика газа: •Контакт GND (земля) датчика MQ5 подключен к контакту GND платы Arduino •Контакт VCС (питание) датчика MQ5 подключен к контакту +5V платы Arduino •Контакт I/O (данные) подключен к цифровому выходу №6 Arduino Подключение зуммера: •Контакт GND (земля) зуммера подключен к контакту GND платы Arduino •Контакт VCС (питание) подключен к контакту +5V платы Arduino •Контакт AOUT (данные) подключен к аналоговому входу А0 Arduino Зуммер Программа предупреждения об утечке газа: int mq5_analogPin = A0; //Определяем контакт, к которому подключен датчик газа MQ5 int mq5_value = 0; //Первоначальное значение датчика //Порог значения датчика газа, при котором выдается звуковой сигнал, если обнаружена //утечка газа const int threshold = 200; void setup() { //Открываем последовательный порт Serial.begin(9600); } void loop() { //Опрос датчика газа mq5_value = analogRead(mq5_analogPin); show_gas(mq5_value); } //Обработка значений датчика газа void show_gas(int value) { // Если значение датчика больше допустимого: if (value > threshold) { // Выдаем звуковой сигнал высотой 440Гц: tone(6, 440, 20); //Зуммер подключен к цифровому выходу №6 } //Отправляем значение датчика в последовательный порт Serial.println(value); } Предупреждение о пожаре Для предупреждения о пожаре робот имеет пожарный извещатель ИП 212-50М, который реагирует на появление дыма. Пожарный извещатель ИП 212-50М При пожаре он выдаст громкий звуковой сигнал. Питается пожарный извещатель от одной батарейки «Крона». Работает автономно. Движение Было решено, что робот будет двигаться на колесах. Для этого была выбрана круглая трехколесная платформа. Она имеет два больших колеса с моторами-редукторами и поворотный ролик. Управляет работой моторов программируемый контроллер Mindstorms RCX из набора «Mindstorms robotics invention»: Он питается от шести батареек AA 1,5 V. Батарейный отсек находится внутри контроллера. Чтобы присоединить контроллер RCX к платформе с колесами пришлось разрезать провод с контактами из набора Mindstorms и припаять его к моторам платформы. Вот что получилось: платформа с установленным контроллером. Программа для контроллера написана на языке «С++» в среде разработки «RobotC” task main() { while (true) { motor[motorA] = 40; motor[motorC] = 40; wait1Msec(1000); motor[motorA] = -40; motor[motorC] = 40; wait1Msec(300); motor[motorA] = 40; motor[motorC] = 40; } } Программа для контроллера «Arduino Uno» //Датчик газа int mq5_analogPin = A0; //Определяем выход, к которому подключен датчик газа MQ5 int mq5_value = 0; //Первоначальное значение датчика //Порог значения датчика газа, при котором выдается звуковой сигнал, если обнаружена //утечка газа const int threshold = 200; // минимальное значение датчика, когда подается звуковой сигнал //Глаза #define Din 12 #define Load 10 #define Clk 11 //Улыбка //Пин подключен к ST_CP входу 74HC595 int latchPin = 8; //Пин подключен к SH_CP входу 74HC595 int clkPin = 4; //Пин подключен к DS входу 74HC595 int dPin = 2; int leds = 0; char inputString[2]; // матрица состояний ГЛАЗА-индикатора 8х8 -одна строка - одно состояние char data[][8]= { {0x3C,0x7E,0xff,0xE7,0xE7,0xff,0x7E,0x3C}, // 0 - ГЛАЗ центр закрашенный. {0x3C,0x7E,0xff,0xCF,0xCF,0xff,0x7E,0x3C}, // 1 - ГЛАЗ вверх. {0x3C,0x7E,0xCF,0xCF,0xFF,0xff,0x7E,0x3C}, // 2 - ГЛАЗ еще вверх. {0x3C,0x7E,0x9F,0x9F,0xFF,0xff,0x7E,0x3C}, // 3 - ГЛАЗ еще вверх. {0x3C,0x1E,0x9F,0xFF,0xFF,0xff,0x7E,0x3C}, // 4 - ГЛАЗ еще вверх. //Обратно {0x3C,0x7E,0x9F,0x9F,0xFF,0xff,0x7E,0x3C}, // 5 - ГЛАЗ вниз. {0x3C,0x7E,0xCF,0xCF,0xFF,0xff,0x7E,0x3C}, // 6 - ГЛАЗ еще вниз. {0x3C,0x7E,0xff,0xCF,0xCF,0xff,0x7E,0x3C}, // 7 - ГЛАЗ вниз. {0x3C,0x7E,0xff,0xE7,0xE7,0xff,0x7E,0x3C}, // 8 - ГЛАЗ центр. //вниз {0x3C,0x7E,0xFF,0xF3,0xF3,0xff,0x7E,0x3C}, // 9 - ГЛАЗ вниз. {0x3C,0x7E,0xFF,0xFF,0xF3,0xF3,0x7E,0x3C}, // 10 - ГЛАЗ еще вниз. {0x3C,0x7E,0xff,0xFF,0xF9,0xf9,0x7E,0x3C}, // 11 - ГЛАЗ вниз. {0x3C,0x7E,0xff,0xFF,0xF9,0xf9,0x78,0x3C}, // 12 - ГЛАЗ вниз. //Обратно {0x3C,0x7E,0xff,0xFF,0xF9,0xf9,0x7E,0x3C}, // 13 - ГЛАЗ вверх. {0x3C,0x7E,0xFF,0xFF,0xF3,0xF3,0x7E,0x3C}, // 14 - ГЛАЗ еще вверх. {0x3C,0x7E,0xFF,0xF3,0xF3,0xff,0x7E,0x3C}, // 15 - ГЛАЗ еще вверх. {0x3C,0x7E,0xff,0xE7,0xE7,0xff,0x7E,0x3C}, // 16 - ГЛАЗ центр. {0xFF,0x81,0x81,0x81,0x81,0x81,0x81,0xFF}, // 17-КВАДРАТ {0xFF,0x81,0x81,0x99,0x99,0x81,0x81,0xFF}, // 18-КВАДРАТНЫЙ ГЛАЗ {0x3C,0x42,0x81,0x99,0x99,0x81,0x42,0x3C}, // 21 - ГЛАЗ центр. {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}, //22 - закрыт {0x3C,0x42,0xB1,0xB1,0x81,0x81,0x42,0x3C}, //23 - ВЕРХ левый угол. {0x3C,0x42,0x81,0x8D,0x8D,0x81,0x42,0x3C}, //24 - ВНИЗ средне. {0x3C,0x42,0x81,0x81,0x8D,0x8D,0x42,0x3C}, // 25 - ВНИЗ направо {0x3C,0x42,0x81,0x81,0xB1,0xB1,0x42,0x3C}, // 26 - ВЕРХ направо угол {0x3C,0x42,0x81,0xB1,0xB1,0x81,0x42,0x3C}, // 27 - ВЕРХ средне {0x3C,0x42,0x81,0xE1,0xE1,0x81,0x42,0x3C}, // 28 - ВЕРХ высоко {0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C}, //29 - НИЖНИЕ моргание. }; void setup() { //Датчика газа Serial.begin(9600); // open serial at 9600 bps //Глаза pinMode(Din, OUTPUT); pinMode(Load, OUTPUT); pinMode(Clk, OUTPUT); //Улыбка //устанавливаем режим OUTPUT pinMode(latchPin, OUTPUT); pinMode(clkPin, OUTPUT); pinMode(dPin, OUTPUT); bitSet(leds, 7); updateShiftRegister(); bitSet(leds, 6); updateShiftRegister(); bitSet(leds, 5); updateShiftRegister(); bitSet(leds, 4); updateShiftRegister(); bitSet(leds, 3); updateShiftRegister(); bitSet(leds, 2); updateShiftRegister(); bitSet(leds, 1); updateShiftRegister(); bitSet(leds, 0); updateShiftRegister(); //Глаза //Устанавливаем Decode Mode, Intensity, Scan Limit, Shutdown и Display Test, но сначала digitalWrite (Clk, 0); //первый такт устанавливаем в 0 // настраиваем Data16sent(0x09,0x00); //Decode Mode - без декодирования. Data16sent(0x0A,0x08); //Intensity - среднее свечение 17 из 32 Data16sent(0x0B,0x07); //Scan Limit - Используем все 8 катодов. Data16sent(0x0C,0x01); //используем режим Shutdown в Normal Mode. Data16sent(0x0F,0x00); //Display Test - Normal Mode. } void loop() { delay(100); //Глаза FlashNow(0); delay(1000); FlashNow(1); //Опрос датчика газа mq5_value = analogRead(mq5_analogPin); show_gas(mq5_value); delay(100); FlashNow(2); delay(100); FlashNow(3); delay(100); FlashNow(4); delay(1000); FlashNow(5); delay(100); FlashNow(6); delay(100); FlashNow(7); delay(100); FlashNow(8); delay(1000); FlashNow(9); delay(100); FlashNow(10); delay(1000); FlashNow(11); delay(100); FlashNow(12); delay(100); FlashNow(13); delay(100); FlashNow(14); delay(250); FlashNow(15); delay(100); FlashNow(16); delay(1000); FlashNow(17); delay(100); FlashNow(18); delay(1000); FlashNow(19); delay(1000); FlashNow(20); delay(100); FlashNow(21); delay(100); FlashNow(22); delay(100); FlashNow(23); delay(1000); FlashNow(24); delay(100); FlashNow(25); delay(100); FlashNow(26); delay(100); FlashNow(27); delay(1000); } ///////////////////////////////////////////////////////////////////////////////////////////////// //Глаза void FlashNow(int sost){ for(int i=0;i<8;i++){ char temp='0x0'+(i+1); Data16sent(temp,data[sost][i]); } } void Data16sent (char adress, char data ){ //Функция. Принимает 8 бит адреса и 8 бит //данных, //отправляет и защёлкивает 16 бит посылку в MAX7219 digitalWrite(Load, 0); shiftOut(Din, Clk, MSBFIRST, adress); shiftOut(Din, Clk, MSBFIRST, data); digitalWrite(Load,1); } ///////////////////////////////////////////////////////////////////////////////////////////////// //Улыбка void updateShiftRegister() { digitalWrite(latchPin, LOW); shiftOut(dPin, clkPin, MSBFIRST, (leds>>8)); shiftOut(dPin, clkPin, MSBFIRST, leds); digitalWrite(latchPin, HIGH); delay(50); } //Датчик газа void show_gas(int value){// Если значение датчика больше допустимого if (value > threshold) { // Выдаем звуковой сигнал высотой 440Гц: tone(6, 440, 5000); } //Отправляем значение датчика в последовательный порт Serial.println(value); }