japaton
Posts: 11
Joined: Mon Jan 06, 2020 4:26 pm

RPi Zero digitalRead unreliable?

Mon Jan 06, 2020 5:03 pm

I have created a simple reminder for my aging Mother-In-Law as a first project. (She has to call the front desk of the retirement community every morning around 8:00 to tell them she's okay.) The program activates a relay to turn on a light reminding her to call, then turns it off when a momentary contact button is pressed or after 120 minutes has lapsed. The program is fired by a cron every morning at 8:00am. The whole thing runs headless in a box with the button on top. It usually works perfectly, but sometimes the relay switches off after 20 or 30 minutes without the button being pressed. I have attached a diagram of the circuit, and the code is below.

Can someone please help me discover why the digitalRead appears to test high sometimes without the button being pressed? Maybe some transient voltage appearing? Do I need to ground it somehow? Or do I need a more reliable way of testing the button?

Thanks.

Code: Select all

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define RelayPin 1   // raspberry pin 18
#define ButtonPin 0  // raspberry pin 17

int main(void)
{
    if(wiringPiSetup() == -1) return 1;	// exit immediately if setup fails

    int min = 120;			// number of minutes until time lapses
    time_t starting = time(NULL);	// time stamp (seconds) when program starts
    time_t ending = starting + min*60;	// time when program will end if button not pressed

    pinMode (ButtonPin, OUTPUT);   	// set button to output temporarily
    digitalWrite(ButtonPin, LOW);	// make sure button pin is low
    pinMode (ButtonPin, INPUT);   	// reset button to input

    pinMode (RelayPin, OUTPUT);   	// set relay pin to output
    digitalWrite (RelayPin, HIGH); 	// close relay (turn lights on) before loop

    while (digitalRead(ButtonPin) == LOW && time(NULL) < ending)
	{
	delay (1);    // loop on 1ms until button pressed (pin 17 goes high) or time lapses
	}	
	

    digitalWrite (RelayPin, LOW); 	// open the relay (turn lights off) before exit

    return 0;
}
Attachments
Screen Shot 2020-01-06 at 11.53.56 AM.png
Screen Shot 2020-01-06 at 11.53.56 AM.png (62.07 KiB) Viewed 248 times

User avatar
mahjongg
Forum Moderator
Forum Moderator
Posts: 13142
Joined: Sun Mar 11, 2012 12:19 am
Location: South Holland, The Netherlands

Re: RPi Zero digitalRead unreliable?

Mon Jan 06, 2020 5:09 pm

A Velleman VMA406 relay module is not compatible with the 3V3 output signals of a PI, its designed for an Arduino.

You need a transistor inverter to drive it.

+Vs = +5V, the transistor can be any NPN small signal transistor, such as a BC547, or a 2N2222

Image

trejan
Posts: 2237
Joined: Tue Jul 02, 2019 2:28 pm

Re: RPi Zero digitalRead unreliable?

Mon Jan 06, 2020 5:18 pm

japaton wrote:
Mon Jan 06, 2020 5:03 pm
pinMode (ButtonPin, OUTPUT); // set button to output temporarily
digitalWrite(ButtonPin, LOW); // make sure button pin is low
pinMode (ButtonPin, INPUT); // reset button to input
This isn't how you set a pulldown. Remove the output and digitalwrite calls. Set to input and use pullUpDnControl(ButtonPin, PUD_DOWN)

japaton
Posts: 11
Joined: Mon Jan 06, 2020 4:26 pm

Re: RPi Zero digitalRead unreliable?

Mon Jan 06, 2020 5:22 pm

Thanks for the answer. So, I guess that although the 3v3 always trips the relay, it doesn't hold reliably. I appreciate the help.

User avatar
PeterO
Posts: 5951
Joined: Sun Jul 22, 2012 4:14 pm

Re: RPi Zero digitalRead unreliable?

Mon Jan 06, 2020 6:21 pm

japaton wrote:
Mon Jan 06, 2020 5:22 pm
Thanks for the answer. So, I guess that although the 3v3 always trips the relay, it doesn't hold reliably. I appreciate the help.
No, it looks like the issue is with how you are reading the button, not how you are driving the relay.
With no pull down configured it's quite possible that the pin may pick up noise on the wire to the button that may make it read as a "1".
PeterO

Code: Select all

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define RelayPin 1   // raspberry pin 18
#define ButtonPin 0  // raspberry pin 17

int main(void)
{
    if(wiringPiSetup() == -1) return 1;	// exit immediately if setup fails

    int min = 120;			// number of minutes until time lapses
    time_t starting = time(NULL);	// time stamp (seconds) when program starts
    time_t ending = starting + min*60;	// time when program will end if button not pressed

  
    pinMode (ButtonPin, INPUT);   	// reset button to input
    pullUpDnControl(ButtonPin, PUD_DOWN);

    pinMode (RelayPin, OUTPUT);   	// set relay pin to output
    digitalWrite (RelayPin, HIGH); 	// close relay (turn lights on) before loop

    while (digitalRead(ButtonPin) == LOW && time(NULL) < ending)
	{
	delay (1);    // loop on 1ms until button pressed (pin 17 goes high) or time lapses
	}	
	

    digitalWrite (RelayPin, LOW); 	// open the relay (turn lights off) before exit

    return 0;
}
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

hippy
Posts: 7911
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: RPi Zero digitalRead unreliable?

Mon Jan 06, 2020 7:05 pm

Looking at the VMA405 board it seems to have the relay switching transiistor (Q1) and other components on-board, so seems almost certainly a missing internal pull-down issue.

japaton
Posts: 11
Joined: Mon Jan 06, 2020 4:26 pm

Re: RPi Zero digitalRead unreliable?

Mon Jan 06, 2020 7:12 pm

Thanks for the answers. I will remove the logic to set the pin output/low, and add the pull-down.

Return to “Beginners”