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

суббота, 2 апреля 2016 г.

EV3 Телеграф

Давненько мы не задавали жару в виде наших хитрых задачек  готовым "бонусным" роботам. Одной из интереснейших "домашних" EV3-моделей является BANNER PRINT3R, инструкцию по сборке и базовую программу для нее подготовил Ральф Хемпел. Этот робот умеет писать EV3 LEGO MINDSTORMS на чековой ленте, ловко доставая ее из рулона.


Мы долго думали, чем бы озадачить данного робота, какие интересные дополнения внести в конструкцию и вспомнили об одном из наших ранних проектов в цикле "Строим из микроконтроллеров" под названием "Азбука Морзе на базе Arduino":

Нам показалось, что будет очень интересно совместить распознавание кода Морзе с печатью распознанных букв на ленте - получится телеграф.



Конструкцию печатающего узла мы оставили практически без изменений, немного доработав ее под более широкую ленту (именно такая попалась нам в магазине). Блок EV3 разместили таким образом, чтобы хорошо был виден экран, добавили датчик-кнопку для ввода точек и тире. Исходную инструкцию по сборке BANNER PRINT3R можно посмотреть в разделе "Больше роботов" в домашней версии ПО или скачать здесь.



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



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

Скачать нашу программу можно по ссылке.

Общую схему работы нашего "EV3 Телеграфа" вы можете посмотреть на картинке ниже.


Распознаватель кода Морзе анализирует нажатия на датчик-кнопку, выделяет короткие и длинные нажатия, короткие паузы между элементами кода в буксе и длинные паузы между буквами. Далее приведен код распознавателя:

While "True"
    
  m[0] = 0
  m[1] = 0
  m[2] = 0
  m[3] = 0
  m[4] = 0
  m[5] = 0
  
  X = 0
  P = EV3.Time
  
  While  next_letter
    If Sensor.ReadPercent(1) > 50 Then
      If A = 0 Then
        A = EV3.Time
        Speaker.Note(100,"E5",10000)
        Program.Delay(50)
      EndIf
      P = EV3.Time  
    EndIf 
    
    If Sensor.ReadPercent(1) = 0 And A > 0 Then
      If B = 0 Then
        B = EV3.Time
        Speaker.Stop()
        Program.Delay(50)
      EndIf
      P = EV3.Time 
    EndIf
    
    If A > 0 And B > 0 Then
      T = B - A
      If T > 500 Then
        m[X] = 2
      Else
        m[X] = 1
      EndIf
      A = 0
      B = 0
      X = X+1
      P = EV3.Time
    EndIf
        
    If EV3.Time - P >= 2000 Or X > 5 Then 
      next_letter = "False"
    EndIf
        
  EndWhile 

В массив m мы записываем 1 для точек и 2 для тире. Остальные, невостребованные в букве элементы заполняются нулями.

Руководствуясь кодом Морзе для русского алфавита


мы закодировали коды Морзе для всех русских букв в массивы b1 .. b33

'a
b1[0] = 1
b1[1] = 2
b1[2] = 0
b1[3] = 0
b1[4] = 0
b1[5] = 0


b2[0] = 2
b2[1] = 1
b2[2] = 1
b2[3] = 1
b2[4] = 0
b2[5] = 0

После того, как получена длинная пауза или ведены все 6 символов кода буквы анализируем совпадение элементов массива m (буфера) с элементами массивов b1 .. b33 используя конструкцию вида

h = "True"
  For I = 0 To 5  
    If  m[i] <> b1[i] Then
      h = "False"
    EndIf    
  EndFor
  If h = "True" Then
    Speaker.Play(100,"EV3Telegraph/b1")
    LCD.BmpFile(1,0,0,"EV3Telegraph/b1")
    BO = 1

    BOprint()
  EndIf  

Данный код при совпадении массивов выводит на экран распознанную букву, произносит ее и запускает процедуру добавления в очередь печати:

Sub BOprint
  i = 0
  While O[i] <> 0 
    If O[i] <> 0 Then
      i = i + 1
    EndIf    
  EndWhile
  O[i] = BO
EndSub

Блок "драйвера" принтера работает с очередью печати, забирая первую букву, если очередь не пустая и выводит ее на печать

Sub Printer
  While  "True"
    If O[0] = 1 Then 
      b1()
      Clear()
    EndIf
    ...
    If O[0] = 32 Then 
      b32()
      Clear()
    EndIf 
  EndWhile
EndSub

После печати буквы она удаляется из очереди, а вся очередь сдвигается после этого влево, чтобы "драйвер печати".обработал следующую букву в очереди:

Sub Clear
  i = 0
  While O[i] <> 0 
    O[i] = O[i+1]
    i = i + 1    
  EndWhile  
EndSub 

Для печати буквы используем процедуры движения по осям MoveX() и MoveY()

Sub MoveX
  If  XM > 0 Then
    Motor.Move("C",-50,XM,"True")
  Else
    Motor.Move("C",50,-1 * XM,"True")
  EndIf  
EndSub

Sub MoveY
  If  YM > 0 Then
    Motor.Move("A",50,YM,"True")
  Else
    Motor.Move("A",-50,-1 * YM,"True")
  EndIf  
