Технический форум по робототехнике.
nefilim » 22 авг 2011, 15:23
Здравствуйте.
2 дня бьюсь над одной загадкой:
Требуется собрать входящие байты в одно целое число.
Вводим, к примеру 123
Вариант № 1:
char incoming;
char str[4];
int i=0;
void setup() {
Serial.begin(9600);
}
void loop() {
i=0;
while (Serial.available()) {
incoming = Serial.read();
if (incoming < '0' || incoming > '9') break;
str[i] = incoming;
i++;
// Serial.println(i);
}
if (i != 0)
{
str[i] = 0;
Serial.println(atoi(str));
}
}
Результат:
1
2
3
Вариант № 2:
char incoming;
char str[4];
int i=0;
void setup() {
Serial.begin(9600);
}
void loop() {
i=0;
while (Serial.available()) {
incoming = Serial.read();
if (incoming < '0' || incoming > '9') break;
str[i] = incoming;
i++;
Serial.println(i);
}
if (i != 0)
{
str[i] = 0;
Serial.println(atoi(str));
}
}
Результат:
1
2
3
123
Внимание! во втором примере итоговый результат выводимый Serial.println(atoi(str)); правильный!
Каким образом Serial.println(i); влияет на результат?
Мужики помогите! Уже все мозги сломал.
Заранее благодарен!
dccharacter » 22 авг 2011, 16:06
Вероятно пока ты выводишь символ в порт у тебя успевает прилететь второй и третий байты, поэтому у тебя while три раза проходит и потом один раз выполняется Serial.println(atoi(str)); В первом же случае у тебя Serial.println(atoi(str)); выполняется три раза.
linvinus » 22 авг 2011, 22:43
ошибка в логике программы,
while (Serial.available()) { отработает только один раз, т.к. скорость передачи данных много меньше скорости обработки этого цикла
фактически у вас
while (1) {
while (Serial.available()>0) {
...
}
print
}
Почитайте внимательно что возвращает Serial.available()
Исправить очень просто, если в нужном месте ещё проверять на количество принятых байт.
Grem » 22 авг 2011, 22:54
Короче надо так.
- Код: Выделить всё • Развернуть
if (Serial.available()>0)
{
delay(5);
serAva = Serial.available();
for (i=0; i<serAva; i++)
inputBytes[i] = Serial.read();
inputBytes[i] = '\0';
serial.println(atoi(inputBytesPtr));
}
linvinus » 22 авг 2011, 23:02
Ну сейчас все блеснут своими знаниями
))
Может устроим соревнование запустить оригинальную программу с минимальными изменениями?
По моим расчётам нужно дописать пять символов xx xxx в нужное место, но я не стал указывать своё решение, а подсказал в чём проблема, чтобы вызвать у автора вдохновение.
Вариантов много.
Grem » 22 авг 2011, 23:29
По моим расчётам нужно дописать пять символов xx xxx в нужное место
Могу поспорить, что дописав "хх ххх" в любое место программы лучше не станет.
Ну сейчас все блеснут своими знаниями
Зато не ЧСВ, как в вашем случае.
linvinus » 23 авг 2011, 09:05
>Могу поспорить, что дописав "хх ххх" в любое место программы лучше не станет.
С этим погорячился
уже поздно было, нужно поправить три символа и переместить одну строчку.
но и ваш способ
- Код: Выделить всё • Развернуть
if (Serial.available()>0)
{
delay(5);
serAva = Serial.available();
for (i=0; i<serAva; i++)
inputBytes[i] = Serial.read();
inputBytes[i] = '\0';
serial.println(atoi(inputBytesPtr));
}
Считает только то что прилетит за 5 миллисекунд, на скорости 9600 ничего нового не прилетит.
>Зато не ЧСВ, как в вашем случае.
Не понял.
nefilim » 23 авг 2011, 11:53
Мужики! Всем спасибо! Это действительно из-за скорости обработки и соотв скорости поступления данных из порта. Я действительно не до конца разобрался с Serial.available(). Она действительно выдает только кол-во байт в буфере. В Ардуино новичек. Все переписал под свои задачи.
А задача была простая, получать с другой Ардуино значения потенциометра через Xbee и управлять мотором.
Тему можно закрывать.
Спасибо всем!
пы.сы. Кстати кому интересно, могу выложить код - попинаете немного.
linvinus » 23 авг 2011, 12:10
Молодец! Если ты хочешь чтобы пинали то тебя запинают
Лучше изучать код серьёзных проектов, где решается аналогичная задача и мотать на ус.
Собственно что нужно было изменить чтобы код заработал.
- Код: Выделить всё • Развернуть
char incoming;
char str[4];
int i=0;
void setup() {
Serial.begin(9600);
}
void loop() {
while (Serial.available()) {
incoming = Serial.read();
if (incoming < '0' || incoming > '9') break;
str[i] = incoming;
i++;
// Serial.println(i);
}
if (i > 2) //на данные отводим три знака
{
str[i] = 0;
Serial.println(atoi(str));
i=0;
}
}
Но на мой взгляд это довольно криво
И delay лучше стараться вообще не использовать, вычислительной мощности и так мало.
nefilim » 23 авг 2011, 12:38
Где можно посмотреть код серьезных проектов? С удовольствием гляну!
linvinus » 23 авг 2011, 13:03