一、前言

这一节主要给大家分享一下树莓派部分的代码。

语言还是以python为主,简单益于理解,各种扩展库也很好用。而且对于我们这种比赛,小项目来说,能完成任务,实现功能就行。至于可靠性,效率等考虑都是其次的。
对于树莓派遇到的一些环境安装呀等问题我这里就不做过多的解释。网上资料一搜一大把,只是可能需要自己整理筛选,获取自己想要的部分。当然,收藏夹里也有一些之前踩坑的解决文章。稍后整理一下就挂上来。

二、Python实现封装打包自己写的代码

得先说一下这个,因为学51,32单片机入得门,所以格外的注重不同功能函数的放置,也就养成了习惯。我们知道,以32来说,都会有一个文件夹,放我们自己写的功能代码,然后每个文件夹有单独的.c和.h文件。这样子我们在keil中用的时候,直接在编译器设置好头文件,就可以互相调用,然后在每个功能模块中include对应的头文件就可以直接引用了。
那Python呢?一般都是import***from***,不打包一般放在同一目录下,可能可以直接用,有时候又不行。具体啥原因我这门外汉也不懂。反正咋们多做一个打包工作,咋们自己写的脚本也可以拿来用了。 而且树莓派我是直接用的里面自带一个编译器写的代码(叫啥忘了),脚本语言就是方便,写完直接python .py 就能跑。不像是在ROS里写C++代码,每次都要手动编译一样。 后面在jetson里面还直接用的pycharm写,更方便。

参考链接

Python实现封装打包自己写的代码
这篇文章是我收藏的,应该是十分详细而且能用的,所以按照步骤来一步步做就能成功。

我的参考

在这里插入图片描述
这个就是我最终工程文件。拷贝出来说一下:

其中buid ,-inof,dist几个文件都是自动生成的,另外除了All_main.py是主函数以外,剩下的几个main函数都是我对各个模块单独调试用的,可以忽略。所以原始文件就全部放在refuse文件夹下面,在refuse文件夹再新建一个_init_.py脚本。
在这里插入图片描述

init.py

# -*- coding: utf-8 -*-
#!/usr/bin/env python
 
def run():
    print ('This is a run package!')
if __name__ == '__main__':
    run()

setup.py

from setuptools import find_packages,setup
setup(
  name = 'motor.py',
  version = '1.0',
  packages = find_packages(),
)
setup(
  name = 'paj7260.py',
  version = '1.0',
  packages = find_packages(),
)
setup(
  name = 'ultrasonic.py',
  version = '1.0',
  packages = find_packages(),
)
setup(
  name = 'myserial.py',
  version = '1.0',
  packages = find_packages(),
)
setup(
  name = 'display.py',
  version = '1.0',
  packages = find_packages(),
)
setup(
  name = 'key.py',
  version = '1.0',
  packages = find_packages(),
)

注:整理完之前写的各个功能函数代码,发现写的很多地方风格不太好,而且有些地方逻辑上有bug。 下面的代码都是当初初学python写的,一边参考别人的代码,一边看菜鸟教程写的,所以有些地方的语法不太规范,所以大佬勿取笑,有误可以指出。整理这些主要学习交流用,给后面的学弟学妹做参考!(手动狗头)

三、 树莓派的硬件解码播放器——Omxplayer

播放视频音频的软件在树莓派中调用还是很多的,但是找了一圈想要在程序中调用,还是这个软件好用。先看这篇文章,也是在收藏夹里,还算是详细。(ps我记得当时安装这个,弄环境弄了好久,具体因为啥我也忘了,好像wget不好下,而且当时下了安装成功。但是用的时候提示找不到模块,反正具体因为什么我忘记,后来找到whl包安装才成功,我文件夹里还有,后面一起打包上传到我的资源)

Omxplayer的安装使用1
omxplayer的安装与使用2

至于代码,简单的一匹。

from omxplayer import OMXPlayer
from pathlib import path
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)
GPIO.setup(40, GPIO.IN)

VIDEO_PATH = Path("/home/pi/Refuse-Classification/rubbish/Earth-Song.mp4")
player = OMXPlayer(VIDEO_PATH, args = '-b -o local' )    
#执行完这一语句就进入WUILE循环,下面代码的意思是40引脚拉高时退出循环,然后播放停止
#我后面洗的代码类似,手势模块检测有物体靠近就停止
while Ture:
	if (GPIO.input(40) == GPIO.HIGH):
		break
