Blynk super slow response

Hi. I communicated two ESP8266 through BLYNK BRIDGE. I did tests and everything was fine. My broad project consists of sending data from an accelerometer / gyroscope (MPU6050) to the master ESP and that it sends the data to the slave ESP to control a led strip (WS2812) and an audio card (Tsunami wav trigger). Up to this point it all works perfectly BUT when I add the virtual pins part to the App, it becomes exaggeratedly slow, it stops working as it should.

I already tried changing wifi signals. Any suggestions? please

MASTER

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include "I2Cdev.h"
#include "MPU6050.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif

MPU6050 accelgyro;

int16_t ax, ay, az;
int16_t gx, gy, gz; 

//new
long tiempo_prev;
float dt;
float ang_x, ang_y, ang_z;
float ang_x_prev, ang_y_prev, ang_z_prev; 

char auth[] = "JHzKPO_BFl8_k_6z7We62kX6UYjxDsC6";

char ssid[] = "INFINITUM3EF9_2.4";
char pass[] = "kYX95bL3L9";
//char ssid[] = "wifi bonito";
//char pass[] = "pepepecas";

// Bridge widget on virtual pin 1
WidgetBridge bridge1(V1);

// Timer for blynking
BlynkTimer timer;

BLYNK_CONNECTED() {
  bridge1.setAuthToken("5LTsygvSwVPMC6kAOpW1HWjfnJ3tKCDh"); // Place the AuthToken of the second hardware here
}

void setup()
{
   #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif
  
  Serial.begin(115200);
    // Inicializa el MPU6050
    Serial.println("Initializing I2C devices...");
    accelgyro.initialize();

    // Verifica la conexiĂłn
    Serial.println("Testing device connections...");
    Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");

  Blynk.begin(auth, ssid, pass);
  timer.setInterval(10, updateFiltered);
 
 //new
 //**OFFSETS DEL MPU6050 HORIZONTAL **//  
  accelgyro.setXAccelOffset(-742); //-523            
  accelgyro.setYAccelOffset(-2806); //-2809
  accelgyro.setZAccelOffset(1028); //1023
  accelgyro.setXGyroOffset(48); //83 76
  accelgyro.setYGyroOffset(11);//18 22
  accelgyro.setZGyroOffset(9); //13 
}

//funciĂłn para filtro complementario
void updateFiltered()
{
      dt = (millis() - tiempo_prev) / 1000.0;
   tiempo_prev = millis();
 
   //Calcular los ĂĄngulos con acelerometro
   float accel_ang_x = atan(ay / sqrt(pow(ax, 2) + pow(az, 2)))*(180.0 / 3.14);
   float accel_ang_y = atan(-ax / sqrt(pow(ay, 2) + pow(az, 2)))*(180.0 / 3.14);
 
   //Calcular angulo de rotaciĂłn con giroscopio y filtro complementario
   ang_y = 0.3*(ang_y_prev + (gy / 131)*dt) + 0.7*accel_ang_y;
   ang_x = 0.6*(ang_x_prev + (gz / 131)*dt) + 0.4*accel_ang_x; //NO CAMBIAR NADA, ESTÁ PERFECTO ASÍ :)
 
   ang_x_prev = ang_x; //MOVIMIENTOS A LOS COSTADOS
   ang_y_prev = ang_y; //MOVIMIENTOS FRONTALES 
 
  Serial.print("\t"); 
  Serial.print("Rotacion en X:  "); 
  Serial.print(ang_x_prev);
  Serial.print("\t Rotacion en Y: "); 
  Serial.println(ang_y_prev);  

  //ENVÍO DE DATOS AL OTRO ESP8266
   bridge1.virtualWrite(V3, ang_x_prev);
   bridge1.virtualWrite(V4, ang_y_prev);
} 

void loop()
{
  Blynk.run();
  timer.run();  
  accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
}

SLAVE

#include <SoftwareSerial.h>
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
BlynkTimer timer;
char auth [] = "5LTsygvSwVPMC6kAOpW1HWjfnJ3tKCDh";

//char ssid[] = "INFINITUM3EF9_2.4";
//char pass[] = "kYX95bL3L9";
char ssid[] = "wifi bonito";
char pass[] = "pepepecas";

