Нужно разбить строку на массив
- Войдите на сайт для отправки комментариев
Чт, 01/02/2018 - 19:15
Доброго времени суток, есть такая проблема, с arduino и вообще с языком программирования C знаком недавно и плохо, но нужно решить задачку.
Суть такая: в com порт приходит строка 60;70;59;59;73;75;55;65;67;71
Читаю ее так:
String myString; if (Serial.available() > 0) { myString = Serial.readString(); }
Все получается нормально, но нужно как-то разбить эту строку либо на массив, либо еще как-то. Строка может быть разной длинны
https://www.arduino.cc/reference/en/language/variables/data-types/string...
Все конечно здорово, но могли бы как то более менее понятней направить?
indexOf substring toInt
Ищите ; берете подстроку и преобразуете в число и так далее в цикле пока не конец строки.
Доброго времени суток, есть такая проблема, с arduino и вообще с языком программирования C знаком недавно и плохо, но нужно решить задачку.
Суть такая: в com порт приходит строка 60;70;59;59;73;75;55;65;67;71
Читаю ее так:
вы читаете строку неправильно.
Если в момент, когда вы обратились к Serial, строка еще не принята полностью - у вас в переменной myString будет только начало строки случайного размера, а все остальное либо прочитается в следующий раз, если хватит буфера для хранения, либо будет потеряно.
Дело в том, что оператор Serial.readString() вовсе не ждет, пока строка будет принята полностью. Чтобы код работал правильно, вам надо читать из Serial до тех пор, пока не будет принят маркер окончания строки - обычно символ "\n"
вы читаете строку неправильно.
Оххх :(((
Дело в том, что оператор Serial.readString() вовсе не ждет, пока строка будет принята полностью.
и ахх :((
и ахх :((
Чо вздыхаем? Где гарантия-то, что нужная строка будет принята полностью? То, что в исходниках readString для каждого символа таймаут по чтению стоит - не решает ровным счётом ни-че-го. Представьте на секунду, что передающая сторона заткнулась на середине передачи строки "123456", т.е. передала "123" - и всё, встала колом. Принимающая сторона что примет по таймауту? Правильно, строку "123". А что принимающая сторона может, согласно своему алгоритму, ждать? Правильно, "123456". Как сделать вывод, что строка принята не полностью? Правильно, никак, если юзать readString. Патамушта нет никакого признака конца пакета, от слова "совсем".
Ооох, теоретики :)
String тут не любят, мож и прально, но я пользуюсь
я думаю из примера все должно быть понятно
и ахх :((
Чо вздыхаем? Где гарантия-то, что нужная строка будет принята полностью? То, что в исходниках readString для каждого символа таймаут по чтению стоит - не решает ровным счётом ни-че-го. Представьте на секунду, что передающая сторона заткнулась на середине передачи строки "123456", т.е. передала "123" - и всё, встала колом. Принимающая сторона что примет по таймауту? Правильно, строку "123". А что принимающая сторона может, согласно своему алгоритму, ждать? Правильно, "123456". Как сделать вывод, что строка принята не полностью? Правильно, никак, если юзать readString. Патамушта нет никакого признака конца пакета, от слова "совсем".
Ооох, теоретики :)
Хех! ждал это от b707 :)
Да нет вопросов, без признака окончание строки/пакета может все загнутся и в readString, но как сказал бы ув. b707
"Ну вы других-то совсем за идиотов не держите :)"
в концепции Ардуино readString читать все что пришло/лежит в буфере порта с секундной (по умолчанию) поправкой прилета туда еще чего то. А затыки на передающей стороне, это проблемы передающей стороны, в случае с тем же read можно никогда не дождаться признака окончания строки/пакета и висеть в ожидании вечно.
readString выплюнет то что есть, и это можно уже анализировать :))
я думаю из примера все должно быть понятно
String в функцию по значению? Эээх, не жалко оперативки, от слова "совсем".
А затыки на передающей стороне, это проблемы передающей стороны,
Это из серии "все вокруг виноваты, только не мы" :) Пол-страны живёт по таким принципам, однако. Грамотно реализованная принимающая сторона должна разруливать всякие нештатные ситуации, будь то неприём пакета полностью, или - попытка передающей стороны зафлудить канал: в жизни всякое бывает, и если глюк передающей стороны выносит всю сеть устройств на том же RS-485, то нахер нужна и такая передающая сторона, да и для такой принимающей стороны - место тоже в помойке.
я думаю из примера все должно быть понятно
String в функцию по значению? Эээх, не жалко оперативки, от слова "совсем".
используешь String - про оперативку забудь ! :)
А затыки на передающей стороне, это проблемы передающей стороны,
Это из серии "все вокруг виноваты, только не мы" :) Пол-страны живёт по таким принципам, однако. Грамотно реализованная принимающая сторона должна разруливать всякие нештатные ситуации, будь то неприём пакета полностью, или - попытка передающей стороны зафлудить канал: в жизни всякое бывает, и если глюк передающей стороны выносит всю сеть устройств на том же RS-485, то нахер нужна и такая передающая сторона, да и для такой принимающей стороны - место тоже в помойке.
как мне кажется readString и призван чтобы "разруливать всякие нештатные ситуации", ну да лодно тема не о том.
ну а так и Watchdog на помойку, это удел программеров использующих String и goto :)
используешь String - про оперативку забудь ! :)
Ну не по значению же в функции пихать. А так, если про "оперативку забудь", то перерасхода там - 6 байт на объект String. Другое дело, что глобальный объект String будет держать выделенный в оперативке буфер до конца своего существования, поэтому лучше избегать глобальных объектов, ограничиваясь какой-то областью видимости, и всё будет ок. Ну или - создавать объект на куче, чтобы при необходимости всегда можно было убить, высвободив память.
Юзаю String и не парюсь, от слова "совсем", местного неприятия String - не разделяю. Но вот чтоб по значению в функцию передавать - за это самолично готов по рукам бить :) Ибо вот тут как раз - дичайший перерасход оперативки в момент размещения копии объекта на стеке. Представьте, что будет, если объект держит строчку длиной 1200 символов при размере всей оперативки в 2Кб ;) Если передавать по ссылке - таких проблем не возникнет.
как мне кажется readString и призван чтобы "разруливать всякие нештатные ситуации",
readString НИ-ЧЕ-ГО не разруливает, ни штатную, ни нештатную ситуацию. Ибо: как вы сможете понять, что это конец пакета? По таймауту? Дык передающая сторона отвалилась на середине передачи. Сама проверка по таймауту означает ровно следующее: если следующего байта нет в приёмном буфере больше, чем секунду - считаем, что мы всё приняли за этот вызов readString, всё. Нет никакой дополнительной семантики у этого метода, никаких нештатных ситуаций он разруливать не способен.
ну а так и Watchdog на помойку, это удел программеров использующих String и goto :)
Это вообще к чему - не понял.
используешь String - про оперативку забудь ! :)
Ну не по значению же в функции пихать. А так, если про "оперативку забудь", то перерасхода там - 6 байт на объект String. Другое дело, что глобальный объект String будет держать выделенный в оперативке буфер до конца своего существования, поэтому лучше избегать глобальных объектов, ограничиваясь какой-то областью видимости, и всё будет ок. Ну или - создавать объект на куче, чтобы при необходимости всегда можно было убить, высвободив память.
Юзаю String и не парюсь, от слова "совсем", местного неприятия String - не разделяю. Но вот чтоб по значению в функцию передавать - за это самолично готов по рукам бить :) Ибо вот тут как раз - дичайший перерасход оперативки в момент размещения копии объекта на стеке. Представьте, что будет, если объект держит строчку длиной 1200 символов при размере всей оперативки в 2Кб ;) Если передавать по ссылке - таких проблем не возникнет.
согласен, принимаю :)
переписал, передаю по ссылке, сэкономил 250 байт на выше приведенном примере, пасиб !
Юзаю String и не парюсь, от слова "совсем", местного неприятия String - не разделяю.
Проблема String не в том, что она противопоказана, а в том, что ее применение требует достаточно высокой квалификации программиста (IMHO).
Проблема String не в том, что она противопоказана, а в том, что ее применение требует достаточно высокой квалификации программиста (IMHO).
Согласен. Из недостатков реализации класса String также отмечу, что метод invalidate(), чистящий динамический буфер, запрятан в секцию protected, поэтому нет никакой возможности ручками почистить оперативку, кроме
Жутко раздражает, но приходится с этим жить :)
компилятор подскажет
или я что то не так понял ?
компилятор подскажет
или я что то не так понял ?
Нужно окружение, в котором возникает такая ошибка. Вангую, пытаетесь обратиться к i извне блока, ограниченного {}.
да я то это понимаю, я у Винни хотел спросить что он имеет ввиду.
В нас проросли семена зловредных баобабов. «Если баобаб не распознать вовремя, потом от него уже не избавишься, — предупреждает Маленький Принц. — Он завладеет всей планетой. Он пронижет ее насквозь своими корнями. И если планета очень маленькая, а баобабов много, они разорвут ее на клочки». Вообще, это очень просто — встал поутру, умылся, привел себя в порядок и сразу же приведи в порядок свою планету. Баобабы надо непременно выпалывать каждый день, как только их можно отличить от будущих розовых кустов. Молодые ростки у них почти одинаковые...» https://pikabu.ru/story/quotmalenkiy_printsquot_2033473
Ну а теперь баобабы заменим на String , а планету за Ардуину. String это переменная переменной длины , причем длина все время увеличивается и забирает память. Это с одной хорошо, так как данные какими большими они не были влезут в String. Так попользовались Sting и все удалите.
Возьмем к примеру
и этот
И теперь видно что 2 байта улетело. И такая история со Sring. И чем локальнее String тем меньше шансов , что он сожрет память.