树莓派示例代码
gpio代码
gpio介绍
GPIO(英语:General-purpose input/output),通用型之输入输出的简称,功能类似8051的P0—P3,其接脚可以供使用者由程控自由使用,PIN脚依现实考量可作为通用输入(GPI)或通用输出(GPO)或通用输入与输出(GPIO),如当clk generator, chip select等。
既然一个引脚可以用于输入、输出或其他特殊功能,那么一定有寄存器用来选择这些功能。对于输入,一定可以通过读取某个寄存器来确定引脚电位的高低;对于输出,一定可以通过写入某个寄存器来让这个引脚输出高电位或者低电位;对于其他特殊功能,则有另外的寄存器来控制它们。
使用RPI.GPIO库
1. 点亮led灯
# -*- coding:UTF-8 -*-
"""
点亮单个led
"""
import RPi.GPIO as GPIO
import time# 设置编码模式
GPIO.setmode(GPIO.BCM)
# 设置警告
GPIO.setwarnings(False)# 定义使用16号引脚控制led
led_bcm16=16# 程序初始化
def init():# 将引脚初始默认状态GPIO.cleanup()# 初始化16引脚模式GPIO.setup(led_bcm16,GPIO.OUT,initial=GPIO.LOW)print("程序已经启动啦!")# 程序运行函数
def run():init()# 2.5s之后点亮ledprint("2.5s之后点亮led")time.sleep(2.5)GPIO.output(led_bcm16,GPIO.HIGH);# 让程序始终处于运行的状态while True:pass# 将程序跑起来
run()
2. 跑马灯
-*- coding:UTF-8 -*-"""
跑马灯教程
"""
import RPi.GPIO as GPIO
import time# 设置端口编码模式
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)# 定义端口
ledlist=[16,20,21]# 初始化函数
def led_init():GPIO.cleanup()for num in ledlist:GPIO.setup(num, GPIO.OUT, initial=GPIO.LOW);print("led初始化完成:",num)led_init()def run():count=0# 程序始终运行while True:# 先将所有的灯都熄灭for index in ledlist:print(index)GPIO.output(index, GPIO.LOW)# 按照计数索引点灯curr_index = ledlist[count%len(ledlist)]GPIO.output(curr_index, GPIO.HIGH)# 计数要累加count = count+1time.sleep(0.5)run()GPIO.cleanup()
3. 开关控制led
#-*- coding:UTF-8 -*-
"""
开关的使用
"""
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)bcm16 = 16
bcm21 = 21def btn_init():GPIO.cleanup()GPIO.setup(bcm16,GPIO.OUT,initial=GPIO.LOW);# 按钮连接的GPIO针脚的模式设置为信号输入模式,同时默认拉高GPIO口电平,# 当GND没有被接通时,GPIO口处于高电平状态,取的的值为1# 注意到这是一个可选项,如果不在程序里面设置,通常的做法是通过一个上拉电阻连接到VCC上使之默认保持高电平GPIO.setup(bcm21, GPIO.IN, pull_up_down=GPIO.PUD_UP)def run():btn_init()while True:if GPIO.input(bcm21) ==0 :GPIO.output(bcm16,GPIO.HIGH);print("低电平")time.sleep(1)else:GPIO.output(bcm16,GPIO.LOW);print("高电平")time.sleep(1)try:run()
finally:GPIO.cleanup()
4. 红外感应灯
#-*- coding:utf-8 -*-
import RPi.GPIO as GPIO
import time
"""
演示红外传感器的使用
"""# 设置GPIO口为BCM编码方式
GPIO.setmode(GPIO.BCM)# 忽略警告信息
GPIO.setwarnings(False)# 定义红外数据接收引脚
# 输出端:控制led亮灭
bcm16 = 16
# 输入端:读取人体感应传感器状态
bcm21 = 21def infrared_init():GPIO.cleanup()# 初始化引脚GPIO.setup(bcm21,GPIO.IN,pull_up_down=GPIO.PUD_DOWN);GPIO.setup(bcm16,GPIO.OUT,initial=GPIO.LOW);print("人体感应灯已经启动起来...")def run():while True:if GPIO.input(bcm21) == 1:curtime = time.strftime('%Y-%m-%d-%H-%M-%S', time.localtime(time.time()))print(curtime)GPIO.output(bcm16,GPIO.HIGH)time.sleep(3)GPIO.output(bcm16,GPIO.LOW)else:passtry:infrared_init()run()
finally:# 引脚清理GPIO.cleanup()print("程序执行完成")
5. 超声波测距
#-*- coding:UTF-8 -*-"""
超声波传感器的使用
"""
import RPi.GPIO as GPIO
import time# 信号发出引脚
bcm16_tri = 16
# 信号接收引脚
bcm20_echo = 20
# 开关引脚
bcm21 = 21# 超声波测距函数
def get_distance():GPIO.output(bcm16_tri, GPIO.HIGH)time.sleep(0.000015)GPIO.output(bcm16_tri, GPIO.LOW)print("发送已经完成")while not GPIO.input(bcm20_echo):passt1 = time.time()while GPIO.input(bcm20_echo):passt2 = time.time()print("distance is %d cm" % (((t2 - t1) * 340 / 2) * 100))time.sleep(0.01)return ((t2 - t1) * 340 / 2) * 100GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)def init():GPIO.cleanup()# 按钮连接的GPIO针脚的模式设置为信号输入模式,同时默认拉高GPIO口电平,# 当GND没有被接通时,GPIO口处于高电平状态,取的的值为1# 注意到这是一个可选项,如果不在程序里面设置,通常的做法是通过一个上拉电阻连接到VCC上使之默认保持高电平GPIO.setup(bcm21, GPIO.IN, pull_up_down=GPIO.PUD_UP)GPIO.setup(bcm16_tri, GPIO.OUT,initial=GPIO.LOW);GPIO.setup(bcm20_echo, GPIO.IN)# 运行
def run():while True:# 监听开关的状态if GPIO.input(bcm21) ==0 :get_distance();print("低电平")time.sleep(1)else:print("高电平")time.sleep(1)# 程序启动
try:init();run();
finally:GPIO.cleanup()
PWM介绍
脉冲宽度调制是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM进行编码。
呼吸灯案例
# -*- coding:utf-8 -*-
"""
呼吸灯案例
"""
import RPi.GPIO as GPIO
import time
# 定义控制引脚
bcm21_led = 21;
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)pwm_led=Nonedef init():global pwm_ledGPIO.cleanup()GPIO.setup(bcm21_led,GPIO.OUT,initial=GPIO.LOW)pwm_led = GPIO.PWM(bcm21_led, 50);def run():init()# 设置初始占空比count=1;# 设置每次变化的步长step=2;while True:count += step# 修改占空比pwm_led.start(count)# 到达边界之后,数值改变方向要取反if count >= 99 or count <=1:step = -1*step# 让程序运行稍微慢一点time.sleep(0.03)# 将程序跑起来
try:run()
finally:GPIO.cleanup()
电机驱动
# -*- coding:utf-8 -*-
"""
电机驱动的案例
注意:开发板需要与驱动板共地,否则会有问题
"""
import RPi.GPIO as GPIO
import time# 定义引脚
bcm20_motor = 20
bcm21_motor = 21
bcm16_ena = 16GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)# pwm
pwm_motor = Nonedef init():GPIO.cleanup()GPIO.setup(bcm20_motor,GPIO.OUT,initial=GPIO.HIGH);GPIO.setup(bcm21_motor,GPIO.OUT,initial=GPIO.LOW);GPIO.setup(bcm16_ena,GPIO.OUT,initial=GPIO.HIGH);global pwm_motorpwm_motor = GPIO.PWM(bcm16_ena,1000)def run():# 设置电机转动占空比pwm_motor.start(5)GPIO.output(bcm20_motor,GPIO.HIGH)GPIO.output(bcm21_motor,GPIO.LOW)while True:pass# 将程序跑起来
try:init()run()
finally:GPIO.cleanup()
综合 四轮小车案例
功能实现¶
通讯¶ socket网络通讯
前进¶
后退¶
左转¶
右转¶
下位机代码
#-*- coding:utf-8 -*-
import RPi.GPIO as GPIO
import socket
import time
import string
import threading#小车状态值定义
enSTOP = 0
enRUN =1
enBACK = 2
enLEFT = 3
enRIGHT = 4
enTLEFT =5
enTRIGHT = 6#小车电机引脚定义
IN1 = 20
IN2 = 21
IN3 = 19
IN4 = 26
ENA = 16
ENB = 13#小车和舵机状态变量
g_CarState = 0#小车速度变量
CarSpeedControl = 35# 小车转向速度变量
CarDirectSpeedControl=80#设置GPIO口为BCM编码方式
GPIO.setmode(GPIO.BCM)#忽略警告信息
GPIO.setwarnings(False)#电机引脚初始化为输出模式
def init():global pwm_ENAglobal pwm_ENBGPIO.setup(ENA,GPIO.OUT,initial=GPIO.HIGH)GPIO.setup(IN1,GPIO.OUT,initial=GPIO.LOW)GPIO.setup(IN2,GPIO.OUT,initial=GPIO.LOW)GPIO.setup(ENB,GPIO.OUT,initial=GPIO.HIGH)GPIO.setup(IN3,GPIO.OUT,initial=GPIO.LOW)GPIO.setup(IN4,GPIO.OUT,initial=GPIO.LOW)#设置pwm引脚和频率为2000hzpwm_ENA = GPIO.PWM(ENA, 2000)pwm_ENB = GPIO.PWM(ENB, 2000)pwm_ENA.start(0)pwm_ENB.start(0)#小车前进
def run():GPIO.output(IN1, GPIO.HIGH)GPIO.output(IN2, GPIO.LOW)GPIO.output(IN3, GPIO.LOW)GPIO.output(IN4, GPIO.LOW)pwm_ENA.ChangeDutyCycle(CarSpeedControl)pwm_ENB.ChangeDutyCycle(CarDirectSpeedControl)#小车后退
def back():GPIO.output(IN1, GPIO.LOW)GPIO.output(IN2, GPIO.HIGH)GPIO.output(IN3, GPIO.LOW)GPIO.output(IN4, GPIO.LOW)pwm_ENA.ChangeDutyCycle(CarSpeedControl)pwm_ENB.ChangeDutyCycle(CarDirectSpeedControl)#小车左转
def left():GPIO.output(IN1, GPIO.LOW)GPIO.output(IN2, GPIO.LOW)GPIO.output(IN3, GPIO.HIGH)GPIO.output(IN4, GPIO.LOW)pwm_ENA.ChangeDutyCycle(CarSpeedControl)pwm_ENB.ChangeDutyCycle(CarDirectSpeedControl)#小车右转
def right():GPIO.output(IN1, GPIO.LOW)GPIO.output(IN2, GPIO.LOW)GPIO.output(IN3, GPIO.LOW)GPIO.output(IN4, GPIO.HIGH)pwm_ENA.ChangeDutyCycle(CarSpeedControl)pwm_ENB.ChangeDutyCycle(CarDirectSpeedControl)#小车原地左转
def spin_left():GPIO.output(IN1, GPIO.HIGH)GPIO.output(IN2, GPIO.LOW)GPIO.output(IN3, GPIO.HIGH)GPIO.output(IN4, GPIO.LOW)pwm_ENA.ChangeDutyCycle(CarSpeedControl)pwm_ENB.ChangeDutyCycle(CarSpeedControl)#小车原地右转
def spin_right():GPIO.output(IN1, GPIO.LOW)GPIO.output(IN2, GPIO.LOW)GPIO.output(IN3, GPIO.LOW)GPIO.output(IN4, GPIO.HIGH)pwm_ENA.ChangeDutyCycle(CarSpeedControl)pwm_ENB.ChangeDutyCycle(CarSpeedControl)#小车停止
def brake():GPIO.output(IN1, GPIO.LOW)GPIO.output(IN2, GPIO.LOW)GPIO.output(IN3, GPIO.LOW)GPIO.output(IN4, GPIO.LOW)try:init()global connectflag connectflag = 0count = 50# 通过socket创建监听套接字并设置为非阻塞模式tcpservicesock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)tcpservicesock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)tcpservicesock.setblocking(0)# 填充绑定服务器的ip地址和端口号# 注意:这里一定要根据自己的树莓派的ip地址来填tcpservicesock.bind(('192.168.12.1', 8888))# 监听客户端的连接tcpservicesock.listen(5)print("waiting for connection....")# 创建监听列表clientAddrList = []print("服务器已经开启啦!")while True:try:#准备接受客户端的连接并返回连接套接字tcpclientsock,addr = tcpservicesock.accept()if tcpclientsock:connectflag = 1print("连接成功啦!")except:pass else:print("new user :%s " % str(addr))#设置连接套接字为非阻塞的模式并将连接的套接字放入到监听列表中tcpclientsock.setblocking(0)clientAddrList.append((tcpclientsock,addr))for tcpclientsock,addr in clientAddrList:try:global recvbufglobal sendbufrecvbuf = ''#TCP接受数据# print("Start recv!",addr)recvbuf = tcpclientsock.recv(128)print("Start recv over!")except:passelse:if len(recvbuf) > 0:print("recvbuf",recvbuf)g_CarState = int(recvbuf);# 根据解析的数据让小车做出相应的运动if g_CarState == enSTOP:brake()elif g_CarState == enRUN:run()elif g_CarState == enLEFT:print("左转")left()elif g_CarState == enRIGHT:right()elif g_CarState == enBACK:back()elif g_CarState == enTLEFT:spin_left()elif g_CarState == enTRIGHT:spin_right()else:brake()else:tcpclientsock.close()clientAddrList.remove((tcpclientsock,addr))except KeyboardInterrupt:pass
tcpclientsock.close()
tcpservicesock.close()
pwm_ENA.stop()
pwm_ENB.stop()GPIO.cleanup()
上位机代码 遥控端
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton,QVBoxLayout,QHBoxLayout
import sys
from socket import *
import threadingaddress = "192.168.12.1"
port = 8888;
server_socket="";def connectCar():global server_socket;server_socket = socket(AF_INET, SOCK_STREAM)server_socket.connect((address, port))print("连接成功!")#小车状态值定义
enSTOP = 0
enRUN =1
enBACK = 2
enLEFT = 3
enRIGHT = 4
enTLEFT =5
enTRIGHT = 6def controlCallback(val):print("发送数据",val)server_socket.send(str(val).encode())if __name__ == '__main__':# 创建核心类app = QApplication(sys.argv)# 创建窗口widget = QWidget();widget.resize(200,400)# 创建水平布局vbox = QVBoxLayout(widget)leftBtn = QPushButton("连接");vbox.addWidget(leftBtn)leftBtn.clicked.connect(lambda : connectCar())# 创建按钮leftBtn = QPushButton("左转");vbox.addWidget(leftBtn)leftBtn.clicked.connect(lambda :controlCallback(enLEFT))# 创建按钮rightBtn = QPushButton("右转");vbox.addWidget(rightBtn)rightBtn.clicked.connect(lambda :controlCallback(enRIGHT))# 创建按钮forwordBtn = QPushButton("前进");vbox.addWidget(forwordBtn)forwordBtn.clicked.connect(lambda :controlCallback(enRUN))# 创建按钮backBtn = QPushButton("后退");vbox.addWidget(backBtn)backBtn.clicked.connect(lambda :controlCallback(enBACK))# 创建按钮stopBtn = QPushButton("停止");vbox.addWidget(stopBtn)stopBtn.clicked.connect(lambda :controlCallback(enSTOP))widget.show()app.exec()
综合 麦克纳姆轮小车案例
http://robot.czxy.com/docs/raspberry/03_quickstart/
下位机代码
# -*- coding:utf-8 -*-
import RPi.GPIO as GPIO
import socket
import time
# import string
# import threading# 小车状态值定义
STATE_STOP = 0;STATE_FORWORD = 1;
STATE_BACK = 2;STATE_LEFT = 3;
STATE_RIGHT = 4;STATE_LEFT_FRONT = 5;
STATE_RIGHT_FRONT = 6;STATE_LEFT_BACK = 7;
STATE_RIGHT_BACK = 8;STATE_CLOCKWISE = 9;
STATE_COUNTERCLOCKWISE = 10;STATE_TEST = 11;# 小车点击引脚定义; 小车电机按照顺时针方向 1,2,3,4 排列
# 左前方 白紫蓝
MOTOR_LEFT_FRONT_A = 22
MOTOR_LEFT_FRONT_B = 27
MOTOR_LEFT_FRONT_PWM = 17# 右前方 绿黄橙
MOTOR_RIGHT_FRONT_A = 5
MOTOR_RIGHT_FRONT_B = 6
MOTOR_RIGHT_FRONT_PWM = 13# 右后方 绿黄橙
MOTOR_RIGHT_BACK_A = 12
MOTOR_RIGHT_BACK_B = 16
MOTOR_RIGHT_BACK_PWM = 20# 左后方 白紫蓝
MOTOR_LEFT_BACK_A = 19
MOTOR_LEFT_BACK_B = 26
MOTOR_LEFT_BACK_PWM = 21# 设置GPIO口为BCM编码方式
GPIO.setmode(GPIO.BCM)# 忽略警告信息
GPIO.setwarnings(False)class Motor:"""电机对象"""def __init__(self,motorA,motorB,motorPwm):self.motorA = motorA;self.motorB = motorB;self.motorPwm = motorPwm;self.pwm = None;self.init_motor()# 小车速度变量self.carSpeed = 50def init_motor(self):GPIO.setup(self.motorA, GPIO.OUT, initial=GPIO.LOW)GPIO.setup(self.motorB, GPIO.OUT, initial=GPIO.LOW)GPIO.setup(self.motorPwm, GPIO.OUT, initial=GPIO.HIGH)self.pwm = GPIO.PWM(self.motorPwm, 2000)self.pwm.start(0)def forward(self,value=0):GPIO.setup(self.motorA, GPIO.OUT, initial=GPIO.HIGH)GPIO.setup(self.motorB, GPIO.OUT, initial=GPIO.LOW)self.pwm.ChangeDutyCycle(self.carSpeed)def back(self,value=0):GPIO.setup(self.motorA, GPIO.OUT, initial=GPIO.LOW)GPIO.setup(self.motorB, GPIO.OUT, initial=GPIO.HIGH)self.pwm.ChangeDutyCycle(self.carSpeed)def stop(self):GPIO.setup(self.motorA, GPIO.OUT, initial=GPIO.LOW)GPIO.setup(self.motorB, GPIO.OUT, initial=GPIO.LOW)self.pwm.ChangeDutyCycle(0)class HeiCar:def __init__(self):self.currentState = 0;# 按照顺时针的方向# 左前方self.motor1 = Motor(MOTOR_LEFT_FRONT_A, MOTOR_LEFT_FRONT_B, MOTOR_LEFT_FRONT_PWM)# 右前方self.motor2 = Motor(MOTOR_RIGHT_FRONT_A, MOTOR_RIGHT_FRONT_B, MOTOR_RIGHT_FRONT_PWM)# 右后方self.motor3 = Motor(MOTOR_RIGHT_BACK_A, MOTOR_RIGHT_BACK_B, MOTOR_RIGHT_BACK_PWM);# 左后方self.motor4 = Motor(MOTOR_LEFT_BACK_A, MOTOR_LEFT_BACK_B, MOTOR_LEFT_BACK_PWM);self.motors = [self.motor1,self.motor2,self.motor3,self.motor4];def forword(self):""" 小车前进"""for motor in self.motors:motor.forward();def back(self):"""小车后退"""for motor in self.motors:motor.back();def stop(self):"""停止"""for motor in self.motors:motor.stop();def left(self):"""小车向左边 横着走"""self.motor1.back()self.motor4.forward();self.motor2.forward()self.motor3.back()def right(self):""" 小车向右边 横着走"""self.motor1.forward()self.motor4.back()self.motor2.back()self.motor3.forward()def left_front(self):""" 向左前方 45度 """self.motor1.stop()self.motor4.forward()self.motor2.forward()self.motor3.stop()def right_front(self):""" 向右前方 45度 """self.motor1.forward()self.motor4.stop()self.motor2.stop()self.motor3.forward()def left_back(self):""" 向左后45 度"""self.motor1.back()self.motor4.stop()self.motor2.stop()self.motor3.back()def right_back(self):""" 右后 45 度"""self.motor1.stop()self.motor4.back()self.motor2.back()self.motor3.stop()def clockwise(self):""" 顺时针"""self.motor1.forward()self.motor4.forward()self.motor2.back()self.motor3.back()def counterclockwise(self):""" 逆时针 """self.motor1.back()self.motor4.back()self.motor2.forward()self.motor3.forward()try:car = HeiCar();global connectflagconnectflag = 0count = 50# 通过socket创建监听套接字并设置为非阻塞模式tcpservicesock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcpservicesock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)tcpservicesock.setblocking(0)# 填充绑定服务器的ip地址和端口号# 注意:这里一定要根据自己的树莓派的ip地址来填tcpservicesock.bind(('192.168.12.1', 8888))# 监听客户端的连接tcpservicesock.listen(5)print("waiting for connection....")# 创建监听列表clientAddrList = []print("服务器已经开启啦!")while True:try:# 准备接受客户端的连接并返回连接套接字tcpclientsock, addr = tcpservicesock.accept()if tcpclientsock:connectflag = 1print("连接客户端成功啦!")except:passelse:# print("new user :%s " % str(addr))# 设置连接套接字为非阻塞的模式并将连接的套接字放入到监听列表中tcpclientsock.setblocking(0)clientAddrList.append((tcpclientsock, addr))for tcpclientsock, addr in clientAddrList:try:global recvbufglobal sendbufrecvbuf = ''# TCP接受数据# print("Start recv!",addr)recvbuf = tcpclientsock.recv(128)# print("Start recv over!")except:passelse:if len(recvbuf) > 0:# print("recvbuf", recvbuf)state = int(recvbuf);car.currentState = state;# 根据解析的数据让小车做出相应的运动if state == STATE_STOP:print("=====停止1=====")car.stop()elif state == STATE_FORWORD:print("=====前进=====")car.forword()elif state == STATE_BACK:print("=====后退=====")car.back()elif state == STATE_LEFT:print("=====左移=====")car.left()elif state == STATE_RIGHT:print("=====右移=====")car.right()elif state == STATE_LEFT_FRONT:print("=====左前方=====")car.left_front()elif state == STATE_RIGHT_FRONT:print("=====右前方=====")car.right_front()elif state == STATE_LEFT_BACK:print("=====左后方=====")car.left_back()elif state == STATE_RIGHT_BACK:print("=====右后方=====")car.right_back()elif state == STATE_CLOCKWISE:print("=====顺时针=====")car.clockwise()elif state == STATE_COUNTERCLOCKWISE:print("=====逆时针=====")car.counterclockwise()elif state == STATE_TEST:car.forword()time.sleep(0.5)car.stop()time.sleep(0.5)car.back()time.sleep(0.5)car.stop()car.left()time.sleep(0.5)car.stop()time.sleep(0.5)car.right()time.sleep(0.5)car.stop()time.sleep(0.5)car.left_front()time.sleep(0.5)car.stop()time.sleep(0.5)car.right_back()time.sleep(0.5)car.stop()time.sleep(0.5)car.right_front()time.sleep(0.5)car.stop()time.sleep(0.5)car.left_back()time.sleep(0.5)car.stop()time.sleep(0.5)car.clockwise()time.sleep(0.5)car.stop()time.sleep(0.5)car.counterclockwise()time.sleep(0.5)else:print("=====停止2=====")car.stop()# 让小车运动0.5s 即停止time.sleep(0.5)car.stop()time.sleep(0.5)else:tcpclientsock.close()clientAddrList.remove((tcpclientsock, addr))car.stop()except KeyboardInterrupt:pass
tcpclientsock.close()
tcpservicesock.close()
GPIO.cleanup()
上位机代码
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton,QVBoxLayout,QHBoxLayout
import sys
from socket import *
# import threadingaddress = "192.168.12.1"
port = 8888
server_socket=""def connectCar():global server_socketserver_socket = socket(AF_INET, SOCK_STREAM)server_socket.connect((address, port))print("连接服务端成功啦!")#小车状态值定义
STATE_STOP = 0;STATE_FORWORD = 1;
STATE_BACK = 2;STATE_LEFT = 3;
STATE_RIGHT = 4;STATE_LEFT_FRONT = 5;
STATE_RIGHT_FRONT = 6;STATE_LEFT_BACK = 7;
STATE_RIGHT_BACK = 8;STATE_CLOCKWISE = 9;
STATE_COUNTERCLOCKWISE = 10;
STATE_TEST = 11def controlCallback(val):print("发送数据",val)server_socket.send(str(val).encode())print("发送成功!")if __name__ == '__main__':# 创建核心类app = QApplication(sys.argv)# 创建窗口widget = QWidget()widget.resize(200,400)# 创建垂直布局vbox = QVBoxLayout(widget)# 创建水平布局hbox0 = QHBoxLayout()hbox1 = QHBoxLayout()hbox2 = QHBoxLayout()hbox3 = QHBoxLayout()hbox4 = QHBoxLayout()hbox5 = QHBoxLayout()hbox6 = QHBoxLayout()hbox7 = QHBoxLayout()hbox8 = QHBoxLayout()hbox9 = QHBoxLayout()vbox.addLayout(hbox0)vbox.addLayout(hbox1)vbox.addLayout(hbox2)vbox.addLayout(hbox3)vbox.addLayout(hbox4)vbox.addLayout(hbox5)vbox.addLayout(hbox6)vbox.addLayout(hbox7)vbox.addLayout(hbox8)vbox.addLayout(hbox9)# --------------------------------------------------------------------------------leftBtn = QPushButton("必须要先连接服务端")hbox0.addWidget(leftBtn)leftBtn.clicked.connect(lambda : connectCar())# --------------------------------------------------------------------------------# 创建按钮leftForwardBtn = QPushButton("左前")hbox1.addWidget(leftForwardBtn)leftForwardBtn.clicked.connect(lambda :controlCallback(STATE_LEFT_FRONT))# 创建按钮forwordBtn = QPushButton("前进")hbox1.addWidget(forwordBtn)forwordBtn.clicked.connect(lambda :controlCallback(STATE_FORWORD))# 创建按钮rightForwardBtn = QPushButton("右前")hbox1.addWidget(rightForwardBtn)rightForwardBtn.clicked.connect(lambda :controlCallback(STATE_RIGHT_FRONT))# --------------------------------------------------------------------------------# 创建按钮leftBtn = QPushButton("左移")hbox2.addWidget(leftBtn)leftBtn.clicked.connect(lambda :controlCallback(STATE_LEFT))# 创建按钮stopBtn = QPushButton("停止")hbox2.addWidget(stopBtn)stopBtn.clicked.connect(lambda :controlCallback(STATE_STOP))# 创建按钮rightBtn = QPushButton("右移")hbox2.addWidget(rightBtn)rightBtn.clicked.connect(lambda :controlCallback(STATE_RIGHT))# --------------------------------------------------------------------------------# 创建按钮leftBackBtn = QPushButton("左后")hbox3.addWidget(leftBackBtn)leftBackBtn.clicked.connect(lambda :controlCallback(STATE_LEFT_BACK))# 创建按钮backBtn = QPushButton("后退")hbox3.addWidget(backBtn)backBtn.clicked.connect(lambda :controlCallback(STATE_BACK))# 创建按钮rightBackBtn = QPushButton("右后")hbox3.addWidget(rightBackBtn)rightBackBtn.clicked.connect(lambda :controlCallback(STATE_RIGHT_BACK))#--------------------------------------------------------------------------------# 创建按钮counterclockwiseBtn = QPushButton("逆时针旋转")hbox4.addWidget(counterclockwiseBtn)counterclockwiseBtn.clicked.connect(lambda :controlCallback(STATE_COUNTERCLOCKWISE))# 创建按钮clockwiseBtn = QPushButton("顺时针旋转")hbox4.addWidget(clockwiseBtn)clockwiseBtn.clicked.connect(lambda :controlCallback(STATE_CLOCKWISE))#--------------------------------------------------------------------------------# 创建按钮FRBLBtn = QPushButton("测试")hbox5.addWidget(FRBLBtn)FRBLBtn.clicked.connect(lambda :controlCallback(STATE_TEST))widget.show()app.exec()