I have a very strange relay problem. I wrote a code to change LED state in RaspberryPi. before I purchased the 4-channel 5v relay board I used LED to indicate HIGH and LOW. That works perfectly fine, but once I connect the relay board it switch vigorously for about half a second, and then work inversely to the outputs, the outputs are generally low but the relays then stay at the normally open positions and switch over to normally closed once they get a high.
To make this more confusing, I connected the relays together with the LED's just to be sure, now the LED's still light up correctly and the relays still switch incorrectly
What bugs me though?
from gpiozero import LED
from time import sleep
red = LED(17)
while True:
red.on()
sleep(1)
red.off()
sleep(1)
(1) Ah, your relay module has a JD-Vcc jumper, so you need to cap/uncap the jumper and wire the Rpi 3V3 signal line and 3V3 or 5V power lines accordingly.
The JD-Vcc jumper setting is a a bit complicated.
You might like to read the following EE SE Q&A for more details on wiring the signal and power lines for JD-Vcc relay module:
How to properly use a relay module with a JD-VCC jumper for Raspberry Pi?
(2) Your "Status LED shows on but relay not switched on/off accordingly" might be related the common problem of "Relay always on but never off" or "Rpi's logical High signal is not High enough to switch off relay".
The reason is that Rpi High is only about 3V but not high enough as Arduino High which is specified as 4V. So the status LED misleadingly shows On status but relay not switched Off/On accordingly. (This confusing problem arises because the relay is originally designed for Arduino whose logical High is higher than Rpi High.)
Again this is complicated to explain by a couple of sentences.You might like to read the above EE SE Q&A (Especially Appendix B) for more details.
Related
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.
I have this digital dial indicator : Helios-Preisser Digimet 1722-502". It comes with a capacity to output its reading over a USB serial cable. The USB cable is a special 4 pin connector on the end that plugs into the calipers and a normal USB on the other end.
Although the device comes with special software, I am trying to write a basic python library to communicate with it. Below is the snippet of the manuel which explains the data communication protocol
I am using the python Serial library and have managed to get some communication going with it. Here's what I have so far
import serial
ser = serial.Serial(port ='/dev/tty.usbserial-MA4LOCLF', baudrate=4800,parity=serial.PARITY_EVEN, bytesize=serial.SEVENBITS,stopbits=serial.STOPBITS_TWO, dsrdtr=True, xonxoff=True)
# press the small red button on the cable. This generates a data entry
In [77]: ser.inWaiting()
Out[77]: 8
In [78]: ser.read(8)
Out[78]: '+000.00\r'
So this works great when using the mode the data is being requested by the pressing of the small red button on the cable plugged into the dial indicator
However, there is another mode where one can request a data entry. This is the mode described in the manual as "data transmission by request of peripheral" where one has to pulse the DataRequest pin low for T1 (100ms<T1<1000ms).
I have tried mostly randomly all possible combinations I could think to get this data request working but to no avail. All attempts at using the write function from the serial library have not worked
In [79]: ser.write('0\r')
Out[79]: 2
In [80]: ser.inWaiting()
Out[80]: 0
I am a bit out of ideas. I know this mode works because when you download (in Windows only) the software which comes with the device, you have the ability to send that request. SO there must be a way of emulating this request with the python serial library but I'm stuck and I'm not even sure how to proceed.
Any help would be appreciated.
Thanks
pyserial supports (or it should, but at the end of the day that would depend on the driver and not on pyserial itself) a function to change the state of the port's control lines.
You need to do something like this:
ser.setDTR(False)
time.sleep(0.5)
ser.setDTR(True)
If you read from the port right after you should get the value you are looking for.
To get the timing more or less right you should run your code as a script instead of line by line.
Ok, well after much "messing around", I was able to debug this problem and find the solution but it was certainly not a linear process. I should point out that I was placed on the right path thanks to the suggestions by Marcos G. who pointed out that you can indeed control the dtr lines directly with pyserial.
Here's the answer.
After some more searching the web, I found this link which provided a suggestion for how to troubleshoot your serial connection on a mac. This Coolterm software was immensely helpful.
I downloaded it and it allows you to monitor the state of the various RTS and DTS (and other) lines while you are communicating in a real time with you device. Super useful!
This showed me that:
When "sending" a reading from the device by pressing the red button, the DTR line was True and the RTS line was irrelevant. This is indeed what is shown in the documentation.
In order to "request" a reading from the device the DTR line needed to be False and the RTS line needed to be pulsed from False to True back to False with the precise timing. This worked and indeed produced a reading waiting on the USB line.
Here's the code below
import time
import serial
ser = serial.Serial(port ='/dev/tty.usbserial-MA4LOCLF', baudrate=4800,parity=serial.PARITY_EVEN, bytesize=serial.SEVENBITS,stopbits=serial.STOPBITS_TWO, dsrdtr=True)
ser.dtr=False
ser.rts=False
# request one reading every second
while(1):
ser.rts=True
time.sleep(0.1)
ser.rts=False
time.sleep(0.1)
print ser.read(ser.inWaiting())
time.sleep(1)
I am doing a project that involves using a Raspberry Pi to control all the switchboards in my house. I will start by wiring three switchboards first.
I am planning to use one 8-channel and one 2-channel relay for each of the switchboards, as each of these switchboards contain 10 switches. So, that amounts to 30 relay units.
However, I do not have as many as 30 free GPIO pins on my Raspberry Pi. I can use a port expander, but the Pi is installed with a camera and stationed near a door and fixed there. So, all the 30 wires from the switchboards need to be brought to the Pi, which will make the walls look messy. I was wondering if I could install an Arduino mini for each of the switchboards and control the relays using the Arduinos.
The Arduinos in that case need to the connected to the Raspberry Pi somehow such that when I want to switch on a specific light in my bedroom, I send a command to the Pi. The Pi sends the corresponding information to the Arduino in some well-defined format, like JSON, mentioning the switch number and the action to be performed. The Arduino switches on or off the switch and returns a message to the Pi.
Can this be done? I would be grateful if anyone could help me with this.
Thanks in advance.
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.
This question is as much related to software as it is related to hardware and I posted the similar question to electronic stack exchange for hardware part.
I have an instrument which writes its output to the okidata printer. My goal is to write it directly to the computer in some text-ASCII file. The pinout from the device is shown in the image below:
It is DB-25 with only 8 pin in use so I assume it is transmitting data serially. So I bought a null modem (crossover) cable with DB-25 female to DB-9 female converter and attached it to my serial port of my computer. One thing about the device is, it used to recognize whether printer is ready or not when it was plugged in the printer, thus I assume the printer had set one of the pin high if it was ready so that the device(instrument) knew that the printer was ready. If this logic should be followed, then I had to set one pin among these 8 pins to high.
I am just experimenting with pyserial and could not figure out and the device is saying that printer is not ready which means that it is not seeing one pin it wants to see high as high.
I tried setting serial RTS and DTR to false and toggled true but does not help.
Am I not understanding something here? Can somebody point me in how to approach this and replace the printer. I can also use arduino if required but I am not seeing how to for now.