Небольшой пример как взаимодействовать Windows приложению с Arduino. Передавать и получать данные через последовательный порт.
Скетч для Arduino
//переменная для получения значения с порта
String commandValue;
void setup() {
pinMode(13,OUTPUT);
Serial.begin(9600);
Serial.setTimeout(50);
}
void loop() {
//если в буфере есть значение, то получаем его
if(Serial.available()) {
commandValue = Serial.readString();
}
//если это значение равно on – то зажигаем светодиод на плате
if(commandValue == "on"){
digitalWrite(13,HIGH);
//если все удачно, то отвечаем что включили
Serial.println("on");
} else
//то же самое при отключении
if(commandValue == "off"){
digitalWrite(13,LOW);
Serial.println("off");
}
commandValue = "";
delay(10);
}
Приложение Windows Forms на с#
Форма
На форме четыре компонента:
ComboBox – ComboBoxPort (список доступных портов)
Button – buttonConn (копка для соединения/разъединения с Arduino)
Button – buttonOnOff (кнопка для отправки сообщения Arduino)
TextBox – textBoxRead (текстовое поле для приема сообщений от Arduino)
Код
namespace WindowsFormsArduinoConnect
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//функция для передачи строки в textBoxRead из потока
delegate void SetTextCallback(string text);
//функция вкл/откл кнонки buttonConn из потока
delegate void SetEnableCallback(bool en);
//поток для считывания значений с порта
private Thread readThread = null;
//семафор для подключения к Ардуино
bool isConn = false;
//ссылка на последовательный порт
SerialPort SP;
//при загрузке формы получаем все открытые порты и выводим их в comboBoxPort
private void Form1_Load(object sender, EventArgs e)
{
comboBoxPort.Items.Clear();
string[] portnames = SerialPort.GetPortNames();
if (portnames.Length != 0)
{
foreach (string portname in portnames)
{
comboBoxPort.Items.Add(portname);
}
comboBoxPort.SelectedIndex = 0;
}
}
//функция для соединения с Ардуино
private void ConnectToArduino()
{
if (comboBoxPort.GetItemText(comboBoxPort.SelectedItem) != "")
{
buttonConn.Enabled = false;
//создаем последовательны порт
SP = new SerialPort();
//задаем параметры порта. порт не открываем. открытие производится в потоке
SP.PortName = comboBoxPort.GetItemText(comboBoxPort.SelectedItem);
SP.BaudRate = 9600;
SP.DtrEnable = true;
SP.ReadTimeout = 5000;
SP.WriteTimeout = 500;
isConn = true;
buttonConn.Text = "disconnect";
buttonOnOff.Text = "on";
//создаем поток
readThread = new Thread(new ThreadStart(Read));
//запускаем его
readThread.Start();
//нужна пауза, соединение с последовательном портом не мгновенно
Thread.Sleep(1000);
buttonOnOff.Enabled = true;
}
}
//функция разрыва соединения
private void DisconnectToArduino()
{
buttonConn.Enabled = false;
isConn = false;
buttonConn.Text = "connect";
buttonOnOff.Enabled = false;
}
//событие при нажатии на кнопку соединения/разъеденения
private void buttonConn_Click(object sender, EventArgs e)
{
if (!isConn)
{
ConnectToArduino();
} else
{
DisconnectToArduino();
}
}
//при закрытие формы
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if(isConn) DisconnectToArduino();
}
//передача Ардуино команды on/off
private void buttonOnOff_Click(object sender, EventArgs e)
{
buttonOnOff.Enabled = false;
if (buttonOnOff.Text == "on" )
{
SP.Write("on");
} else
{
SP.Write("off");
}
}
//функция для передачи строки в textBoxRead из потока
private void SetText(string Text)
{
if (textBoxRead.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
Invoke(d, new object[] { Text });
} else
{
textBoxRead.Text += Text+ "\n";
textBoxRead.SelectionStart = textBoxRead.TextLength;
textBoxRead.ScrollToCaret();
}
}
//функция вкл/откл кнонки buttonConn из потока
private void SetEnable(bool en)
{
if (buttonConn.InvokeRequired)
{
SetEnableCallback d = new SetEnableCallback(SetEnable);
Invoke(d, new object[] { en });
}
else
{
buttonConn.Enabled = en;
}
}
//тело потока
public void Read()
{
//открываем соединения с портом
SP.Open();
SetEnable(true);
//пока открыто соединение считываем значение и вставляем его в textBoxRead
while (isConn)
{
try
{
string message = SP.ReadLine();
SetText(message);
}
catch (TimeoutException) { }
}
//при завершении потока, закрываем соединение с портом
SP.Close();
SetEnable(true);
}
//в зависимости от полученной команды от Ардуино выполняем код
string oldparam;
private void textBoxRead_TextChanged(object sender, EventArgs e)
{
oldparam = textBoxRead.Lines[textBoxRead.Lines.Length-2];
switch (oldparam)
{
case "on":
buttonOnOff.Text = "off";
buttonOnOff.Enabled = true;
break;
case "off":
buttonOnOff.Text = "on";
buttonOnOff.Enabled = true;
break;
}
}
}
}
Ссылки
Исходники - https://disk.yandex.ru/d/tocswQAynkXpXw