How to add Blynk to my MPU-6050 "Movement Detector"

My coding skills may leave a lot to be desired but my ability to spend money is admirable. :joy:

@Gunner @Costas My D1 Mini Pro’s arrived this morning. I’m surprised by how small they are, I was expecting something similar to the NodeMCU’s I have.

Edit
And they load super fast. :astonished:
Do I need to buy antenna’s for them?

1 Like

Yes if you want optimum range and a minor hack to the board.

1 Like

Can you recommend a particular type, there seems to be a lot to choose from.

You’re missing a right facing curly bracket “}” before the line that says:

BLYNK_WRITE(V13) // Alarm ON/OFF Button set to SWITCH mode

You’ll then find another error, you didn’t declare the variable MotionOnFlag
You need to declare it as a global variable at the top of your code, probably as a Boolean variable type.

I know its not considered the cool way to structure code, but I prefer to have all of my curly brackets on the left hand side of the screen, indented so that I can see when one’s missing. Some of your code is written a bit like that, but the rest isn’t. I find it really difficult when the first curly bracket is at the end of a long if statement and the corresponding closing one is floating around on the left hand side of the screen.

Pete.

1 Like

@PeteKnight I’ve sorted those, I think. Then I had to move a few things around and Now I’m getting a new error:

error: 'PitchRollSensorRead' was not declared in this scope

This has me beat. :weary:

This “Blynk Button” has defeated me. Why does this error get me in one skectch but not another?

