stanwin00
Posts: 37
Joined: Tue Aug 06, 2019 9:55 am

GPIO outputs

Tue Feb 04, 2020 8:13 am

Hi experts, i recently deployed a working access control electromagnetic door lock system with the usage of tkinter for loading the gui on my display.

I have 4 threads running in my application using the method Thread:
1) tkinter gui main thread
2) USB reader for reading rfid cards thread
3) Flask application
4) Function waiting for a response from 2 exit buttons.

My issue is that GPIO.input(4) randomly gets activated to be false thereby unlocking the door. Is there anyway i can improve the code such that the door will stay lock unless the buttons are pressed. The door is controlled by GPIO 12.

My code is as below:

Code: Select all

#!/usr/bin/env python3
import sys
import os
import config
from flask import Flask, jsonify, request, render_template, send_from_directory, Response
import pymysql.cursors
from threading import Thread
import threading
import time
import RPi.GPIO as GPIO
import json
from evdev import InputDevice
from select import select

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(12, GPIO.OUT)
GPIO.setup(12, GPIO.LOW)
GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(4, GPIO.IN, pull_up_down=GPIO.PUD_UP)

app = Flask(__name__)
@app.route('/unlock/',methods=['GET','POST'])
def opendoor():
    if request.content_type=='application/json':
        print (request.json)
        if request.method=='POST':
            data = request.get_json()
            doorid = data.get('doorid')
  
            if doorid==somevalue
                try:
                    GPIO.output(12, GPIO.HIGH)
                    time.sleep(5)
                    GPIO.output(12,GPIO.LOW)
                    return jsonify("Access Granted - Welcome.")
                except:
                    return jsonify("Access Denied - You are not authorized to access the premise, please contact the administrator")
        else:
            return jsonify("Failed - please contact the administrator")
    else:
        return jsonify("Application needs to reboot")

@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, 'static'),
                          'favicon.ico',mimetype='image/vnd.microsoft.icon')
try:
    # python 2
    import Tkinter as tk
    import ttk
except ImportError:
    # python 3
    import tkinter as tk
    from tkinter import ttk

class Fullscreen_Window:

    def __init__(self):
        self.show_idle()
        t = Thread(target=self.flask_main)
        t2 = Thread(target=self.listen_rfid)
        t.daemon = True
        t2.daemon = True
        t.start()
        t2.start()
        self.buttonpress =self.tk.after(100,self.button)

    def flask_main(self):
        app.run(parameters for flask)

    def button(self):

        if GPIO.input(5)==0:
           print ("exit button is pressed")
           GPIO.output(12, GPIO.HIGH)
           time.sleep(5)
           GPIO.output(12, GPIO.LOW)
           time.sleep(.1)
           
        if GPIO.input(4)==0:
           print("receptionist button is pressed")
           GPIO.output(12, GPIO.HIGH)
           time.sleep(5)
           GPIO.output(12, GPIO.LOW)
           time.sleep(.1)

        self.buttonpress = self.tk.after(100, self.button)

    def show_idle(self):
        ...gui set up...

     def listen_rfid(self):
        global accessLogId
        keys = "X^1234567890XXXXqwertzuiopXXXXasdfghjklXXXXXyxcvbnmXXXXXXXXXXXXXXXXXXXXXXX"
        dev = InputDevice('/dev/input/event0')
        rfid_presented = ""

        while True:
            r,w,x = select([dev], [], [])
            for event in dev.read():
                if event.type==1 and event.value==1:
                    if event.code==28:
                        connect to database and perform validation.
                    else:
                        rfid_presented += keys[ event.code ]

if __name__ == '__main__':
    w = Fullscreen_Window()
    w.tk.mainloop()

User avatar
rpiMike
Posts: 1387
Joined: Fri Aug 10, 2012 12:38 pm
Location: Cumbria, UK

Re: GPIO outputs

Tue Feb 04, 2020 8:56 am

GPIO 4 is the default pin for the 1 wire interface. Check it’s disable in Raspberry Pi Configuration or use a different pin.

stanwin00
Posts: 37
Joined: Tue Aug 06, 2019 9:55 am

Re: GPIO outputs

Tue Feb 04, 2020 9:05 am

Hi @rpiMike, i've checked and the interface is disabled. I've tried adding GPIO.output(12, GPIO.LOW) at the top of the button function to ensure the lock stays closed but it clashes with my other threads.

Not sure how else i can code this.

User avatar
rpiMike
Posts: 1387
Joined: Fri Aug 10, 2012 12:38 pm
Location: Cumbria, UK

