• Если вы хотите, чтобы код было легко и быстро писать — делайте его сразу удобным для чтения.

Arduino и Raspberry Pi

С появлением библиотеки LitDev в MS Small Basic открылась масса новых возможностей. Одна из таких возможностей — взаимодействие с устройствами Arduino и Raspberry Pi. Здесь мы приводим две вводных статьи, позволяющих в общих чертах понять принципы взаимодействия с устройствами Arduino и Raspberry Pi с использованием MS Small Basic.

MS Small Basic и Arduino

Arduino это дешевый и популярный способ собрать свою собственную электронику, в том числе робототехническую — с небольшими датчиками и двигателями, и немного изучить программирование для управления ею. Управление ей с помощью MS Small Basic позволяет отображать получаемые данные или изменять настройки в интерактивном режиме с вашего компьютера.

Взаимодействовать с Arduino с помощью Small Basic можно, используя класс для работы с последовательным портом, в данном случае LDCommPort в расширении LitDev (класс LDCommPort). Также, возможно использование класса LDHID. По сути, мы можем отправлять и получать данные в виде байтов или строк в Arduino-устройство, подключенное к компьютеру через USB-соединение. Здесь используются строки, так как мы всегда можем преобразовать их в любое другое значение, например, в числа.

Вы можете использовать любой формат для своих данных, но вам понадобится использовать событие (LDCommPort.DataReceived) в Small Basic, чтобы обнаружить, что данные были получены. В программе Arduino не требуется никаких событий, поскольку она работает в непрерывном цикле, вы просто проверяете наличие новых данных при каждом проходе цикла.

Отправка данных в Arduino из Small Basic

При отправке данных в Arduino первый символ использовался для определения типа данных:

i — для целого числа
f — для числа с плавающей точкой
s — для строки
1-8 — для одной из 8 кнопок, созданных в интерфейсе Small Basic.

Отправка данных в Small Basic из Arduino

При отправке данных из Arduino в Small Basic можно просто отправлять любые данные, которые нужно, в виде строки в кодировке ASCII, проверяя целые числа, числа с плавающей запятой, строки и символы. Можно использовать символ перевода строки ‘\ n’ (ASCII-код 10), в качестве признака завершения передачи всех данных. Этот символ автоматически добавляется командой Arduino Serial.println, но не Serial.print.

Программа на MS Small Basic

Сама программа расположена в официальном репозитории Small Basic по адресу http://smallbasic.com/program/?VBZ059

Здесь мы также приводим её текст.

Initialise()
'
'==================================================
'MAIN LOOP
'==================================================
'
While ("True")
    If (newData <> "") Then
        tbData = Text.Append("Data received : "+newData+nl,Controls.GetTextBoxText(tb))
        Controls.SetTextBoxText(tb,tbData)
        newData = ""
    EndIf
    Program.Delay(10)
EndWhile
'
'==================================================
'SUBROUTINES
'==================================================
'
Sub Initialise
    gw = 600
    gh = 215
    GraphicsWindow.Width = gw
    GraphicsWindow.Height = gh
    GraphicsWindow.Title = "Small Basic Arduino Interface"
    GraphicsWindow.BackgroundColor = "Gray"
    GraphicsWindow.BrushColor = "Black"
    nl = Text.GetCharacter(10)
    '
    status = LDCommPort.OpenPort("COM3",9600)
    LDCommPort.SetEncoding("Ascii")
    LDCommPort.DataReceived = OnDataReceived
    '
    nButton = 8
    spacing = (gw-30)/nButton
    width = (gw-40)/nButton-10
    For i = 1 To nButton
        buttons[i] = Controls.AddButton("Action"+i,20+spacing*(i-1),175)
        Controls.SetSize(buttons[i],width,25)
        LDShapes.BrushColour(buttons[i],"SteelBlue")
    EndFor
    Controls.ButtonClicked = OnButtonClicked
    '
    clear = Controls.AddButton("Clear",20,20)
    Controls.SetSize(clear,width,25)
    LDShapes.BrushColour(clear,"SteelBlue")
    '
    send = Controls.AddButton("Send",20+spacing,20)
    Controls.SetSize(send,width,25)
    LDShapes.BrushColour(send,"SteelBlue")
    '
    value = Controls.AddTextBox(20+2*spacing,20)
    Controls.SetSize(value,gw-2*spacing-40,25)
    LDShapes.PenColour(value,"White")
    LDShapes.BrushColour(value,"DimGray")
    '
    tb = Controls.AddMultiLineTextBox(20,60)
    Controls.SetTextBoxText(tb,"Connection status : "+status)
    Controls.SetSize(tb,gw-40,100)
    LDShapes.PenColour(tb,"White")
    LDShapes.BrushColour(tb,"DimGray")
