pythonflaskraspberry-pi

Busy GPIO's Raspberry PI5


I bought the new PI5, and I'm in a middle of a difficulty:

This is a python/flask script - main.py - which call for a python script named shift_register.py and runs SRoutput():

from website import create_app
from flask import send_from_directory, request

import os, sys

ctrl_hardware_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'ctrl_hardware'))
sys.path.append(ctrl_hardware_path)
from shift_register import SRoutput


app = create_app()

@app.route("/images/<path:filename>")
def serve_image(filename):
    return send_from_directory("images", filename)

# Definição dos bits a serem transmitidos

#Rota para receber o parâmetro binário e usar no shift_register.py
@app.route('/atualizar_shift_register', methods=['GET'])
def atualizar_shift_register():
    parametro = request.args.get('parametro')

    # Remove o prefixo '0b' se presente
    if parametro.startswith('0b'):
        parametro = parametro[2:]

    # Chama a função SRoutput do shift_register.py passando o parâmetro binário
    SRoutput(int(parametro,2)) #Converte o parâmetro binário para inteiro

    return f'Parâmetro binário {parametro} passado com sucesso!'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True) #Defenido para executar em todos os ip's disponíveis pela rede

This is script shift_register.py:

from gpiozero import OutputDevice

import time

import warnings
warnings.filterwarnings("ignore")

SER = OutputDevice(5, initial_value=None)         # GPIO 5 - SER/DS (serial data input, SPI data)
RCLK = OutputDevice(6)        # GPIO 6 - RCLK/STCP
SRCLK = OutputDevice(13)      # GPIO 13 - SRCLK/SHCP (storage register clock pin, SPI clock)
OE = OutputDevice(19)         # GPIO 19 - Enable/Disable do SR
SRCLR = OutputDevice(26)      # GPIO 26 - O registo de deslocamento � limpo (ACTIVO BAIXO)

# Setup dos pinos
#GPIO.setup(SER, GPIO.OUT)               
#GPIO.setup(RCLK, GPIO.OUT)                     
#GPIO.setup(SRCLK, GPIO.OUT)
#GPIO.setup(SRCLR, GPIO.OUT)
#GPIO.setup(OE, GPIO.OUT)

# Inicializar a variavel correspondente a R1
# Reles 1 e 2
# checkshift = 0b0011

# Valor por defeito de espera nas operacoes do registo de deslocamento
WaitTimeSR = 0.1

#####################################################
# Tabela de verdade do Registo de Deslocamento
# SER | SRCLK | 'SRCLR | RCLK |  'OE | Sa�das/Fun��es
#  X      X       X       X       H    Q's inactivas
#  X      X       X       X       L    Q'S activos
#  X      X       L       X       X    SR limpo
#  L    + et      H       X       X    0 no SR
#  H    + et      H       X       X    1 no SR
#  X      X       X     +et       X   dados out
######################################################

# Inicaializa o pino de clear dos registos a 1 - o clear � controlado e feito numa fun��o
SRCLR.on() #GPIO.output(SRCLR,1)

# Enable do SR - sa�das sempre activas
OE.off() #GPIO.output(OE, 0)

# Fun��o que verifica e desloca os bits para armazenar no registo de deslocamento
def SRoutput(checkshift):
    for i in range(9):
        shift = checkshift & 1
        if shift == 1:
            print ("UM")
            WriteReg (shift, WaitTimeSR)
        else:
            print ("ZERO")
            WriteReg(shift, WaitTimeSR)
        checkshift = checkshift >> 1
    OutputReg()

# Defini��o da fun��o que envia os dados para o registo de deslocamento,
# segundo o algoritmo descrito em baixo

### ALGORITMO ###
# Enviar um bit para o pino SER/DS
### Depois de enviado, � dado um impulso de clock (SRCLK/SHCP) e o bit armazenado nos registos
###### ... um segundo bit � enviado, repetindo os dois passos em cima - � repetido at� estarem armazenados 8 bits
######### Por ultimo � dado um impulso aos registos (RCLK/STCP) para obter os 8 bits na saida

def WriteReg (WriteBit, WaitTimeSR):
    SRCLR.off() #GPIO.output (SRCLK, 0)  # Clock - flanco POSITIVO
    SER.value = WriteBit #GPIO.output (SER,WriteBit) # Envia o bit para o registo
    time.sleep (WaitTimeSR) # Espera 100ms
    SRCLK.on() #GPIO.output(SRCLK,1)

