Показаны сообщения с ярлыком Arduino. Показать все сообщения
Показаны сообщения с ярлыком Arduino. Показать все сообщения

воскресенье, 20 ноября 2016 г.

Проект выходного дня "Поющее ведро"

Вот уже много лет в самом укромном и скромном по своей площади месте в нашей квартире стоит старенький аналоговый радиоприемник. Стоит неприметно, на шкафу. Но стоит только войти в это маленькое, но часто посещаемое помещение, как он оживает и радует посетителя музыкой, обычно это "Радио на 7 холмах". Устроено все очень просто: свет включается автоматически, с использованием светильника со встроенным датчиком движения.


Включившись, светильник запускает вытяжной вентилятор и это самое радио. Вероятно годы берут свое и внутри "почти японского" маленького чуда высохли какие-то конденсаторы или что-то еще начало приходить в негодность и настройка на радиостанции стала все чаще сбиваться, вынуждая искать стул и крутить ручку настройки.

И вот тут-то и попался на глаза второй динамик, оставшийся от нашего большого железного робота. Решено было сделать незатейливую замену отжившему свое устройству, способную продолжить радовать нас музыкой в автоматическом режиме.

Итак динамик, Supra SSB-5, автомобильный, пять дюймов, 40-140 Вт.
В качестве воспроизводящего устройства мы будем использовать DFPlayer Mini, он имеет на борту 3Вт усилитель и поддерживает microSD карты объемом до 32 Гб. 
Казалось бы всего 3 Вт усилитель и такой мощный динамик - это бред, но практика показало обратное. Звучит эта связка вполне приятно, громкости для задуманного сценария использования хватает с избытком, а динамик выдает довольно сочный бас, в отличии от полуваттного спикера в старом радио.
Чтобы добавить дополнительную функциональность нашему устройству, воспользуемся Arduino Pro Mini (можно использовать любой аналог). 


Плата нам понадобится для запуска музыкальных треков в случайном порядке, для управлению режимами эквалайзера и громкостью. Не секрет, что в разное время суток, фоновый шум в городской квартире заметно отличается, поэтому мы добавим в нащу схему часы реального времени, чтобы включать музыку в разное время суток с разной громкостью, кроме этого ночью мы будем немного прибирать басы на эквалайзере. Модуль часов реального времени мы использовали вот такой, DS1302:


Питаться устройство будет от USB, в качестве источника питания мы использовали зарядку мобильного телефона, 5В 1А. Общая схема соединения всех компонентов такова:


Для работы с DFPlayer Mini потребуются библиотеки DFPlayer library V2.0 и SoftwareSerial. Для работы с часами DS1302 также потребуется соответствующая библиотека.

Платы мы закрепили на кусочке утеплителя, это самое быстрое и ленивое крепление, которое нам приходилось до этого делать. В тоже время оно вполне надежно для домашнего стационарного использования.



В качестве корпуса мы использовали ведерко из под шпатлевки, вышло довольно мило и герметично.



Код в скетча для Arduino у нас такой:

#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>
#include <stdio.h>
#include <DS1302.h>

namespace {

const int kCePin   = 7;  // Chip Enable
const int kIoPin   = 6;  // Input/Output
const int kSclkPin = 5;  // Serial Clock

DS1302 rtc(kCePin, kIoPin, kSclkPin);

}  // namespace


SoftwareSerial mySerial(10, 11); // RX, TX

