arduino read in pyfirmata gives output as none - python

I wrote a basic code for reading values from analog pin 0(I have a light sensor attached to it and the output is coming at analog pin 0) in python3 using pyfirmata, but it is giving the output as none no matter what. I tried the same code in arduino IDE and that is giving the right answer. Please help.
Code is :
from pyfirmata import Arduino, util
import time
board = Arduino('/dev/cu.usbmodem1411')
it = util.Iterator(board)
it.start()
board.analog[0].enable_reporting()
while True :
print (board.analog[0].read())
time.sleep(1)
Even when it gives an output after few seconds, it gives 0.29 which isn't actually the sensor value that comes on serial monitor. That value varies between 0 and 1023 and is relatively quite larger than this.

The analog pins of Arduino linearly translate the input voltages between 0 and +5V to 0
and 1023. However, in pyFirmata , the values between 0 and +5V are linearly translated
into the float values of 0 and 1.0. For example, if the voltage at the analog pin is 1V, an
Arduino program will measure a value somewhere around 204, but you will receive the
float value as 0.2 while using pyFirmata’s read() method in Python.

You'll need to start an Iterator thread before reading
board = pyfirmata.Arduino("COM5") # change com port
board.digital[3].mode = pyfirmata.INPUT
it = pyfirmata.util.Iterator(board)
it.start()
board.digital[3].read()
Most of the time it work, but sometimes None still show up. Sometimes time.sleep can help.

You have to do an if conditional first, something like this (and try running analogfirmata):
while True:
if board.analog[0].read() == None:
pass
else:
print("board.analog[0].read()")

Related

Arduino pyfirmata analog reading problems

I am having some problems reading analog values from my Arduino Mega using pyfirmata.
I use Arduino Mega with a Mega Sensor Shield.
I would like to read analog values from a HW-201 IR sensor (pin A5).
I have uploaded the Standard firmata sketch on Arduino IDE, and I am running the following code using Anaconda Spyder:
import serial
import serial.tools.list_ports
from pyfirmata import ArduinoMega, util
from time import sleep
def readArduinoPort():
COM = []
ports = list(serial.tools.list_ports.comports())
for p in ports:
if "Arduino" in p.description:
COM.append(str(p.device))
return COM
COM = readArduinoPort()
board = ArduinoMega(COM[0])
pin = board.get_pin('a:5:i')
it = util.Iterator(board)
it.start()
try:
while True:
print(pin.read())
sleep(0.1)
except KeyboardInterrupt:
pass
Now, this code runs just fine the first time I use it, generating numbers close to 1 when the sensor is detecting proximity and numbers close to 0 when not detecting anything.
However, whenever I try to run the Iterator a second time (without restarting the kernel), the code generates seemingly random numbers (almost like the pin was floating, like nothing was connected to it).
Any idea why this is happening? Is this a normal behavior?
Thank you!
I already checked these questions that do not entirely address my issue:
arduino pyfirmata analog reading
Analog readings on Arduino returns wrong values
I have the same result by not having anything pinned to pin A5 of the Arduino Mega.
I wasn't sure, but I tried adding:
board.analog[5].enable_reporting()
before the iterator and then:
board.analog[5].disable_reporting()
but nothing changed.
Board Differences
I ran into the same problem. I own both a Mega and an Uno and needed to select the appropriate Board and Processor in the tools menu:
Tools > Board > _board_
Tools > Processor > _processor_

BME280 on Raspberry Pi using Python 3 - Odd first reading

I have 2 x Pimoroni BME280 and they both produce the same initial reading of 21.95*C 698.09hPa 76.34% humidity.
Using this simple code
import time
from smbus2 import SMBus
from bme280 import BME280
bus = SMBus(1)
bme280 = BME280(i2c_dev=bus)
while True:
temperature = bme280.get_temperature()
pressure = bme280.get_pressure()
humidity = bme280.get_humidity()
print('{:05.2f}*C {:05.2f}hPa {:05.2f}%'.format(temperature, pressure, humidity))
time.sleep(1)
and I always get as the first line of output as...
21.95*C 698.09hPa 76.34%
followed by the correct data for example...
18.70*C 993.54hPa 55.88%
18.70*C 993.53hPa 56.12%
18.71*C 993.54hPa 56.06%
18.71*C 993.54hPa 55.95%
Does anybody know why this is?
Currently I have the same thing on both of my BME280 so presume it's some sort of initialization thing on the first reading which must be discarded. If I run my program the only solution I can see it to ask twice what thr readings are and discard the first reading..
Thanks for reading and helping...
I would presume that this is caused due to an initial transient value being outputted by the sensor as a result of initialising your sensor.
It would be interesting to see how an Arduino would handle the initialisation process
vis-à-vis said transient value with your sensor.
As you said, if your continuous readings are 'correct', I would try to perhaps delay the output process or omit the first reading in some way or another.

Multiple reproducible errors with a Brecknell Scale

