I have 4 LEDs connected to GPIO outputs of a Raspberry Pi. I want to use the argv command so that I can select the LEDs using a simple binary code. For example:
python test.py 1010
This would light up the first and third LEDs in the row. The problem is I don't think Im approaching this correctly. Here is my code so far
from sys import argv
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.OUT)
GPIO.setup(12, GPIO.OUT)
GPIO.setup(13, GPIO.OUT)
GPIO.setup(15, GPIO.OUT)
x, y = argv
print "Script:", x
if y == '0000':
GPIO.output(11, 0)
GPIO.output(12, 0)
GPIO.output(13, 0)
GPIO.output(15, 0)
if y == '0001':
GPIO.output(11, 0)
GPIO.output(12, 0)
GPIO.output(13, 0)
GPIO.output(15, 1)
GPIO.cleanup()
Im leaving out the rest of the combinations so I dont bloat this question. Im running into several syntax issues, but Im wondering if I should just scrap this and go about it another way. Im new and any advice would be appreciated.
It sounds very much like what you really want is to map the pieces of your input string to the values of your calls to GPIO.output. You can do that easily (and with far less code than you currently have) by iterating over the control string:
led_map = {
# This maps each "bit" of your input string to the correct ID for GPIO.
0 : 11,
1 : 12,
2 : 13,
3 : 15
}
for i in xrange(len(y)):
bit = y[i]
GPIO.output(led_map[i], int(bit))
This setup prevents you from having to code each permutation separately (which quickly becomes terrible even with only two or three bits, let alone four or more). Rather than thinking in terms of permutations, you can just consider the bits individually, and perform the appropriate functions on each of them in turn.
Related
I have some troubles handling interruptions with my Raspberry Pi 4, using Python.
I have a DC motor with an encoder , I would like to make a speed control of this motor. But I have some issues with reading the encoder values with my Raspberry.
Here is the code I run :
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
HallA = 5 # GPIO pin for Hall A
HallB = 6 # GPIO pin for Hall B
GPIO.setup(HallA, GPIO.IN) #set up the input
GPIO.setup(HallB, GPIO.IN)
incmot = 0 # set up the counter
def encodeur_inc(channel) : #function of the interruption
B = GPIO.input(HallB) #read the second signal
global incmot
if B == 1 :
incmot = incmot +1
else :
incmot = incmot -1
GPIO.add_event_detect(HallA, GPIO.RISING, callback = encodeur_inc) #setting up the interruption
try :
while True :
print(incmot)
except :
GPIO.cleanup()
The problem is that, for the same number of revolutions, I get a different number of pulses each time (from 480 to 650 pulses per revolution, while the manufacturer announces 690). I tried to identify where the problem could come from:
It does not come from the encoder, I displayed on an oscilloscope the signals of the two outputs of the encoder, they were indeed phase quadrature rectangle waves
The raspberry does not miss interrupts, by rising a pin high when entering the interrupt then low when leaving, I displayed on the oscilloscope the inputs and outputs of the interrupt.
GPIO.output(20, GPIO.HIGH) #at the beginning of the function
GPIO.output(20, GPIO.LOW) #at the end of the function
So I don't see where the inconsistencies I see could come from. I you have any clue that could help me don't hesitate.
Thanks for your help !
Thanks to #quamrana, I understood where the problem came from. When the program was interrupted, the time taken to execute the interrupt was variable and, going clockwise, Hall B could be at 1 or 0, instead of 1 all the time.
To get around this problem, using a D latch allows Python time to execute the interrupt and correctly read whether the engine is moving forward or backward. Hall A is the clock of the latch and Hall B is the data.
I am trying to create essentially a thermostat control using a DHT22 sensor. I would like to read the data from the sensor and using an if statement compare the sensor value to a set temperature value. If achieved the if statement would turn on a relay using a normally off outlet. Below is the code i have wrote in Geany programming to get a general idea of what i would like to do.
from time import sleep
import RPi.GPIO as GPIO
import Adafruit_DHT as dht
GPIO.setmode(GPIO.BCM)
AC_1_GPIO = 17 #sets relay to GPIO pin 17 for AC unit control
DHT_1_GPIO = 3
GPIO.setup(AC_1_GPIO, GPIO.OUT) #sets up GPIO to be on or off based on condition
#GPIO.setup(DHT_1_GPIO, GPIO.OUT) #
humdtemp = dht.read_retry(dht.DHT22, DHT_1_GPIO)
Temp_Max = 32 #this is temperature maximum value for tent
#Humd_Max = 60 #this is relative humidity maximum value for
#Humd_Min = 30 #this is relative humidity mininum value for
while True: #creates continuous loop
if humdtemp > Temp_Max: #compares sensor value to maximum
# temperature value
GPIO.output(AC_1_GPIO, GPIO.LOW) #turns on AC unit using controllable relay
elif humdtemp == Temp_Max:
print ("Achieving 72 degree temperature") #we need to select a temperature setpoint value
else:
GPIO.output(AC_1_GPIO, GPIO.HIGH) #turns 'on' normally off relay
I am trying to basically write a simple script that will tell the fan (plugged into pin 4 on the GPIO) to turn on at a certain temp, and if anything less, turn the fan off. I am starting with something simple just to see if I can control the fan based on temperature. Here is what I have so far:
import os
from time import sleep
import signal
import sys
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(4, GPIO.OUT)
temp = os.popen('vcgencmd measure_temp').readline()
if temp > 65:
GPIO.output(4, True)
else:
GPIO.output(4, False)
When I run this, it either appears to run but the fan doesn't turn off even though the temp hasn't nearly reached the level I wrote, or it will tell me that the pin is already in use but it will continue anyways. Either way, the fan still runs regardless of current temp.
vgencmd returns as:
temp-37.0'C
How would I remove the non-numerical characters so I am stuck with an int? When I execute it I get this:
ValueError: invalid literal for int() with base 10: "temp=37.6'C\n"
NOTE: Some of the imported modules aren't in use yet, that's why they are there.
You're very close. These two lines are problematic:
temp = os.popen('vcgencmd measure_temp').readline()
if temp > 65:
Here, temp is a string. You need to convert temp to an integer before trying to compare it against an integer. Assuming the line you're reading is just a decimal string corresponding to some temperature, you simply call int(), like this:
temp = os.popen('vcgencmd measure_temp').readline()
temp = int(temp)
Update Since you posted the output you're actually trying to parse, we can use regular expressions to match the output, with the re module. We'll also put this in a function:
def measure_temp():
raw = os.popen('vcgencmd measure_temp').readline()
m = re.match("temp=(\d+\.?\d*)'C", raw)
if not m:
raise ValueError("Unexpected temperature string: " + raw)
return float(m.group(1))
temp = measure_temp()
Note that I used a capture group around the actual temperature decimal in the string, and accessed it using m.group(1).
Let's put it together now. Also, when your code isn't doing what you expect, it is extremely helpful to include some "debug prints", like this:
def measure_temp():
raw = os.popen('vcgencmd measure_temp').readline()
m = re.match("temp=(\d+\.?\d*)'C", raw)
if not m:
raise ValueError("Unexpected temperature string: " + raw)
return float(m.group(1))
temp = measure_temp()
print 'Temperature from vcgencmd: {}'.format(temp)
if temp > 65:
print 'Turning on GPIO 4'
GPIO.output(4, True)
else:
print 'Turning off GPIO 4'
GPIO.output(4, False)
Once you get the basics working, there are a few other things you're going to run into:
Your script checks the temperature and toggles the GPIO once. If you want this thing to operate like a thermostat, you're going to need to keep doing these actions, using a while loop.
If your while loop runs very fast, and the temperature fluctuates right around your setpoint (65), you're going to find your code rapidly turning the fan on/off. It may help to add a bit of hysteresis to the system. For example, if you set your home thermostat (heating) to 70 degrees, it may come on at 69, but turn off at 71. Or it may simply not change states if it has already changed states within the last X seconds.
The simplest solution would be to sleep() for a short period of time between checks:
while True: # Loop forever
# Read the current temperature
temp = os.popen('vcgencmd measure_temp').readline()
temp = int(temp)
print 'Temperature from vcgencmd: {}'.format(temp)
# Control the fan
if temp > 65:
print 'Turning on GPIO 4'
GPIO.output(4, True)
else:
print 'Turning off GPIO 4'
GPIO.output(4, False)
# Wait before the next iteration
time.sleep(5)
I have a MCP3008 connected to RPi and 2 x Force Sensitive Resistor - Square connected to the MCP3008. The sensors are laying side by side horisontal on my desk and I can read and print the data (0-100) from both sensors (sensor1 and sensor2) separately. I just can't come up with any idea of python code to detect when I touch sensor1 (left) and move my finger to sensor2 (right).
In addition I need to know how many milliseconds it takes from that I touch sensor1 until I lifted from sensor2.
from time import sleep
from gpiozero import MCP3008
sensor1 = MCP3008(1) # Pin 2 on the ADC
sensor2 = MCP3008(2) # Pin 3 on the ADC
# Read data from the ADC
def getData(readSensor):
value = readSensor
rawValue = value.value
return rawValue
while True:
print('Sensor1 = {0:.0f}'.format(getData(sensor1)*100))
print('Sensor2 = {0:.0f}'.format(getData(sensor2)*100))
print('')
sleep(0.1)
You are going to need to timestamp the events and then use the time stamps to determine what action to take. Something like the below might help you.
if getData(sensor1) > TOUCH_THRESHOLD:
sensor1LastPressedAt = time.time()
Do the same for sensor2 and compare the time stamps.
(TOUCH_THRESHOLD is the value that you measure to be someone touching the button)
I actually want to use this waterproof ultrasonic sensor DYP-ME007Y-PWM (http://hanjindata.lgnas.com:10000/myweb/P0400/P0400.pdf) on my raspberry PI Compute Module on a classic Raspbian OS. It has 4 pin's (gnd,Trig,Echo and 5V).
Here is my schematic:
Raspberry Pi | Sensor
GND | GND
5V | 5V
22 | Trig
23 | Echo
I've found some tutorials that explain how ultrasonic sensors works and mannage to have good results with other kind of ultrasonic sensors like this one for exemple (http://www.micropik.com/PDF/HCSR04.pdf)
Here is my code :
# Import required Python libraries
import time
import RPi.GPIO as GPIO
# Use BCM GPIO references
# instead of physical pin numbers
GPIO.setmode(GPIO.BCM)
# Define GPIO to use on Pi
GPIO_TRIGGER = 22
GPIO_ECHO = 23
print "Ultrasonic Measurement"
# Set pins as output and input
GPIO.setup(GPIO_TRIGGER,GPIO.OUT) # Trigger
GPIO.setup(GPIO_ECHO,GPIO.IN) # Echo
# Set trigger to False (Low)
GPIO.output(GPIO_TRIGGER, False)
# Allow module to settle
time.sleep(0.5)
# Send 10us pulse to trigger
while True:
GPIO.output(GPIO_TRIGGER, True)
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
start = time.time()
while GPIO.input(GPIO_ECHO)==0:
start = time.time()
while GPIO.input(GPIO_ECHO)==1:
stop = time.time()
# Calculate pulse length
elapsed = stop-start
# Distance pulse travelled in that time is time
# multiplied by the speed of sound (cm/s)
# That was the distance there and back so halve the value
distance = (elapsed * 34000)/2
print "Distance : %.1f" % distance
time.sleep(0.05)
# Reset GPIO settings
GPIO.cleanup()
I doesn't work, i obtain always the same output whatever i do with my sensor
Does anybody has alreeady play with this sensor ? As you can see, the datasheet is pretty ligth, so maybe you will see something my poor electronics skills have missed
Greetings !
You are expecting GPIO_ECHO to be 1 from the start. According to the documentation it is first 0, then 1, and then back to
1.
Maybe
while GPIO.input(GPIO_ECHO)==0:
# some short sleep might be better
pass
start = time.time()
while GPIO.input(GPIO_ECHO)==1:
pass
while GPIO.input(GPIO_ECHO)==0:
pass
stop = time.time()
There are methods available for detecting rising edge and falling edge, see for example raspi.tv arcticle. It might be better to use those methods.
According to:
https://forum.arduino.cc/index.php?topic=153700.30
the sensor is quite sensitive to getting enough power - Check that your 5V doesn't drop too much.
Also the Raspberry Pi GPIO pins are 3V3 - They might not like the output from the sensor (which presumably is 5V), and the sensor might not trigger on the 3V3 output from the Raspberry pi.