EndSub
'
'==================================================
'EVENT SUBROUTINES
'==================================================
'
Sub OnDataReceived
    dataIn = Text.Append(dataIn,LDCommPort.RXAll())
    If (Text.IsSubText(dataIn,nl)) Then
        newData = LDText.Trim(dataIn)
        dataIn = ""
    EndIf
EndSub
'
Sub OnButtonClicked
    button = Controls.LastClickedButton
    If (button = clear) Then
        tbData = ""
    ElseIf (button = send) Then
        val = Controls.GetTextBoxText(value)
        If (val = Math.Round(val)) Then
            tbData = Text.Append("*** "+val+" sent as integer ***"+nl,Controls.GetTextBoxText(tb))
            val = "i"+val
        ElseIf (val+0 = val) Then
            tbData = Text.Append("*** "+val+" sent as float ***"+nl,Controls.GetTextBoxText(tb))
            val = "f"+val
        ElseIf (val <> "") Then
            tbData = Text.Append("*** "+val+" sent as string ***"+nl,Controls.GetTextBoxText(tb))
            val = "s"+val
        Else
            tbData = Text.Append("*** Nothing sent ***"+nl,Controls.GetTextBoxText(tb))
        EndIf
        If (val <> "") Then
            LDCommPort.TXString(val)
        EndIf
    Else
        For i = 1 To nButton
            If (button = buttons[i]) Then
                tbData = Text.Append("*** Action "+i+" instruction sent ***"+nl,Controls.GetTextBoxText(tb))
                LDCommPort.TXString(i)
            EndIf
        EndFor
    EndIf
    Controls.SetTextBoxText(tb,tbData)
EndSub

Программа Arduino

Ниже приведен код для Arduino, которые можно использовать для Arduino UNO, обратите внимание, что он использует порт COM3 (у вас он может быть другим) и программатор ArduinoISP.

Код Arduino написан на языке C. В интернет существует множество примеров для всех видов электронных проектов. Этот код компилируется и отправляется в Arduino с помощью специальной Arduino IDE. Данный образец просто тестирует описанную связь между Arduino и Small Basic, без всякой электроники. Код мог бы быть короче, если бы вы просто хотели отправлять данные в Small Basic или иметь только пару кнопок (размер кода довольно ограничен на Arduino), но в данном случае стояла задача протестировать различные типы данных при обмене данными.

Команда Serial.begin(9600) устанавливает скорость связи для последовательного порта, также установленную в Small Basic, LDCommPort.OpenPort («COM3», 9600) — для синхронизации при передаче данных.

Команда Serial.setTimeout(10) предотвращает использование частичных данных, вам может потребоваться изменить это. Если вы читаете байты, подумайте об использовании Serial.available() в цикле while для чтения всех доступных байтов.

char cInput;
int iInput;
float fInput;
String sInput;
void setup()
{
        Serial.begin(9600);
        Serial.setTimeout(10);
}

void loop()
{
	Input();
	delay(10);
}

void Input()
{
	sInput = Serial.readString();
	cInput = '0';
	if (sInput.length() > 0)
	{    
		cInput = sInput.charAt(0);
		switch (cInput)
		{
			case 'i':
				iInput = sInput.substring(1).toInt();
				Serial.println(iInput);
				break;
			case 'f':
				fInput = sInput.substring(1).toFloat();
				Serial.println(fInput);
				break;
			case 's':
				sInput = sInput.substring(1);
				Serial.println(sInput);
				break;      
			case '1':
				fInput = 3.14;
				Serial.println(fInput);
				break;
			case '2':
				iInput = random(256);
				Serial.println(iInput);
				break;
			case '3':
				Serial.println("A text result");
				break;
			case '4':
				Serial.print('A');
				Serial.print('B');
				Serial.println('C'); 
				break;
			default:
				Serial.println("Error");
				break;
		}
	}
}

