---
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
```
