Using Segmented Switch and reading 3 Analog pins

Hello,
I found Blynk recently to help build a project and found some issues. I’m using Blynk onr a Particle Photon running 1.4.4 firmware and communicating wifi, and using iOS on the Blynk Server.

I’m reading analog data from 3 weight sensors A0-A3, then having those values, for the moment, being read directly by Blynk. No issue there.
From there, those values are added together to give a Total Weight, which works well.

Using 3 virtual pins, V0,V1, V2, I’m allowing user entry of pounds, displaying Total Weight, and displaying an alert LED, respectively.

The Virtual Alert LED should only go off when the selected setting on the segmented switch is used in conjunction with the Total weight, so if totAna >0, 5, 10, or 25% of the entered weight from V0,

Physically, I have a single LED (light1) wired to D0 to go off at the same time as led1.

I’m not sure if my segment is running correctly, and both LEDs stay on, despite the criteria not being met.
Any help would be appreciated to get this working.




/*************************************************************
  Blynk is a platform with iOS and Android apps to control
  Arduino, Raspberry Pi and the likes over the Internet.
  You can easily build graphic interfaces for all your
  projects by simply dragging and dropping widgets.

    Downloads, docs, tutorials: http://www.blynk.cc
    Sketch generator:           http://examples.blynk.cc
    Blynk community:            http://community.blynk.cc
    Follow us:                  http://www.fb.com/blynkapp
                                http://twitter.com/blynk_app

  Blynk library is licensed under MIT license
  This example code is in public domain.

 *************************************************************

  No coding required for direct digital/analog pin operations!

 *************************************************************/

#define BLYNK_PRINT Serial  // Set serial output for debug prints
//#define BLYNK_DEBUG       // Uncomment this to see detailed prints

#include <blynk.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "xxxxxxxx";
//char auth[] = "xxxxxxxxx";
int light1 = D0;// This is where your LED is plugged in. The other side goes to a resistor connected to GND.
//int light2 = D1;
//int light3 = D2;
WidgetLED led1(V3);

int pressure1 = A0; // This is where your photoresistor or phototransistor is plugged in. The other side goes to the "power" pin (below).
int pressure2 = A1;
int pressure3 = A3;
int analog1; // Here we are declaring the integer variable analogvalue, which we will use later to store the value of the pressure sensor.
int analog2;
int analog3;
int ledToggle(String command); // Forward declaration
int poundValue;
int poundPercent;
int TTWB;
int totAna;


BLYNK_WRITE(V0)
{
    int poundValue;
    poundValue = param.asInt(); // assigning incoming value from pin V1 to a variable
    //poundPercent =poundValue * .25;
  // process received value
   // Serial.printlnf("V0 Numeric Input is: ", &poundPercent, INT);
    }

BLYNK_WRITE(V1) {
  switch (param.asInt())
  {
    case 1: { TTWB = 0;
        break;
      }
    case 2: { TTWB = 5;
        break;
      }
    case 3: { TTWB = 10;
        break;
      }
    case 4: { TTWB = poundValue * .25;
        break;
      }
        }
}

void readSensors()
{
    Blynk.syncVirtual(V1);
    analog1 = analogRead(pressure1);// 
    analog2 = analogRead(pressure2);
    analog3 = analogRead(pressure3);
    totAna = analog1 + analog2 + analog3;
    Blynk.virtualWrite(V2, totAna);


if (totAna > TTWB){
    led1.on();
    digitalWrite(light1, HIGH);
	Serial.printlnf("%d",totAna);
	Particle.publish("Total Weight", String(totAna), PRIVATE);
}
else if (totAna < TTWB) {
        led1.off();
		digitalWrite(light1,LOW);
		}
}

void setup()
{
    Serial.begin(9600);
    delay(5000); // Allow board to settle
    	pinMode(light1, OUTPUT);
   
    Blynk.begin(auth);
}

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


First of all, you cant get away with doing this in Blynk. Your readSensors function contains a Blynk.syncVirtual and a Blynk.virtualWrite that are called every time the void loop executes, and an an led1 on/off (which is in effect a Blynk.virtualWrite) which is called unless totAna == TTWB. (I’m guessing that this last bit is a flaw in your logic?).
Take a read of this:
http://help.blynk.cc/getting-started-library-auth-token-code-examples/blynk-basics/keep-your-void-loop-clean

Pete.

