пятница, 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, поэтому один из датчиков на роботе мы используем самодельный:


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

понедельник, 18 апреля 2016 г.

Немного о футболе роботов WRO gen.III. Часть 3

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


Как мы выяснили ранее, угол, при котором будет достигнута точка схода с "орбиты" и направление на ворота соперников зависят от расположения мяча на поле. Если принять направление на ворота соперников за 0 градусов, то точка схода с орбиты при движении робота вокруг мяча против часовой стрелки будет достигнута при 90 градусах, а при движении по часовой стрелке - при -90 градусах относительно направления на ворота.


В разных точках поля меняться будет только направление на ворота соперников, а указанное соотношение углов будет сохраняться. Но это все хорошо в теории, в реальных условиях один из углов легко может быть например 78 градусов, а другой -104. Это обусловлено как мы уже обсуждали ранее несовершенством датчика-компаса и магнитными наводками.
Таким образом для каждой точки поля (или его выделенной зоны) нам необходимы заранее сохраненные в памяти робота направления на ворота соперников и пара точек схода. Сколько будет таких точек (зон) - зависит от требуемой точности наведения на ворота (и, следовательно, разрешения воображаемой системы координат, делящей поле на зоны).


Очевидно, что чем рассматриваемая зона поля ближе к воротам соперников и чем она дальше от "горизонтальной" оси поля (напомним, что мы рассматриваем поле как 2D плоскость), тем угол "атаки" будет больше, см. рис. (a > b)

Теперь давайте поговорим о том, каким образом нападающий должен установить в какой конкретно точке (зоне) поля он находится, чтобы начать работать в соответствии с углами, актуальными для данной точки. Снова обратимся к регламенту и вспомним, что нападающий может иметь на борту дальномер, обращенный вправо, а измерять расстояние им он может только в направлении правого борта (относительно своих ворот), см. рис


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

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

Действительно, вратарь, стоя в защите, располагает информацией об удаленности мяча (приблизительной) и угле, образованном направлением на мяч и направлением на ворота соперников:


Зная данный угол вратарь может определить точку поля (зону) в которой находится в данный момент мяч и передать ее координаты нападающему.

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


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

суббота, 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    

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

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

Немного о футболе роботов WRO gen.III. Часть 2

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


Вооружившись познаниями в геометрии или онлайн-калькулятором прямоугольных треугольников можно рассчитать углы, при которых робот должен сходить с орбиты в каждой точке поля. Поле удобно представить в виде воображаемой координатной сетки, разбив его на нужное вам количество зон - в зависимости от требуемой точности наведения на ворота. На изображении выше для примера приведена разбивка на 9 зон, имеющих координаты от (1,1) до (3,3).
Для каждой зоны будет две точки схода - для движения вокруг мяча по часовой стрелке и против. Отслеживать точку схода удобно по компасу, сравнивая текущий азимут с требуемым с учетом некоторой заданной погрешности.
Но тут нас поджидает неприятность - дело в том, что цифровой компас Hitechnic - устройство несовершенное, и даже после тщательной калибровки в связи с наличием наводок на поле показания будут распределены по окружности неравномерно, в каком-то направлении "градусы будут чаще", в каком-то реже (см. рис).


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

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

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


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

Положим точки схода роботу удалось достичь и он, развернувшись, смотрит прямо на мяч. Какие его дальнейшие действия? Как ему узнать, что на "линии его взгляда" - вражеские ворота, а перед ним мяч? На второй вопрос можно получить ответ смотря на показания ИК-поисковика, он должен быть в зоне 5, а вот с первым - опять не все так просто. На разных точках поля направление на центр ворот соперников - различно. Как быть?

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


В главе 6 "От джойстика до футбола" онлайн курса Сергея Филиппова "Основы робототехники" автор предлагает интересный способ забить мяч в ворота - сначала робот движется на мяч, а как только до него остается совсем небольшое расстояние - движется на ворота, тем самым направляя и подталкивая мяч в их направлении.

Как долго роботу следует это делать? Ответ на этот вопрос робот может получить из следующих источников:
- ИК-поисковик (мяч не на линии движения робота)
- Компас (движение не в направлении ворот соперников)
- Энкодеры и таймер ("атака"слишком затянулась).

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

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





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


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