I am currently trying to write a python (2.7) script based around the GPSd library to provide GPS speed data at an update rate of 10Hz using the adafruit Ultimate GPS raspberry Pi Hat (https://www.adafruit.com/product/2324) with time stamps also reported at 0.1s.
The module itself is capable of up to 10Hz update rates however defaults to 1 Hz when set up and currently I cannot successfully increase it. I've have tried issuing PMTK commands (https://cdn-shop.adafruit.com/datasheets/PMTK_A11.pdf) to increase the update rate however cannot get this to work (PMTK220) and have included setting the baudrate to the maximum value of 115200.
I've searched all over for a method of getting the update rate output to increase however cannot see where the issue lies. The code below and prints out responses at a rate faster than 10 Hz however the values are only being updated every 1s.
import os
import serial
from gps import *
import datetime
import time
import threading
import subprocess
#### CURRENTLY TRYING TO INCREASE GPS POLLING UPDATE RATE FROM DEFAULT 1Hz to 10Hz
subprocess.call(["stty","-F","/dev/serial0","raw","115200","cs8","clocal","-cstopb"])
subprocess.call(["sudo","systemctl","stop","gpsd.socket"])
subprocess.call(["sudo","systemctl","disable","gpsd.socket"])
subprocess.call(["sudo","gpsd","/dev/ttyS0","-F","/var/run/gpsd.sock"])
subprocess.call(["echo","-e","$PMTK251,115200*27\r\n","/dev/ttyS0"]) # command to set baudrate of serial port
subprocess.call(["echo","-e","$PMTK220,100*2F\r\n","/dev/ttyS0"]) #command to set GPS Update Rate
gpsd = None #seting the global variable
os.system('clear') #clear the terminal (optional)
class GpsPoller(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
global gpsd #bring it in scope
gpsd = gps(mode=WATCH_ENABLE) #starting the stream of info
self.current_value = None
self.running = True #setting the thread running to true
def run(self):
global gpsd
while gpsp.running:
gpsd.next() #this will continue to loop and grab EACH set of gpsd info to clear the buffer
gpsp = GpsPoller() # create the thread
gpsp.start() # start it up
os.system('clear')
x = 0
while x < 20: # infinite loop- use ctrl + c to end
print gpsd.utc # print timestamp
print gpsd.fix.speed # print gps speed
print '-----------------'
time.sleep(0.025) # Set print rate much higher than maximum possible of 10 Hz update rate
Probably a little late for this, but the module is set to a 9600 rate by default, iirc. Try setting the baud to 9600 on the Pi first then send the $PMTK251,115200 line. Now change the rate on the Pi to 115200 & send the 10hz part ($PMTK220,100*2F\r\n)
Related
Hi everybody, I need help with following problem please:
I try to drive a Dimension Engineering Kangaroo/Sabertooth motor controller from a Python script using pyserial.
Everything works so far except that the motor output stops after some time and the USB/serial connection becomes 'unresponsive'. The faster the rate at which the serial commands are sent, the quicker this happens.
This is how I initialize the serial connection:
# open serial port
Saber = serial.Serial("COM1", 19200, timeout=1, write_timeout=0)
# starting the motor
Saber.write("1,start\r".encode("gbk"))
Then the position commands are sent using a loop:
while True:
pos = 2000 # just an example, the script calculates a new required position every iteration
command = "1,p" + str(pos) + "s500\r"
Saber.write(command.encode("gbk"))
time.sleep(.1) # the lower this break, the faster the device becomes unresponsive...?
After the device stops, I have to disconnect it / power it down, to be able to open a serial connection again.
Could it be that some sort of buffer gets filled and 'locks' the port?
I have tried to free the read/write buffers using:
Saber.reset_input_buffer()
Saber.reset_output_buffer()
But that does not solve the problem :/ Any help is greatly apprechiated! Thanks!
I'm trying to create an application that will sense my laundry machine turning on. Then when it's done, i want it to detect that and flash my Hue bulbs. I'm using the SW-420 vibration sensor and Python for this project. I have successfully gotten it to recognize vibration, but unfortunately, it's not what I need. The following is my current code.
#!/usr/bin/python
import RPi.GPIO as GPIO
import time
import subprocess
#GPIO SETUP
channel = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(channel, GPIO.IN)
def start(channel):
if GPIO.input(channel):
print "Dryer has started!"
time.sleep(1)
else:
print "Dryer has stopped"
time.sleep(1)
#f = open("status", "w") #Used to create light status file
#subprocess.call(["perl", "/home/pi/huepi/huepi", "lights"], stdout=f); # creates status file
#subprocess.call(["perl", "/home/pi/huepi/huepi", "for", "1 3 4 5 6 10 11 12", "do", "blinkonce"]); # blinks hue bulbs
GPIO.add_event_detect(channel, GPIO.BOTH, bouncetime=300) # let us know when the pin goes HIGH or LOW
GPIO.add_event_callback(channel, start) # assign function to GPIO PIN, Run function on change
# infinite loop
while True:
time.sleep(1)
The issue that I'm having is even when the machine is running the sensor registers that it has stopped. I've tried using
GPIO.add_event_detect(channel, GPIO.RISING, bouncetime=300)
and
GPIO.add_event_detect(channel, GPIO.FALLING, bouncetime=300)
both with the same results. I just need it to register that the machine has started then with it stops flash the Hue bulb and wait for the next time the machine starts back up.
I'm using a Perl library called Huepl to interface with but bulbs That section of the code is working fine. If you need any more information I'll be glad to supply. Thank you in advance!
Set started via callback on your first detected vibration. Set a lastShakeTime to now via callback whenever you detect vibration.
In your main loop check if nothing was detected for 60s:
import datetime
# infinite loop
while True:
time.sleep(1)
now = datetime.datetime.now()
if started and (now - lastShakeTime).total_seconds() > 60:
# do something with your oleds
Polling vs. Eventbased:
https://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/
I'm working with t-type thermocouple and needs to read the temperature data using python on Raspberry Pi 3. I used Adafruit MAX31856 to connect the thermocouple to the Pi and and tried to read it using this module.
I want to read the temperature for an extended period of time so I tried to print it out in a while loop However, anytime I run my code, I only get few 'correct' readings then the temperature resets to 0 until I re-run the code again - see the attached image.
I don't know what is causing this, and I don't think this is a connection problem since it prints the correct temperature when I re-run the code without touching the set-up.
Does anyone know why the reading is resetting to 0?
Here is my code:
from Adafruit_MAX31856 import MAX31856
import time
# Raspberry Pi software SPI configuration.
CLK = 4
CS = 22
DO = 17
DI = 27
sensor = MAX31856(clk=CLK, cs=CS, do=DO, di=DI)
while True:
temp = sensor.readTempC()
print('Thermocouple Temperature: {0:0.3F}*C'.format(temp))
time.sleep(1.0)
Try resetting sensor by putting sensor = MAX31856(clk=CLK, cs=CS, do=DO, di=DI) in the while loop.
this is the simple code to measure distance using ultrasoinic sensor attached to reapberry-pi and by writing python script--
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
TRIG = 16
ECHO = 20
print "Distance Measurement In Progress"
GPIO.setup(TRIG,GPIO.OUT)
GPIO.setup(ECHO,GPIO.IN)
while True:
GPIO.output(TRIG, False)
print "Waiting For Sensor To Settle"
time.sleep(2)
GPIO.output(TRIG, True)
time.sleep(0.00001)
GPIO.output(TRIG, False)
while GPIO.input(ECHO)==0:
pulse_start = time.time()
while GPIO.input(ECHO)==1:
pulse_end = time.time()
pulse_duration = pulse_end - pulse_start
distance = pulse_duration * 17150
distance = round(distance, 2)
print "Distance:",distance,"cm"
use case is- I have to run this script only when all the pins of ultrasonic sensor is properly connected to the circuit and the raspberry-pi. so my question is, can we identify the pin connection before running the script? or can we identify whether our hardware is working properly or not?
With the trigger/echo style of interfacing, could you use a pull-up to make the echo input from the ranger be (permanently) at the 1 level when the sensor isn't fitted? In your code this line appears to be 0 during ranging and go to 1 when the echo is detected. Then the initialization code simply checks for the echo input being stuck at 1 to determine that the ranger isn't fitted. You'll need a pull-up or pull-down on that line anyway to ensure it has a valid level when the device isn't attached.
Perhaps connecting the trigger output pin to the echo input pin using a high-value (100k?) resistor (and no pullup on the echo pin) would be better - the initialization then is to waggle the trigger pin around and check for the echo pin quickly changing to the same level. If it doesn't change so quickly the ultrasonic ranger is probably attached.
A possibly more robust approach would be to use an ultrasonic sensor like the US-100 for example see http://www.ebay.co.uk/itm/US-100-Ultrasonic-Sensor-Module-Temperature-Compensation-Range-for-Arduino-K6-/291843077304?hash=item43f333f4b8:g:vgkAAOSwFnFV-7Fx which has a jumper to select serial output, sent every 100ms. Using the serial interface you know if the device is/isn't fitted simply from presence/absence of data on the serial port.
I am trying to have a script which I trigger via cron to turn a pin low and high based on a temperature, however.. I have having a couple of problems.
1 - When the script starts and it setsup the GPIO pin, it will either pull the pin high or low (depending on paramater) - there doesn't appear to be a way to tell it not to change the current state of the pin.
This is a problem because if the relay is high and the default state is low then the relay will be set low and then could change to high again very quickly after - doing this every minute is pretty hard on what the pin is controlling (same applies if the default state is high).
2 - When the script exits it cleans up the GPIO pins and changes the state of my pin. Ideally if the script turns the pin high then when it exits I want the pin to remain high. If I remove the cleanup function then the next time the script runs it says that the pin was already in use (problem?).
So the script which runs every minute looks like this.
#!/usr/bin/python
import RPi.GPIO as GPIO
import time
import random
from temp import Temp # custom object to handle the temp sensor.
def main():
random.seed()
GPIO.setmode(GPIO.BCM)
PUMP_ON_TEMP = 38
PUMP_OFF_TEMP = 30
GPIO_PIN = 18
try:
t = Temp('28-00000168c492')
GPIO.setup(GPIO_PIN, GPIO.OUT)
current_temp = t.getTemp()
print current_temp
if current_temp > PUMP_ON_TEMP:
GPIO.output(GPIO_PIN, 1)
print "Turning the pump on! %s" % current_temp
if current_temp < PUMP_OFF_TEMP:
GPIO.output(GPIO_PIN, 0)
print "Turning the pump off! %s" % current_temp
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
if __name__ == '__main__':
main()
This run every minute via cron. I don't want to use a loop.
I have tried to read the pin as an input first to get current hight/low state but that throws an error saying the pin needs to be setup first....