As @PeteKnight said, your loop() has problem as described.
Besides, you have one more problem at BLYNK_WRITE(V0) where local var poundValue will mask and destroy global var poundValue, creating the real culprit ans error you mentioned.

both LEDs stay on, despite the criteria not being met.
as TTWB is always 0 (TTWB = poundValue * .25; as global poundValue = 0)

You also have to use BlynkTimer to call readSensors() to clean up the loop()

Try the following code (and note the mods and comments)

#define BLYNK_PRINT Serial  // Set serial output for debug prints
//#define BLYNK_DEBUG       // Uncomment this to see detailed prints

#include <blynk.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "*************";
//char auth[] = "***********";
int light1 = D0;// This is where your LED is plugged in. The other side goes to a resistor connected to GND.
//int light2 = D1;
//int light3 = D2;
WidgetLED led1(V3);

int pressure1 = A0; // This is where your photoresistor or phototransistor is plugged in. The other side goes to the "power" pin (below).
int pressure2 = A1;
int pressure3 = A3;
int analog1; // Here we are declaring the integer variable analogvalue, which we will use later to store the value of the pressure sensor.
int analog2;
int analog3;
int ledToggle(String command); // Forward declaration
int poundValue;
int poundPercent;
int TTWB;
int totAna;

// Add this
BlynkTimer timer;

BLYNK_WRITE(V0)
{
    // Can't use this here. If do this, global poundValue won't be updated and is possibly always 0
    //int poundValue;
    poundValue = param.asInt(); // assigning incoming value from pin V1 to a variable
    //poundPercent =poundValue * .25;
   // process received value
   // Serial.printlnf("V0 Numeric Input is: ", &poundPercent, INT);
    }

BLYNK_WRITE(V1) {
  switch (param.asInt())
  {
    case 1: { TTWB = 0;
        break;
      }
    case 2: { TTWB = 5;
        break;
      }
    case 3: { TTWB = 10;
        break;
      }
    case 4: { TTWB = poundValue * .25;
        break;
      }
        }
}

void readSensors()
{
    // Check to see if this is necessary
    Blynk.syncVirtual(V1);
    analog1 = analogRead(pressure1);// 
    analog2 = analogRead(pressure2);
    analog3 = analogRead(pressure3);
    totAna = analog1 + analog2 + analog3;

    // What is this V2, 
    // Not as described 
    // Using 3 virtual pins, V0,V1, V2, I’m allowing user entry of pounds, displaying Total Weight, and 
    // (V2???) displaying an alert LED, respectively.
    Blynk.virtualWrite(V2, totAna);


    if (totAna > TTWB){
      led1.on();
      digitalWrite(light1, HIGH);
      Serial.printlnf("%d",totAna);
      Particle.publish("Total Weight", String(totAna), PRIVATE);
    }
    // Add <= for perfection
    else if (totAna <= TTWB) {
      led1.off();
      digitalWrite(light1,LOW);
    }
}

void setup()
{
    // Change to 115.2K baud in terminal
    Serial.begin(115200);
    delay(5000); // Allow board to settle
    pinMode(light1, OUTPUT);
   
    Blynk.begin(auth);

    // Call every 1s, try to use longer time if possible
    timer.setInterval(1000L, readSensors);
}

void loop()
{
    Blynk.run();

    // Add this
    timer.run();
    // Add remove this
    //readSensors();
}

1 Like

@khoih, I went through it as @PeteKnight and cleaned it up, and yes, I found my local variables were wiping out globals, so I got rid of the locals. You beat me posting my fixes before I could. Thank you both.

I got rid of this

// Check to see if this is necessary
   Blynk.syncVirtual(V1);

Later, I got rid of this

Blynk.virtualWrite(V2, totAna);

Do I just put the following instead as it own function outside readsensors as shown below?

BLYNK_WRITE(V2)
{
    totAna= param.asInt();
}

When the segmented switch is set to 0 (NWB), any sum of the 3 sensors(as shown in Applied Total Weight) going over 0 should make the led1 and light1 light, then clear when value is zero. I say zero, the sensor will have some bouncing around, but that i’m not too worried about.

When the segmented switch is set to 5 (TTWB 5LBS), any sum of the 3 sensors is greater than 5, led1 and light1 light, and then clear when below 5.

Same for when set to 10 (TTWB 10 LBS).

When set to setting 4 (PWB 50%), which should look at V0 (Patient Weight) data entered, then calculate 25% of that, then when the sum of the 3 sensors is greater than calculated value, it should light up everything, then clear when the condition is not met.

