Отправка сенсорной информации в ThingSpeak через Arduino Uno r3 и ESP8266-01 с помощью wifiManager - PullRequest
0 голосов
/ 14 марта 2019

У меня есть проект, в котором у меня есть датчик уровня воды, подключенный к моему Arduino Uno r3.У меня есть модуль ESP8266-01, подключенный к моему Arduino.Используя AT-команды, я смог загрузить результат датчика в ThinkSpeak.Однако я хотел иметь возможность войти в другие каналы Wi-Fi, поэтому я установил wifiManager.h, ESP8266WiFi.h, DNSServer.h и ESP8266WebServer.h на мой ESP8266, и все работало нормально.Поскольку он не мог подключиться из-за отсутствия IP-адреса и пароля, он открылся в режиме AP, и я подключился к нему со своего компьютера и вошел в систему.Я ввел свой IP-адрес и пароль и нажал SAVE, а ESP переработан и подключен.Сейчас я пытаюсь загрузить данные датчика в thingSpeak, но я думаю, что AT-команды больше не работают, так как я получаю сообщение об ошибке. EspData не был объявлен в этой области.Вот мой код.

// это новый код, который я поместил в ESP8266 и загрузил информацию с датчика в thinkSpeak с помощью GPIO 2. Как вы можете видеть, я использовал wifiManager для подключения к wifi, а затем прочитал датчик, работающий отArduino через порт GPIO 2.

#include <FS.h>

#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino

//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>         //https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h>

//NEW STUFF START

char apiKey[20]="";
WiFiClient client;

char defaultHost[100] = "api.thingspeak.com";  //Thing Speak IP address (sometime the web address causes issues with ESP's :/
    long itt = 500;
    long itt2 = 500;

const byte wifiResetPin = 13;
int interruptPinDebounce = 0;
long debouncing_time = 1000;
volatile unsigned long wifiResetLastMillis = 0;


bool shouldSaveConfig = false;

void saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;}

  void handleWifiReset(){
    if(millis()<wifiResetLastMillis){
      wifiResetLastMillis = millis();
    }
    if((millis() - wifiResetLastMillis)>= debouncing_time){
      Serial.println("Clearing WiFi data resetting");
      WiFiManager wifiManager;
      wifiManager.resetSettings();
      SPIFFS.format();
      ESP.reset();
      delay(1000);
    }
    wifiResetLastMillis = millis();
  }

void setup() {
  WiFiManager wifiManager;
    // put your setup code here, to run once:
    Serial.begin(115200);
    pinMode(wifiResetPin, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(wifiResetPin), handleWifiReset,FALLING);

    //NEW STUFF START
    //clean FS, for testing
  //SPIFFS.format();

  //read configuration from FS json
  Serial.println("mounting FS...");

  if (SPIFFS.begin()) {
    Serial.println("mounted file system");
    if (SPIFFS.exists("/config.json")) {
      //file exists, reading and loading
      Serial.println("reading config file");
      File configFile = SPIFFS.open("/config.json", "r");
      if (configFile) {
        Serial.println("opened config file");
        size_t size = configFile.size();
        // Allocate a buffer to store contents of the file.
        std::unique_ptr<char[]> buf(new char[size]);

        configFile.readBytes(buf.get(), size);
        DynamicJsonBuffer jsonBuffer;
        JsonObject& json = jsonBuffer.parseObject(buf.get());
        json.printTo(Serial);
        if (json.success()) {
          Serial.println("\nparsed json");
          strcpy(defaultHost, json["defaultHost"]);
          strcpy(apiKey, json["apiKey"]);
        } else {
          Serial.println("failed to load json config");
        }
      }
    }
  } else {
    Serial.println("failed to mount FS");
  }
  WiFiManagerParameter customHostServer("defaultHost", "Host Server", defaultHost, 100);
  WiFiManagerParameter customAPIKey("apiKey", "ThingSpeakWriteAPI", apiKey, 20);
//END NEW STUFF
    //WiFiManager
    //Local intialization. Once its business is done, there is no need to keep it around
   //WiFiManager wifiManager;

    //NEW STUFF START 
    wifiManager.setSaveConfigCallback(saveConfigCallback);
    wifiManager.addParameter(&customHostServer);
    wifiManager.addParameter(&customAPIKey);
     //END NEW STUFF
    //reset saved settings
   //wifiManager.resetSettings();

    //set custom ip for portal
    //wifiManager.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));

    //fetches ssid and pass from eeprom and tries to connect
    //if it does not connect it starts an access point with the specified name
    //here  "AutoConnectAP"
    //and goes into a blocking loop awaiting configuration
    wifiManager.autoConnect("AutoConnectAP");
    Serial.println("Connected");
  //NEW STUFF START
  strcpy(defaultHost, customHostServer.getValue());
  strcpy(apiKey, customAPIKey.getValue());
  if (shouldSaveConfig) {
    Serial.println("saving config");
    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.createObject();
    json["defaultHost"] = defaultHost;
    json["apiKey"] = apiKey;
    File configFile = SPIFFS.open("/config.json", "w");
    if (!configFile) {
      Serial.println("failed to open config file for writing");
    }

    json.printTo(Serial);
    json.printTo(configFile);
    configFile.close();
    //end save
  }
  Serial.println("local ip");
  Serial.println(WiFi.localIP());
  //END NEW STUFF
    //or use this for auto generated name ESP + ChipID
    //wifiManager.autoConnect();
pinMode(2,INPUT);
pinMode(1,INPUT);

    Serial.println("WriteApi");
    Serial.println(apiKey);


    //if you get here you have connected to the WiFi
    Serial.println("connected...yeey :)");
     //save the custom parameters to FS
     strcpy(defaultHost,customHostServer.getValue());
  strcpy(apiKey,customAPIKey.getValue());

}

