прямая заговор с использованием pyserial и matplotlib - PullRequest
1 голос
/ 25 ноября 2011

Я могу захватывать данные с последовательного устройства через pyserial, в настоящее время я могу экспортировать только данные в текстовый файл, текстовый файл имеет формат, как показано ниже, он имеет 3 столбца

>21 21 0 
>
>41 41 0.5
>
>73 73 1
>    
....
>2053 2053 5
>
>2084 2084 5.5
>
>2125 2125 6

Теперь я хочу использовать matplotlib для генерации live в графе 2 цифры (x, y) x, y - второй и третий столбец, первый столбец, '>', а в строках нет данных можно удалить

спасибо людям!

============================

Обновление: сегодня, после следуйте этим инструкциям от

http://www.blendedtechnologies.com/realtime-plot-of-arduino-serial-data-using-python/231 http://eli.thegreenplace.net/2008/08/01/matplotlib-with-wxpython-guis pyserial - Как прочитать последнюю строку, отправленную с последовательного устройства

теперь я могу жить на графике с многопоточностью, но Элибен сказал, что этот Guis каждый раз отображает только одно значение, что приводит к очень большому ограничению, потому что моя цель - построить 2 или 3 столбца, здесь код был изменен из смешанных технологий

Вот серийный обработчик: из потоков импортируй тему

import time
import serial

last_received = ''
def receiving(ser):
    global last_received
    buffer = ''
    while True:
        buffer = buffer + ser.read(ser.inWaiting())
        if '\n' in buffer:
            lines = buffer.split('\n') # Guaranteed to have at least 2 entries
            last_received = lines[-2]
            #If the Arduino sends lots of empty lines, you'll lose the
            #last filled line, so you could make the above statement conditional
            #like so: if lines[-2]: last_received = lines[-2]
            buffer = lines[-1]


class SerialData(object):
    def __init__(self, init=50):
        try:
            self.ser = ser = serial.Serial(
                port='/dev/ttyS0',
                baudrate=9600,
                bytesize=serial.EIGHTBITS,
                parity=serial.PARITY_NONE,
                stopbits=serial.STOPBITS_ONE,
                timeout=0.1,
                xonxoff=0,
                rtscts=0,
                interCharTimeout=None
            )
        except serial.serialutil.SerialException:
            #no serial connection
            self.ser = None
        else:
            Thread(target=receiving, args=(self.ser,)).start()

    def next(self):
        if not self.ser:
            return 100  #return anything so we can test when Arduino isn't connected
                #return a float value or try a few times until we get one
        for i in range(40):
            raw_line = last_received[1:].split(' ').pop(0)
            try:
                return float(raw_line.strip())
            except ValueError:
                print 'bogus data',raw_line
                time.sleep(.005)
        return 0.
    def __del__(self):
        if self.ser:
            self.ser.close()

if __name__=='__main__':
    s = SerialData()
    for i in range(500):
        time.sleep(.015)
        print s.next()

Для меня я изменил этот сегмент, чтобы он мог получить данные моего 1-го столбца

for i in range(40):
                raw_line = last_received[1:].split(' ').pop(0)
                try:
                    return float(raw_line.strip())
                except ValueError:
                    print 'bogus data',raw_line
                    time.sleep(.005)
            return 0.

и сгенерировать графовую базу по этим функциям в файле GUI

from Arduino_Monitor import SerialData as DataGen
def __init__(self):
        wx.Frame.__init__(self, None, -1, self.title)

        self.datagen = DataGen()
        self.data = [self.datagen.next()]

............................................... .

def init_plot(self):
        self.dpi = 100
        self.fig = Figure((3.0, 3.0), dpi=self.dpi)

        self.axes = self.fig.add_subplot(111)
        self.axes.set_axis_bgcolor('black')
        self.axes.set_title('Arduino Serial Data', size=12)

        pylab.setp(self.axes.get_xticklabels(), fontsize=8)
        pylab.setp(self.axes.get_yticklabels(), fontsize=8)

        # plot the data as a line series, and save the reference 
        # to the plotted line series
        #
        self.plot_data = self.axes.plot(
            self.data, 
            linewidth=1,
            color=(1, 1, 0),
            )[0]

Итак, мой следующий вопрос - как в реальном времени захватить как минимум 2 столбца и передать данные 2 столбцов в графический интерфейс, чтобы он мог генерировать график с 2 осями.

self.plot_data.set_xdata(np.arange(len(self.data)))  #my 3rd column data
self.plot_data.set_ydata(np.array(self.data))        #my 2nd column data

Ответы [ 3 ]

2 голосов
/ 29 ноября 2011

Ну, это читает вашу строку и конвертирует числа в числа с плавающей точкой. Я предполагаю, что вы сможете адаптировать это по мере необходимости.

import numpy as np
import pylab as plt

str = '''>21 21 0 
>
>41 41 0.5
>
>73 73 1
>
>2053 2053 5
>
>2084 2084 5.5
>
>2125 2125 6'''
nums = np.array([[float(n) for n in sub[1:].split(' ') if len(n)>0] for sub in str.splitlines() if len(sub)>1])

fig = plt.figure(0)
ax = plt.subplot(2,1,1)
ax.plot(nums[:,0], nums[:,1], 'k.')
ax = plt.subplot(2,1,2)
ax.plot(nums[:,0], nums[:,2], 'r+')
plt.show()
1 голос
/ 26 ноября 2011

Здесь у вас есть пример Эли Бендерского о том, как выводить данные, поступающие из последовательного порта

0 голосов
/ 26 августа 2016

некоторое время назад у меня была такая же проблема.Я потратил много времени на написание одного и того же материала снова и снова.поэтому я написал для него пакет python.

https://github.com/girish946/plot-cat

, вам просто нужно написать логику для получения данных из последовательного порта.

пример здесь:https://github.com/girish946/plot-cat/blob/master/examples/test-ser.py

...