PubSubClient ESP32 disconnected while receive message - c++

I create a project to receive message from MQTT. My full code is here
https://github.com/kamshory/OTP-Mini/blob/main/Server/Server.ino
WiFiClient espClient;
PubSubClient client(espClient);
void setup()
{
char * mqttServer = "192.168.1.3";
client.setServer(mqttServer, 1883);
client.setCallback(mqttCallback);
}
void mqttCallback(const char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print("Message: ");
char * mqttTopic = "sms";
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
messageTemp += (char)payload[i];
}
Serial.println();
// Feel free to add more if statements to control more GPIOs with MQTT
// If a message is received on the topic esp32/output, you check if the message is either "on" or "off".
// Changes the output state according to the message
if (String(topic) == String(mqttTopic)) {
}
}
void mqttReconnect() {
Serial.print("WiFi status = ");
Serial.println(WiFi.status());
char * clientId = "php";
char * mqttUsername = "user";
char * mqttPassword = "pass";
char * mqttTopic = "sms";
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection ");
// Attempt to connect
if (client.connect(clientId, mqttUsername, mqttPassword)) {
Serial.println("connected");
// Subscribe
boolean sub = client.subscribe("sms");
Serial.println(sub);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
When ESP32 publish a message in a topic, the message is received by subscriber (I create the subscriber with Java). But when it try to receive the message with callback, the client is disconnected.
I try to debug with edit library on file PubSubClient.cpp
boolean PubSubClient::loop() {
if (connected()) {
unsigned long t = millis();
if ((t - lastInActivity > MQTT_KEEPALIVE*1000UL) || (t - lastOutActivity > MQTT_KEEPALIVE*1000UL)) {
if (pingOutstanding) {
this->_state = MQTT_CONNECTION_TIMEOUT;
_client->stop();
return false;
} else {
buffer[0] = MQTTPINGREQ;
buffer[1] = 0;
_client->write(buffer,2);
lastOutActivity = t;
lastInActivity = t;
pingOutstanding = true;
}
}
if (_client->available()) {
uint8_t llen;
uint16_t len = readPacket(&llen);
uint16_t msgId = 0;
uint8_t *payload;
if (len > 0) {
lastInActivity = t;
uint8_t type = buffer[0]&0xF0;
if (type == MQTTPUBLISH) {
if (callback) {
uint16_t tl = (buffer[llen+1]<<8)+buffer[llen+2]; /* topic length in bytes */
memmove(buffer+llen+2,buffer+llen+3,tl); /* move topic inside buffer 1 byte to front */
buffer[llen+2+tl] = 0; /* end the topic as a 'C' string with \x00 */
char *topic = (char*) buffer+llen+2;
// msgId only present for QOS>0
if ((buffer[0]&0x06) == MQTTQOS1) {
msgId = (buffer[llen+3+tl]<<8)+buffer[llen+3+tl+1];
payload = buffer+llen+3+tl+2;
callback(topic,payload,len-llen-3-tl-2);
buffer[0] = MQTTPUBACK;
buffer[1] = 2;
buffer[2] = (msgId >> 8);
buffer[3] = (msgId & 0xFF);
_client->write(buffer,4);
lastOutActivity = t;
} else {
payload = buffer+llen+3+tl;
callback(topic,payload,len-llen-3-tl);
}
}
} else if (type == MQTTPINGREQ) {
buffer[0] = MQTTPINGRESP;
buffer[1] = 0;
_client->write(buffer,2);
} else if (type == MQTTPINGRESP) {
pingOutstanding = false;
}
} else if (!connected()) {
// readPacket has closed the connection
return false;
}
}
return true;
}
return false;
}
The type value is 208 which is MQTTPINGRESP not 48 which is MQTTPUBLISH.
So, where is the problem?
Is my library or my code?
I download library from https://www.arduino.cc/reference/en/libraries/pubsubclient/

Related

3x Arduino + ESP32 with ESP-NOW

The configuration on "machine" looks like this:
Computer with custom app WPF C#, have connected ESP32-sender.
On other side of room there is ESP32 as recaiver that have connected to it 3 arduino due, that controls a lot of stepper motors.
My problem is, that if I send a single command all works great. Directly on other side it executes.
The problem starts when there is a lot of commands to send. ESP32 starts to makes Delivery fail status and after that moment all further commands are lost.
That's the code of Master-ESP connected to PC.
Which arduino to send is decide by one of the symbols on begin of message "!,#,#"
#include <esp_now.h>
#include <WiFi.h>
#include <Wire.h>
uint8_t broadcastAddress[] = {0x94, 0xB9, 0x7E, 0xD0, 0x93, 0x64};
String inMess;
typedef struct Message {
char a[100];
} Message;
// Variable to store if sending data was successful
String success;
Message message;
Message send_message;
esp_now_peer_info_t peerInfo;
char incoming;
String full = "";
bool text_done = false;
bool sended = false;
// Callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
//Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success*" : "Delivery Fail*");
if (status ==0){
success = "Delivery Success :)";
text_done = false;
full = "";
sended = false;
}
else{
success = "Delivery Fail :(";
delay(10);
sended = false;
Serial.println(success);
}
}
// Callback when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&message, incomingData, sizeof(message));
Serial.println(message.a);
}
void setup() {
// Init Serial Monitor
Serial.begin(115200);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
Serial.println(WiFi.macAddress());
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_send_cb(OnDataSent);
// Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
if(Serial.available() > 0 && !text_done){
incoming = Serial.read();
if(incoming == '\n'){
text_done = true;
full.trim();
full.toUpperCase();
}
if(text_done == false){
full += incoming;
}
}
if(text_done){
if(full[0] != '!' && full[0] != '#' && full[0] != '#'){ //check if text is worth sending to other esp
text_done = false;
full = "";
}
}
if(text_done){
if(!sended){
full.toCharArray(send_message.a,sizeof(send_message));
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &send_message, sizeof(send_message));
if (result == ESP_OK) {
//Serial.println("Sent success*");
sended = true;
}
else {
Serial.println("Error sending*");
delay(10);
}
}
}
}
That's the code of recaiver ESP
#include <esp_now.h>
#include <WiFi.h>
#include <SoftwareSerial.h>
#include <Wire.h>
SoftwareSerial worker;
SoftwareSerial tool;
//Serial2 is Table, software serials are others
uint8_t broadcastAddress[] = {0x7C, 0x9E, 0xBD, 0x4B, 0x47, 0xA4};
String outMess;
String outMessTable;
String outMessTool;
String inMess;
typedef struct Message {
char a[100];
} Message;
String success;
Message message;
Message send_message;
bool sended = true;
String again_message = "";
esp_now_peer_info_t peerInfo;
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
//Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
if (status == 0) {
success = "Delivery Success :)";
sended = true;
again_message = "";
}
else {
success = "Delivery Fail :(";
sended = false;
delay(5);
}
}
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&message, incomingData, sizeof(message));
Serial.println(message.a);
sendTo((String)message.a);
}
void setup() {
// Init Serial Monitor
Serial.begin(115200);
Serial2.begin(115200, SERIAL_8N1, 16, 17);
//rx tx
worker.begin(57600, SWSERIAL_8N1, 25, 26, false);
if (!worker) {
Serial.println("Invalid SoftwareSerial pin configuration, check config");
while (1) {
delay (1000);
}
}
//rx tx
tool.begin(57600, SWSERIAL_8N1, 32, 33, false);
if (!tool) {
Serial.println("Invalid SoftwareSerial pin configuration, check config");
while (1) {
delay (1000);
}
}
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
Serial.println(WiFi.macAddress());
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_register_send_cb(OnDataSent);
// Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
// Register for a callback function that will be called when data is received
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
// Set values to send
if(sended){
if (worker.available() > 0) {//!
char t = worker.read();
if(t == '\n'){
outMess.trim();
sendToEsp(outMess,"!");
outMess = "";
}
else{
outMess += t;
}
}
}else{
if(again_message.length()>0){
delay(10);
sendToEsp(again_message.substring(1),again_message.substring(0,1));
}else{
sended = true;
}
}
if(sended){
if (tool.available() > 0) {//#
char t = tool.read();
if(t == '\n'){
outMessTool.trim();
sendToEsp(outMessTool,"#");
outMessTool = "";
}
else{
outMessTool += t;
}
}
}else{
if(again_message.length()>0){
delay(10);
sendToEsp(again_message.substring(1),again_message.substring(0,1));
}else{
sended = true;
}
}
if(sended){
if (Serial2.available() > 0) { //#
char t = Serial2.read();
if(t == '\n'){
outMessTable.trim();
sendToEsp(outMessTable,"#");
outMessTable = "";
}else{
outMessTable += t;
}
}
}else{
if(again_message.length()>0){
delay(10);
sendToEsp(again_message.substring(1),again_message.substring(0,1));
}else{
sended = true;
}
}
if(Serial.available() > 0){
outMess = Serial.readStringUntil('\n'); //read command from pc
outMess.trim(); // remove uneccesery spaces
sendTo(outMess);
}
}
void sendToEsp(String text, String which){
String mess = which + text;
again_message = mess;
mess.toCharArray(send_message.a,sizeof(send_message));
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &send_message, sizeof(send_message));
if (result == ESP_OK) {
// Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
sended = true;
again_message = "";
}
}
void sendTo(String outMess){
Serial.print("=");
Serial.print(outMess);
if(outMess[0] == '!'){ //worker
worker.enableTx(true);
worker.println(outMess.substring(1));
worker.enableTx(false);
Serial.println("send to worker");
}
if(outMess[0] == '#') {//table
Serial2.println(outMess.substring(1));
Serial.println("send to table");
}
if(outMess[0] == '#'){ //tool
tool.enableTx(true);
tool.println(outMess.substring(1));
tool.enableTx(false);
Serial.println("send to tool");
}
}
If I send one message with a delay of writing next one by hand it works great.
If the message is sended via c# very fast, esp32 is handling first few of them then losing on sending or recaiving, sometimes both of esp32 sometimes only one.
How could I prevent that to make stable connection ?

