MQTT Client логин/пароль к WiFi с SD карты

JIEXA
Offline
Зарегистрирован: 11.02.2015

Возникла необходимость подключаться к разным точкам доступа. Как это сделать?

Есть скетч клиента и скетч чтения данных с карты.

// скетч чтения данных с SD карты
#include <SPI.h>
#include <SD.h>
File myFile;
// Измените это в соответствии с вашей платой расширения или модулем;
const int chipSelect = 53;

char* names[2][1];
void setup() 
{
  // Открыть последовательное соединение и ждать открытия порта:
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");
  // вызавим функцию для загрузки .
  configSD();
}
void loop() 
{
  // после завершения настройки ничего не делать.
}
void configSD() // функции чтения конфигурационного файла с SD
{
  // вспомогательные переменные
  int h = 0; 
  int q = 0;       
  int d=2;
  char array[d][10];
  char *buffer;
  char symbol2 = 0;
  File configFile = SD.open("config.txt");
  if (configFile) 
  {
      Serial.println("config.txt open OK");
      // файл существует считываем из него данные 
        while  (configFile.available())   
        {
          // считываем байт входящего файла
          symbol2 = configFile.read();
           if (symbol2==';') // символ конца строки
          {
            array[q][h]='\0'; 
            q++; 
            h=0; 
          }
          else // если еще не конец строки посимвольно добавляем 
          {
            array[q][h] = symbol2; 
            h++;
          }
          delay(2);
        }
      configFile.close(); // закрываем файл
  }
  char *p;
  byte t;
  for (int j=0; j < d; j++) 
  {
    t = 0;
    for( buffer = strtok_r(array[j], ";", &p); buffer; buffer = strtok_r(NULL, ";", &p) )
    {
      names[j][t]=buffer; 
           
      t++;
         }
  }
   
      Serial.println(names[0][0]);//wifi сеть
      Serial.println(names[0][1]);//пароль от сети
     
}
// Скетч  mqtt клиента
/*
  SimpleMQTTClient.ino
  The purpose of this exemple is to illustrate a simple handling of MQTT and Wifi connection.
  Once it connects successfully to a Wifi network and a MQTT broker, it subscribe to a topic and send a message to it.
  It will also send a message delayed 5 seconds later.
*/

#include "EspMQTTClient.h"

EspMQTTClient client(
  "WifiSSID",
  "WifiPassword",
  "192.168.1.100",  // MQTT Broker server ip
  "MQTTUsername",   // Can be omitted if not needed
  "MQTTPassword",   // Can be omitted if not needed
  "TestClient",     // Client name that uniquely identify your device
  1883              // The MQTT port, default to 1883. this line can be omitted
);

void setup()
{
  Serial.begin(115200);

  // Optionnal functionnalities of EspMQTTClient : 
  client.enableDebuggingMessages(); // Enable debugging messages sent to serial output
  client.enableHTTPWebUpdater(); // Enable the web updater. User and password default to values of MQTTUsername and MQTTPassword. These can be overrited with enableHTTPWebUpdater("user", "password").
  client.enableLastWillMessage("TestClient/lastwill", "I am going offline");  // You can activate the retain flag by setting the third parameter to true
}

// This function is called once everything is connected (Wifi and MQTT)
// WARNING : YOU MUST IMPLEMENT IT IF YOU USE EspMQTTClient
void onConnectionEstablished()
{
  // Subscribe to "mytopic/test" and display received message to Serial
  client.subscribe("mytopic/test", [](const String & payload) {
    Serial.println(payload);
  });

  // Subscribe to "mytopic/wildcardtest/#" and display received message to Serial
  client.subscribe("mytopic/wildcardtest/#", [](const String & topic, const String & payload) {
    Serial.println(topic + ": " + payload);
  });

  // Publish a message to "mytopic/test"
  client.publish("mytopic/test", "This is a message"); // You can activate the retain flag by setting the third parameter to true

  // Execute delayed instructions
  client.executeDelayed(5 * 1000, []() {
    client.publish("mytopic/test", "This is a message sent 5 seconds later");
  });
}

