Передача данных DHT датчика с одной ARDUINO на другую посредством радиоканала (433,92) и последующий анализ данных.
- Войдите на сайт для отправки комментариев
Добрый день, уважаемые форумчане.
Не могу преобразовать данные в число для послед. анализа, полученные из буфера другой ардуинки по RC-каналу:
От ардуины с датчиком DHT по радиоканалу на приемник другой ардуинки приходит строка вот в таком виде /22.5/40.8
Далее через сериал порт эта строка посимвольно формируется на экране с помощью след функции:
uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)) // Non-blocking { int i; //Serial.print("Got: "); for (i = 0; i < buflen; i++) { Serial.print((char)buf[i]); } Serial.println(" "); }
и выглядит точно также: /22.5/40.8
Собственно вопрос: Как мне создать две float (наверное) переменные со след. значениями:
rcTemp с числовым значением 22.5 и rcHum с числовым значением 40.8, чтоб можно было эти переменные использовать в дальнейшем, например, для включения реле и тп?
В ардуино-справочнике в разделе "типы данных" не совсем понятно как их преобразовывать, или как выдернуть нужные мне символы из строки... и в итоге получить число. Привык сам разбираться, но тут тяжелый случай.
В том то и дело, не получается присвоить char *rBuf = buf ни так, ни так char *rBuf = 'buf' . Второй вариант, просто стрка из 3 симолов присвается.
В данном варианте ругается на ошибку:
Было бы здорово еще ссылку на мой вопрос, где почитать о конвертации типов данных можно. Гуглу даже вопрос сформировать не получается правильно. Помогите разобраться.
Или может зря отключил цикл for (i = 0; i < buflen; i++
Это наверное мой случай)) Но просто так не сдамся)))
Вы перестаньте дергаться между темами и по нормально во всем разберитесь. Вы выбрали путь когда вам нужно данные с датчика разбить по байтам и отправить. vxl выбрал путь преобразования данных в коды АСКИ и передачи. Скажу сразу первый вариант хоть и сложнее, но более правильный.
это нерабочий код
И так, почему ругается компилятор?
Первая причина в том, что вы пытаетесь присвоить константе переменную. Давайте разберемся, что же не так. Рассмотрим на примере пластилина, то есть его можно как угодно мять. Вы компилятор. Вот у вас два одинаковых куска пластилина. Операция присваивания "=" означает, что нужно взять один кусок пластилина и сделать его такой же формы как и другой. Вам говорят: "приствойте пластилин А к пластилину В"
вы берете и мнете, все нормально, сделали.
Константа - это кусок твердого пластилина, замороженный пластелин. И вам говорят: "сделайте кусок замерзшего пластилина А такой же формы как и В.
Что же вы ответите на это? Я не могу! Он твердый! Руки больно! Вот и компилятор не может присвоить константе переменную.
Вторая причина - это то что вы пытаетесь указателю присвоить переменную.
Указатель это всего лишь адрес массива. Вам говорят сделайте пластилин формой Россия г. Москва, ул.Тверская дом 1. Вы понимаете что такое форма куба, форма шара и т.д. но как форма может быть адресом??? Это как вообще такое возможно??? Да никак. Вот по этой причине и ругается компилятор.
Что бы привоить массиву переменную нужно обратиться к элементу массива
Или можно указателю присвоить адрес переменной
В том то и дело, не получается присвоить char *rBuf = buf ни так, ни так char *rBuf = 'buf' . Второй вариант, просто стрка из 3 симолов присвается.
В данном варианте ругается на ошибку:
Пишем
и всего делов. Только не понимаю для чего это. Почему не использовать прямо buf в atof. Там можно точно также преобразовать тип, как я здесь написал.
Ну, а про s - правильно, откуда у Вас s, если она у Вас называется rBuf?
Спасибо за наводку, Евгений. Теперь я получил 2 значения температуры и влажности вот таким образм. (эквивалент Вашему, выше предложенному варианту) вот такой строкой:
В итоге я получил строку s1 с символами пусть 22.2 и строку s2 с символами 33.3
Как мне получить s1+s1=44.4 или s1+s2=55.5? Компилятор не даст выполнить эту операцию со строками, как я понимаю. Как мне char (строку) перевести в цифру 22.2, чтоб я cмог дальше выполнить след условие.:
Спасибо за наводку, Евгений. Теперь я получил 2 значения температуры и влажности вот таким образм. (эквивалент Вашему, выше предложенному варианту) вот такой строкой:
В итоге я получил строку s1 с символами пусть 22.2 и строку s2 с символами 33.3
Как мне получить s1+s1=44.4 или s1+s2=55.5? Компилятор не даст выполнить эту операцию со строками, как я понимаю. Как мне char (строку) перевести в цифру 22.2, чтоб я cмог дальше выполнить след условие.:
Какой эе это эквивалент? Я же Вам писал как преобразовать их к числам, а не к строкам
double as1 = atof((char *) buf+1);
double as2 = atof((char *) buf+6);
Теперь as1 и as2 - числа, а не строки. Надо Вам их сложить, ну и складывайте as1+as2
ДА! То, что доктор прописал. Спасибо!
Действительно все работает.
Но подозреваю, что при передаче вместо строки /22.2/33.3 , с которой Вы помогли мне разобраться, например /-2.2/33.3 или /2.2/33.3 меня ждет сюрприз?))) Из-за того что температура будет не в десятках, т.е. не двухзначным числом, а односзначным. А с минусом и предположить сложно )))... НО все-равно спасибо, помогли новичку. 2 выходных убил изучая типы данных, но так и не осилил.
Возникли вопросы:
1. Почему double , а не float
2. С этой строкой не все понятно. Про atof прочел на вики, а вот ((char *) buf+1) ???
Как я понимаю char* сформировал строку с некотороми символами неопределенной длины, допустим 0123456789... buf+1 указывает на то, что мне нужно начать читать эту строку со второго символа (и читает он ее так 123456789...), а как он определил длину в 4 символа? Именно тип данных double определил, что это будет 4 символа (4 байта это 1234), так ?
Никаких сюрпризов, всё как должно быть:
/-2.2/33.3 – результат -2,2 и 33,3
/2.2/33.3 – результат 2,2 и 3,3
Обратите внимание на второй результат. Вы, видимо не этого хотите.
Пераметр функции atof – адрес с которого начинается число. В случае второго примера число 33,3 начинается с пятого символа, а мы пишем шестой, значит первая тройка будет проигнорирована.
Если Вас интересует универсальное вычитывание, то Вам надо определиться какие вообще могут быть строки: сколько чисел, допускаются ли пробелы – в общем надо строго определить формат входной строки. Без этого ничего универсального не получается.
Потому что результат функции atof – double. Можете написать float – преобразуется. При этом компилятор может, конечно ругнуться на потерю точности, но это будет предупреждение, а не ошибка. Чтобы не ругался надо преобразовать тип явно.
2. С этой строкой не все понятно. Про atof прочел на вики, а вот ((char *) buf+1) ???
Как я понимаю char* сформировал строку с некотороми символами неопределенной длины, допустим 0123456789... buf+1 указывает на то, что мне нужно начать читать эту строку со второго символа (и читает он ее так 123456789...), а как он определил длину в 4 символа? Именно тип данных double определил, что это будет 4 символа (4 байта это 1234), так ?
Нет.
buf+1 – означает, что Вас интересует строка, начиная с первого символа (они с нулевого нумеруются).
buf+6 – означает, что Вас интересует строка, начиная с шестого символа (они с нулевого нумеруются).
(char *) ничего не формирует. Он вообще ничего не делает. У Вас ведь buf имеет тип uint8_t *. Так? А функции atof нужен тип char *. Если ничего не делать, то компилятор ругается на несоответсвие типов – Вы это видели.Так вот выражение (char *) не делает ничего, оно лишь говорит компилятору, что мол «знаю, что тебе нужен тип char * - так вот не парься и считай, что там char * и есть». Компилятор это проглатывает и спокойно работает.
Длину в 4 символа никто никак не определял. atof читает столько символов, сколько есть, пока там идёт что-то похожее на число. Как только там встретится то, что не может быть числом – она останавливается. Попробуйте 1234.56789A – она благополучно схавает до 9 включительно, а на A останвится. Результат: 1234.56789
Спасибо... Буду двигаться дальше. Все вопросы буду задавать в этой теме.
Все собрал, выяснилась следующая проблема:
Радиус действия совсем маленький. В прямой видимости данные передаются максимум на 2 метра. Это с припаянными антенками по 17,3 см. Как я понимаю на ресивер и на приемник можно подать большее напряжение (на трансмиттер - 12В, а на ресивер 5В), чтоб увеличить дальность?
Питание на трансмитер и ресивер подаю только с самой ардуины. Наверное этого не достаточно.
Подчищу код и выложу сюда оба скетча (R/T). Возможно там накосячил.
Игрался с этим чудом, больше 2 метров по прямой не работало. Стабильно работало, то расстояние не больше 50 см. что очень мало. Подавать больше питания пока не пробивал, если у Вас есть возможность — это сделать, то о результате отпишитесь. Спасибо!
Ок, но в городе и в поле - разница доже должна быть. 433 частота там чище, в поле)) Тему буду продолжать.