python-serial OSError: [Errno 11] Resource temporarily unavailable - python

I am using Arduino Nano to serial communicated with ODROID (single-board computer installed Ubuntu 14.04).
The Arduino code:
void setup() {
Serial.begin(9600); // set the baud rate
Serial.println("Ready"); // print "Ready" once
}
void loop() {
char inByte = ' ';
if(Serial.available()){ // only send data back if data has been sent
char inByte = Serial.read(); // read the incoming data
Serial.println(inByte);
}
delay(100); // delay for 1/10 of a second
}
The Python code in ODROID:
#!/usr/bin/env python
from time import sleep
import serial
ser = serial.Serial('/dev/LIDAR', 9600, timeout=1) # Establish the connection on a specific port
sleep(1)
print "Arduino is initialized"
counter = 32 # Below 32 everything in ASCII is gibberish
while True:
if (ser.inWaiting()>0):
counter +=1
ser.write(str(chr(counter))) # Convert the decimal number to ASCII then send it to the Arduino
print ser.readline() # Read the newest output from the Arduino
sleep(.1) # Delay for one tenth of a second
if counter == 255:
counter = 32
ser.close
Traceback(most recent last):
File "./serial_test1.py", line 16, in <module>
print ser.readline() # Read the newest output from the Arduino
File "/usr/lib/python2.7/dis-package/serial/serialposix.py", line 43, in read
buf = os.read(self.fd, size-len(read))
OSError: [Errno 11]Resource temporarily unavailable
Then I had this issue after print some values, I know this problem maybe no data in available at current time. But how can I figure out this issue. Thanks for your help.

I don't know if this will work for ODROID, but I found a post about similar problem with Raspberry PI. In that post one of the answers redirected to this link
There it says the problems is caused by Raspberry Pi serial port, which is used by default to use the system console which conflicts when you try to use it for your own purposes
To disable the serial por for console you must edit the file /etc/inittab and comment the line T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100 (You comment it with a # at the begining of the line, like in python). You must reboot the ODROID and it should work
I suggest you to read the answer I linked cause it explains a bit more about how can you substitute the serial port to access the command line (It suggests using ssh) and another thing is that Raspberry PI (And assume ODROID works similar) sends at boot time a message through serial port that will be received by the Arduino. You can remove that message and it's explained there
Hope this helps you

You are receiving this error since your serial device is being used by os itself. You should stop os to use this device.
Serial getty is now a service and you should stop and/or disable it:
sudo systemctl stop serial-getty#ttyAMA0.service
sudo systemctl disable serial-getty#ttyAMA0.service
Note that my native serial device id is ttyAMA0.
to permanently disable serial service, use
sudo systemctl mask serial-getty#ttyAMA0.service
in this case serial service will not start even on reboot.

Related

What connection string do I use for pyvisa when my TCP device is connected via a USB to Ethernet Adapter?

I am attempting to communicate with a BraggMETER Interrogator that supports SCPI.
OS: Windows 10
Connection hardware: j5create JUH470 USB 3.0 Multi-Adapter Gigabit Ethernet / 3-Port USB 3.0 HUB
Part of my confusion: Should I access as a USB device or as a TCPIP device?
When I connect via Telnet, all goes well. The IP Address and Port are 10.0.0.10 and 3500.
> telnet
> open 10.0.0.10 3500
:IDEN?
:ACK:HBM FiberSensing:FS22SI v3.0:08:046 840 200 898:20190116
:STAT?
:ACK:1
In Python, I am usig the pyvisa library.
import easy_scpi as scpi
import pyvisa
DeviceAddress = '10.0.0.10'
DevicePort = '3500'
VISADevice = f'TCPIP0::{DeviceAddress}::{DevicePort}::SOCKET'
# Doesn't work either --> VISADevice = 'ASRL10::INSTR'
rm = pyvisa.ResourceManager()
print(rm.list_resources())
inst = rm.open_resource(VISADevice)
print(inst.query("*IDEN?"))
inst.close()
The error is always on rm.open_resource. I have tried numerous connection strings. They give different errors. Here are three of them:
pyvisa.errors.VisaIOError: VI_ERROR_INTF_NUM_NCONFIG (-1073807195): The interface type is valid but the specified interface number is not configured.
pyvisa.errors.VisaIOError: VI_ERROR_TMO (-1073807339): Timeout expired before operation completed.
pyvisa.errors.VisaIOError: VI_ERROR_RSRC_NFOUND (-1073807343): Insufficient location information or the requested device or resource is not present in the system.
Update 1
I downloaded National Instruments NI-Max and used their NI I/O trace. This connection string "works":
TCPIP::10.0.0.10::3500::SOCKET
However, I still get the timeout error. Tried ensuring that the newline termination character is sent and upped the timeout to 5 seconds (which did take effect, as it delayed the logging of the timeout error). No dice. Still gives a timeout error.
Update 2
While not the same setup, someone else reports a problem who is using an NI GPIB-to-USB card (GPIB-USB-HS). The common thread is a USB adapter...
https://community.keysight.com/thread/37567
I'm not able to comment so I'm commenting here
Have you tried using a normal socket?
import socket
DeviceAddress = '10.0.0.10'
DevicePort = '3500'
BUFSIZ = 1024
ADDR = (DeviceAddress, DevicePort)
cmd = "IDN?" # or "*IDEN?" as you've put?
braggMeterSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
braggMeterSocket.connect(self.ADDR)
braggMeterSocket.send(cmd + "\n") #maybe with new line depending on what the device terminator is.
mesg = braggMeterSocket.recv(BUFSIZ)
mesg = mesg.strip() # Remove \n at end of mesg
print(mesg)
The problem was that the device exects CRLF (carriage return plus linefeed) as an SCPI command terminator. I was only sending one of those two characters, "\n".
Python I/O does not adapt to the OS like some languages I have used, which will interpret "\n" as "\r\n" in some situations.
Likewise, NI-Max only sent the "\n" and omitted the "\r".

Access sensor through serial port on Raspberry Pi 3B

I've got the following problem and after long hours of frustration I cannot get it to work, could somebody please help a noob out?
I've several SRF02 Ranging sensors which I wanted to use through I2C on my Raspberry Pi 3B Jessie.
I followed the tutorial and changed the first sensor to address 0xF2 (0x79 seen from Raspberry) and it all went perfectly. But the problem is that the addresses 0x78 to 0x7B are reserved for 10-bit I2C Adressing, so I have to use another one. But since I cannot access it anymore through I2C since I changed the address I decided to do it through the serial port.
I tried changing it as described in the tutorial but it doesn't work. Here is the code and what I did after research to get it done:
I checked the address of the Sensor. On powering up it sends one long and 9 short flashes so its address should be 0x09 in serial mode.
I updated and upgraded my Raspberry.
I connected the sensors RX pin to the Rasp TX and viceversa. +5V of the sensor to +3V of the Rasp (Is this a problem?). Sensors ground and mode pin to ground.
On raspi-config I changed the serial console to disabled and the serial harware ports to enabled.
Here is my /boot/cmdline.txt:
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles
I added the following to my /boot/config.txt:
enable_uart=1
dtoverlay=pi3-disable-bt
core_freq=250
My python code (By sending the range commands the sensor should flash once, but it doesn't, also I don't get any Result):
import serial
import time
ser = serial.Serial(port='/dev/serial0', baudrate = 9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_TWO, timeout=1, write_timeout=5)
USED_ADDRESS = '0x09'
TARGET_ADDRESS = '0x03'
# GET DISTANCE IN CM
ser.write(USED_ADDRESS)
ser.write('0x51')
time.sleep(0.07)
ser.write(USED_ADDRESS)
ser.write('0x5E')
results = ser.read(2)
if(results != None and len(results) > 0):
print 'RESULTS:'
for result in results:
print result
else:
print 'NO RESULT'
#CHANGING ADDRESS
#First command
ser.write(USED_ADDRESS)
ser.write('0xA0')
#Second command
ser.write(USED_ADDRESS)
ser.write('0xAA')
#Third command
ser.write(USED_ADDRESS)
ser.write('0xA5')
#Target Address
ser.write(USED_ADDRESS)
ser.write(TARGET_ADDRESS)
print "DONE"
Result of dmesg | grep tty:
[ 0.000000] Kernel command line: 8250.nr_uarts=1 bcm2708_fb.fbwidth=640 bcm2708_fb.fbheight=480 bcm2708_fb.fbswap=1 vc_mem.mem_base=0x3dc00000 vc_mem.mem_size=0x3f000000 dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles
[ 0.000312] console [tty1] enabled
[ 0.748748] 3f201000.serial: ttyAMA0 at MMIO 0x3f201000 (irq = 87, base_baud = 0) is a PL011 rev2
Result of ls -l /dev/serial*:
lrwxrwxrwx 1 root root 7 Feb 16 15:06 /dev/serial0 -> ttyAMA0
lrwxrwxrwx 1 root root 5 Feb 16 15:06 /dev/serial1 -> ttyS0
Somebody got an idea? I would be super-duper gratefull for any hint.
Ok guys I solved it! I found the solution here: https://www.raspberrypi.org/forums/viewtopic.php?t=63419
Connections as follows:
Pi 5V to device 5V Pi ground to device ground Pi ground to device mode
Pi TX to device RX
Then configure the Pi serial link to 9600.
stty -F /dev/ttyAMA0 9600
Then use echo to send commands to the device.
The first byte is the device address (0 - 15). The second byte is a
command.
To change the device from address 0 to address 5 use
echo -ne "\x00\xA0\x00\xAA\x00\xA5\x00\x05" >/dev/ttyAMA0
To change the device from address 5 back to address 0 use
echo -ne "\x05\xA0\x05\xAA\x05\xA5\x05\x00" >/dev/ttyAMA0
All the details are in the docs you linked.

Simulate enter key in python serial script

I'm currently trying to do something simple with a Telit CC864 Cellular module. The module is controlled with AT-Commands through serial ports. So with a modem control software such as minicom, I can input the following sequence of commands:
Input: AT
Output: OK
Input: AT#SGACT=1,1
Output: OK
Input: AT#SD=1,0,54321,"30.19.24.10",0,0,1
Output: CONNECTED
Input: AT#SSEND=1
> Hello world!
>
Output: OK
What this does is it connects to a server I have set up and sends a packet "Hello world!". Everything is working in minicom. However, what I am trying to do is convert this to a python script. Here's what I have so far:
import serial
import time
# Modem config
modem_port = serial.Serial()
modem_port.baudrate = 115200
modem_port.port = "/dev/tty.usbserial-00002114B"
modem_port.parity = "N"
modem_port.stopbits = 1
modem_port.xonxoff = 0
modem_port.timeout = 3
modem_port.open()
def send_at_command(command):
modem_port.write(bytes(command+"\r", encoding='ascii'))
def read_command_response():
print(modem_port.read(100).decode('ascii').strip())
print("\n")
if modem_port.isOpen():
# Check network status
send_at_command("AT+CREG=1")
read_command_response()
# Configure Socket
send_at_command("AT#SCFG=1,1,0,0,1200,0")
read_command_response()
# Obtain IP from network
send_at_command("AT#SGACT=1,1")
read_command_response()
# Connect to AWS server
send_at_command("AT#SD=1,0,54321,\"30.19.24.10\",0,0,1")
read_command_response()
# Send packet to AWS server
send_at_command("AT#SSEND=1")
read_command_response()
send_at_command("This is sent from Python Script.")
read_command_response()
modem_port.close()
However, this script fails to send the packet. I'm thinking that the reason is because in minicom, I have to press enter after Hello world! in order to send the packet. I'm at a loss at how to simulate this in the python script. Any suggestions would be much appreciated.
EDIT:
So I was reading the module documentation some more, and it seems that what I need to do is send Ctrl-Z char (0x1A hex) through the serial port. Do you know how I would do this in python?
Note that the documentation indicated that the execute command was ctrl-z so this answer has been edited to remove references to \n and \r
EDIT:
Based on your comments, try
def send_at_command(command): modem_port.write(bytes(command+"\1a", encoding='ascii'))

Python script to configure an XBee module fails on a raspberry pi

I have a python script that I want to use to configure some XBee modules. It works perfectly find when connect to a computer via an xbee development board, but fails when connect to a raspberry pi via the slice of pi board.
I have narrowed down the problem to it failing to enter the command mode, after sending the +++ the xbee never sends the OK message. Here is the relevant code:
...
CC = '+'
GT = '1.1' # Tried different values here
...
def startCommandMode(self):
self.emptyBuffer() # Tried with and without this line
sleep(self.GT) # Tried with and without this line
self.ser.write(self.CC + self.CC + self.CC)
sleep(self.GT)
return self.getReply() == 'OK'
...
def getReply(self):
count = 0
reply = ''
while True:
char = self.ser.read()
if char == '\r':
break
if len(char) == 0:
return None
reply += char
return reply
The full source is available on github if needed.
I know it is not a problem with the xbee module, the raspberry pi or the slice of pi board as it works perfectly fine if I try it manually using "picocom -lc /dev/ttyAMA0".
Some things to check:
Are you getting anything in response?
Have you enabled flow-control on the XBee? Make sure D6 and D7 are set to 0 since the Raspberry Pi serial port doesn't have flow control.
Is the Python code configured for flow control? It might be waiting for a CTS signal that is never asserted.
Can you try using the XBee Development Board on the Raspberry Pi's USB port?
Use the following:
....
if args.common:
args.at = ['ID', 'CH', 'MY', 'DL', 'DH', 'AP'] + args.at
xbee = XBee(args.port, args.baud);
sleep(2)
xbee.CC = args.CC
xbee.GT = args.GT
....
....
IMHO I thick Rpi need more time to initialize serial port, thats why I am using this delay
. Also is applicable for transparent mode so add a delay after port init.
I hope this will Ok for you. For me it is solved.
BR.
Manel.

Interfacing with TUN\TAP for MAC OSX (Lion) using Python

I found the following tun\tap example program and can not get it to work:
http://www.secdev.org/projects/tuntap_udp/files/tunproxy.py
I have modified the following lines:
f = os.open("/dev/tun0", os.O_RDWR)
ifs = ioctl(f, TUNSETIFF, struct.pack("16sH", "toto%d", TUNMODE))
ifname = ifs[:16].strip("\x00")
The first line was modified to reflect the real location of the driver. It was originally
f = os.open("/dev/net/tun", os.O_RDWR)
Upon running I get the following error:
sudo ./tuntap.py -s 9000
Password:
Traceback (most recent call last):
File "./tuntap.py", line 65, in <module>
ifs = ioctl(f, TUNSETIFF, struct.pack("16sH", "toto%d", TUNMODE))
IOError: [Errno 25] Inappropriate ioctl for device
I am using the latest tun\tap drivers installed from http://tuntaposx.sourceforge.net/download.xhtml
The OSX tun/tap driver seems to work a bit different. The Linux example dynamically allocates a tun interface, which does not work in OSX, at least not in the same way.
I stripped the code to create a basic example of how tun can be used on OSX using a self-selected tun device, printing each packet to the console. I added Scapy as a dependency for pretty printing, but you can replace it by a raw packet dump if you want:
import os, sys
from select import select
from scapy.all import IP
f = os.open("/dev/tun12", os.O_RDWR)
try:
while 1:
r = select([f],[],[])[0][0]
if r == f:
packet = os.read(f, 4000)
# print len(packet), packet
ip = IP(packet)
ip.show()
except KeyboardInterrupt:
print "Stopped by user."
You will either have to run this as root, or do a sudo chown your_username /dev/tun12 to be allowed to open the device.
To configure it as a point-to-point interface, type:
$ sudo ifconfig tun12 10.12.0.2 10.12.0.1
Note that the tun12 interface will only be available while /dev/tun12 is open, i.e. while the program is running. If you interrupt the program, your tun interface will disappear, and you will need to configure it again next time you run the program.
If you now ping your endpoint, your packets will be printed to the console:
$ ping 10.12.0.1
Ping itself will print request timeouts, because there is no tunnel endpoint responding to your ping requests.
so about the 'No such file or directory' error when doing:
f = os.open("/dev/tun12", os.O_RDWR)
this worked for me:
brew install Caskroom/cask/tuntap

Categories

Resources