• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

обмен данными между arduino и esp8266 по uart

Soyer

Member
Здравствуйте!
Прошу помощи, мучаюсь уже 3 дня, результат = 0
Необходимо с меги передать данные (в частности ssid и пароль WIFI сети).
Задумка такая: имеется целая куча устройств на базе ESP8266 (датчики уровня освещения, температурные датчики .... разбросанные по всему дому) которые подключаются к серверу HA по MQTT. Чтобы жестко не привязывать их к паролю и имени WiFi сети, и не использовать алгоритм создания этими устройствами точки доступа и WEB сервера с последующим вводом имени сети и пароля для каждого из множества устройств, решил этот процесс автоматизировать. А именно: ssid и пароль записываются на microSD которая вставляется в модуль на меге, мега при включении считывает их и передает по uart на ESP'шку настроенную сервером. Если устройства немогут подключиться к роутеру, они подключатся к серверу и запросят с него повторно данные подключения с помощью GET запроса, если они не изменились, то попытка подключения повторится, если изменились, то данные обновятся, и подключение произойдет с новыми ssid и pass.
на меге для подключения использую Serial1, и до передачи данных с меги пока не дощел, по задумке мега начнет передавать данные esp при получении запроса на них, и вот тут встрял:

C++:
//КОД АРДУИНО
#define esp Serial1 // меняем Serial1, на esp
#define READY_TO_RECEIVE_DATA 253 // ESP готов к приему данных
#define SSD  "ssid\"
#define PSSW "pass\"

char* ssid = "TNT";//для примера
char* pass = "HELLO";//для примера
String inputString = ""; 
bool cmdComplete = false;
void setup() {
  Serial.begin(9600);
  esp.begin(9600);
}

void loop() {
 
}

void serialEvent1() {
  while (esp.available()) {
    char inChar = (char)esp.read();
    inputString += inChar;
  }
   //вот тут получаю крякозябры ,
   //причем сразу после включения esp, до отправки запроса с нее
    Serial.print(inputString);
}
C++:
//ESP8266 (wemos D1 mini)
#define READY_TO_RECEIVE_DATA 253// готов к приему данных
char* ssid = "";
char* pass = "";
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  delay(500);
 //тут пробовал и Serial.write(READY_TO_RECEIVE_DATA), результат тот же
  Serial.print(READY_TO_RECEIVE_DATA, DEC);
}

void loop() {
  delay(1000);
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
в сериале меги лезут крякозябры:
вот скрин сериала ардуины до паузы (т.е. сразу после включения (сброса) esp)
ard_1.png
вот скрин сериала ардуины после передачи esp числа 253:
ard_2.png

вот скрин сериала esp сразу после включения (сброса):
esp_1.png
а вот скрин сериала esp после Serial.print(READY_TO_RECEIVE_DATA, DEC):
esp_2.png


Объясните, плиз, откуда этот мусор лезет, в какую сторону копать не используя AT команды?
Заранее спасибо!
 

CodeNameHawk

Moderator
Команда форума
//вот тут получаю крякозябры , //причем сразу после включения esp, до отправки запроса с нее
Это нормально, идет стартовая информация есп на скорости 74480.
Проблема тут
Код:
inputString += inChar;
надо за собой подчищать. Для проверки выкиньте плюс.
 
Последнее редактирование:

Soyer

Member
Это нормально, идет стартовая информация есп на скорости 74480.
Проблема тут
Код:
inputString += inChar;
надо за собой подчищать. Для проверки выкиньте плюс.
да, спасибо, получилось.
но, решил все-таки использовать софтверный на вемосе.
пока с парсингом, но потом буду делать по GET запросу:

C:
//arduino
#define esp Serial1 // меняем Serial1, на esp
#define READY_TO_RECEIVE_DATA_SSID 253// готов к приему данных ssid
#define READY_TO_RECEIVE_DATA_PASS 254// готов к приему данных pass
const char*  SSD = "ssid:";
const char*  PSS = "password:";

char* ssid = "TNT";
char* pass = "HELLO";
String inputString = "";         // a String to hold incoming data
bool cmdComplete = false;  // whether the string is complete
void setup() {
  Serial.begin(9600);
  esp.begin(9600);
}

void loop() {
  if (cmdComplete) {
    Serial.println(inputString);
    esp.println(inputString);
    inputString = "";
    cmdComplete = false;
  }
}

void serialEvent1() {
  bool cComp = false;
  int val = 0;
  while (esp.available()) {
    if (esp.peek() == '\n') {
      cComp = true;
    }
    val = esp.parseInt();
  }
  if (cComp == true) {
    cComp = false;
    switch (val) {
      case READY_TO_RECEIVE_DATA_SSID:
        inputString = SSD;
        inputString = inputString + ssid;
        inputString = inputString + "\n";
        cmdComplete = true;
        break;
      case READY_TO_RECEIVE_DATA_PASS:
        inputString = PSS;
        inputString = inputString + pass;
        inputString = inputString + "\n";
        cmdComplete = true;
        break;
    }
  }
}
C:
//esp8266(wemos)
#include <SoftwareSerial.h>
#define TX D1
#define RX D2
SoftwareSerial ard(RX, TX); // RX, TX

#define LED_ON_PULSE 1000   // ms
#define READY_TO_RECEIVE_DATA_SSID 253// готов к приему данных ssid
#define READY_TO_RECEIVE_DATA_PASS 254// готов к приему данных pass
String ssid = "";
String pass = "";
int key;
unsigned long previousMillis = 0;
String inputString;
bool stringComplete = false;
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  ard.begin(9600);
  delay(1000);

}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= LED_ON_PULSE) {
    previousMillis = currentMillis;
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  }
  if (Serial.available()) serialEvent();
  if (ard.available()) ard_Event();
  if (stringComplete) {
    Serial.print(inputString);
    inputString = "";
    stringComplete = false;
  }
}

