RPi + ESP8266 stability issues - raspberry-pi3

I was recently working on a home automation project which has finally come to end and I am thinking to install it in my home. First of all, I would like to brief you with the basic architecture.
I am using a Raspberry Pi 3 as the central controller node which is running Node-Red and its Mosca palette. Currently, there are 5 ESP-01 in the project. Four of them are wired up with a relay and the remaining ESP is wired up with a DHT11 temperature sensor. Almost everything is running good but I am facing some stability issues, like, when I recycle the power the ESP-01 doesn't run the program. Serial monitor stays blank. However, when I disconnect the GPIO2 from the relay and then power up the ESP. The program begins. So, I have to pull out the GPIO2 then power up the ESP then connect the GPIO2 with the relay on every power recycle. Another problem which I am facing is sometimes the ESP crashes automatically. It sometimes prints out fatal exception(0) or soft wdt reset even though I have added a watchdog timer.
Here is the code for one of the client ESP:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
const char* ssid = "........";
const char* password = ".........";
const int led = 13;
const char* mqtt_server = "192.168.1.8";
WiFiClient espClient;
PubSubClient client(espClient);
const int ledGPIO2 = 2;
void setup_wifi() {
int i;
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("WIFI BEGUN");
while (WiFi.status() != WL_CONNECTED) {
ESP.wdtFeed();
delay(500);
i++;
if ((i&0x01)==0){
digitalWrite(led, 0);
} else {
digitalWrite(led, 1); // led should start blinking at .5 seconds
}
Serial.print(".");
if (i>1000) break; // get out after 50 seconds
if (i==1000){
}
Serial.print(".");
Serial.println("");
Serial.print("WiFi connected - ESP IP address: ");
Serial.println(WiFi.localIP());
}
}
void callback(String topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
if(topic=="Lamp1"){
Serial.print("Changing GPIO 2 to ");
if(messageTemp == "on"){
digitalWrite(ledGPIO2, HIGH);
Serial.print("On");
}
else if(messageTemp == "off"){
digitalWrite(ledGPIO2, LOW);
Serial.print("Off");
}
}
Serial.println();
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect("ESP8266Client")) {
Serial.println("connected");
client.subscribe("Lamp1");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup() {
pinMode(ledGPIO2, OUTPUT);
digitalWrite(ledGPIO2, true);
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
if(!client.loop())
client.connect("ESP8266Client");
}
Also, I have been thinking for an efficient power supply for ESP. Batteries cannot be reliable for long-term and powering up via an adapter would be unfeasible as the module is going to be mounted on the wall. Moreover, ac to dc converter was something which seems to be a decent way for power supply.
Vcc - 3.3V
CH_PD - 3.3V
Tx - Tx (Arduino)
Rx - Rx (Arduino)
GPIO0 - GND (while uploading the sketch)/ 3.3V
GND - GND
I am not using capacitors or resistors. I am getting a 5V supply from Arduino which is regulated to 3.3V using LD33V voltage regulator.
Any suggestions would be appreciated. Thank You!!

Related

Esp32-WROOM-32D can't connect to my home wifi

I am trying to get my esp32 to connect to my wifi, but it attempts forever without connecting. I don't think there is anything wrong with the code. I'm thinking the issue is something with my router.
#include<WiFi.h>
const char *ssid = "mySSID";
const char *password = "myPW";
void initWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
Serial.println(WiFi.localIP());
}
void setup() {
Serial.begin(115200);
initWiFi();
Serial.print("RRSI: ");
Serial.println(WiFi.RSSI());
}
void loop() {
// put your main code here, to run repeatedly:
}
I have a netgear router that puts out a 2.4G and 5G network. I ran a WiFi scan sketch on my esp32 and it successfully saw my 2.4Ghz wifi and identified it was using WPA2. I checked my router log and saw it thought my esp32 connection attempts were DoS attacks so i disabled DoS protection, and added my esp32's mac address to the allow list. None of that worked. any ideas here?
I checked my code vs your code. I can only see one difference.
// Debug information
#define DEBUG 1
#if DEBUG ==1
#define debug(x) Serial.print(x)
#define debugln(x) Serial.println(x)
#else
#define debug(x)
#define debugln(x)
#endif
#define vtDelay(x) vTaskDelay(x / portTICK_PERIOD_MS)
void initWiFi() {
debug("Start initWiFi");
// Set WiFi to station mode and disconnect from an AP if it was previously connected
WiFi.mode(WIFI_STA);
//WiFi.disconnect();
vtDelay(1000);
WiFi.begin(ssid, password);
debugln("Connecting to WiFi ..");
WiFiAttempts = 1;
while (WiFiRet != WL_CONNECTED ) {
WiFiRet = WiFi.status();
debug("WiFi.status = ");
debug(WiFiRet);
debug(" WiFiAttempts = ");
debugln(WiFiAttempts++);
vtDelay(1000);
if (WiFiAttempts > 20) {
debugln("Restarting the ESP32");
ESP.restart();
}
}
debugln(WiFi.localIP());
}
This works for me the only difference was the vtDelay for 1000 milliseconds. I am also using my 2.4G and have security set to 'WPA2-PSK'.
I hope this helps.

