Python - чтение акселерометра, запись в CSV с использованием многопроцессорной обработки - PullRequest
0 голосов
/ 10 января 2019

Я пытаюсь использовать акселерометр MPU-6000 и Raspberry Pi 3 B для регистрации данных вибрации на лобовом стекле. Я довольно новичок в Python, поэтому, пожалуйста, потерпите меня.

После нескольких итераций я написал скрипт на Python 2, который должен использовать многопроцессорную обработку для чтения с сенсора и записи с помощью csv. План состоит в том, чтобы определить два процесса, где один прослушивает и захватывает данные акселерометра, а другой процесс записывает данные в файл CSV. Я использую события для запуска двух процессов: событие для захвата датчика дается прерыванием с помощью кнопки, а событие для записи csv - из процесса захвата датчика, когда его список достигает определенного значения. Содержимое списка помещается в очередь, которая должна быть прочитана процессом записи CSV. На данный момент очередь добавляется в новый список по прибытии, который затем должен быть добавлен в файл CSV. Если есть возможность добавить файл CSV непосредственно из очереди, пожалуйста, дайте мне знать.

На данный момент, похоже, что событие CSV установлено с произвольными интервалами по сравнению с тем, что я хотел бы сделать. Первоначально мой внутренний предел списка был 2460 записей, и был уменьшен в целях устранения неполадок. С пределом, например, 10 для внутреннего accel_list в listen_sens_data, событие CSV, кажется, устанавливается каждый раз, когда я вхожу в listen_sens_data, так как напечатанное «Состояние события CSV» является положительным. Кажется, что данные помещаются в очередь, но вызов q.get () непосредственно после помещения данных в очередь показывает, что первая точка данных отсутствует. Кроме того, только четыре следующих точки данных считываются из очереди, размер списка не имеет значения. Первоначальное тестирование показало, что функция csv_write_list была активна изначально на первой итерации, вызывая csv_event, но никакие данные, кроме фиктивных данных из других функций, не были записаны в файл CSV. Кто-нибудь видит очевидные ошибки, которые я сделал? И может ли быть более структурированный способ выполнения этой конкретной операции?

Сценарий приведен ниже, а картинки с запущенным сценарием приведены ниже.

#!/usr/bin/python
import smbus
import math
import csv
import time
import sys
import datetime
import RPi.GPIO as GPIO
import os

from multiprocessing import Queue, Process, Event


# Register addresses
power_mgmt_1 = 0x6b
power_mgmt_2 = 0x6c
samplerate_divider = 0x19
accel_config = 0x1C
I2C_mast_ctrl = 0x24
Mot_Det_Ctrl = 0x69
INT_Enable = 0x38

#Enable analog GPIO pins for LED control and push button ctrl
GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP)

GPIO.setwarnings(False)
GPIO.setup(17, GPIO.OUT)
GPIO.setup(27, GPIO.OUT)

GPIO.output(17, GPIO.HIGH)
GPIO.output(27, GPIO.HIGH)
time.sleep(2)
GPIO.output(17, GPIO.LOW)
GPIO.output(27, GPIO.LOW)


accel_status = 0
green_led_status=False

#Interrupt for starting measurement 
def start_meas_callback(channel):
    global accel_status

    accel_status = 1
    accel_event.set()

    print "Starting accelerometer measurements, logging to CSV file"

    GPIO.output(17, GPIO.HIGH)
    GPIO.output(27, GPIO.HIGH)

    return accel_event

GPIO.add_event_detect(23, GPIO.FALLING, callback=start_meas_callback, bouncetime=300)

#Interrupt for stopping measurement
def stop_meas_callback(channel):
    global accel_status
    global green_led_status
    accel_status = 0
    accel_event.clear()

    print "Accelerometer measurements stopped, written to CSV file"
    #Closing csv file
    csv_close()
    GPIO.output(17, GPIO.HIGH)
    GPIO.output(27, GPIO.HIGH)
    time.sleep(1)
    GPIO.output(27, GPIO.LOW)
    time.sleep(2)
    GPIO.output(17, GPIO.LOW)

    return accel_event

GPIO.add_event_detect(24, GPIO.FALLING, callback=stop_meas_callback, bouncetime=300)


#Read functions

def read_byte(reg):
    return bus.read_byte_data(address, reg)

def read_word(reg):
    h = bus.read_byte_data(address, reg)
    l = bus.read_byte_data(address, reg+1)
    value = (h <<8)+l
    return value

def read_word_2c(reg):
    val = read_word(reg)
    if (val >= 0x8000):
        return -((65535 - val) + 1)
    else:
        return val


csvwriter = None
filename_total =0
filepath_merge = 0 