I'm working on getting a weight from a usb scale using python and PyUSB. Here's my code
import sys
import usb.core
import usb.util
from reports import \
ReportFactory, STATUSES, ZERO_WEIGHT, STABLE_WEIGHT, DATA_REPORT
device = usb.core.find(idVendor=0x67b, idProduct=0x2303)
if device is None:
raise ValueError('Device Not Found')
if device.is_kernel_driver_active(0) is True:
device.detach_kernel_driver(0)
usb.util.claim_interface(device, 0)
device.set_configuration()
collected = 0
attempts = 50
while collected < attempts:
ret = device.read(0x2,0x0040)
sret=''.join([chr(x) for x in ret])
print "Return Raw: ",ret
print "Return : ", sret
print ReportFactory.build(ret)
# release the device
usb.util.release_interface(device, 0)
device.attach_kernel_driver(0)
The first time I run this program I get Resource busy error
The second run I get Operation timed out on the 5th dump.
Subsequent runs after that result in immediate timeouts.
There are several things going on here
Why do I get a resource busy error on first run? I would think the kernel_driver if statement I have should take care of it.
Why do I get data that looks nothing like what a USB scale should produce?
Why the timeout after 4 dumps of data? Everytime!
The device information is thus
Any help would be much appreciated!
Ok, anyone that is struggling to get anything from the GP100 Brecknell scale using PyUSB, switch to PySerial. Since this is one of the cheapest USB scales on the market, I'm guessing this information will help many.
I emailed the manufacturer for documentation and they've sent me some valuable serial protocol information.
If you set the protocol of the scale to 7010 you can use python code that looks like this
import time
import serial
ser = serial.Serial(
port='/dev/ttyUSB0',
baudrate=2400,
bytesize=8,
parity='N',
stopbits=2
)
while 1:
x = ser.read(100)
print(x)
This will stream 8 bytes of data.
The first byte is status information that can be interpreted thusly
Bits 2-4
Bits 5-8
Bytes 2 & 3 can be safely ignored.
Bytes 4-8 have the weight information, represented by characters 0-9 (e.g. 00023 = 2.3 lbs). This scale is only accurate +- 0.6 lbs and does not work in ounces, perhaps other models using the same serial controller utilize the oz capabilities. The PG100 does not.

While loop not working immediately while reading from a Sensor without printing the read from the sensor?

I am attempting to read multiple Reflective IR Sensors continuously until each one is blocked. I am using an Arduino running Standard Firmata and Pythons Pyfirmata library.
Every time I try a standard read without printing the result in a while loop I am getting a 15 to 30 second delay (I cannot figure out why):
Example1 - works but with random unexplained delay:
Sensor1 = board.get_pin('a,0,i') #analogue, pin 0, input mode
while Sensor1.read() != 0: #Sensor defaults to 0.6 V but when blocked 0.0v
Sensor1.read()
Example2 - works but I now have a bunch of sensor read outputs:
Sensor1 = board.get_pin('a,0,i') #analogue, pin 0, input mode
while Sensor1.read() != 0: #Sensor defaults to 0.6 V but when blocked 0.0v
Sensor1.read()
print(Sensor1.read()) # this prints a bunch of read outputs
For some reason when I add the print(Sensor1.read()) I will get an immediate response when the sensor is blocked. But if I remove this portion of code to eliminate the garbage output I get an unexplained time delay in between when the sensor is blocked and when it is recognized by the code and moves on. What I would like to do is constantly read the sensor without printing that read and get an immediate response of breaking the while loop once the sensor is blocked and produces the 0.0v. I believe that I also have the option of suppressing the print outputs for these while loops but I want to know if there is an alternative? Thank you so much for reviewing this question and thanks a million for any help!
The read() might not always be exact 0. Maybe use a threshold value, for example:
while Sensor1.read() > 10:
Another solution would be to use interrupts and set flags, so you don't have to do the polling (and could put the device to sleep).
I know i'ts an old topic, but I ran into this problem with pyfirmata a few days ago, and today I solved it simply by printing a new line with the end= parameter, it creates a new line, but the following prints stays on the same line.
Sensor1 = board.get_pin('a,0,i')
while Sensor1.read() != 0:
Sensor1.read()
print('', end='')

Python hangs when using serial.write() on my Raspberry 2

I use pySerial for communication between RaspberryPi 2 and Arduino but after my first 100 write-calls it starts to become very slowly when writing.
My Code looks like this:
import serial
ser = serial.Serial("/dev/ttyACM0", 2000000, write_timeout=0)
while True:
byteData = getData()
sentBytes = ser.write(byteData)
if sentBytes == 4:
print("All Data was sent successfully!")
Everything is fine for the first second but then it hangs and I only send like 4 bytes each second. I also saw this post here but on my Raspbian machine a /dev/serial0 or /dev/ttyS0 doesn't exist. How I get this rushing like in the first second permanently?
You are using a very high baud rate, a buffer may be running full and cause the hick up after a short while.
Try a very conservative baud rate of 9600 and see if you have the same issue.
Also make sure your getData() actually always returns 4 bytes, otherwise your print statement might not get evaluated in every loop.

Categories

Resources