0. Начало
1. Цифровой ввод — кнопка
2. Аналоговый вывод — Fading
3. Аналоговый ввод – потенциометр
4. Аналоговый ввод – осциллограф
5. Генерация звука – пьезоизлучатель.
6. Фоторезистор
7. Сенсор на светодиоде
8. Общение с Arduino — программирование работы с COM-портом.
Правильным местом с которого стоит начать своё изучение написание программ для взаимодействия с Arduino/CraftDuino является официальный сайт:
http://www.arduino.cc/playground/Main/InterfacingWithSoftware
— там приведены примеры работы с последовательным портом из разных языков и сред программирования.
Ниже рассмотрим примеры работы с Arduino на С, С++, С#, PERL и Python.
Arduino + C
http://todbot.com/blog/2006/12/06/arduino-serial-c-code-to-talk-to-arduino/
приводится в пример консольная POSIX C – программа, исходник которой можно скачать здесь
— программа может принимать и передавать данные на плату Arduino/Freeduino
Использование:
laptop% gcc -o arduino-serial arduino-serial.c laptop% ./arduino-serial Usage: arduino-serial -p [OPTIONS] Options: -h, --help Print this help message -p, --port=serialport Serial port Arduino is on -b, --baud=baudrate Baudrate (bps) of Arduino -s, --send=data Send data to Arduino -r, --receive Receive data from Arduino & print it out -n --num=num Send a number as a single byte -d --delay=millis Delay for specified milliseconds
Примечание:
Порядок параметров имеет значение! ‘-b’ нужно устанавливать перед указыванием порта ‘-p’.
Можно устанавливать несколько флагов для выполнения последовательности действий:
‘-d 2000 -s hello -d 100 -r’
Означает: «ждать 2 секунды, отправить ‘hello’, ждать 100msec, считать ответ»
Примеры использования:
1. Отправить в Arduino один ASCII-символ «6»
laptop% ./arduino-serial -b 9600 -p /dev/tty.usbserial -s 6
2. Отправить в Arduino строчку “furby”
laptop% ./arduino-serial -b 9600 -p /dev/cu.usbserial -s furby
3. Получить данные от Arduino
laptop% ./arduino-serial -b 9600 -p /dev/cu.usbserial -r read: 15 Hello world!
Данный пример показывает вывод данных от скетча serial_hello_world.pde
из проекта Spooky Arduino (Зловещий Ардуино).
Отправить ASCII-строчку “get” в Arduino и получить результат:
laptop% ./arduino-serial -b 9600 -p /dev/cu.usbserial -s get -r read: d=0
И немножко о внутреннем устройстве программы:
Там всего три интересных функции, которые показывают пример работы с последовательным портом на C:
int serialport_init(const char* serialport, int baud)
— получает имя порта («/dev/tty.usbserial»,»COM1″) и скорость работы, а возвращает файловый дескриптор открытого порта.
int serialport_write(int fd, const char* str)
– отправляет в порт (по файловому дескриптору) строчку данных
int serialport_read_until(int fd, char* buf, char until)
– считывает данные из последовательного порта в буфер, пока не встретит определённый символ (char until)
Arduino + C++ (using libSerial)
http://devlog.bigmonachus.org/2008/08/interfacing-arduino-with-c-and.html
Работа с последовательным портом с использованием библиотеки libSerial
libSerial работает в POSIX-системах (на Windows работать не будет)
подключение библиотеки:
#include < SerialStream.h > #include < iostream > #define PORT "/dev/ttyUSB0" // указывается порт, к которому подключена Arduino SerialStream ardu; using namespace std; using namespace LibSerial;
примеры работы:
void open() { ardu.Open(PORT); /*The arduino must be setup to use the same baud rate*/ ardu.SetBaudRate(SerialStreamBuf::BAUD_9600); ardu.SetCharSize(SerialStreamBuf::CHAR_SIZE_8); } int get(char out) { int res; char str[SOME_BIG_SIZE]; ardu << out; ardu >> str; sscanf(str,"%d",&res); return res; }
Ссылки:
Serial Programming Guide for POSIX Operating Systems
Arduino + C++ (for windows)
http://www.arduino.cc/playground/Interfacing/CPPWindows
по ссылке можно найти пример класса для работы с последовательным портом в системах на базе Windows:
SerialClass.h (header)
#ifndef SERIALCLASS_H_INCLUDED #define SERIALCLASS_H_INCLUDED #define ARDUINO_WAIT_TIME 2000 #include <windows.h> #include <stdio.h> #include <stdlib.h> class Serial { private: // дескриптор COM-порта HANDLE hSerial; // статус соединения bool connected; // различная информация о соединении COMSTAT status; // последняя ошибка DWORD errors; public: // инициализация с указанным COM-портом Serial(char *portName); // закрытие соединения //NOTA: по каким-то причинам не удаётся переподключиться // нужно перезапускать программу ~Serial(); // считываем данные в буфер – если nbChar больше, чем // число доступных байт – возвращает только // доступные данные // возвращает -1 при ошибке int ReadData(char *buffer, unsigned int nbChar); // записывает данные из буфера в порт // возвращает true при удаче bool WriteData(char *buffer, unsigned int nbChar); // возвращает статус соединения bool IsConnected(); }; #endif // SERIALCLASS_H_INCLUDED
Serial.cpp (source code file)
#include "SerialClass.h" Serial::Serial(char *portName) { // пока ещё не подключились this->connected = false; // пытаемся подключиться к порту посредством CreateFile this->hSerial = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // проверяем – было ли соединение успешным if(this->hSerial==INVALID_HANDLE_VALUE) { //если не было – выводим ошибку if(GetLastError()==ERROR_FILE_NOT_FOUND){ // печатаем ошибку printf("ERROR: Handle was not attached. Reason: %s not available.\n", portName); } else { printf("ERROR!!!"); } } else { // подключились – теперь устанавливаем параметры DCB dcbSerialParams = {0}; // считываем текущие параметры if (!GetCommState(this->hSerial, &dcbSerialParams)) { // если невозможно – говорим о неудаче printf("failed to get current serial parameters!"); } else { // устанавливаем параметры для соединения с Arduino dcbSerialParams.BaudRate=CBR_9600; dcbSerialParams.ByteSize=8; dcbSerialParams.StopBits=ONESTOPBIT; dcbSerialParams.Parity=NOPARITY; // применяем параметры if(!SetCommState(hSerial, &dcbSerialParams)) { printf("ALERT: Could not set Serial Port parameters"); } else { // отлично! Мы успешно подлючились :) this->connected = true; //ждём пока Arduino перезагрузится Sleep(ARDUINO_WAIT_TIME); } } } } Serial::~Serial() { // проверяем статус подключение if(this->connected) { // отключаемся this->connected = false; // закрываем дескриптор порта CloseHandle(this->hSerial); } } int Serial::ReadData(char *buffer, unsigned int nbChar) { // число считываемых байт DWORD bytesRead; // число байт, которое мы действительно хотим считать unsigned int toRead; // используем ClearCommError для получения информации о статусе последовательного порта ClearCommError(this->hSerial, &this->errors, &this->status); // проверяем – есть ли информация для считывания if(this->status.cbInQue>0) { // если количество данных меньше требуемого – считываем // столько, сколько есть if(this->status.cbInQue>nbChar) { toRead = nbChar; } else { toRead = this->status.cbInQue; } // Пытаемся считать нужное количество данных и //возвращаем число считанных байт при удачном завершении. if(ReadFile(this->hSerial, buffer, toRead, &bytesRead, NULL) && bytesRead != 0) { return bytesRead; } } // ничего не считали или где-то была ошибка – возвращаем -1 return -1; } bool Serial::WriteData(char *buffer, unsigned int nbChar) { DWORD bytesSend; // пытаемся записать значение буфера buffer в COM-порт if(!WriteFile(this->hSerial, (void *)buffer, nbChar, &bytesSend, 0)) { // если не получилось – получаем код ошибки и возвращаем false ClearCommError(this->hSerial, &this->errors, &this->status); return false; } else return true; } bool Serial::IsConnected() { // просто возвращаем статус соединения :) return this->connected; }
Пример использования:
#include <iostream> #include "SerialClass.h" #define COM_PORT "COM1" #define BUF_SIZE 256 int main() { Serial com1(COM_PORT); // обнуляем буфер char buf[BUF_SIZE]; for(int i=0;i<BUF_SIZE;i++) buf[i]='\0'; // считываем и выводим данные из порта com1.ReadData(buf,BUF_SIZE-1); std::cout <<buf<< std::endl; return 0; }
Данный пример тестировался в CodeBlocks
,но должен прекрасно работать и в Visual Studio 🙂
Arduino + C#
http://www.arduino.cc/playground/Interfacing/Csharp
.Net 2.0 предоставляет возможность просто работать с System.IO.Ports
— поэтому очень просто написать программу, например, которая будет принимать вводимую информацию с клавиатуры и перенаправлять её в порт.
using System; using System.IO.Ports; namespace test { class Program { static void Main(string[] args) { SerialPort port = new SerialPort("COM1", 9600); port.Open(); while (true) { String s=Console.ReadLine(); if (s.Equals("exit")) { break; } port.Write(s+'\n'); } port.Close(); } } }
Скомпилировать данный пример можно даже без сред разработки, а просто имея установленный .NET Framework. Для этого нужно перейти в директорию Framework-а – обычно это что-то вроде:
c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\
теперь нужно скопировать туда файл с программой на C# — пусть это будет
com-cs.cs
Чтобы скомпилировать — нужно выполнить команду:
csc com-cs.cs
Компилятор отработает и в директории появится исполняемый файл
com-cs.exe
Примеры:
C# with Arduino Duemilanove + Led On/Off/Pwm Control
C# + Arduino Duemilanove + RGB Led Control
Arduino + PERL
http://www.arduino.cc/playground/Interfacing/PERL
требуется модуль Device::SerialPort
# установка параметров COM-порта use Device::SerialPort; my $port = Device::SerialPort->new("/dev/tty.usbserial"); # 19200, 81N on the USB ftdi driver $port->baudrate(19200); $port->databits(8); $port->parity("none"); $port->stopbits(1);
Передача данных в порт:
$port->write("Whatever you feel like sending");
Получение данных от Arduino:
while (1) { # пытаемся получить данные из порта my $char = $port->lookfor(); # если данные есть – распечатываем :) if ($char) { print "Recieved character: $char \n"; } }
Arduino + Python
http://www.arduino.cc/playground/Interfacing/Python
работая в UNIX-подобных системах, с последовательным портом можно общаться, как с файлом – считывать и записывать данные.
Но есть кросплатформенная библиотека – pySerial
, которая делает эти операции более наглядными.
эта библиотека уже упоминалась в посте про осциллограф на ардуине
Однако, для её работы под Windows понадобится ещё
pyWin32
# # для работы с COM-портом нужна библиотека # pySerial, кроме того, под винду понадобится еще pyWin32 # import serial SERIAL_PORT = 'COM1' SERIAL_SPEED = 38400 ser = serial.Serial(SERIAL_PORT, SERIAL_SPEED) while 1: #s = ser.read() # считывается один байт s = ser.readline().strip() # считывается строка и убираются символы “\r\n” print s # печатаем на экран
писать данные в порт так же просто:
import serial ser = serial.Serial('/dev/tty.usbserial', 9600) ser.write('5')
Примеры:
если не хочется ничего ставить – можно посмотреть или использовать питоновский порт
arduino_serial.py
программы Tod E. Kurt-а arduino-serial.c
Arduino и IRC-бот на Python-е
Контроль Arduino с использованием HTML-форм на Python-е
Arduino + Processing
http://www.arduino.cc/playground/Interfacing/Processing
читать далее: 9. Аналоговый датчик температуры – LM335
Программа для управления портами Arduino/CraftDuino
По теме
Arduino, термины, начало работы
КМБ для начинающих ардуинщиков
Состав стартера (точка входа для начинающих ардуинщиков)
Arduino и Matlab
Arduino и LabVIEW
Processing и Arduino
openFrameworks и Arduino
0 комментариев на «“Практическое программирование Arduino/CraftDuino — общение с Arduino — программирование работы с COM-портом”»
Всем привет!
Кто нибудь пробовал работать с библиотекой LibSerial при написании программ в Linux???
Считываю из буфера порта всякую фигню, а программа «cu» всё читает идеально!..
Вопрос снимается, всё работает )))
Связка Arduino + C в AltLinux, показывает эффективные результаты!
При чтении информации из буфера, не забудьте его почистить (buf[i]).