error: 'PitchRollSensorRead' was not declared in this scope
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>`
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include <MPU6050.h>

char auth[] = "060348058fd549f083b9b649e6784852";
char ssid[] = "BTHub6-P38S";
char pass[] = "wAwhd7rKg3cT";

int MotionOnFlag;
int LimitationFlag = 0;

BlynkTimer timer;

MPU6050 mpu;

void setup() 
{
  Serial.begin(115200);

  Blynk.begin(auth, ssid, pass);

  Serial.println("Initialize MPU6050");

  while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_16G))
  {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }
  
  mpu.setAccelPowerOnDelay(MPU6050_DELAY_3MS);

  mpu.setIntFreeFallEnabled(false);  
  mpu.setIntZeroMotionEnabled(false);
  mpu.setIntMotionEnabled(false);
  
  mpu.setDHPFMode(MPU6050_DHPF_5HZ);

  mpu.setMotionDetectionThreshold(2);
  mpu.setMotionDetectionDuration(5);

  mpu.setZeroMotionDetectionThreshold(8);
  mpu.setZeroMotionDetectionDuration(2);
  
  checkSettings();
  timer.setInterval(100L, MotionSensorRead); // run the scan for motion function loop 10x/second
  timer.setInterval(100L, PitchRollSensorRead); // run the scan for Pitch & Roll function loop 10x/second
 
}

void checkSettings()
{
  Serial.println();
  
  Serial.print(" * Sleep Mode:                ");
  Serial.println(mpu.getSleepEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Motion Interrupt:          ");
  Serial.println(mpu.getIntMotionEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Zero Motion Interrupt:     ");
  Serial.println(mpu.getIntZeroMotionEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Free Fall Interrupt:       ");
  Serial.println(mpu.getIntFreeFallEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Motion Threshold:          ");
  Serial.println(mpu.getMotionDetectionThreshold());
  Serial.print(" * Motion Duration:           ");
  Serial.println(mpu.getMotionDetectionDuration());
  Serial.print(" * Zero Motion Threshold:     ");
  Serial.println(mpu.getZeroMotionDetectionThreshold());
  Serial.print(" * Zero Motion Duration:      ");
  Serial.println(mpu.getZeroMotionDetectionDuration());
  
  Serial.print(" * Clock Source:              ");
  switch(mpu.getClockSource())
  {
    case MPU6050_CLOCK_KEEP_RESET:     Serial.println("Stops the clock and keeps the timing generator in reset"); break;
    case MPU6050_CLOCK_EXTERNAL_19MHZ: Serial.println("PLL with external 19.2MHz reference"); break;
    case MPU6050_CLOCK_EXTERNAL_32KHZ: Serial.println("PLL with external 32.768kHz reference"); break;
    case MPU6050_CLOCK_PLL_ZGYRO:      Serial.println("PLL with Z axis gyroscope reference"); break;
    case MPU6050_CLOCK_PLL_YGYRO:      Serial.println("PLL with Y axis gyroscope reference"); break;
    case MPU6050_CLOCK_PLL_XGYRO:      Serial.println("PLL with X axis gyroscope reference"); break;
    case MPU6050_CLOCK_INTERNAL_8MHZ:  Serial.println("Internal 8MHz oscillator"); break;
  }
  
  Serial.print(" * Accelerometer:             ");
  switch(mpu.getRange())
  {
    case MPU6050_RANGE_16G:            Serial.println("+/- 16 g"); break;
    case MPU6050_RANGE_8G:             Serial.println("+/- 8 g"); break;
    case MPU6050_RANGE_4G:             Serial.println("+/- 4 g"); break;
    case MPU6050_RANGE_2G:             Serial.println("+/- 2 g"); break;
  }  

  Serial.print(" * Accelerometer offsets:     ");
  Serial.print(mpu.getAccelOffsetX());
  Serial.print(" / ");
  Serial.print(mpu.getAccelOffsetY());
  Serial.print(" / ");
  Serial.println(mpu.getAccelOffsetZ());

  Serial.print(" * Accelerometer power delay: ");
  switch(mpu.getAccelPowerOnDelay())
  {
    case MPU6050_DELAY_3MS:            Serial.println("3ms"); break;
    case MPU6050_DELAY_2MS:            Serial.println("2ms"); break;
    case MPU6050_DELAY_1MS:            Serial.println("1ms"); break;
    case MPU6050_NO_DELAY:             Serial.println("0ms"); break;
  }  
  
  Serial.println();
}

void MotionSensorRead() {  // Motion sensor read(Bike Alarm)
  Vector rawAccel = mpu.readRawAccel();
  Activites act = mpu.readActivites();
  if (act.isActivity)
  {
    Blynk.virtualWrite(V14, "Yes");
  } else
  {
    Blynk.virtualWrite(V14, "No");
  }

  if (act.isInactivity)
  {
    Blynk.virtualWrite(V15, "Yes");
  } else
  {
    Blynk.virtualWrite(V15, "No");
  }
}

  if (MotionOnFlag == 1 && LimitationFlag == 0) {  // Check if both ON and that limit flag is inactive
    LimitationFlag = 1; // Set time limit flag for notifications
    timer.setTimeout(16000L, LimitationFlagReset);  // Start 16 second timer for limiting flag reset
    Vector rawAccel = mpu.readRawAccel();
    Activites act = mpu.readActivites();
    if (normGyro.XAxis > maxval || normGyro.XAxis < minval && normGyro.YAxis > maxval || normGyro.YAxis  < minval && normGyro.ZAxis > maxval || normGyro.ZAxis  < minval) {
      Blynk.virtualWrite(V10, "Movement Detected");
      Blynk.notify("BIKE BEING STOLEN!");
    }  else {
      Blynk.virtualWrite(V10, "Bike Secure");
    }
  }
}
  MotionOnFlag = param.asInt();
}
void LimitationFlagReset() {
  LimitationFlag = 0;  // Reset limitation flag
  
void PitchRollSensorRead() {  // Pitch & Roll sensor read(Bike Telemetry)
  Vector normAccel = mpu.readNormalizeAccel();
  Vector normGyro = mpu.readNormalizeGyro();

  // add/remove /* and */ to enable-disable serial prints
  Serial.print(" Accel Xnorm = ");
  Serial.println(normAccel.XAxis);
  Serial.print(" Accel Ynorm = ");
  Serial.println(normAccel.YAxis);
  Serial.print(" Accel Znorm = ");
  Serial.println(normAccel.ZAxis);
  Serial.print(" Gyro Xnorm = ");
  Serial.println(normGyro.XAxis);
  Serial.print(" Gyro Ynorm = ");
  Serial.println(normGyro.YAxis);
  Serial.print(" Gyro Znorm = ");
  Serial.println(normGyro.ZAxis);

  Blynk.virtualWrite(V20, normAccel.XAxis);
  Blynk.virtualWrite(V21, normAccel.YAxis);
  Blynk.virtualWrite(V22, normAccel.ZAxis);
  Blynk.virtualWrite(V23, normGyro.XAxis);
  Blynk.virtualWrite(V24, normGyro.YAxis);
  Blynk.virtualWrite(V25, normGyro.ZAxis);  

  Blynk.syncVirtual(V13);  // Checks current status of Alarm ON/OFF button and updates sketches awareness of it
}
  BLYNK_WRITE(V13) { // Alarm ON/OFF Button set to SWITCH mode
}

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

put:

void PitchRollSensorRead();
void MotionSensorRead();

Right below your char auth, ssid etc.

The timer setup in setup() needs to know about the existence of those functions before it can do anything with it, so you have to say they exist first. I think this has something to do with the way Arduino compiles (specificly in what order).

1 Like

Thanks @Lichtsignaal
Why does the code before I try to add the Blynk Button compile and run perfectly without me having to add:

void PitchRollSensorRead();
void MotionSensorRead();

I know this is probably a dumb question but, why does it require to know the “existence” of those functions in this code but not the previous one without the Blynk Button?

Here’s the code before I tried to add the Blynk Button.

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>`
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include <MPU6050.h>

