Взяв за основу код примера MyAdder напишем код класса ArServo, для управления сервомашинкой, подключённой к Arduino.
Управление осуществляется через последовательный порт, по протоколу Firmata.
//
// пример объекта Urbi
//
#include <urbi/uobject.hh>
#include "serial/serial.h"
class ArServo: public urbi::UObject
{
public:
// конструктор
ArServo(const std::string& str);
~ArServo();
int init();
// переменные
urbi::UVar val;
urbi::UVar pin;
Serial sg;
// методы
int port(int port, int rate);
double set(int angle);
};
// конструктор - определяем достпные из Urbi переменные и функции
ArServo::ArServo(const std::string& s)
: urbi::UObject(s) // required
{
// доступ к пременным
UBindVar (ArServo, val);
UBindVar (ArServo, pin);
// доступ к функциям
UBindFunction (ArServo, port);
UBindFunction (ArServo, set);
UBindFunction(ArServo, init);
};
ArServo::~ArServo()
{
if(sg.IsConnected()){
sg.Close();
}
};
int ArServo::init()
{
pin=0;
return 0;
};
// открываем порт
int ArServo::port(int port, int rate=9600)
{
bool b = sg.Open(port, rate);
if(!b){
printf("[!] Error: cant open COM-port!\n");
return 1;
}
printf("[i] ok\n");
return 0;
};
// пакет Firmata
double
ArServo::set (int angle)
{
if(!sg.IsConnected()){
printf("[!] Error: open COM-port first!\n");
return 0;
}
char buf[3];
buf[0] = 0xE0 | (int)pin;
buf[1] = angle & 0x7F;
buf[2] = (angle >> 7) & 0x7F;
sg.Send(buf, 3);
Sleep(100);
val=angle;
return angle;
};
// загружаем объект
UStart(ArServo);
А вот какой скетч нужно загрузить в Arduino/CraftDuino (фактически — это немного модифицированный пример, поставляемый с библиотекой Firmata).
Данный скетч позволяет по протоколу Firmata управлять двумя сервомашинками, подключёнными к 7 и 8 цифровым портам контроллера Arduino/CraftDuino.
#include <Firmata.h>
#include <Servo.h>
Servo servo7; // объекты класса Servo
Servo servo8; // для работы с сервомашинками
// функция обрабатывающая аналоговые сообщения Firmata
void analogWriteCallback(byte pin, int value)
{
if(pin == 7)
servo7.write(value); // поворачиваем серву на угол value
if(pin == 8)
servo8.write(value);
}
void setup()
{
// устанавливаем версию протокола
Firmata.setFirmwareVersion(0, 2);
// задание функции-обработчика аналоговых сообщений
Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
servo7.attach(7); // указываем порт подключения сервы
servo8.attach(8);
Firmata.begin(9600); // инициализация библиотеки Firmata
}
void loop()
{
while(Firmata.available()) // если есть сообщения
Firmata.processInput(); // запускаем функции-обработчики
}
Однако, произодить инициализацию можно и нужно через конструктор.
В urbiScript такую роль выполняет функция init().
т.е. задав функцию инициализации в виде:
int init(int port, int rate);
можем написать:
int ArFirmata::init(int port, int rate)
{
pin=0;
return open(port, rate);
};
// открываем порт
int ArFirmata::open(int port, int rate=9600)
{
bool b = sg.Open(port, rate);
if(!b){
printf("[!] Error: cant open COM-port %d with rate %d!\n", port, rate);
return 1;
}
printf("[i] ok\n");
return 0;
};
и тогда порт будет открываться при создании нового объекта:
Комментарии (0)
RSS свернуть / развернутьТолько зарегистрированные и авторизованные пользователи могут оставлять комментарии.