AnswerBun.com

Is this a Python quirk or an imperfection in the Raspberry Pi input?

Raspberry Pi Asked by cornerpocket on October 20, 2020

I am running out of ideas to get this Python code working the way I want it to. Please take a look at my code and help me figure out what’s wrong, or if it’s a hardware issue with the Pi causing my issue.

Goal:
Use a fingerprint reader to start my car. Car is controlled via RPi GPIO pins and relays.

The setup:
I’m using a fingerprint reader module and a modified version of the Adafruit fingerprint reader script. I have a button wired into my dash in the car that when turned on, will activate the Ignition and Accessory circuits (Windows, Radio, cigarette lighter, etc.), and then the fingerprint reader will activate until a registered finger is placed, or the button is switched off again. the button is wired between GPIO 5 and a ground pin on the Raspberry Pi, and pulls the pin “LOW” when active. GPIO 5 is initially pulled up.

The problem:
I seem to be having issues getting a “button_state” variable to read reliably here. The following code is almost function perfect, but every time I switch the button “OFF” after the car is started, a repeated command happens where it will print “Accessories Off”, as it should, but then it prints “Accessories On”, followed by “Accessories Off” again. I really can’t understand why this part of the code is creating this unwanted repetition here, especially because “Accessories On” should only print if the button is on (0) but the button is clearly off (1)

This makes me wonder if the RPi pin is giving false signals and confusing the code, or is there something wrong with the flow of my Python code here?

The code:

import RPi.GPIO as io
import time
import adafruit_fingerprint
import serial
io.setwarnings(False)
io.setmode(io.BCM)
io.setup(5, io.IN, io.PUD_UP)
BUTTON = 5
ACC = 23
IGN = 27
START = 22
uart = serial.Serial("/dev/ttyAMA0", baudrate=57600, timeout=1)
finger = adafruit_fingerprint.Adafruit_Fingerprint(uart)
started = 0
ignition = 0

##################################################


# This block is pretty much straight from the Adafruit code, slightly 
# modified with my button checks, this segment seems to work fine

def get_fingerprint():
    while finger.get_image() != adafruit_fingerprint.OK:
        button_off = io.input(BUTTON)
        if button_off == 1:
            return False
        if button_off == 0:
            pass
    if finger.image_2_tz(1) != adafruit_fingerprint.OK:
        return False
    if finger.finger_fast_search() != adafruit_fingerprint.OK:
        return False
    return True

while True:

    button_off = io.input(BUTTON) ### Constantly checking for the button state because 
# when I dont it seems to just remember the state from a certain point instead of giving reliable updated readings

#Button is on
    if started == 0: #car is not started yet
        if ignition == 0: #Accessory and Ignition are not on
            if button_off == 0:
                print ("Accessories on") #This message displays after turning the button off... why?? The if statement clearly says 0 so I don't get why this part of the code would execute
                ignition = 1
        if ignition == 1:
            if button_off == 0:
                if get_fingerprint():
                    print("Car started.")
                    started = 1
    if started == 1:
        pass

#Button is off
    if button_off == 1:

        if ignition == 1: #should only do this once if the button was on, otherwise just continue polling the input state of the button.
            print("Accessories off") ###This statement works fine before the finger print, but will execute twice if I turn off the button after the finger sequence. Why?
            ignition = 0
            started = 0

One Answer

Thanks everyone for the suggestions. I suspected something like contact bounce wasn't the issue here because the button response works perfectly before the fingerprint sequence of the code executed, it was only after the get_fingerprint block returning True that the button would have the effect, making me think the python code was repeating somewhere it shouldn't.

To anyone googling this in the future or anyone interested in doing a similar project, here is the tweaked code that I got working with the help of a friend. Using a fingerprint reader compatible with the Adafruit fingerprint library and a switch, I can start my car using a fingerprint. I have the script boot at startup using crontab.