char auth[] = "060348058fd549f083b9b649e6784852";
char ssid[] = "BTHub6-P38S";
char pass[] = "wAwhd7rKg3cT";

BlynkTimer timer;

MPU6050 mpu;

void setup() 
{
  Serial.begin(115200);

  Blynk.begin(auth, ssid, pass);

  Serial.println("Initialize MPU6050");

  while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_16G))
  {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }
  
  mpu.setAccelPowerOnDelay(MPU6050_DELAY_3MS);

  mpu.setIntFreeFallEnabled(false);  
  mpu.setIntZeroMotionEnabled(false);
  mpu.setIntMotionEnabled(false);
  
  mpu.setDHPFMode(MPU6050_DHPF_5HZ);

  mpu.setMotionDetectionThreshold(2);
  mpu.setMotionDetectionDuration(5);

  mpu.setZeroMotionDetectionThreshold(8);
  mpu.setZeroMotionDetectionDuration(2);
  
  checkSettings();
  timer.setInterval(100L, MotionSensorRead); // run the scan for motion function loop 10x/second
  timer.setInterval(100L, PitchRollSensorRead); // run the scan for Pitch & Roll function loop 10x/second
 
}

void checkSettings()
{
  Serial.println();
  
  Serial.print(" * Sleep Mode:                ");
  Serial.println(mpu.getSleepEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Motion Interrupt:          ");
  Serial.println(mpu.getIntMotionEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Zero Motion Interrupt:     ");
  Serial.println(mpu.getIntZeroMotionEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Free Fall Interrupt:       ");
  Serial.println(mpu.getIntFreeFallEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Motion Threshold:          ");
  Serial.println(mpu.getMotionDetectionThreshold());
  Serial.print(" * Motion Duration:           ");
  Serial.println(mpu.getMotionDetectionDuration());
  Serial.print(" * Zero Motion Threshold:     ");
  Serial.println(mpu.getZeroMotionDetectionThreshold());
  Serial.print(" * Zero Motion Duration:      ");
  Serial.println(mpu.getZeroMotionDetectionDuration());
  
  Serial.print(" * Clock Source:              ");
  switch(mpu.getClockSource())
  {
    case MPU6050_CLOCK_KEEP_RESET:     Serial.println("Stops the clock and keeps the timing generator in reset"); break;
    case MPU6050_CLOCK_EXTERNAL_19MHZ: Serial.println("PLL with external 19.2MHz reference"); break;
    case MPU6050_CLOCK_EXTERNAL_32KHZ: Serial.println("PLL with external 32.768kHz reference"); break;
    case MPU6050_CLOCK_PLL_ZGYRO:      Serial.println("PLL with Z axis gyroscope reference"); break;
    case MPU6050_CLOCK_PLL_YGYRO:      Serial.println("PLL with Y axis gyroscope reference"); break;
    case MPU6050_CLOCK_PLL_XGYRO:      Serial.println("PLL with X axis gyroscope reference"); break;
    case MPU6050_CLOCK_INTERNAL_8MHZ:  Serial.println("Internal 8MHz oscillator"); break;
  }
  
  Serial.print(" * Accelerometer:             ");
  switch(mpu.getRange())
  {
    case MPU6050_RANGE_16G:            Serial.println("+/- 16 g"); break;
    case MPU6050_RANGE_8G:             Serial.println("+/- 8 g"); break;
    case MPU6050_RANGE_4G:             Serial.println("+/- 4 g"); break;
    case MPU6050_RANGE_2G:             Serial.println("+/- 2 g"); break;
  }  

  Serial.print(" * Accelerometer offsets:     ");
  Serial.print(mpu.getAccelOffsetX());
  Serial.print(" / ");
  Serial.print(mpu.getAccelOffsetY());
  Serial.print(" / ");
  Serial.println(mpu.getAccelOffsetZ());

  Serial.print(" * Accelerometer power delay: ");
  switch(mpu.getAccelPowerOnDelay())
  {
    case MPU6050_DELAY_3MS:            Serial.println("3ms"); break;
    case MPU6050_DELAY_2MS:            Serial.println("2ms"); break;
    case MPU6050_DELAY_1MS:            Serial.println("1ms"); break;
    case MPU6050_NO_DELAY:             Serial.println("0ms"); break;
  }  
  
  Serial.println();
}

void MotionSensorRead() {  // Motion sensor read(Bike Alarm)
  Vector rawAccel = mpu.readRawAccel();
  Activites act = mpu.readActivites();
  if (act.isActivity)
  {
    Blynk.virtualWrite(V14, "Yes");
  } else
  {
    Blynk.virtualWrite(V14, "No");
  }

  if (act.isInactivity)
  {
    Blynk.virtualWrite(V15, "Yes");
  } else
  {
    Blynk.virtualWrite(V15, "No");
  }
}
void PitchRollSensorRead() {  // Pitch & Roll sensor read(Bike Telemetry)
  Vector normAccel = mpu.readNormalizeAccel();
  Vector normGyro = mpu.readNormalizeGyro();

  // add/remove /* and */ to enable-disable serial prints

  Serial.println();
  
  Serial.print(" Accelerometer Norm ");
  Serial.print(" X-Axis = ");
  Serial.print(normAccel.XAxis);
  Serial.print(" Y-Axis = ");
  Serial.print(normAccel.YAxis);
  Serial.print(" Z-Axis = ");
  Serial.print(normAccel.ZAxis);
  Serial.println();

  Serial.print(" Gyroscope Norm");
  Serial.print(" X-Axis = ");
  Serial.print(normGyro.XAxis);
  Serial.print(" Y-Axis = ");
  Serial.print(normGyro.YAxis);
  Serial.print(" Z-Axis = ");
  Serial.print(normGyro.ZAxis);
  Serial.println();
  
  Blynk.virtualWrite(V20, normAccel.XAxis);
  Blynk.virtualWrite(V21, normAccel.YAxis);
  Blynk.virtualWrite(V22, normAccel.ZAxis);
  Blynk.virtualWrite(V23, normGyro.XAxis);
  Blynk.virtualWrite(V24, normGyro.YAxis);
  Blynk.virtualWrite(V25, normGyro.ZAxis);  
}
void loop()
{
  Blynk.run();
  timer.run();
}

Well the “Button” has beat me. :exploding_head:

Yes its another error I can’t solve. I need my bed :weary:

error: 'Blynk' does not name a type

If anyone’s feeling generous and wants to take a look I’d appreciate it, here’s my code.

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>`
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include <MPU6050.h>
#define minval -1
#define maxval 1

char auth[] = "060348058fd549f083b9b649e6784852";
char ssid[] = "BTHub6-P38S";
char pass[] = "wAwhd7rKg3cT";

int MotionOnFlag;
int LimitationFlag = 0;

void PitchRollSensorRead();
void MotionSensorRead();



BlynkTimer timer;

MPU6050 mpu;

void setup() 
{
  Serial.begin(115200);

  Blynk.begin(auth, ssid, pass);

  Serial.println("Initialize MPU6050");

  while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_16G))
  {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }
  
  mpu.setAccelPowerOnDelay(MPU6050_DELAY_3MS);

  mpu.setIntFreeFallEnabled(false);  
  mpu.setIntZeroMotionEnabled(false);
  mpu.setIntMotionEnabled(false);
  
  mpu.setDHPFMode(MPU6050_DHPF_5HZ);

  mpu.setMotionDetectionThreshold(2);
  mpu.setMotionDetectionDuration(5);

  mpu.setZeroMotionDetectionThreshold(8);
  mpu.setZeroMotionDetectionDuration(2);
  
  checkSettings();
  timer.setInterval(100L, MotionSensorRead); // run the scan for motion function loop 10x/second
  timer.setInterval(100L, PitchRollSensorRead); // run the scan for Pitch & Roll function loop 10x/second
 
}

void checkSettings()
{
  Serial.println();
  
  Serial.print(" * Sleep Mode:                ");
  Serial.println(mpu.getSleepEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Motion Interrupt:          ");
  Serial.println(mpu.getIntMotionEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Zero Motion Interrupt:     ");
  Serial.println(mpu.getIntZeroMotionEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Free Fall Interrupt:       ");
  Serial.println(mpu.getIntFreeFallEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Motion Threshold:          ");
  Serial.println(mpu.getMotionDetectionThreshold());
  Serial.print(" * Motion Duration:           ");
  Serial.println(mpu.getMotionDetectionDuration());
  Serial.print(" * Zero Motion Threshold:     ");
  Serial.println(mpu.getZeroMotionDetectionThreshold());
  Serial.print(" * Zero Motion Duration:      ");
  Serial.println(mpu.getZeroMotionDetectionDuration());
  
  Serial.print(" * Clock Source:              ");
  switch(mpu.getClockSource())
  {
    case MPU6050_CLOCK_KEEP_RESET:     Serial.println("Stops the clock and keeps the timing generator in reset"); break;
    case MPU6050_CLOCK_EXTERNAL_19MHZ: Serial.println("PLL with external 19.2MHz reference"); break;
    case MPU6050_CLOCK_EXTERNAL_32KHZ: Serial.println("PLL with external 32.768kHz reference"); break;
    case MPU6050_CLOCK_PLL_ZGYRO:      Serial.println("PLL with Z axis gyroscope reference"); break;
    case MPU6050_CLOCK_PLL_YGYRO:      Serial.println("PLL with Y axis gyroscope reference"); break;
    case MPU6050_CLOCK_PLL_XGYRO:      Serial.println("PLL with X axis gyroscope reference"); break;
    case MPU6050_CLOCK_INTERNAL_8MHZ:  Serial.println("Internal 8MHz oscillator"); break;
  }
  
  Serial.print(" * Accelerometer:             ");
  switch(mpu.getRange())
  {
    case MPU6050_RANGE_16G:            Serial.println("+/- 16 g"); break;
    case MPU6050_RANGE_8G:             Serial.println("+/- 8 g"); break;
    case MPU6050_RANGE_4G:             Serial.println("+/- 4 g"); break;
    case MPU6050_RANGE_2G:             Serial.println("+/- 2 g"); break;
  }  

  Serial.print(" * Accelerometer offsets:     ");
  Serial.print(mpu.getAccelOffsetX());
  Serial.print(" / ");
  Serial.print(mpu.getAccelOffsetY());
  Serial.print(" / ");
  Serial.println(mpu.getAccelOffsetZ());

  Serial.print(" * Accelerometer power delay: ");
  switch(mpu.getAccelPowerOnDelay())
  {
    case MPU6050_DELAY_3MS:            Serial.println("3ms"); break;
    case MPU6050_DELAY_2MS:            Serial.println("2ms"); break;
    case MPU6050_DELAY_1MS:            Serial.println("1ms"); break;
    case MPU6050_NO_DELAY:             Serial.println("0ms"); break;
  }  
  
  Serial.println();
}

void MotionSensorRead() {  // Motion sensor read(Bike Alarm)
  Vector rawAccel = mpu.readRawAccel();
  Activites act = mpu.readActivites();
  if (act.isActivity)
  {
    Blynk.virtualWrite(V14, "Yes");
  } else
  {
    Blynk.virtualWrite(V14, "No");
  }

  if (act.isInactivity)
  {
    Blynk.virtualWrite(V15, "Yes");
  } else
  {
    Blynk.virtualWrite(V15, "No");
  }
}

  Blynk.syncVirtual(V13); { // Checks current status of Alarm ON/OFF button and updates sketches awareness of it
{      
  BLYNK_WRITE(V13) { // Alarm ON/OFF Button set to SWITCH mode
  MotionOnFlag = param.asInt();
}

void LimitationFlagReset() {
  LimitationFlag = 0;  // Reset limitation flag
  if (MotionOnFlag == 1 && LimitationFlag == 0) {  // Check if both ON and that limit flag is inactive
    LimitationFlag = 1; // Set time limit flag for notifications
    timer.setTimeout(16000L, LimitationFlagReset);  // Start 16 second timer for limiting flag reset
    Vector rawAccel = mpu.readRawAccel();
    Vector normGyro = mpu.readNormalizeGyro();
    if (normGyro.XAxis > maxval || normGyro.XAxis < minval && normGyro.YAxis > maxval || normGyro.YAxis  < minval && normGyro.ZAxis > maxval || normGyro.ZAxis  < minval) {
      Blynk.virtualWrite(V10, "Movement Detected");
      Blynk.notify("BIKE BEING STOLEN!");
    }  else {
      Blynk.virtualWrite(V10, "Bike Secure");
    }
  }
}

}  
void PitchRollSensorRead() {  // Pitch & Roll sensor read(Bike Telemetry)
  Vector normAccel = mpu.readNormalizeAccel();
  Vector normGyro = mpu.readNormalizeGyro();

  // add/remove /* and */ to enable-disable serial prints
  Serial.print(" Accel Xnorm = ");
  Serial.println(normAccel.XAxis);
  Serial.print(" Accel Ynorm = ");
  Serial.println(normAccel.YAxis);
  Serial.print(" Accel Znorm = ");
  Serial.println(normAccel.ZAxis);
  Serial.print(" Gyro Xnorm = ");
  Serial.println(normGyro.XAxis);
  Serial.print(" Gyro Ynorm = ");
  Serial.println(normGyro.YAxis);
  Serial.print(" Gyro Znorm = ");
  Serial.println(normGyro.ZAxis);

  Blynk.virtualWrite(V20, normAccel.XAxis);
  Blynk.virtualWrite(V21, normAccel.YAxis);
  Blynk.virtualWrite(V22, normAccel.ZAxis);
  Blynk.virtualWrite(V23, normGyro.XAxis);
  Blynk.virtualWrite(V24, normGyro.YAxis);
  Blynk.virtualWrite(V25, normGyro.ZAxis);  

}

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

I think that what @Lichtsignaal was meaning is that you should move those two entire functions up towards the top of your code, so that the functions have been declared before you try to reference them via your timer definitions.
However, this isn’t the solution to your problem, as declaring a function before its referenced stopped being a requirement of the Arduino IDE long time ago.

You had a few issues…

Your

Blynk.syncVirtual(V13);

statement was hanging there on its own, so the IDE was trying to treat it as a function. I’ve moved it up one line so that its now part of the

void PitchRollSensorRead()

function - I assume that this is correct?

You also had a extra curly bracket hanging around. I’ve restructured the brackets a bit to get to the bottom of that one.

Lastly, you’d mis-spelled your MotionOnFlag variable as “MotionnOFlag” in one place.

This code now compiles. Whether it does what you want it to is another matter :grinning:

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>`
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include <MPU6050.h>
#define minval -1
#define maxval 1

char auth[] = "060348058fd549f083b9b649e6784852";
char ssid[] = "BTHub6-P38S";
char pass[] = "wAwhd7rKg3cT";

int MotionOnFlag;
int LimitationFlag = 0;

BlynkTimer timer;

MPU6050 mpu;


void setup() 
{
  Serial.begin(115200);

  Blynk.begin(auth, ssid, pass);

  Serial.println("Initialize MPU6050");

  while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_16G))
  {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }
  
  mpu.setAccelPowerOnDelay(MPU6050_DELAY_3MS);

  mpu.setIntFreeFallEnabled(false);  
  mpu.setIntZeroMotionEnabled(false);
  mpu.setIntMotionEnabled(false);
  
  mpu.setDHPFMode(MPU6050_DHPF_5HZ);

  mpu.setMotionDetectionThreshold(2);
  mpu.setMotionDetectionDuration(5);

  mpu.setZeroMotionDetectionThreshold(8);
  mpu.setZeroMotionDetectionDuration(2);
  
  checkSettings();
  timer.setInterval(100L, MotionSensorRead); // run the scan for motion function loop 10x/second
  timer.setInterval(100L, PitchRollSensorRead); // run the scan for Pitch & Roll function loop 10x/second
 
}

void checkSettings()
{
  Serial.println();
  
  Serial.print(" * Sleep Mode:                ");
  Serial.println(mpu.getSleepEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Motion Interrupt:          ");
  Serial.println(mpu.getIntMotionEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Zero Motion Interrupt:     ");
  Serial.println(mpu.getIntZeroMotionEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Free Fall Interrupt:       ");
  Serial.println(mpu.getIntFreeFallEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Motion Threshold:          ");
  Serial.println(mpu.getMotionDetectionThreshold());
  Serial.print(" * Motion Duration:           ");
  Serial.println(mpu.getMotionDetectionDuration());
  Serial.print(" * Zero Motion Threshold:     ");
  Serial.println(mpu.getZeroMotionDetectionThreshold());
  Serial.print(" * Zero Motion Duration:      ");
  Serial.println(mpu.getZeroMotionDetectionDuration());
  
  Serial.print(" * Clock Source:              ");
  switch(mpu.getClockSource())
  {
    case MPU6050_CLOCK_KEEP_RESET:     Serial.println("Stops the clock and keeps the timing generator in reset"); break;
    case MPU6050_CLOCK_EXTERNAL_19MHZ: Serial.println("PLL with external 19.2MHz reference"); break;
    case MPU6050_CLOCK_EXTERNAL_32KHZ: Serial.println("PLL with external 32.768kHz reference"); break;
    case MPU6050_CLOCK_PLL_ZGYRO:      Serial.println("PLL with Z axis gyroscope reference"); break;
    case MPU6050_CLOCK_PLL_YGYRO:      Serial.println("PLL with Y axis gyroscope reference"); break;
    case MPU6050_CLOCK_PLL_XGYRO:      Serial.println("PLL with X axis gyroscope reference"); break;
    case MPU6050_CLOCK_INTERNAL_8MHZ:  Serial.println("Internal 8MHz oscillator"); break;
  }
  
  Serial.print(" * Accelerometer:             ");
  switch(mpu.getRange())
  {
    case MPU6050_RANGE_16G:            Serial.println("+/- 16 g"); break;
    case MPU6050_RANGE_8G:             Serial.println("+/- 8 g"); break;
    case MPU6050_RANGE_4G:             Serial.println("+/- 4 g"); break;
    case MPU6050_RANGE_2G:             Serial.println("+/- 2 g"); break;
  }  

  Serial.print(" * Accelerometer offsets:     ");
  Serial.print(mpu.getAccelOffsetX());
  Serial.print(" / ");
  Serial.print(mpu.getAccelOffsetY());
  Serial.print(" / ");
  Serial.println(mpu.getAccelOffsetZ());

  Serial.print(" * Accelerometer power delay: ");
  switch(mpu.getAccelPowerOnDelay())
  {
    case MPU6050_DELAY_3MS:            Serial.println("3ms"); break;
    case MPU6050_DELAY_2MS:            Serial.println("2ms"); break;
    case MPU6050_DELAY_1MS:            Serial.println("1ms"); break;
    case MPU6050_NO_DELAY:             Serial.println("0ms"); break;
  }  
  
  Serial.println();
}

void MotionSensorRead() // Motion sensor read(Bike Alarm)
{
  Vector rawAccel = mpu.readRawAccel();
  Activites act = mpu.readActivites();
  if (act.isActivity)
  {
    Blynk.virtualWrite(V14, "Yes");
  } 
  else
  {
    Blynk.virtualWrite(V14, "No");
  }

  if (act.isInactivity)
  {
    Blynk.virtualWrite(V15, "Yes");
  }
  else
  {
    Blynk.virtualWrite(V15, "No");
  }
  Blynk.syncVirtual(V13); // Checks current status of Alarm ON/OFF button and updates sketches awareness of it
}

     
BLYNK_WRITE(V13) // Alarm ON/OFF Button set to SWITCH mode
{
  MotionOnFlag = param.asInt();
}


void LimitationFlagReset()
{
  LimitationFlag = 0;  // Reset limitation flag
  if (MotionOnFlag == 1 && LimitationFlag == 0)  // Check if both ON and that limit flag is inactive
  {  
    LimitationFlag = 1; // Set time limit flag for notifications
    timer.setTimeout(16000L, LimitationFlagReset);  // Start 16 second timer for limiting flag reset
    Vector rawAccel = mpu.readRawAccel();
    Vector normGyro = mpu.readNormalizeGyro();
    if (normGyro.XAxis > maxval || normGyro.XAxis < minval && normGyro.YAxis > maxval || normGyro.YAxis  < minval && normGyro.ZAxis > maxval || normGyro.ZAxis  < minval)
    {
      Blynk.virtualWrite(V10, "Movement Detected");
      Blynk.notify("BIKE BEING STOLEN!");
    } 
    else
    {
      Blynk.virtualWrite(V10, "Bike Secure");
    }
  }
}

  
void PitchRollSensorRead() // Pitch & Roll sensor read(Bike Telemetry)
{  
  Vector normAccel = mpu.readNormalizeAccel();
  Vector normGyro = mpu.readNormalizeGyro();

  // add/remove /* and */ to enable-disable serial prints
  Serial.print(" Accel Xnorm = ");
  Serial.println(normAccel.XAxis);
  Serial.print(" Accel Ynorm = ");
  Serial.println(normAccel.YAxis);
  Serial.print(" Accel Znorm = ");
  Serial.println(normAccel.ZAxis);
  Serial.print(" Gyro Xnorm = ");
  Serial.println(normGyro.XAxis);
  Serial.print(" Gyro Ynorm = ");
  Serial.println(normGyro.YAxis);
  Serial.print(" Gyro Znorm = ");
  Serial.println(normGyro.ZAxis);

  Blynk.virtualWrite(V20, normAccel.XAxis);
  Blynk.virtualWrite(V21, normAccel.YAxis);
  Blynk.virtualWrite(V22, normAccel.ZAxis);
  Blynk.virtualWrite(V23, normGyro.XAxis);
  Blynk.virtualWrite(V24, normGyro.YAxis);
  Blynk.virtualWrite(V25, normGyro.ZAxis);  
}


void loop()
{
  Blynk.run();
  timer.run();
}
1 Like

@PeteKnight Thank you for taking the time to look at it. As the code grows in size I’m struggle with what goes where and why. It compiled and uploaded fine but no joy with the button, it doesn’t work. I was hoping it would turn the alarm function on and off like it did in the previous Earth Quake sketch of @Lichtsignaal.

Blynk.syncVirtual(V13);

Is supposed to check the status of the button(On or Off) and update the sketch. Not sure if its in the right place or not.

Those braces give me nightmares, I can never get them right. :confused:

That’s me being tired, its 3am here and I’m still trying to fix this damn button.

No work for me now, bad weather has brought the site to its knee’s. I’ve left a skeleton crew there, the rest of us are back Monday(weather permitting).
I’ll take another look at the code later this morning if my head doesn’t explode in the next 15 minutes while I drink my coffee and stare at this sketch. :joy:

On the plus side I’ve squished the sensor, the Wemos D1 and a small breadboard onto the back of 2 x 3.7v LiPo batteries. Nice and compact and ready for me to do a bit of testing on the bike(if I get this button working).

I will try to summarize the process…

In the App a Button Widget has two default states, ON and OFF. Each time you press a button it sets the associated vPin to 1 (ON) when you press and 0 (OFF) when you release. Switch mode just make this a more manually controlled process requiring separate presses to achieve state changes.

These vPin state changes are sent to the Server and then to the Sketch… when the Sketch receives the announcement, it triggers what is called a Blynk Function that is associated with the same vPin… or in this case

BLYNK_WRITE(vPin) {
// do stuff here every state change
}

So normally this simple function would be called twice for each full Button action (e.g press/1 and release/0), but that is not any good for a normal action for ON and another for OFF…

Thus we can add in a parameter check to see the actual contents of the vPin (in this case 0 or 1) and have separate action depending on the state of the vPin

BLYNK_WRITE(vPin) {
  if (param.asInt() == 1) {  // looks at the vPin parameter as an integer and if it is 1...
    // do stuff here if state is 1
  } else {  // but if the parameter is 0 then ...
    // do stuff here if state is 0
  }
}

And the braces are used to contain each separate step

Orange for the entire function
Green for action if state is 1/ON
Blue for action if state is 0/OFF

image


This whole “Power” or “MotionOnFlag” setting process would normally end up looking like this for you…

BLYNK_WRITE(V13) { // Alarm ON/OFF Button set to SWITCH mode
  if (param.asInt() == 1) {  // looks at the vPin parameter as an integer and if it is 1...
    MotionOnFlag = 1
  } else {  // but if the parameter is 0 then ...
    MotionOnFlag = 0
  }
}

But for code writing simplicity’s sake, I had originally written this command in “shorthand”.

It functionally works the same way, but visually interpreting it can be tricky without understanding the longer process.

BLYNK_WRITE(V13) // Alarm ON/OFF Button set to SWITCH mode
{
  MotionOnFlag = param.asInt(); // this setts the variable to the vPin state
}
1 Like

One final tidbit before I crash for my next sleep period :sleeping:

All that last above BLYNK_WRITE() function does is set a flag (MotionOnFlag) to 1/ON or 0/OFF… a later timed loop uses that flag to determine if it is supposed to actually read the sensor and react to it or not (like a virtual power button).

However, if after pressing the button ON in your App… your device (NodeMCU or Wemos) gets rebooted, it will not actually know what the state of that flag is… and will default to 0/OFF… EVEN if the Button is still 1/ON in your App.

This is where that Blynk.syncVirtual(V13); command comes into play.

If it is placed in your void setup() loop, then it will get processed once every bootup… and what it does is ask the server what the last known state of V13 was… that way if the App button was still 1/ON, then this sync command would tell the above BLYNK_WRITE() function to “run” with the state of 1/ON and restore the sketches “awareness” of the App’s Button setting.

1 Like

@Gunner I know your a busy guy so giving me such a detailed reply is very much appreciated, huge thank you. :+1::+1:

So the 2 modes of the Button in the app are exactly the same as a real button would have.
Momentary = Push
Maintained = Switch
Well that’s easy to remember.

Now I know why it was so difficult to work out how and what it did. To give me more incentive to learn, I’ve been comparing other peoples code. Trying to figure out how and what it does, then piecing it all together to make something useful, not just a blinking LED. Your short hand through me, couldn’t find anything to compare it too. :face_with_monocle:
Hopefully now with your simplified explanation above i can figure it out for myself. :crossed_fingers:

I’m lucky if I sleep more than 5 hours, think I have insomnia.

Obviously important, because if I think the bike alarm is on, and its not. Mr LightFingers might have himself a fun time with my pride and joy and I wouldn’t know.

:motorcycle:

Well I’m getting closer to having a motorcycle alarm with basic telemetry. But the Blynk Button has me beat for now.