int brillo;
int lastvalxmap;
int valX; //inclinacion en x
int valY; //inclinacion en z
int valxmap;  //valor mapeado
int valxmapabs;
int valymap;  //valor mapeado
int valymapabs;

//variables para cambio de color
int R;
int G;
int B;
 
//**************************TSUNAMI**************************************
#define TSUNAMI_NUM_OUTPUTS  8

#define CMD_TRACK_CONTROL      3
#define CMD_STOP_ALL           4
#define CMD_MASTER_VOLUME      5
#define CMD_TRACK_VOLUME       8
#define CMD_TRACK_FADE         10
#define CMD_SET_INPUT_MIX      15
#define CMD_SET_MIDI_BANK      16

#define TRK_PLAY_SOLO 0
#define TRK_PLAY_POLY 1
#define TRK_PAUSE     2
#define TRK_RESUME    3
#define TRK_STOP      4
#define TRK_LOOP_ON   5
#define TRK_LOOP_OFF  6
#define TRK_LOAD      7

#define SOM1  0xf0
#define SOM2  0xaa
#define EOM   0x55

#define IMIX_OUT1 0x01
#define IMIX_OUT2 0x02
#define IMIX_OUT3 0x04
#define IMIX_OUT4 0x08

  uint16_t numTracks;
  uint8_t numVoices;
  uint8_t rxCount;
  uint8_t rxLen;
  bool rxMsgReady;
  bool versionRcvd;
  bool sysinfoRcvd;
 
//PINES TIRA LED***********************************************************
#define PIN        D2 //pin del esp8266 IZQUIERDA
#define PIN2       D5 //DERECHA
#define NUMPIXELS 22 // 22 chips que controlan 3 leds cada uno. 66 leds en total

//PINES TSUNAMI************************************************************
const byte txpin = 2;              //D4 pin transmisor
const byte rxpin = 5;              //D1 pin receptor
SoftwareSerial tsunami(rxpin, txpin);  // Crea un objeto para la trasmision serial
 
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_BRG + NEO_KHZ800);  //configuraciĂłn tira led tipo BRG
Adafruit_NeoPixel pixels2(NUMPIXELS, PIN2, NEO_BRG + NEO_KHZ800);  //configuraciĂłn tira led tipo BRG

//******CONNECTED*****************
/*BLYNK_CONNECTED() {
  //Blynk.syncVirtual(V);
  Blynk.syncVirtual(V3, V4);
}*/
//********************************
BLYNK_WRITE (V3) {
  valX = param.asInt (); //RECIBE ANGULO X
 // Serial.println(valX); OK
 //***MAPEO DE LOS VALORES DE LA WAV TRIGGER***//   21*4=84
  valxmap = valX;
  valxmap = map(valxmap, 0.00, 84.00, 0.00, 66.00); 
   // Serial.println(valxmap);
  //Para casos de valores negativos:
   valxmapabs = abs(lastvalxmap);
}
//*************************************************
BLYNK_WRITE (V4) {
  valY = param.asInt (); //RECIBE ANGULO Y
 
 //***MAPEO DE LOS VALORES DE LA WAV TRIGGER***//
  valymap = valY;
  valymap = map(valymap, 0.00, 84.00, 0.00, 240.00); 

  //Serial.print("anguloY");
  //Serial.println(valY);

  //Para casos de valores negativos:
  brillo =  (abs(valymap)+15);
}
//*************************************************

