树莓派示例代码 点亮led灯 跑马灯 开关控制led 红外感应灯 超声波测距

树莓派示例代码

gpio代码

gpio介绍

GPIO(英语:General-purpose input/output),通用型之输入输出的简称,功能类似8051的P0---P3,其接脚可以供使用者由程控自由使用,PIN脚依现实考量可作为通用输入(GPI)或通用输出(GPO)或通用输入与输出(GPIO),如当clk generator, chip select等。

既然一个引脚可以用于输入、输出或其他特殊功能,那么一定有寄存器用来选择这些功能。对于输入,一定可以通过读取某个寄存器来确定引脚电位的高低;对于输出,一定可以通过写入某个寄存器来让这个引脚输出高电位或者低电位;对于其他特殊功能,则有另外的寄存器来控制它们。

使用RPI.GPIO库

1. 点亮led灯

py 复制代码
# -*- 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之后点亮led
    print("2.5s之后点亮led")
    time.sleep(2.5)

    GPIO.output(led_bcm16,GPIO.HIGH);

    # 让程序始终处于运行的状态
    while True:
        pass


# 将程序跑起来
run()

2. 跑马灯

py 复制代码
-*- 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+1

        time.sleep(0.5)

run()

GPIO.cleanup()

3. 开关控制led

py 复制代码
#-*- coding:UTF-8 -*-
"""
开关的使用
"""
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

bcm16 = 16
bcm21 = 21


def 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. 红外感应灯

py 复制代码
#-*- coding:utf-8 -*-
import RPi.GPIO as GPIO
import time
"""
演示红外传感器的使用
"""

# 设置GPIO口为BCM编码方式
GPIO.setmode(GPIO.BCM)

# 忽略警告信息
GPIO.setwarnings(False)

# 定义红外数据接收引脚
# 输出端:控制led亮灭
bcm16 = 16
# 输入端:读取人体感应传感器状态
bcm21 = 21


def 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:
            pass

try:
    infrared_init()
    run()
finally:
    # 引脚清理
    GPIO.cleanup()
    print("程序执行完成")

5. 超声波测距

py 复制代码
#-*- 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):
        pass
        t1 = time.time()

    while GPIO.input(bcm20_echo):
        pass
        t2 = time.time()

    print("distance is %d cm" % (((t2 - t1) * 340 / 2) * 100))
    time.sleep(0.01)
    return ((t2 - t1) * 340 / 2) * 100


GPIO.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进行编码。

呼吸灯案例

py 复制代码
# -*- coding:utf-8 -*-
"""
呼吸灯案例
"""
import RPi.GPIO as GPIO
import time
# 定义控制引脚
bcm21_led = 21;
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

pwm_led=None


def init():
    global pwm_led
    GPIO.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()

电机驱动

py 复制代码
# -*- coding:utf-8 -*-
"""
电机驱动的案例
注意:开发板需要与驱动板共地,否则会有问题
"""
import RPi.GPIO as GPIO
import time

# 定义引脚
bcm20_motor = 20
bcm21_motor = 21
bcm16_ena = 16


GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

# pwm
pwm_motor = None


def 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_motor
    pwm_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网络通讯

前进¶

后退¶

左转¶

右转¶

下位机代码

py 复制代码
#-*- 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_ENA
    global pwm_ENB

    GPIO.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引脚和频率为2000hz
    pwm_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 = 0

    count = 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 = 1
            print("连接成功啦!")
        except:
            pass 
        else:
            print("new user :%s " % str(addr))
            #设置连接套接字为非阻塞的模式并将连接的套接字放入到监听列表中
            tcpclientsock.setblocking(0)
            clientAddrList.append((tcpclientsock,addr))

        for tcpclientsock,addr in clientAddrList:
            try:
                global recvbuf
                global sendbuf
                recvbuf = ''
                #TCP接受数据
                # print("Start recv!",addr)
                recvbuf = tcpclientsock.recv(128)
                print("Start recv over!")
            except:
                pass
            else:
                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()  

上位机代码 遥控端

py 复制代码
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton,QVBoxLayout,QHBoxLayout
import sys
from socket import *
import threading


address = "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 = 6


def 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/

下位机代码

py 复制代码
# -*- 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 = 50

    def 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 connectflag
    connectflag = 0

    count = 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 = 1
            print("连接客户端成功啦!")
        except:
            pass
        else:
            # print("new user :%s " % str(addr))
            # 设置连接套接字为非阻塞的模式并将连接的套接字放入到监听列表中
            tcpclientsock.setblocking(0)
            clientAddrList.append((tcpclientsock, addr))

        for tcpclientsock, addr in clientAddrList:
            try:
                global recvbuf
                global sendbuf
                recvbuf = ''
                # TCP接受数据
                # print("Start recv!",addr)
                recvbuf = tcpclientsock.recv(128)
                # print("Start recv over!")
            except:
                pass
            else:
                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()

上位机代码

py 复制代码
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton,QVBoxLayout,QHBoxLayout
import sys
from socket import *
# import threading


address = "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("连接服务端成功啦!")


#小车状态值定义
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


def 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()
相关推荐
清风66666610 小时前
基于单片机与DAC0832的双路波形信号发生系统设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
azwsm11 小时前
电路元器件和GPIO控制器
单片机·嵌入式硬件
kebidaixu14 小时前
FreeRTOS 移植到 STM32F407VETX 记录(一)
stm32·单片机·嵌入式硬件
CSDN官方博客14 小时前
「谁说嵌入式只是调包和焊板子?」—— 2026嵌入式全栈技术征锋令
嵌入式硬件·物联网·embedding
点灯小铭15 小时前
基于单片机的数码管定时插座设计与定时开关功能实现
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
云栖梦泽15 小时前
玩转RK3506SDK
linux·嵌入式硬件
数智工坊17 小时前
机器人四大主控板系统分层选型指南:树莓派、ESP32、STM32与Arduino的能力边界与实战定位
stm32·嵌入式硬件·机器人
进击的小头18 小时前
第8篇:IGBT 从零到精通:核心原理、关键参数、选型指南与工业级应用要点
经验分享·嵌入式硬件·学习
点灯小铭18 小时前
基于单片机的多模式智能洗衣机设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
项目題供诗18 小时前
STM32-AD单通道&AD多通道(十九)
stm32·单片机·嵌入式硬件