how to solve meaningless characters on serial montior Arduino

Hi i am new at Arduino Uno , i am trying to use imu sensor and read datas from it so i installed mpu9500 lib from arduino website and run one example from its lib. However as i open the serial monitor, it displays strange characters . I check the pin configuration many times and load different libs and examples but i could not fix it.
Here is the codes i run.
#include "MPU9250.h"
MPU9250 mpu;
void setup() {
Serial.begin(115200);
Wire.begin();
delay(2000);
if (!mpu.setup(0x68)) { // change to your own address
while (1) {
Serial.println("MPU connection failed. Please check your connection with `connection_check` example.");
delay(5000);
}
}
}
void loop() {
if (mpu.update()) {
static uint32_t prev_ms = millis();
if (millis() > prev_ms + 25) {
print_roll_pitch_yaw();
prev_ms = millis();
}
}
}
void print_roll_pitch_yaw() {
Serial.print("Yaw, Pitch, Roll: ");
Serial.print(mpu.getYaw(), 2);
Serial.print(", ");
Serial.print(mpu.getPitch(), 2);
Serial.print(", ");
Serial.println(mpu.getRoll(), 2);
}
And this is what i get also i changed value of boud but nothing changed
01:10:23.688 -> ⸮7в⸮⸮⸮⸮⸮⸮`f⸮⸮⸮⸮⸮f⸮⸮⸮~⸮⸮xxf⸮~⸮⸮fx⸮⸮⸮⸮⸮⸮怘⸮
Try running simple Serial print code at the same baud rate(115200) and check if your board is alright. Then run the following code once:
#include "MPU9250.h"
MPU9250 mpu; // You can also use MPU9255 as is
void setup() {
Serial.begin(115200);
Wire.begin();
delay(2000);
mpu.setup(0x68); // change to your own address
}
void loop() {
if (mpu.update()) {
Serial.print(mpu.getYaw()); Serial.print(", ");
Serial.print(mpu.getPitch()); Serial.print(", ");
Serial.println(mpu.getRoll());
}
}

ArduinoHTTPClient websocket undocumented max message size?

I have an Arduino MKRNB 1500 (with LTE-M network capability).
My code uses a websocket to upload messages to a server. The messages are uploaded every second or so of around 800-1000 bytes. My websocket server accepts these messages (i have tried with a browser client). But the ArduinoHTTPClient library WebSocketClient refuses to send messages that are over 128 bytes. The Arduino just hangs from that point onwards.
Because of the network latency, this means i cannot send more than around 600 bytes a second.
This limitation seems arbitrary, and is not documented as far as i have seen. It can be easily reproduced using the following code. Sending smaller messages more frequently is not an option because the network latency of LTE-M is around 150ms.
How can i send larger messages?
#include <ArduinoHttpClient.h>
#include <MKRNB.h> //For LTE-M or NB-IOT connections
#include "arduino_secrets.h"
// initialize the LTE-M library instance
NBClient nbClient;
GPRS gprs;
NB nbAccess;
char server[] = "echo.websocket.org"; // server address
const char PINNUMBER[] = "0000"; // = SIM SECRET_PINNUMBER;
int port = 80; // port 80 is the default for HTTP
WebSocketClient client = WebSocketClient(nbClient, server, port);
int count = 120;
void setup() {
Serial.begin(9600);
// LTE-M connection
Serial.println(F("Connecting to LTE-M network"));
boolean connected = false;
while (!connected) {
if ((nbAccess.begin(PINNUMBER) == NB_READY) &&
(gprs.attachGPRS() == GPRS_READY)) {
connected = true;
} else {
Serial.println("Not connected");
delay(1000);
}
}
}
void loop() {
Serial.println("starting WebSocket client");
client.begin();
while (client.connected() and count <= 1000) {
Serial.print("Sending hello ");
Serial.println(count);
// send a hello #
client.beginMessage(TYPE_TEXT);
client.print(count);
client.print(": ");
int i = 0;
while (i<= count){
client.print("X");
i++;
}
client.endMessage();
// increment count for next message
count++;
// check if a message is available to be received
int messageSize = client.parseMessage();
if (messageSize > 0) {
Serial.println("Received a message:");
Serial.println(client.readString());
}
delay(1000);
}
Serial.println("disconnected");
}
After examining the ArduinoHttpClient library, it turns out the WebSocketClient.h file has a limited buffer defined on line 89:
uint8_t iTxBuffer[128];
i changed that to
uint8_t iTxBuffer[4096];
And the problem was resolved.
custom size must be supported soon.
https://github.com/arduino-libraries/ArduinoHttpClient/issues/68

Attiny85 with ArduinoUno for I2c comm

I am working on attiny85 for I2C communication. I have gone through different libraries already like Wire.h, TinyWire.h, tinyWireM.h, tinyWireS.h.
In the start I want to send some byte of data through I2C comm and tried to scope the pin with oscilloscope but its not giving me the appropriate results. Looking on the internet about different ways to make attiny85 work with I2c is really heartless and I could not achieve the task. Finally, I tried to make attiny85 as master and arduino Uno as slave as it was spare in my box.
I tried to make attiny85 as master and send data to arduino and looks the output on serial monitor but its showing zero.
For the reference, the master and slave codes are attached and my task is just simple to check on serial.
Attiny85 as Master
#include <TinyWireM.h>
void setup()
{
TinyWireM.begin();
}
void loop()
{
TinyWireM.begin();
TinyWireM.beginTransmission(0x08);
TinyWireM.send(0x99);
int Byte1 = TinyWireM.endTransmission();
delay(1000);
}
Arduino as Slave
#include <Wire.h>
const byte add = 0x08;
int byte1;
void setup()
{
Wire.begin(add);
Wire.onReceive(receiveEvent);
Serial.begin(9600);
}
void loop()
{
Serial.println ("Data receiving");
Serial.println(byte1);
delay(1000);
}
void receiveEvent(int bytes)
{
byte1 = Wire.read();
}
But I am not able to get the output on serial monitor of arduino.
What am i doing wrong here?
I have used Atiny85 as a slave using TinyWireS lib (https://github.com/nadavmatalon/TinyWireS) some time back and it worked fine.
Below were the pin configurations
ATtiny85 pin 5 with Arduino Uno A4 and
ATtiny85 pin 7 with Arduino Uno A5
Below are my codes
Atiny.
#include "TinyWireS.h"
const byte SLAVE_ADDR = 100;
const byte NUM_BYTES = 4;
volatile byte data = { 0, 1, 2, 3 };
void setup() {
TinyWireS.begin(SLAVE_ADDR);
TinyWireS.onRequest(requestISR);
}
void loop() {}
void requestISR() {
for (byte i=0; i<NUM_BYTES; i++) {
TinyWireS.write(data[i]);
data[i] += 1;
}
}
Uno.
#include <Wire.h>
const byte SLAVE_ADDR = 100;
const byte NUM_BYTES = 4;
byte data[NUM_BYTES] = { 0 };
byte bytesReceived = 0;
unsigned long timeNow = millis();
void setup() {
Serial.begin(9600);
Wire.begin();
Serial.print(F("\n\nSerial is Open\n\n"));
}
void loop() {
if (millis() - timeNow >= 750) { // trigger every 750mS
Wire.requestFrom(SLAVE_ADDR, NUM_BYTES); // request bytes from slave
bytesReceived = Wire.available(); // count how many bytes received
if (bytesReceived == NUM_BYTES) { // if received correct number of bytes...
for (byte i=0; i<NUM_BYTES; i++) data[i] = Wire.read(); // read and store each byte
printData(); // print the received data
} else { // if received wrong number of bytes...
Serial.print(F("\nRequested ")); // print message with how many bytes received
Serial.print(NUM_BYTES);
Serial.print(F(" bytes, but got "));
Serial.print(bytesReceived);
Serial.print(F(" bytes\n"));
}
timeNow = millis(); // mark preset time for next trigger
}
}
void printData() {
Serial.print(F("\n"));
for (byte i=0; i<NUM_BYTES; i++) {
Serial.print(F("Byte["));
Serial.print(i);
Serial.print(F("]: "));
Serial.print(data[i]);
Serial.print(F("\t"));
}
Serial.print(F("\n"));
}

Arduino callback stops working when there is a new connection to MQTT broker

First time posting on here, I am hoping somebody will be able to give me some help with an annoying problem I a having.
I am trying to control an Arduino through MQTT with websockets this all works fine until a new connection to the broker is made, the Arduino then does not respond to the callbacks.
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
// Update these with values suitable for your network.
byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(192, 168, 0, 123);
const char* server = "192.168.0.30";
char message_buff[100];
// defines and variable for sensor/control mode
#define MODE_OFF 0 // not sensing light, LED off
#define MODE_ON 1 // not sensing light, LED on
#define MODE_SENSE 2 // sensing light, LED controlled by software
int senseMode = 0;
unsigned long time;
EthernetClient ethClient;
PubSubClient mqttClient(ethClient);
void callback(char* topic, byte* payload, unsigned int length) {
int i = 0;
for (int i=0;i<length;i++) {
message_buff[i] = payload[i];
}
String msgString = String(message_buff);
Serial.println("Payload: " + msgString);
if (msgString.equals("onn")){
senseMode = MODE_ON;
}else if(msgString.equals("off")){
senseMode = MODE_OFF;
}
}
void reconnect() {
// Loop until we're reconnected
while (!mqttClient.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (mqttClient.connect("arduinoClient")) {
Serial.println("connected");
// Once connected, publish an announcement...
mqttClient.publish("test","AR1 Connected");
// ... and resubscribe
mqttClient.subscribe("test");
} else {
Serial.print("failed, rc=");
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup()
{
Serial.begin(9600);
pinMode(7, OUTPUT);
mqttClient.setServer(server, 1883);
mqttClient.setCallback(callback);
Ethernet.begin(mac, ip);
// Allow the hardware to sort itself out
delay(1500);
}
void loop()
{
if (!mqttClient.connected()) {
reconnect();
}
switch (senseMode) {
case MODE_OFF:
// light should be off
digitalWrite(7, LOW);
break;
case MODE_ON:
// light should be on
digitalWrite(7, HIGH);
break;
}
mqttClient.loop();
}
Outputs:
Attempting MQTT connection...failed, rc= try again in 5 seconds
Attempting MQTT connection...connected
Payload: onn
Payload: off
Payload: JTPA.CONNECTED
Payload: onnA.CONNECTED
Payload: offA.CONNECTED
Any help would be much appreciated.
Thanks.
As thrashed out in the comments the problem here is that you are using the same MQTT client ID for all instances. This will not work as every client needs a unique id and the broker will disconnect duplicates.
You need a way to generate a unique id, this question on the Arduino site has some hints on how to do this.

Resources