Python 2.7 + Raspberry Pi 3 + UART (Serial) - python-2.7

some trouble with Python on RPi3 over UART.
My Python 2.7 script:
import time
import serial
ser = serial.Serial(
port='/dev/ttyS0',
baudrate=115200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
while 1:
ser.write('hello')
time.sleep(1)
And output in terminal is:
hellohello`??p?nnn?`??p?nnn?`??p?nnn?`??p?nnn?`??p?nnn?`??p?nnn?`??p?nnn?
Sometimes is "hello" two times, sometimes five times.
Standars RPi3 console output is off (in raspi-config). UART converter is 3V3 logic.
Could you help me? Thanx a lot!
Waldi

Related

Searching for an expression returned from a shell process that never finishes using python 2.7 on raspberry PI

I am having a raspberry pi 4 (RPI) with python 2.7 installed. Within a python script, I am executing a shell script, which flashes a µController (µC) connected to the pi. The shell script prints some stuff and reaches idle after printing "Connecting". Note that the script does not finish at this point!
Now I want to use subprocess (or any other function) to forward me all the prints from the shell script. I do then want to check if the keyphrase "Connecting" has been printed. Besides, I need a timeout if the shell script gets stuck before printing "Connecting".
However, I am quite new to python, thus I dont know how to use the subprocess correctly to be able to retrieve the prints from the shell script and set a timeout for the script as well.
Here is some sort of pseudo code:
output = subprocess.Popen(["./prebuilt/bin/bbb_cc13xx-sbl /dev/ttyACM0 {hexfileName} cc13x2 -e -p -v"], \
stdout=subprocess.PIPE, stderr = subprocess.PIPE, shell = True)
expression_found = False
for i in range(5)
if(output.stdout.find('Expression') != -1):
expression_found = True
break
time.sleep(1)
if(expression_found):
do that..
else:
do this...
Is there an easy way to implement my two needs?
EDIT: Adding the prints to the terminal like os.system() does would be great, too.
Best wishes
Slev1n
I actually found a simple solution, the mistake is to pipe stderr instead of stdout. The first one being empty all/most of the time.
Here is a solution where the prints from the child process where displayed on the terminal in real time and where I was able to search for a keyword within the stdout pipe. I was also able to terminate the child process without errors. I could also add a timeout as well for terminating the child process. The codes was also validated on raspberry pi 4B with python 2.7.
Here the main process:
import subprocess, sys
import time
cmd = "contprint.py"
p = subprocess.Popen( cmd , shell=True,
stdout=subprocess.PIPE,
universal_newlines=True)
startTime = time.time()
maxTime = 8
while True:
currentTime = time.time()
if (currentTime - startTime) > maxTime:
p.terminate()
break
else:
output = p.stdout.readline()
print(output)
keyWord = "EOF"
if keyWord in output:
print("Keyword {} has be found".format(keyWord))
p.terminate()
break
if len(output) == 0:
print("Output is empty")
p.terminate()
break
if p.poll() is not None:
print("p.poll is not none")
p.terminate()
break
And here the child process:
import time, sys
count = 0
while(1):
count += 1
print(count)
try:
sys.stdout.flush()
except:
print("Escape Error!")
time.sleep(0.5)
if(count == 10):
print("EOF")
if(count == 20):
pass`enter code here`
Any comments are welcome.

How to send ascii characters through serial in python?

I want to send 3 numbers (integers) through serial port in ascii format. I use putty terminal to see the receiving data on the other end. The problem is that putty doesn't shows anything except strings. I tried to use the ord() function to get the ascii format but I cannot see anything on putty. Is it just a putty problem with ascii format, or I don't send data at all? How can I be sure that I send the data in the correct format (ascii)?
I am new to python, so sorry if this sounds trivial.
I use Ubuntu 16.04 LTS and Python 2.7.12.
Thank you in advance!
#!/opt/bin/python
import serial
import time
camera = [0, 0, 0]
ser = serial.Serial('/dev/ttyUSB0', 9600)
print (ser.name)
print ("Port Open")
time.sleep(2)
while ser.isOpen():
for i in range(1):
#ser.write(b'5')
#ser.write(chr(5))
#ser.write(5)
ser.write(ord(str(camera[0])))
#ser.write(bytes(camera))
print(camera)
time.sleep(1)
camera[1] = camera[1] + 1
ser.close()

How to use regular expressions to pull something from a terminal output?

I'm attempting to use the re module to look through some terminal output. When I ping a server through terminal using ping -n 1 host (I'm using Windows), it gives me much more information than I want. I want just the amount of time that it takes to get a reply from the server, which in this case is always denoted by an integer and then the letters 'ms'. The error I get explains that the output from the terminal is not a string, so I cannot use regular expressions on it.
from os import system as system_call
import re
def ping(host):
return system_call("ping -n 1 " + host) == 0
host = input("Select a host to ping: ")
regex = re.compile(r"\w\wms")
final_ping = regex.search(ping(host))
print(final_ping)
system returns 0, not anything too useful. However, if we were to do subprocess, we can get teh output, and store it to a variable, out, then we can regex search that.
import subprocess
import re
def ping(host):
ping = subprocess.Popen(["ping", "-n", "1", host], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, error = ping.communicate()
return str(out)
host = input("Select a host to ping: ")
final_ping = re.findall("\d+ms",ping(host))[0]
print(final_ping)
Output:
22ms
There are two problems with your code:
Your ping function doesn't return the terminal output. It only returns a bool that reports if the ping succeeded. The ping output is directly forwarded to the terminal that runs the Python script.
Python 3 differentiates between strings (for text, consisting of Unicode codepoints) and bytes (for any data, consisting of bytes). As Python cannot know that ping only outputs ASCII text, you will get a bytes object if you don't specify which text encoding is in use.
It would be the best to use the subprocess module instead of os.system. This is also suggested by the Python documentation.
One possible way is to use subprocess.check_output with the encoding parameter to get a string instead of bytes:
from subprocess import check_output
import sys
def ping(host):
return check_output(
"ping -n 1 " + host,
shell=True,
encoding=sys.getdefaultencoding()
)
...
EDIT: The encoding parameter is only supported since Python 3.6. If you are using an older version, try this:
from subprocess import check_output
import sys
def ping(host):
return check_output(
"ping -n 1 " + host,
shell=True
).decode()
...

Sniff error in Scapy

I am trying to use scapy for one of my project. But, it gives the following error, When I test it.
NameError: name 'sniff' is not defined
import sys
from scapy import *
devices = set()
def PacketHandler(pkt):
if pkt.haslayer(Dot11) :
dot11_layer = pkt.getlayer(Dot11)
if dot11_layer.addr2 and ( dot11_layer.addr2 not in devices ):
devices.add(dot11_layer.addr2)
print dot11_layer.addr2
sniff(iface = sys.argv[1], count = int(sys.argv[2]), prn = PacketHandler)
if I change module name to scapy.all, it says there is no module.
Python version: 2.7
Scapy version: 2.3.3
I have just installed with pip install scapy.Any helps would be appreciated.
You must import Scapy as from scapy.all import *, and you must not name your script scapy.py (or any other script in the current directory or your PYTHONPATH)!

python + wx & uno to fill libreoffice using ubuntu 14.04

I collected user data using a wx python gui and than I used uno to fill this data into an openoffice document under ubuntu 10.xx
user + my-script ( +empty document ) --> prefilled document
After upgrading to ubuntu 14.04 uno doesn't work with python 2.7 anymore and now we have libreoffice instead of openoffice in ubuntu. when I try to run my python2.7 code, it says:
ImportError: No module named uno
How could I bring it back to work?
what I tried:
installed https://pypi.python.org/pypi/unotools v0.3.3
sudo apt-get install libreoffice-script-provider-python
converted the code to python3 and got uno importable, but wx is not importable in python3 :-/
ImportError: No module named 'wx'
googled and read python3 only works with wx phoenix
so tried to install: http://wxpython.org/Phoenix/snapshot-builds/
but wasn't able to get it to run with python3
is there a way to get the uno bridge to work with py2.7 under ubuntu 14.04?
Or how to get wx to run with py3?
what else could I try?
Create a python macro in LibreOffice that will do the work of inserting the data into LibreOffice and then in your python 2.7 code envoke the macro.
As the macro is running from with LibreOffice it will use python3.
Here is an example of how to envoke a LibreOffice macro from the command line:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
##
# a python script to run a libreoffice python macro externally
# NOTE: for this to run start libreoffice in the following manner
# soffice "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp;" --writer --norestore
# OR
# nohup soffice "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp;" --writer --norestore &
#
import uno
from com.sun.star.connection import NoConnectException
from com.sun.star.uno import RuntimeException
from com.sun.star.uno import Exception
from com.sun.star.lang import IllegalArgumentException
def uno_directmacro(*args):
localContext = uno.getComponentContext()
localsmgr = localContext.ServiceManager
resolver = localsmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext )
try:
ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
except NoConnectException as e:
print ("LibreOffice is not running or not listening on the port given - ("+e.Message+")")
return
msp = ctx.getValueByName("/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory")
sp = msp.createScriptProvider("")
scriptx = sp.getScript('vnd.sun.star.script:directmacro.py$directmacro?language=Python&location=user')
try:
scriptx.invoke((), (), ())
except IllegalArgumentException as e:
print ("The command given is invalid ( "+ e.Message+ ")")
return
except RuntimeException as e:
print("An unknown error occurred: " + e.Message)
return
except Exception as e:
print ("Script error ( "+ e.Message+ ")")
print(e)
return
return(None)
uno_directmacro()
And this is the corresponding macro code within LibreOffice called "directmacro.py" and stored in the User area for libreOffice macros (which would normally be $HOME/.config/libreoffice/4/user/Scripts/python :
#!/usr/bin/python
from com.sun.star.awt.MessageBoxButtons import BUTTONS_OK, BUTTONS_OK_CANCEL, BUTTONS_YES_NO, BUTTONS_YES_NO_CANCEL, BUTTONS_RETRY_CANCEL, BUTTONS_ABORT_IGNORE_RETRY
from com.sun.star.awt.MessageBoxButtons import DEFAULT_BUTTON_OK, DEFAULT_BUTTON_CANCEL, DEFAULT_BUTTON_RETRY, DEFAULT_BUTTON_YES, DEFAULT_BUTTON_NO, DEFAULT_BUTTON_IGNORE
from com.sun.star.awt.MessageBoxType import MESSAGEBOX, INFOBOX, WARNINGBOX, ERRORBOX, QUERYBOX
def directmacro(*args):
import socket, time
class FontSlant():
from com.sun.star.awt.FontSlant import (NONE, ITALIC,)
#get the doc from the scripting context which is made available to all scripts
desktop = XSCRIPTCONTEXT.getDesktop()
model = desktop.getCurrentComponent()
text = model.Text
tRange = text.End
cursor = desktop.getCurrentComponent().getCurrentController().getViewCursor()
doc = XSCRIPTCONTEXT.getDocument()
parentwindow = doc.CurrentController.Frame.ContainerWindow
# your cannot insert simple text and text into a table with the same method
# so we have to know if we are in a table or not.
# oTable and oCurCell will be null if we are not in a table
oTable = cursor.TextTable
oCurCell = cursor.Cell
insert_text = "This is text inserted into a LibreOffice Document\ndirectly from a macro called externally"
Text_Italic = FontSlant.ITALIC
Text_None = FontSlant.NONE
cursor.CharPosture=Text_Italic
if oCurCell == None: # Are we inserting into a table or not?
text.insertString(cursor, insert_text, 0)
else:
cell = oTable.getCellByName(oCurCell.CellName)
cell.insertString(cursor, insert_text, False)
cursor.CharPosture=Text_None
return None
You will of course need to adapt the code to either accept data as arguments, read it from a file or whatever.
Ideally I would say use python 3, because python 2 is becoming outdated. The switch requires quite a bit of new coding changes, but better sooner than later. So I tried:
sudo pip3 install -U --pre \
-f http://wxpython.org/Phoenix/snapshot-builds/ \
wxPython_Phoenix
However this gave me errors, and I didn't want to spend the next couple of days working through them. Probably the pre-release versions are not ready for prime time yet.
So instead, what I recommend is to switch to AOO for now. See https://stackoverflow.com/a/27980255/5100564 for instructions. AOO does not have all the latest features that LO has, but it is a good solid Office product.
Apparently it is also possible to rebuild LibreOffice with python 2 using this script: https://gist.github.com/hbrunn/6f4a007a6ff7f75c0f8b