BLYNK
HOME       📲 GETTING STARTED       📗 DOCS       ❓HELP CENTER       👉 SKETCH BUILDER

RPI disconnect after 30/40 minutes

Hi all,

I have a problem with my Blynk application running on Raspberry Pi 3.

The Rpi is running the C++ code provided by blynk guys on GitHub but with some modifications.
In particular I have introduced a thread management with pthreads library to manage different task while blynk is connected.
In particular each task talk with other electronics board connected to wifi (STM32 Nucleo) for temperature reading and energy monitoring purpose

The problem is that seens thats everything is working fine (I can read temperature and monitor energy, send and receive commands) but after 30 minutes the connection with Blynk server goes down and never reconnect.

I tried to remove all my code and start running basic and original blynk application and everithing is working fine.

I cannot explain why using thread in the code can lead to connection lose

Please can someone explain me what is going wrong?

Many thanks

1 Like

I have the same problem now!!! After 1 month running correctly now disconnect every second.

Which version are you working with?

2.27.0 beta. with latest local server

Not the App version, what version is running on the RPI :stuck_out_tongue_winking_eye: This OP said using C++, so probably WireingPi, but there is also a NodeJS and a Python version of Blynk Library for RPi. All are different, so your “Me Too” may have nothing to do with this OP issue.

@Pol We need a lot more details… RPi type, does it disconnect when using other sketches as well, actual type and version of library, Local or Cloud server (and if Local, is it running on same RPi)… etc… including seeing the actual code you are trying to run now. Please properly format your code after pasting it here:


Blynk - FTFC

Also, since the RPI is a full SOC not just a microconrtoller, there could be many issues at play not just your code or the library… is the Linux version all up to date? Is the RPi running on a good stable 5v power supply, or just USB off a PC or something. Any other background processes running… and so on.

1 Like

I’m running nodejs on my rpi. But for now problem solved by rebooting the pi.

I’m using Blynk C++ version 0.5.3 version on Raspberry Pi 3 B+.

I have tried removing all my modification to basic sketch and everything is working fine, I mean no disconnections happen up to now (It is working with basic skecth for 3 days).

RPI Blynk connect to cloud, so I have a connection branch to your server in the cloud and another branch (actually my pThreads in my modified blynk code) to connect to others device wified in my home.

I will post all my code this evening when I will be at home.

Many thank to all you guys for the fast replies

Further:

  • Very stable power supply present (I know problems that come out from bad power supply). Dedicated and original power supply source.
  • Ethernet connection by cable directly on the MODEM port
  • RPI is updated to lastest stable version of raspbian
  • RPI is dedicated only to this task, so no other background process are present a part from samba (to connect RPI desktop to my laptop) and default processes present on raspbian

Right now my application principles are the follwing:

  • Blynk code generate a detached thread to listen for incoming commection from my endpoints
  • If a new endpoint has been detected it is inserted in a shared table with its file descriptor and a new detached thread is generated to server command from your cloud server to my endpoint node. This thread, for each connected endpoint, generates automatically a temperature read command every 5 seconds (with blocking recv() function) and the result is saved inside a shared table where each result is identified by the file descriptor of the node that give me asked result
  • If a temperature read command comes from cloud it will read result saved in the shared table filled with result by the thread that ask every 5 seconds the node 's temperature.

My code will be visible in few hours

/**
 * @file       main.cpp
 * @author     Volodymyr Shymanskyy
 * @license    This project is released under the MIT License (MIT)
 * @copyright  Copyright (c) 2015 Volodymyr Shymanskyy
 * @date       Mar 2015
 * @brief
 */

//#define BLYNK_DEBUG
#define BLYNK_PRINT stdout
#ifdef RASPBERRY
  #include <BlynkApiWiringPi.h>
#else
  #include <BlynkApiLinux.h>
#endif
#include <BlynkSocket.h>
#include <BlynkOptionsParser.h>

static BlynkTransportSocket _blynkTransport;
BlynkSocket Blynk(_blynkTransport);

static const char *auth, *serv;
static uint16_t port;

#include <BlynkWidgets.h>
#include "HomeBridge.h"

WidgetTerminal TermExec(V11);
WidgetTerminal TermLog(V10);

// Sala update temperature reading
BLYNK_READ(V5) {
	
	double Temp;
	
	if(HomeBridge_TemperatureGet("TS1", &Temp) < 0) {
		Blynk.virtualWrite(V11, "TS1 - Error on command execution\r\n");
	} else {
		Blynk.virtualWrite(V5, Temp1);
	}
}

// Asilo update temperature reading
BLYNK_READ(V6) {
	
	double Temp;
	
	if(HomeBridge_TemperatureGet("TS2", &Temp) < 0) {
		Blynk.virtualWrite(V11, "TS2 - Error on command execution\r\n");
	} else {
		Blynk.virtualWrite(V6, Temp2);
	}
}