Re: GPIO outputs

Tue Feb 04, 2020 9:15 am

Have you got long wires between the buttons and GPIO pins?

stanwin00
Posts: 37
Joined: Tue Aug 06, 2019 9:55 am

Re: GPIO outputs

Tue Feb 04, 2020 9:25 am

as a matter of fact that GPIO(4) does have a long wire connected to it. I was afraid it will be that conclusion.... @rpiMike

gordon77
Posts: 5036
Joined: Sun Aug 05, 2012 3:12 pm

Re: GPIO outputs

Tue Feb 04, 2020 9:43 am

How about just adding a delay for a long press (1 sec)..

Code: Select all

if GPIO.input(4)==0:
       time.sleep(1)
       if GPIO.input(4)==0:
           print("receptionist button is pressed")
           GPIO.output(12, GPIO.HIGH)
           time.sleep(5)
           GPIO.output(12, GPIO.LOW)
           time.sleep(.1)
or a bit better..

Code: Select all

if GPIO.input(4) == 0:
       start = time.time()
       stop = 0
       while time.time() - start < 1 and stop == 0:
           stop = GPIO.input(4)
       if stop == 0:
           print("receptionist button is pressed")
           GPIO.output(12, GPIO.HIGH)
           time.sleep(5)
           GPIO.output(12, GPIO.LOW)
           time.sleep(.1)

Bope
Posts: 71
Joined: Sat Jul 06, 2019 2:57 am

Re: GPIO outputs

Tue Feb 04, 2020 5:48 pm

You are picking up EMF on the long wire. I had the same problem with one of my projects. Use a 2N2222 transistor. Set the GPIO to high and connect to the collector. Set emitter to ground. Wire from your switch to the base with a resistor. Prior to the resistor connect a small capacitor and resistor shunted to ground. Look at this thread https://www.raspberrypi.org/forums/view ... e#p1540361 Substitute my sensor for your switch. You should be able to get enough transistors and capacitors for more projects than you can think of for only a couple dollars.

The theory here is the capacitor soaks up the high frequency EMF and bleeds it to ground. The low frequency signal when the button is pushed saturates the capacitor and sends the signal to the transistor.

stanwin00
Posts: 37
Joined: Tue Aug 06, 2019 9:55 am

Re: GPIO outputs

Wed Feb 05, 2020 1:38 am

thanks @bope, that solution sounds logical but that means it would cause me more hardware installation overhead. perhaps one for the future. Why does this occur though? Will this same problem occur if we are not using a raspberry pi? and using the standard microcontroller board?

I'll try out @gordon77's method for now. Just that instead of being 1 second, I gave it a 0.1 second delay. If the 1 second code is implemented, users would have to press and hold the button for the gpio to be active.

gordon77
Posts: 5036
Joined: Sun Aug 05, 2012 3:12 pm

Re: GPIO outputs

Wed Feb 05, 2020 8:34 am

stanwin00 wrote:
Wed Feb 05, 2020 1:38 am
thanks @bope, that solution sounds logical but that means it would cause me more hardware installation overhead. perhaps one for the future. Why does this occur though? Will this same problem occur if we are not using a raspberry pi? and using the standard microcontroller board?

I'll try out @gordon77's method for now. Just that instead of being 1 second, I gave it a 0.1 second delay. If the 1 second code is implemented, users would have to press and hold the button for the gpio to be active.
The delay period is to allow it to filter out unwanted spikes, maybe 0.1 is enough

Bope
Posts: 71
Joined: Sat Jul 06, 2019 2:57 am

Re: GPIO outputs

Wed Feb 05, 2020 5:20 pm

You can use a software fix but you are more likely to make the button feel unresponsive or have some random triggers. The hardware overhead is negligible to the cost you have already spent. The long wire is acting as an antennae. You could try something like coax cable if you ground the shielding.

stanwin00
Posts: 37
Joined: Tue Aug 06, 2019 9:55 am

Re: GPIO outputs

Thu Feb 06, 2020 2:20 am

@bope thanks for that. Yes i agree that for my next project i should fix the hardware side. However on second thought, my wire to GPIO4 is probably about 2 to 3m long at best. Will that still pick up emf signals?

@gordon77 thanks for the tip. it seems to be holding. No reported spikes since yesterday

Bope
Posts: 71
Joined: Sat Jul 06, 2019 2:57 am

Re: GPIO outputs

Thu Feb 06, 2020 5:22 pm

I am not an electronics engineer so I can't tell you definitively. I would bet it is going to depend on the location and the amount of EMF signal in the area.

Return to “Beginners”