Go Down

Topic: Receive topics on subscribe to MQTT is spotty (Read 399 times) previous topic - next topic

BlueRidgeDog

I have a Uno with a ESP8266 connected to software serial. It publishes and subscribes to an MQTT server on the same local wireless network. The current code (below) is just mock-up to get the flow to MQTT then to Node Red working so that the code can be moved to the larger project that needs to report status and take input from MQTT.

It works well for publish, but if a third party publishes to a topic that the Uno is subscribed to, there is less than a 70% chance the Uno will get the topic notice (that controls a light in this example). To trigger a change on the Uno often takes four or more publish activities. I was going to solve this with some logic on the publish side that simply publishes to the topic until the desired change is observed, but it may just be my code (more hack than programmer).

I have tried to remove blocking in the code and reduced the frequency of publish activity to keep the network connection generally open. The Uno to ESP8266 connection is at 9600 and I suspect that may be part of the issue (but that is required by WiFiEsp.h).

So, in short, if you see any reason I am creating the low success rate for subscribed topics, please feel free to make suggestions.

Code: [Select]
#include <WiFiEsp.h>
#include <PubSubClient.h>

#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(10, 11); // RX, TX
#endif

const char* ssid = "RavensNest";
const char* password = "bigkites";
const char* mqtt_server = "192.168.0.151";

WiFiEspClient espClient;
PubSubClient client(espClient);

// Variables
long lastMsg = 0;
char msg[50];
int value = 0;
int BUILTIN_LED = 13;
String clientId = "AquariumController";
long lastReconnectAttempt = 0;


void setup() {
  pinMode(BUILTIN_LED, OUTPUT);
  Serial.begin(115200);
  Serial1.begin(9600);
  // initialize ESP module
  WiFi.init(&Serial1);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {

  if (!client.connected()) {
    long now = millis();
    if (now - lastReconnectAttempt > 5000) {
      lastReconnectAttempt = now;
      // Attempt to reconnect
      if (reconnect()) {
        lastReconnectAttempt = 0;
      }
    }
  } else {
    // Client connected
    client.loop();
  }
  PublishMQTT();
}

void PublishMQTT()  {
  long now = millis();
  if (now - lastMsg > 10000) {
    lastMsg = now;
    ++value;
    snprintf (msg, 50, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("outTopic", msg);
  }
}

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  randomSeed(micros());
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);
  } else {
    digitalWrite(BUILTIN_LED, HIGH);
  }
}

void SubscribeMQTT()  {
  client.subscribe("inTopic");
}

bool reconnect() {
  if (client.connect(clientId.c_str())) {
    Serial.println("connected");
    SubscribeMQTT();
  }
  return client.connected();
}

pert

The Uno to ESP8266 connection is at 9600 and I suspect that may be part of the issue (but that is required by WiFiEsp.h).
This is incorrect. The reason why you must use 9600 baud is that is the default baud rate of the AT firmware on the ESP8266. You can use an AT command sent to the ESP8266 to increase the communication baud rate of the AT firmware if you want to increase it. You will find instructions in the ESP8266 AT command reference documentation.

Juraj

#2
Nov 18, 2019, 11:37 am Last Edit: Nov 18, 2019, 11:40 am by Juraj
This is incorrect. The reason why you must use 9600 baud is that is the default baud rate of the AT firmware on the ESP8266. You can use an AT command sent to the ESP8266 to increase the communication baud rate of the AT firmware if you want to increase it. You will find instructions in the ESP8266 AT command reference documentation.
the default baud rate of AT firmware is 115200. the WiFiEsp library is usually used over SoftwareSerial on Uno. but the library doesn't work good at higher baud rates, so 9600 baud is recommended on hardware Serial too.

@BlueRidgeDog, if you can update the AT firmware to AT 1.7.1 (SDK 3), I recommend you to use my new WiFiEspAT library

pert

