Thursday, November 16, 2017

ESP-8266 and Solving WDT Resets

So without adding much more complexity than WiFi to an ESP8266 sketch, you might get some WDT errors; if you have a serial link you can see the restart message, if not you might just notice a hang followed by a restart. Or not; if the hang is short enough but at the wrong (right?) time, you'll just get a restart.

Long story short: Writing software for the ESP8266 isn't like writing a blink sketch for an Arduino. But it's also not much different than writing a WiFi sketch for an Arduino, either. I think the primary difference is the libraries and Espressif SDK underpinning the ESP are a bit more complex, and it includes a hardware / software watchdog. If the watchdog timer expires, the system assumes that something hung, and restarts to recover.

There are some voodoo-type references to peppering your code with delay() and yield() statements to solve this. What I've done is wrap them in a simple function that manages  when to execute them.

There is one global (counter) and  you can call WDTPulse() whenever you might have a long running routine that won't quickly exit. Inside there is also a call to ESP.wdtFeed(), this requires no special #includes or other declarations as it's declared extern . It really does seem to feed the watchdog.

long counter;

// ******************************** wdt pulse ********************************
void WDTPulse() {
  if ( (counter % 100000) == 0 ) {
    ESP.wdtFeed();
    yield();
    delay(1); 
  }
  counter++;
}

// Example of use; within the possibly-never-ending WiFi setup:
while (stat != WL_CONNECTED) {
  WiFi.begin(ssid, pass);
  WiFi.waitForConnectResult();
  stat = WiFi.status();
  WDTPulse();
}


Or the as yet not totally tested version, which might be better....

// ******************************** wdt pulse ********************************
void WDTPulse() {
  if ( (counter % 100000) == 0 ) {
    ESP.wdtFeed();
    delay(1); 
  }
  yield();
  counter++;
}

Wednesday, November 15, 2017

ESP-8266 - Using UDP as a replacement for serial port debugging messages

The ESP-01 isn't exactly bristling with I/O pins, and running out of pins is a given. Assigning an entire pin for serial debugging output seems silly, so here is a thought; just send the strings via UDP to your workstation instead.

Below are two ways to do this.

In the first instance I'm using a String class which can copy itself to a global buffer, which is fine for quick-n-dirty messages, but as you'll see it is cumbersome for including variables.

It's just as easy to skip the String parameter and use sprintf to pre-fill the global char buffer. You get variable formatting with sprintf for free, too. Either way works and has a place. Unless you *really* hate the String class (some folks do).

// UDP_Test - Noel Dodd 2017
// One day I'll put this on git but for now, enjoy.


#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#define UDP_BUFFER_SIZE 256
#define DEBUG_PORT 10101
WiFiUDP UDP;
char udpBuffer[UDP_BUFFER_SIZE];
IPAddress logIP ( 172, 16, 25, 1 ); // Hardcoded destination IP address

uint8_t counter;

// ************ setup ****************
void setup() {
  // init
  counter = 0;

  // Do WiFi setup; hardcoded here for brevity
  IPAddress ip = IPAddress(172,16,25,100);
  IPAddress gw = IPAddress(172,16,25,1);
  IPAddress subnet = IPAddress(255,255,255,0);
  IPAddress dns = IPAddress(172,168,25,1);

  WiFi.persistent(false);
  WiFi.setAutoConnect(true);
  WiFi.mode(WIFI_STA);
  WiFi.config(ip,gw,subnet,dns); 
  
  int stat = WiFi.status();
  
  while (stat != WL_CONNECTED) {
    WiFi.begin("ssid", "pass");    // replace with real ssid, pass
    WiFi.waitForConnectResult();
    stat = WiFi.status();

    // optionally blink an LED here
    delay(50);
  }
  
  // Log that we are done, String method
  UDPSend( "Setup complete..." );  
}

// ************ Loop ****************
void loop() {
   // Log something (messy way, with Strings)
   String val = String(counter,DEC);
   String msg = String("String counter = " + val );
   UDPSend( msg );

   // Log something else (tidy, with sprintf)
   sprintf( udpBuffer, "Variable counter = %i", counter );
   UDPBufSend ( );

   // Do some work...
   delay(500);

   // Inc counter to see it work; let it wrap over 255
   counter++;
}

// ************ UDPSend ****************
void UDPSend ( String msg ) {

  // copy msg into buffer
  msg.toCharArray( udpBuffer, UDP_BUFFER_SIZE );
  
  UDP.beginPacket( logIP, DEBUG_PORT );
  UDP.write( udpBuffer, UDP_BUFFER_SIZE );
  UDP.endPacket();
  
}


// ************ UDPBufSend ****************
void UDPBufSend ( ) {

  UDP.beginPacket( logIP, DEBUG_PORT );
  UDP.write( udpBuffer, UDP_BUFFER_SIZE );
  UDP.endPacket();
  
}

Monday, November 13, 2017

Very quick note on eBay PIR HC-SR501 sensors and the ESP-8266

This is regarding the HC-SR501 sensor.

1. They work just fine.

2. Supply with +5V, and the signal output is +3.3V, so safe for the ESP-8266. I've measured mine as +3.33v output when supplied +5.04v from USB.

I can cite no written source for #2. "I read it somewhere on teh interwebz" so I tested it, and it appears safe.

I've also read that Espressif might have let the cat out of the bag on a forum post that the GPIO's are +5V tolerant.