IOCP Socket Worker threads works too much slow when i test it with client simulator

I'm developing a mmorpg with iocp sockets.When im testing with my client simulator , after 70-80 connection , writing operation at socket worker thread slowing down than users get lagged.
This is my worker thread ;
typedef void(*OperationHandler)(Socket * s, uint32 len);
void HandleReadComplete(Socket * s, uint32 len);
void HandleWriteComplete(Socket * s, uint32 len);
void HandleShutdown(Socket * s, uint32 len);
static OperationHandler ophandlers[] =
{
&HandleReadComplete,
&HandleWriteComplete,
&HandleShutdown
};
uint32 THREADCALL SocketMgr::SocketWorkerThread(void * lpParam){
SocketMgr *socketMgr = (SocketMgr *)lpParam;
HANDLE cp = socketMgr->GetCompletionPort();
DWORD len;
Socket * s = nullptr;
OverlappedStruct * ov = nullptr;
LPOVERLAPPED ol_ptr;
while (socketMgr->m_bWorkerThreadsActive)
{
if (!GetQueuedCompletionStatus(cp, &len, (LPDWORD)&s, &ol_ptr, INFINITE))
{
if (s != nullptr)
s->Disconnect();
continue;
}
ov = CONTAINING_RECORD(ol_ptr, OverlappedStruct, m_overlap);
if (ov->m_event == SOCKET_IO_THREAD_SHUTDOWN)
{
delete ov;
return 0;
}
if (ov->m_event < NUM_SOCKET_IO_EVENTS)
ophandlers[ov->m_event](s, len);
}
return 0;}
This is Write Complete event handler;
void HandleWriteComplete(Socket * s, uint32 len)
{
if (s->IsDeleted()) {
return;
}
s->m_writeEvent.Unmark();
s->BurstBegin(); // Lock
s->GetWriteBuffer().Remove(len);
TRACE("SOCK = %d removed = %d",s->GetFd(),len);
if (s->GetWriteBuffer().GetContiguousBytes() > 0) {
s->WriteCallback();
}
else {
s->DecSendLock();
}
s->BurstEnd(); // Unlock
}
WriteCallBack function ;
void Socket::WriteCallback()
{
if (IsDeleted() || !IsConnected()) {
return;
}
// We don't want any writes going on while this is happening.
Guard lock(m_writeMutex);
if(writeBuffer.GetContiguousBytes())
{
DWORD w_length = 0;
DWORD flags = 0;
// attempt to push all the data out in a non-blocking fashion.
WSABUF buf;
buf.len = (ULONG)writeBuffer.GetContiguousBytes();
buf.buf = (char*)writeBuffer.GetBufferStart();
m_writeEvent.Mark();
m_writeEvent.Reset(SOCKET_IO_EVENT_WRITE_END);
TRACE("\n SOCK = %d aslında giden = %X THREADID = %d", GetFd(), buf.buf[4],GetCurrentThreadId());
int r = WSASend(m_fd, &buf, 1, &w_length, flags, &m_writeEvent.m_overlap, 0);
if (r == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
{
m_writeEvent.Unmark();
DecSendLock();
Disconnect();
}
}
else
{
// Write operation is completed.
DecSendLock();
}
}
this is stuffs about mutexes ;
public:
/* Atomic wrapper functions for increasing read/write locks */
INLINE void IncSendLock() { Guard lock(m_writeMutex); ++m_writeLock; }
INLINE void DecSendLock() { Guard lock(m_writeMutex);
--m_writeLock; }
INLINE bool HasSendLock() {Guard lock(m_writeMutex); return (m_writeLock != 0); }
INLINE bool AcquireSendLock()
{
Guard lock(m_writeMutex);
if (m_writeLock != 0)
return false;
++m_writeLock;
return true;
}
private:
// Write lock, stops multiple write events from being posted.
uint32 m_writeLock;
std::recursive_mutex m_writeLockMutex;
This is read event handler;
void HandleReadComplete(Socket * s, uint32 len)
{
if (s->IsDeleted())
return;
s->m_readEvent.Unmark();
if (len)
{
s->GetReadBuffer().IncrementWritten(len);
s->OnRead();
s->SetupReadEvent();
}
else
{
// s->Delete(); // Queue deletion.
s->Disconnect();
}
}
OnRead function ;
void KOSocket::OnRead()
{
Packet pkt;
for (;;)
{
if (m_remaining == 0)
{
if (GetReadBuffer().GetSize() < 5) {
//TRACE("pkt returnzzz GetFd %d", GetFd());
return; //check for opcode as well
}
uint16 header = 0;
GetReadBuffer().Read(&header, 2);
//printf("header : %X", header);//derle at k
if (header != 0x55AA)
{
TRACE("%s: Got packet without header 0x55AA, got 0x%X\n", GetRemoteIP().c_str(), header);
goto error_handler;
}
GetReadBuffer().Read(&m_remaining, 2);
if (m_remaining == 0)
{
TRACE("%s: Got packet without an opcode, this should never happen.\n", GetRemoteIP().c_str());
goto error_handler;
}
}
if (m_remaining > GetReadBuffer().GetAllocatedSize())
{
TRACE("%s: Packet received which was %u bytes in size, maximum of %u.\n", GetRemoteIP().c_str(), m_remaining, GetReadBuffer().GetAllocatedSize());
goto error_handler;
}
if (m_remaining > GetReadBuffer().GetSize())
{
if (m_readTries > 4)
{
TRACE("%s: packet fragmentation count is over 4, disconnecting as they're probably up to something bad\n", GetRemoteIP().c_str());
goto error_handler;
}
m_readTries++;
return;
}
uint8 *in_stream = new uint8[m_remaining];
m_readTries = 0;
GetReadBuffer().Read(in_stream, m_remaining);
uint16 footer = 0;
GetReadBuffer().Read(&footer, 2);
if (footer != 0xAA55
|| !DecryptPacket(in_stream, pkt))
{
TRACE("%s: Footer invalid (%X) or failed to decrypt.\n", GetRemoteIP().c_str(), footer);
delete [] in_stream;
goto error_handler;
}
delete [] in_stream;
// Update the time of the last (valid) response from the client.
m_lastResponse = UNIXTIME2;
//TRACE("pkt:%d GetFd %d", pkt.GetOpcode(), GetFd());
if (!HandlePacket(pkt))
{
TRACE("%s: Handler for packet %X returned false\n", GetRemoteIP().c_str(), pkt.GetOpcode());
#ifndef _DEBUG
goto error_handler;
#endif
}
m_remaining = 0;
}
//TRACE("pkt return11 GetFd %d", GetFd());
return;
error_handler:
Disconnect();
}
and this is how my server sends to packet to clients ;
BurstBegin();
//TRACE("\n SOCK = %d FREE SPACE = %d ",GetFd(),GetWriteBuffer().GetSpace()/*, GetWriteBuffer().m_writeLock*/);
if (GetWriteBuffer().GetSpace() < size_t(len + 6))
{
size_t freespace = GetWriteBuffer().GetSpace();
BurstEnd();
Disconnect();
return false;
}
TRACE("\n SOCK = %d gitmesi gereken paket = %X THREADID = %d", GetFd(), out_stream[0],GetCurrentThreadId());
r = BurstSend((const uint8*)"\xaa\x55", 2);
if (r) r = BurstSend((const uint8*)&len, 2);
if (r) r = BurstSend((const uint8*)out_stream, len);
if (r) r = BurstSend((const uint8*)"\x55\xaa", 2);
if (r) BurstPush();
BurstEnd();
The number of Worker threads according to processor number;
for(int i = 0; i < numberOfWorkerThreads; i++)
{
m_thread[i] = new Thread(SocketWorkerThread, this);
}
The server which i tested on it has Intel XEON E5-2630 v3 2.40 ghz (2 processor)
Can you guys help me about how can i improve performance ? For ex: when the client moves in the map per 1.5 second that sends to move packet to server and if it success server sends to every client in that region that move packet.
When client count increasing server starts to slow down to send back to packets to clients.My write buffer filling fully (it's capacity 16384 bytes) cause server couldn't send packets inside of the writebuffer.

Arduino compiler failing with error code - invalid types 'int[int]' for array subscript

Quite a bit of untested code but the only thing really concerning me at the moment is my DISPLAY variable. I don't see how it is much different than my FONT array (which works fine) yet DISPLAY is the one that gets 'invalid types 'int[int]' for array subscript' I should be able to index an array of integers with integers (at least I have been with FONT).
#include <WiFiNINA.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include "font.h"
const int PIXEL_WIDTH = 30;
const int PIXEL_HEIGHT = 5;
int DISPLAY[PIXEL_HEIGHT][PIXEL_WIDTH] = {};
bool MILI_TIME = false;
String FORMATTING[2] = {"LONGS","SHORTH:LONGM"};
char ssid[] = "REMOVED"; // your network SSID (name) between the " "
char pass[] = "REMOVED"; // your network password between the " "
int keyIndex = 0; // your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS; // connection status
WiFiServer server(80); // server socket
WiFiClient client = server.available();
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
int ledPin = LED_BUILTIN;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
while (!Serial); // dont do anything until there is a serial connection
enable_WiFi();
connect_WiFi();
server.begin();
printWifiStatus();
timeClient.begin();
timeClient.setTimeOffset(-14400);
}
void loop() {
timeClient.update();
client = server.available();
if (client) {
printWEB();
}
preRender();
}
void preRender(){
String FILLED_FORMATTING[2] = FORMATTING;
for(int i=0;i<2;i++){
FILLED_FORMATTING[i].replace("LONGH",leadWithZero(timeHours()));
FILLED_FORMATTING[i].replace("LONGM",leadWithZero(timeMinutes()));
FILLED_FORMATTING[i].replace("LONGS",leadWithZero(timeSeconds()));
FILLED_FORMATTING[i].replace("SHORTH",timeHours());
FILLED_FORMATTING[i].replace("SHORTM",timeMinutes());
FILLED_FORMATTING[i].replace("SHORTS",timeSeconds());
}
int x = 0;
for(int i=0;i<FILLED_FORMATTING[0].length();i++){
int c_ID = charID(FILLED_FORMATTING[0][i]);
if(c_ID < 38){
for(int j=0;j<5;j++){
DISPLAY[j][x] = FONT[c_ID][j][0];
x += 1;
DISPLAY[j][x] = FONT[c_ID][j][1];
x += 1;
DISPLAY[j][x] = FONT[c_ID][j][2];
x += 1;
if(i != FILLED_FORMATTING[0].length()){
DISPLAY[j][x] = 0;
x += 1;
}
}
}
}
x = PIXEL_WIDTH-1;
for(int i=FILLED_FORMATTING[1].length()-1;i>=0;i--){
int c_ID = charID(FILLED_FORMATTING[1][i]);
if(c_ID < 38){
for(int j=0;j<5;j++){
DISPLAY[j][x] = FONT[c_ID][j][0];
x -= 1;
DISPLAY[j][x] = FONT[c_ID][j][1];
x -= 1;
DISPLAY[j][x] = FONT[c_ID][j][2];
x -= 1;
if(i != 0){
DISPLAY[j][x] = 0; //<----------- compiler error here, and ofc all instances above
x -= 1;
}
}
}
}
}
int charID(char c){
for(int i=0;i<FONT_ID.length();i++){
if(FONT_ID[i] == c){
return i;
}
}
return 40;
}
String timeHours(){
if(MILI_TIME){
return String(timeClient.getHours());
}
else{
return convFromMili(timeClient.getHours());
}
}
String timeMinutes(){
return String(timeClient.getMinutes());
}
String timeSeconds(){
return String(timeClient.getSeconds());
}
String leadWithZero(String t){
if(t.length() < 2){
t = "0"+t;
return t;
}
}
String convFromMili(int t){
if(t > 12){
t -= 12;
}else if(t == 0){
t += 12;
}
String ts = String(t);
return ts;
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
Serial.print("To see this page in action, open a browser to http://");
Serial.println(ip);
}
void enable_WiFi() {
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}
String fv = WiFi.firmwareVersion();
if (fv < "1.0.0") {
Serial.println("Please upgrade the firmware");
}
}
void connect_WiFi() {
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(10000);
}
}
void printWEB() {
if (client) { // if you get a client,
Serial.println("new client"); // print a message out the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected()) { // loop while the client's connected
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
Serial.write(c); // print it out the serial monitor
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
//create the buttons
client.print(WiFi.getTime());
client.print("<br>");
client.print(timeClient.getEpochTime());
client.print("<br>");
client.print(timeClient.getFormattedTime());
client.print("<br>");
client.print(timeClient.getDay());
client.print("<br>");
client.print(timeClient.getHours());
client.print("<br>");
client.print(timeClient.getMinutes());
client.print("<br>");
client.print(timeClient.getSeconds());
client.print("<br>");
client.print("<div style=\"display:block;padding-left:calc(50% - 150px);margin-bottom:50px\"><div style=\"background-color:#e3e3e3;width:300px;height:120px;font-size:50px;text-align:center;padding-top:50px\">ON</div></div>");
client.print("<div style=\"display:block;padding-left:calc(50% - 150px)\"><div style=\"background-color:#e3e3e3;width:300px;height:120px;font-size:50px;text-align:center;padding-top:50px\">OFF</div></div>");
// The HTTP response ends with another blank line:
client.println();
// break out of the while loop:
break;
}
else { // if you got a newline, then clear currentLine:
currentLine = "";
}
}
else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
if (currentLine.endsWith("GET /H")) {
digitalWrite(ledPin, HIGH);
}
if (currentLine.endsWith("GET /L")) {
digitalWrite(ledPin, LOW);
}
if (currentLine.endsWith("%VAL")) {
// Trim 'GET /' and '%VAL'
currentLine.remove(0,5);
currentLine.remove(currentLine.indexOf("%"),4);
Serial.println(currentLine);
Serial.println();
}
}
}
// close the connection:
client.stop();
Serial.println("client disconnected");
}
}
font.h:
int FONT[37][5][3] = {{{1,1,1},{1,0,1},{1,0,1},{1,0,1},{1,1,1},},{{1,1,0},{0,1,0},{0,1,0},{0,1,0},{1,1,1},},{{1,1,1},{0,0,1},{1,1,1},{1,0,0},{1,1,1},},{{1,1,1},{0,0,1},{1,1,1},{0,0,1},{1,1,1},},{{1,0,1},{1,0,1},{1,1,1},{0,0,1},{0,0,1},},{{1,1,1},{1,0,0},{1,1,1},{0,0,1},{1,1,1},},{{1,1,1},{1,0,0},{1,1,1},{1,0,1},{1,1,1},},{{1,1,1},{0,0,1},{0,0,1},{0,0,1},{0,0,1},},{{1,1,1},{1,0,1},{1,1,1},{1,0,1},{1,1,1},},{{1,1,1},{1,0,1},{1,1,1},{0,0,1},{1,1,1},},{{1,1,1},{1,0,1},{1,1,1},{1,0,1},{1,0,1},},{{1,1,0},{1,0,1},{1,1,0},{1,0,1},{1,1,0},},{{1,1,1},{1,0,0},{1,0,0},{1,0,0},{1,1,1},},{{1,1,0},{1,0,1},{1,0,1},{1,0,1},{1,1,0},},{{1,1,1},{1,0,0},{1,1,1},{1,0,0},{1,1,1},},{{1,1,1},{1,0,0},{1,1,1},{1,0,0},{1,0,0},},{{1,1,1},{1,0,0},{1,0,1},{1,0,1},{1,1,1},},{{1,0,1},{1,0,1},{1,1,1},{1,0,1},{1,0,1},},{{1,1,1},{0,1,0},{0,1,0},{0,1,0},{1,1,1},},{{0,0,1},{0,0,1},{0,0,1},{1,0,1},{1,1,1},},{{1,0,1},{1,0,1},{1,1,0},{1,0,1},{1,0,1},},{{1,0,0},{1,0,0},{1,0,0},{1,0,0},{1,1,1},},{{1,1,1},{1,1,1},{1,0,1},{1,0,1},{1,0,1},},{{1,1,0},{1,0,1},{1,0,1},{1,0,1},{1,0,1},},{{1,1,1},{1,0,1},{1,0,1},{1,0,1},{1,1,1},},{{1,1,1},{1,0,1},{1,1,1},{1,0,0},{1,0,0},},{{1,1,1},{1,0,1},{1,0,1},{1,1,0},{0,0,1},},{{1,1,1},{1,0,1},{1,1,0},{1,0,1},{1,0,1},},{{0,1,1},{1,0,0},{0,1,0},{0,0,1},{1,1,0},},{{1,1,1},{0,1,0},{0,1,0},{0,1,0},{0,1,0},},{{1,0,1},{1,0,1},{1,0,1},{1,0,1},{1,1,1},},{{1,0,1},{1,0,1},{1,0,1},{0,1,0},{0,1,0},},{{1,0,1},{1,0,1},{1,0,1},{1,1,1},{1,1,1},},{{1,0,1},{1,0,1},{0,1,0},{1,0,1},{1,0,1},},{{1,0,1},{1,0,1},{1,1,1},{0,0,1},{1,1,1},},{{1,1,1},{0,0,1},{0,1,0},{1,0,0},{1,1,1},},{{0,0,0},{0,1,0},{0,0,0},{0,1,0},{0,0,0}}};
String FONT_ID = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ:";
did check -
int D[5][30];
void setup() {
}
void loop() {
D[0][0] = 0;
}
and of course its fine, so I'm just wondering where I went wrong in the mess above?
and yes there's a good bit of mess/debugging stuff
Simple solution... don't use DISPLAY as a variable it seems. Changing to DISPLAY_ fixed it, figured the variable was defined as a normal integer somewhere... just not in my code.