V3 is an alert LED, ABOVE LIMIT, that triggers based on what criteria is set on segmented switch.

I’ve gone through and edited it with both your recommendations, I’m just not sure that the V0 is being processed correctly, and the led1/light1 stay lit, and APPLIED TOTAL WEIGHT (V2) stopped updating. Any insight to that?

I think you should post your latest code, and a CLEAR description of exactly what is and isn’t working.

Pete.

It’s really time consuming to understand your logic and application. Anyway, to know what’s wrong, you normally have to place a lot of debugging code lines at strategic places to understand what’s going on.
Sometimes, it’s not because of your error but libraries’ bugs, configurations, etc… that we have no control or knowledge yet.

So the following code will possibly help you to understand more what’s happening:

#define BLYNK_PRINT Serial  // Set serial output for debug prints
//#define BLYNK_DEBUG       // Uncomment this to see detailed prints

#define USE_PARTICLE_PHOTON     true

#if USE_PARTICLE_PHOTON
  #include <blynk.h>      // For Particle Photon
#else
  // Just to test compiling for other platform
  #include <ESP8266WiFi.h>
  #include <BlynkSimpleEsp8266.h>

  // Your WiFi credentials.
  // Set password to "" for open networks.
  char ssid[] = "****";
  char pass[] = "****";  
#endif

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "*************";

int light1 = D0;// This is where your LED is plugged in. The other side goes to a resistor connected to GND.
//int light2 = D1;
//int light3 = D2;

#define BLYNK_PIN_PATIENT_WEIGHT            V0
#define BLYNK_PIN_TTWB                      V1
#define BLYNK_PIN_APPLIED_TOTAL_WEIGHT      V2
#define BLYNK_PIN_OVER_LIMIT_ALERT          V3

WidgetLED led1(BLYNK_PIN_OVER_LIMIT_ALERT);

int pressure1 = A0; // This is where your photoresistor or phototransistor is plugged in. The other side goes to the "power" pin (below).

#if USE_PARTICLE_PHOTON
  int pressure2 = A1;
  int pressure3 = A3;
#else
  int pressure2 = A0;     //A1;   // Just to test compiling
  int pressure3 = A0;     //A3;   // Just to test compiling
#endif

int poundValue;
int TTWB;
int totAna;

// Add this
BlynkTimer timer;

#define DEBUGGING     true

BLYNK_WRITE(BLYNK_PIN_PATIENT_WEIGHT)
{
  poundValue = param.asInt(); // assigning incoming value from pin V1 to a variable
  
  #if (DEBUGGING)
    Serial.println("poundValue = " + String(poundValue));
  #endif
}

BLYNK_WRITE(BLYNK_PIN_TTWB) 
{   
  #if (DEBUGGING)
    Serial.println("BLYNK_PIN_TTWB param = " + String(param.asInt()));
  #endif
  
  switch (param.asInt())
  {
    case 1: 
    { 
      TTWB = 0;
      break;
    }
    case 2: 
    { 
      TTWB = 5;
      break;
    }
    case 3: 
    { 
      TTWB = 10;
      break;
    }
    case 4: 
    { 
      // To be sure not some math library error
      //TTWB = poundValue * .25;
      TTWB = (poundValue / 4);
      break;
    }
  }

  #if (DEBUGGING)
    Serial.println("TTWB  = " + String(TTWB));
  #endif
  
}

void readSensors()
{
  totAna = analogRead(pressure1) + analogRead(pressure2) + analogRead(pressure3);

  #if (DEBUGGING)
    Serial.println("Total ANA = " + String(totAna));
    Serial.println("TTWB = " + String(TTWB));  
  #endif
  
  if (totAna > TTWB)
  {
    led1.on();
    digitalWrite(light1, HIGH);
    #if USE_PARTICLE_PHOTON
      Particle.publish("Total Weight", String(totAna), PRIVATE);
    #endif
  }
  else if (totAna <= TTWB) 
  {
    led1.off();
    digitalWrite(light1,LOW);
  }
}

void setup()
{
  // Change to 115.2K baud in terminal
  Serial.begin(115200);
  delay(5000); // Allow board to settle
  pinMode(light1, OUTPUT);
  
  //Blynk.begin(auth);
  // Just for compiling for other platform
  Blynk.begin(auth, ssid, pass);
  
  // Call every 1s, try to use longer time if possible
  timer.setInterval(1000L, readSensors);
}

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

