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


2 комментария:

  1. А зачем такой огород ради одного датчика? Этот шарп же можно напрямую к еве3 подключить с одним только резистором. И скорость работы будет гораздо выше, чем по I2C.

    ОтветитьУдалить
    Ответы
    1. Почему же одного. Это в примере он один. А подключить можно хоть десяток и все на один порт EV3.

      Удалить

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