ESP8266 Wifi error code -301

23 views (last 30 days)
Phil Gaudet
Phil Gaudet on 18 Nov 2019
Edited: Vinod on 11 Apr 2022
Using new Adafruit Huzzah breakout with Arduino IDE 1.8.10, TS library 1.5.0 on MacOS 10.15.1 . Board always connects to fixed IP address on my network. It never connects to ThingSpeak, throwing a -301 error code. This same board works fine as a webserver and gets network time without a problem using other custom code. I have tried the TS Wifi example with no luck and used the thermistor example to create this code. Had an existing account in TS and just added a new channel. The new channelID and write API key along with SSID and PW are in a separate file called Credentials.h (not shown here). Tried generating new write API key, no joy.
/*
* Monitor solar battery charger sending current, voltage, temperature
* to Thingspeak
*
* Running on Adafruit ESP Hazzah breakout PID:2471
* Using FTDI Friend V1.0 PID:284 Jumpered for 5V power
*
* Board settings:
* BOARD: Adafruit Feather HUZZAH ESP8266
* Flash Size: 4M (1M SPIFFS)
*
* ESP8266 Connections:
* PIN VBATT - 6V BATTERY (+) (wht) WITH 1N4004 IN SERIES TO DROP SUPPLY BELOW 6V
* PIN GND - BATT (-) (blk)
* PIN 3V - INA219 VCC (red)
* PIN GND - INA219 GND (blk)
* PIN 5 SCL - I2C (grn) INA219(0x40)
* PIN 4 SDA - I2C (yel)
*
* Loosely based on https://www.mathworks.com/help/thingspeak/read-and-post-temperature-data.html
*
* v2 11/18/19 pg
* Add one-wire temp sensor
*
*/
#include <ESP8266WiFi.h>
#include <Wire.h>
#include "ThingSpeak.h"
#include "Credentials.h"
#include <Adafruit_INA219.h>
const uint8_t INA_ADDR = 0x40;
Adafruit_INA219 ina219;
bool INAConnected = false;
float shuntvoltage = 0;
float battvoltage = 0;
float current_mA = 0;
float loadvoltage = 0;
float power_mW = 0;
float batttemp = 0;
unsigned int dataFieldOne = 1; // Field to write current data
unsigned int dataFieldTwo = 2; // Field to write voltage data
unsigned int dataFieldThree = 3; // Field to write temperature data
WiFiClient client;
uint32_t lastConnectionTime = 0;
const unsigned long POSTING_INTERVAL = 20L * 1000L; // Post data every 20 seconds.
/******************************************************/
void setup() {
Serial.begin(115200);
Serial.println();
// Initialize the INA219.
// By default the initialization will use the largest range (32V, 2A). However
// you can call a setCalibration function to change this range (see comments).
ina219.begin();
// CHECK IF INA IS CONNECTED
Wire.beginTransmission (INA_ADDR);
if (Wire.endTransmission() == 0) {
Serial.print (F("I2C device found at 0x"));
Serial.println(INA_ADDR, HEX);
INAConnected = true;
}
else Serial.println(F("******** NO INA219 *********"));
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, pass);
WiFi.config(ip, gateway, subnet); // Connect to WiFi network as fixed IP
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.print("\nConnected at IP:"); Serial.println( WiFi.localIP().toString().c_str());
ThingSpeak.begin(client);
} // end setup
/**********************************************************/
void loop() {
// If interval time has passed since the last connection, send data to ThingSpeak.
if (millis() - lastConnectionTime > POSTING_INTERVAL)
{
lastConnectionTime = millis();
if(INAConnected)
{
shuntvoltage = ina219.getShuntVoltage_mV();
loadvoltage = ina219.getBusVoltage_V();
current_mA = ina219.getCurrent_mA();
power_mW = ina219.getPower_mW();
battvoltage = loadvoltage + (shuntvoltage / 1000);
batttemp = 0;
Serial.println("");
Serial.print("Load Voltage: "); Serial.print(loadvoltage); Serial.println(" V");
Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
Serial.print("Batt Voltage: "); Serial.print(battvoltage); Serial.println(" V");
Serial.print("Current: "); Serial.print(current_mA); Serial.println(" mA");
Serial.print("Power: "); Serial.print(power_mW); Serial.println(" mW");
Serial.print("Bat Temp: "); Serial.print(batttemp); Serial.println(" degC");
}
int httpCode = write2TSData(myChannelID,dataFieldOne, current_mA, dataFieldTwo, battvoltage, dataFieldThree, batttemp);
if (httpCode == 200) {
Serial.println("Channel write successful.");
}
else {
Serial.println("Problem writing to channel. HTTP error code " + String(httpCode));
}
} // end of interval timer
} // end loop
/********************************************************************************************
* Read data from a single field on a channel with readTSData. You can write a single value
* to ThingSpeak using writeTSData and write multiple values simultaneously with write2TSdata.
*/
float readTSData( long TSChannel,unsigned int TSField ){
float data = ThingSpeak.readFloatField( TSChannel, TSField, myReadAPIKey );
Serial.println( " Data read from ThingSpeak: " + String( data, 9 ) );
return data;
}
// Use this function if you want to write a single field.
int writeTSData( long TSChannel, unsigned int TSField, float data ){
int writeSuccess = ThingSpeak.writeField( TSChannel, TSField, data, myWriteAPIKey ); // Write the data to the channel
if ( writeSuccess ){
Serial.println( String(data) + " written to Thingspeak." );
}
return writeSuccess;
}
// Use this function if you want to write multiple fields simultaneously.
int write2TSData( long TSChannel, unsigned int TSField1, float field1Data, unsigned int TSField2, long field2Data, unsigned int TSField3, long field3Data ){
ThingSpeak.setField( TSField1, field1Data );
ThingSpeak.setField( TSField2, field2Data );
ThingSpeak.setField( TSField3, field3Data );
int writeSuccess = ThingSpeak.writeFields( TSChannel, myWriteAPIKey );
return writeSuccess;
}