#Opening / creating a CSV file
def csv_open():

    global filename_total
    global filepath_merge

    filename_time_raw = datetime.datetime.now()
    filename_time=filename_time_raw.strftime('%y-%m-%d--%H:%M:%S')
    filename_total='accel-data-'+filename_time+'.csv'
    filepath = os.path.dirname(os.path.abspath(filename_total))
    print "Absolute filepath"
    print filepath
    filepath_merge = os.path.join(filepath, filename_total)
    print "Merged filepath"
    print filepath_merge

    csvfile = open(filepath_merge, 'a')
    global csvwriter
    csvwriter = csv.writer(csvfile)

#Closing csv file   
def csv_close():
    global csvwriter
    global filepath_merge
    with open(filepath_merge, 'a') as csvfile:
        csvwriter.writerow(['File close',' file close',' file close',' file close'])
#Writing content to CSV file
def csv_write(timedelta, accelerometerx, accelerometery, accelerometerz):

    global csvwriter
    csvwriter.writerow([timedelta,  accelerometerx, accelerometery, accelerometerz])


#Write entire content from a list or Queue to CSV file
#def csv_write_list(accel_list_inp, csv_event):
def csv_write_list():
    global csvwriter
    #global accel_list
    #global green_led_status
    item = []
    print "waiting for CSV event"
    csv_event.wait()
    if csv_event.is_set():
        print " CSV_WRITE event captured!"
        print csv_event
        #for i in iter(q.get()):
            #item.append(q.get())
            #print "Q value is \n"
            #print q.get()
            # print i        
        print " \n Printing item list if for loop is passed: \n"
        print item 
        csvwriter.writerows(item)
        print "\n CSV file written? \n"
        #GPIO.output(27, GPIO.LOW)
        #GPIO.output(27, green_led_status)
        #green_led_status = not green_led_status
        #accel_list[:]=[]
        item [:] = []
        csv_event.clear()
    print "State of CSV event now: \n"
    print csv_event


#Extend list while sampling data
    def list_ext(timedelta_lst, accelerometerx_lst, accelerometery_lst, accelerometerz_lst):
    accel_list.extend([[timedelta_lst, accelerometerx_lst, accelerometery_lst, accelerometerz_lst]])
        #print (accel_list)


#Function to listen for sensor data. Will be used for multiprocess purpose
def listen_sens_data(accel_event):
    #global accel_status
    #global accel_list
    #global list_length


    green_led_status = True

    accel_list=[]
    list_length = 2460       

    while True:

            accel_event.wait()
            if accel_event.is_set():

                    data_interrupt_read =  bus.read_byte_data(address, 0x3A)

                    if data_interrupt_read == 1:

                            GPIO.output(27, GPIO.LOW)
                            GPIO.output(27, green_led_status)
                            green_led_status = not green_led_status


                            meas_time = datetime.datetime.now()

                            accelerometer_xout = read_word(0x3b)
                            accelerometer_yout = read_word(0x3d)
                            accelerometer_zout = read_word(0x3f)

                            #list_ext(meas_time, accelerometer_xout, accelerometer_yout, accelerometer_zout)
                            accel_list.extend([[meas_time, accelerometer_xout, accelerometer_yout, accelerometer_zout]])
                            print "State of CSV_event: \n"
                            print csv_event

                            if len(accel_list) == 10:
                                    print "accel_list being written \n"
                                    print accel_list

                                    map(q.put, accel_list)
                                    #csv_event.set()

                                    for i in iter(q.get()):
                                            print "Content of Q: \n"
                                            print q.get()

                                    accel_list[:]=[]
                                    print "state of CSV_event after set!!!!: \n"
                                    print csv_event
                                    print "acccel list empty?"
                                    print accel_list
                                    #return csv_event
                                    #GPIO.output(27, GPIO.LOW)
                                    #GPIO.output(27, green_led_status)
                                    #green_led_status = not green_led_status

                                    #break 
                                    #csv_write_list(accel_list)






#I2C settings 
bus = smbus.SMBus(1) # bus = smbus.SMBus(1) 
address = 0x69       # via i2cdetect



# Power management settings
bus.write_byte_data(address, power_mgmt_1, 0)
bus.write_byte_data(address, power_mgmt_2, 0x00)


#Configure sample-rate divider

#bus.write_byte_data(address, samplerate_divider, 0x0C)
bus.write_byte_data(address, samplerate_divider, 0xFF)

#Configure data ready interrupt:
bus.write_byte_data(address,INT_Enable, 0x01) 


#Opening csv file and getting ready for writing
csv_open()

csv_write('Time', 'X_Axis', 'Y_Axis', 'Z_Axis') 



print
print "Accelerometer"
print "---------------------"