void setup () {
Serial.begin (9600);
mySerial.begin (9600);
mp3_set_serial (mySerial);
        randomSeed(analogRead(4));
delay(300);  //wait 1ms for mp3 module to set volume
        
        Time t = rtc.time();

        // ночь, громкость на минимум, бас убираем
        if (t.hr < 5) {
          mp3_set_EQ (0);
          delay(100);          
 mp3_set_volume (10);
          delay(100);
 mp3_play (1);
        }

        // поздний вечер
        if (t.hr >= 22) {
          mp3_set_EQ (2);
          delay(100);          
 mp3_set_volume (15);
          delay(100);
 mp3_play (4);
        }

        // раннее утро
        if (t.hr >= 5 && t.hr < 8) {
          mp3_set_EQ (2);
          delay(100);
          mp3_set_volume (15);
          delay(100);
 mp3_play (2);
        }

        // позднее утро
        if (t.hr >= 8 && t.hr < 11) {
          mp3_set_EQ (2);
          delay(100);          
 mp3_set_volume (18);
          delay(100);
 mp3_play (2);
        }

        // вечер
        if (t.hr >= 20 && t.hr < 22) {
          mp3_set_EQ (2);
          delay(100);          
 mp3_set_volume (20);
          delay(100);
 mp3_play (4);
        }

        // день
        if (t.hr >= 11 && t.hr < 17) {
          mp3_set_EQ (2);
          delay(100);          
 mp3_set_volume (22);
          delay(100);
 mp3_play (3);
        }

        // ранний вечер
        if (t.hr >= 17 && t.hr < 20) {
          mp3_set_EQ (2);
          delay(100);          
 mp3_set_volume (20);
          delay(100);
 mp3_play (4);          
        }

        delay(500);
        while (analogRead(A0) < 430) {
          delay(100);    
        }          
}

void loop () {         
mp3_play (int(random(5,1024)));
        delay(100);
        while (analogRead(A0) < 430) {
          delay(100);    
        }  
}

При подаче питания по часам определяется текущий временной промежуток, "скрипучим голосом робота" произносится одна из фраз "Доброе утро", "Добрый день", "Добрый вечер", "Доброй ночи", заранее записанных в виде mp3 на карте microSD, предварительно громкость устанавливается в соответствующее времени суток значение. Далее играются музыкальные треки в случайном порядке до тех пор, пока есть питание (его отключит датчик движения, когда человек выйдет из помещения).

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


Если вы захотите повторить наш проект, то есть вариант не завязываться на внешний датчик движения, в корпус можно встроить модуль для Arduino, способный определять движение в ИК-диапазоне:

Из дополнительных возможностей, которые в скором времени уже хочется добавить:
  • Плавное повышение громкости с 0 до разрешенного в данный временной промежуток значения
  • Разная музыка в разное время суток, ночью - только спокойная классика, никакого металла!
  • Ваш вариант?


воскресенье, 10 июля 2016 г.

Большой железный робот. Часть 4. Добавим еще железа

Давненько не было вестей от нашего большого железного робота. Не смотря на плотный график подготовки к соревнованиям (ВРО) работы по проекту все же двигались, хотя и не так быстро, как нам хотелось бы. Вот так вот наш робот выглядит в данный момент:


Первым делом мы установили П-образный каркас, из того же алюминиевого профиля 25x25x2, из которого ранее собирали раму. Крепление каркаса выполнено Г-образными мебельными уголками и болтами М6. В высоту каркас от уровня пола в верхней точке - 65 см.



На каркас смонтировали сервоподвес с двумя степенями свободы, это будущая "шея" робота, этот механизм будет двигать головой. Голову планируем собирать в следующий раз, хотим смонтировать на ней камеру, микрофон, динамик-твиттер и антенны wi-fi.




Сервоприводы использовали с металлическими редукторами, MG995.


Электронные компоненты решили разделить на группы, разместив их в разных отсеках. Наш робот - учебный, поэтому важно чтобы все в нем было наглядным. Исходя из этого мы выделили следующие 4 группы компонентов:

1) "Силовой отсек" содержит драйверы двигателей, усилитель мощности звука. Об этих штуковинах мы писали в предыдущих частях статьи.





Так как эти компоненты достаточно прилично греются при работе, в отсеке предусмотрели активное охлаждение, программно завязанное на цифровой датчик температуры DS18B20. Вентилятор, управляемый через мосфет IRF530N, включается, когда температура в отсеке превышает 40 градусов и его обороты пропорциональны превышению температуры над этим порогом. 


2) "Отсек питания" содержит разводку силового питания, кнопку включения робота, предохранитель.



3) "Мозговой центр" содержит Raspberry Pi 2 и Arduino Mega 2560, соединенные по USB. В Raspberry Pi 2 вставлен Wi-Fi адаптер. Кроме этого здесь мы разместили датчики напряжения и силы тока. 




Дял получения стабильных 5В используем преобразователь DC-DC на 5А
Датчик напряжения позволит контролировать заряд батареи, чтобы не допустить слишком сильного ее разряда. 
Датчик силы тока ACS712 ACS712ELC-30A позволит контролировать потребление энергии роботом, на основании этих данных можно прогнозировать время, которое он еще сможет проработать, программно снижать токи потребления (замедлять моторы в режим экономии при низком заряде аккумулятора).


4) "Отсек управления сервоприводами". Здесь будут сосредоточены компоненты для управления сервоприводами "шеи" и, возможно, "рук" робота (манипуляторов). Кроме этого здесь планируется разместить электронный компас. Питание сервоприводам будет обеспечивать отдельный DC-DC преобразователь.




Монтажные отсеки соединены гофрированными трубками для проводов (сливной шланг для стиральной машины).


Каркас собран с использованием металлопластиковых труб, болтов и шпилек М6.




В процессе работы над дизайном корпуса попробовали использовать технологию "стеклоткань+эпоксидная смола" по болванке, склеенной из пенопласта и монтажной пены, но отказались от нее, корпус выходил слишком "монолитным". Вероятно для конечного устройства это будет неплохим вариантом, но нам пока хочется иметь быстрый доступ к любым компонентам робота. чтобы с удобством в них покопаться.



пятница, 20 мая 2016 г.

Датчик для LEGO Mindstorms EV3 своими руками

Если вам также как и нам не хватает возможностей стандартных датчиков EV3, не достаточно 4-х портов для датчиков в ваших роботах или вы хотите подключить к своему роботу какую-нибудь экзотическую периферию - эта статья для вас. Поверьте, самодельный датчик для EV3 - это проще чем кажется. "Крутилка громкости" из старого радиоприемника или пара гвоздей, воткнутых в землю в цветочном горшке в качестве датчика влажности почвы - отлично подойдут для эксперимента.

Удивительно, но каждый порт датчика EV3 скрывает в себе целый ряд различных протоколов, в основном это сделано для совместимости с датчиками NXT и датчиками сторонних производителей. Давайте рассмотрим как устроен кабель  EV3


Странно, но красный провод - это земля (GND), зеленый - плюс питания 4,3В. Синий провод - одновременно SDA для шины I2C и TX для протокола UART. Кроме этого синий провод - вход аналогово-цифрового преобразователя для EV3. Желтый провод - одновременно SCL для шины I2C и RX для протокола UART. Белый провод - вход аналогово-цифрового преобразователя для датчиков NXT. Черный - цифровой вход, для датчиков, совместимых с NXT - он дублирует GND. Непросто, не так ли? Давайте по порядку.

Аналоговый вход EV3


В каждом порту датчика есть канал аналогово-цифрового преобразователя. Он используется для таких датчиков, как Touch Sensor (кнопка), датчиков NXT Light Sensor и Color Sensor в режиме измерения отраженного света и внешней освещенности, NXT датчика звука и NXT-термометра.

Сопротивление в 910 Ом, подключенное согласно схеме сообщает контроллеру, что данный порт необходимо переключить в режим аналогового входа. В таком режиме к EV3 можно подключить любой аналоговый датчик, например от Arduino. Скорость обмена с таким датчикаом при этом может достигать нескольких тысяч опросов в секунду, это самый быстродействующий тип датчиков.

Датчик освещенности
Термометр

Датчик влажности почвы

Также можно подключить: микрофон, кнопку, ИК дальномер и многие другие распространенные сенсоры. Если для датчика не достаточно питания в 4,3В, можно запитать его от 5В от разъема USB-порта, расположенного на боковой стороне контроллера EV3.

Упомянутая выше "крутилка громкости" (она же переменный резистор или потенциометр) является отличным примером аналогового датчика - ее можно подключить вот так:



Для чтения значений с такого датчика в стандартной среде программирования LEGO необходимо использовать синий блок RAW

Протокол I2C


Это цифровой протокол, по нему работает например ультразвуковой датчик NXT, многие датчики Hitechnic, такие как IR Seeker или Color Sensor V2. Для иных платформ, например для Arduino, есть масса i2c-датчиков их вы тоже сможете подключить. Схема следующая:



Сопротивление 82 Ом рекомендованы LEGO Group, однако в разных источниках встречаются упоминания о 43 Ом и менее. На самом деле мы попробовли вообще отказаться от этих сопротивлений и все работает, по крайней мере "на столе". В реальном роботе, работающем в условиях различного рода помех, линии SCL и SDA стоит все же притянуть к питанию через сопротивления, как это указано на схеме выше. Скорость работы i2c в EV3 довольно невелика, примерно 10000 кбит/с, именно поэтому всеми любимый Hitechnic Color Sensor V2 такой тормозной :)

К сожалению для стандартного EV3-G от LEGO не существует полноценного блока для двухсторонней связи с i2c датчиком, но используя сторонние среды программирования, такие как RobotC, LeJOS или EV3 Basic можно взаимодействовать практически с любыми i2c датчиками.

Способность EV3 работать по i2c протоколу открывает интересную возможность для подключения нескольких датчиков к одному порту. I2C протокол позволяет поключить к одной шине до 127 подчиненных устройств. Представляете? По 127 датчиков к каждому из портов EV3 :) Более того, часто кучу i2c датчиков совмещают в одном устройстве, например на фото ниже датчик 10 в 1 (содержит компас, гироскоп, акселерометр, барометр и т.д.)


В очень любопытной статье от Dexter рассматривается способ превратить вашу Arduino в i2c датчик для EV3. Зачем это нужно? К плате Arduino могут быть подключены с десяток датчиков разных типов, даже таких, которые напрямую к EV3 подключить не удастся (например ультразвуковой дальномер HC-SR04 или RFID-сканер) и она будет отправлять данные с них на EV3, выступая в роли своеобразного конвертера в i2c. Как это сделать - читайте в статье по ссылке выше, там есть и исходные коды для Arduino и EV3-G блоки для чтения и даже записи данных (да-да, вы сможете щелкать своей 220В релюшкой прямо из EV3-программы). Мы проверили, это все отлично работает.


Как работать с i2c в среде EV3 Basic мы рассказывали в одной из предыдущих статей

UART


Почти все стандартыне EV3-датчики, за исключением Touch Sensor, работают по протоколу UART и именно поэтому они не совместимы с контроллером NXT, который хоть и имеет такие же разъемы, но на портах датчиков у него UART не реализован. Взгляните на схему, она немного проще, чем в предыдущих случаях:



UART-датчики автоматически согласовывают с EV3 скорость своей работы. Первоначально соединившись на скорости 2400 кбит/с они договариваются о режимах работы и скорости обмена, переходя затем на повышенную скорость. Типичные скорости обмена для разных датчиков 38400 и 115200 кбит/с.
LEGO реализовала в своих UART-датчиках довольно замысловатый протокол, поэтому сторонних датчиков, предназначенных изначально не для этой платформы, но совместимых с ней, не существует. Тем не менее этот протокол очень удобен для подключения "самодельных"
датчиков, на базе микроконтроллеров.
Для Arduino существует замечательная библиотека EV3UARTEmulation, написанная известным LeJOS-разработчиком Lawrie Griffiths, которая позволяет этой плате притвориться UART-LEGO-совместимым датчиком. В его блоге LeJOS News есть масса примеров подключения датчиков газа, IMU-сенсора и цифрового компаса с использованием данной библиотеки.

Ниже на видео - пример использования самодельного датчика. У нас нет достаточного числа оригинальных датчиков расстояния LEGO, поэтому один из датчиков на роботе мы используем самодельный:


Задача робота - стартовать с зеленой клетки, найти выход из лабиринта (красная клетка) и вернуться на место старта кратчайшим путем, не заезжая в тупики.

воскресенье, 27 марта 2016 г.

EV3 Basic: подключаемся к Arduino

Уже довольно давно Dexter опубликовали способ взаимодействия EV3 и Arduino с использованием протокола i2c через один из портов датчиков. Этот способ позволяет передавать с Arduino любые данные, например показания подключенных к ней датчиков и использовать их в программе на EV3. Возможна передача данных и в противоположном направлении, например из программы на EV3 можно управлять моторами и реле, подключенными к Arduino.



Все бы хорошо, но способ этот работает только на EV3-G, так как основан на применении специального программного блока для этой среды программирования.


Мы же программируем на EV3 Basic и хотим использовать все преимущества такого межплатформенного взаимодействия в этом языке, поэтому написали аналог данного блока в среде EV3 Basic, он довольно простой, посмотрите:

'//  EV3 Basic, код для взаимодействие с Arduino
'//  EV3 - I2C master, Arduino - I2C slave

MSGSZEV3 = 30
MSGSZSLV = 30
// EV3 порт, к которому подключена Arduino
I2CPORT = 4
// i2c адрес Arduino, в нашем примере 0x04          '
I2CSLVADDR = 4       '

// массив байт, который мы будем передавать на Arduino
sendarray = Vector.Init(MSGSZEV3, 0) 

// массив байт, который мы будем принимать с Arduino
recvarray = Vector.Init(MSGSZSLV, 0)

// далее выполняем в бесконечном цикле
While "True" 

  // Если нужно что-то отослать на Arduino - записываем это в массив sendarray
  sendarray[0] = 255

  // запускаем функцию взаимодействия по i2c, sendarray и принимаем данные
  recvarray = Sensor.CommunicateI2C( I2CPORT, I2CSLVADDR , MSGSZEV3 , MSGSZSLV ,  sendarray )
  
  // выводим на экран первый элемент массива recvarray 
  LCD.Text(1, 0, 0,  2,  recvarray[0])

  // необязательная задержка - чтобы успеть рассмотреть вывод на экран
  Program.Delay(100) 

  // очищаем экран
  LCD.Clear()  
  
EndWhile

На Arduino можно залить стандартный код от Dexter или, например, вот такой модифицированный нами скетч:

#include <Wire.h>

#define SLAVE_ADDRESS 0x04
void setup() 
{
    Wire.begin(SLAVE_ADDRESS);
    Wire.onReceive(receiveData);
    Wire.onRequest(sendData);
}
int pin,st,val=0,flag=0,index=0;
char buf[8];
byte b[1];
void loop()
{
  if(flag==1)
  {
    flag=0;
    Serial.println(pin);
    val=analogRead(pin);
    b[0] = map(val,0,1024, 100, 0);

  }
}

void receiveData(int byteCount)
{
    while(Wire.available()>0) 
    {
      pin=Wire.read();
      flag=1;
    }
}

void sendData()
{
  Wire.write(b,1);
}

Данный пример передает на EV3 данные с аналогового порта А0, пересчитав их в диапазон 0..100.

Конечно же, использовать можно не только Arduino Uno, как в примере от Dexter, но и более миниатюрные варианты плат, например мы использовали для теста Micro:

1. ИК-дальномер Sharp gp2y0a21yk0f, аналоговый, подключен к порту А0
2. Arduino Micro
3. Переходник на Mindstorms-кабель 
4-5. Для питания Arduino (и дальномера через нее) используется кабель microUSB (4), подключаем в боковой разъем EV3 блока (5). Питания от порта датчика не всегда хватает, такой способ более надежный.
6. Кабель датчика втыкается в свободный порт EV3.


среда, 16 марта 2016 г.

Соединяем EV3 и Arduino по Bluetooth



В наших предыдущих проектах, таких как "EV3 Bluetooth - гитара" и "Электроскрипка из LEGO EV3" мы использовали Bluetooth для передачи данных с EV3 на Arduino.

 