player.quit()

四、树莓派控制舵机,驱动L298N控制电机

这里的电机用了L298N电机驱动板,这板子不太好用,发热严重,当时用的外接12V电源控制两个大电机,各种操作不当烧了几块。有可能可以买贵一点的电机驱动板。
在这里插入图片描述

测试代码motor_main.py(三个电机,两个舵机)

from refuse import motor
import RPi.GPIO as GPIO
import time


#底部电机
INT1 = 11
INT2 = 40
ENA = 16

GPIO.setup(INT1,GPIO.OUT)
GPIO.setup(INT2,GPIO.OUT)
GPIO.setup(ENA,GPIO.OUT)

#压缩电机
INT3 = 13
INT4 = 15
ENB = 18

#拉伸电机
INT5 = 29
INT6 = 31
ENC = 33

motor = motor.Motor()

#a = tkey.pressed()

motor.Bomotor_po(INT1,INT2,ENA,1.85)
motor.Bomotor_ne(INT1,INT2,ENA,1.87)

#motor.Bomotor_ne(INT1,INT2,ENA,1.87)
#motor.Bomotor_po(INT1,INT2,ENA,1.85)

#motor.Pumotor_po(INT3,INT4,ENB,12)
#motor.Pumotor_ne1(INT3,INT4,ENB,10)
#motor.Pumotor_ne(INT3,INT4,ENB)
#motor.Pumotor_po(INT3,INT4,ENB,0.5)
print('ok')

    
#motor.Drmotor_po(INT5,INT6,ENC,1.56)
#motor.Drmotor_ne(INT5,INT6,ENC,3.56)

#motor.server()

#motor.Drmotor_po(INT5,INT6,ENC,3.56)
#motor.server()                               #舵机开合
#motor.Pumotor_po(INT3,INT4,ENB,10)
#time.sleep(0.5)
#motor.Pumotor_ne(INT3,INT4,ENB)
#motor.Pumotor_po(INT3,INT4,ENB,0.5)
#motor.Drmotor_ne(INT5,INT6,ENC,3.56)  

moter.py

import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
#底部电机
INT1 = 11
INT2 = 40
ENA = 16
GPIO.setup(INT1,GPIO.OUT)
GPIO.setup(INT2,GPIO.OUT)
GPIO.setup(ENA,GPIO.OUT)
#压缩电机
INT3 = 13
INT4 = 15
ENB = 18
GPIO.setup(INT3,GPIO.OUT)
GPIO.setup(INT4,GPIO.OUT)
GPIO.setup(ENB,GPIO.OUT)
#拉伸电机
INT5 = 29
INT6 = 31
ENC = 33
GPIO.setup(INT5,GPIO.OUT)
GPIO.setup(INT6,GPIO.OUT)
GPIO.setup(ENC,GPIO.OUT)
#触碰开关
GPIO.setup(7, GPIO.OUT)
channel = 35

class Motor():
#舵机
    def server(self):
        p = GPIO.PWM(7,50)  #创建一个 PWM 实例,p = GPIO.PWM(channel, frequency)
        p.start(0)			#调节占空比
        time.sleep(0.2)
        while 1:
            p.ChangeDutyCycle(8.19)		#更改占空比,可以改变转速
            time.sleep(1.5)
            p.ChangeDutyCycle(2.69)
            time.sleep(1.5)
            p.ChangeDutyCycle(0) 
            break
            
#电机
    def Bomotor_po(self, num1, num2, num3, potime):
        pwma = GPIO.PWM(ENA,80)
        pwma.start(90)
        GPIO.output(num1,GPIO.LOW)
        GPIO.output(num2,GPIO.HIGH)
        while 1:
            pwma.ChangeDutyCycle(100)
            time.sleep(potime)
            while 1:
                GPIO.output(num1, GPIO.LOW)
                GPIO.output(num2, GPIO.LOW)
                GPIO.output(num3, GPIO.LOW)
                time.sleep(0.5)
                break
            break
    def Bomotor_ne(self, num1, num2, num3, potime):
        pwma = GPIO.PWM(ENA,80)
        pwma.start(90)
        GPIO.output(num1,GPIO.HIGH)
        GPIO.output(num2,GPIO.LOW)
        while 1:
            pwma.ChangeDutyCycle(100)
            time.sleep(potime)
            while 1:
                GPIO.output(num1, GPIO.LOW)
                GPIO.output(num2, GPIO.LOW)
                GPIO.output(num3, GPIO.LOW)
                time.sleep(0.5)
                break
            break
    def Pumotor_po(self, num1, num2, num3, potime):
        pwmb = GPIO.PWM(ENB,99)
        pwmb.start(99)
        GPIO.output(num1,GPIO.LOW)
        GPIO.output(num2,GPIO.HIGH)
        while 1:
            pwmb.ChangeDutyCycle(99)
            time.sleep(potime)
            while 1:
                GPIO.output(num1, GPIO.LOW)
                GPIO.output(num2, GPIO.LOW)
                GPIO.output(num3, GPIO.LOW)
                break
            break