Some differences from my original code are the get_button() block, and reversing the negative logic to make it less confusing.

Here is the working code. I haven't field tested it extensively yet but everything appears to work perfect now.

import RPi.GPIO as io
import time
import adafruit_fingerprint
import serial
io.setwarnings(False)
io.setmode(io.BCM)

#GPIO Names
BUTTON = 5
ACC = 23
IGN = 27
START = 22
DOME = 20

#GPIO Setup
io.setup(BUTTON, io.IN, io.PUD_UP)
io.setup(ACC, io.OUT)
io.setup(IGN, io.OUT)
io.setup(START, io.OUT)
io.setup(DOME, io.OUT)
io.output(ACC, 1)
io.output(IGN, 1)
io.output(START, 1)
io.output(DOME, 1)

#UART/Fingerprint Setup
uart = serial.Serial("/dev/ttyAMA0", baudrate=57600, timeout=1)
finger = adafruit_fingerprint.Adafruit_Fingerprint(uart)

##################################################

def get_button():
    result = (not io.input(BUTTON))
    time.sleep(.1)
    return result

def get_fingerprint():
    while finger.get_image() != adafruit_fingerprint.OK: #Waiting for finger, loops
        if io.input(BUTTON) == 1: #Exit finger sequence if button off
            return False
    if finger.image_2_tz(1) != adafruit_fingerprint.OK:
        return False
    if finger.finger_fast_search() != adafruit_fingerprint.OK:
        return False
    return True

while True:

    car_on = get_button()

#Button is on
    if car_on:
        if io.input(IGN) == 1:
            io.output(IGN, 0) #Ignition and Accessory on
            io.output(ACC, 0)
        if get_fingerprint():
            io.output(ACC, 1) #Starter sequence
            time.sleep(.3)
            io.output(START, 0)
            time.sleep(.6)
            io.output(START, 1)
            time.sleep(.3)
            io.output(ACC, 0)
            while car_on:
                car_on = get_button() #Check for button off

        if io.input(BUTTON) == 1:
            io.output(IGN, 1) #Button Off = All Systems Off.
            io.output(ACC, 1)

Answered by cornerpocket on October 20, 2020

Add your own answers!

Related Questions

RFID RC522 Reader & Chromium Web Page

1  Asked on December 5, 2020

     

Access Raspberry pi jenkins server over the internet

1  Asked on December 4, 2020 by emil-mller-ringgaard

   

Stuck in matchbox window

1  Asked on December 2, 2020 by christian-benner

   

How to use PI4J with a brushless motor?

1  Asked on November 27, 2020 by cy8berpunk

     

Android Things for RaspBerry

0  Asked on November 16, 2020 by flower

 

Pioneer TV shows “unsupported” when connected to RPI 4

1  Asked on October 29, 2020 by dannyniu

     

Docker disables network connectivity

0  Asked on October 16, 2020 by stevepoling

   

Is there documentation for RPi.GPIO

2  Asked on October 15, 2020 by milliways

 

Redirecting Traffic to local mqtt server

2  Asked on October 11, 2020 by elior

     

Playing Kodi without UPnP

0  Asked on October 6, 2020 by hasan

     

Powering a Servo with 12V Battery and Buck Converter

0  Asked on September 26, 2020 by gumby4231

     

Trying to get SSH over USB to work (Raspberry pi Zero W)

1  Asked on September 26, 2020 by damightyzombie

       

Raspberry PI random connection interruptions

1  Asked on September 22, 2020 by ben

     

Connect sim800 to Raspberry PI (RX, TX)

4  Asked on September 15, 2020 by max

       

make: *** No rule to make target ‘Install’. Stop

1  Asked on September 12, 2020 by travism

       

Ask a Question

Get help from others!

© 2022 AnswerBun.com. All rights reserved. Sites we Love: PCI Database, MenuIva, UKBizDB, Menu Kuliner, Sharing RPP, SolveDir