0

I receive data from serial (pyserial) line by line.

Is it possible to put a condition for each new incoming line according to the previous line result ? exemple :

data3 == int(incoming_data_serial) + int(data2)

This is my current code I am editing with a previous answer deleted by its author. It works fine. It gives result like this :

[63, 0]
[64, 63]
[64, 64]
[63, 64]
[63, 63]
etc...

which is promising. But still I need to know how to incorporate an operator (substract for exemple) between those datas. Exemple : instead of [64, 63] I would like to get only one data of 64 - 63 meaning 1 !

This is my code :

#!/usr/bin/python

import serial
import time

ser = serial.Serial('/dev/ttyS1', 9600, timeout=0.1)

class _share:

def __init__(self):
    self.last_val = [0 for i in range(2)]

def calculate(self, val):
    #prepare data, convert
    self.last_data = val
    self.last_val = [self.last_data] + self.last_val[:-1]
    print((self.last_val))
    return self.last_val

share = _share()

def sensors(theimput):

    while True:
        try:
            time.sleep(0.01)
            ser.flushInput()
            sensor_reception = ser.readline()
            sensor_reception_split = sensor_reception.split()
            #data_sensor_milli = int(receptionsplit[3])
            data_sensor_pho_1 = int(sensor_reception_split[2])
            #data_sensor_tem_1 = int(receptionsplit[1])
            #data_sensor_hum_1 = int(receptionsplit[0])
            return str(share.calculate(data_sensor_pho_1))
        except:
            pass
        time.sleep(0.1)

f = open('da.txt', 'ab')

while 1:
    arduino_sensor = sensors('1')
    f.write(arduino_sensor)
    f.close()
    f = open('da.txt', 'ab')
  • Where is the condition in your example?...but generally speaking, yes; you can do that – Iron Fist Feb 06 '16 at 13:48
  • condition could be : "each time there s an incoming data then recalculate the value of this data by adding it to the previous line result" ... – pythonrocks Feb 06 '16 at 14:04

2 Answers2

0
#ser is the serial object
#data is the variable u want to update

def sensors(last_data):
    temp = []
    while True:
        c = ser.read()
        if not c:
            time.sleep(0.1)
            continue
        if c == '\n' or c == '\r':
            break
        temp.append(c)
    temp = ''.join(temp)
    print('Raw readings:', temp)
    new_data = [int(d) for d in temp.strip().split())]  
    data = [a+b for a, b in zip(last_data, new_data)]
    print('Last data: ', last_data)
    print('New data:', new_data)
    print('Current sum:', data)
    last_data = [i for i in new_data]
    return data, last_data

last_data = [0] * 4
f = open('da.txt', 'a')

while True:
    try:
        sensor_data, last_data = sensors(last_data)
        #last_data = [i for i in last_data]   #uncomment this if the code doesnt work as is
        f.write(sensor_data.__str__() + '\n')
    except:
        f.close()

This code assumes you want to add the last received line of sensor data to the current line of sensor data. This is NOT a running sum.