Другие примеры программ для взаимодействия с Arduino можно посмотреть тут: https://docs.microsoft.com/ru-ru/archive/blogs/smallbasic/small-basic-arduino-sample-programs

Оригинал статьи на английском: https://docs.microsoft.com/ru-ru/archive/blogs/smallbasic/small-basic-arduino

Дополнительно

Статья о способе взаимодействия EV3 и Arduino (EV3-G) с использованием протокола i2c через один из портов датчиков.

Статья «EV3 Basic: подключаемся к Arduino» с помощью EV3 Basic.

Статья о связи EV3 и Arduino через Bluetooth.

 

Small Basic и Raspberry Pi

Представим себе, что мы хотели бы включать и выключать свет, используя программу на Small Basic: это — простейшая классическая задача для встроенных систем.

Есть несколько способов реализовать такую ​​систему. Для этого в световой контроллер мы встроили микрокомпьютер с последовательным портом RS-232. Затем мы подключили кабель от последовательного порта на нашем устройстве к последовательному порту на компьютере с MS Windows, возможно, с разъёмом 25-9 контактов, перекрестным кабелем, адаптером нуль-модема и т.п. Затем мы попытаемся определить скорость передачи данных, настройки четности, а также, какой именно последовательный порт на нашем компьютере. После установки расширения LitDev для поддержки последовательного порта мы теперь можем управлять светом из Small Basic, отправляя команды через последовательный порт на контроллер освещения.

Проблемы с различными кабелями, разъёмами и ограничениями скорости передачи данных для последовательных портов привели в своё время к появлению USB (универсальной последовательной шины), которая стандартизировала кабели и увеличила скорость передачи данных на порядки. Но у USB есть свои специфические проблемы, в том числе тот факт, что устройства могут располагаться по разным адресам в зависимости от того, к какому порту они подключены. Но теперь можно встроить микрокомпьютер с USB-портом в контроллер света и в конечном итоге заставить его работать из Small Basic с помощью расширения LitDev.

Ещё один вариант — встроить микрокомпьютер с проводным или беспроводным Ethernet-контроллером в контроллер освещения. Если на микрокомпьютере работает мини-веб-сервер с чем-то вроде CGI-интерфейса, то можно легко отправлять ему команды из веб-браузера или из Small Basic, используя объект Network.

Raspberry Pi

Существуют сотни плат микрокомпьютеров, которые можно использовать для такого сервера устройств. Мы можем сузить область, сконцентрировавшись только на тех, которые хорошо поддерживаются и стоят менее 30 долларов. Одним из самых популярных в этой линейке является Raspberry Pi. Их продано более пяти миллионов экземпляров. Raspberry Pi доступен в пяти производственных моделях (A, B, A+, B+, 2B). Модели B и B+ имеют два или четыре порта USB и встроенный проводной Ethernet. Модели A и A+ имеют только один порт USB и не имеют встроенной сети, но стоят меньше и потребляют значительно меньше энергии. Оригинальные модели A и B имеют 26-контактный разъем расширения. Модели A+ и B+ имеют 40-контактный разъем расширения (26 контактов из которых такие же, как у A и B). Самая последняя модель Raspberry Pi 2 Model B механически совместима с B+, но имеет более быстрый четырехъядерный процессор и вдвое больше оперативной памяти.

Raspberry Pi Model A+ является наименее дорогим и наиболее энергоэффективным членом семейства с рекомендованной розничной ценой в 20 долларов США. Нам нужно только добавить беспроводной адаптер Ethernet (рекомендуется Edimax EW-7811U), карту micro-SD для загрузки операционной системы и источник питания micro-USB, что немного увеличит общую стоимость системы.

Интерфейсные разъемы на A+ — это: порт micro USB (только для источника питания + 5 В), пара разъемов для плоского кабеля для модулей ЖК-дисплея и камеры, разъем видеовыхода HDMI, разъем для аудио/видео 3,5 мм, один порт USB-хоста и 40-контактный разъем расширения J8. Также мы установили карту micro-SD на 2 гигабайта и беспроводной Ethernet-адаптер Edimax EW-7811U.