void serialEvent() {
  char inChar = (char)Serial.read();
  inputString += inChar;
  if (inChar == '\n') {
    //парсинг
    char buf [inputString.length()];
    inputString.toCharArray(buf, sizeof(buf));
    if (!isDigit(buf[0])) {
      inputString = "";
      return;           //  если НЕ ЦИФРА,покидаем парсинг
    }
    else {
      key = buf[0];
      switch (key) {
        case 49:
          Serial.println("запрос ssid");
          inputString = "";
          ard.print("\n");
          ard.print(READY_TO_RECEIVE_DATA_SSID, DEC);
          break;
        case 50:
          Serial.println("запрос pass");
          inputString = "";
          ard.print("\n");
          ard.print(READY_TO_RECEIVE_DATA_PASS, DEC);
          break;
        default:
          key = 0;
          inputString = "";
          break;
      }
    }
  }
}
void ard_Event() {
  char inChar = (char)ard.read();
  inputString += inChar;
  if (inChar == '\n') {
    switch (key) {
      case 49:
        stringComplete = true;
        break;
      case 50:
        stringComplete = true;
        break;
    }
  }
}
 

Soyer

Member
Есть еще один вопрос:: Изначально хотел использовать задание ssid и password на microSD, но подумал, а что если считывать эти данные напрямую с роутера (ардуина подключена через ethernet кабель используя модуль W5100). Возможен ли такой вариант с помощью какого-то get запроса на роутер, или нет (интернет прошерстил, но так ничего найти не смог)?
Если нет, то тема думаю закрыта.
Спасибо!
 

Soyer

Member
Зайдите на роутер "вручную" если увидите ssid и password, тогда сможете их подучить, если не увидите, то и не получите.
Но вход на роутер то же по паролю...
То что по паролю это и так понятно, но как зайти в него, как этот запрос должен выглядеть? Или искать API именно для нужной модели роутера и их юзать? Может есть какая литература, которая прольет свет на эту тему?
 

max256

New member
То что по паролю это и так понятно, но как зайти в него, как этот запрос должен выглядеть? Или искать API именно для нужной модели роутера и их юзать? Может есть какая литература, которая прольет свет на эту тему?
а как зайти на роутер не подключившись к нему? а если уже подключились, зачем вам узнавать у него пароль, ведь вы его и так знаете раз подключились

UPD: сорри за некропост, не заметил (
 
Сверху Снизу