#这里是压缩电机,在结构上我加了一个触碰开关
#用于检测压缩杆是否归位,
    def Pumotor_ne(self, num1, num2, num3):
        GPIO.setup(channel, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
        #注册一个事件用于检测status是否发现
        GPIO.add_event_detect(channel, GPIO.RISING, bouncetime = 200)
        pwmb = GPIO.PWM(ENB,99)
        pwmb.start(99)
        GPIO.output(num1,GPIO.HIGH)
        GPIO.output(num2,GPIO.LOW)
        while 1:
            pwmb.ChangeDutyCycle(99)
            a = GPIO.event_detected(channel)
            print(a)
            while 1:
                if GPIO.event_detected(channel) == True:
                    print('OK**')
                    break
                time.sleep(0.01)
            while 1:
                GPIO.output(num1, GPIO.LOW)
                GPIO.output(num2, GPIO.LOW)
                GPIO.output(num3, GPIO.LOW)
                time.sleep(0.5)
                break
            break
    def Pumotor_ne1(self, num1, num2, num3, potime):
        pwmb = GPIO.PWM(ENB,99)
        pwmb.start(99)
        GPIO.output(num1,GPIO.HIGH)
        GPIO.output(num2,GPIO.LOW)
        while 1:
            pwmb.ChangeDutyCycle(99)
            time.sleep(potime)
            while 1:
                GPIO.output(num1, GPIO.LOW)
                GPIO.output(num2, GPIO.LOW)
                GPIO.output(num3, GPIO.LOW)
                break
            break
    def Drmotor_po(self, num1, num2, num3, potime):
        pwmc = GPIO.PWM(ENC,80)
        pwmc.start(90)
        GPIO.output(num1,GPIO.LOW)
        GPIO.output(num2,GPIO.HIGH)
        while 1:
            pwmc.ChangeDutyCycle(100)
            time.sleep(potime)
            while 1:
                GPIO.output(num1, GPIO.LOW)
                GPIO.output(num2, GPIO.LOW)
                GPIO.output(num3, GPIO.LOW)
                time.sleep(0.5)
                break
            break
    def Drmotor_ne(self,num1, num2, num3, potime):
        pwmc = GPIO.PWM(ENC,80)
        pwmc.start(90)
        GPIO.output(num1,GPIO.HIGH)
        GPIO.output(num2,GPIO.LOW)
        while 1:
            pwmc.ChangeDutyCycle(100)
            time.sleep(potime)
            while 1:
                GPIO.output(num1, GPIO.LOW)
                GPIO.output(num2, GPIO.LOW)
                GPIO.output(num3, GPIO.LOW)
                time.sleep(0.5)
                break
            break

五、树莓派串口通信

myserial.py

import serial
import time
ser = serial.Serial("/dev/ttyAMA0",115200)
if ser.isOpen == False:
    ser.open()                # 打开串口
serlist =  []
class myserial():
    def ser(self):
        try:
            count2 = 0
            serlist.clear()
            while True:
                ser.flushInput()
                time.sleep(0.1)
                count1 = ser.inWaiting()
                if count1 == 1:
                    global a
                    a = str(ser.read(count1),encoding='utf-8')
                    if count2 < 3:
                        serlist.append(a)
                        count2 += 1
                    print(a)
            #这里简单的做了一个判断,判断三次接收到的结果是否一致,等待识别稳定
                if count2 == 3:
                    if serlist[0] == serlist[1] == serlist[2]:
                        return serlist[0]
                        break
                    else:
                        count2 = 0
                        serlist.clear()
                time.sleep(0.2)
        except KeyboardInterrupt:
            if ser != None:
                ser.close()

myserial_main.py

from refuse import myserial
import time

myser = myserial.myserial()
a = myser.ser()
print(a)

六、树莓派检测超声波

ultrasonic.py

这里没注释,如果有看不懂的,自行百度!

import time
import RPi.GPIO as GPIO
trigger_pin = 36
echo_pin = 38
GPIO.setmode(GPIO.BOARD)
class ultrasonic():       
    def send_trigger_pulse(self):
        GPIO.setup(trigger_pin,GPIO.OUT)
        GPIO.output(trigger_pin,True)
        time.sleep(0.00015)
        GPIO.output(trigger_pin,False)
    def wait_for_echo(self, value,timeout):
        GPIO.setup(echo_pin,GPIO.IN)
        self.count = timeout
        while GPIO.input(echo_pin) != value and self.count>0:
            self.count = self.count-1
    def get_distance(self):
        self.send_trigger_pulse()
        self.wait_for_echo(True,10000)
        start = time.time()
        self.wait_for_echo(False,10000)
        finish = time.time()
        self.pulse_len = (finish-start)*340/2*100  //根据光速算时间
        distance_cm = self.pulse_len
        return distance_cm

ultrasonic_main.py

from refuse import ultrasonic
import time
from PIL import Image
from omxplayer import OMXPlayer
from refuse import display
mydis = display.display()

music_path = '/home/pi/RefuseClassification/test/warining.mp3'
img5 = Image.open('/home/pi/rubbish/warning.png')
img4 = Image.open('/home/pi/rubbish/can.png')
dislist =  []
distance = ultrasonic.ultrasonic()
discount = 0
dislist.clear()
while True:
    print('ok')    
    while True:   
        dist = distance.get_distance()
        #这里是算三次测试的平均
        if discount < 3:
            dislist.append(dist)
            discount += 1
            if discount == 3:
                disnum = (dislist[0]+dislist[1]+dislist[2]) / 3
                #如果连续测试距离小于10,则认为物体靠近(针对溢满检测)
                if disnum < 10:
                    mydis.Pdisplay(img4)
                    player = OMXPlayer(music_path, args = '-b -o local' )                   
                    break
                else:
                    dislist.clear()
                    discount = 0
                    break    
        time.sleep(0.1)

七、paj7620手势传感器

具体的参考资料可以查看这篇文章,写的很详细。
PAJ7620U2手势识别模块 使用教程

在这里插入图片描述

简单说一下这个模块,它有个很小的镜头,还有个光感,所以他有两个功能,其一:就是检测手势,好像是可以识别8种手势,上下左右,画圈什么的,效果呢,将就用,我都测试过。其二:就是他可以检测物体靠近,输出光线强度和面积,进而判断,这个比超声波稳定,出错几率也比较小,所以用到了这个模块。

paj7620.py

import time
import smbus
#i2c地址
PAJ7620U2_I2C_ADDRESS   = 0x73
#寄存器选择
PAJ_BANK_SELECT         = 0xEF
#寄存器第0组
PAJ_SUSPEND             = 0x03
PAJ_INT_FLAG1_MASK      = 0x41
PAJ_INT_FLAG2_MASK      = 0x42
PAJ_INT_FLAG1           = 0x43
PAJ_INT_FLAG2           = 0x44
PAJ_STATE               = 0x45
PAJ_PS_HIGH_THRESHOLD   = 0x69
PAJ_PS_LOW_THRESHOLD    = 0x6A
PAJ_PS_APPROACH_STATE   = 0x6B
PAJ_PS_DATA             = 0x6C
PAJ_OBJ_BRIGHTNESS      = 0xB0
PAJ_OBJ_SIZE_L          = 0xB1
PAJ_OBJ_SIZE_H          = 0xB2
#寄存器第1组
PAJ_PS_GAIN             = 0x44
PAJ_IDLE_S1_STEP_L      = 0x67
PAJ_IDLE_S1_STEP_H      = 0x68
PAJ_IDLE_S2_STEP_L      = 0x69
PAJ_IDLE_S2_STEP_H      = 0x6A
PAJ_OPTOS1_TIME_L       = 0x6B
PAJ_OPTOS2_TIME_H       = 0x6C
PAJ_S1TOS2_TIME_L       = 0x6D
PAJ_S1TOS2_TIME_H       = 0x6E
PAJ_EN                  = 0x72
#手势检测的中断标志
PAJ_UP                  = 0x01 
PAJ_DOWN                = 0x02
PAJ_LEFT                = 0x04 
PAJ_RIGHT               = 0x08
PAJ_FORWARD             = 0x10 
PAJ_BACKWARD            = 0x20
PAJ_CLOCKWISE           = 0x40
PAJ_COUNT_CLOCKWISE     = 0x80
PAJ_WAVE                = 0x100
#开机初始化数组
Init_Register_Array = (
    (0xEF,0x00),
    (0x37,0x07),
    (0x38,0x17),
    (0x39,0x06),
    (0x41,0x00),
    (0x42,0x00),
    (0x46,0x2D),
    (0x47,0x0F),
    (0x48,0x3C),
    (0x49,0x00),
    (0x4A,0x1E),
    (0x4C,0x20),
    (0x51,0x10),
    (0x5E,0x10),
    (0x60,0x27),
    (0x80,0x42),
    (0x81,0x44),
    (0x82,0x04),
    (0x8B,0x01),
    (0x90,0x06),
    (0x95,0x0A),
    (0x96,0x0C),
    (0x97,0x05),
    (0x9A,0x14),
    (0x9C,0x3F),
    (0xA5,0x19),
    (0xCC,0x19),
    (0xCD,0x0B),
    (0xCE,0x13),
    (0xCF,0x64),
    (0xD0,0x21),
    (0xEF,0x01),
    (0x02,0x0F),
    (0x03,0x10),
    (0x04,0x02),
    (0x25,0x01),
    (0x27,0x39),
    (0x28,0x7F),
    (0x29,0x08),
    (0x3E,0xFF),
    (0x5E,0x3D),
    (0x65,0x96),
    (0x67,0x97),
    (0x69,0xCD),
    (0x6A,0x01),
    (0x6D,0x2C),
    (0x6E,0x01),
    (0x72,0x01),
    (0x73,0x35),
    (0x74,0x00),
    (0x77,0x01),
)
#方法注册初始化数组
Init_PS_Array = (
    (0xEF,0x00),
    (0x41,0x00),
    (0x42,0x00),
    (0x48,0x3C),
    (0x49,0x00),
    (0x51,0x13),
    (0x83,0x20),
    (0x84,0x20),
    (0x85,0x00),
    (0x86,0x10),
    (0x87,0x00),
    (0x88,0x05),
    (0x89,0x18),
    (0x8A,0x10),
    (0x9f,0xf8),
    (0x69,0x96),
    (0x6A,0x02),
    (0xEF,0x01),
    (0x01,0x1E),
    (0x02,0x0F),
    (0x03,0x10),
    (0x04,0x02),
    (0x41,0x50),
    (0x43,0x34),
    (0x65,0xCE),
    (0x66,0x0B),
    (0x67,0xCE),
    (0x68,0x0B),
    (0x69,0xE9),
    (0x6A,0x05),
    (0x6B,0x50),
    (0x6C,0xC3),
    (0x6D,0x50),
    (0x6E,0xC3),
    (0x74,0x05),
)
#手势注册初始化数组
Init_Gesture_Array = (
    (0xEF,0x00),
    (0x41,0x00),
    (0x42,0x00),
    (0xEF,0x00),
    (0x48,0x3C),
    (0x49,0x00),
    (0x51,0x10),
    (0x83,0x20),
    (0x9F,0xF9),
    (0xEF,0x01),
    (0x01,0x1E),
    (0x02,0x0F),
    (0x03,0x10),
    (0x04,0x02),
    (0x41,0x40),
    (0x43,0x30),
    (0x65,0x96),
    (0x66,0x00),
    (0x67,0x97),
    (0x68,0x01),
    (0x69,0xCD),
    (0x6A,0x01),
    (0x6B,0xB0),
    (0x6C,0x04),
    (0x6D,0x2C),
    (0x6E,0x01),
    (0x74,0x00),
    (0xEF,0x00),
    (0x41,0xFF),
    (0x42,0x01),
)
class PAJ7620U2(object):
    def __init__(self,address=PAJ7620U2_I2C_ADDRESS):
        self._address = address
        self._bus = smbus.SMBus(1)
        time.sleep(0.5)
        if self._read_byte(0x00) == 0x20:
            print("\nGesture Sensor OK\n")
            for num in range(len(Init_Register_Array)):
                self._write_byte(Init_Register_Array[num][0],Init_Register_Array[num][1])
        else:
            print("\nGesture Sensor Error\n")
        self._write_byte(PAJ_BANK_SELECT, 0)
        for num in range(len(Init_PS_Array)):
                self._write_byte(Init_PS_Array[num][0],Init_PS_Array[num][1])
        self._write_byte(PAJ_BANK_SELECT, 0)
    def _read_byte(self,cmd):
        return self._bus.read_byte_data(self._address,cmd)
    def _read_u16(self,cmd):
        LSB = self._bus.read_byte_data(self._address,cmd)
        MSB = self._bus.read_byte_data(self._address,cmd+1)
        return (MSB << 8) + LSB
    def _write_byte(self,cmd,val):
        self._bus.write_byte_data(self._address,cmd,val)
    def check_gesture_B(self):
        OBJ_BRIGHTNESS  =   self._read_byte(PAJ_OBJ_BRIGHTNESS)
        return OBJ_BRIGHTNESS
    def check_gesture_S(self):
        OBJ_SIZE        =   self._read_u16(PAJ_OBJ_SIZE_L)
        return OBJ_SIZE

八、树莓派检测轻触开关(实际就是检测开关的高低电平, GPIO.add_event_detect相关功能函数自行百度学习)

# -*- coding: utf-8 -*-
from RPi import GPIO
import time
GPIO.setmode(GPIO.BOARD)
# 关闭警告
GPIO.setwarnings(False)
channel = 35
# 设置GPIO输入模式, 使用GPIO内置的上拉电阻, 即开关断开情况下输入为HIGH
#GPIO.setup(channel, GPIO.IN, pull_up_down = GPIO.PUD_UP)
# 检测HIGH -> LOW的变化
#GPIO.add_event_detect(channel, GPIO.FALLING, bouncetime = 200)
class mykey():    
    def pressed(self):
#        GPIO.setup(channel, GPIO.IN, pull_up_down = GPIO.PUD_UP)
#        GPIO.add_event_detect(channel, GPIO.FALLING, bouncetime = 200)
        while True:
            # 如果检测到电平FALLING, 说明开关闭合
            if GPIO.event_detected(channel):
                print('ok1')
                return 1
                break
            time.sleep(0.01)     # 10毫秒的检测间隔
GPIO.cleanup()

九、主函数(这里我就不列完整代码了,写的可能有些水,怕影响大家,简单的梳理一下思路)

(1)首先我一直循环播放视频,然后手势传感器会一直检测,如果检测到两个参数变大,说明有遮挡,就是有人靠近(传感器我们放在了投递口的位置),直到连续三次检测到数值变小,那么就停止播放视频,程序往下走。
这里只是检测靠近,其实如果出现有人在远处扔垃圾,那么这里检测就会无效,所以我考虑过使用一个测重传感器,检测到有质量,配合上面的人体感应,可能效果会更好。我也买来测试过,这里就不罗列了,大家可以讨论交流。

i=1
player = OMXPlayer(VIDEO_PATH, args = '-b -o local' )    
while i < 3:
    time.sleep(0.1)  
    bright = gesture.check_gesture_B()
    size = gesture.check_gesture_S()
    if bright >20 and size > 150:
        i+=1
    print('%.f, %.f'%(bright,size))
player.quit()
print('finish1')

(2)开始投递垃圾,紧接着开启串口,等待上位机识别传来的数据。(这里就做的十分的简单,其实还是应该规范一点,加上头部和校验,保证一包数据顺利传输,当时没考虑这么多,所以可以进行改进,下面罗列的是最简单的方法,仅做参考)

while m < 6:
    time.sleep(1)
    try:
        while True:
            time.sleep(0.1)  
            bright = gesture.check_gesture_B()
            size = gesture.check_gesture_S()
            if bright >20 and size > 150:
                break
   
    except KeyboardInterrupt:
        if ser != None:
            ser.close()
    print('finish2')
    time.sleep(3)
    a = myser.ser()
                   
    print('finish3')
    time.sleep(1)

(3)就是判断识别到的垃圾,记录相关信息到txt文件(为了后面显示打印),显示识别到的垃圾种类,然后就是调用电机舵机进行归位。逻辑很简单吧。

    if a == '0':
        f = open('/home/pi/test.txt','a')
        f.write('5号干电池\n')
        f.close()
        mydis.Pdisplay(img0)

        motor.Bomotor_po(INT1,INT2,ENA,1.85)         #底部电机正转
        motor.server()                               #舵机开合
        motor.Bomotor_ne(INT1,INT2,ENA,1.90)         #底部电机反转

(4)用表格的形式显示相关信息,这里可以参考我这种调用一个弹出框写文字的形式,当然这也是最简单容易实现的办法。 同样高级一点的可以调用一个网页来显示。 更厉害一点的,可以使用pyqt,自己写一个界面。这个难度上也不算大,比赛也有人用的,我觉得十分优秀,可以尝试!

rubbish1 = linecache.getline('/home/pi/test.txt',1).strip()
master = tk.Tk()
w1 = tk.Label(master, text=' 序号                              垃圾名称                     数量                   成功与否',height = 4, width = 700, font=("微软雅黑", 12))
w1.pack()

w2 = tk.Label(master, text='1                                 '+rubbish1+'                         1                     OK!',height = 4, width = 700, background='skyblue', font=("微软雅黑", 12))
w2.pack()

w3 = tk.Label(master, text= '2                                 '+rubbish2+'                         1                     OK!',height = 4, width = 700, background='yellow', font=("微软雅黑", 12))
w3.pack()

w4 = tk.Label(master, text='3                                 '+rubbish3+'                         1                     OK!',height = 4, width = 700, background='lavender',font=("微软雅黑", 12))
w4.pack()

w5 = tk.Label(master, text='4                                 '+rubbish4+'                         1                     OK!',height = 4, width = 700, background='crimson', font=("微软雅黑", 12))
w5.pack()

w6 = tk.Label(master, text='5                                 '+rubbish5+'                         1                     OK!',height = 4, width = 700, background='beige', font=("微软雅黑", 12))
w6.pack()

w7 = tk.Label(master, text='我太厉害了!分类成功!不夸夸我吗! (๑´ㅂ`๑)',height = 6, width = 700, background='ghostwhite',font=("幼圆", 14))
w7.pack()

(5)最后就是溢满检测,然后溢满显示报警信息,播放报警音频。

distance = ultrasonic.ultrasonic()
    discount = 0
    dislist.clear()    
    while True:   
        dist = distance.get_distance()
        if discount < 3:
            dislist.append(dist)
            discount += 1
            if discount == 3:
                disnum = (dislist[0]+dislist[1]+dislist[2]) / 3
                if disnum < 10:
#                    mydis.Pdisplay(img5)
                    plt.figure(figsize=(10, 6))
                    plt.axis('off')  # 不需要坐标轴
                    plt.imshow(img5)                    
                    mngr = plt.get_current_fig_manager()
                    mngr.window.wm_geometry("+10+10")  # 调整窗口在屏幕上弹出的位置
                    plt.pause(5)  # 该句显示图片15秒
                    plt.ioff()  # 显示完后一定要配合使用plt.ioff()关闭交互模式,否则可能出奇怪的问题
                     
                    plt.clf()  # 清空图片
                    plt.close()  # 清空窗口
                    player = OMXPlayer(music_path, args = '-b -o local' )
                    
                    break
                else:
                    dislist.clear()
                    discount = 0
                    break    
        time.sleep(0.1)

十、总结

现在看来整个过程不过如此。不过当时才开始玩树莓派和K210,也是花了不少时间和精力。但是也确实做的十分粗糙,现在看来可以改进的地方也是特别多。包括语法呀,命名规范呀,代码逻辑呀。 比如,这套程序逻辑跑下来,其实识别一个可能要十几秒,遇到压缩的话可能二十几秒,这对于实际运行肯定是不行的。一是改变结构,我们二代确实改变了,效果显著。其二就是改进代码,比如加入多线程,这个对树莓派来说是个小kiss,而且这个多线程是真的好用,可以简化我们的思考逻辑,但是呢也得注意,防止程序跑飞,这里不做过多讨论
总之呢,以上内容仅供参考,现在看来确实挺low,不过算是处女座,也挺有意思的,再接再厉,哈哈,学无止境!!!