Передача данных от ардуино нано к 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
#define bit_lightTualet 7 #define bit_lightKoridor 6 #define bit_lightWanna 5 #define bit_lightKuhnia 4 #define bit_moveTualet 3 #define bit_moveKoridor 2 #define bit_moveWanna 1 #define bit_moveKuhnia 0 byte state; void loop() { rawTualet = analogRead( pinPhotoTualet ); rawKoridor = analogRead( pinPhotoKoridor ); rawWanna = analogRead( pinPhotoWanna ); rawKuhnia = analogRead( pinPhotoKuhnia ); if(rawTualet >= 400) bitSet(state, bit_lightTualet); else bitClear(state, bit_lightTualet); if(rawKoridor >= 400) bitSet(state, bit_lightKoridor); else bitClear(state, bit_lightKoridor); if(rawWanna >= 400) bitSet(state, bit_lightWanna); else bitClear(state, bit_lightWanna); if(rawKoridor >= 400) bitSet(state, bit_lightKuhnia); else bitClear(state, bit_lightKuhnia); Serial.write(state); Serial.println(state);так?
т.е. я посылаю переменную state вида byte где каждый из восьми бит этой переменной содержит значение 0 или 1?
а странные значения в com это преобразование в аски?
Да, все правильно понимаете. Так довольно удобно работать с булевыми величинами
Да, все правильно понимаете. Так довольно удобно работать с булевыми величинами
Ещё на будующее, если у меня будет больше переменных (температура, влажность и др), то можно ли таким же образом передать, например, температуру от 18b20 равную 25,56 градуса?
Значения в порту нормальные, кубик это от write перевод в аски. По поводу температуры: как минимум два байта целая и дробная часть, а проще наверное просто float передавать и все.
Что-то не получается принять)
#define bit_lightTualet 7 #define bit_lightKoridor 6 #define bit_lightWanna 5 #define bit_lightKuhnia 4 #define bit_moveTualet 3 #define bit_moveKoridor 2 #define bit_moveWanna 1 #define bit_moveKuhnia 0 byte state; void setup() { pinMode( 2, OUTPUT ); Serial.begin(115200); } void loop() { if (Serial.available() > 0) { state = Serial.read(); } if (bitRead(state, bit_lightTualet) == 1) digitalWrite(2, LOW); if(bitRead(state, bit_lightTualet) == 0) digitalWrite(2, HIGH); Serial.println(state); }Передавайте именно 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).