0

我有一个项目,其中我有一个连接到我的 Arduino Uno r3 的水位传感器。我有一个连接到我的 Arduino 的 ESP8266-01 模块。使用 AT 命令,我能够将传感器结果上传到 ThinkSpeak。但是我希望能够登录其他 wifi 频道,所以我将 wifiManager.h、ESP8266WiFi.h、DNSServer.h 和 ESP8266WebServer.h 放在我的 ESP8266 上,一切正常。由于没有IP和密码而无法连接,因此它以AP模式打开,我从计算机连接到它并登录。我输入了我的 IP 地址和密码,然后点击保存,ESP 被回收并连接。我现在正在尝试将传感器数据上传到 thingSpeak,但我认为 AT 命令不再起作用,因为我收到错误 espData is not declared in this scope。这是我的代码。

//这是我放到 ESP8266 上的新代码,并使用 GPIO 2 从传感器上传信息到 thinkSpeak 如您所见,我使用 wifiManager 连接到 wifi,然后通过 GPIO 2 端口读取由 Arduino 供电的传感器。

#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 发送信息,但事实并非如此。任何想法为什么会发生这种情况。

我用新代码替换了旧代码,据说可以将我的 thingSpeak 写入 API 保存到 SPIFFS。如果我删除设置,然后将闪存大小设置为 512k (128k SPIFFS) 上传,则 FS 挂载并将默认主机和 Api 写入密钥保存到 SPIFF,然后 ESP8266 重新启动连接到互联网并转到thingSpeak 并更新传感器读数。问题仍然是我想关闭 ESP8266 以节省能源,但是当我重新启动它时,只有 (void) 循环运行,所以即使它连接到 wifi,甚至可能连接到 thingSpeak,它也不会更新传感器输入。如何从 SPIFFS 获取信息 api 写入密钥到我的草图的 (void) 循环部分,以便它在关闭后将传感器数据发送到thingSpeak。或者我没有连接到 ThingSpeak。

4

1 回答 1

0

这回答了我在使用 ESP8266 和 Arduino uno 连接到不同的 wifi 和密码以及添加自定义参数的过程中遇到的很多问题。我仍然有一些问题,但会在单独的帖子中询问,希望有人可以帮助我。

于 2019-03-28T05:37:40.460 回答