# Funcao que limpa o registo
def register_clear ():
    SRCLK.off() #GPIO.output(SRCLK, 0)
    time.sleep(WaitTimeSR) # espera 100ms
    SRCLK.on() #GPIO.output(SRCLK, 1)

# Armazenar o valor no registo
def OutputReg():
    RCLK.off() #GPIO.output(RCLK, 0)
    time.sleep(WaitTimeSR)
    RCLK.on() #GPIO.output(RCLK, 1)

(Sorry, the comments are in Portuguese...)

However, when I run main.py I get these errors:


[* Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000
 * Running on http://X.X.X.X:5000
Press CTRL+C to quit
 * Restarting with stat
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/gpiozero/pins/pi.py", line 408, in pin
    pin = self.pins[info]
          ~~~~~~~~~^^^^^^
KeyError: PinInfo(number=29, name='GPIO5', names=frozenset({'BOARD29', 'BCM5', 5, '5', 'WPI21', 'GPIO5', 'J8:29'}), pull='', row=15, col=1, interfaces=frozenset({'', 'spi', 'dpi', 'gpio', 'i2c', 'uart'}))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/grinder/Documents/GitHub/Unnamed-Thesis/webserver/main.py", line 8, in <module>
    from shift_register import SRoutput
  File "/home/grinder/Documents/GitHub/Unnamed-Thesis/ctrl_hardware/shift_register.py", line 7, in <module>
    SER = OutputDevice(5, initial_value=None)         # GPIO 5 - SER/DS (serial data input, SPI data)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/gpiozero/devices.py", line 103, in __call__
    self = super().__call__(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/gpiozero/output_devices.py", line 74, in __init__
    super().__init__(pin, pin_factory=pin_factory)
  File "/usr/lib/python3/dist-packages/gpiozero/mixins.py", line 75, in __init__
    super().__init__(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/gpiozero/devices.py", line 549, in __init__
    pin = self.pin_factory.pin(pin)
          ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/gpiozero/pins/pi.py", line 410, in pin
    pin = self.pin_class(self, info)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/gpiozero/pins/lgpio.py", line 126, in __init__
    lgpio.gpio_claim_input(
  File "/usr/lib/python3/dist-packages/lgpio.py", line 755, in gpio_claim_input
    return _u2i(_lgpio._gpio_claim_input(handle&0xffff, lFlags, gpio))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/lgpio.py", line 458, in _u2i
    raise error(error_text(v))
lgpio.error: 'GPIO busy'

(I've changed all the GPIO's and they are all busy)

Strangely enough, this worked with PI3 and RPi.

What am I missing?

Thank you!


Solution

  • Fix my problem: If anyone stumble upon this error this is how I fix it:

    import os
    os.environ['GPIOZERO_PIN_FACTORY'] = os.environ.get('GPIOZERO_PIN_FACTORY', 'mock')
    from gpiozero import OutputDevice
    

    Addendum

    By setting 'mock' as the default, the code is configuring gpiozero to use a pin simulation (a simulated environment) if the environment variable is not explicitly defined.

    This setup is useful for testing or running the code in environments where physical pins are not available, allowing the code to continue functioning without interaction with real hardware.

    Only part of the problem is solved

    [Solution] In case if someone has the same problem:

    from website import create_app
    from flask import send_from_directory, request
    
    import os, sys
    
    ctrl_hardware_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'ctrl_hardware'))
    sys.path.append(ctrl_hardware_path)
    from shift_register import SRoutput
    
    app = create_app()
    
    @app.route("/images/<path:filename>")
    def serve_image(filename):
        return send_from_directory("images", filename)
    
    # Definição dos bits a serem transmitidos
    
    #Rota para receber o parâmetro binário e usar no shift_register.py
    @app.route('/atualizar_shift_register', methods=['GET'])
    def atualizar_shift_register():
        parametro = request.args.get('parametro')
    
        # Remove o prefixo '0b' se presente
        if parametro.startswith('0b'):
            parametro = parametro[2:]     
    
        # Chama a função SRoutput do shift_register.py passando o parâmetro binário
        SRoutput(int(parametro,2)) #Converte o parâmetro binário para inteiro
    
        return f'Parâmetro binário {parametro} passado com sucesso!'
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=5000, **debug=True**) #Defenido para executar em todos os ip's disponíveis pela rede
    

    On PI5, the argument debug=True make ALL GPIO's busy. Removing it resolved the problem