BLYNK_WRITE(V6) {
  switch (param.asInt())
  {
    case 1: // Item 1
      Serial.println("color rojo");
        B = 255;
        R = 0;
        G= 0;
      break;
    case 2: // Item 2
      Serial.println("color azul");
        B = 0;
        R = 255;
        G= 0;
      break;
    case 3:
     Serial.println("color verde");
       B = 0;
       R = 0;
       G= 255;
    break;
    case 4:
     Serial.println("color amarillo");
       B = 255;
       R = 0;
       G= 255;
    break;
     case 5:
     Serial.println("color morado");
       B = 87;
       R = 100;
       G= 35;
    break;
    case 6:
     Serial.println("color naranja");
       B = 255;
       R = 0;
       G= 128;
    break;
     case 7:
     Serial.println("color rosa");
       B = 255;
       R = 128;
       G= 0;
    break;
  }
}
//*************************************************
void setup () {
  Serial.begin (115200);
  Blynk.begin (auth, ssid, pass);
  tsunami.begin(9600);  
 
 //Temporizadores de funciones
 timer.setInterval(10, luces);

 //***INICIALIZACIÓN DE LA TIRA LED***//
  #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif

  pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
  pixels2.begin();

  pixels.clear();
  pixels2.clear();
}
//*******************LUZ Y SONIDO**********************************
void luces(){
  
if(valxmap == 0){
   pixels.clear();
   pixels2.clear();
  }
  
//DERECHA
if (valxmap > 0) {
   clearizquierda();
   
  if (valxmap != lastvalxmap) {
  lastvalxmap = valxmap;
 

     for( int a = lastvalxmap; a <= NUMPIXELS; a++){
         pixels.setPixelColor(a, pixels.Color(0, 0, 0)); //NADA
     }//for para "limpiar" el color

     for( int b = 0; b < lastvalxmap; b++){
         pixels.setPixelColor(b, pixels.Color(B, R, G)); //VERDE
         pixels.setBrightness(brillo); //brillo de los leds basado en movimiento adelante
     }//for para asignar color 
     
   pixels.show();
   trackPlayPoly(valxmapabs, 3, true);  //BOCINA CABEZA DERECHA 0
   //trackGain(valxmapabs, 5);
 //  tsunami.trackFade(2, 0, 2000, false);  // Fade Track 2 to 0dB over 2 sec
  }
}// final if DERECHA

//IZQUIERDA
if (valxmap < 0) {
 clearderecha();
 
if (valxmap != lastvalxmap) {
  lastvalxmap = valxmap;

     for( int a = valxmapabs; a <= NUMPIXELS; a++){
         pixels2.setPixelColor(a, pixels2.Color(0, 0, 0)); //NADA
     }//for para "limpiar" el color

     for( int b = 0; b < valxmapabs; b++){
         pixels2.setPixelColor(b, pixels2.Color(B, R, G)); //VERDE
         pixels2.setBrightness(brillo); //brillo de los leds  basado en movimiento atrĂĄs
        
     }//for para asignar color 
   
   pixels2.show();
  
   trackPlayPoly(valxmapabs, 1, true); //BOCINA CABEZA IZQUIERDA 4
  // trackGain(valxmapabs, 5);
  // tsunami.trackFade(2, 0, 2000, false);  // Fade Track 2 to 0dB over 2 sec
   } 
}// final if IZQUIERDA
}
//*****************************************************************

void clearderecha(){
   for( int e = lastvalxmap; e <= NUMPIXELS; e++){
         pixels.setPixelColor(e, pixels.Color(0, 0, 0)); //NADA
     } 
     pixels.show();
}//final void1

void clearizquierda(){
   for( int e = lastvalxmap; e <= NUMPIXELS; e++){
         pixels2.setPixelColor(e, pixels2.Color(0, 0, 0)); //NADA
     } 
     pixels2.show();
}//final void2

