433MHz Sender and Receiver in Python on Raspberry PI - python

Is there any way to get a working 433MHz-Sender or -Receiver in a Python Thread?
I have tried those from Ninjablocks and those from Adafruit. But the Problem is that these are all c or c++ scripts, that are outputting to stdout and have no end of the output. I also tried piping them through a Unix-FIFO but there no data is transmitted until I close the Program (Ctrl + C) the second problem is, that the finished programs doesn't recognize my ninjablocks 433MHz Temperature Sensor, that is one of the most important parts of the system.
The 433 MHz Sender/Receiver are connected with the GPIOs of my Raspberry PI (Version B, Rev 2.0)
My Goal is to get the several 433 MHz Sensors (And some sonsors connected via i2c or spi these are already working) working with a python script, that does calculate some Rules (e.g. When Motion detected in Living Room, and between Sunset and Sunrise, turn Light on; Turn on Heating when Temperature Drops below 20°C etc.)
I have written a small program:
import RPi.GPIO as io
data = [] * 10000
while not interrupted:
data.append(io.input(rxPin))
io.wait_for_edge(rxPin, io.BOTH
I expected that code to output something like 1010101010101 because every Edge is recognized. My next step would have been to measure time between the edges and - based on that time - decide if it was a short 1/0 or a long 1/0 (433MHz seems to be encoded like short 1 long = = 1 long 1 short 0 = 0 or vise versa) but the output was something like:0110011001000000010110010 etc. so the python thread is missing some 1s and 0s, I think.
has anybody an idea to get that Wireless input in my Program?

If you are running python I guess you are using some kind of linux on the Raspberry Pi, am I right?
Linux is not real time os, meaning your python loop does not run all the the time and can skip some GPIO data. You can solve it by either using a real time os like Chibios or use kernel module to stop all interrupts and sample the GPIO continuously as demonstrated in the Panalyzer project.

Related

Creating custom protocol with Raspberry Pi 4

Hello and thank you for reading. As a hobby project I thought it would be fun to try and create my own communication protocol. I am trying to use the GPIO-pins on my Raspberry Pi 4 to send a digital signal. The reason for using a Raspberry Pi is because I want to connect it to a webpage that I want to run on the Pi. I am using Python with the RPi.GPIO library to control the pins. I am very much at the start of this project but I already ran into a problem.
When sending pulses for my signal I get a strange offset when going for higher speeds. See the code below:
import RPi.GPIO as GPIO
import time
pin = 18 # select pin
pulse_time = 1/100 # set lenght of pulse
GPIO.setmode(GPIO.BOARD)
GPIO.setup(pin, GPIO.OUT)
GPIO.output(pin, GPIO.HIGH) # set pin high
time.sleep(pulse_time) # wait
GPIO.output(pin, GPIO.LOW) # set pin low
time.sleep(pulse_time)
GPIO.output(pin, GPIO.HIGH)
time.sleep(pulse_time)
GPIO.cleanup()
In the variable "pulse_time" I set the wait time for the pulses. In this case I am trying to send bits with a speed of 100 bits per second. Which would be 1 bit per 10 milliseconds. See the image below for the data signal (sorry for bad quality, my oscilloscope doesn't have a USB-port for screenshots).
In the image above you can see the 2 pulses I send with my Python code. The first pulse is exactly 10ms long, just as I wanted, but the second pulse already gets a slight offset. When changing the bps to 1000 instead of 100, the offset gets a lot worse. For my project I intend to use a bitrate of 2400 bps.
I also tried doing the same things using C++ instead of Python, since C++ is generally faster/better at controlling hardware. Sadly the GPIO library 'wiringPi' for C++ got deleted and I can't find another way to control the GPIO-pins using C++.
Now that I explained the situation I have the following questions:
Can I set a clock speed in Python for controlling the pins at a set speed? If so, what is the max bps I could reach?
Is there a new way to control the GPIO-pins using C++ instead of Python?
Am I an idiot for trying to do this on a Raspberry Pi and should I use something else?
Any advice would be appreciated. Thank you in advance for taking the time to answer any of my questions.
I think this offset could come from the time it takes to run GPIO.output(pin, GPIO.HIGH).
You could improve this by measuring this execution time and condier it in the time.sleep(...). (e.g. time.sleep(pulse_time - some_gpio_time)
Have a look at timeit to measure the time experimentally or you could try to measure it on the fly and consider it in the consecutive sleep.
But keep in mind, that an applicaiton like that is not intented to fulfill hard realtime requirements and you will always get some error. To achieve better timing you would need to implement this as a linux kernel module, but this might go a bit too far for a hobby project.

How to parse specific data from a serial input on a Raspberry Pi?

I am using a GPS module for precise positioning. It's going to be autonomous and we need to make a fail-safe in case the GPS loses its rtk fix.
To do that, I am employing a Raspberry Pi 4b connected via UART to the GPS module. The GPS sends a message, GNGGA, where one of the parameters informs the status of the fix, then the Raspberry Pi monitors these parameters and keeps checking if the fix type stays as rtk fixed and sends an alert if not.
So far I have the code below that connects the Raspberry Pi to the module
#!/usr/bin/env python
import time
import serial
ser=serial.Serial(
port='/dev/serial/serial01'
baudrate=460800
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
counter=0
while 1:
x=ser.readline()
If I print x, I get something like this:
�6ȶ< �>�r�%���a���5��PFpx���� zR�b�qI��#ǃy�v����$p���`X�w�?Ĉ*�����>��G;
A���
O���������r[���nlB>X$GNGGA,202538.90,2156.26451,S,04753.49406,W,1,12,0.52,751.9,M,-6.2,M,,*53
The unreadable part of the code is some other messages the GPS needs, while the readable part is the part I want to extract.
I believe I know the logic behind what needs to be done: I need to recognize the start of this string, and since the size of this is fixed, I should be able to use its length to extract the whole string or just the parameter I need.
I don't have much experience dealing with serial communication with python so I don't know how to employ this logic. After a few hours of trial and error, I managed to find the start of the string with a few if's, but I don't how to go from here.
Can anyone give some advice?

Reading synchronised data from 2 serial USB ports concurrently in Python. Threading? Multiprocessing?

I'm building an autonomous rover controlled by a Raspberry Pi using RTK GPS navigation. I am using two separate U-Blox RTK GPS modules on the rover operating at 4Hz to get very accurate position and heading calculations and they are both connected to the Pi through USB ports. I'm using the pyserial library to read the NMAE sentences as they are output through USB. The problem I have encountered is that the serial data sent by each module is precisely synchronised and so while calling Serial.readline() for one port, the data sent to the other port is missed.
The basics of the code currently looks something like this:
`class GPS():
def __init__(self,port,baud):
self.gpsSerial = serial.Serial(port,baud)
# init some variables
return
def read(self):
NMEASentance = str(self.gpsSerial.readline())
if NMEASentance not what_i_wanted_or_blank:
return 0
# do some processing, update vars
return 1
frontGps = GPS(port1,baud)
rearGps = GPS(port2,baud)
while True:
if frontGps.read():
# grab the new data
if rearGps.read():
# grab the new data
What ends up happening is that while one serial port is being read and the data processed, the other is transmitting simultaneously and is missed. I have tried doing both reads one after the other and leaving the processing for later, but the problem persists.
How do i read both ports simultaneously? Will threading each serial read work (they will both still be running in the same process, and so won't be executed concurrently, right?)
If the solution is multiprocessing then could someone please post some skeleton code for me to follow because this problem is really doing my head in.
Thanks for any help!
Would love to get some code on this:
Set up two processes to read from the serial ports and add them to a shared queue
I have a GPS serial loop running and need to add a second serial link for a magnetometer and needed a way to keep the two streams separate
Currently, working with a Neo6M GPS and noticed that the #GPRMC message is like a heartbeat that is transmitted once a second on each UTC second tick.
The #GPRMC is the GPS standard sentence that transmits UTC time/date
(and location, speed and heading) so it makes sense that it would be transmitted at UTC second = 00.00
After reading about the problem it occurred to me that all the GPS receivers are probably doing the same. So if you have any number of them powered up, they will all be synchronized.
If my theory is correct:
Armies of GPS-enabled pi soldier robots could be made to walk in step even though they are continents apart.

Remote connection between Raspberry pi and other computer through python over internet on real time

I want a help in robotics stuff..
My Question is ... :
How to connect my robotic car ( car is having raspberry pi as controller) with my computer via internet .. so the I can control the car from my computer's keybord..
Previously i was using VNC and made a python tkinter script (stored at raspberry pi) and by the help of vnc i control the car but it was not good ..
Most of the time the when i press the key, function works after sometime and worst thing was that it stores all the commands in a queue or buffer ..
So realtime operation was not happenping ( like: if i press forward arrow key for 2 seconds, it evoked moveForward() 20 times which is equal to 2 meters forward move and takes 4 seconds to travel .. BUT after that if i press right arrow key then it evokes moveRight() .. the worst part is it will execute after finishing the moveForward() stored in a queue i.e after 4 seconds .. and not on real time)
Is there any way to control/give command to raspberry pi on real time and not in a queue manner via socketing or other thing ?
note : i have a static ip address with specific port open and it has to be done over internet.
The appearance of your car might mainly relate to the whole system response time. The Raspberry Pi may be not fast enough. If there is no necessary, analog signal may on real time.

Python Serial Communication Using HC-05 Connected to OS X Version 10.11.1 (15B42)

this is my first post on stack overflow yet I use it all the time to solve my many programming issues. So first off, thank you for any help that is given.
I have been given a task by my advisor to get HC-05 sending and receiving serial comms with python and I am at my wits end on the final part of getting it up and running. I have searched everything I possibly can and have not yet found the answer, or even a similar issue. I have the comms working somewhat well. My baud rate is set at 115200 and have that matched in python serial. I am using an Arduino to gather values from sensors on a robot, send the values to python over serial to run calculations then have the result send back. I am sending two values and only receiving one. I first got it up and running by using serial comms over usb cable and it works perfect. I then made a few alterations to get it sending over bluetooth. The data that is being sent from the Arduino through bluetooth is perfect. When I do calculations and send the result back, however, the values are off. I have a timer Interrupt Service Routine (ISR) running on the Arduino that sends the values at 100Hz. If I slow that down to 10Hz, the response from computer to Arduino gets better and if I slow it down to 1HZ it is perfect. Unfortunately, I really need it to be working well at 100Hz for accurate control of my robot. I have included a link below of a plot of the response at 10Hz. Alpha and Theta are values sent from Arduino, V is a calculation done by python and V_echo is V being sent to Arduino, multiplied by 2 and sent back to python. As you can see, V_echo is broken and jagged when it should be a smooth line like the others. All of this tells me that while the send rate of the HC-05 is fine, the receive rate is too slow. I have changed baud rate possibilities, played with making the HC-05 a master vs. slave and slave-loop... slave works the best. The last thing I can think of is using stop bits. I have pyserial sending two stop bits and have the HC=05 stop bit set to two by using AT+UART=115200,1,0. If stop bits are my solution, I clearly have it set up wrong. I don't know exactly what python does when I include stop bits and furthermore I don't know if I need to do any program that reads the bit or if the HC-05 just understands it... If stop bits are not my answer, I look forward to finding out what is. Thanks again.

Categories

Resources