My problem is when I call a GPIO function it freezes the program like it is in some endless loop. The following line of code shows how I am calling the GPIO functions.
GPIO.output(Run_Pin,GPIO.HIGH)
I tracked the problem to the GPIO function ( both input and output) by commenting out the GPIO functions; the code runs correctly and does not freeze.
.
Yes, I import RPi.GPIO as GPIO and set up the GPIO pis correctly.
Yes, you are correct I am using Rasberry PI 3B running Python. My project is a stepper motor controller. Since Python can not handle the micro-second timing needed for the proper operation of the motor I am using a logic controller ( Adafruit ItsyBitsy 32u4 - 3V) to provide the required timing. I am using the Rasberry GPIO pins to tell the logic controller what task to run. Plus a GUI user interface to select what function the user wants to run.
Right now the Rasberry is not connected to the logic controller, so I can ensure the Python code is working ( which is not and need help.
The fowling code shows that I have set up the GPIO correctly Run_Pin is defined as GPIO pin 23 and set up as an output
#=== Set GPIO Pins ===
Toy_Sel_Pins = (14, 15)
Abort_Pin =18
Run_Pin = 23
DIR_Pin = 24
IntensitySelect_Pins = (1, 7, 8, 25) # Tell contrler ieinIntensity value
Busy_Pin = 12
BUZZER_Pin = 16
PWR_LED_Pin = 20
Ready_LED_Pin = 21
PUSH_BUTTON_Pin = 37
#Initize the GPIO pins
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUZZER_Pin, GPIO.OUT)
GPIO.setup(IntensitySelect_Pins, GPIO.OUT)
GPIO.setup(Ready_LED_Pin, GPIO.OUT)
GPIO.setup(PWR_LED_Pin, GPIO.OUT)
GPIO.setup(PUSH_BUTTON_Pin, GPIO.IN)
GPIO.setup(Busy_Pin, GPIO.IN)
GPIO.setup(Run_Pin, GPIO.OUT)
GPIO.setup(DIR_Pin , GPIO.OUT)
GPIO.setup(Abort_Pin, GPIO.OUT)
GPIO.setup(Toy_Sel_Pins, GPIO.OUT)
def Run_Task():
global Run_Pin
global Busy_Pin
global Stop_LED_Flashing
global Abort_Pin
# First start the LED flashing thread
# Stop_LED_Flashing = False
# Ready_LED_Flashing = Thread(Set_Ready_LED_Flashing)
# Ready_LED_Flashing.daemon = True
# Ready_LED_Flashing.start()
# Debug Statement
print("Run_Task Telling controller to excute task")
print(" TEST TEST TEST")
print(" TEST TEST TEST TEST")
# Tell controler to excute the task
GPIO.output(Run_Pin,GPIO.HIGH)
#Debug Statement
print(" Run Pin >> " , GPIO.input(Run_Pin))
print(" Checking Busy_Pin >>",GPIO.input(Busy_Pin),)
# Wait until stepper controler has started the task
while(not GPIO.input(Busy_Pin)): # Wait for controller to start tesk
#Debug Statement
print("Waiting Busy Pin >> false")
sleep(1) #Wait 1 mS to allow logic controler time to respond
# Now wait until stepper controler has finish the task
#Debug Statment
print(" Waiting for Busy_Pin to return to false", GPIO,input(Busy_Pin) )
while(GPIO,input(Busy_Pin)):
#Debug Statement
print("Waiting Busy Pin >> True")
sleep(1)
Control has finshed so return Run pin to false to telling the controller the PI has
GPIO.output(Run_Pin, False)
GPIO.output(Abort_Pin, False)
Stop_LED_Flashing = True
# Debug Statement
print("Controller comleted task Retuning")
#**********************************************
If you want to see the entire code here is Dropbox link o it
To truly zoom in on whether it is the IO pin or not, you can create a simple
empty while loop with just the IO pin script by where you toggle the pin between the two states continuously. Something roughly like this (start with one pin only for simplicity and then build from there):
# Pin set-up code here (only include the code for the desired pin)
-
-
-
while True:
GPIO.output(channel, GPIO.HIGH)
GPIO.output(channel, GPIO.LOW)
GPIO.output(channel, GPIO.HIGH)
GPIO.output(channel, GPIO.LOW)
Do you have access to an o-scope? If not, how are you verifying that the pin is toggling and at the required frequency?
Correction:
Ok, so you’re really not toggling the pin at a frequency. I take it the Rasberry pins provide a binary address (let’s say three pins) 0b011, and the logic controller, based on this input read, ... tell the logic controller what task to run. Ok. Understood. But testing it as per the recommended script above is still valid. We can test for all of the output pins that are providing the code to the controller on an individual basis. If verified, then we can move to the next verification step.
Yes, you are very correct on the controller interface’ I set up the task info then tells the controller to run taken by setting Run_Pin high. The controller sets busy pin high telling Python it is busy doing a task. Python then waits for the Busy_Pin to go low to continue the rest of program…
OK, the following test code hangs up on the first GPIO operation. Also, the pin does not go high!!!
import RPi.GPIO as GPIO
from time import sleep
GPIO.setmode(GPIO.BCM)
GPIO.setup(14, GPIO.OUT)
while(True):
print("High")
GPIO.output(14,GPIO.HIGH)
sleep(500)
print("LOW")
GPIO.output(14,GPIO.LOW)
sleep(500)
From the tutorial (in section Pin numbering): The advantage of using this numbering system is that your hardware will always work, regardless of the board revision of the RPi.
You tested pin 14. Can you retest pin 23 since this was the pin in question. Also check physically if this pin is routed correctly to the logic controller. That is, if this pin goes to, say, pin 25 of the controller, check and verify this.
By the way, the unit of the argument to the timer is in seconds and not milliseconds. So, 500 refers to 500 seconds (8.3 minutes) and not 0.5 s. To test it with the timer you could have used:
sleep(1) # One second increments
or, if you wanted half a second increments:
sleep(0.5)
Depending on the internals of the GPIO module of the Rasberry, you might have to add a pull-up resistor to each of the pins. That is, if the GPIOs have an open-collector configuration without the option of providing one internally ,then you will have to provide your own external pull-up resistor.
Take a look a the Rasberry datasheet or user manual for details.
If a pull-up resistor is provided by default, then check that there are no shorts to whatever it is you’re connecting it to. If you have a multimeter, disconnect the pin from everything and test it by checking the voltage at that pin (just set the pin to HIGH without toggling it for test purposes).
Always ensure that there is a current limiting resistor in series so the LED (make sure it is placed with the correct polarity) does not burn up and provide a different kind of light show.
I briefly looked your script from the link that you provided on GIT. I would recommend replacing these lines:
from tkinter import *
from tkinter import _setit
with:
import tkinter as tk
Then, all the names from this library that you are using would need to be prefixed with tk. As in:
tk.label ... etc.
tk._setit ... etc.
This will avoid name collision with native names that you may have or add at a later date. There was actually a user last week whose script was malfunctioning and it was due to name collision.
You would think that with over twenty years of experience, I should know to connect the DVM ground lead to the circuit ground to get an acrate voltage… DADADA (LOL). Once I connect the ground lead all the GPIO pins are working properly (High = 3.3V and LOW = 0 V).
I have changed from BCM to BOARD pin numbers.
I did not write the GUI so I will pass your tkinter suggestions to them.
Thank you for pointing out my syntax error.
Your correct on the sleep function being is in seconds instead of milliseconds. I think I was thinking in Arduno delay fnctuin my bad.
I discovered a possible clue as to why the Run_Task function is crashing. One of the logic controllers function is called Alignment(). In this function, there are GPIO functions that do not crash. Also, this function calls another function called ChangeToyType, which also has GPIO statements that do not crash. So why is the Run_Task function GPIOs crashing and locking up the program?
I have updated the source code. I changed from BCM to BOARD pin numbering. and other changes. The ChangeToyType function is at line 477 and the Alignment is at line 723. SmakerCode_TST.py
I do not need milliseconds in the main script. I only use sleep to debug the code.
I think I found the error in the Run Task function. Yes, it is stuck in an endless loop tiring to read a GPIO (Busy_Pin) Since the controller is not hooked up there is no signal on that pin means it is floating. Commenting out the read GPIO pin the code runs properly. I just have to correct the logic flow of the program.