//**************************CONTROL*******************************************
void trackControl(int trk, int code, int out, int flags) {
  
uint8_t txbuf[10];
uint8_t o;

  o = out & 0x07;
  txbuf[0] = SOM1;
  txbuf[1] = SOM2;
  txbuf[2] = 0x0a;
  txbuf[3] = CMD_TRACK_CONTROL;
  txbuf[4] = (uint8_t)code;
  txbuf[5] = (uint8_t)trk;
  txbuf[6] = (uint8_t)(trk >> 8);
  txbuf[7] = (uint8_t)o;
  txbuf[8] = (uint8_t)flags;
  txbuf[9] = EOM;

  tsunami.write(o);
  tsunami.write(SOM1);
  tsunami.write(SOM2);
  tsunami.write(0x0a);
  tsunami.write(CMD_TRACK_CONTROL);
  tsunami.write((uint8_t)code);
  tsunami.write((uint8_t)trk);
  tsunami.write((uint8_t)(trk >> 8));
  tsunami.write((uint8_t)o);
  tsunami.write((uint8_t)flags);
  tsunami.write(EOM);
}
//***************************POLY**********************************************
void trackPlayPoly(int trk, int out, bool lock) {
  
int flags = 0;

  if (lock)
    flags |= 0x01;
  trackControl(trk, TRK_PLAY_POLY, out, flags);
}
//***************************GAIN**********************************************
void trackGain(int trk, int gain) {

uint8_t txbuf[9];
unsigned short vol;

  txbuf[0] = SOM1;
  txbuf[1] = SOM2;
  txbuf[2] = 0x09;
  txbuf[3] = CMD_TRACK_VOLUME;
  txbuf[4] = (uint8_t)trk;
  txbuf[5] = (uint8_t)(trk >> 8);
  vol = (unsigned short)gain;
  txbuf[6] = (uint8_t)vol;
  txbuf[7] = (uint8_t)(vol >> 8);
  txbuf[8] = EOM;
}
//****************************LOOP********************************************
void loop () {
  Blynk.run ();
  timer.run();  
}

Master

timer.setInterval(10, updateFiltered);

Slave

timer.setInterval(10, luces);

Timer Intervals are in millisecs. It might be

Master

timer.setInterval(10000, updateFiltered);

Slave

timer.setInterval(10000, luces);

When you use the bridge widget the receiving end should have a virtual write as well
eg.
BLYNK_WRITE (V3)
{
valX = Parma.asInt();
Blynk.virtualWrite (V3, valX);

As already pointed out above, your extremely fast timers triggered Blynk’s “anti-flooding” action, which tends to slow down the whole processing. Even with Bridge, try to keep within the 10 Writes Per Second recommendation.

Thank you all for answering. Now I made the change from 10ms to 100 ms in both codes (I require the response to be as fast as possible).
I also added the Blynk.virtualWrite at the Bridge reception. But it’s still just as slow. It even seems that it stops at times :frowning:

Blynk (background library control) wants to run as fast as it can, but without flooding, and will intervene if you try to push too much too fast.

So try increasing your timers to 1000 (1 second), at a minimum, and see if that helps… then slowly reduce (or increase) the timing until you find a workable balance.

I just now find out by reading the code that this is just something for fun. Slave displays LED strings according to some movements from Master;s accel-gyroscope.

I’ve been mistaken that this project is doing something serious and useful to spend some time to look at it.

So I’m going to retract every comments as if for real Tsunami detection project.

1 Like

“accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz”
What is this doing in the loop? Loop should be clean

If this is indeed a Tsunami alarm which works by looking for a local seismic event and aims to warn of the likelihood of an impending tsunami, then there are more design flaws…

  1. the duration of the seismic event will be an important indicator of the likelihood of a tsunami occurring. As a result, the duration needs to be measured (which the code doesn’t appear to do) and the alarm triggered only if it meets the desired duration and intensity.

  2. while it is important to have as much warning of an impending potential tsunami as possible, seismic waves travel much faster than sea waves in deep water. This means that there is a significant delay between the seismic event and the resulting tsunami, so speed of response of the detection system isn’t as critical as it may seem.

  3. Mrs K and I survived the 2004 Boxing Day tsunami, and we felt no seismic activity beforehand (despite it being a 9.1 magnitude event) but the impact of the tsunami where we were (Phuket, Thailand) was devastating. So, seismic monitoring alone in a single location isn’t necessarily an indication that a tsunami will or won’t occur in that location.

  4. as @Tania is located in Central America then a better (or maybe additional) solution may be to use tsunami alert data from NOAA which is available via a variety of data feed formats.

  5. I still don’t understand why the project uses two ESP devices.

  6. the Slave code uses SoftwareSerial. I thought that there was a major issue when using SoftwareSerial with the ESP core and that EspSoftwareSerial had to be used instead.

Pete.

1 Like

Dear @PeteKnight

I’m as mistaken as you’re that this is real-Tsunami project. Maybe we’re too out-of-date, not keeping up with the new trends :slight_smile:

Yes, I had my doubts about that, but my last two pints are relevant anyway.

Pete.