167 lines
3.9 KiB
Markdown
167 lines
3.9 KiB
Markdown
---
|
||
title: "📟 Работа с Serial в Gambas"
|
||
date: 2023-03-18T16:31:00+03:00
|
||
draft: false
|
||
tags: [serial, basic, arduino, tutorial]
|
||
---
|
||
|
||
## Задача
|
||
|
||
Получать и отправлять данные по **Serial** в Gambas.
|
||
|
||
## Что будет использоваться
|
||
|
||
1. UART устройство, в моём случае **Arduino Nano**.
|
||
2. Библиотека `AsyncStream.h` от **AlexGyver** для асинхронного чтения из Serial.
|
||
3. Arduino IDE для загрузки скетча в МК.
|
||
4. Среда Gambas, очевидно же.
|
||
|
||
## Код для Arduino
|
||
|
||
Показываю пример работы библиотеки `AsyncStream.h` со страницы на GitHub.
|
||
|
||
```c
|
||
#include "AsyncStream.h"
|
||
AsyncStream<100> serial(&Serial, '\n');
|
||
|
||
void setup() {
|
||
Serial.begin(9600);
|
||
}
|
||
|
||
void loop() {
|
||
if (serial.available()) {
|
||
Serial.println(serial.buf);
|
||
}
|
||
}
|
||
```
|
||
|
||
Код получает данные по `Serial` и сразу печатает его в обратно.
|
||
|
||
В своём случает я хочу, чтобы Arduino отправляла **PONG**,
|
||
если ей передать **PING**.
|
||
А также каждые 5 секунд отправляла сообщение в Serial.
|
||
|
||
```c
|
||
#include "AsyncStream.h"
|
||
|
||
// Объявление AsyncStream
|
||
// 50 -- значение задержки чтения
|
||
AsyncStream<50> serial(&Serial, '\n');
|
||
|
||
// таймер для хранения значения millis()
|
||
unsigned long timer = 0;
|
||
|
||
void setup() {
|
||
Serial.begin(9600);
|
||
}
|
||
|
||
void loop() {
|
||
if (serial.available()) {
|
||
if (strcmp(serial.buf, "ping") == 0) {
|
||
Serial.println("PONG");
|
||
}
|
||
}
|
||
|
||
if (millis() - timer > 5000) {
|
||
Serial.println("Every 5 sec message");
|
||
timer = millis();
|
||
}
|
||
}
|
||
```
|
||
|
||
## Код для Gambas
|
||
|
||
Подключение к Serial
|
||
|
||
```basic
|
||
' Переменная порта
|
||
Public SerialDevice As New SerialPort
|
||
|
||
' Метод подключения к порту
|
||
Public Sub SerialDeviceConnect() As Boolean
|
||
Dim Port As String = "/dev/ttyUSB0"
|
||
|
||
' если есть подключение к порту, завершаем функцию
|
||
If SerialDevice.Status Then Return False
|
||
|
||
Print "Connecting to " & Port
|
||
|
||
SerialDevice.PortName = Port
|
||
SerialDevice.Speed = "9600"
|
||
SerialDevice.Parity = 0
|
||
SerialDevice.DataBits = "8"
|
||
SerialDevice.StopBits = "1"
|
||
SerialDevice.FlowControl = 0
|
||
|
||
Try SerialDevice.Open()
|
||
If Error Then Print "ERROR: Bad address"
|
||
|
||
End
|
||
|
||
' Метод, который вызывает подключение к Serial
|
||
Public Sub DeviceConnectButton_Click()
|
||
|
||
SerialDeviceConnect()
|
||
|
||
End
|
||
```
|
||
|
||
Таймер, который вызывает чтение из Serial и печает полученные данные
|
||
|
||
```basic
|
||
' Таймер
|
||
Public Sub LogTimer_Timer()
|
||
|
||
If SerialDevice.Status Then
|
||
Dim SerialText As String = SerialRead()
|
||
|
||
If SerialText.Len > 0 Then Print SerialText
|
||
Endif
|
||
|
||
End
|
||
```
|
||
|
||
Метод, который получает данные из Serial и печатает их
|
||
|
||
```basic
|
||
' Метод получения команд из Serial
|
||
Public Sub SerialRead() As String
|
||
|
||
Dim RxLen As Integer ' Длина полученных данных
|
||
Dim Rx As String ' Полученная строка
|
||
|
||
Try Read #SerialDevice, Rx, Lof(SerialDevice)
|
||
If Error Then
|
||
Return
|
||
Else
|
||
RxLen = InStr(Rx, Chr(13))
|
||
|
||
If RxLen > 0 Then
|
||
Return Replace$(Rx, "\n", "")
|
||
Endif
|
||
Endif
|
||
|
||
End
|
||
```
|
||
|
||
Метод, который отправляет команду в Serial
|
||
|
||
```basic
|
||
' Отправка команд в Serial
|
||
Public Sub SerialWrite(Text As String)
|
||
|
||
Try Write #SerialDevice, Text
|
||
If Error Then Print "Ошибка"
|
||
|
||
End
|
||
```
|
||
|
||
```basic
|
||
' Метод, который вызывает подключение к Serial
|
||
Public Sub DeviceSendButton_Click()
|
||
|
||
SerialWrite("ping")
|
||
|
||
End
|
||
```
|