net-snmp v2c working well but v3 return STAT_ERROR

I'm currently trying to develop snmpManager in my embedded device(linux OS). This device should communicate with another device's snmpAgent. Well, my code working good for snmpV2c also my snmp packets show in wireshark pcap. But when i try snmpV3 packets snmp_synch_response(session, requestPdu, &responsePdu) func return STAT_ERROR Btw snmpV2c was returning STAT_SUCCESS My code is shown in below, i created snmp session for v2 and v3.
snmp_session *snmptypes::fCreateSession(QString IP)
{
struct snmp_session session;
snmp_sess_init(&session);
session.peername = strdup(IP.toAscii());
static const char* v3_passphrase = "blablabl";
session.retries = 2;
session.timeout = 1000000;
session.engineBoots = 0;
session.engineTime = 0;
QString engineID = "0000000c000000007f000001";
session.contextEngineID = reinterpret_cast<uchar*>(strdup(engineID.toAscii()));
qDebug()<<"contextEngineID:"<<session.contextEngineID;
/*memory allocated by strdup() will be freed by calling snmp_close() */
if(SnmpMainWidget::activeWaveForm == SnmpMainWidget::snmpv2c)
{
session.version = SNMP_VERSION_2c;
const char *str;
QString path = "user";
QByteArray ba;
ba = path.toLatin1();
str = ba.data();
session.community = const_cast<unsigned char*>(reinterpret_cast<const unsigned char *>(str));
session.community_len = path.length();
session.retries = 2;
session.timeout = 1000000;
}
else if (SnmpMainWidget::activeWaveForm == SnmpMainWidget::snmpv3)
{
session.version = SNMP_VERSION_3;
session.securityName = strdup("blabl");
session.securityNameLen = strlen(session.securityName);
session.securityModel = USM_SEC_MODEL_NUMBER;
session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
session.securityAuthProto = usmHMACMD5AuthProtocol;
// session.securityAuthProtoLen = sizeof (usmHMACMD5AuthProtocol) / sizeof (oid);
session.securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN;
session.securityPrivProto = usmNoPrivProtocol;
session.securityPrivProtoLen = USM_PRIV_PROTO_NOPRIV_LEN;
session.securityAuthKeyLen =USM_AUTH_KU_LEN;
if (generate_Ku(session.securityAuthProto,session.securityAuthProtoLen,(u_char *) (v3_passphrase),
strlen(v3_passphrase),session.securityAuthKey,
&session.securityAuthKeyLen) != SNMPERR_SUCCESS)
{
qWarning()<<"ERROR KODU"<<generate_Ku(session.securityAuthProto,session.securityAuthProtoLen,(u_char *) (v3_passphrase),
strlen(v3_passphrase),session.securityAuthKey,
&session.securityAuthKeyLen);
snmp_log(LOG_ERR,"Error generating Ku from authentication pass phrase. \n");
exit(1);
}
}
struct snmp_session* openedSession = snmp_open(&session);
if(openedSession == nullptr)
{
snmp_sess_perror(reinterpret_cast<const char*>("No Ack!"), openedSession);
qWarning()<<"Error while Session opening! FILE:"<<__FILE__<<"LINE:"<<__LINE__;
}
else
qDebug()<<"creating session is succeed!";
return openedSession;
}
Session is creating successfully. no problem so far. Let's continue, then i create pdu like shown below,
snmp_pdu *snmptypes::fCreatePDU(tsPDUvariables PDUvariables)
{
// qDebug()<<"nrepeaters"<<PDUvariables.nrepeaters;
// qDebug()<<"mrepeaters"<<PDUvariables.mrepetitions;
qDebug()<<"setParam"<<PDUvariables.setParam;
qDebug()<<"dataType"<<PDUvariables.dataType;
struct snmp_pdu* requestPdu;
oid requestOid[MAX_OID_LEN];
size_t requestOidLength = MAX_OID_LEN;
snmp_parse_oid(static_cast<const char*>(PDUvariables.OID.toAscii()), requestOid, &requestOidLength);
switch (PDUvariables.msgType) {
case snmpGet:
requestPdu = snmp_pdu_create(SNMP_MSG_GET);
if (SnmpMainWidget::activeWaveForm == SnmpMainWidget::snmpv3){
requestPdu->version = SNMP_VERSION_3;
requestPdu->securityName = strdup("user");
requestPdu->securityNameLen = strlen(requestPdu->securityName);
requestPdu->securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
requestPdu->securityModel = USM_SEC_MODEL_NUMBER;
}
snmp_add_null_var(requestPdu, requestOid, requestOidLength);
break;
//there are some other case like set,getbulk but don't need to focus these.get enough for now.
}
qDebug()<<"creating PDU is succeed!";
return requestPdu;
}
Finally I'm using snmpget func. for send snmp packet to dedicated IP;
Problem occure right here, snmpv2 snmpStatus return success but snmpv3 reutn error. There for snmpv3 packet doesn't appear on wireshark and also doesn't send. I cant understand what am i wrong in V3 while V2 was working well.
bool snmptypes::fSnmpGet(QString IP,QString OID)
{
const char PACKET_HEADER_BYTE = 4;//4Byte = SOH + len/256 + len%256 + EOH
struct snmp_session* session = fCreateSession(IP);
tsPDUvariables PDUvariables;
PDUvariables.OID = OID;
PDUvariables.msgType = snmpGet;
struct snmp_pdu* requestPdu = fCreatePDU(PDUvariables);
qDebug()<<"PDUvariables.msgType"<<PDUvariables.msgType;
qDebug()<<"PDUvariables.dataType"<<PDUvariables.dataType;
qDebug()<<"PDUvariables.OID"<<PDUvariables.OID;
qDebug()<<"PDUvariables.setParam"<<PDUvariables.setParam;
struct snmp_pdu* responsePdu = nullptr;
if(requestPdu != nullptr && session != nullptr)
{
int snmpStatus = snmp_synch_response(session, requestPdu, &responsePdu);
qDebug()<<"snmpStatus"<<snmpStatus;
qDebug()<<"requestStatus::errStat"<<requestPdu->errstat;
qDebug()<<"session->s_errno"<<session->s_errno;
if(snmpStatus == STAT_SUCCESS)
{
if( responsePdu->errstat == SNMP_ERR_NOERROR and responsePdu->errstat == SNMP_ERR_NOERROR)
{
/* SUCCESS: Print the result variables */
struct variable_list *snmpVariables;
for(snmpVariables = responsePdu->variables; snmpVariables; snmpVariables = snmpVariables->next_variable)
{ qDebug()<<"fSnmpGet"<<__LINE__;
print_variable(snmpVariables->name, snmpVariables->name_length, snmpVariables);
}
for(snmpVariables = responsePdu->variables; snmpVariables != nullptr; snmpVariables = snmpVariables->next_variable)
{
QString strOID;
for(size_t i =0; i<snmpVariables->name_length;i++)
{
qDebug()<<"snmpVariables->name[i]"<<snmpVariables->name[i];
strOID.append(".");
strOID.append(QString::number( snmpVariables->name[i]));
}
qDebug()<<"strOID"<<strOID;
unsigned int OIDLen = static_cast<unsigned int> (strOID.length());
qDebug()<<"OID_Length:"<< static_cast<unsigned int> (OIDLen);
unsigned int paramLen = static_cast<unsigned int> (snmpVariables->val_len);
qDebug()<<"paramLen"<<paramLen;
unsigned int txDataLen = 5+OIDLen + paramLen;
qDebug()<<"txDataLen"<<txDataLen;
int totalTxDataLen = txDataLen+PACKET_HEADER_BYTE;
unsigned char *outMessBuff = static_cast<unsigned char *>(malloc(totalTxDataLen));
unsigned char *dataBuff = static_cast<unsigned char *>(malloc(txDataLen));
dataBuff[0] = snmpReqResponse;
dataBuff[1] = static_cast<unsigned char>(OIDLen/256 );
dataBuff[2] = static_cast<unsigned char>(OIDLen%256) ;
dataBuff[3] = static_cast<unsigned char>(paramLen/256) ;
dataBuff[4] = static_cast<unsigned char>(paramLen%256 );
if(OIDLen > 0)
{
memcpy(dataBuff+5,strOID.toAscii(),OIDLen);
}
if(paramLen > 0)
{
memcpy(dataBuff+5+OIDLen,snmpVariables->val.string,paramLen);
}
totalTxDataLen = SnmpMainWidget::IPC.prepareIPCmessage(outMessBuff, dataBuff, static_cast<int>(txDataLen));
SnmpMainWidget::IPC.sendIpcMessageToQt(reinterpret_cast<const char *>(outMessBuff),static_cast<unsigned int>(totalTxDataLen)); // reinterpret_cast bit of dangerous should be good test !!
SnmpMainWidget::IPC.PrintPacketInHex("SNMP-->QT :",outMessBuff, static_cast<unsigned int>(totalTxDataLen));
free(dataBuff);
free(outMessBuff);
}
}
}
else
{
if(snmpStatus == STAT_SUCCESS)
{
fprintf(stderr, "Error in packet\nReason: %s\n", snmp_errstring(responsePdu->errstat));
}
else if(snmpStatus == STAT_TIMEOUT)
{
fprintf(stderr, "Timeout: No response from %s.\n", session->peername);
}
else
{
printf("snmp get requestPdu->command: %d\n", requestPdu->command);
printf("snmp get errstat: %s\n", snmp_errstring(requestPdu->errstat));
printf("snmp get errindex: %s\n", snmp_errstring(requestPdu->errindex));
fprintf(stderr, "session->s_errno %d,session->s_snmp_errno %d \n", session->s_errno, session->s_snmp_errno);
}
if(responsePdu)
{
snmp_free_pdu(responsePdu);
}
snmp_close(session);
}
}
else
return false;
return true;
}
I'm just solving the problem. When I checked the internet I realize missing init_snmp("snmpapp"); function in my code. After adding init snmp, v3 set get message is send perfectly.
snmp_session *snmptypes::fCreateSession(QString IP)
{
struct snmp_session session;
init_snmp("snmpapp");
snmp_sess_init(&session);
session.peername = strdup(IP.toAscii());
.....
}
Maybe it would be a useful answer for people who will have the same problem.

