Всем привет. Как правильно организовать передачу 15 переменных типа float, по сериал? Данные в таком формате 12.25,12.36,10.45,8.12, ... Отправляю с ардуино уно на esp8266. На ардуине формирую строку, кидаю в сериал, жду 1с: Код (C++): sendData = String(data_a[0]) + "," + String(data_a[1]) + "," + String(data_a[2]) + "," + String(data_a[3]) + "," + String(data_a[4]) + "," + String(data_a[5]) + "," + String(data_a[6]) + "," + String(data_a[7]) + "," + String(data_a[8]) + "," + String(data_a[9]) + "," + String(data_a[10]) + "," + String(data_a[11]) + "," + String(data_a[12]) + "," + String(data_a[13]) + "," + String(data_a[14]) + ","; Serial.println(sendData); delay(1000); На есп, читаю в строку и шлю по вифи: Код (C++): if (Serial.available()) { char temp = Serial.read(); if (temp > ' ') { data += temp; } client.print(data); На сервере(сокет) получаю кракозябры, типа х56/x25/x45 и т.д. Если на есп, я убираю прием с ардуины, и вывожу строку с данными 12.25,12.36,10.45,8.12 на сокет, то сокет обрабатывает их нормально, и выводит в таком виде в котором я отправил. Т.е выходит я не правильно принял данные с ардуины, пните в нужном направлении.
В виде двоичного буфера длиной 60 байт (60 = 15 переменных по 4 байта ) То, как делаете вы - запихивать флоат в строки, чтобы после передачи разбирать их из строк обратно в числа - это удаление гланд через задницу.
Создать массив из этих переменных и перекинуть его побайтно (write-read). Или что нужно? В виде текста?
Если приглядется к первому сообщению - массив у автора уже есть. Это не сразу можно заметить, потому что он (автор) запихивает каждый элемент массива в строку по отдельности, как будто не догадывается о наличии в языке Си циклов Автор, - вам рано еще коды писать, начните с чтения учебника
Это дело привычки и языка. Не зря же после массивов и структур Си придумали такие вещи как json, xml, etc. Не сями едиными...
Я с вами согласен - на Перле или Питоне, к примеру, я бы тоже строчками передавал. Но автор-то пишетт на Си... В Си, на мой взгляд, как раз работа со строками продумана слабее всего- и явно хуже, чем с двоичными данными - поэтому совершенно непонятно, зачем самому лезть в эти дебри, если данные изначально бинарные, "родные" для Си.
С дебрями тоже не все однозначно. Представление float в разных железках компилятороами может быть выполнено по-разному и стыковки будут непростыми.
Float можно заменить на int, умножив на 1000 например. Чтобы оперировать с целыми числами, а на клиенте пк буду делить и писать в файлы. Когда есть желание и стремление, то ни чего не рано. Да, на ардуине есть массив, его передаю на есп, с есп на клиент в ПК. Мне нужно передать данные на пк, любым способом, главное что бы работало. С есп данные идут корректно, но когда с ардуины на есп и на пк то с ошибками, так как не правильно передаются с ардуины на есп.
Данные (байты информации) идут без ошибок. Просто компиляторы по-разному составляют из них числа. То есть на стороне одного из устройств надо как-то решать эту проблему. Именно поэтому и существует способ передачи информации в текстовом виде с последующим преобразованием в цифровой, если это необходимо, что бывает не всегда. Я бы в вашем случае вместо массива Си делал простой json объект '{1:234.00,2:743.22...}' и перегонял его в компьютер где и парсил. Это как направление мысли.
Программа на пк у меня написана под Linux, на фреймворке QT. Я сейчас проверил, в сериал есп пишу данные в ручную, далее передаю на пк. Пишу 1 в сериал есп, на пк получаю 47, 2 - 48. Т.е. приходят коды символов. Отправил число 450 пришли коды 52 53 48.. json можно в си встроить? Я пока про json не читал, на работе. Дома почитаю.
так зачем же дело встало? Получить из кода символа цифру - непосильная задача? это одно действие char c; int a; a = c - '0';
Простите Игорь, согласится не могу. Ваш совет из разряда вредных. Вместо того чтоб один раз разобраться в различии представлений типа флоат на стороне ардуины и компа (залачка-то ерундовая. ну что может быть сложного в 4х байтах?) - вы предлагаете сначала формировать json обьект с одной стороны. а потом парсить его с другой? Неээфективный и медленный подход, имх, который. к тому же, потребует от автора много больше сил и времени, чем передача двоичных данных
Давайте посмотрим. Возможно автор решит проблему и поделится. Быстро или медленно, много или мало - вещи относительные. Возможно решение лежит в программировании в машинных кодах - конечная задача известна только автору. Я понимаю, что оторваться ментально от привычек и подходов Си сложно. Но json в целом удобнее. Задача же не только "протолкнуть" данные, но и как-то обработать. И не обязательно это будет Си: Python на стороне компа гораздо удобнее. И если данные к нему придут в приятном для него формате - что здесь плохого?
Добавлю. Json - не стиль ардуино. Но здесь и общение идет с компьютером. А ему (по мощности) плевать на то как придут данные - лишь бы программисту было удобно. Отправить данные с ардуино - та же бодяга: включил библиотеку и выполнил пример. ESP-8266 переправит это транзитом. Все несложно. Так что совет не так вреден как кажется. И я даю его в твердой уверенности что поступил бы именно так.
Согласен, самый правильный алгоритм - тот, который лучше знаешь ИМХО, у ТС уже достаточно вариантов. пусть выбирает.
Конечно спорить не буду... но: Код (C++): float pf = 1234567.89; //snd - буфер для передачи memcpy(&snd[0], &pf, sizeof(float)); ... //далее собственно передача правда snd[0] указал почти не так просто... при пиёме допустим в структуру или массив такое обращение: Код (C++): float fp = (*(float*)(&rcv[0])); будет нормально, а вот к примеру: Код (C++): //при передаче (*(float*)(&snd[1])) = 123.456; ... //при приёме float frs = (*(float*)(&rcv[1])); такое вряд ли прокатит... хотя можно и memcpy применить. Но всё же проще распологать данные в структуре/массиве кратно размеру (в байтах) ну типа этого: Код (C++): typedef struct _DAT { float fp1; float fp2; int32_t p321; int16_t p161; int8_t p81; } DAT; то есть по убывающей - это гарантированно. Но можно и (как ранее говорил) memcpy. А ещё можно #pagma pack(1) примеить... но вот тут компиляторы разные сработают по разному. Прще сразу учесть выравнивание.
Только не смейтесь... RX с TX перепутал... На есп сделал так: bool send = false; int c; String data = " "; Код (C++): while (Serial.available()) { char temp=Serial.read(); if (temp>' ') { //data += temp; c = temp -'0'; data +=c; } //c = Serial.read(); send = true; } Шлю на пк так: Код (C++): if(send) { client.print(data); data = " "; send = false; } На ардуине, шлю большую строку из первого поста через Serial.print(); На пк, в программе на QT, даже не надо преобразовывать, строка приходит в первозданном виде, кроме запятой, она почему то приходит как -4. Перепробовал ку ча вариантов, потом пригляделся к проводам, и тут доперло что перепутал их. Спасибо за помощь всем!