Управление несколькими сервами через serial

zander
Offline
Зарегистрирован: 27.10.2012

Привет! Делаю проект для управления сервами по xbee. C одной стороы потенциометры, с другой - сервы. С одной сервой все получилось. А вот как быть с 2мя? Как через сериал отправить данные какой серве крутиться?

 

Мысли такие: нужны 2 переменные

1 - в которой хранится номер сервы,

2 - в которой хранится угол.

Но я не могу понять как это реализовать через сериал( Как отправлять данные побайтово? На стороне приемника должно быть что-то вроде if/case (в arduino IDE нет case? как можно его заменить? только if else?) которые определяют какой серве адресовать угол, ну и там уже крутить в теле.

Подскажите пожалуйста как это сделать?=)

Так же хотелось бы понять как все-таки serial работает, а конкретно Serial.print(println,write,read).

C avaiable тоже не ясно. Когда пишут if(Serial.available() == 1), что это значит? Проверка пришел 1 символ? или байт?

Еще думал о i2c. Но не знаю, поддерживают ли сервы i2c? И если да, то как узнать id сервы? Спасибо)

 

 

memfise
Offline
Зарегистрирован: 30.06.2012

Для начала ознакомтесь с http://arduino.ru/Reference там все достаточно подробно ррасписано, с небольшими примерами.

 

zander
Offline
Зарегистрирован: 27.10.2012

Я читал. Но про сериал мне не понятно  до конца. Опыт в программировании небольшой.

maksim
Offline
Зарегистрирован: 12.02.2012

Здесь на форуме уже наверное с десяток тем про управление через сериал чем либо и тем пяток про хВее так что поиском воспользуйтесь! А в Аппаратные вопросы посмотрите самую первую прикрепленную тему. 

maksim
Offline
Зарегистрирован: 12.02.2012

zander пишет:
C avaiable тоже не ясно. Когда пишут if(Serial.available() == 1), что это значит? Проверка пришел 1 символ? или байт?
Вы говорите что читали Программирование и спрашиваете чем отличается символ (char) от байта (byte) как то вы плохо читали или не читали вовсе. Символ и байт в памяти занимают 1 байт, но символ это знаковый тип переменной, а байт беззнаковый, то есть символ может принимать значения от -128 до 127, а байт от 0 до 255, но это все теже 8 бит, так что avaiable == 1 информирует вас о том что пришли 8 бит (1 байт) а какой тип будет у этих 8 бит после того как вы их прочитаете решать вам.

zander пишет:
Еще думал о i2c. Но не знаю, поддерживают ли сервы i2c? И если да, то как узнать id сервы? Спасибо)
Уж не знаю про какие сервы вы говорите, если ваша поддерживает i2c то значит поддерживает, а если вы говорите об обычных китайских сервах будь то аналоговых, будь то цифровых, то для этого есть библиотека Servo.

zander
Offline
Зарегистрирован: 27.10.2012

 Перечитал раздел прогаммирование, много прояснилось - спасибо Максим=)

Решил передавать данные массивами. Но почему то при передаче, крутиться только одна серва на стороне приемника. Сериал порт приемника не могу посмортеть, ардуино пишет "порт занят". Подскажите, плиз, в чем дело.

Передатчик:

int potPin1 = 0;
int potPin2 = 1;
int a[2];

void setup()
{
Serial.begin(9600);
}

void loop()
{
a[0] = map(analogRead(potPin1), 0, 1023, 0, 9);
a[1] = map(analogRead(potPin2), 0, 1023, 0, 9);

for (int i = 0; i < 2; i++)
{Serial.print(a[i]);
delay(400);
}
}

Приемник:

#include <Servo.h>

int a[2]; 
int pos[2];
int srvPin1 = 9;
int srvPin2 = 10;

Servo ServoOne, ServoSec;

void setup()
{
Serial.begin(9600);

ServoOne.attach(srvPin1);
ServoSec.attach(srvPin2);
}

void loop()
{
if(Serial.available()){

for(int i = 0; i < 2; i++)
{
a[i] = Serial.read() - '0';

pos[i] = map(a[i], 0, 9, 0, 180);

a[i] = constrain(pos[i], 0, 180);

delay(100);

if (i == 0)
ServoOne.write(a[i]);
else
ServoSec.write(a[i]);

Serial.println(a[i]);

}
}
Serial.flush();
} 
zander
Offline
Зарегистрирован: 27.10.2012

 Да и кстати, с версии 1.0 же serial.flush изменился. Почему то
while (Serial.available())
Serial.read();
не решает проблему. Приходится компилить в 0.22. 

Да и все-таки не могу понять как работает Serial.read. Написано: Cчитывает очередной доступный байт из буфера последовательного соединения.
Т.е. если я пишу int a = Serial.read(); в int запишется первый байт? А если я следом напишу int b = Serial.read(); то в и запишется второй байт?


zander
Offline
Зарегистрирован: 27.10.2012

 Сейчас код приемника такой:

#include <Servo.h>

int a[2], b[2]; 
int pos[2];
int srvPin1 = 9;
int srvPin2 = 10;

Servo ServoOne, ServoSec;

void setup()
{
Serial.begin(9600);

ServoOne.attach(srvPin1);
ServoSec.attach(srvPin2);
}

void loop()
{

if(Serial.available()){

for(int i = 0; i < 2; i++)
{
a[i] = Serial.read() - '0';

pos[i] = map(a[i], 0, 9, 0, 180);

b[i] = constrain(pos[i], 0, 180);

delay(100);

ServoOne.write(b[0]);
ServoSec.write(b[1]);

Serial.println(b[i]);


}
}
//Serial.flush();
}

Крутятся обе=) но порой меняются местами эмм как бы объясниться: ну скажем первый пот крутит первую серву, второй - вторую. Если выставить оба пота на ноль, а потом скажем крутить первый пот, то может крутиться вторая серва. Полагаю дело в 
ServoOne.write(b[0]);
ServoSec.write(b[1]);

Изначально писал тут

if (i == 0)
ServoOne.write(a[i]);
else
ServoSec.write(a[i]);

но крутилось не так как надо=)

Еще бы как-то оптимизировать с массивами.

У меня просто опыт в программировании почти нулевой, поэтому сорри за такие вопросы..

И еще почему то одна серва постоянно гудит. именно гудит, слышно когда стоит