Answers (3)

Phil Gaudet
Phil Gaudet on 20 Nov 2019
After spending the day slashing a burning I found that if I remove the line
WiFi.config(ip, gateway, subnet); // Connect to WiFi network as fixed IP
it works with deep sleep. Go figure.

Christopher Stapels
Christopher Stapels on 18 Nov 2019
For simplicity, perhaps you could try to write single field example in the thingSpeak library under esp8266. Im a big fan of the code you cited ofrom ThingSpeak, but the example in the library has even less going on. If you try that one, can you show the serial monitor output? I don't have the Huzzah but Ive sucessfully tested other ESP's with the library.

Phil Gaudet
Phil Gaudet on 18 Nov 2019
Christopher,
Thanks for the quick response. While trying to get this working I had updatad the ESP8266 board file and that caused a bunch of problems with compiling. It was looking for a python3 alias that the MacOS security couldn't deal with. I downgraded from ESP board file 2.6.1 to 2.5.2 and then it compiled and worked. So I noticed in the simple example that it checks if wifi is connected every time through the loop where I was connecting just once in setup. Is that necessary? I'm not sure why the example works and my code doesn't.
Screen Shot 2019-11-18 at 5.59.02 PM.png
  6 Comments
Milan Zajicek
Milan Zajicek on 11 Apr 2022
When I tried to send data to thingspeak frequently without delay, I saw, that only some requests ending with code 200 (but never the first, this was usually 301 or 401). This obscure hack solve my problem. Data are sent usually in second attempt.
int attempts = 0;
while (ok == 0) {
int x = ThingSpeak.writeField(myChannelNumber, 2, DS18B20_TEMP, myWriteAPIKey);
if(x == 200){
Serial.println("Channel update successful.");
ok = 1;
}
else{
Serial.println("Problem updating channel. HTTP error code " + String(x));
}
attempts = attempts + 1;
}
Vinod
Vinod on 11 Apr 2022
Edited: Vinod on 11 Apr 2022
@Milan Zajicek: Your code above needs to have delay(15000) statement inside the while loop so you are not exceeding the rate limit for your channel. A paid license allows you to drop the delay to 1000ms. Note that exceeding the rate limit wantonly can result in the account being restricted on ThingSpeak.
As to the root cause of why after a deep sleep on the ESP you get a -301, it is likely that somewhere in the stack the ESP is caching the IP address of api.thingspeak.com. This may not be the valid IP address after a sleep and wakeup depending on how long the device is in deep sleep. The correct solution will be to use the dns_gethostbyname() function with the https://api.thingspeak.com address after the device wakes up from a deep sleep.

Sign in to comment.

Communities

More Answers in the  ThingSpeak Community

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!