Операционная система Raspbian Linux

Обычная операционная система для Raspberry Pi — это Raspbian Linux, который по сути представляет собой Debian Linux, перекомпилированный для процессора в Raspberry Pi. Его необходимо установить на карту micro-SD, которая затем вставляется в Raspberry Pi. Карта micro-SD должна быть отформатирована с двумя разделами: небольшой раздел файловой системы DOS FAT, содержащий загрузочные файлы, и более крупный раздел файловой системы ОС Linux, содержащий остальную часть операционной системы.

Raspbian Linux — это одновременно сильная и слабая сторона Raspberry Pi. Благодаря наследию Unix, он невероятно мощный для такого маленького компьютера. Обратной стороной является то, что для встраиваемой системы без управления (без клавиатуры или дисплея) Raspbian Linux оставляет желать лучшего. Установка, настройка и администрирование — нетривиальная задача. Раздел операционной системы может быть поврежден, если система не выключена должным образом. Кроме того, ячейки флэш-памяти на карте micro-SD со временем изнашиваются. SD-карты дешевы и просты в использовании, они предназначены для записи фотографий и тому подобного, а не для разделов постоянно работающей операционной системы.

MuntsOS

MuntsOS — это крайне урезанный дистрибутив операционной системы Linux. Он поставляется в виде одного файла образа ядра Linux со встроенной в него корневой файловой системой. Когда ядро ​​загружается на целевом компьютере, оно распаковывает новую копию корневой файловой системы в оперативную память и использует ее там. Raspberry Pi загружается с карты micro-SD, но после завершения загрузки он больше не получает доступ к карте micro-SD. Это дает несколько преимуществ. Во-первых, файловая система в оперативной памяти (RAM-диск) очень быстрая, намного быстрее, чем карта micro-SD. Во-вторых, MuntsOS нельзя повредить, отключив питание без надлежащего завершения работы. Каждый раз, когда Raspberry Pi загружается, он распаковывает новую чистую копию корневой файловой системы из образа ядра. В-третьих, он обычно ничего не записывает на карту micro-SD, что помогает избежать износа ячеек флэш-памяти на карте.

The Thin Server

Шаблон проектирования системы, называемый The Thin Server, по сути является инверсией концепции «тонкого клиента», которую Sun Microsystems и другие компании начали продавать ещё в конце 20-го века. Идея, лежащая в основе JavaStation и других устройств тонких клиентов, заключалась в перемещении как можно большей сложности программного обеспечения и вычислительной мощности с клиентского компьютера на сервер. Клиентский компьютер должен был быть не более чем сетевым интерфейсом для мыши, клавиатуры, монитора и звука. Все прикладное программное обеспечение пользователя работает на сервере, где им можно централизованно управлять.

Напротив, The Thin Server — это не что иное, как сетевой интерфейс для одного устройства ввода-вывода. В идеале The Thin Server создается на дешевом и широко распространенном сетевого микрокомпьютере, таком как, например, Raspberry Pi. Программное обеспечение должно легко устанавливаться с ПК пользователя или с Mac без использования каких-либо специальных инструментов программирования. Он должен иметь возможность работать без подключения к сети и администрироваться через сеть. Он должен выживать без регулярных отключений и не должен много записывать на флэш-носители. Он должен предоставлять сетевой API с использованием HTTP в качестве оптимального протокола взаимодействия.

MuntsOS, операционная система которая полностью работает в оперативной памяти, хорошо подходит для The Thin Server, к тому же, эти две концепции развивались вместе последние несколько лет.

GPIO

Интерфейс GPIO — это соединения, доступные на микрокомпьютерах, таких как Raspberry Pi. Провода шины интерфейса GPIO передают цифровые сигналы (вкл. / Выкл. Или высокий / низкий или двоичный 1/0) между микрокомпьютером и внешним устройством. Вывод GPIO может быть настроен как вход, то есть сигнал идёт от внешнего устройства к микрокомпьютеру, или как выход, то есть сигнал идёт от микрокомпьютера к внешнему устройству.