Если вы смотрели код нашей EV3 Bluetooth гитары, то видели как это было реализовано - мы не вдавались особо в тонкости Bluetooth протокола EV3. Пакет данных обрамлялся маркерами и отправлялся, на приемной стороне мы отбрасывали служебную информацию, заголовок пакета и из его тела извлекали строку, обрамленную маркерами. Такой способ передачи работает только в одну сторону, он довольно громоздкий и неудобный.

Мы долго ждали, пока кто-нибудь не напишет библиотеку для Arduino, позволяющую этой платформе полноценно взаимодействовать с EV3, но так и не дождались, поэтому решили написать такой инструмент сами. Надеемся он будет полезен Mindstorms-сообществу и пригодится в ваших проектах. 

Исходники  EV3 открыты и мы заглянули в них в поисках описания Bluetooth-протокола. Оказалось, что он неплохо прокомментирован и понятен. EV3 может отправлять и принимать через именованные майл-слоты три типа данных - числа, текст и логические значения.

Например, передавая текст "text" в удаленный слот с именем text вы отправите по Bluetooth последовательно 11000100819E05746578740005007465787400, а отправляя число -3,14 в слот с именем Numeric отправите 13000100819E084E756D65726963000400C3F548C0. Непонятно, правда? 

Чтобы не иметь дело с длинными  строками цифр мы публикуем ряд функций для Arduino, используя которые вы сможете общаться с вашим EV3. Мы не оформляли их в виде библиотеки, так как писали их в общем-то для собственных нужд.


Первым делом вы должны "спарить" ваш EV3 и Bluetooth-модуль, подключенный к Arduino и узнать имя модуля на стороне Arduino. Ваш EV3 не будет знать, что общается не с себе подобным, а с кучей микросхем и проводов, притворяющихся другим EV3. Это здорово, потому что общаться с Arduino вы  сможете из любого языка программирования для платформы EV3, который умеет работать с Bluetooth, будь то EV3-G, EV3 Basic или RobotC.

Например, на языке EV3-G код, который будет отправлять данные на Arduino будет выглядеть так:


Первый синий блок устанавливет соединение в Arduino-Bluetooth-модулем, в нем важно указать корректное имя модуля, которое вы ухнали при "спаривании". В данном примере мы отправляем логическое значение "Истина" в майл-слот с именем Status по нажатию кнопки, подключенной в первому порту.

Принимает данные с Arduino вот такая конструкция, Важно указать тип принимаемых данных и имя майл-слота.


Давайте смотреть скачанный по ссылке выше код.

Функция AskForEV3Message() опрашивает приемный буфер на предмет пакета данных, присланных с EV3. при их наличии она разбирает пакет и записывает в переменную in_message_type единицу, если пришло логическое значение, 2 - для числа и 3 - для текста. Если сообщения не было - в переменной будет 0. В случае наличия сообщения в переменную in_mailbox запишется имя слота, а в одну из переменных in_value_logic, in_value_numeric или in_value_chars - принятое значение, в зависимости от его типа в in_message_type.

Таким образом в программе вы можете использовать функцию приема данных AskForEV3Message()  с EV3 например таким образом:

AskForEV3Message();
if (in_message_type != 0) Serial.println(in_mailbox);
if (in_message_type == 1) Serial.println(in_value_logic);
if (in_message_type == 2) Serial.println(in_value_numeric);
if (in_message_type == 3) Serial.println(in_value_chars);

Смотрим дальше, теперь давайте отправим данные на удаленный EV3 из вашей Arduino-программы. Вы можете использовать три функция MakeLogicEV3Message, MakeNumericEV3Message и MakeTextEV3Message для отправки данных соответствующих типов, пример:

// отправляем в EV3-слот TestLogic истину
MakeLogicEV3Message("TestLogic", true);

// отправляем в в EV3-слот MyNumeric случайное число от 0 до 100
MakeNumericEV3Message("MyNumeric", (int)random(100));

// отправляем в в EV3-слот EV3Text строку "text_example"
MakeTextEV3Message("EV3Text", "text_example");

Давайте договоримся, что вы откроете код вашего будущего проекта также, как мы делаем это для вас. Удачи!

Самое популярное