I haven't found a useful answer to my problem from the many forums I've found. If you know one please comment a link below.
I have a Raspberry Pi Zero and an Arduino Fio w/ an Xbee module. I'm currently trying to do a simple test with the Zero and an Arduino Uno just to practice serial communication. I only need the Zero to receive data and not transmit, which is what several forums only direct towards. I want to take an integer from a compass heading (received by the Xbee from a beacon unit at some distance away).
So for my practice I send an integer on the Arduino using Serial.write(). On the Zero I simply use python and the library pyserial with the function serial.readline(). Also, yes, I've stepped the Arduino tx pin's voltage to 3.3 volts and I know the Zero is receiving a transmission. When I set the Arduino integer to say 39, the Zero will (with a print function) show the ASCII character corresponding to the hex value of 39 which is 9 (but it is a string not an integer).
In essence, my dilemma is I can't figure out how to convert the transmission to an integer that I can use trig with to make calculations. Firstly, I'm not sure if it's possible to make a fix on the Arduino side. Secondly, if it can be on the Zero, I'm not familiar enough with the pyserial library to know how to fix it. In addition to my second point, I've tried type casting it with int(string) to convert it to a string. I get an error code saying that the operation is invalid with an operator of base 10 (or something close to that).
I'm currently at my home and do not have access to my code on either the Arduino or Zero so please talk to me first instead of complaining 'show code'. I'm an experienced programmer and adept enough to talk through complications. Thank you.
Related
I have a Raspberry Pi 3B+ with an IC card reader that uses UART. The program is written in Python.
The data it receives is often wrong, but sometimes accurate.
There are 3 variations of the same card:
b'\\x02\\t\\x01\\xf4\\xec7\\xf6\\xd1\\x03'
HEX: f4ec37f6
DEC: 4109121526
b'\\x01\\x02\\x9d\\x85\\\\xfe'
HEX: 855cfe
DEC: 0008740094
b'\\x01\\x86\\x9d\\xc5\\\\xfe'
HEX: c55cfe
DEC: 0012934398
The first variation is the right one, which the card reader of my computer always reads the same result 4109121526, and it seldom appears on the RPI. For the other 2 variations, they always show up without a specific pattern.
The baud rate is 9600, I tried other rates, but it got even worse. The timeout is 0.5s, doesn't seem to matter.
Tried switching to a better power supply, nothing changed.
The store that sold me the reader told me to check the protocol and do data validation, but I have no idea what he's talking about. Is that related to the issue?
Got any idea? Thanks in advance!
I dont know why is this happening but am quite pissed off :-), because am struggling with this for two days now..
HW:
Arduino board --> Raspberry Model 2 B
Am sending one second impulse from arduino mega digital pin 8 to raspberry.
I added voltage divider so i have clean 3,25V impulse.
RSP reads most of impulses correctly but sometimes i get false readings.
E.g. one impulse is triggered and few are not or it starts to trigger impulses but I didn't send any from arduino side.
I try with pullup, pulldown setup but the problem is the same.
Maybe i should define that the "impulse" is value that last 1 second and everything else is "garbage" ?. If so, how to make this ?
CODE:
GPIO.setmode(GPIO.BCM)
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP)
#GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
...
GPIO.Cleanup()
The funny part is that if i test the impulse from RSP 3,3V pin, it works every time ( of course with pull_down setup ). So, what could be a problem ?
3,3V and 3,25 is no difference at all and RSP defines HIGH from 2.8 - 3.3V...
Any ideas ?
For me, it's more a matter of electronic.
In fact, for that kind of library, we can assume that the functions work correctly (I suppose that you wrote correct code that was built like that: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/robot/buttons_and_switches/).
I believe that the electronic problem can come from several sources:
Either your ground is badly connected (or it's not the same for the arduino and the rasperry pi). So, the reference tension isn't the same and a 0V for the arduino can be 1V for the raspberry pi.
It can also be a result of a bad interpretation of when your circuit is on and off. Don't forget that to put a plain 0V in the input of the raspberry pi (when the circuit is off). You need to explicitly write 0V at the output of the arduino (I mean: digitalWrite(ledPin, LOW);) otherwise your pin would not be "grounded" but "floating" and the tension can fluctuate from any value (close to 0) to another depending on environmental factors.
(to achieve it, you can also use pull down resistances, see: http://playground.arduino.cc/CommonTopics/PullUpDownResistor).
It can also be a transient phenomenon due to unwanted capacitive reactions. So, when your current changes quickly, the circuit cannot follow it instantaneously and it will produce some voltage glitches.
I suggest checking the two first points. If it cannot solve your problem, it should be related to the second point and you could handle it with capacitors and wait times.
I hope it will help :)
Thank you for replay. This are the test's that I made today.
- I have connected the zener diode to get the 3,3v and this part is good
- tested with different impulse lengths
None of them worked.
It's interesting, if i start the RSP script and if i just wait for impulse ( without triggering it ) i will get some 30 reading in few minutes. So it looks like that there is something going on.
I disabled this part of the code in arduino, but i still get this readings...
Btw. should i connect arduino and rsp GND together ?
E.
I am trying to connect the Black Swift with an display from Parallalax[1]. I have been reading lots of tutorials about that but with the displays being used on the tutorials there is always a difference to the pins on my display. The displays that are being used usually have lots of pins where you can choose the ones you need, but the display I have just has 3 pins (5V, GND, RX). Now I assume that with this RX pin I can control the display (like when I use lots of pins on other displays). But I dont know where to connect that RX pin on my Black Swift. The next thing is,
I have also read the manual on that display I have (the link I provided) but the examples they use there are all built up on some boards that are being sold on the website (for example nothing about how to connect a raspberry or arduino). When reading a tutorial everything seems pretty easy, but I guess I didnt choose my hardware wisely :(
Now my question, since I am new to this, is it possible to connect that display to some random microcontroller (in my case Black Swift) ? If yes, where should I connect that RX pin? What is this RX pin doing, (didnt find anything in the manual about that)? Since they are using some special way (PBasic?) to control the display (is inside the manual), is it be possible to control the display with pythong?
Thanks for the help
EDIT:
So far I have managed to turn on/off the UART mode, and it seems that this is not the issue bcz I am getting same results (weired characters on te display).
[1] https://www.parallax.com/sites/default/files/downloads/27979-Parallax-Serial-LCDs-Product-Guide-v3.1.pdf
The linked PDF tells the story pretty conclusively. You need a UART from your controller with the matching bps-rate as set up by the DIP-switches.
Following http://www.black-swift.com/wiki/index.php/File:BlackSwift-1.0-pinout.png you should connect GPIO10/UART_TX to the RX, and then program your uC in whatever language it supports.
I have been attempting to have a Raspberry Pi interface with an embedded circuit using the UART interface. The UART interface on the Pi is in working order and I can receive messages from the circuit, though I am having trouble sending messages to the circuit.
I am using Python 3.3 with Pyserial 2.7. Sample code is available, though it uses Pyserial 2.6. When used with older versions of Python (<2.6), ser.write() accepts strings, but now it only accepts bytearrays.
The problem I am having is in sending carriage returns... The old code supposedly functioned with just:
ser.write("L1\r")
but now I am using the following:
ser.write(bytearray("L1\r", "ascii"))
The circuit does not respond to the command. I think the resultant message is sending \r as two individual characters rather than a carriage return. How would I make sure my code is outputting commands appended with carriage returns?
Notes: I can reasonably expect that the circuit is working well and that the Pi's UART interface is functional. The circuit is an Atlas Scientific Dissolved Oxygen Circuit. The circuit's documentation demands that commands be written in the form l1<cr> or L1<CR>.
Relevant links:
Old sample code (https://www.atlas-scientific.com/_files/code/pi_sample_code.pdf)
Documentation describing write method (http://pyserial.sourceforge.net/pyserial_api.html#classes)
Thanks in advance!
EDIT: Netch makes a strong point: ser.write(b'L1\r') works and is much cleaner. Both methods, however, ARE sending a correct '\r' sequence.. The problem is that the circuit still does not regard L1\r as a valid command. At this point, I think my issue may be some property of my serial port.
My port is declared as such:
ser = serial.Serial(
port = '/dev/ttyAMA0',
baudrate = 38400,
bytesize = serial.EIGHTBITS,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE,
timeout = 1
)
This port declaration is done with accordance to the circuit's datasheet (I can only post two links unfortunately :( Google brings it up easily).
[EDIT] For future viewers, I just want to point out that for the newer EZO version of the circuit, the command is "L,1" or really "L,1\r"
[/EDIT]
This is a known issue with the circuit. The first read after power up will fail. instead of prepending a \r with every read, just send a bogus command with \r included and then reset input buffer
ser.write('bogus\r'.encode()) # EDIT: had to add .encode() to get it to work. see https://stackoverflow.com/questions/22275079/pyserial-write-wont-take-my-string
ser.flushInput() # or for pyserial 3+ ser.reset_input_buffer()
#now do your thing
EDIT: had to add .encode() to get it to work. see pySerial write() won't take my string
After powering up the EZO™ class circuit when it is in UART mode the
first command sent to it will comeback as an error. This is because
the UART buffer will show that it has received a character during
power up. Simply send a blank character to the pH circuit after it is
powered up, this will clear the buffer.
I have found a solution!! Unfortunately, I cannot explain how it works. Perhaps anyone reading this could elaborate on it and give a proper explanation!
The circuit's documentation demands commands be in the form CMD<CR>. Indeed, sample code provided by the manufacturer sends the L1 command through pyserial as ser.write("L1\r").
Now that ser.write() demands bytes however, I have found that ser.write(b'L1\r') does not work.. The command is received though it is somehow unknown to the circuit.
After toying around for a while, I have discovered that ser.write(b'\rL1\r') works! The debugging led flashes red once before processing the command. It seems like I just need to send a 'dummy command' to get the circuit's attention!
I am not sure if this is the fault of pyserial, the circuit, or my own ignorance. If anyone can shed some light on this, it would be much appreciated! :D
I have linked here the circuits documentation in case anyone is interested. https://www.atlas-scientific.com/_files/_datasheets/_circuit/DO_Circuit_5.0.pdf
Say I have the following python script to read in serial data from my Arduino:
import serial
ser = serial.Serial("dev/ttyACM1", 9600)
ser.timeout = 2
ser.readlines()
On the other end I've flashed my Arduino with a program that sends 20 voltage readings every 0.5 seconds. The Arduino starts sending those readings from the moment it's hooked up, then after 20 seconds it stops and sends nothing.
Now what I've noticed is that I can read those 20 voltage values using the first script whenever I want. That is, I can hook up the Arduino, wait a couple of minutes then read in the values. This makes me think that the data is getting stored somewhere. I'm inclined to think that it's not being stored on the Arduino but on my laptop somewhere.
I've come up with a few questions that I hope the community could help me with:
Where is PySerial getting the data from (the Arduino or some buffer on my laptop)?
For how long is the data stored in this place?
Is there a way to clear this space before reading in values?
How much storage space is there?
When you set the baud rate in PySerial (second line in script), is this the rate that
PySerial reads data from the storage area (not the Arduino)?
I've noticed that if I set the baud rate in PySerial too high the first few lines of data are fragmented and sometimes completely wrong, why?
Not exactly related but when you set serial.Serial.timeout are the
units in seconds?
I appreciate your time.
Have you tried using a terminal program like TerraTerm (windows) or GTKTerm (linux) to open the same port to the arduino? I think this would be helpful to answer some of your questions.
Some quick answers to your questions that I can dump off the top of my head.
From the port specified, I'm guessing you are asking something deeper than this?
If you do a
x = ser.readlines()
then the data will be in x as long as you'd like.
There is a flush function defined in PySerial
Not sure. You can specify how many characters you would like to read though
example:
x = ser.read(number)
The pyserial documentation states the following
Read size bytes from the serial port. If a timeout is set it may return less characters as requested. With no timeout it will block until the requested number of bytes is read.
http://pyserial.sourceforge.net/pyserial_api.html
This is the clock rate of the port you are opening, ie /dev/ttyACM1, most serial comms are at 9600, if you happen to be using a USB to serial you'll need 115200
Clock rate mismatch. You're computer is sampling data at a rate higher than the arduino is providing it, causing it to be incorrectly displayed.
Seconds, quote from Pyserial documentation : "timeout = x: set timeout to x seconds (float allowed)" Same link as number 4
Hope that helps some!