Oops, I completely got that backwards. Thanks for straightening that out Juraj! I didn't know the WiFiEsp library didn't work well with 115200 on hardware serial ports (of course I am aware that you can't do it on software serial port).

BlueRidgeDog

if you can update the AT firmware to AT 1.7.1 (SDK 3), I recommend you to use my new WiFiEspAT library
Thanks.  I have not flashed one of these.  Not flashed anything in 20 years!  But I will give it a try, but I have to get a USB to serial plug (or just cut a cable????) and I have one on order (as I was simply going to put the code on the ESP8266 and test it as a stand alone to see if the issue was indeed the library).  Looking over your library, it appears that it is a replacement for the one I am using, but requires the newer AT version, and can run at higher speeds. 

This is incorrect. The reason why you must use 9600 baud is that is the default baud rate of the AT firmware on the ESP8266.
This was my initial thinking as well and for the longest time I thought the chip was bad or my code was bad as you have to really dig to realize that when they use 9600 for the library, it is not an example, but a requirement.  I can use the library and connected to wifi at higher baud rates, but it degenerates and fails.

Juraj

you can use the USB adapter of Uno. upload Blink into ATmega (because Blink doesn't use Serial) and then wire the esp8266 to RX,TX of Uno as RX to RX and TX to TX. this will connect the esp8266 to the USB chip of Uno as RX to TX. put the esp8266 in flashing mode by wiring io 0 to ground (oi0 LOW at boot goes into flashing mode). the esptool or FDT parameters are in README.md of the library

BlueRidgeDog

you can use the USB adapter of Uno. upload Blink into ATmega (because Blink doesn't use Serial) and then wire the esp8266 to RX,TX of Uno as RX to RX and TX to TX. this will connect the esp8266 to the USB chip of Uno as RX to TX. put the esp8266 in flashing mode by wiring io 0 to ground (oi0 LOW at boot goes into flashing mode). the esptool or FDT parameters are in README.md of the library
Thanks.  If my adapter is slow to arrive I will try that.  Is blink important or any empty sketch?  I will need to solder a lead to 0, but that is not a problem (my breakout adapter has only VCC, GND, TX and RX exposed).  On the RX to RX issue, that was another hurdle as normal TX to RX wiring on the Uno is reversed.  I had level shifted TX on the on the Uno only to find out it was RX.

The final project is to run on a mega and will be on hardware serial, but I debug each component on the uno as the project is getting so large that it is far easier to do one item (WiFi, sensors, relays etc) at a time.


Juraj

Thanks.  If my adapter is slow to arrive I will try that.  Is blink important or any empty sketch?  I will need to solder a lead to 0, but that is not a problem (my breakout adapter has only VCC, GND, TX and RX exposed).
empty sketch is good too.
doesn't the adapter have some buttons?

BlueRidgeDog

doesn't the adapter have some buttons?
I should have (tomorrow) a simple USB to serial via breadboard as well as a breadboard to ESP adapter, so I should be able to give it a shot.  Right now it is on a mounting board that does the level conversion for RX as well as supplies a beefier 3v.

Juraj

#9
Nov 19, 2019, 07:24 am Last Edit: Nov 19, 2019, 07:31 am by Juraj
I should have (tomorrow) a simple USB to serial via breadboard as well as a breadboard to ESP adapter, so I should be able to give it a shot.  Right now it is on a mounting board that does the level conversion for RX as well as supplies a beefier 3v.
for flashing it will be good, but the adapter can't supply enough current on 3.3 V pin to run WiFi of the esp8266 and the AP starts at default so the firmware crashes immediately.


BlueRidgeDog

Well, a small snag.  0 is to ground.  Pulling 3.3v off of usb adapter with level converter built in for TX.  I can connect, erase, but not flash.

Code: [Select]
jervin@Ripstop:~/Arduino/ESP8266_AT_LoBo-master/at_lobo$ ./flash.sh -t 1MB

==========================
Flashing ESP8266 firmware:
--------------------------
  Flash type: 1MB
  Flash mode: qio
   Partition: 0
     Address: 0x001000
    Firmware: '../bin/upgrade/esp8266_AT_1_2.bin'
 Erase Flash: 'yes'
================================================

esptool.py v2.8
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 4c:11:ae:03:ca:91
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 0.0s
Staying in bootloader.

esptool.py v2.8
Serial port /dev/ttyUSB0
Connecting........_____....._____....._____....._____....._____....._____....._____

A fatal error occurred: Failed to connect to Espressif device: Timed out waiting for packet header

Flash write failed!
jervin@Ripstop:~/Arduino/ESP8266_AT_LoBo-master/at_lobo$

BlueRidgeDog

Okay...got the flash, for those interested:  Pull GPIO0 to 3.3v, pull rst to 3.3v, each with a 10K resistor.  Power on the chiip.  Start the flash, when it is trying to connect, pull rst to ground and hold, then pull GPIO0 to ground and hold, release rst, then release GPIO0.  You have to do this while it is "connecting".  Now on to trying the new library.



Code: [Select]
esptool.py v2.8
Serial port /dev/ttyUSB0
Connecting........_____....._____....._____....._
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 4c:11:ae:03:ca:91
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Compressed 128 bytes to 75...
Wrote 128 bytes (75 compressed) at 0x000fc000 in 0.0 seconds (effective 64.3 kbit/s)...
Hash of data verified.
Flash params set to 0x0020
Compressed 4080 bytes to 2696...
Wrote 4080 bytes (2696 compressed) at 0x00000000 in 0.1 seconds (effective 511.2 kbit/s)...
Hash of data verified.
Compressed 1684 bytes to 1206...
Wrote 1684 bytes (1206 compressed) at 0x0007b000 in 0.0 seconds (effective 422.1 kbit/s)...
Hash of data verified.
Compressed 435348 bytes to 313261...
Wrote 435348 bytes (313261 compressed) at 0x00001000 in 28.4 seconds (effective 122.8 kbit/s)...
Hash of data verified.

Leaving...
Staying in bootloader.

Finished.

BlueRidgeDog

Okay.  I change the wifi library, only making the following code changes:

Code: [Select]

#include "WiFiEspAT.h"
WiFiClient espClient;


....and there is no lag in the MQTT subscribe process...buttons in node red work like buttons!  I am still on software serial as the UNO lacks HW, but when the project is moved to the mega I can configure the speed back to 115200 (bumping the ESP back up with AT+UART_DEF=115200,8,1,0,0)

The only real problem is flashing this little thing.

Now on to the next portion of the project...three final sensors then the AquariumControl system will be done.  Well, the prototype, then I get to build a board and an enclosure.

Juraj

io 0 must be LOW at boot to go in flashing mode. but the powering must be good. that is why the flashing with USB of Uno or over hardware serials with SerialPassthrough sketch is better

Go Up