void loop()
{
  client.loop();
}

Помогите объединить, чет не выходит.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так то надо? Объединить, или чтобы клиент мог к разным точкам подключаться?

JIEXA
Offline
Зарегистрирован: 11.02.2015

Надо чтоб клиент мог  к разным точкам подключаться. Я решил что чтение с SD карты настроек вайфай сети будет оптимальным решением. Но у меня не выходит эти два скетча объединить. Может есть какое другое решение?

Вот здесь EspMQTTClient client происходит настройка подключения клиента. как мне передать туда данные из SD карты.

sadman41
Offline
Зарегистрирован: 19.10.2016

Есть, конечно, решение. Забить на ардуину и пойти за грибами.

JIEXA
Offline
Зарегистрирован: 11.02.2015

грибы конечно хорошо, но лучше на море.

b707
Offline
Зарегистрирован: 26.05.2017

JIEXA пишет:

Помогите объединить, чет не выходит.

а в чем проблема то? Функцию configSD() из первого кода просто копируете во второй.  Из setup() первого кода добавляете в setup второго инициализацию SD карты и запуск функции configSD(). Туда же вставляете создание экземпляра EspMQTTClient, подставляя в параметры прочитанные в функции configSD() имя сети и пароль

JIEXA
Offline
Зарегистрирован: 11.02.2015
C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_302682\SimpleMQTTClient.ino: In function 'void onConnectionEstablished()':

