Прием и передача массива по uart
- Войдите на сайт для отправки комментариев
Чт, 20/02/2014 - 17:03
Уважаумые форумчане, помогите решить вопрос по приему и передачи массива значений. Написал скетчи, а работать не хочет. Делаю дистанционное управление танком, это проба передачи данных управления. Передача:
byte buf[6]; void setup() { Serial.begin(9600); } void loop() { buf[0] = map(analogRead(0), 0, 1023, 0, 254); buf[1] = map(analogRead(1), 0, 1023, 0, 254); buf[2] = map(analogRead(2), 0, 1023, 0, 254); buf[3] = digitalRead(A3); buf[4] = digitalRead(A4); buf[5] = digitalRead(A5); Serial.write(0xff); // synchronize for (int i=0; i < sizeof(buf); i++) { Serial.write(buf[i]); } }
Прием:
int out[2]; char buf[5]; void setup() { Serial.begin(9600); out[0] = (9); out[1] = (10); out[2] = (11); for (int q = 3; q <= 5; q++) { pinMode(q, OUTPUT); digitalWrite(q, LOW); } } void loop() { if (Serial.available()>sizeof(buf)) { byte x = Serial.read(); if (0xff == x) // sync byte { for (int i =0; i <= 5; i++) { x = Serial.read(); analogWrite(out[i],x); digitalWrite(i,x); } } } }
Подскажите пожал
вот на передачу.
я честно сказать точно не помню как пишется. но там что то вроде должно быть.
максим тебе точно скажет как там правильно пишется
Передатчик вроде работает, в мониторе ком порта данные идут нормально. Мне кажется, что я где-то с приемником накосячил. Если поменять analogWrite на servo[i].write(x), то все работает.
так у вас ваш или тот что я предложил нормлаьно работает?
если вы управляете мотором при чем здесь servo библиотека?
и по моему в приемнике неправильно сделано. но я не уверен и не буду утверждать
Передатчик нормально работает(Вроде). Servo, для примера. Я тоже считаю, что проблема где-то в приемнике, но не могу понять где((
создайте массив. запишите туда сначала все значения. а потом уже управляйте моторами и чем хотите
и еще добавьте ответ на передатчик что все получено. и можно снова слать. а то передатчик все время шлет, а приемник может еще не успел обработать. буфер переполнится. данные потеряются
Не совсем понял про массив((.
Вот так работае идеально, передача:
Прием:
И для обмена нужно двухстороннюю передачу делать, а у меня с трансиверами проблемы. Если по почте заказывать, месяц ждать, весь интерес пройдет, а до города ехать 650 км. На севере живу. А кто такой Максим? Как его пригласить в наш диалог, или связаться с ним?
в самом первом посте - у вас буферы на передачу и на прием разной длины
и вот это как-то.... ммм... одним словом, так нельзя :)
Буферы делал одинаковые, просто при вставке один код старый взял. Даже при одинаковых размерах не работает.
Что здесь не так? Если не считать, что вместо int out [2] нужно поставить int out [3]
чтение можно в цикл засунуть. только непонятно как вы считываете аналоговое значение с цифрового входа? что за ардуина такая
Это все работает. То, что вы сейчас написали, тот же код только немного по другому оформлен. А в каком месте я считываю аналог с цифры?????
analogRead (0) = analogRead (A0) - всЁ равно...
digitalRead(A0) = digitalRead (14) (uno, duemilanove, decimila) аналогично
Этого ни кто и не отрицал. Я считываю цифру с аналога, это нормально. Мне просто удобнее писать А0 и т.д. Просто у меня Mega и аналог там подписан как А0 и т.д.
Только непонятно как в этом цикле написать A0, A1, A2......
Вряд-ли for ( int i = A0 ; i < A4 ; i++) ;)
Буферы делал одинаковые, просто при вставке один код старый взял. Даже при одинаковых размерах не работает.
Что здесь не так? Если не считать, что вместо int out [2] нужно поставить int out [3]
а это, по вашему, ерунда? ошибки с памятью (невыделение, запись низвестно куда, чтение неизвестно откуда) - значительная доля всех глюков.
Да это не важно. Что автоматом вместо i расставятся цифры, что я явно задам, передатчик работает. На данный момент я это знаю точно.
А я не сказал, что это ерунда. Наоборот, я спросил, что там не так.
Только непонятно как в этом цикле написать A0, A1, A2......
Вряд-ли for ( int i = A0 ; i < A4 ; i++) ;)
Это можно записать как:
for (int i=0; i<4; i++)
{
buf[i] = map(analogRead(Ai), 0, 1023, 0, 180);
}
Да это не важно
вы не понимаете основ использования памяти. вылезание за границы массива является грубейшей ошибкой. если на пальцах, то нельзя впихивать невпихуемое
Да это не важно
вы не понимаете основ использования памяти. вылезание за границы массива является грубейшей ошибкой. если на пальцах, то нельзя впихивать невпихуемое
Это написано было для trembo. А у вас я спросил, как можно по другому сделать, чтобы впихнулось)) И вообще, что-то со всем кодом не так. За ночь сделал много открытий на этом форуме, сейчас попробовал по другому сделать, но... Снова не нравится. Какие-то непонятные скачки по портам где выхода.
Вот код приемника:
А это передатчик:
Это можно записать как:
for (int i=0; i<4; i++)
{
buf[i] = map(analogRead(Ai), 0, 1023, 0, 180);
}
Проверяли? Компилится? i и Ai - ведь это ДВЕ разные переменные.
Это можно записать как:
for (int i=0; i<4; i++)
{
buf[i] = map(analogRead(Ai), 0, 1023, 0, 180);
}
Нельзя.
Если очень надо то можно так:
Это можно записать как:
for (int i=0; i<4; i++)
{
buf[i] = map(analogRead(Ai), 0, 1023, 0, 180);
}
Нельзя.
Если очень надо то можно так:
Да это не в этом проблема. Передатчик работает, номально передает данные. мне их принять надо корректно. И второй вариант кода как-то более рабочий.
Да это не в этом проблема. Передатчик работает, номально передает данные. мне их принять надо корректно. И второй вариант кода как-то более рабочий.
А с передачей данных всегда проще, чем с приемом. Тут главное понимать, что вы работаете с асинхронным приемо-передатчиком (UART) - т.е. приемнику пофиг когда, как, и примет ли вообще другая сторона посланные данные, он плюнул их в "черную дыру" и забыл. А вот приемник должен уметь каким-то образом определить начало передачи пакета данных и их окончание (или длину), проверить контрольную сумму принятых данных. И второй постулат: приемо-передатчик пересылает данные байтами, хоть вы в прогрмме и можете вызвать какую-либо функцию передачи word, long, float, физически будет передана последовательность байт. Теперь мы стали ближе к понимаю, что при работе с данными нам нужен протокол передачи данных.
От лирики к практике:
1) Не факт, что последний ваш вариант правильней, чем первый. В первом варианте я усмотрел правильную вещь - байт синхронизации пакета данных 0xFF:
buf[0] = map(analogRead(0), 0, 1023, 0, 254); -- тут вначале не понял почему ограничение по 254
Serial
.write(0xff);
// synchronize -- а теперь понял
2) В последнем примере вы передаете сначала символ, а потом данные в диапазоне 0-254, а где гарантия что данные из map() и ваши символы не совпадут, тогда весь прием поедет? А где гарантия, что результат map() и digitalRead() имеет размерность 1 байт и в будущем не изменится?
3) Как надо делать: создаем свой протокол передачи данных. У вас был массив - уже хорошо, но на практике лучше использовать структуру, она гибче в использовании в коде и позволяет создать пакет данных с разными типами/размерностью полей.
Пока кратко, а то позно уже, а мне на рыбалку рано вставать :)
а) Создаем структуру, в которой учитываем следующие поля: 1-2 байта синхронизации - можете свои инициалы впихнуть (будет брэндовый протокол:), длина пакета (определиться с длиной чего?, от и до?), ID сообщения в пакете (вдруг ваш протокол получит развитие в других ваших проекта и будете предавать разные пакеты данных - с разными ID и соответственно с разной структурой пакета), 1-2 байта контрольной суммы (определиться с длиной подсчета от и до?). Со структурой пакета все!
б) Сразу продумываете алгоритм подсчета контрольной суммы. Реализуете ее в коде. Тупо мой пример при работе с бинарным протоколом UBX GPS-приемников фирмы u-blox, для примера:
в) Передача пакета выглядит примерно так, опять для примера:
г) Прием... все спать, спать, завтра продолжу.
Вот это исчерпывающий ответ))) Минимум воды и максимум нужной информации))
Вот так все работает.
Приемник:
Передатчик:
Понятнее если
Понятнее если
Я многого еще не знаю и я копипастил))
Видимо не осилили про асинхронность UART, про передачу байтами, про протокол? ;)
Передатчик может запутать приемник (в том виде как сейчас ревлизован приемник) этими пересылками:
45
Serial
.write(map(analogRead(pot1x), 0, 1023, 0, 254));
47
Serial
.write(map(analogRead(pot1y), 0, 1023, 0, 127));
49
Serial
.write(map(analogRead(pot2x), 0, 1023, 0, 127));
т.к. функция map() может вернуть значение = вашим передаваемым символам: от 'a' до 'k', ведь символ это тоже байт! А учитывая асинхронность передачи/приема данных, ваша реализация приемника не гарантирует правильный прием (разберем на одном примере с 'a'):
045
if
(
Serial
.available() &&
Serial
.read() ==
'a'
)
046
{
047
a =
Serial
.read();
048
//analogWrite(speedl,a);
049
//analogWrite(speedr,a);
050
}
Допустим, ваш передатчик передал символ 'a', а потом передал -
Serial
.write(map(analogRead(pot1x), 0, 1023, 0, 254)); ,
но map() вернул число = значению символа 'a'. Таким образом передатчик передал 2 символа 'a'. Тепрь рассмотрим код приемника, допустим(!) цикл попал на первое чнеие символа 'a' сработало условие и мы сразу читаем втрой байт... А кто вам сказал, что второй байт в это мгновение уже поступил в приемник и готов быть счтитан!? - это и есть следствие асинхронности приема/передачи UART! Следовательно переменной a будет присвоена -1 (если я не путаю) - уже ошибка в данных! Далее цикл пролетел несколько оборотов, в приемник наконец потсупил второй символ 'a' от передатчика и мы опять провалились на присвоение значения переменной a - вторая ошибка в принятых данных (тут может либо -1, если следующий байт еще не поступил в приемник или непонятно какой байт следующей команды передатчика (ваши символы от 'a' до 'k' )).
Аналогичные проблемы вас поджидают и с командами 'b' и 'c'.
Такой пример понятен? Надеюсь с асинхронностю покончили. А то что у вас все заработало правильно, так это звезды так сложились или арду вам подарок приготовила к празднику:)
(шепотом: не хотел бы я быть в одной команде с таким танком, еще пальнет в своих :)
Я не волшебник, я только учусь. Поиграться пока хватает)) Сейчас пытаюсь сделать компенсацию дула и вот тут засада... Может кто-нибудь скачать отсюда https://www.loveelectronics.co.uk/Tutorials/13/tilt-compensated-compass-arduino-tutorial библиотеки и выложить сюда? Не могу зайти туда(((
Я тоже вчера не смог, плюс Хром перехватил перенаправление на другой вредоносный сайт. А раньше я на это сайт заходил и эту статью читал. Гляну, может сохранилась копия.
Я нашел библиотеки эти, но..
tiltcompass:74: error: request for member 'YAxis' in 'acc', which is of non-class type 'int'
Итак практически на каждую строку.
А я нашел библиотеку для пересылки данных - EasyTransfer! Попробуйте использовать ее в своих тестах, похоже она использует те фичи, которые я пытался популярно объяснить.
У меня в примерах она есть. Надо посмотреть. Там и для virtualWire есть примеры, а у меня как раз такие трансиверы завалялись))