Lidar and Servo on Raspberry pi 4 - python

I've two separate code bases for Tf-mini(Lidar) and servo motor. I want the both code to run at the same time. I tried to combine them in to a single code, But only one code runs at a time. Please help to rewrite or edit the code.
Code for servo motor here:
import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(7, GPIO.OUT)
p = GPIO.PWM(7, 100)
t = 0.007
r = 20
p.start(r)
while True:
for i in range(5,r):
p.ChangeDutyCycle(i)
print(i)
time.sleep(t)
for i in range(r,5,-1):
p.ChangeDutyCycle(i)
print(i)
time.sleep(t)`
Code for lidar here:
import time
import serial
ser = serial.Serial("/dev/ttyAMA0", 115200)
def read_data():
while True:
counter = ser.in_waiting
if counter > 8:
bytes_serial = ser.read(9)
ser.reset_input_buffer()
if bytes_serial[0] == 0x59 and bytes_serial[1] == 0x59: # this portion is for python3
print("Printing python3 portion")
distance = bytes_serial[2] + bytes_serial[3]*256 # multiplied by 256, because the binary
data is shifted by 8 to the left (equivalent to "<< 8").
# Dist_L, could simply be added resulting in 16-bit data of Dist_Total.
strength = bytes_serial[4] + bytes_serial[5]*256
temperature = bytes_serial[6] + bytes_serial[7]*256
temperature = (temperature/8) - 256
print("Distance:"+ str(distance))
print("Strength:" + str(strength))
if temperature != 0:
print("Temperature:" + str(temperature))
ser.reset_input_buffer()
if bytes_serial[0] == "Y" and bytes_serial[1] == "Y":
distL = int(bytes_serial[2].encode("hex"), 16)
distH = int(bytes_serial[3].encode("hex"), 16)
stL = int(bytes_serial[4].encode("hex"), 16)
stH = int(bytes_serial[5].encode("hex"), 16)
distance = distL + distH*256
strength = stL + stH*256
tempL = int(bytes_serial[6].encode("hex"), 16)
tempH = int(bytes_serial[7].encode("hex"), 16)
temperature = tempL + tempH*256
temperature = (temperature/8) - 256
print("Printing python2 portion")
print("Distance:"+ str(distance) + "\n")
print("Strength:" + str(strength) + "\n")
print("Temperature:" + str(temperature) + "\n")
ser.reset_input_buffer()
if __name__ == "__main__":
try:
if ser.isOpen() == False:
ser.open()
read_data()
except KeyboardInterrupt(): # ctrl + c in terminal.
if ser != None:
ser.close()
print("program interrupted by the user")
Please help me to combine these two code to run at the same time.

I think I see your problem. Both segments of code are sequentially driven and hence it will create problems. Here is what you need to do (pseudo code):
loop forever:
t1=start_time
change duty cycle #remove the wait code
poll the serial port #the ladar code
t2=end_time
if t2 - t1 < t:
wait (t - (t2-t1))
Being an old Arduino fan myself, I see the struggles of handling the servo motor. I have a simple library to do most of the dirty work for me. You are most welcome to use my library via any of the two links:
https://github.com/vikramdayal/RaspberryMotors or https://pypi.org/project/RaspberryMotors/#description

Related

Cannot unpack noniterable bool object

I'm new to Python and posting on SO.
I'm doing a class project on trying to create an automated climate control system with a Raspberry pi(Pi4 4GB) and a DHT.
Here is my current error and code and I'm not sure what's causing the fail in the loop. It works for a while then errors out. It seems to error when it gets a bad read from the sensor, but until then it works fine.
Traceback (most recent call last):
File "/home/pi/raphael-kit/python/Climatecontrol.py", line 156, in <module>
main()
File "/home/pi/raphael-kit/python/Climatecontrol.py", line 118, in main
humidity, temperature = readDht11()
TypeError: cannot unpack non-iterable bool object
import RPi.GPIO as GPIO
import time
import LCD1602
dhtPin = 17
relayPin = 23 # Set GPIO23 as control pin
set_temp = 25 # this is the required temperature
GPIO.setmode(GPIO.BCM)
# Set relayPin's mode to output,
# and initial level to High(3.3v)
GPIO.setup(relayPin, GPIO.OUT, initial=GPIO.HIGH)
MAX_UNCHANGE_COUNT = 100
STATE_INIT_PULL_DOWN = 1
STATE_INIT_PULL_UP = 2
STATE_DATA_FIRST_PULL_DOWN = 3
STATE_DATA_PULL_UP = 4
STATE_DATA_PULL_DOWN = 5
def readDht11():
GPIO.setup(dhtPin, GPIO.OUT)
GPIO.output(dhtPin, GPIO.HIGH)
time.sleep(0.05)
GPIO.output(dhtPin, GPIO.LOW)
time.sleep(0.02)
GPIO.setup(dhtPin, GPIO.IN, GPIO.PUD_UP)
unchanged_count = 0
last = -1
data = []
while True:
current = GPIO.input(dhtPin)
data.append(current)
if last != current:
unchanged_count = 0
last = current
else:
unchanged_count += 1
if unchanged_count > MAX_UNCHANGE_COUNT:
break
state = STATE_INIT_PULL_DOWN
lengths = []
current_length = 0
for current in data:
current_length += 1
if state == STATE_INIT_PULL_DOWN:
if current == GPIO.LOW:
state = STATE_INIT_PULL_UP
else:
continue
if state == STATE_INIT_PULL_UP:
if current == GPIO.HIGH:
state = STATE_DATA_FIRST_PULL_DOWN
else:
continue
if state == STATE_DATA_FIRST_PULL_DOWN:
if current == GPIO.LOW:
state = STATE_DATA_PULL_UP
else:
continue
if state == STATE_DATA_PULL_UP:
if current == GPIO.HIGH:
current_length = 0
state = STATE_DATA_PULL_DOWN
else:
continue
if state == STATE_DATA_PULL_DOWN:
if current == GPIO.LOW:
lengths.append(current_length)
state = STATE_DATA_PULL_UP
else:
continue
if len(lengths) != 40:
#print ("Data not good, skip")
return False
shortest_pull_up = min(lengths)
longest_pull_up = max(lengths)
halfway = (longest_pull_up + shortest_pull_up) / 2
bits = []
the_bytes = []
byte = 0
for length in lengths:
bit = 0
if length > halfway:
bit = 1
bits.append(bit)
#print ("bits: %s, length: %d" % (bits, len(bits)))
for i in range(0, len(bits)):
byte = byte << 1
if (bits[i]):
byte = byte | 1
else:
byte = byte | 0
if ((i + 1) % 8 == 0):
the_bytes.append(byte)
byte = 0
#print (the_bytes)
checksum = (the_bytes[0] + the_bytes[1] + the_bytes[2] + the_bytes[3]) & 0xFF
#if the_bytes[4] != checksum:
#print ("Data not good, skip")
#return False
return the_bytes[0], the_bytes[2]
def main():
while True:
humidity, temperature = readDht11()
if humidity is not None and temperature is not None:
print("Temp={0:0.1f}*C Humidity={1:0.1f}%".format(temperature, humidity))
# test for low temperature
if temperature < set_temp:
print(GPIO.output(relayPin, GPIO.LOW))
# test for high temperature
if temperature > (set_temp + 1):
print(GPIO.output(relayPin, GPIO.HIGH))
else:
print("Failed to retrieve data from humidity sensor")
time.sleep(5) #this is the time between taking readings and acting on them you can reduce it but not below 5 seconds
# Define a destroy function for clean up everything after
# the script finished
def setup():
LCD1602.init(0x27, 1) # init(slave address, background light)
LCD1602.write(0, 0, 'Temperature: %s C')
LCD1602.write(1, 1, 'humidity: %s %%')
time.sleep(2)
def destroy():
# set relay to off
GPIO.output(relayPin, GPIO.LOW)
# Release resource
GPIO.cleanup()
if __name__ == '__main__':
try:
setup()
except KeyboardInterrupt:
destroy()
as a note I haven't managed to get the LCD working in tandem but im more worried about the main functionality

Python - Thread copied duplicate

Am trying to do multithreading in my python app. I got main thread which creates sub-threads. However, for testing am only using 1 thread. The task that the thread must do is collect data and then store it in DB. But, I can see it stores it twice, after debugging I found that I get 2 threads instead of 1.
main program :
app = webApp.app
def main_program():
sleep(3)
while True:
Sensor.sensors.items()
def start_webApp():
bottle.run(app=app, host='0.0.0.0', port=8080, reloader=True, debug=True)
if __name__ == '__main__':
app_thread = threading.Thread(target=start_webApp).start()
s1_thread = threading.Thread(target=sensor_thread.start_sensor_reading, args=(14, SL.bedroom_1,), name="Sensor_1")
s1_thread.start()
main_program()
thread file
def start_sensor_reading(sensor_pin, sensor_location):
sleep(3)
global sensor, current, pulses, sensor_status
sensor = DigitalInputDevice(sensor_pin)
current = WFS.isIdle
pulses = 0
valve_open_time = 0
valve_close_time = 0
Sensor.sensors[sensor_location] = False
doc_ref = db.collection(sensor_location.value).document()
while True:
if current == WFS.isIdle:
print("idle")
if sensor.value == 1:
print("S IS OPENED")
current = WFS.isOpened
if pulses == 0:
valve_open_time = datetime.datetime.now()
if current == WFS.isOpened:
m, s = get_time_diff(valve_open_time)
if s > 30:
Sensor.sensors[sensor_location] = True
while sensor.value == 1:
print("S IS OPENED - Counting pulses")
pulses += sensor.value
current = WFS.isNoisy
if current == WFS.isNoisy:
print("S IN NOISE")
valve_close_time = datetime.datetime.now()
while sensor.value == 0:
print("S IN NOISE - checking if will close")
minutes, seconds = get_time_diff(valve_close_time)
if seconds > 3:
current = WFS.isClosed
break
if current == WFS.isClosed:
current = WFS.isIdle
sleep(10) <<< HERE IS THE PROBLEM - I do sleep 10 secs to see how many times it prints <<<<<<
print("S IS CLOSED - SAVING IN DB - SENSOR PIN : " + str(sensor_pin))
sleep(10)
m, s = get_time_diff(valve_open_time)
duration = str(m) + ":" + str(s)
liters = pulses / 450
doc_ref.set({
'Liters': liters,
'Started_At': valve_open_time,
'Stopped_At': valve_close_time,
'Duration': duration
})
pulses = 0
console output
S IN NOISE - checking if will close
S IN NOISE - checking if will close
S IS CLOSED - SAVING IN DB - SENSOR PIN : 14
S IS CLOSED - SAVING IN DB - SENSOR PIN : 14
idle
idle
idle
idle
As you can see I must get IS CLOSED printed once but it appears twice
Regards
I found that it was flask thread cousing the coping of the threads so I removed it then evrything was working fine.

Catching stdout and camera frames in realtime from subprocess

I have a wireless sensor node that transmits wirelessly to a receiver connected to my computer. I use this command to see the data in real time
sudo stdbuf -o0 ./pip_sense.v2 l l | stdbuf -o0 grep -P "TX:03(376|004)
I am new to Python, but I was able to develop a piece of code as show below to capture the stdout and takes frames from a camera connected to the same computer. That is when a packet (data) is received, at that timestamp, a frame will be captured.
It is working fine, except the fact that its running slow. I am running my sensor at a rate of 10 Hz (transmitting every 0.1 sec.) but the code does what is required at a slower rate. I know that is because I am using cv2.imwrite() (I commented out this part and that helped in reducing the delay). But also, as discussed in this post and its said (as I understand) that using shell=True can invoke extra shell process and thus increase the delay.
Also, looking at this, Popen() seems to be causing delays as well. A solution is proposed in the second link, but I do not really understand how to modify it to work for me.
#!/usr/bin/env python
from subprocess import Popen, PIPE
import time
import sys
import cv2
import os
import csv
import argparse
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from collections import OrderedDict
from datetime import datetime
PIP_CMD = 'sudo stdbuf -o0 ./pip_sense.v2 l l | stdbuf -o0 grep -P "TX:03(376|004)"'
def run(command):
process = Popen(command, stdout=PIPE, shell=True)
while True:
line = process.stdout.readline().rstrip()
if not line:
break
yield line
print ('Starting...')
def createFolder(directory):
try:
if not os.path.exists(directory):
os.makedirs(directory)
except OSError:
print ('Error: Creating directory. ' + directory)
createFolder('/home/piptag/pip-test/capture_webcam/EXPERIMENTS')
file1 = open('/home/piptag/pip-test/capture_webcam/EXPERIMENTS/3376.txt','w')
file1.write("Time Stamp \t TX ID \t RSSI \tSEQ NO \tCAP \tX-Axis \tY-Axis \tZ-Axis \t X \t Y \t Z \n") # Header line
file1.write("-------------------------------------------------------------------------------------------------------------------------------------\n")
file2 = open('/home/piptag/pip-test/capture_webcam/EXPERIMENTS/3004.txt','w')
file2.write("Time Stamp \t TX ID \t RSSI \tSEQ NO \tX-Axis \tY-Axis \tZ-Axis \t X \t Y \t Z \n") # Header line
file2.write("-------------------------------------------------------------------------------------------------------------------------------------\n")
dirname = "/home/piptag/pip-test/capture_webcam/EXPERIMENTS/"
def save_webcam(dirname):
cam = cv2.VideoCapture(-1) # was getting error (V4L: can't open camera by index 0), thus changes it to -1
jpg_quality = 75
frame_number = 0
if cam.isOpened():
ret_val, img = cam.read()
else:
ret_val = False
timestamp = int(TS)
path = dirname + str(tx) + str("-") + str(timestamp) + ".jpg"
cv2.imwrite(path, img, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])
frame_number = frame_number + 1
##this is the end of the camera program
def twos_comp(val, bits):
"""compute the 2's compliment of int value val"""
if (val & (1 << (bits - 1))) != 0: # if sign bit is set e.g., 8bit: 128-255
val = val - (1 << bits) # compute negative value
return val # return positive value as is
#########################################MAIN###################################
if __name__ == "__main__":
for line in run(PIP_CMD):
raw_data = line.split('\t')
if len(raw_data) > 1:
TS = raw_data[0][3:]
tx = raw_data[3].split(':')[-1]
rssi = float(raw_data[4][5:])
crc_ok = True if (raw_data[5] != b'BAD CRC') else False
no_drop = True if (raw_data[1] == b'Drop:0') else False
# If CRC check is ok and no drop, process the packet
if crc_ok and no_drop:
data = raw_data[-1].split(':')[-1].split()
cat = ""
for i in data:
cat += str(i)
if tx == '03376':
save_webcam(dirname)
print data
CapStatus=data[1]
if CapStatus == '50':
Cap='0'
elif CapStatus == '51':
Cap='1'
SEQNO1=str(int((data[2]),16))
x_axis1=data[3]+data[4]
y_axis1=data[5]+data[6]
z_axis1=data[7]+data[8]
TX1=tx
x1 = twos_comp(int(x_axis1,16), 16) * 0.0039 #* 9.80665 #the value is multiplied by 0.004 as the ADXL345 reports data as 4mg per 1lsb
y1 = twos_comp(int(y_axis1,16), 16) * 0.0039 #* 9.80665 #the value is multiplied by 0.004 as the ADXL345 reports data as 4mg per 1lsb
z1 = twos_comp(int(z_axis1,16), 16) * 0.0039 #* 9.80665 #the value is multiplied by 0.004 as the ADXL345 reports data as 4mg per 1lsb
st1 = str(TS) + "\t "+ "{:<5}".format(str (TX1)) + "\t" + "{:<10}".format(str (rssi)) + "{:<5}".format(SEQNO1) + "\t" + "{:<5}".format(str (Cap)) + "\t" + "{:<5}".format(str (x_axis1)) + "\t" + "{:<5}".format(str (y_axis1)) + "\t"+ "{:<5}".format(str(z_axis1)) + "\t" + "{:<5}".format(str(x1)) + "\t" + "{:<5}".format(str(y1)) + "\t" + "{:<5}".format(str(z1)) +"\n"
file1.write(st1)
elif tx == '03004':
save_webcam(dirname)
print data
SEQNO2=str(int((data[1]),16))
x_axis2=data[2]+data[3]
y_axis2=data[4]+data[5]
z_axis2=data[6]+data[7]
TX2=tx
x2 = twos_comp(int(x_axis2,16), 16) * 0.0039 #* 9.80665 #the value is multiplied by 0.004 as the ADXL345 reports dataas 4mg per 1lsb
y2 = twos_comp(int(y_axis2,16), 16) * 0.0039 #* 9.80665 #the value is multiplied by 0.004 as the ADXL345 reports data as 4mg per 1lsb
z2 = twos_comp(int(z_axis2,16), 16) * 0.0039 #* 9.80665 #the value is multiplied by 0.004 as the ADXL345 reports data as 4mg per 1lsb
st2 = str(TS) + "\t "+ "{:<5}".format(str (TX2)) +"\t "+ "{:<10}".format(str (rssi)) + "{:<5}".format(SEQNO2) + "\t" + "{:<5}".format(str (x_axis2)) + "\t"+ "{:<5}".format(str (y_axis2)) + "\t"+ "{:<5}".format(str(z_axis2))+ "\t"+"{:<5}".format(str(x2)) + "\t" + "{:<5}".format(str(y2))+ "\t"+ "{:<5}".format(str(z2)) +"\n"
file2.write(st2)
file1.close()
file2.close()
I appreciate any help
Thank you
Update:
I got this advice from a friend and it worked.
Calling the cam = cv2.VideoCapture(-1) outside the save_webcam function (as a global variable) reduced the delays a lot.
In this case, the camera will be turned on one time and then capturing images will be done each time save_webcam is called...hence, turning on and off the camera was slowing the process.
However, I would like to enhance the program more, as it get stuck sometimes. So, anyone understands what is in this post and how my stdout part should be modified, then please comment here. I appreciate this.

Testing multiple DS18B20 sensor cables

I'm really new to python and coding in general so i turn here for help. At work we need to test many cables with up to five DS18B20 sensors attached to them. We got this program and we've been using it for a while now to test cables with raspberry Pi. But there are few problems with it.
The program needs to detect the number of sensors attached and see if they're working, then list them by serial number lowest>highest (so we can warm them up, see which one gets highlighted, one by one and physically number them) and repeat.
It feels generally slow and crashes pretty often.
With the cables that have 5 sensors attached to them, it can find the sensors on max 2 cables(more if lucky), and when you attach 3rd cable it won't find them anymore or it will keep saying that there's 10 sensors attached. Rebooting the Pi fixes it but it takes time. Hot-swapping the cables is probably the main culprit here, but its the fastest way.
With 3 sensor cables you can check 4-5 of them until it hangs.
Any hints where the problem could be or how i could make things more efficient and faster are welcome.
Code:
import os,sys,time
import curses
stdscr = curses.initscr()
begin_x = 5; begin_y = 5
height = 40; width = 40
def temp_raw(sensor_str):
f = open(sensor_str, 'r')
lines = f.readlines()
f.close()
return lines
def read_temp(sensor_str):
lines = temp_raw(sensor_str)
while lines[0].strip()[-3:] != 'YES':
lines = temp_raw(sensor_str)
temp_output = lines[1].find('t')
if temp_output != -1:
temp_string = lines[1].strip()[temp_output+2:]
temp_c = float(temp_string) / 1000.0
return temp_c
init = 1
timer = 0
search = 1
curses.noecho()
curses.curs_set(0)
subdirectories = []
old_nbr_of_subdirs = 1
nbr_of_subdirs = 1
old_subdirectories = []
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
while (1):
timer = timer + 1
while search == 1:
stdscr.addstr(10,30, "Searching for sensors");
subdirectories = os.listdir("/sys/bus/w1/devices/");
nbr_of_subdirs = len(subdirectories);
time.sleep(3)
if nbr_of_subdirs > old_nbr_of_subdirs:
stdscr.addstr(10,30, "Found %d new sensors " % (nbr_of_subdirs-old_nbr_of_subdirs));
stdscr.addstr(11,30, "Is this all sensors? (y/n)?");
stdscr.refresh()
c = -1;
while(c == -1):
c = stdscr.getch();
if c == ord('y'):
stdscr.addstr(10,30, " ");
stdscr.addstr(11,30, " ");
stdscr.refresh()
old_nbr_of_subdirs = nbr_of_subdirs;
init = 1;
search = 0;
timer = 0;
else:
stdscr.addstr(10,51 + timer, ". ");
timer = timer + 1;
timer = timer % 4;
stdscr.refresh()
if init == 1:
init = 0
alive_ticker = 0;
temp_list = [];
sensor_oldtemp = [0,0,0,0,0,0];
sensor_temp = [0,0,0,0,0,0];
active_sensor = [0,0,0,0,0,0];
sensors = 0;
alive_ticker = 0;
active = 2;
confirm = 0;
stdscr.addstr(17,0, "Number of subdirectories %d" % (len(subdirectories)));
removed = 0;
index = 0;
length_old_subdirs = len(old_subdirectories);
while (index < length_old_subdirs):
length_old_subdirs = len(old_subdirectories);
if old_subdirectories[index] in subdirectories:
subdirectories.remove(old_subdirectories[index]);
removed += 1;
index += 1;
else:
old_subdirectories.remove(old_subdirectories[index]);
index = 0;
stdscr.addstr(30,20, "Removed %d" % (removed))
stdscr.addstr(18,0, "Number of CUT subdirectories %d" % (len(subdirectories)));
stdscr.addstr(19,0, "Number of old_subdirectories %d" % (len(old_subdirectories)));
stdscr.addstr(13,20, "Press space to confirm active sensor!");
stdscr.addstr(14,20, "Press r to reset!");
for index in range(len(subdirectories)):
if subdirectories[index].find("28") != -1:
temp_list.append("/sys/bus/w1/devices/"+subdirectories[index]+"/w1_slave");
sensor_temp[sensors] = 0;
sensors = sensors + 1;
old_subdirectories = old_subdirectories + subdirectories;
temp_list.sort();
if confirm == 1:
stdscr.addstr(13,20, "Press space to confirm active sensor!");
stdscr.addstr(14,20, "Press r to restart!");
curses.halfdelay(1);
c = stdscr.getch();
if c == 32:
confirm = 0;
timer = 10
for z in range(sensors):
if active_sensor[z] > active:
stdscr.addstr(z+5,20, " " , curses.A_DIM)
active_sensor[z] = 100
stdscr.refresh()
elif c == ord('n'):
init = 1
continue
elif c == ord('r'):
for z in range(sensors):
active_sensor[z] = 1;
if (timer > 9):
timer = 0
nbr_active_sensors = 0
for y in range(sensors):
if 99 > active_sensor[y]:
nbr_active_sensors = nbr_active_sensors + 1;
sensor_temp[y] = read_temp(temp_list[y]);
if ((sensor_oldtemp[y] + 0.1) < sensor_temp[y]):
active_sensor[y] = active_sensor[y] + 1;
sensor_oldtemp[y] = sensor_temp[y]
stdscr.addstr(3,5, "nbr_active_sensors=%d" % (nbr_active_sensors))
stdscr.addstr(4,5, "sensors=%d" % (sensors))
if nbr_active_sensors == 0:
search = 1
timer = 0;
continue
for x in range(sensors):
if (99 > active_sensor[x] and active_sensor[x] > active):
confirm = 1
stdscr.addstr(x+5,20, "Sensor %d value %4.2f ID:%s : %d " % (x+1, sensor_temp[x], temp_list[x][20:-9], active_sensor[x]), curses.A_STANDOUT)
elif active_sensor[x] <= active:
stdscr.addstr(x+5,20, "Sensor %d value %4.2f ID:%s : %d " % (x+1, sensor_temp[x], temp_list[x][20:-9], active_sensor[x]))
stdscr.refresh()
alive_ticker = alive_ticker + 1
stdscr.addstr(2, 55, "Alive ticker: %6d" % (alive_ticker))
Question: when you insert the 3rd cable (with 2-3 temp sensor on them) it just won't find any new sensors anymore.
If I recall properly there is a Limit of 2 Cable. Have you verified your Hardware supports more Cable?
I suggest to rewrite the Code and separate the Code into UI, Sensor and Wire Parts.
For instance:
class DS18B20(object):
...
def read(self):
...
class One_Wire(object):
def search(self):
print("Searching sensors")
...
def read(self):
print('Reading sensors')
for key in self.sensors:
self.sensors[key].read()
def refresh(self):
print("Refreshing sensors")
...
def history(self, alive=True):
print('Reading History')
...
Usage:
if __name__ == '__main__':
oWire = One_Wire()
oWire.search()
print(oWire)
oWire.refresh()
print(oWire)
oWire.read()
print(oWire)
history = oWire.history()
print(history)
Output:
Searching sensors
Sensors:5, active:5
id:i2c-0 CONNECT temp:None, id:i2c-3 CONNECT temp:None, id:i2c-1 CONNECT temp:None, id:i2c-5 CONNECT temp:None, id:i2c-6 CONNECT temp:None
Refreshing sensors
NEW Sensor:i2c-2
NEW Sensor:i2c-4
Sensors:7, active:6
id:i2c-0 CONNECT temp:None, id:i2c-2 CONNECT temp:None, id:i2c-3 CONNECT temp:None, id:i2c-1 disconnect temp:None, id:i2c-5 CONNECT temp:None, id:i2c-6 CONNECT temp:None, id:i2c-4 CONNECT temp:None
Reading sensors
Reading sensors
Reading sensors
Sensors:7, active:6
id:i2c-0 CONNECT temp:19, id:i2c-2 CONNECT temp:25, id:i2c-3 CONNECT temp:26, id:i2c-1 disconnect temp:None, id:i2c-5 CONNECT temp:25, id:i2c-6 CONNECT temp:18, id:i2c-4 CONNECT temp:30
Reading History
[{'i2c-0': [20, 27, 19]}, {'i2c-2': [30, 21, 25]}, {'i2c-3': [23, 29, 26]}, {'i2c-5': [30, 18, 25]}, {'i2c-6': [30, 21, 18]}, {'i2c-4': [24, 18, 30]}]

Calculating revolutions per minute in Python from an Arduino

I'm trying to calculate rpm's in python via a reed switch from the arduino.
i cant seem to get it right. can some one please help me get the code right.
my results are not consistent.
my problem is I'm trying to count the revolution per minute but I'm having issues with the minute part. the revolution counter works OK every time the reed switch is passed the count increases 1,2,3,4,5,6(etc). but, the rpm part witch is rev / ((time.time() - t)/60) gives me a result that keeps increases the value does not increase or decrease fast enough according to the speed of the revolution. so when when the reed switch is passed at 30 rev per minute it should reed out 30 RPM; when when the reed switch is passed at 90 rev per minute it should reed out 90 RPM. i know that i need to get a count of revolution for every minute, i guess its the ever minute part that i having a hard time programing.
thanks for helping me out this has been bothering me for months now.
import serial
import time
ser = serial.Serial('/dev/ttyACM0', 9600)
t = time.time()
a = ser.read()
rev = 0
while (a == ser.read()):
rev += 1
print rev / ((time.time() - t)/60)
New problem, now I'm trying to add two reed switches. i can get both to work separately, but when i go to pass the second reed switch i get script terminated. i now why I'm getting the script termination( one if true other is false terminate), but I'm not sure how to code it properly. the b'1' and b'2' is what is coming in from the arduino
my goal is to get both reeds to read at the same time.
import serial
import time
ser = serial.Serial('/dev/ttyACM0', 9600)
a = ser.read()
t0 = time.time()
while(a == ser.read()):
if a == b'2':
t1 = time.time()
try:
print(1 / ((t1-t0)/60))
except ZeroDivisionError:
pass
t0 = t1
if a == b'1':
t1 = time.time()
try:
print(1 / ((t1-t0)/60))
except ZeroDivisionError:
pass
t0 = t1
my none working code so you can get an idea of what I'm trying to do. if i could somehow break out the b'1' and b'2'. down below in the font object part you will see were m and r will need to go
import serial
import time
ser = serial.Serial('/dev/ttyACM0', 9600)
import pygame, sys
from pygame.locals import *
t0 = time.time()
pygame.init()
DISPLAYSURF = pygame.display.set_mode((400, 300))
pygame.display.set_caption('MPH!')
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
BLUE = (148, 228, 255)
BLACK = (0, 0, 0)
while True:
a = ser.read()
if a == b'2':
t1 = time.time()
try:
rpmm = (1 / ((t1-t0)/60))
m = str((7.065 *rpmm * 60)/5280).strip("\n,\r")
except ZeroDivisionError:
pass
t0 = t1
if a == b'1':
t1 = time.time()
try:
r = str((1 / ((t1-t0)/60))).strip("\n,\r")
except ZeroDivisionError:
pass
t0 = t1
fontObj = pygame.font.SysFont('digitaldream', 40)
textSurfaceObj = fontObj.render('MPH:'+m, True, BLUE, BLACK)
textRectObj = textSurfaceObj.get_rect()
textRectObj.center = (200, 150)
fontObj2 = pygame.font.SysFont('digitaldream', 40)
textSurfaceObj2 = fontObj2.render('RPM:'+r, True, BLUE, BLACK)
textRectObj2 = textSurfaceObj2.get_rect()
textRectObj2.center = (200, 200)
DISPLAYSURF.fill(BLACK)
DISPLAYSURF.blit(textSurfaceObj, textRectObj)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
For now, your code will output the average RPM since the reading started. If ser.read() returns one time for every rotation, you can do something like this to get the instantaneous rotation speed:
import serial
import time
ser = serial.Serial('/dev/ttyACM0', 9600)
a = ser.read()
t0 = time.time()
while(a == ser.read()):
t1 = time.time()
try:
print(1 / ((t1-t0)/60))
except ZeroDivisionError:
pass
t0 = t1
If you take a look at your new code, you should realize that the variable a is not assigned any new value during the while loop. You only check if ser.read() is equal to the value it had before you entered the for loop. This means that if ser.read() takes another value than what it had prior to entering the while loop, the statement a == ser.read() will be False.
This code will work for both values of ser.read().
import serial
import time
ser = serial.Serial('/dev/ttyACM0', 9600)
t0 = time.time()
while True:
a = ser.read()
if a == b'2' or a == b'1':
t1 = time.time()
try:
print(1 / ((t1-t0)/60))
except ZeroDivisionError:
pass
t0 = t1
else:
break
You may get a division by zero if your first read is too fast.

Categories

Resources