//callback notifying us of the need to save config


void loop() {
  delay(5000);

String apiKey2 = apiKey;
char defaultHost[100] = "api.thingspeak.com";
  pinMode(2,INPUT);
  pinMode(1,INPUT);

  const int waterInPin = 2;  // Analog input pin that the potentiometer is attached to
    const int BatteryInPin = 1;  // Analog input pin that the potentiometer is attached to
    int waterSensorInValue;//reading our water lever sensor
int waterSensorOutValue;//conversion of water sensor value
int BatterySensorInValue;//reading our water lever sensor
int BatterySensorOutValue;//conversion of water sensor value
    // put your main code here, to run repeatedly:
    waterSensorInValue = analogRead(waterInPin);
   BatterySensorInValue = analogRead(BatteryInPin);
  waterSensorOutValue = map(waterSensorInValue,0,1024,0,225);
  BatterySensorOutValue = map(BatterySensorInValue,0,1024,0,225);
 Serial.println("WaterOutValue = ");
  Serial.println(waterSensorOutValue );
  Serial.println("WaterInValue = ");
  Serial.println(waterSensorInValue );
  Serial.println("BatteryOutValue = ");
  Serial.println(BatterySensorOutValue );
  Serial.println("BatteryInValue = ");
  Serial.println(BatterySensorInValue);
    delay(18000);
    itt = waterSensorInValue;
    itt2 = BatterySensorInValue;






    if (client.connect(defaultHost,80))
    { // "184.106.153.149" or api.thingspeak.com
        itt++;  //Replace with a sensor reading or something useful

        String postStr = apiKey;
        postStr +="&field1=";
        postStr += String(itt);
        postStr +="&field2=";
        postStr += String(itt2);
        postStr += "\r\n\r\n\r\n";

        client.print("POST /update HTTP/1.1\n");
        client.print("Host: api.thingspeak.com\n");
        client.print("Connection: close\n");
        client.print("X-THINGSPEAKAPIKEY: "+String (apiKey)+"\n");
        client.print("Content-Type: application/x-www-form-urlencoded\n");
        client.print("Content-Length: ");
        client.print(postStr.length());
        client.print("\n\n\n");
        client.print(postStr);

        Serial.println("% send to Thingspeak");
    }

    client.stop();

    Serial.println("Waiting…");

    delay(20000);
}

Я добавлю другой код на плату Arduino, не связанную с датчиком или интернетом. Однако приведенный выше код прекрасно работает, если он подключен к последовательному порту и работает сразу после загрузкикод.Если я отключаю Arduino от последовательного порта на компьютере, а затем повторное подключение ничего не происходит.Я думаю, что он должен продолжать запускать вышеуказанный код для подключения к Интернету, чтения датчика и отправки информации в thingSpeak, но это не так.Любые идеи, почему это происходит.

Я заменяю старый код на новый, который якобы сохраняет мои вещи. Speak write api в SPIFFS.Если я удаляю настройку, а затем загружаю с установленным размером флэш-памяти 512 КБ (128 КБ SPIFFS), FS монтирует и по умолчанию записывает ключ записи Host и Api в SPIFF, а затем ESP8266 перезапускает подключение к Интернету и переходит к thingSpeak и обновляет показания датчика.Проблема остается в том, что я хочу отключить ESP8266 для экономии энергии, но когда я перезагружаю его, запускается только петля (void), так что даже если он подключается к Wi-Fi и, возможно, даже к thingSpeak, он не обновляет входные сигналы датчика.Как получить ключ записи API-данных из SPIFFS в часть цикла (void) моего эскиза, чтобы он отправлял данные датчика в thingSpeak после выключения.Или я не подключаюсь к ThingSpeak.В любом случае, это другой вопрос, поэтому я сделаю репост с более конкретным вопросом и отмечу ответ.

1 Ответ

0 голосов
/ 28 марта 2019

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

...