SimpleMQTTClient:50:3: error: 'client' was not declared in this scope

   client.subscribe("mytopic/test", [](const String & payload) {

   ^

C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_302682\SimpleMQTTClient.ino: In lambda function:

SimpleMQTTClient:64:5: error: 'client' is not captured

     client.publish("mytopic/test", "This is a message sent 5 seconds later");

     ^

C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_302682\SimpleMQTTClient.ino: In function 'void loop()':

SimpleMQTTClient:70:3: error: 'client' was not declared in this scope

   client.loop();

Просто переставил как сказали.

JIEXA
Offline
Зарегистрирован: 11.02.2015
#include "EspMQTTClient.h"
#include <SPI.h>
#include <SD.h>

File myFile;
// Измените это в соответствии с вашей платой расширения или модулем;
const int chipSelect = 8;

char* names[2][1];

void setup()
{
  Serial.begin(115200);
Serial.print("Initializing SD card...");
  if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");
  // вызавим функцию для загрузки .
  configSD();

  EspMQTTClient client(
  "WifiSSID",
  "WifiPassword",
  "192.168.1.100",  // MQTT Broker server ip
  "MQTTUsername",   // Can be omitted if not needed
  "MQTTPassword",   // Can be omitted if not needed
  "TestClient",     // Client name that uniquely identify your device
  1883              // The MQTT port, default to 1883. this line can be omitted
);

  // Optionnal functionnalities of EspMQTTClient : 
  client.enableDebuggingMessages(); // Enable debugging messages sent to serial output
  client.enableHTTPWebUpdater(); // Enable the web updater. User and password default to values of MQTTUsername and MQTTPassword. These can be overrited with enableHTTPWebUpdater("user", "password").
  client.enableLastWillMessage("TestClient/lastwill", "I am going offline");  // You can activate the retain flag by setting the third parameter to true
}

// This function is called once everything is connected (Wifi and MQTT)
// WARNING : YOU MUST IMPLEMENT IT IF YOU USE EspMQTTClient
void onConnectionEstablished()
{
  // Subscribe to "mytopic/test" and display received message to Serial
  client.subscribe("mytopic/test", [](const String & payload) {
    Serial.println(payload);
  });

  // Subscribe to "mytopic/wildcardtest/#" and display received message to Serial
  client.subscribe("mytopic/wildcardtest/#", [](const String & topic, const String & payload) {
    Serial.println(topic + ": " + payload);
  });

  // Publish a message to "mytopic/test"
  client.publish("mytopic/test", "This is a message"); // You can activate the retain flag by setting the third parameter to true

  // Execute delayed instructions
  client.executeDelayed(5 * 1000, []() {
    client.publish("mytopic/test", "This is a message sent 5 seconds later");
  });
}

void loop()
{
  client.loop();
}

void configSD() // функции чтения конфигурационного файла с SD
{
  // вспомогательные переменные
  int h = 0; 
  int q = 0;       
  int d=2;
  char array[d][10];
  char *buffer;
  char symbol2 = 0;
  File configFile = SD.open("config.txt");
  if (configFile) 
  {
      Serial.println("config.txt open OK");
      // файл существует считываем из него данные 
        while  (configFile.available())   
        {
          // считываем байт входящего файла
          symbol2 = configFile.read();
           if (symbol2==';') // символ конца строки
          {
            array[q][h]='\0'; 
            q++; 
            h=0; 
          }
          else // если еще не конец строки посимвольно добавляем 
          {
            array[q][h] = symbol2; 
            h++;
          }
          delay(2);
        }
      configFile.close(); // закрываем файл
  }
  char *p;
  byte t;
  for (int j=0; j < d; j++) 
  {
    t = 0;
    for( buffer = strtok_r(array[j], ";", &p); buffer; buffer = strtok_r(NULL, ";", &p) )
    {
      names[j][t]=buffer; 
           
      t++;
         }
  }
   
      Serial.println(names[0][0]);//wifi сеть
      Serial.println(names[0][1]);//пароль от сети
     
}

 

b707
Offline
Зарегистрирован: 26.05.2017

JIEXA - вы зачем это все затеяли? - чтобы читать пароль и имя сети с SD карты, и потом подставить их в описание клиента, так? И где вы это в коде делаете?

Я очень в общих чертах обьяснил вам, что нужно делать. чтобы обьединить два кода. Но это не является пошаговой инструкцией, выполнив которую, вы получите готовую программу. Я не стал расписывать каждую запятую, иначе инструкция получилась бы слишком длинной. Это лишь направление, двигаясь по которому, вы должны сами переписать свой скетч.

Теперь вернемся к первому вопросу - кроме того, что в скетче куча ошибок, у вас в коде нет главного. Прочитав данные с карты, вы должны запомнить пароль и имя сети в переменных, которые потом подставить в вызов клиента. Ничего подобного у вас нет, вы так и инициализируете клиент с какими-то жестко забитыми строчками типа "WifiSSID","WifiPassword" вместо прочитанный с карточки данных

 

 

JIEXA
Offline
Зарегистрирован: 11.02.2015
"Туда же вставляете создание экземпляра EspMQTTClient"
 
Вы написали?
 
Я просто показал что это  вызывает ошибки.  А то что я не подставил в него переменные, это не главное. 
Я так понимаю куча ошибок в скетче чтения данных с SD карты? Не могли бы вы их указать?
b707
Offline
Зарегистрирован: 26.05.2017

JIEXA пишет:

"Туда же вставляете создание экземпляра EspMQTTClient"
 
Вы написали?
 
Я просто показал что это  вызывает ошибки.  А то что я не подставил в него переменные, это не главное. 
 
это как раз главное. Именно для того, чтобы в конструктор можно было подставить переменные, прочитанные с карты - я просил перенести его в setup(). Пока он у вас в глобальном поле, никакие переменные вы в него не добавите.
 
А ошибки это вызывает потому, что у вас клиент стал локальной переменной. Чтобы этого не происходило, указатель на клиент надо было оставить глобальным, а экземпляр клиента создавать методом new
JIEXA
Offline
Зарегистрирован: 11.02.2015

Спасибо, все получилось.