Попытка отправки последовательных данных через Bluetooth от датчиков Arduino на Python - PullRequest
0 голосов
/ 16 февраля 2019
***Python code:***
import serial
import pandas as pd
import time
import re
import xlrd
from msvcrt import getch
import numpy as np
i = 0
x = 0
y = 0

df = pd.read_excel(r'C:\Users\lynchfamily\Desktop\mlglovesdata.xls')
# Read COM9
# Read from COM10 as well
# Readline() only works with a timeout (IMPORTANT)
serHC = serial.Serial('COM9', 115200,timeout=.250,parity=serial.PARITY_NONE,rtscts=1) # This is the JY
serRN = serial.Serial('COM10', 115200,timeout=.250,parity=serial.PARITY_NONE,rtscts=1) # This is the silvermate


def serialin():
    # Sensor lists
    sensor_names = list()
    sensor_values = list()
    global i
    # Read a certain amount of bytes from serial and then continue
    # Regular expressions for finding the proper data
    while i < 6:
        # print(i) for debugging
        global serHC
        global serRN
        #searchObj = re.search(r'(A\d?\d*)?(\d*)?',serHC.read(4).decode(),re.I)
        #searchObjRN = re.search(r'(A\d?\d*)?(\d*)?',serRN.read(4).decode(),re.I)
        # Serial data stops while in loop
        # The if statements keep the false values out of the program
        #if searchObj.group(1):
        sensor_names.append(serHC.read(2))
        #if searchObj.group(2):
        sensor_values.append(serHC.read(2))
        #if searchObjRN.group(1):
        sensor_names.append(serRN.read(2))
        #if searchObjRN.group(2):
        sensor_values.append(serRN.read(2))
        i = i + 1
    while 1:
        # Get the key from the msvcrt module
        key = getch().decode('ASCII')

        # If key is pressed, do something
        if key:
            print(key)
            # Zip them together
            # Final 2D list
            final_2d_list = zip(sensor_names,sensor_values)
            print(list(sorted(final_2d_list)))
            #vals = df.Dataframe([
            #df.append(vals)
            #print(sorted_array_1stdim[r])
            #sensor_values = [0] * 10
            # Thread for reading definition
            break
            # Fancy recursion
    sensor_values.clear()
    sensor_names.clear()
    i = 0
    serialin()
serialin()

Код Arduino:

// The device with green colored wires
void setup() {

  Serial.begin(115200);

}

void loop() {
   // It won't work with the I2C while loop for some reason. Perhaps it is getting stuck up on it

   Serial.print("A4");
   Serial.print(analogRead(0)); // Read the local analog signal
   delay(5);
   Serial.print("A5");
   Serial.print(analogRead(1)); // Read the local analog signal
   delay(5);
   Serial.print("A6");
   Serial.print(analogRead(2)); // Read the local analog signal
   delay(5);
   Serial.print("A7");
   Serial.print(analogRead(3)); // Read the local analog signal


}

Я пытаюсь отправить аналоговые данные с датчиков через bluetooth серебряный помощник от sparkfun,и HC-06 модули для Python.
Я должен читать аналоговые данные с задержкой в ​​5 секунд между каждым, чтобы показания не конфликтовали.
Данные поступают через последовательные порты COM9 и COM10.Я знаю, что последовательный порт в python может блокировать, поэтому я попытался сначала прочитать его, а затем поместить в список.
Я также знаю, что после прочтения последовательного интерфейса он, кажется, не блокируется.Когда я использовал serHC.readline() и serRN.readline(), я получал нечто похожее на то, что я ожидал увидеть.
Однако данные в списке не обновлялись в соответствии с изменением датчиков.Я должен признать, что python не является моим основным языком программирования, поэтому я и прошу помощи.
Я подумал, что, возможно, использование нескольких потоков может сработать, но я не смог получить serHC и serRN переменные в основном потоке.

Буду признателен за любую помощь !!

1 Ответ

0 голосов
/ 16 февраля 2019

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

Использование подхода, основанного на потоках.

Для начала должно быть достаточно следующего эскиза:

import serial
import time
import re
import threading

BYTES_TO_READ = 6

# read from serial port
def read_from_serial(board, port):
    print("reading from {}: port {}".format(board, port))
    payload = b''
    ser = serial.Serial(port, 115200,timeout=.250, parity=serial.PARITY_NONE, rtscts=1)
    bytes_count = 0
    while bytes_count < BYTES_TO_READ:
        read_bytes = ser.read(2)

        # sum number of bytes returned (not 2), you have set the timeout on serial port
        # see https://pythonhosted.org/pyserial/pyserial_api.html#serial.Serial.read
        bytes_count = bytes_count + len(read_bytes)
        payload = payload + read_bytes

    # here you have the bytes, do your logic
    # ...
    print("READ from {}: [{}]".format(board, payload))
    return


def main():

    board = {
        'JY': 'COM9',
        'SILVER': 'COM10'
    }

    threads = []
    for b in board:

        t = threading.Thread(target=read_from_serial, args=(b, board[b],))
        threads.append(t)
        t.start()

    # wait for all threads termination
    for t in threads:
        t.join()

main()

Для изучения потоков: https://pymotw.com/3/threading/

Периодическое чтение из сериалов

Ниже эскизадля чтения каждые TIME_PERIOD секунд.Для бесконечного цикла while вокруг чтения есть «нить» цикл с вложенным блоком try/catch для обнаружения проблем со связью последовательных каналов и повторной попытки подключения после TIME_PERIOD.

. Возьмем его в качестве исходного примера.!

import serial
import time
import re
import threading

BYTES_TO_READ = 6

TIME_PERIOD = 5

def read_message(board, port, handle):
    payload = b''
    bytes_count = 0
    while bytes_count < BYTES_TO_READ:
        read_bytes = handle.read(2)
        bytes_count = bytes_count + len(read_bytes)
        payload = payload + read_bytes
    # here you have the bytes, do your logic
    # ...
    print("READ from {}: [{}]".format(board, payload))

def serial_thread(board, port):
    print("reading from {}: port {}".format(board, port))

    while True:
        try:
            handle = serial.Serial(port, 115200,timeout=.250, parity=serial.PARITY_NONE, rtscts=1)

            while True:
                read_message(board, port, handle)
                time.sleep(TIME_PERIOD)
        except Exception as e:
            print("ERROR: {}".format(e))
            print("retrying in {} seconds".format(TIME_PERIOD))
            handle.close()
            time.sleep(TIME_PERIOD)

def main():
    board = {
        'JY': '/dev/ttyUSB0',
        'SILVER': '/dev/ttyACM0'
    }
    threads = []
    for b in board:
        t = threading.Thread(target=serial_thread, args=(b, board[b],))
        threads.append(t)
        t.start()
    # wait for all threads termination
    for t in threads:
        t.join()

main()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...