void setup()
{
	Blynk.begin(auth, serv, port);
    
	// Start Home Bridge thread
    HomeBridge_Initialization();
}

void loop()
{
    Blynk.run();
}


int main(int argc, char* argv[])
{
    parse_options(argc, argv, auth, serv, port);

    setup();
	
    while(true) {
        loop();
    }

    return 0;
}

/**************************HomeBridge.c**************************/
#include "HomeBridge.h"

/* Max 10 device attacched */
#define MAX_CONN_DEVICES	10
#define MSG_BUFFER_DIM		16

void HomeBridge_ServerHandler(void);
void HomeBridge_ClientHandler(void * sockFd);
void HomeBridge_LogStream(string LogDescr);

// Entry points thread funcitons
static void * HomeBridge_ServerHandlerEntryPoint(void * unused);
static void * HomeBridge_ClientHandlerEntryPoint(void * sockFd);

// pthread stuffs as global variables for module
pthread_t 		SrvThread;
pthread_t 		ClntThread;

/* Connected Devices list - SHARED VARIABLE */
static struct DeviceTable	DeviceList[MAX_CONN_DEVICES];

/******************************************************************************/
void HomeBridge_Initialization(void) {
	
    pthread_create(&SrvThread, NULL, HomeBridge_ServerHandlerEntryPoint, NULL);
}

/******************************************************************************/
int HomeBridge_TemperatureGet(char * devID, double * Temp) {
	
	int i = 0;
	int DataIndex;
	bool Found = true;
	
	// Get device list position
	while(memcmp(DeviceList[i].Name, devID, sizeof(DeviceList[i].Name)) != 0) {
		if(i >= MAX_CONN_DEVICES) {
			Found = false;
			cout<<"Device not found in list because not yet connected"<<endl; 
			break;
		} else {
			i++;
		}
	}
	
	if(Found == true) {
		// Get related data
		DataIndex = ((DeviceList[i].DataIndex == 0) ? 1 : 0);
		*Temp = DeviceList[i].Temperature[DataIndex];
		return 0;
	} else {
		return -1;
	}
}

/******************************************************************************/
int HomeBridge_EventQueueInsert(char * devID, char * Cmd) {
	
	int i = 0;
	bool Found = true;
	
	// Get device list position
	while(memcmp(DeviceList[i].Name, devID, sizeof(DeviceList[i].Name)) != 0) {
		if(i >= MAX_CONN_DEVICES) {
			Found = false;
			cout<<"Device not found in list because not yet connected"<<endl; 
			break;
		} else {
			i++;
		}
	}
	
	if(Found == true) {
		// Wait untill previous command has been executed
		while(DeviceList[i].NewCmd == true);
		
		// Save connected device ID
		memcpy(DeviceList[i].Command, Cmd, sizeof(DeviceList[i].Command));
		DeviceList[i].NewCmd = true;
		
		return 0;
	} else {
		return -1;
	}
}

/******************************************************************************/
void HomeBridge_ClientHandler(void * sockFd) {
	
	int i = 0u;
	time_t Start = 0;
	time_t Elapsed = 0;
	// Get socked file descriptor
	int socketFd = *(int *)sockFd;
	char Buf[MSG_BUFFER_DIM];
	
	// Create thread
	pthread_detach(pthread_self());
	
	// Get device list position
	while(DeviceList[i].Sock != socketFd) {
		i++;
	}
	
	// Send command to connected device
	if(send(socketFd, "WHO", sizeof("WHO"), 0) < 0) {
		cout<<"Node Identification sending error [fd ="<<socketFd<<"]"<<endl;
	}
	
	// Blocking receiving ID from connected device
	if(recv(socketFd, Buf, MSG_BUFFER_DIM, 0) < 0) {
		cout<<"Node Identification retrieving error [fd ="<<socketFd<<"]"<<endl;
	} else {
		// Save connected device ID
		memcpy(DeviceList[i].Name, Buf, (sizeof(DeviceList[i].Name) - 1u));
		DeviceList[i].Name[4] = '\0';
		cout<<DeviceList[i].Name<<" Connected"<<endl;
	}
	
	// Get starting time
	Start = time(NULL);
	
	// Connection engaged
	while(1) {
		
		if(DeviceList[i].NewCmd == true) {
			// Send command to connected device
			if(send(socketFd, DeviceList[i].Command, sizeof(DeviceList[i].Command), 0) < 0) {
				cout<<"["<<DeviceList[i].Name<<"]"<<"Data sending error [fd ="<<socketFd<<"]"<<endl;
			}
			
			// Blocking receiving ID from connected device
			if(recv(socketFd, Buf, MSG_BUFFER_DIM, 0) < 0) {
				cout<<"["<<DeviceList[i].Name<<"]"<<"Data retrieving error [fd ="<<socketFd<<"]"<<endl;
			} else {
				// Convert ASCII value to double
				//DeviceList[i].Temperature = atof(Buf);
			}
			
			// Set queued command consumed
			DeviceList[i].NewCmd = false;
			
			sleep(100);
		} else {
			// Get temperature every 5 seconds
			Elapsed = difftime(time(NULL), Start);
			
			if(Elapsed > 5) {
				// Send command to connected device
				if(send(socketFd, "GET", sizeof("GET"), 0) < 0) {
					cout<<"["<<DeviceList[i].Name<<"]"<<"Temperature sending error [fd ="<<socketFd<<"]"<<endl;
				}
				
				// Blocking receiving ID from connected device
				if(recv(socketFd, Buf, MSG_BUFFER_DIM, 0) < 0) {
					cout<<"["<<DeviceList[i].Name<<"]"<<"Temperature retrieving error [fd ="<<socketFd<<"]"<<endl;
				} else {
					// Convert ASCII value to double
					DeviceList[i].DataIndex = ((DeviceList[i].DataIndex == 0) ? 1 : 0);
					DeviceList[i].Temperature[DeviceList[i].DataIndex] = atof(Buf);
				}
				
				// Get new time
				Start = time(NULL);
			}
		}
	}
}

