Передача данных от ардуино нано к NodeMCU
- Войдите на сайт для отправки комментариев
Пнд, 30/10/2017 - 15:27
Добрый день!
Стоит задача передачи данных (состояния освещенности, движения, температуры и др.) от ардуино к NodeMCU для последующего отображения на андроид устройствах и т.д. Почему сразу не на NodeMCU? - мало входов, да и ардуинок хватает. попробывал передавать строкой через Serial - работает, но надо конвертировать String в Integer, правильно ли это? Т.е. мне надо, чтобы ардуино собирала все данные и передавала их NodeMCU, а она в свою очередь уже будет управлять освещением и тд. Подскажите, пожалуйста, может есть способ проще? (желательны ссылки и примеры).Спасибо, скетчи ниже
#include <OneWire.h> #include <DallasTemperature.h> #include <DS1302.h> // освещение начало const int pinPhotoTualet = A0; // Фоторезистор в туалете с подтягивающим резистором 10 кОм на А0 const int pinPhotoKoridor = A1; // Фоторезистор в коридоре с подтягивающим резистором 10 кОм на А1 const int pinPhotoWanna = A2; // Фоторезистор в ванной с подтягивающим резистором 10 кОм на А2 const int pinPhotoKuhnia = A3; // Фоторезистор на кухне с подтягивающим резистором 10 кОм на А3 int rawTualet = 0; // Освещенность в туалете int rawKoridor = 0; // Освещенность в коридоре int rawWanna = 0; // Освещенность в ванной int rawKuhnia = 0; // Освещенность на кухне int lightTualet = 0; //переменная для хранения состояния света ( 1 - вкл/0 - выкл) int lightKoridor = 0; int lightWanna = 0; int lightKuhnia = 0; //освещение конец //движение начало int moveTualet = 0; //переменная для хранения состояния движения int moveKoridor = 0; int moveWanna = 0; int moveKuhnia = 0; int pirPinTualet = 2; //пины подключения датчиков движения int pirPinKoridor = 3; int pirPinWanna = 4; int pirPinKuhnia = 5; int calibrationTime = 10; //Время калибровки датчика движения 30 сек (10-60 сек. по даташиту) int ledPin = 13; void setup() { pinMode( pinPhotoTualet, INPUT ); pinMode( pinPhotoKoridor, INPUT ); pinMode( pinPhotoWanna, INPUT ); pinMode( pinPhotoKuhnia, INPUT ); digitalWrite(pirPinTualet, LOW); digitalWrite(pirPinKoridor, LOW); digitalWrite(pirPinWanna, LOW); digitalWrite(pirPinKuhnia, LOW); delay(500); for(int i = 0; i < calibrationTime; i++) //калибровка 30 сек { //Во время калибровки будет мигать сигнальный диод i % 2 ? digitalWrite(ledPin, HIGH) : digitalWrite(ledPin, LOW); delay(1000); } digitalWrite(ledPin, HIGH); //По окончанию калибровки зажжем сигнальный диод delay(50); Serial.begin(115200); } void loop() { rawTualet = analogRead( pinPhotoTualet ); rawKoridor = analogRead( pinPhotoKoridor ); rawWanna = analogRead( pinPhotoWanna ); rawKuhnia = analogRead( pinPhotoKuhnia ); if(rawTualet >= 400) lightTualet = 1; else lightTualet = 0; if(rawKoridor >= 400) lightKoridor = 1; else lightKoridor = 0; if(rawWanna >= 400) lightWanna = 1; else lightWanna = 0; if(rawKuhnia >= 400) lightKuhnia = 1; else lightKuhnia = 0; if(digitalRead(pirPinTualet) == HIGH) moveTualet = 1; else moveTualet = 0; if(digitalRead(pirPinKoridor) == HIGH) moveKoridor = 1; else moveKoridor = 0; if(digitalRead(pirPinWanna) == HIGH) moveWanna = 1; else moveWanna = 0; if(digitalRead(pirPinKuhnia) == HIGH) moveKuhnia = 1; else moveKuhnia = 0; String test = "T1"; test += lightTualet; test += "1T"; test += "T2"; test += lightKoridor; test += "2T"; test += "T3"; test += lightWanna; test += "3T"; test += "T4"; test += lightKuhnia; test += "4T"; test += "T5"; test += moveTualet; test += "5T"; test += "T6"; test += moveKoridor; test += "6T"; test += "T7"; test += moveWanna; test += "7T"; test += "T8"; test += moveKuhnia; test += "8T"; Serial.println(test); // вывожу в порт для настройки //Serial.print("Illumination Tualet"); //Serial.println( rawTualet ); //Serial.print("Illumination Koridor"); //Serial.println( rawKoridor ); // Serial.print("Illumination Wanna"); //Serial.println( rawWanna ); //Serial.print("Illumination Kuhnia"); //Serial.println( rawKuhnia ); delay (500); }
Приемник
String T1, T2, T3, T4, T5, T6, T7, T8; int lightTualet, lightKoridor, lightWanna, lightKuhnia, moveTualet, moveKoridor, moveWanna, moveKuhnia; void setup() { pinMode( 2, OUTPUT ); Serial.begin(115200); } void loop() { if(Serial.available()){ String Var=""; while (!Serial.available()) delay(20); delay(400); while (Serial.available()) Var = Var + (char)(Serial.read()); T1=Var.substring(Var.indexOf("T1")+2,Var.indexOf("1T")); T2=Var.substring(Var.indexOf("T2")+2,Var.indexOf("2T")); T3=Var.substring(Var.indexOf("T3")+2,Var.indexOf("3T")); T4=Var.substring(Var.indexOf("T4")+2,Var.indexOf("4T")); T5=Var.substring(Var.indexOf("T5")+2,Var.indexOf("5T")); T6=Var.substring(Var.indexOf("T6")+2,Var.indexOf("6T")); T7=Var.substring(Var.indexOf("T7")+2,Var.indexOf("7T")); T8=Var.substring(Var.indexOf("T8")+2,Var.indexOf("8T")); lightTualet = (T1.toInt()); lightKoridor = (T2.toInt()); lightWanna = (T3.toInt()); lightKuhnia = (T4.toInt()); moveTualet = (T5.toInt()); moveKoridor = (T6.toInt()); moveWanna = (T7.toInt()); moveKuhnia = (T8.toInt()); Serial.print(lightTualet); Serial.print(lightKoridor); Serial.print(lightWanna); Serial.print(lightKuhnia); Serial.print(moveTualet); Serial.print(moveKoridor); Serial.print(moveWanna); Serial.println(moveKuhnia); } if (lightTualet == 1) digitalWrite(2, LOW); if(lightTualet == 0) digitalWrite(2, HIGH); Serial.print("SVET: "); Serial.println(lightTualet); }
Вот ещё, ардуино соединена с NodeMCU проводами RX-TX, TX-RX, GND-GND
Можно все одним байтом передать, 8 бит как раз. Ну или если планируется наращивать можно двумя тремя байтами, там и до пакетной передачи дойдете :)
Можно все одним байтом передать, 8 бит как раз. Ну или если планируется наращивать можно двумя тремя байтами, там и до пакетной передачи дойдете :)
не силеня в програмировании, что поделать)
А не проще взять радиомодули и передавать сразу масив или пременную?
1 вариант.
2 вариант.
Примеры не знаю где искать :) Если кратко то у вас 4 зоны, в каждой зоне два типа датчика (как я понял датчик движения и датчик освещенности) тогда все эти данные можно уместить в 8 бит. Допустим есть переменная byte state; бит 7 отвечает за освещенность в туалете (1 освещен 0 нет) 6 бит за освещенность в коридоре 5 в ванне 4 в кухне, 3й за движение в туалете 2й в коридоре 1й в ванне и 0й в кухне. Тогда ваши условия будут такими
и дальше по аналогии. Имеете один байт и передаете его Serial.write(state);
На стороне приемника получаете этот байт и bitRead(state, 7) читаете и делаете что надо.
Номера битов лучше прописать константами или дефайнами типа #define bit_lightTualet 7
Примеры не знаю где искать :) Если кратко то у вас 4 зоны, в каждой зоне два типа датчика (как я понял датчик движения и датчик освещенности) тогда все эти данные можно уместить в 8 бит. Допустим есть переменная byte state; бит 7 отвечает за освещенность в туалете (1 освещен 0 нет) 6 бит за освещенность в коридоре 5 в ванне 4 в кухне, 3й за движение в туалете 2й в коридоре 1й в ванне и 0й в кухне. Тогда ваши условия будут такими
и дальше по аналогии. Имеете один байт и передаете его Serial.write(state);
На стороне приемника получаете этот байт и bitRead(state, 7) читаете и делаете что надо.
Номера битов лучше прописать константами или дефайнами типа #define bit_lightTualet 7
так?
т.е. я посылаю переменную state вида byte где каждый из восьми бит этой переменной содержит значение 0 или 1?
а странные значения в com это преобразование в аски?
Да, все правильно понимаете. Так довольно удобно работать с булевыми величинами
Да, все правильно понимаете. Так довольно удобно работать с булевыми величинами
Ещё на будующее, если у меня будет больше переменных (температура, влажность и др), то можно ли таким же образом передать, например, температуру от 18b20 равную 25,56 градуса?
Значения в порту нормальные, кубик это от write перевод в аски. По поводу температуры: как минимум два байта целая и дробная часть, а проще наверное просто float передавать и все.
Что-то не получается принять)
Передавайте именно Serial.write потому что println добавляет еще служебные символы.
Передавайте именно Serial.write потому что println добавляет еще служебные символы.
откуда Вы всё это знаете?))
а как теперь послать две переменные byte и принять каждую, как понять где какая?
а как теперь послать две переменные byte и принять каждую, как понять где какая?
Посылаете сначала X, а потом Y. При приеме та, что пришла первой - будет X.
... и откуда я это все знаю? - сам удивляюсь....
а как теперь послать две переменные byte и принять каждую, как понять где какая?
Посылаете сначала X, а потом Y. При приеме та, что пришла первой - будет X.
... и откуда я это все знаю? - сам удивляюсь....
Serial.write(state);
Serial.write(state1);
и принимать надо в той же последовательности?
можно лексический анализатор пабыстренькаму прикрутить
можно лексический анализатор пабыстренькаму прикрутить
мне бы попроще
Товарищи, с битами вроде разобрался. А как передать значение температуры с датчика?
Можно все одним байтом передать, 8 бит как раз. Ну или если планируется наращивать можно двумя тремя байтами, там и до пакетной передачи дойдете :)
Подскажите, пожалуйста, а как еще можно передавать данные через Serial? может с каким-то идентификатором, чтобы принимающая NodeMCU знала, что это значение относится к такой-то переменной?
Отправляйте не 1 байт а 3. Пусть первый байт будет state а два других это температура float. Принимаете это все дело в буфер размером 3и байта. А дальше с первым байтом понятно что делать, а второй и третий байт можно либо через указатели обработать либо memcpy скопировать, если предполагается, что буфер может затереться. Получится подобие "пакета".
Вариантов много, можно смотреть сколько байт приняли, если 1 то это state если два то это температура. Можно собрать полный пакет с заголовком, контрольной суммой и прочими штуками.
Отправляйте не 1 байт а 3. Пусть первый байт будет state а два других это температура float.
float - 4 байта
float - 4 байта
Да, точно, спасибо, флоат 4 байта, я просто думал об отправке температуры в виде двух байт (целое и после запятой) ну и под это дело затупил.
"2 байта: целое и после запятой" - это fixed (8.8).