Servo и ошибка при передаче значения 128 градусов
- Войдите на сайт для отправки комментариев
Сб, 20/12/2014 - 17:24
Доброго времени суток! Проблема почти полностью описана в теме. Если подробнее: есть манипулятор с 4мя сервами (база, плече, локоть и кисть). Подключены они к Ардуино Уно. На Уне изначально был примерно такой скетч:
#include <Firmata.h> #include <Servo.h> Servo servo8; Servo servo9; Servo servo10; Servo servo11; void analogWriteCallback(byte pin, int value) { if ( pin == 8 ) { servo8.write(value); } if ( pin == 9 ) { servo9.write(value); } if ( pin == 10 ) { servo10.write(value); } if ( pin == 11 ) { servo11.write(value); } } void setup() { Firmata.setFirmwareVersion(0, 2); Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); servo8.attach(8); servo9.attach(9); servo10.attach(10); servo11.attach(11); Firmata.begin(9600); } void loop() { while(Firmata.available()) Firmata.processInput(); }
Отдельная програмка, написанная в Qt, передает через класс Serial значения углов. Примерно так:
#define FRST_PORT 8 #define SRVS_AMOUNT 4 #define DELAY1 10 #define DELAY2 500 void MainWindow::handler() { if (!outputFile->open(QIODevice::ReadOnly | QIODevice::Text)) { statusLbl->setText("Can't open file"); } while ( !outputFile->atEnd()) { QString str = outputFile->readLine(); QTextStream stream(&str); QList<int> intList; for (int i = 0; i < SRVS_AMOUNT; i++) { int number; stream >> number; intList.append(number); } uint8_t buf[3]; for (int i = 0; i < SRVS_AMOUNT; i++) { buf[0] = 0xE0 | (i + FRST_PORT); buf[1] = intList[i] & 0x7F; buf[2] = intList[i] >> (i + FRST_PORT) & 0x7F; serial->Send(buf, 4); Sleep(DELAY1); } Sleep(DELAY2); statusLbl->setText("Keep moving..."); } outputFile->close(); statusLbl->setText("Reading is finished"); }
Дальше, serial.Send() отправляет эту красоту в файл (com-порт).
Как я понимаю, проблема в том, что 01111111 = 127 - это обрабатывается, а 10000000 - 128 и больше - нет. То есть, 8й бит отдается под знак.
Внимание вопрос: как обработать эту ошибку?
Всем спасибо:)
Поковырял Firmata
значение передается двумя байтами(вначале старший, потом младший), а у вас что-то неясное ограниченное по 127 и не в нужном порядке:
другой протокол. Наверно нужно что-то вроде этого. И тип беззнаковый QList<uint16_t> intList
а байт команды совмещен с номером порта так:
С этим в вашем исходнике порядок.
Ух ты. Спасибо) Темный лес пока что работа с COM.
QList<uint16_t> intList ? Данные на на условие i>=0 && i<=180 проверяются на предыдущих этапах. Или я что-то неправильно понял? И какого типа buf? Может это таки он uint16_t?
uint8_t - 8 бит без знака тоесть 0x00...0xFF
uint16_t - 16 бит - 0x0000...0xFFFF
тоесть 8*2=16
2 байта дляпередачи инфы, содержащийся в одной переменной uint16_t.
2 байта, а не бита. Я туплю