Hope that you’ve solved your problems in next post or you have to show us all the debugging messages.

Good luck and hope we, at sometime in the future, won’t be the patient using it :smile: .

1 Like

Using the code you posted @khoih, it works well. Thank you.

I found the following issues:

poundValue = 300 **<--I changed the poundValue on the app**
TTWB  = 75     **<--It does the math correctly**
Total ANA = 298
TTWB = 75
Total ANA = 297
TTWB = 75
Total ANA = 301
TTWB = 75
Total ANA = 299
TTWB = 75
Total ANA = 295
TTWB = 75
Total ANA = 297
TTWB = 75
poundValue = 250 **<--value is changed, but TTWB continues to be calculated off the original 300**
Total ANA = 298
TTWB = 75
Total ANA = 288
TTWB = 75
Total ANA = 298
TTWB = 75
Total ANA = 302
TTWB = 75
BLYNK_PIN_TTWB param = 3   **<--Here, I select option 3 on segmented switch**
TTWB  = 10
BLYNK_PIN_TTWB param = 4   **<--then go back to option 4, where it updates TTWB based on the new Pound value**
TTWB  = 62
Total ANA = 297
TTWB = 62
Total ANA = 300
TTWB = 62
Total ANA = 298
TTWB = 62

You can manually enter a value, and it updates correctly, but why does TTWB only update after a momentary switch from option 4 to any other position, back to option 4?

Also, virtual pin V2, tied to a Labeled Value in the Blynk app, titled Applied Total Weight, should be receiving the value totAna, or the Total ANA being seen on serial. What would be the correct way to push this to the app?

I was thinking the following, but appreciate any corrections.

BLYNK_WRITE(BLYNK_PIN_APPLIED_TOTAL_WEIGHT)
{
   totAna = param.asInt();
}

Because that’s what the code tells it to do!
The bit that “does the math” is here…

And this only exists in case 4 of the segmented switch. If you want it to re-calculate TTWB when a new poundValue is inputted then you need to add this into the code in the BLYNK_WRITE(BLYNK_PIN_PATIENT_WEIGHT) callback function as well.

You need to add…

Blynk.virtualWrite(V2, totAna);

to the void readSensors() function.

Pete.

1 Like
  1. but why does TTWB only update after a momentary switch from option 4 to any other position, back to option 4?

I’m sorry for posting the code not yet being tested.
Please test the following one:

....
unsigned int selectedSegmentedSW = 1;

BLYNK_WRITE(BLYNK_PIN_PATIENT_WEIGHT)
{
  poundValue = param.asInt(); // assigning incoming value from pin V1 to a variable
   
  switch (selectedSegmentedSW)
  {
    case 1: 
    { 
      TTWB = 0;
      break;
    }
    case 2: 
    { 
      TTWB = 5;
      break;
    }
    case 3: 
    { 
      TTWB = 10;
      break;
    }
    case 4: 
    { 
      TTWB = (poundValue / 4);
      break;
    }
  }

  #if (DEBUGGING)
    Serial.println("poundValue = " + String(poundValue));
    Serial.println("TTWB  = " + String(TTWB));
  #endif  
  
}

BLYNK_WRITE(BLYNK_PIN_TTWB) 
{    
  selectedSegmentedSW = param.asInt();
  
  #if (DEBUGGING)
    Serial.println("BLYNK_PIN_TTWB selectedSegmentedSW = " + String(selectedSegmentedSW));
  #endif    
}
....

  1. As @PeteKnight pointed out, you need to add either

Blynk.virtualWrite(BLYNK_PIN_APPLIED_TOTAL_WEIGHT, totAna);
or
Blynk.virtualWrite(V2, totAna);

to the end of function readSensors()

2 Likes

Thank you again @PeteKnight and @khoih. It calculates the new TTWB after the value is incremented by the - or + or typed in with no issues.

What I’m running into now is this:

TTWB = 80
Total ANA = 1
TTWB = 80
BLYNK_PIN_TTWB selectedSegmentedSW = 2
Total ANA = 0
TTWB = 80
Total ANA = 0
TTWB = 80
poundValue = 319
TTWB  = 5
Total ANA = 0
TTWB = 5
Total ANA = 1
TTWB = 5

So the TTWB updates only after incrementing the poundValue up or down, doesn’t matter, then it works as it should? It seems I’m missing something to get it to refresh TTWB somewhere after.

I’d suggest that you re-read my last post.

Pete.