树莓派示例代码 点亮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()
相关推荐
blessing。。10 分钟前
I2C学习
linux·单片机·嵌入式硬件·嵌入式
嵌新程2 小时前
day03(单片机高级)RTOS
stm32·单片机·嵌入式硬件·freertos·rtos·u575
Lin2012302 小时前
STM32 Keil5 attribute 关键字的用法
stm32·单片机·嵌入式硬件
电工小王(全国可飞)2 小时前
STM32 RAM在Memory Map中被分为3个区域
stm32·单片机·嵌入式硬件
maxiumII2 小时前
Diving into the STM32 HAL-----DAC笔记
笔记·stm32·嵌入式硬件
美式小田5 小时前
单片机学习笔记 9. 8×8LED点阵屏
笔记·单片机·嵌入式硬件·学习
兰_博5 小时前
51单片机-独立按键与数码管联动
单片机·嵌入式硬件·51单片机
时光の尘6 小时前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
嵌入式大圣7 小时前
单片机结合OpenCV
单片机·嵌入式硬件·opencv
日晨难再9 小时前
嵌入式:STM32的启动(Startup)文件解析
stm32·单片机·嵌入式硬件