Передать и принять Integer по Serial
- Войдите на сайт для отправки комментариев
Ср, 19/04/2017 - 23:31
Хотел по быстрому настроить передачу одного integer с одной ардуины на другую. Но, так как программирую не важно, быстро не получилось. Долго искал готовый скетч, но что то с ровного места найти так и не смог.
В итоге сделал почти сам (ну подглядел часть конечно). Тему создал для таких как я, чтобы в поиске находилась.
Гуру, поправьте если коряво сделал. Но работает вроде хорошо.
Передача
#include <SoftwareSerial.h> SoftwareSerial Serial100(10,11); // Rx, Tx передаём через софтсериал порт unsigned int var = 2665; // переменная которую передаём unsigned long prev=0; // для таймера void setup() { Serial100.begin(19200); } void loop() { unsigned long cur=millis (); if (cur-prev>100){ // шлём раз в 0,1 с byte b1 = ( byte )( var >> 8 ); // перевод нашей переменной в два байта byte b2 = ( byte )var; Serial100.print ("1"); // сначала шлем символ "1" Serial100.write (b1); // далее шлём первый байт переменной Serial100.print ("2"); //далее шлём символ "2" Serial100.write (b2); //далее шлём второй байт переменной Serial100.print ("3"); // далее шлем символ "3" передача окончена prev=cur;} }
Прием
#include <SoftwareSerial.h> SoftwareSerial Serial100(10,11); // приниамем через софтсериал порт unsigned int var; // принимаемая переменная // ниже байты и флаги для приема переменной byte b0; byte b1; byte b2; bool byte1read=0; bool byte2read=0; bool byteEnd=0; void setup() { Serial100.begin(19200); } void loop() { SerialREAD(); //если флаг "можно читать переменную из 2х байтов" в true // то соединяем байты в переменную if (byteEnd) {var = ( ( unsigned int )b1 << 8 ) | b2; byteEnd=0;} } void SerialREAD (){ if (!Serial100.available()) return; // если в буфере сериала ничего нет сразу выходим из цикла b0 = Serial100.read(); // если в буфере что-то есть читаем if (byte1read){ if (b0!=0x31 && b0!=0x32 && b0!=0x33) {b1=b0; byte1read=0;} }// пишем в первый байт if (byte2read){ if (b0!=0x31 && b0!=0x32 && b0!=0x33) {b2=b0; byte2read=0;} }// пишем во второй байт if (b0==0x31) byte1read=1; // если приняли символ '1' (см. ASCII )флаг "можно писать в первый байт" в true if (b0==0x32) byte2read=1; // если приняли символ '2' флаг "можно писать во второй байт" в true if (b0==0x33) byteEnd=1; // если приняли символ '3' флаг "можно читать переменную из 2х байтов" в true }
А как физически вы связали ардуины?
MaksVV, а так сложно-то? Зачем эти три символа-то? Чего просто два байта не передать? Ну, или, даже через символы, но в лоб, типа
int n = 321;
Serial.print(n):
.....
int n = Serial.parseInt();
Неее, это не наш метод. Слишком просто. Надо было вообще свой язык форматирования придумать, аля для передачи числа 341:
Все это загонять в сериал, и парсить, парсить, парсить. Зато потом можно как развернуться))))
Ну, да, так круче! Сюда ещё и полномасштабный xml-engine прикрутить можно.
А вообще задача-то в совершенно буквальном смысле "как два байта переслать" :)
MaksVV, а так сложно-то? Зачем эти три символа-то? Чего просто два байта не передать? Ну, или, даже через символы, но в лоб, типа
int n = 321;
Serial.print(n):
.....
int n = Serial.parseInt();
Потому что книгу по программированию читать долго. А сделать уже надо было. Теперь знаем как проще. Наверное кому то еще пригодится.
Пс. Дуины физически рядом находятся. Соединены просто тремя проводами. Тх рх земля.
MaksVV, а так сложно-то? Зачем эти три символа-то? Чего просто два байта не передать? Ну, или, даже через символы, но в лоб, типа
int n = 321;
Serial.print(n):
.....
int n = Serial.parseInt();
У меня чего-то так не заработало. Где я не так делаю? Скетч тормозится помоему на int var = Serial.parseInt(); и дальше ничего не делает. То что по сериалу байты прилетают это верно, проверил через Serial.read()
Передача
Приём
А с чего Вы взяли, что он тормозится и что он по-Вашему должен делать? Он ничего не печатает и вообще ничего не делает у Вас.
на самом деле я так пробовал
короче я так понимаю что то с вот этим связано Serial.setTimeout()
мне нужно чтобы данные раз в 0,1 сек обновлялись
строчку 22 убираю, данные начинают идти в сериал100, иначе - не идут
А чего сразу не сказал? Зачем мозг-то пудрить?
короче я так понимаю что то с вот этим связано Serial.setTimeout()
И да, и нет.
Вы прочитали как parseint работает? Или тупо вставили?
Он у Вас не работает потому, что Вы слишком часто передаёте числа без разделителя.
Работает он так
1. Читаем, если НЕ цифра и НЕ знак - ура, мы закончили
2. Если же цифра, то запомнили её
3. Ждём следующего символа или таймаута
4. Если поступил следующий символ, то идём к п.1
5. Если наступил таймаут, то ура, мы закончили
Вот, как-то так.
Вы же передаёт часто и потом в п.3 он всегда дожидается следующей цифры.
ЧТобы этого не было передавайте между числамии какой-нибудь разделитель (пробел, например). Тогда он будет радостно вылетать.
Например, сейчас у Вас
Serial.print(12); Serial.print(34);
Serial.print(12); Serial.print(' ');Serial.print(34);Serial.print(' ');
Он их нормально съест как два числа, т.к. пробел будет воспринят как разделитель. Не обязательно пробел - любая "нецифра".
короче я так понимаю что то с вот этим связано Serial.setTimeout()
И да, и нет.
Вы прочитали как parseint работает? Или тупо вставили?
Он у Вас не работает потому, что Вы слишком часто передаёте числа без разделителя.
Работает он так
1. Читаем, если НЕ цифра и НЕ знак - ура, мы закончили
2. Если же цифра, то запомнили её
3. Ждём следующего символа или таймаута
4. Если поступил следующий символ, то идём к п.1
5. Если наступил таймаут, то ура, мы закончили
Вот, как-то так.
Вы же передаёт часто и потом в п.3 он всегда дожидается следующей цифры.
ЧТобы этого не было передавайте между числамии какой-нибудь разделитель (пробел, например). Тогда он будет радостно вылетать.
Например, сейчас у Вас
Serial.print(12); Serial.print(34);
Serial.print(12); Serial.print(' ');Serial.print(34);Serial.print(' ');
Он их нормально съест как два числа, т.к. пробел будет воспринят как разделитель. Не обязательно пробел - любая "нецифра".
я почитал там сям, но так как вы объясняетете, нигде не пишут. Спасибо за ликбез.
Если можно подскажите как в потоке определять начало пакета для записи в массив? Я так понимаю после считывания из буфера данные более недоступны. Иными словами буквы к буквам цыфры к цыфрам...
Если можно подскажите как в потоке определять начало пакета для записи в массив? Я так понимаю после считывания из буфера данные более недоступны. Иными словами буквы к буквам цыфры к цыфрам...
Как минимум - можете по получению байта копировать его к себе в предварительно созданный char buffer[предполагаемая_длина_пакета+запасец].
Если можно подскажите как в потоке определять начало пакета для записи в массив? Я так понимаю после считывания из буфера данные более недоступны. Иными словами буквы к буквам цыфры к цыфрам...
В Ардуино нет такого понятия как пакет. Соответственно, как сами эти пакеты организуете, так и будет работать. Можно, например, подсмотреть как организованы пакеты в наиболее распространенных протоколах и что-то аналогичное сделать самому.
Да, после того как байт считан из буфера, о его сохранности должны заботиться Вы сами. Например, поместив его в другой буфер.
Замечательный ответ... Спрошу тогда так, если я в операторе сравнения буду проверять что прочитал, уже эти данные я никуда не запишу!? Как узнать что внутри (буква или цыфра). Можно наверно записать в char если на передатчике serial.print(); но потом как это собирать parseInt'ом неясно.
Подытожу: можно ли как то отсортировать буквы с циыфрами и цыфры собрать парсИнт'ом?
Ничерта не понял. Вам нужна волшебная команда, которая сортирует, хранит и собирает? Такой нет. Есть отдельные действия - собрать, хранить и сортировать. Вы сами их должны выстроить в соответствии с тем, какой алгоритм у вас нарисовался в голове. И это выстраивание называется программированием. Его изучают долго и кропотливо.
Замечательный ответ...
....
Подытожу: можно ли как то отсортировать буквы с циыфрами
никак. По сериалу отправляются байты, а цифры это или буквы - вы решаете сами, для компьютера это одно и то же.
И да, вы зря иронизируете по поводу предыдущего ответа. adriano ответил вполне по делу, просто ваш низкий уровень знаий пока не дает вам это понять.
Ах да, я забыл, форум же он не для помощи....ушел рыдать
Ах да, я забыл, форум же он не для помощи....ушел рыдать
вот мне даже интересно. Вы думаете, над вами глумяться? в каком месте. интересно? вот, например, в моем последнем сообщении - что именно вы считаете глумом?
Еще про буквы и цифры. Вот 'a' и 'c' - это буквы или цифры? Вроде ответ очевиден. Однако если это буквы. почему их можно вычитать и складывать? Вот такой код отлично компилируется и работает. Значение x после вычитания = 2
int x = 'c' - 'a';
Итог - все. что вам ответили - не глум, а чистая правда. По сериал отправляются байты, а чем их считать - буквами, цифрами или, к примеру, картинкой или музыкой - выбираете вы сами. Вы можете с одной стороны отправить в сериал строчку "ab". а с другой считать ее ParseInt-ом и получится число.
если я в операторе сравнения буду проверять что прочитал, уже эти данные я никуда не запишу!?
Ви таки не поверите, можно сравнивать и сохранять одновременно. Си - это страшный язык.
char ch;
if ((ch=Serial.read())=='цыфра или буква')
{
то запхать считанный ch в свой буфер
}
Да кинте вы уже кусочек кода или описание где почитать о таком.. что мы из пустиого в порожнее, еслиб я нашел хоть плохенькое что то, то привел бы сюда, пусть и поглумятся, лишь бы разъяснили, только кроме слов что я ничего не умею ничего не прочел еще.. а глум здесь, это норма.... так что нет не думаю, я знаю что глумятся.
Ви таки не поверите, можно сравнивать и сохранять одновременно. Си - это страшный язык.
а проще сначала сохранить, потом сравнивать
to DetSimen
вот и ответ, спасибо!
Да кинте вы уже кусочек кода или описание где почитать о таком.. что мы из пустиого в порожнее, еслиб я нашел хоть плохенькое что то, то привел бы сюда, пусть и поглумятся, лишь бы разъяснили, только кроме слов что я ничего не умею ничего не прочел еще.. а глум здесь, это норма.... так что нет не думаю, я знаю что глумятся.
какой код вам нужен? что делает-то? читает из сериал? я ж напишу, а вы опять за глум примете
byte a = Serial.read();
Да кинте вы уже кусочек кода или описание где почитать о таком.. что мы из пустиого в порожнее, еслиб я нашел хоть плохенькое что то, то привел бы сюда, пусть и поглумятся, лишь бы разъяснили, только кроме слов что я ничего не умею ничего не прочел еще.. а глум здесь, это норма.... так что нет не думаю, я знаю что глумятся.
какой код вам нужен? что делает-то? читает из сериал? я ж напишу, а вы опять за глум примете
byte a = Serial.read();
if (a == 'цифра или буква')
if ((ch=Serial.read())=='цыфра или буква')
вангую, следующий вопрос будет - почему не компилиуется оператор 'цыфра или буква'
парсИнт не прикрутить к этой конструкции, ну соберем руками раз так....
парсИнт не прикрутить к этой конструкции, ну соберем руками раз так....
прочитайте сообщение №13 в этой ветке - там подробно разжевано, как парсеинг пользовать.
Ах да, я забыл, форум же он не для помощи...
Совершенно верно. Рад, что до Вас это дошло!
Форум, он для общения по интересам. Хотите, чтобы кто-то был заинтересован с Вами общаться - будьте интересны собеседнику. Это, кстати, касается любого общения - не только форума и Интернета.
Бин! Я один из главных "глумителей"... но тут не тот случай. Человек просто вообще не знает.
----
Андриклл, смотри:
1. есть такая штука Serial.peek(), ровно ТОЖЕ САМОЕ, что и read, но символ остается в буфере, то есть следующий read его прочтет, понял?
Это самое проссто решение, после анализа буквы через peek потом вызовешь parseInt и все.
2. Другой способ прочитать всю строку до конца в массив char. и потом анализировать. Если выберешь 2, то потом поясню...
стёр
Как я долго писал... Спасибо...Я не против глума, но если в нем есть подсказки или ответ в любой форме.... а то был глум-флуд... это уж слишком :-)
Евгений я через ту пропасть к Вам врят ли докричу, так что хоть лестницу бы подали....
Мне вот даже интересно Вам 2-х летние дети интересные собеседники? Но мы же с ними общаемся.. так что то не работает правило...(поправки наверно нужны).
to wdrakula
Да с peek теперь все понятно и удобно он же и в роли эвэйлбл, как я понял, спасибо, теперь все прояснилось.
Прочитайте внимательно свою фразу, и скажите, только честно, Вы бы поняли что тут сказано?
"После приема эти данные идут как надо, если поставить 128 и более в массиве, то сначала идет то что в массиве а потом все сбивается.... причем это каждый раз разные цыфры и каждый раз после ресета идут данные массива и через время сбиваются, более 250 не пробовал совсем, застрял на этом"
Я может тупой, но я ни хрена не понял.
Мне вот даже интересно Вам 2-х летние дети интересные собеседники? Но мы же с ними общаемся.. так что то не работает правило...
ваша ошибка, что вы почему-то решили, что тут ясли для двухлетних. Нет, по этой аналогии тут школа, класс этак пятый и выше :) Если двухлетнего привести на урок химии в 7-м классе - много он поймет? - Ничего. Но разве это означает. что учитель - никудышный? нет, просто ребенку еще надо очень много узнать, прежде чем идти в 7-й класс.
ЕвгенийП Нет не понял бы, пока я писал, дракула ответил тем что мне нужно и я стер код... спасибо!
через Serial.write передачу я не смог настроить, получалось так что данные то верные то нет, начало массива было там где нужно, передавал 6 цифр. моли поменяться первые две, три или последние цыфры масива. что это было.... наверно не нужно разбираться теперь.
b707 ванга из вас так себе
Небыло понятно, пробовал write, print почитал как формируется эта передача, и непонятно стало как это все разделять.
Приемник
Вот так все заработало. можно и в массив запереть... всем спасибо....
wdrakula
Получилось так что можно и не анализировать, после записи Serial.peek(); можно сразу serial.parseInt();
А контроль всяких начал через считанное значение перем=serial.peek();
единственное наверно parseInt не очищает буфер если там не цифры, пришлось flush добавить
Вот смотрите, у Вас есть целое число во внутреннем машинном представлении. Для того, чтобы его переслать, Вы преобразуете его в текстовый вид. Затем Вы принимаете строка и парсите её, чтобы преобразовать обратно во внутреннее представление.
Почему не передавать число прямо во внутреннем представлении? Зачем преобразовывать его в строку, а потом обратно?
ну так яж из группы велосипеды и костыли...
Написал же что врайтом не зашло и что делать не знаю.. код стер уже... могу конечно восстановить.. побегать так сказать по граблям, а вы скажите какие шишки полезные на лбу, а какие зря.
А если без шуток то надо восстановить код и закинуть сюда чтоб сказали что в нем не так.
Что значит "не зашло". Должно заходить, куда оно нахрен денется-то?
Ну, если хотите, я могу сделать Вам пример с двумя ардуинами в протеусе. Надо?
Нет, у меня пример с 2-мя спаянными.. так что сейчас только восстановлю как было и заброшу.
Не догадался сделать монитор порта для передатчика.. Какие то буквы периодически появляются в разобраных на byte из int данных.
код
Какие то буквы периодически появляются в разобраных на byte из int данных.
А в строке 19 не хотите i начальное значение присвоить?
А вот на приемнике почти все правильно стало за исключением первого значения, но думаю оно просто неверно собирается в инт из байт, сейчас добьюсь результата и закину...
В 19 строке хочу, но онож локальное....
До этого не приходило в голову, а сейчас как будто от Вас волны... онож создается в в свободном пространстве и может быть ....любым.
Не знаю что и сказать, все работает....
У меня в исходнике было отправлять первые 5 значений (начало пакета) через for, может там небыло сброшено i и из за него сбивалось.
Строка 32! Вы издеваетесь? Вы же сами сказали, что там может быть всё, что угодно! Так и работает она у Вас "пока везёт". Добавите какую-нибудь строку и всё рухнет. Так трудно написать там int i = 0; ????
Исправил... все исправил... так что за f, в тексте (в ком порту, передатчика)? оно не мешает, но неясно что это...
Выложите текущие версии приёмника и передатчика, чтобы мне не гадать что Вы исправили, а что - нет. Я посмотрю.
ТХ
RX
Первую величину массива изменил чтобы проверить предел по byte
Думаю что f, это переполнение буфера, не успевает в монитор все данные слить которые получает. (задержек нет никаких на передачу)