WDT reset cause 4 after reinstalling Arduino

I try to control my LED strip with an Android app.
I reinstalled the Arduino IDE since I didn't like the Windows-store version. The serial monitor broke for whatever reason so I switched back to the Windows-store version.
But now I'm getting a WDT reset error, which I can't seem to overcome.
I'm also using Adafruit_NeoPixel and wherever I put "ledstrip.begin" or "ledstrip.show" seems to break it.
#include <ESP8266WiFi.h>
#include <Adafruit_NeoPixel.h>
byte RED = 14;
byte GREEN = 12;
byte BLUE = 13;
byte PIN_COUNT = 20;
Adafruit_NeoPixel ledstrip = Adafruit_NeoPixel(PIN_COUNT, 6, NEO_RGB + NEO_KHZ800); //(num of leds, )
WiFiServer server(port);
void setup()
{
Serial.begin(115200);
delay(10);
ledstrip.begin();
Serial.print("Connecting to: ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
byte tries;
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
tries++;
Serial.println(".");
if (tries == 5)
{
Serial.println("Connection failed");
return;
}
}
Serial.println("\nWiFi connected");
server.begin();
Serial.println("Server URL: ");
Serial.print(WiFi.localIP());
}
void print_tokens(char* strings)
{
byte index = sizeof(strings);
for (int n = 0; n < index; n++)
{
Serial.println(strings[n]);
}
}
char *tokenize_request(String request)
{
char requestArray[1024];
char *ptr = NULL;
byte index = 0;
char *strings[10];
strcpy(requestArray, request.c_str());
ptr = strtok(requestArray, ";");
while (ptr != NULL) {
strings[index] = ptr;
index++;
ptr = strtok(NULL, ";");
}
return *strings;
}
void loop()
{
WiFiClient responder = server.available();
if (!responder)
{
return;
}
while (!responder.available())
{
delay(1);
}
String request = responder.readStringUntil('#');
char *strings[10] = {tokenize_request(request)};
print_tokens(*strings);
int mode = atoi(strings[0]);
int R = atoi(strings[1]);
int G = atoi(strings[2]);
int B = atoi(strings[3]);
if (mode == 1)
{
ledstrip.setPixelColor(5, R, G, B);
}
if (mode == 0)
{
ledstrip.setPixelColor(5, 0, 0, 0);
}
ledstrip.show();
delay(1);
Serial.println("------------------------------------------------------------------");
}
Serial monitor output: