python printing out a array of bytes via serial port - python

I am kind a new to python and I am trying to print out an array of bytes which I am receiving via a serial interface.
The code Looks like this
print('Teststring')
ref.ser.write('outx=0\n'.encode())
ref.ser.flush()
s = self.ser.read(size=10)
print(s)
I am expecting the printout to look like this
Teststring
INPUT DATA (Input of my bytearray s)
So the behaviour is like I have an external device which I want to send an reply to my write/flush command and receive the data via the serial input and print out the received information on my computer.
Right now the issue is that the computer is not printing out the expected input data.
I guess my problem is that I need to convert the data s to a string or something like that?

Related

Send variable from LabVIEW 2016 to Rasperry Pi 3 via TCP/IP to incorperate in code

I am trying to create a few inputs in LabVIEW 2016 which a user can modify (eg. total frames = 100). This number will then be sent to and RPi3 unit which is running a basic TCP/IP server script. The idea is that these numbers will set the variables in a simple instrument control code. I can connect to the RPi in LabVIEW and can send a string but things break down there:
-the string seems to be sent as Decimal ASCII
-when decoded in python, the string is converted so that every character is a separate element, with a separate index (eg. if I send 100 I get str[0]=1, str[1]=0, str[2]=0, len(str)=3)
-i need to send several variables and several commands in one string and then unpack it in python so that I can call each one separately and assign it to the appropriate function
Any advice would be appreciated.
I would personally just create a cluster of your paramters in labview, then use 'flatten to json' and you can simply decode that in python into a object with each of your variables inside it.
in python, you can then easily load that config data
import json
# sample string, replace this with received data from client/server comms
config = '{'total frames': 100, 'rate': 30, 'additional': 'whatever'}'
newconfig = json.loads(config)
print( list(newconfig) ) # list of all the tuples
# ['total frames', 'rate', 'additional']
# to access any tuple
num_frames = newconfig['total frames']

Working with TCP sockets in Python

I need to:
1) Create a socket to a specific IP and Port
2) Send a string of data via the connection
3) Await the response and check it is valid
I have seen a lot of conflicting advice at the moment and so decided to ask a new question to try and clear this up.
I'm trying to use the socket library in Python to achieve this however am facing a couple of issues. I've tried a few different methods, however I am facing an issue sending the string of data. My data is in XML format so getting this as a string is proving difficult for me. I have attempted converting it to binary however would prefer it in plain text format, just that it should be as a string. Any pointers as to whether the code would fulfil the 3 steps I wish to complete would be perfect!
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('109.73.xxx.xxx', 29006))
s.sendall('*XML SHOULD GO HERE*')
data = s.recv(1024)
s.close()
print 'Received', repr(data)
I haven't got a response back from the server at the moment because I suspect of the erroneous format of the string of data sent. This means I haven't been able to check whether the code prints the response data from the server.
The XML data I need to pass as a string is in the following format:
<Message xmlns:xsi="http://www.w3.org/CANNOTPROVIDETHISURL" xmlns:xsd="http://www.w3.org/CANNOTPROVIDETHISURL">
<ClientHeader>
<element1>RC1234</element1>
<element2>1234</element2>
<element3>12345678</element3>
<element4>123456789</element4>
<element5>-1</element5>
<element6>-1</element6>
<element7>A123</element7>
<element8>TMS</element8>
</ClientHeader>
<MsgType>TYPE</MsgType>
<MsgData></MsgData>
</Message>

How to separate values received from a serial port and store it as separate variables in python?

I am new to python, to sensors and Stackoverflow. I am working on a project at my uni to read 4 sensor data on COM4 of my pc through pyserial. I wrote the below code to accomplish this:
import serial
ser = serial.Serial('COM4', 9600, timeout=5)
ser.write("\r".encode())
response = ser.read(60)
print (response)
ser.close()
I get the output something like:
b'reply:node01\r\n69\r\n45\r\n117\r\n994\r\n
Values 69,45,117,994 are readings from the 4 sensors respectively. I did some research and changed print (response) to print (response.decode('utf-8')) , now I get the output which looks like:
reply:node01
69
45
117
994
I really need some help in separating and storing the sensor values from my initial output or from the output that I received after adding print (response.decode('utf-8')) as separate variables, something like field1=69, field2=45, field3=117, field4=994. So that I can send this to thingspeak API:
https://api.thingspeak.com/update?api_key=XXXXXXXXXXXXXXXXXXX&field1=69&field=45&field3=117&field4=994
PS: Scalable - more number of sensors might be added at later stage of this project, so the number of data values received will also increase.
Please, I really need some help with this.
Good call on the conversion to text from bytes. Now suppose you store that decoded string, as in
my_str = response.decode('utf-8')
You can use the splitlines string method to get strings for each line:
field0, field1, field2, field3, field4 = my_str.splitlines()
Then you can interpolate those values into some template to give you the URL you want. If you'd prefer a list of the values, just use
fields = my_str.splitlines()

Convert received data in C++

I'm Working with Arduino (C++) and Raspberry Pi (Pyhon) with a RF module.
I've some doubts with the conversion of the data. I'm sending this data from Arduino:
unsigned long numbers = {12345678};
and Raspberry receive: 12345678
The library I'm using has a ackPayload function, so I can send data back like this:
akpl_buf = [c,1,2,3]
The c variable is just an incremental number.
Now, in the Arduino I receive this:
Received Ack:235802126
I use an static uint32_t variable to receive the answer to the raspberry and I printed it like this (In Arduino C++): printf("Received Ack:%lu\n\r",message_count);
The question is, how can I convert the received data? it should be like: 12,1,2,3 or 12123
Plus: what type of data is currently printing?
After some research and ask some people, I knew that the RF library returned the data in bytes so Received Ack:235802126 is the conversion from byte to unsigned long
so what I had to do was assign that data to a char array, and after that print it
char data[20];
importData(&data);
data[size+1] = '\0';
print data;
something like that.

python concatenate ctype struct and array

I am trying to implement a custom UDP protocol. This protocol has a header and data. The header has information about the structure of the data.
The header is defined using a ctypes struct and the data using 'h' array(signed short).
I am using python sockets.
I tried sending the header ans data using separate calls to "socket.sendto" like this:
s.sendto(header, addr)
s.sendto(data, addr)
But I am not able to receive this as a continuous stream. "socket.recvfrom" is only fetching the header. Maybe if I call "socket.recvfrom" again I will get the data as well. But thats not what I need. I need the full packet as a stream. I think concatenating the header and data in the server itself might fix this.
So I tried different combinations of the following to concatenate the two:
converting the header to "c_char_p" array.
Converting the data to bytearray
using numpy.concatenate
Standard array concatenation after converting the header to 'B' array.
Converting header to 'h' array. (This failed with "string length not a multiple of item size"
All the above failed for one reason or the other.
If I need to convert either header or data, I would prefer it to be the header as it is smaller. But if there is no way around, I am ok with converting the data.
Would appreciate any help.
Relevant code snippets:
sdata = array("h")
.
.
.
header=protocol.HEADER(1,50,1,50,1,50,1,50,1,10,1,12,1,1,1,1,1,18,19,10,35,60,85,24,25)
.
.
s.sendto(header+sdata, addr)
You can copy the header struct into a ctypes array of bytes:
>>> buf = (ctypes.c_char * ctypes.sizeof(header)).from_buffer_copy(header)
Now, in Python 2,
>>> buf.raw + sdata.tostring()
should give you what you're looking for.
In Python 3, it would be
>>> buf.raw + sdata.tobytes()

Categories