/******************************************************************************/
void HomeBridge_ServerHandler(void)
{
	int 					DevIndex = 0u;
	int 					serverSocket, newSocket;
	struct sockaddr_in 		serverAddr, clientAddr;
	socklen_t 				addr_size;
  
	// Create thread
	pthread_detach(pthread_self());
	
	// Reset device list table
	memset(DeviceList, 0, sizeof(DeviceList));
	
	// Create the socket. 
	serverSocket = socket(AF_INET, SOCK_STREAM, 0);
	if(serverSocket < 0)
		HomeBridge_LogStream("Error on socket creation");
  
	// Configure settings of the server address struct
	bzero((char*) &serverAddr, sizeof(serverAddr));
	// Address family = Internet 
	serverAddr.sin_family = AF_INET;
	// Set port number, using htons function to use proper byte order 
	serverAddr.sin_port = htons((long)12001);
	// Set IP address to localhost 
	serverAddr.sin_addr.s_addr = INADDR_ANY;
	// Set all bits of the padding field to 0 
	//memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
	
	// Bind the address struct to the socket 
	if(bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)) < 0)
		HomeBridge_LogStream("Error on socket bind");
  
	// Listen on the socket, with 10 max connection requests queued 
	if(listen(serverSocket, 10) < 0)
		HomeBridge_LogStream("Error on listening");

	while(1)
    {
        // Accept call creates a new socket for the incoming connection
        newSocket = accept(serverSocket, (struct sockaddr *) &clientAddr, &addr_size);
		
		if(newSocket != -1) {
			if(DevIndex == (MAX_CONN_DEVICES - 1)) {
				HomeBridge_LogStream("Too many devices already connected");
			} else {
				/* Save attached device */
				DeviceList[DevIndex].Sock = newSocket;
				DevIndex++;
			
				if(pthread_create(&ClntThread, NULL, HomeBridge_ClientHandlerEntryPoint, (void *)&newSocket) != 0) {
					HomeBridge_LogStream("Failed to create Client thread");
				}
			}
		} else {
			HomeBridge_LogStream("Error on socket accept");
		}	
    }
}

/******************************************************************************/
void HomeBridge_LogStream(string LogDescr) {
	
	int			mrk;
	char		LogData[64];
	// Initialize date time
	time_t 		Time = time(NULL);
	struct tm 	*DateTime = localtime(&Time);
	
	// Format output log string
	mrk = strftime(LogData, sizeof(LogData), "[%D - %H:%M:%S] ", DateTime);
	strcpy(&LogData[mrk], LogDescr.c_str());
	
	cout<<LogData<<endl;
}

/**************************************HomeBridge.h************************************/
#ifndef HOMEBRIDGE_H
#define HOMEBRIDGE_H

#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sys/time.h>

using namespace std;

/* Attached device list */
struct DeviceTable {
	int  			Sock;
	char			Name[4];
	char			Command[4];
	int				DataIndex;
	double			Temperature[2];
	double			Humidity;
	double			Power;
	bool			NewCmd;
};

extern void HomeBridge_Initialization(void);
extern int HomeBridge_EventQueueInsert(char * devID, char * Cmd);
extern int HomeBridge_TemperatureGet(char * devID, double * Temp);
/*extern void HomeBridge_HumidityGet(string devID, double * Hum);
extern void HomeBridge_EnergyGet(string devID, double * KWh);*/

#endif	//HOMEBRIDGE_H

Fixed your code post… backticks, not commas or apostrophes :wink:

Sorry, but now posted code should be correctly modified