SoreDakeNoKoto
  • 1,175
  • 1
  • 9
  • 16
  • Thanks a lot ! I tried but I get this message : new_data = int.from_bytes(ser.read(), byteorder='big') AttributeError: type object 'int' has no attribute 'from_bytes' – pythonrocks Feb 06 '16 at 23:24
  • @pythonrocks I assume you're using Python 2? Find out the type of data returned by `ser.read()`; if its `str`, then use `int()` to cast it instead. I will edit my code to read a line before converting the data – SoreDakeNoKoto Feb 07 '16 at 01:29
  • @ TisteAndii : How would u incorporate your code into the one i edited ? – pythonrocks Feb 07 '16 at 13:29
  • @pythonrocks What type of data are you receiving? Strings? Or bytes? Show me what a line looks like – SoreDakeNoKoto Feb 07 '16 at 13:37
  • @ TisteAndii :I receive strings. The ser.readline() is like : "30 20 126 5026" (humidity, temperature, photocell, and milliseconds) but I split it in order to isolate datas. Then I get '126' only (for the photocell). This value is made via int() so that i can work with math operators on it. – pythonrocks Feb 07 '16 at 14:01
  • @ TisteAndii : nothing appears on interpreter. On file : First line is : [0, 0, 32, 33427] and then I get this : [ ] on each following lines. – pythonrocks Feb 07 '16 at 15:28
  • @pythonrocks I've edited the code. Edit your post so I can see your code. – SoreDakeNoKoto Feb 07 '16 at 15:35
  • Andii : I have edited my post trying to insert your code. But doesn't work : same than before. Getting : ('Last data: ', [33, 20, 25, 4128]) ('New data:', []) ('Current sum:', []) – pythonrocks Feb 09 '16 at 16:24
  • What version of python are you using? Are the results you showed me, the WHOLE result? A picture of the exact results on screen and in the file would be nice. – SoreDakeNoKoto Feb 09 '16 at 16:54
  • Version is 2.7.1 . This is part of the result (since input datas never stop coming in) and here is the screenshot : [Imgur](http://i.imgur.com/6HfpYQq.png) – pythonrocks Feb 09 '16 at 18:10
  • @pythonrocks ok...show me the first few results not the ones at the end, so I can track exactly what happened. The problem may have to do with Also what is sending the data being received? An arduino? Let me reduce the code to simply get lines of sensor readings and if it works, then we'll continue from there. It looks like u're using python 3 though – SoreDakeNoKoto Feb 09 '16 at 18:45
  • I found the solution to the first problem. In fact, first thing to do is to "flush" the serial buffer. Now your program runs better. (I edit my code with the buffer flushing line). Current sum is ok. But still strange things happen. Here is the result (screenshot) : [Imgur](http://i.imgur.com/pNvicMQ.png). – pythonrocks Feb 10 '16 at 12:58
  • Try this and report results. – SoreDakeNoKoto Feb 10 '16 at 13:32
  • The flushing makes sense, but you may accidentally flush your sensor data. What if you flush first and then send some unique agreed byte to the sender to indicate you are ready to receive before calling the `sensors()` function? – SoreDakeNoKoto Feb 10 '16 at 13:34
  • No I tried. Only works fine within the loop and right after the time.sleep(). – pythonrocks Feb 10 '16 at 14:02
  • For it to work, you will need to make changes to the code embedded in the sender. But thats by the way, have you tried my edited code? You can also increase the baud so u dont have to wait so long for bytes – SoreDakeNoKoto Feb 10 '16 at 14:06
  • Your code does not work still. The same results than before. To find a solution I propose you to include your code inside this one [Imgur](http://i.imgur.com/bjIVNCj.png) and to proceed as you said step by step... in order to debug little by little ? – pythonrocks Feb 11 '16 at 12:37
  • If I were with your PC, I'd be able to find out the exact source of the problem with a few `print()`s, but since that isnt the case, you'll have to settle for trying a few things and posting the results here. The code works for the first 2 readings and after that it stops. I need to see the raw readings obtained in each function call, so I can pinpoint the problem, which could even be related to your sender if i'm right. You say you're using Python 2.7.1 yet the print functions you're using indicate you are using Python 3. Perhaps we should move this to the chat section. – SoreDakeNoKoto Feb 11 '16 at 14:33
  • Python 2.7 is installed but I m using ninja IDE editor which is python 3 "oriented". Thats why u might be confused on some prints (I correct them to avoid a blue underline ... ). /// Chating ? why not ! seems a good idea ! – pythonrocks Feb 12 '16 at 18:13
  • edited latest code... only remaining to find the solution how to add or substract the two datas inside the range... – pythonrocks Feb 13 '16 at 11:32
  • Trying to put list(map(sum, self.last_val)) but does'nt work. – pythonrocks Feb 13 '16 at 11:42
  • Can you summarise *exactly* what you want to do with the data you get over the serial connection? – SoreDakeNoKoto Feb 13 '16 at 12:30
  • I m sure solution is around there but I don't know how to implement. http://stackoverflow.com/questions/29471260/sum-of-elements-stored-inside-a-tuple – pythonrocks Feb 13 '16 at 13:46
  • ok found the solution. See next answer. Thanks anyway for your help ! – pythonrocks Feb 13 '16 at 18:54
-1

The solution !

#!/usr/bin/python

import serial
import time
import operator

ser = serial.Serial('/dev/ttyS1', 9600, timeout=0.1)

class _share:

def __init__(self):
    self.last_val = [0 for i in range(2)]

def calculate(self, val):
    #prepare data, convert
    self.last_data = val
    self.last_val = [self.last_data] + self.last_val[:-1]
    b = reduce(operator.__sub__, self.last_val)
    print((b))
    return b

share = _share()

def sensors(theimput):

    while True:
        try:
            time.sleep(0.01)
            ser.flushInput()
            sensor_reception = ser.readline()
            sensor_reception_split = sensor_reception.split()
            #data_sensor_milli = int(receptionsplit[3])
            data_sensor_pho_1 = int(sensor_reception_split[2])
            #data_sensor_tem_1 = int(receptionsplit[1])
            #data_sensor_hum_1 = int(receptionsplit[0])
            return str(share.calculate(data_sensor_pho_1))
        except:
            pass
        time.sleep(0.1)

f = open('da.txt', 'ab')

while 1:
    arduino_sensor = sensors('1')
    f.write(arduino_sensor)
    f.close()
    f = open('da.txt', 'ab')