[Solved] Blynk interfering with reading pin on Particle Photon

So,
I have a program that controls my clothes dryer on my Photon, it uses an lcd shield and Blynk for control.
Here’s the problem, if I use Blynk it will stop the photon from reading the on/off button. Any idea what could be happnening? I’ve set up a simple demo app that elicits the same behavior.

// This #include statement was automatically added by the Particle IDE.
#include "blynk/blynk.h"

// This #include statement was automatically added by the Particle IDE.
#include "LiquidCrystal/LiquidCrystal.h"

#define BLYNK_PRINT Serial
char auth[] = "authgoeshere";

int start_stop_button = A5;
LiquidCrystal lcd(2, 1, 6, 5, 4, 3);


void setup() 
{
   // Blynk.begin(auth);
pinMode(start_stop_button, INPUT);
lcd.begin(16, 2);
lcd.clear();
}
void loop() 
{
   // Blynk.run();
    lcd.setCursor(0,0);
    lcd.print("Button");
int reading = digitalRead(start_stop_button);
if (reading == HIGH){
    lcd.setCursor(0,1);
    lcd.print("    pressed");
}

if (reading == LOW){
    lcd.setCursor(0,1);
    lcd.print("not pressed");
}
}

Basically, if Blynk runs, the Photon doesn’t read A5.
Thanks in advance,
JR

A few tips that don’t immediately address your problem but maybe contribute
Try to use INPUT_PULLDOWN (providing you got your button hooked to 3v3 and not Vin/5V).
Use a variable that holds your last button state and only perform the LCD action (including the common two lines) on change (aka when last state != current state).
Next check the update interval for your pin in the Blynk app and maybe slow that down.

Thanks Scruff, but those don’t address this particular issue. The pin has a hardware pulldown resistor. The state changes and prints fine without Blynk loading, so the sate change isn’t the problem.

I’ve asked about this on the blynk forum as well, and I’m getting advice to try button interrupt, so maybe that’s the ticket

Hence the introductory statement

And without knowing the LiquidCrystal library by heart, moving those calls into an ISR might not work, but you could use a flag and keep the actual work in loop().

BTW, IMHO even if hammering the display every few microseconds works, it’s still poor practice.

This is just a test program :slight_smile:
The actual code is much longer and uglier, and it addresses the state and interval, which is why I know those are not the problem.

I guess it must have something to do with your code or setup, since this code works just fine for me

#include "blynk/blynk.h"

// Blynk App setup
// add a Value Widget for D0
// add a LED   Widget for V0

const char auth[] = "<-- blynk token -->";
const int pinButton   = A5;    
const int pinLED      = D7;           // jumper wire to D0
const int pinReadLED  = D0;           // jumper wire to D7
const int vpinState   = V0;


void setup() {
  pinMode(pinButton, INPUT_PULLUP);  // or PULLDOWN (requires inverting logic bellow)
  pinMode(pinLED, OUTPUT);           // for feedback of button state
  //pinMode(pinreadLED, INPUT);      // Blynk will read this as state of LED

  Blynk.begin(auth);
}

void loop() {
    static int lastState;
    int currentState = !digitalRead(pinButton); 
    
    if (currentState != lastState)
    {
        digitalWrite(pinLED, currentState);
        Blynk.virtualWrite(vpinState, currentState ? -1 : 0);  // required for glitch in Blynk LED Widged
        lastState = currentState;
    }

    Blynk.run();
}

So it’s not really Blynk.run() impacting digitalRead(A5) or vice versa.
But as it could be your Blynk app that causes the problem.
If I use A5 or D7 in my app the correct behaviour of my Photon is impaired, since there are conflicting assignments (my code vs. Blynk app) for one pin (even if both would use the pin as INPUT) - just as you can’t use one pin twice in any Blynk app.

And be careful with your button or pull-resistor if you are using an A pin as input in Blynk app, since Blynk will set that pin for analogRead() which makes them not 5V tolerant, so you can only apply 3.3V max!

And be careful with your button or pull-resistor if you are using an A pin as input in Blynk app, since Blynk will set that pin for analogRead() which makes them not 5V tolerant, so you can only apply 3.3V max!

this may well be the problem. The button is getting 5v. There is a physical pulldown resistor on it, but if Blynk can only handle 3v3, then that’s very likely the issue. I’ll try wiring the button to 3v3 instead of 5v. If I write HIGHT out to a digital pin, does it write 3 or 5 volts?

It’s not that Blynk only can handle 3.3V but the pins can physically only handle 3.3V in analog read mode. Once you applied more than that to the ADC chances are high that you’ve fried your ADC.
Hence I prefer using internal pull-resistors or external only pulling to the native levels to avoid such accidents.

The docs clearly state that this is a 3.3V µC so you’ll only get 3.3V off any GPIO. But in digital input mode or digital pull mode (OUTPUT LOW) they are 5V tolerant.

Interesting. It hasn’t fried the ADC (thank goodness), since if I turn Blynk off, it still reads the buttons. I’m trying your code now, I’ll let you know how it goes :slight_smile:
Thanks!

Being able to still digitalRead() a pin is no proof that the ADC is not fried.
To really know, you’d need to analogRead() a signal somwhere between 0 & 3.3V.

Oh?
Well it only needs to digital read in my case, so hopefully it’s not broken, but as long as it can still read high/low, my app will work.

I got your test app to work, though I noticed you are doing something weird with the LED within the app. I changed it so it works. Apparently more recent versions of the Blynk library don’t want to write high/low to the led widget, the led widget wants 0-255, and high==1. So, if you multiply high by 255, that might work. I just use the LED widgets as below.

Thanks for your help, I’m still not sure why my dryer code and test code don’t work though. More digging required!

const char auth[] = "authgoeshere";
const int pinButton   = A5;    
const int pinLED      = D7;           // jumper wire to D0
//const int pinReadLED  = D0;           // jumper wire to D7
const int vpinState   = V0;


void setup() {
  pinMode(pinButton, INPUT_PULLDOWN);  // or PULLDOWN (requires inverting logic bellow)
  pinMode(pinLED, OUTPUT);           // for feedback of button state
  //pinMode(pinreadLED, INPUT);      // Blynk will read this as state of LED

  Blynk.begin(auth);
}

void loop() {
    static int lastState;
    int currentState = !digitalRead(pinButton); 
    
    if (currentState != lastState)
    {
        digitalWrite(pinLED, currentState);
          WidgetLED appLED(V1); //register to virtual pin 1
            if (currentState == LOW){
                appLED.off();
                 }
            if(currentState == HIGH){
                appLED.on();
            }
        //Blynk.virtualWrite(vpinState, currentState*255);  // required for glitch in Blynk LED Widged
        lastState = currentState;
    }

    Blynk.run();
}

That’s nothing odd and works just as is.

The “secret” of using -1 here makes use of the fact that -1 (= 0xFFFFFFFF) uses all bits high, no matter how long the used data type and I don’t need to know if it’s a one, two or four byte value that’s expected :wink:
And the use of condition ? true-value : false-value is called “ternary operator” which compresses your six lines of code with two extra function calls into one line.

Well, if it’s simplicity you’re after

 Blynk.virtualWrite(vpinState, currentState*255);

Works.
I actually can’t get

Blynk.virtualWrite(vpinState, currentState ? -1 : 0);

To work more than once in a row (It seems like it works for one state change, but that’s all)

That’s odd, it works on mine continually :confused: (have to check what version Blynk lib I used)
However, you found a solution that works for you, that’s most important.

1 Like