EndSub

Процедура MoveXY() позволяет рисовать наклонные линии

Sub MoveXY
  If YM > 0 Then
    For j = 1 To XM / 5
      Motor.Move("A",50,5,"True")
      Motor.Move("C",-50,-5,"True")
    EndFor  
  Else
    For j = 1 To XM / 5
      Motor.Move("A",-50,-5,"True")
      Motor.Move("C",-50,-5,"True")
    EndFor      
  EndIf  
EndSub

Для поднимания и опускания маркера (ручки) используем процедуру PenMotor()

Sub PenMotor
  tM = EV3.Time
  regulator = "True"
  If pen = "True" Then
    PM = 150
  Else
    PM = 0
  EndIf
  While regulator
    eM = PM - Motor.GetCount("B")
    vM = eM * kM
    Motor.Start("B",vM)
    If Math.Abs(Motor.GetCount("B") - PM) < 5 Then
      regulator = "False"
    EndIf
    If  EV3.Time - tM > 1000 Then
      regulator = "False"
    EndIf  
  EndWhile
  Motor.Stop("B","True")
EndSub

В качестве примера, чтобы нарисовать букву "И" требуется выполнить следующую последовательность вызова процедур:

Sub b9
  Y = 300
  MoveY()
  
  pen = "True"
  PenMotor()
  
  Y = -300
  MoveY()  
  
  Y = 300
  X = 300
  MoveXY()
  
  Y = -300
  MoveY()  
  
  pen = "False"
  PenMotor()  
  
  X = 100
  MoveX()
EndSub    

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

воскресенье, 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.


вторник, 27 октября 2015 г.

NXT 2.0 Printer с печатью растровых изображений

Cобираем LEGO-принтер по книге "The Unofficial LEGO MINDSTORMS NXT 2.0 Inventor's Guide" (David J. Perdue, Laurens Valk). Добавляем возможность печати произвольного растрового изображения, например из JPЕG-файла. Программа написана в среде EV3, конвертер из графического формата в формат данных EV3 - на Processing.

Программа и конвертер



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

Итак, в архиве вы найдете написанный нами конвертер на языке Processing. Он необходим, чтобы сконвертировать изображение JPG в формат NXT/EV3.

Скачать среду Processing можно тут.

Далее нужно подготовить изображение. Оно должно быть черно-белое, причем не содержать оттенков серого (пример ниже, правильное изображение - снизу).


Подготовленную картинку необходимо скопировать в папку конвертера. Далее скорректировать код на Processing:

Имя файла с картинкой

  img = loadImage( "in.jpg" );

Файл данных EV3
  output = createWriter("out.rtf");

размеры картинки
  size(140,140);

Запустить конвертер, получившийся файл out.rtf скопировать в блок NXT/EV3 используя менеджер памяти среды программирования.

В программе NXT_Printer.ev3 указать как называется файл с картинкой, без расширения, например out.

Пример печати с использованием нашей программы:





EV3 EL3CTRIC GUITAR + Bluetooth Arduino MIDI-сontroller

Превращаем бонусную модель EV3 "EL3CTRIC GUITAR" в беспроводную MIDI-гитару. Приемником и конвертером сигнала выступает плата Arduino. Нота или аккорд, сгенерированные, гитарой передаются по bluetooth, конвертируются arduino в MIDI протокол и передаются на выход - на любое MIDI-устройство (синтезатор, ПК-секвенсор и т.п.). Далее мы обрабатываем сигнал гитарными примочками и пускаем на гитарный комбик.

Программа


NXT Support Gunner + Bluetooth

XT Support Gunner - пушка с наведением в двух плоскостях, с возможностью стрельбы очередью - собрана из LEGO Mindsorms NXT 2.0. Робот управляется с компьютера из языка Python с использованием модулей nxt-python, PyBluez, pygame. На роботе запущен MotorControl, который принимает команды через Bluetooth.

Программа


понедельник, 26 октября 2015 г.

Санта и Рудольф

Команда проекта представляет вашему вниманию "новогоднего" робота из EV3 Santa and Rudolph.

Программа


NXT Jeep

Робот Джип собран по инструкции из книги David J. Perdue "The Unofficial LEGO MINDSTORMS NXT 2.0 Inventor's Guide" . Управляем джипом используя компьютерный руль и педали. Угол поворота колес полностью соответствует углу поворота руля, сила нажатия на педаль газа - мощности, подаваемой на ведущие колеса. Программа для управления написана на языке Python и выполняется на компьютере, который по каналу bluetooth передает сигналы управления на робота и опрашивает его датчики. Интересное в этой модели также то, что ведущими являются передние колеса (независимый привод) и это не мешает ими выполнять повороты.

программа


EV3 in-line skater

Строим робота "на роликовых коньках" из LEGO Mindstorms EV3. Он способен двигаться вперед, поворачиваться, хотя к его колесам нет привода от двигателей - он пытается повторить способ перемещения человека на роликах.


EV3 Rock Sequencer

Робо-секвенсор от Damien Kee пересобран из деталей LEGO EV3. Теперь он не просто пищит - он играет ураганный рок! Слушаем Smoke on the water в исполнении робота!

Наша программа


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