print "This is multi-processing"
print "Write data to list, then to CSV"
print "Please push button 1 to start logging accelerometer data "
print "Push button 2 to stop logging accelerometer data"




if __name__ == '__main__':


    q = Queue(maxsize=0)
    accel_event = Event()
    csv_event = Event()
    csv_event.clear()

    p1=Process(target=listen_sens_data, args=(accel_event,) )

    #p2=Process(target=csv_write_list, args=(q, csv_event,))
    p2=Process(target=csv_write_list,)


    p1.start()
    p2.start()
    #q.close()
    #q2.close()
    #q.join_thread()
    #p1.join()
    #p2.join()

Вывод из окна терминала:

pi@raspberrypi:~ $ sudo python accel_pb_multipc.py
Absolute filepath
/home/pi
Merged filepath
/home/pi/accel-data-19-01-09--17:48:04.csv

Accelerometer
---------------------
This is multi-processing
Write data to list, then to CSV
Please push button 1 to start logging accelerometer data
Push button 2 to stop logging accelerometer data
waiting for CSV event
Starting accelerometer measurements, logging to CSV file
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:


<multiprocessing.synchronize.Event object at 0x761c6810>
accel_list being written

[[datetime.datetime(2019, 1, 9, 17, 48, 5, 594852), 52, 228, 47700],                 [datetime.datetime(2019, 1, 9, 17, 48, 5, 607713), 40, 208, 47760], [datetime.datetime(2019, 1, 9, 17, 48, 5, 639358), 96, 408, 47808], [datetime.datetime(2019, 1, 9, 17, 48, 5, 671228), 65532, 184, 47712], [datetime.datetime(2019, 1, 9, 17, 48, 5, 702824), 16, 232, 47700], [datetime.datetime(2019, 1, 9, 17, 48, 5, 734651), 124, 308, 47644], [datetime.datetime(2019, 1, 9, 17, 48, 5, 766272), 168, 136, 47588], [datetime.datetime(2019, 1, 9, 17, 48, 5, 798043), 324, 308, 47808], [datetime.datetime(2019, 1, 9, 17, 48, 5, 829792), 176, 212, 47644], [datetime.datetime(2019, 1, 9, 17, 48, 5, 861571), 65480, 160, 47848]]
Content of Q:

[datetime.datetime(2019, 1, 9, 17, 48, 5, 607713), 40, 208, 47760]
Content of Q:

[datetime.datetime(2019, 1, 9, 17, 48, 5, 639358), 96, 408, 47808]
Content of Q:

[datetime.datetime(2019, 1, 9, 17, 48, 5, 671228), 65532, 184, 47712]
Content of Q:

[datetime.datetime(2019, 1, 9, 17, 48, 5, 702824), 16, 232, 47700]
state of CSV_event after set!!!!:

<multiprocessing.synchronize.Event object at 0x761c6810>
acccel list empty?
[]
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:


<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
State of CSV_event:

<multiprocessing.synchronize.Event object at 0x761c6810>
accel_list being written

[[datetime.datetime(2019, 1, 9, 17, 48, 5, 893203), 88, 184, 47736], [datetime.datetime(2019, 1, 9, 17, 48, 5, 924978), 65516, 188, 47852], [datetime.datetime(2019, 1, 9, 17, 48, 5, 956636), 92, 220, 47728], [datetime.datetime(2019, 1, 9, 17, 48, 5, 988486), 132, 124, 47728], [datetime.datetime(2019, 1, 9, 17, 48, 6, 20205), 156, 172, 47944], [datetime.datetime(2019, 1, 9, 17, 48, 6, 51899), 92, 260, 47724], [datetime.datetime(2019, 1, 9, 17, 48, 6, 83681), 72, 320, 47840], [datetime.datetime(2019, 1, 9, 17, 48, 6, 115352), 108, 216, 47736], [datetime.datetime(2019, 1, 9, 17, 48, 6, 147018), 44, 228, 47708], [datetime.datetime(2019, 1, 9, 17, 48, 6, 178720), 36, 140, 47696]]
Content of Q:

[datetime.datetime(2019, 1, 9, 17, 48, 5, 766272), 168, 136, 47588]
Content of Q:

[datetime.datetime(2019, 1, 9, 17, 48, 5, 798043), 324, 308, 47808]
Content of Q:

[datetime.datetime(2019, 1, 9, 17, 48, 5, 829792), 176, 212, 47644]
Content of Q:

[datetime.datetime(2019, 1, 9, 17, 48, 5, 861571), 65480, 160, 47848]
state of CSV_event after set!!!!:

<multiprocessing.synchronize.Event object at 0x761c6810>
acccel list empty?
[]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...