How can I fix issue connecting Arduino with python? - python

I am trying to configure python on my arduino. Ive followed like 10 tutorials but none of them are working. Ive tried to connect via pyserial. When I use pyserial, I simply get no response, here is the code.
I am trying to process data and code in python, then send data to arduino to run. I already downloaded the Firmata libraries on both, no issues there. I have also uploaded the arduino standard firmata sketch, no issues there.
Code being run on my python ide:
import serial
import time
Arduino = serial.Serial('com5',115200)
time.sleep(5)
while True:
while (Arduino.inWaiting()==0):
print("ur dumb")
pass
dataPacket = Arduino.readline()
print(dataPacket)
Code being run on my Arduino IDE:
int count = 1;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.print(count);
delay(1000);
count = count+1;
}
Similary I've tried:
import pyfirmata
import time
board = pyfirmata.Arduino('/dev/ttyACM0')
it = pyfirmata.util.Iterator(board)
it.start()
digital_input = board.get_pin('d:10:i')
led = board.get_pin('d:13:o')
while True:
sw = digital_input.read()
if sw is True:
led.write(1)
else:
led.write(0)
time.sleep(0.1)

you can use a more accessible python program here to work:
import serial
import time
ArduinoUnoSerial = serial.Serial('com5',115200)
while 1:
print (ArduinoUnoSerial.readline())
this will work with your Arduino program
don't worry about the board no matter whether it is mega or uno or anything else ArduinoUnoSerial.readline() will work

Related

Cisco Packet Tracer error UnboundLocalError in python

I am getting an UnboundLocalError error when I run a python code that shouldn't result in an error according to most python users. The version of Packet Tracer is 8.0.0 and probably python 2
I was told that globing is not good to use instead I should use functions where I return the value.
Code:
from udp import *
from time import *
from gpio import *
def onUDPReceive(ip, port, data):
return int(data)
def main():
socket = UDPSocket()
temp=socket.onReceive(onUDPReceive)
print(socket.begin(1235))
while True:
if temp >= 520:#error
digitalWrite(3, HIGH);
delay(1000)
digitalWrite(3, LOW);
delay(500)
customWrite(9, 2);
else:
digitalWrite(0, LOW);
customWrite(2, 0);
if __name__ == "__main__":
main()
Error: UnboundLocalError: local variable 'temp' referenced before assignment in file main.py on line 15
What I have tried:
I have tired to print(temp);right after temp=socket.onReceive(onUDPReceive), but it still gives me the same error
When adding
try:
print(temp);
ParseError: bad input in file main.py on line 17
The system:
Image of code

Run a python script with NodeJS causing problems

My python script has two main steps:
Open two webbrowser tabs (default browser). And let a LED blink.
When i am executing the python script via shell with "python netflix.py" everything works fine.
But when i am trying to start it via my (see below) NodeJS script. Only the LED will be blink. The webbrowser tabs won't come up.
Does anyone know where the issue is?
#!/usr/bin/env node
process.env.UV_THREADPOOL_SIZE = 1208;
var http = require('http');
const server = http.createServer(function(request, response) {
try{
console.log('Request incoming...');
var spawn = require('child_process').spawn;
if(request.url == '/abort'){
console.log('Calling abort.py ...');
var process = spawn('python',["./abort.py"]);
}else{
console.log('Calling netflix.py');
var process = spawn('python',["./netflix.py"]);
}
}catch(e){
console.log('Error');
console.log(e);
}
});
server.on('error', function(){
console.log('error');
});
const port = 8000;
server.listen(port);
server.timeout = 10000;
console.log(`Listening at http://leitner-pi:${port}`);
import sys
import webbrowser
from gpiozero import LED
from time import sleep
try:
webbrowser.open_new_tab("http://netflix.com");
finally:
print("")
print("Lasse PIN 7 blinken..")
led = LED(17)
while True:
led.on()
sleep(0.3)
led.off()
sleep(0.3)
Fixed: Well, I made a workaround.
First, I split the python script into two scripts. Webbrowser and LED script, to avoid any kind of interruptions or something else. Second, I changed the webbrowser to:
os.system(‘sudo -upi chromium-browser URL1 URL2’).
At last, I am calling both new
scripts from my node webserver, like I used before.
Now it works fine.

Turtlebot subscriber pointcloud2 shows color in Gazebo simulator but not in robot

I am subscribing to topic "/camera/depth/points" and message PointCloud2 on a turtlebot (deep learning version) with ASUS Xtion PRO LIVE camera.
I have used the python script below under the gazebo simulator environment and i can receive x, y, z and rgb values successfully.
However, when i run it in the robot, the rgb values are missing.
Is this a problem of my turtlebot version, or camera or is it that i have to specify somewhere that i want to receive PointCloud2 type="XYZRGB"? or is it a sync problem? Any clues please thanks!
#!/usr/bin/env python
import rospy
import struct
import ctypes
import sensor_msgs.point_cloud2 as pc2
from sensor_msgs.msg import PointCloud2
file = open('workfile.txt', 'w')
def callback(msg):
data_out = pc2.read_points(msg, skip_nans=True)
loop = True
while loop:
try:
int_data = next(data_out)
s = struct.pack('>f' ,int_data[3])
i = struct.unpack('>l',s)[0]
pack = ctypes.c_uint32(i).value
r = (pack & 0x00FF0000)>> 16
g = (pack & 0x0000FF00)>> 8
b = (pack & 0x000000FF)
file.write(str(int_data[0])+","+str(int_data[1])+","+str(int_data[2])+","+str(r)+","+str(g)+","+str(b)+"\n")
except Exception as e:
rospy.loginfo(e.message)
loop = False
file.flush
file.close
def listener():
rospy.init_node('writeCloudsToFile', anonymous=True)
rospy.Subscriber("/camera/depth/points", PointCloud2, callback)
rospy.spin()
if __name__ == '__main__':
listener()
The contents of Published topics are determined by the software that provides them - i.e. the drivers for your camera. To fix this you therefore need to get the right driver and use the topic that it says contains the required information.
You can find recommended drivers for your cameras on the ROS wiki or on some community websites - like this. In your case, the ASUS devices should use openni2 and set depth_registration:=true - as documented here.
At this point, /camera/depth_registered/points should now show the combined xyz and RGB point cloud. To use it, your new listener() code should look something like this:
def listener():
rospy.init_node('writeCloudsToFile', anonymous=True)
# Note the change to the topic name
rospy.Subscriber("/camera/depth_registered/points", PointCloud2, callback)
rospy.spin()

Finding Bluetooth low energy with python

Is it possible for this code to be modified to include Bluetooth Low Energy devices as well? https://code.google.com/p/pybluez/source/browse/trunk/examples/advanced/inquiry-with-rssi.py?r=1
I can find devices like my phone and other bluetooth 4.0 devices, but not any BLE. If this cannot be modified, is it possible to run the hcitool lescan and pull the data from hci dump within python? I can use the tools to see the devices I am looking for and it gives an RSSI in hcidump, which is what my end goal is. To get a MAC address and RSSI from the BLE device.
Thanks!
As I said in the comment, that library won't work with BLE.
Here's some example code to do a simple BLE scan:
import sys
import os
import struct
from ctypes import (CDLL, get_errno)
from ctypes.util import find_library
from socket import (
socket,
AF_BLUETOOTH,
SOCK_RAW,
BTPROTO_HCI,
SOL_HCI,
HCI_FILTER,
)
if not os.geteuid() == 0:
sys.exit("script only works as root")
btlib = find_library("bluetooth")
if not btlib:
raise Exception(
"Can't find required bluetooth libraries"
" (need to install bluez)"
)
bluez = CDLL(btlib, use_errno=True)
dev_id = bluez.hci_get_route(None)
sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)
sock.bind((dev_id,))
err = bluez.hci_le_set_scan_parameters(sock.fileno(), 0, 0x10, 0x10, 0, 0, 1000);
if err < 0:
raise Exception("Set scan parameters failed")
# occurs when scanning is still enabled from previous call
# allows LE advertising events
hci_filter = struct.pack(
"<IQH",
0x00000010,
0x4000000000000000,
0
)
sock.setsockopt(SOL_HCI, HCI_FILTER, hci_filter)
err = bluez.hci_le_set_scan_enable(
sock.fileno(),
1, # 1 - turn on; 0 - turn off
0, # 0-filtering disabled, 1-filter out duplicates
1000 # timeout
)
if err < 0:
errnum = get_errno()
raise Exception("{} {}".format(
errno.errorcode[errnum],
os.strerror(errnum)
))
while True:
data = sock.recv(1024)
# print bluetooth address from LE Advert. packet
print(':'.join("{0:02x}".format(x) for x in data[12:6:-1]))
I had to piece all of that together by looking at the hcitool and gatttool source code that comes with Bluez. The code is completely dependent on libbluetooth-dev so you'll have to make sure you have that installed first.
A better way would be to use dbus to make calls to bluetoothd, but I haven't had a chance to research that yet. Also, the dbus interface is limited in what you can do with a BLE connection after you make one.
EDIT:
Martin Tramšak pointed out that in Python 2 you need to change the last line to print(':'.join("{0:02x}".format(ord(x)) for x in data[12:6:-1]))
You could also try pygattlib. It can be used to discover devices, and (currently) there is a basic support for reading/writing characteristics. No RSSI for now.
You could discover using the following snippet:
from gattlib import DiscoveryService
service = DiscoveryService("hci0")
devices = service.discover(2)
DiscoveryService accepts the name of the device, and the method discover accepts a timeout (in seconds) for waiting responses. devices is a dictionary, with BL address as keys, and names as values.
pygattlib is packaged for Debian (or Ubuntu), and also available as a pip package.

pySerial write() won't take my string

Using Python 3.3 and pySerial for serial communications.
I'm trying to write a command to my COM PORT but the write method won't take my string. (Most of the code is from here Full examples of using pySerial package
What's going on?
import time
import serial
ser = serial.Serial(
port='\\\\.\\COM4',
baudrate=115200,
parity=serial.PARITY_ODD,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS
)
if ser.isOpen():
ser.close()
ser.open()
ser.isOpen()
ser.write("%01#RDD0010000107**\r")
out = ''
# let's wait one second before reading output (let's give device time to answer)
time.sleep(1)
while ser.inWaiting() > 0:
out += ser.read(40)
if out != '':
print(">>" + out)
ser.close()
Error is at ser.write("%01#RDD0010000107**\r") where it gets
Traceback is like this
data = to_bytes(data)
b.append(item)
TypeError: an integer is required.
It turns out that the string needed to be turned into a bytearray and to do this I editted the code to
ser.write("%01#RDD0010000107**\r".encode())
This solved the problem
You have found the root cause. Alternately do like this:
ser.write(bytes(b'your_commands'))
I had the same "TypeError: an integer is required" error message when attempting to write.
Thanks, the .encode() solved it for me.
I'm running python 3.4 on a Dell D530 running 32 bit Windows XP Pro.
I'm omitting the com port settings here:
>>>import serial
>>>ser = serial.Serial(5)
>>>ser.close()
>>>ser.open()
>>>ser.write("1".encode())
1
>>>

Categories