Операционная система Linux нумерует контакты GPIO от 0 (GPIO0, GPIO1, …). Обратите внимание, что номер контакта Linux GPIO обычно не соответствует никакому физическому номеру контакта. Некоторые процессоры могут иметь сотни доступных контактов GPIO. Linux рассматривает каждый вывод как отдельное устройство ввода-вывода. Raspberry Pi Model A+ имеет несколько контактов GPIO, а также питание и землю для разъема расширения J8.

Контакты GPIO Raspberry Pi представляют собой сигналы 3,3 В, что означает, что выходы переключаются между землей и + 3,3 В, а входы не должны подключаться к напряжениям ниже уровня земли или выше + 3,3 В. Они не могут обеспечивать очень большую мощность и почти всегда будут нуждаться в каком-либо усилителе для работы реальных устройств, таких как двигатели и фонари. Возможно подключить один светодиод к выводу GPIO, но это не рекомендуется. Используйте какой-нибудь усилитель, например ULN2003A.

Обратите внимание, что некоторые из контактов GPIO Raspberry Pi имеют альтернативные функции. Например, GPIO14 и GPIO15 также можно использовать для организации последовательного порта. Такие контакты могут быть недоступны для GPIO.

Для экспериментов удобно подключить Raspberry Pi к макетной плате с помощью адаптера, такого как, например, Adafruit T-Cobbler Plus Jump через разъём расширения J8.

The Thin Server для GPIO

Настроить The Thin Server Raspberry Pi GPIO очень просто. Просто скачайте zip-файл по адресу: http://repo.munts.com/muntsos/thinservers/muntsos-gpio-server-RaspberryPi.zip и разархивируйте его на отформатированную карту micro-SD с файловой системой FAT32. ZIP-файл содержит файл образа ядра MuntsOS, а также ряд других двоичных и текстовых файлов, необходимых Raspberry Pi для загрузки. Он включает поддержку беспроводного сетевого адаптера Edimax EW-7811U (и других, использующих аналогичные наборы микросхем Realtek).

Затем отредактируйте текстовый файл:  autoexec.d/00-wlan-init  на карте micro-SD, чтобы настроить имя хоста The Thin Server, сетевой идентификатор SSID и ключ шифрования. Извлеките карту micro-SD из нашего ПК или Mac и вставьте ее в гнездо в нижней части платы Raspberry Pi. Когда мы включим Raspberry Pi, он загрузит MuntsOS с карты micro-SD и подключится к беспроводной сети.

Обнаружение IP-адреса, полученного Raspberry Pi, может оказаться сложной задачей. Самый простой способ узнать его адрес — воспользоваться службой Apple Bonjour MDNS, которая является частью пакета iTunes для Windows, но также может быть установлена ​​отдельно. The Thin Server Raspberry Pi GPIO зарегистрируется как hostname.local, где hostname — это любое имя, которое мы написали в 00-wlan-init (или RaspberryPi-MuntsOS.local по умолчанию). Если DHCP-сервер назначает Raspberry Pi имя хоста, имя newhostname.local также будет зарегистрировано, где newhostname — это первая часть вновь назначенного имени хоста.

Например, если вы напишете foo в качестве имени хоста в 00-wlan-init, а локальный DHCP-сервер впоследствии назначит имя хоста bar.munts.net, Raspberry Pi ответит как на foo.local, так и на bar.local.

Без MDNS найти IP-адрес будет сложнее. Если у вас есть административный доступ к DHCP-серверу беспроводной сети, вы можете получить от него назначенный IP-адрес. В худшем случае вы можете подключить клавиатуру и дисплей (HDMI) к Raspberry Pi, войти в систему (пользовательский root, пароль по умолчанию) и запустить команду ifconfig, чтобы узнать его IP-адрес.

API сервера GPIO

Веб-сервер, работающий на The Thin Server GPIO, отвечает на запросы следующего вида:

http://servername:8083/GPIO/ddr/n,s Set data direction (0=input, 1=output)

http://servername:8083/GPIO/get/n Get pin (state 0=OFF, 1=ON)

http://servername:8083/GPIO/put/n,s Put pin (state 0=OFF, 1=ON)

где servername — это IP-адрес или имя хоста, n — номер контакта GPIO (пронумерованный операционной системой Linux), а s — новое состояние 0 или 1. В качестве примера приведена следующая последовательность запросов, отправленных из браузера на The Thin Server Raspberry Pi GPIO настроит GPIO26 (который является выводом 37 разъёма расширения J8) в качестве выхода и включит его:

http://foo.local:8083/GPIO/ddr/26,1

http://foo.local:8083/GPIO/put/26,1

Собираем все вместе

Для подключения одного светодиода к разъёму расширения Raspberry Pi A+ J8 используется ULN2003A. Сигнал GPIO26 управляет переключателем низкого напряжения ULN2003A, который служит для усиления тока, достаточного для включения светодиода. Нагрузка, такая как светодиод, должна быть подключена между положительным напряжением питания (+ 3,3 В от Raspberry Pi в данном случае) и одним из выходов ULN2003A. Плоская сторона светодиода или более короткий вывод подключается к контакту 10 ULN2003A, а круглая сторона или более длинный вывод подключается к резистору 220 Ом.

Пример программы для включения и выключения светодиода из Small Basic доступен в репозитории Small Basic по адресу  http://smallbasic.com/program/?PCD388-0.

Здесь мы также приводим её текст.


' Lay out GUI
GraphicsWindow.Width = 300
GraphicsWindow.Height = 130
GraphicsWindow.Title = "LED Control Program"
GraphicsWindow.Show()
GraphicsWindow.DrawText(40, 30, "Server:")
ServerBox = Controls.AddTextBox(100, 28)
ConnectButton = Controls.AddButton("Connect", 120, 80)
Controls.ButtonClicked = ButtonHandler
The second section is the button handler subroutine, which contains the bulk of the program logic:
' Everything interesting happens in the button handler subroutine
Controls.ButtonClicked = ButtonHandler
Sub ButtonHandler
  b = Controls.LastClickedButton
  c = Controls.GetButtonCaption(b)
  If c = "Connect" Then
    servername = Controls.GetTextBoxText(ServerBox)
    pin = 26
    direction = 1
    PutDDR()
    data = 0
    PutGPIO()
    Controls.SetButtonCaption(b, " ON ")
  EndIf
  If c = " ON " Then
    pin = 26
    data = 1
    PutGPIO()
    Controls.SetButtonCaption(b, " OFF ")
  EndIf
  If c = " OFF " Then
    pin = 26
    data = 0
    PutGPIO()
    Controls.SetButtonCaption(b, " ON ")
  EndIf
EndSub
' The last section of the program contains subroutines that wrap the HTTP server API:
' Write GPIO data direction bit
  
' Parameter variables:
' servername -- IP address or host name
' pin -- GPIO pin number (2-26, as numbered by Linux)
' direction -- 0 for input, 1 for output
Sub PutDDR
  webpage = Network.GetWebPageContents("http://" + servername + ":8083/GPIO/ddr/" + pin + "," + direction)
  
  If Text.StartsWith(webpage, "DDR" + pin + "=") Then
  Else
    GraphicsWindow.ShowMessage(webpage, "GPIO Server Error")
  EndIf
EndSub
' Read GPIO data bit
  
' Parameter variables:
' servername -- IP address or host name
' pin -- GPIO pin number (2-26, as numbered by Linux)
' data -- Set to 0 or 1
Sub GetGPIO
  webpage = Network.GetWebPageContents("http://" + servername + ":8083/GPIO/get/" + pin)
   
  If Text.StartsWith(webpage, "GPIO" + pin + "=") Then
    data = Text.GetSubTextToEnd(webpage, Text.GetIndexOf(webpage, "=") + 1)
  Else
    GraphicsWindow.ShowMessage(webpage, "GPIO Server Error")
  EndIf
EndSub
' Write GPIO data bit
' Parameter variables:
' servername -- IP address or host name
' pin -- GPIO pin number (2-26, as numbered by Linux)
' data -- 0=OFF (low), 1=ON (high)
Sub PutGPIO
  webpage = Network.GetWebPageContents("http://" + servername + ":8083/GPIO/put/" + pin + "," + data)
  If Text.StartsWith(webpage, "GPIO" + pin + "=") Then
  Else
    GraphicsWindow.ShowMessage(webpage, "GPIO Server Error")
  EndIf
EndSub

Оригинал статьи на английском: https://social.technet.microsoft.com/wiki/contents/articles/30188.small-basic-and-the-raspberry-pi.aspx



Поделиться: