首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Python中的Raspberry Pi UART中断

Python中的Raspberry Pi UART中断
EN

Stack Overflow用户
提问于 2018-03-21 14:55:26
回答 1查看 2.8K关注 0票数 1

我正在尝试通过XBees收集来自3个Arduino节点(连接到一些传感器)的数据。3个Arduino节点分别连接到XBee系列1无线电设备(终端设备),而协调器连接到我的PC (但稍后将连接到树莓派2型号B)。

我在想,有没有办法在Raspberry Pi上用Python实现UART中断?这是因为,基于我下面的代码,我采用了轮询方法来读取来自我的3个Arduino传感器节点的数据。数据每秒从3个Arduino传感器节点传入,如下面的代码所示。

然而,我的轮询方法引起了一些问题,因为我只在代码的开头执行"arduino.readline()“,之后我将继续在Python代码中执行其他操作。

因此,我想知道是否有任何方法可以使用Python实现UART中断,以便每当有数据传入时,我都会执行一个arduino.readline(),然后继续处理数据。

我的代码如下:( Arduino代码对于所有3个节点都是相同的。)

Python代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import threading
import logging
import time
import serial
import csv
# Arduino; Arduino is now replaced by XBee modules
arduino = serial.Serial('COM18', 9600, timeout=1)  # Open serial port. By right, should check if it is open
def checker(field):
    if 'b' in field:
        field = field.replace('b', '')
    if 't' in field:
        field = field.replace('t', '')
    return field
def make_backup(finalmatrix, field_send, flag): # Back up the 2 most-recent data.
    matrix1 = []  # declares a list
    matrix1.append(flag) # appends the counter 'flag'
    matrix1.extend(field_send) # attaches the list to the end of current list; doesn't work with int
    # finalmatrix is a list of list; if len(finalmatrix) == 2 means: finalmatrix == [[1,2], [3,4]]
    if (len(finalmatrix) == 2):
        finalmatrix = finalmatrix[1:] # Create a new list, take the 2nd mini-list in the list and put it in the new list
        finalmatrix.append(matrix1) # appends the new matrix1
    else:
        finalmatrix.append(matrix1)
    return finalmatrix
def acquire_data():
    flag = 1
    finalmatrix = []
    count = 0
    while True:
        # data_in
        start_time = time.time()
        try:
            data_in = arduino.readline()  # read serial data from Arduino
            # logging.warning(data_in) # debugger
        except:
            pass
        global data_stripped
        data_stripped = data_in.strip()  # Removes spaces and \n
        for data_stripped in arduino:
            if data_stripped.startswith('b') and data_stripped.count(
                    ',') == 3:  # first char identifies where data is coming from; count commas to double-check incoming string
                field = data_stripped.split(',')  # split data to be put into 'boxes'
                bed_sen = field[0] + ',' + field[1] + ',' + field[2]  # We have 3 data sensor fields
                bed_sen_fill = True  # A flag to show that this if-statement has been completed
            if data_stripped.startswith('t') and data_stripped.count(',') == 3:
                field = data_stripped.split(',')
                table_sen = field[0] + ',' + field[1] + ',' + field[2]
                table_sen_fill = True
            if data_stripped.startswith('d') and data_stripped.count(',') == 3:
                field = data_stripped.split(',')
                door_sen = field[0] + ',' + field[1] + ',' + field[2]
                door_sen_fill = True
            try:
                if bed_sen_fill == True and table_sen_fill == True and door_sen_fill == True:
                    data_combi = bed_sen + ',' + table_sen + ',' + door_sen
                    break
            except:
                pass
        if data_combi:
            datasplit = data_combi.split(",")
            field1 = datasplit[0]
            field2 = datasplit[1]
            field3 = datasplit[2]
            field4 = datasplit[3]
            field5 = datasplit[4]
            field6 = datasplit[5]
           field7 = datasplit[6]  # To be deprecated in future; IR sensor no longer in use.
            field8 = datasplit[7]
            field9 = datasplit[8]
        # Removes 'b', 't' chars in strings
        field1 = checker(field1)
        field2 = checker(field2)
        field3 = checker(field3)
        field4 = checker(field4)
        field5 = checker(field5)
        field6 = checker(field6)
        field8 = checker(field8)
        field9 = checker(field9)
        ##### Data Validity Check #####
        field_send = []  # rearrange into list
        field_send.append(field1)
        field_send.append(field2)
        field_send.append(field3)
        field_send.append(field4)
        field_send.append(field5)
        field_send.append(field6)
        field_send.append(field7)
        field_send.append(field8)
        field_send.append(field9)
        if flag == 1:
            finalmatrix = make_backup(finalmatrix, field_send, flag)
            flag = flag + 1
        else:
            finalmatrix = make_backup(finalmatrix, field_send, flag)
            flag = 1
        # print finalmatrix
        if (count == 2 and int(field1) > 1000 or field1 == ''):  # If re-sends, 'b' will appear twice; light_val<1000 always.
            field1 = (int(finalmatrix[0][1]) + int(finalmatrix[1][1])) / 2
            # print ("Error1!")
        if (count == 2 and field2.count('-') == 2 or len(field2) > 3 or field2 == ''):  # If re-send, '-' will appear twice; field2 max 3 digits
            field2 = (int(finalmatrix[0][2]) + int(finalmatrix[1][2])) / 2
            # print ("Error2!")
        if (count == 2 and len(field3) > 1 or field3.count('01') == 1 or field3.count('10') == 1 or field3.count('-') == 1 or field3 == ''):  # Motion_sen is purely binary.
            field3 = (int(finalmatrix[0][3]) + int(finalmatrix[1][3])) / 2
            # print ("Error3!")
        if (count == 2 and int(field4) > 1000 or field4 == ''):  # If re-sends, 't' will appear twice; light_val<1000 always.
            field4 = (int(finalmatrix[0][4]) + int(finalmatrix[1][4])) / 2
            # print ("Error4!")
        if (count == 2 and field5.count('-') == 2 or len(field5) > 3 or field5 == ''):  # If re-send, '-' will appear twice; field5 max 3 digits
            field5 = (int(finalmatrix[0][5]) + int(finalmatrix[1][5])) / 2
            # print ("Error5!")
        if (count == 2 and len(field6) > 1 or field6.count('01') == 1 or field6.count('10') == 1 or field6.count('-') == 1 or field6 == ''):  # Motion_sen is purely binary.
            field6 = (int(finalmatrix[0][6]) + int(finalmatrix[1][6])) / 2
            # print ("Error6!")
        if (count == 2 and len(field8) > 1 or field8.count('01') == 1 or field8.count('10') == 1 or field8.count('-') == 1 or field8 == ''):  # Motion_sen is binary.
            field8 = (int(finalmatrix[0][8]) + int(finalmatrix[1][8])) / 2
            # print ("Error7!")
        if (count == 2 and len(field9) > 1 or field9.count('01') == 1 or field9.count('10') == 1 or field9.count('-') == 1 or field9 == ''):  # SW is binary too!
            field9 = (int(finalmatrix[0][9]) + int(finalmatrix[1][9])) / 2
            # print ("Error8!")
        with open('abs_testdatadiscrep4.csv', 'ab') as csvfile:  # 'ab' to remove newline char after each print
            writer = csv.writer(csvfile)
            sensor_fields = [field1, field2, field3, field4, field5, field6, field7, field8, field9,
                             time.strftime("%H%M%S")]
            if time.time() - start_time >= 1:
                writer.writerow(sensor_fields)
        count = count + 1
        if count == 2:
            count = 2
        print "My program took", time.time() - start_time, "to run"
        time.sleep(0.5)
        # print "My program took", time.time() - start_time, "to run"
def counting():
    while True:
        sum = 3 + 2
        sum2 = sum * 8
        time.sleep(0.2)
def on_light():
    strin = '1'
    arduino.write(strin.encode())
    print "Confirm ON"
def off_light():
    strin = '0'
    arduino.write(strin.encode())
    print "Confirm OFF"
# now threading1 runs regardless of user input
threading1 = threading.Thread(target = acquire_data)
threading2 = threading.Thread(target = counting)
threading1.start()
threading2.start()
while True:
    if raw_input() == 't':
        on_light()
        print "ON"
    if raw_input() == 'r':
        off_light()
        print "OFF"
    time.sleep(1)

Arduino代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <SoftwareSerial.h>

#define lightPin A0 // Light Sensor at Arduino A0 pin
#define echoPin 7 // Echo Pin
#define trigPin 8 // Trigger Pin
#define LEDPinUS 13 // LED at Pin 13 (Ultrasound)
#define pirPin 9 // Input for HC-S501
#define LEDPinPIR 12 // LED at Pin 12 (PIR)

SoftwareSerial xbee(2, 3); // RX, TX
int light ; //Value from light sensor
String lightID = "0";
String distanceUS = "0";
String pirID = "0";
String comma = ",";
int maximumRange = 150; // Maximum range needed
int minimumRange = 0; // Minimum range needed
long duration, distance; // Duration used to calculate distance
int OOR = 0; // OOR = Out of Range

int pirValue; // Place to store read PIR Value
int pirNum = 0;
int pirNumyes = 0;
int pirNumno = 0;

void setup() {
  Serial.begin(9600); //Baud rate must be the same as is on xBee module
  xbee.begin(9600);
  pinMode(lightPin, INPUT); // Light sensor
  pinMode(trigPin, OUTPUT); // Ultrasound sensor
  pinMode(echoPin, INPUT); // Ultrasound sensor
  pinMode(LEDPinUS, OUTPUT); // Ultrasound sensor indicator
  pinMode(pirPin, INPUT); // PIR sensor
  pinMode(LEDPinPIR, OUTPUT); // Ultrasound sensor indicator
  digitalWrite(LEDPinUS, LOW);
  digitalWrite(LEDPinPIR, LOW);
}

void loop() {
  // Light Sensor, "t" = table_sensors
  light = analogRead(lightPin);
  String ID = "t";
  lightID = ID + light + comma; //20-Mar-18: Added ","; disabled ',' printed serially
  // Ultrasound Sensor
  digitalWrite(trigPin, LOW); // clears Trigger pin
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  // Calculate the distance (in cm) based on the speed of sound.
  distance = duration / 58.2;
  if (distance >= maximumRange || distance <= minimumRange) {
    /* Send a negative number to computer and Turn LED ON
      to indicate "out of range" */
    OOR = -1;
    distanceUS = OOR + comma; //20-Mar-18: Added ","; disabled ',' printed serially; removed "+ ID"
    digitalWrite(LEDPinUS, HIGH);
  } else {
    /* Send the distance to the computer using Serial protocol, and
      turn LED OFF to indicate successful reading. */
    distanceUS = distance + comma; //20-Mar-18: Added ","; disabled ',' printed serially; removed "+ ID"
    digitalWrite(LEDPinUS, LOW);
  }
  // Motion sensor
  pirValue = digitalRead(pirPin);
  if (pirValue == HIGH) {
    pirNumyes = 1;
    pirID = pirNumyes + comma; //20-Mar-18: Added ","; disabled ',' printed serially; removed "+ ID"
    digitalWrite(LEDPinPIR, HIGH);
  } else {
    pirNumno = 0;
    pirID = pirNumno + comma; //20-Mar-18: Added ","; disabled ',' printed serially; removed "+ ID"
    digitalWrite(LEDPinPIR, LOW);
  }
  String together = lightID + distanceUS + pirID;
  //Serial.println(together);
  xbee.println(together);
  delay(1000);
}

我试过在谷歌上搜索答案,但似乎什么也找不到。我得到的最接近的答案来自Read serial data without high CPU use上的一个类似的StackOverflow帖子。

但是,我想问一下在Raspberry Pi上是否有针对UART中断的Python实现?

非常感谢您的帮助!:)

EN

回答 1

Stack Overflow用户

发布于 2018-12-04 01:05:35

如果您安装了从RX引脚到任何可用GPIO的额外导线,则至少可以使用RpiGPIO模块边缘中断来提醒您传输正在进行中。它不会告诉您缓冲区已满,当您处理GPIO中断时,您必须检查这一点。至少这将允许您执行其他操作,而不是在循环中等待和/或轮询UART以获取缓冲区数据。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49409615

复制
相关文章
MCU RAM空间不够用了怎么办?
之前使用沁恒公司的一款BLE芯片CH573,随着代码量的增多,开发到后期时遇到了RAM空间不够用的问题,当时吓了我一跳,以为需要重新换更大RAM的芯片。后来经过一番分析,优化之后省出来一部分空间,解决了RAM危机。
用户2366192
2024/04/24
3360
MCU RAM空间不够用了怎么办?
树莓派上运行 Stable Diffusion,260MB 的 RAM「hold」住 10 亿参数大模型
11 个月前 Stable Diffusion 诞生,它能够在消费级 GPU 上运行的消息让不少研究者备受鼓舞。不仅如此,苹果官方很快下场,将 Stable Diffusion「塞进」iPhone、iPad 和 Mac 中运行。这大大降低了 Stable Diffusion 对硬件设备的要求,让其逐渐成为人人都能使用的「黑科技」。
AiCharm
2023/09/06
3850
树莓派上运行 Stable Diffusion,260MB 的 RAM「hold」住 10 亿参数大模型
树莓派上运行 Stable Diffusion,260MB 的 RAM「hold」住 10 亿参数大模型
11 个月前 Stable Diffusion 诞生,它能够在消费级 GPU 上运行的消息让不少研究者备受鼓舞。不仅如此,苹果官方很快下场,将 Stable Diffusion「塞进」iPhone、iPad 和 Mac 中运行。这大大降低了 Stable Diffusion 对硬件设备的要求,让其逐渐成为人人都能使用的「黑科技」。
机器之心
2023/08/08
3610
树莓派上运行 Stable Diffusion,260MB 的 RAM「hold」住 10 亿参数大模型
Block RAM与Distributed RAM
Block RAM与Distributed RAM,简称为BRAM与DRAM, 要搞清楚两者的区别首先要了解FPGA的结构:
根究FPGA
2020/06/30
3.3K0
Block RAM与Distributed RAM
Netty空闲检测之读空闲
客户端与服务端通信的时候,服务端如何感知到客户端下线.客户端可以每4秒向服务端发送一个数据,服务端每5秒进行空闲检测.如果服务端没有读取到数据,则认为客户端已下线.(实际业务中并不会这么处理,我们这里只是为了描述场景)
书唐瑞
2022/06/02
7250
Netty空闲检测之读空闲
Netty空闲检测之写空闲
在之前的文章,我们介绍了Netty空闲检测之读空闲,以及为了介绍此篇文章,我们也特意写了一篇关于写操作的概括文章.读者对于Netty如何进行写操作也有了一个大概的认识了,接下来我们说一下,对于如何检测
书唐瑞
2022/06/02
6580
Netty空闲检测之写空闲
Android studio学习笔记:adb被系统空闲进程占用了怎么办?
在准备run的时候,adb server报错:Unable to open connection to ADB server: java.io.IOException: Can’t find adb server on port 5037, IPv4 attempt: Connection refused: connect, IPv6 attempt: Connection refused: connect 发现端口号5037被占用了,看网上的教程都是被一般进程给占用了,可以直接taskkill掉,空出端口,可是我的是系统进程,无法结束,就很麻。
全栈程序员站长
2022/11/01
7350
Android studio学习笔记:adb被系统空闲进程占用了怎么办?
FPGA block RAM和distributed RAM区别
区别之1 bram 的输出需要时钟,dram在给出地址后既可输出数据。 区别之2 dram使用根灵活方便些 区别之3 bram有较大的存储空间,dram浪费LUT资源 1.物理上看,bram是fpga中定制的ram资源,dram就是用逻辑单元拼出来的。 2.较大的存储应用,建议用bram;零星的小ram,一般就用dram。但这只是个一般原则,具体的使用得看整个设计中资源的冗余度和性能要求。 3.dram可以是纯组合逻辑,即给出地址马上出数据,也可以加上register变成有时钟的ram。而bram一定是
瓜大三哥
2018/02/26
2.1K0
占坑!利用 JenKins 持续集成 iOS 项目时遇到的问题
持续集成(Continuous Integration,简称CI)是一种软件开发实践:许多团队频繁地集成他们的工作,每位成员通常进行日常集成,进而每天会有多种集成。
DevOps时代
2018/08/01
2.6K0
占坑!利用 JenKins 持续集成 iOS 项目时遇到的问题
ram和rom的区别_RAM和ROM各有什么特点
  1、EPROM:(Electrically Programmable Read-Only-Memory)电可编程序只读存储器
全栈程序员站长
2022/09/16
2.2K0
ROM与RAM的区别
ROM、PROM、EPROM、EEPROM、NAND flash、NOR flash
Jasonangel
2021/05/28
2.5K0
Block RAM的基本结构
以UltraScale芯片为例,每个Block RAM为36Kb,由两个独立的18Kb Block RAM构成,如下图所示。
Lauren的FPGA
2019/10/31
3.6K0
单口RAM
单口RAM 只有一套数据总线、地址总线和读写控制线,因此当多个外设需要访问同一块单口RAM 时,需要通过仲裁电路来判断。 单口RAM,只有一套地址总线,读和写是分开(至少不能在同一个周期内完成)。下面给出一个8× 8 位RAM 的设计实例。 module ram_single( clk,addm,cs_n,we_n,din,dout ); input clk; input [2:0]addm; input cs_n; input we_n; input [7:0]din; outpu
瓜大三哥
2018/02/24
2.6K0
单口RAM
Linux吃掉了我的内存
在Windows下资源管理器查看内存使用的情况,如果使用率达到80%以上,再运行大程序就能感觉到系统不流畅了,因为在内存紧缺的情况下使用交换分区,频繁地从磁盘上换入换出页会极大地影响系统的性能。而当我们使用free命令查看Linux系统内存使用情况时,会发现内存使用一直处于较高的水平,即使此时系统并没有运行多少软件。这正是Windows和Linux在内存管理上的区别,乍一看,Linux系统吃掉我们的内存(Linux ate my ram),但其实这也正是其内存管理的特点。
马哥linux运维
2018/11/28
7280
区别MB1A MB1B MB1C MB11 MIGO
库存管理模块,MB1A MB1B MB1CMB11 MIGO事务代码可以用作生成收货、发货、转储等物料凭证,经常分不清用哪个事务代码最合适,现在对他们的区别说明一下。
用户5495712
2020/06/10
1.5K0
Understanding RAM Timings
RAM latency is CL-tRCD-tRP-tRAS-CMD latency. To understand them, bear in mind that the memory is internally organized as a matrix, where the data are stored at the intersection of the lines and columns.
用户9732312
2022/05/13
1.8K0
Understanding RAM Timings
如何实现一个RAM?(单端口RAM、伪双端口RAM、真双端口RAM|verilog代码|Testbench|仿真结果)
经典电路设计是数字IC设计里基础中的基础,盖大房子的第一部是打造结实可靠的地基,每一篇笔者都会分门别类给出设计原理、设计方法、verilog代码、Testbench、仿真波形。然而实际的数字IC设计过程中考虑的问题远多于此,通过本系列希望大家对数字IC中一些经典电路的设计有初步入门了解。能力有限,纰漏难免,欢迎大家交流指正。快速导航链接如下:
Loudrs
2023/05/31
7.3K0
如何实现一个RAM?(单端口RAM、伪双端口RAM、真双端口RAM|verilog代码|Testbench|仿真结果)
Linux内存被吃掉了,它去哪里了?
在Windows下资源管理器查看内存使用的情况,如果使用率达到80%以上,再运行大程序就能感觉到系统不流畅了,因为在内存紧缺的情况下使用交换分区,频繁地从磁盘上换入换出页会极大地影响系统的性能。而当我们使用free命令查看Linux系统内存使用情况时,会发现内存使用一直处于较高的水平,即使此时系统并没有运行多少软件。
小小科
2018/09/28
1.5K0
Block RAM的性能与功耗
设计中如果大量使用Block RAM,可通过一些综合属性管理RAM的实现方式以满足系统对性能与功耗的需求。以32Kx32bit RAM为例,目标芯片为UltraScale,通过使用综合属性cascade_height来管理Block RAM的级联高度,如下图所示。
Lauren的FPGA
2019/10/31
1.9K0
关于单片机的RAM
一块RAM 分为了 堆 和 栈   名词而已,知道就可以了, 各种内存溢出问题: 全局数组访问越界 出现的问题:直接重启,或者死机 解决办法 :  额,写好自己的程序吧!!!!!!! 函数的局部变量过
杨奉武
2019/10/17
1.3K0

相似问题

使用了交换,但是有空闲的RAM

10

基于空闲输出的RAM何时升级

10

减少RAM中的缓存内存和增加空闲内存

10

VPS中的Kmemsize问题,即使有大约500 mem的空闲mem

10

为什么“空闲”命令和"dmidecode“显示RAM的不同值?

30
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文