小小屏幕也能接收行空板视频车图传

2023-01-139279
精华项目
AI 快速预览详细 收起
该项目展示了如何使用128*64黑白屏的“鳄霸王”遥控器,通过Python编程实现行空板视频车的图传功能。项目中详细介绍了获取摇杆信息、图像处理及传输的具体步骤。最终效果是能够在小屏幕上实时显示视频车的环境图像,适用于STEM教育和创客项目。
小小屏幕也能接收行空板视频车图传图1


【项目背景】

前两天收到了”鳄霸王“,第一感觉它是一个带屏幕的遥控器,只是这个屏幕有点太小了,128*64,黑白屏。

既然像遥控器,那就把它做成遥控器,屏幕虽小,但也可以显示视频车的图传实时环境图像。


小小屏幕也能接收行空板视频车图传图2


小小屏幕也能接收行空板视频车图传图3

【演示视频】

先上演示视频


【准备工作】

1、获取摇杆信息

小小屏幕也能接收行空板视频车图传图4

小小屏幕也能接收行空板视频车图传图5

2、”鳄霸王“获取图传图像

行空板python程序

  1. def main():
  2. import cv2
  3. import numpy as np
  4. import socket
  5. import time
  6. import binascii
  7. import socket
  8. import time
  9. cap = cv2.VideoCapture(0)
  10. cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
  11. cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
  12. cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
  13. cv2.namedWindow('car',cv2.WND_PROP_FULLSCREEN)    #Set the windows to be full screen.
  14. cv2.setWindowProperty('car', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)    #Set the windows to be full screen.
  15. W=128
  16. H=64
  17. size = (W,H)
  18. val=0
  19. str1=''
  20. while(1): # get a frame and show
  21.     ret, frame1 = cap.read()
  22.     if(ret):
  23.         frame2=frame1.copy()
  24.         frame1 = cv2.resize(frame1, size)
  25.         
  26.         gray1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
  27.         
  28.         BIN1= cv2.adaptiveThreshold(gray1,1,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,7,3)
  29.         frame2 = cv2.rotate(frame2, cv2.ROTATE_90_COUNTERCLOCKWISE)
  30.         cv2.imshow('car', frame2)
  31.         
  32.         str1=""
  33.         for h in range(H):
  34.           for w in range(0,W,16):
  35.              for i in range(4):
  36.                   val=(int(BIN1[h][w+i*4+0])*8 + int(BIN1[h][w+i*4+1])*4 + int(BIN1[h][w+i*4+2])*2 + int(BIN1[h][w+i*4+3])*1)
  37.                   if val>=10:
  38.                     if val == 10:
  39.                       str1=str1+'A'
  40.                     if val==11:
  41.                       str1=str1+'B'
  42.                     if val==12:
  43.                       str1=str1+'C'
  44.                     if val==13:
  45.                       str1=str1+'D'
  46.                     if val==14:
  47.                       str1=str1+'E'
  48.                     if val==15:
  49.                       str1=str1+'F'
  50.                   else:
  51.                       str1=str1+str(val)
  52.              str1=str1+" "
  53.         #print(str1)
  54.         s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  55.         s.connect(('192.168.31.216',10000))
  56.         s.send(bytearray.fromhex(str1))
  57.         time.sleep(0.19)
  58.         if cv2.waitKey(1) & 0xFF == ord('q'):
  59.          break
  60. cv2.destroyAllWindows()
  61. if __name__=='__main__':
  62.     main()
复制代码
掌控板程序
  1. from mpython import *
  2. import usocket
  3. import network
  4. my_wifi = wifi()
  5. my_wifi.connectWiFi("yuntian","yuntian123456")
  6. while not my_wifi.sta.isconnected():
  7.      pass
  8. oled.fill(0)
  9. oled.DispChar(my_wifi.sta.ifconfig()[0], 0, 0, 1)
  10. oled.show()
  11. #socket.socket() 创建了一个 socket 对象,并且支持 context manager type,你可以使用 with 语句,这样你就不用再手动调用 s.close() 来关闭 socket 了
  12. s=usocket.socket(usocket.AF_INET,usocket.SOCK_STREAM)
  13. #bind() 方法的入参取决于 socket 的地址族,在这个例子中我们使用了 socket.AF_INET (IPv4),它接收一个二元组(host, port)入参
  14. #端口号应该是 1-65535 之间的整数(0是保留的),这个整数就是用来接受客户端链接的 TCP 端口号,如果端口号小于 1024,有的操作系统会要求管理员权限
  15. s.bind((my_wifi.sta.ifconfig()[0],10000))
  16. #listen() 方法调用使服务器可以接受连接请求,这使它成为一个「监听中」的 socket
  17. #listen() 方法有一个 backlog 参数。它指定在拒绝新的连接之前系统将允许使用的 未接受的连接 数量。从 Python 3.5 开始,这是可选参数。如果不指定,Python 将取一个默认值
  18. s.listen(5)
  19. while True:
  20.       #accept() 方法阻塞并等待传入连接。当一个客户端连接时,它将返回一个新的 socket 对象,对象中有表示当前连接的 conn 和一个由主机、端口号组成的 IPv4/v6 连接的元组
  21.       con=s.accept()[0]
  22.       data=con.recv(1024)
  23.       #framebuf.FrameBuffer(buffer, width, height, format) 可以构建帧缓存对象, buffer 为缓存区数据,width 为图片宽度,height 为图片高度,format 为FrameBuffer的格式,即对应图片取模时数据输出的扫描模式:framebuf.MONO_HLSB 为水平方向;framebuf.MONO_VLSB 为垂直方向。
  24.       fbuf=framebuf.FrameBuffer(bytearray(data),128,64,framebuf.MONO_HLSB)
  25.       oled.fill(0)
  26.       #oled.blit(fbuf, x, y) 使用OLED显示图片帧,fbuf 为FrameBuffer对象,x 、y 为起始点的坐标x、y。
  27.       oled.blit(fbuf,0,0)
  28.       oled.show()
  29.       con.close()
复制代码
利用电脑先进行测试
小小屏幕也能接收行空板视频车图传图6

行空板视频车
小小屏幕也能接收行空板视频车图传图7

3、控制行空板视频车运动
开启行空板siot
小小屏幕也能接收行空板视频车图传图8
行空板视频车Python程序
  1. from pinpong.board import Board
  2. from microbit_motor import Microbit_Motor #导入Microbit_Motor库
  3. import siot
  4. from pinpong.extension.unihiker import *
  5. from unihiker import GUI
  6. u_gui=GUI()
  7. xianshi=u_gui.draw_text(text="开始",x=50,y=100,font_size=50, color="#0000FF")
  8. # 事件回调函数
  9. def on_message_callback(client, userdata, msg):
  10.   
  11.   if (msg.payload.decode("utf-8")  == 'G'):
  12.       forward(200)
  13.       xianshi.config(text="前进")
  14.   if (msg.payload.decode("utf-8")== 'S'):
  15.       stop()
  16.       xianshi.config(text="停止")   
  17.       
  18.   if (msg.payload.decode("utf-8") == 'B'):
  19.       back(200)
  20.       xianshi.config(text="后退")  
  21.       
  22.   if (msg.payload.decode("utf-8") == 'L'):
  23.       left(200)
  24.       xianshi.config(text="向左")  
  25.       
  26.   if (msg.payload.decode("utf-8") == 'R'):
  27.       right(200)
  28.       xianshi.config(text="向右")
  29. siot.init(client_id="siot_192",server="192.168.31.8",port=1883,user="siot",password="dfrobot")
  30. siot.connect()
  31. siot.loop()
  32. siot.set_callback(on_message_callback)
  33. siot.getsubscribe(topic="car/control")
  34. Board("microbit").begin()
  35. motorbit = Microbit_Motor()
  36. def forward(speed):
  37.   #前进
  38.   #电机有M1,M2,M3,M4, CW代表正转,CCW代表反转,255是速度,范围0-255
  39.   if speed>255:
  40.       speed=255
  41.   motorbit.motor_run(motorbit.M1, motorbit.CW, speed)
  42.   motorbit.motor_run(motorbit.M2, motorbit.CW, speed)
  43.   motorbit.motor_run(motorbit.M3, motorbit.CCW, speed)
  44.   motorbit.motor_run(motorbit.M4, motorbit.CCW, speed)
  45. def back(speed):
  46.   #后退
  47.   #电机有M1,M2,M3,M4, CW代表正转,CCW代表反转,255是速度,范围0-255
  48.   if speed>255:
  49.       speed=255
  50.   motorbit.motor_run(motorbit.M1, motorbit.CCW, speed)
  51.   motorbit.motor_run(motorbit.M2, motorbit.CCW, speed)
  52.   motorbit.motor_run(motorbit.M3, motorbit.CW, speed)
  53.   motorbit.motor_run(motorbit.M4, motorbit.CW, speed)
  54. def left_turn(speed):
  55.   #向左转
  56.   #电机有M1,M2,M3,M4, CW代表正转,CCW代表反转,255是速度,范围0-255
  57.   if speed>255:
  58.       speed=255
  59.   motorbit.motor_run(motorbit.M1, motorbit.CW, speed)
  60.   motorbit.motor_run(motorbit.M2, motorbit.CW, speed)
  61.   motorbit.motor_run(motorbit.M3, motorbit.CW, speed)
  62.   motorbit.motor_run(motorbit.M4, motorbit.CW, speed)
  63. def right_turn(speed):
  64.   #向右转
  65.   #电机有M1,M2,M3,M4, CW代表正转,CCW代表反转,255是速度,范围0-255
  66.   if speed>255:
  67.       speed=255
  68.   motorbit.motor_run(motorbit.M1, motorbit.CCW, speed)
  69.   motorbit.motor_run(motorbit.M2, motorbit.CCW, speed)
  70.   motorbit.motor_run(motorbit.M3, motorbit.CCW, speed)
  71.   motorbit.motor_run(motorbit.M4, motorbit.CCW, speed)
  72. def left(speed):
  73.   #向左
  74.   #电机有M1,M2,M3,M4, CW代表正转,CCW代表反转,255是速度,范围0-255
  75.   if speed>255:
  76.       speed=255
  77.   motorbit.motor_run(motorbit.M1, motorbit.CW, speed)
  78.   motorbit.motor_run(motorbit.M2, motorbit.CCW, speed)
  79.   motorbit.motor_run(motorbit.M3, motorbit.CW, speed)
  80.   motorbit.motor_run(motorbit.M4, motorbit.CCW, speed)
  81. def right(speed):
  82.   #向右
  83.   #电机有M1,M2,M3,M4, CW代表正转,CCW代表反转,255是速度,范围0-255
  84.   if speed>255:
  85.       speed=255
  86.   motorbit.motor_run(motorbit.M1, motorbit.CCW, speed)
  87.   motorbit.motor_run(motorbit.M2, motorbit.CW, speed)
  88.   motorbit.motor_run(motorbit.M3, motorbit.CCW, speed)
  89.   motorbit.motor_run(motorbit.M4, motorbit.CW, speed)
  90. def stop():
  91.   motorbit.motor_stop(motorbit.M1)
  92.   motorbit.motor_stop(motorbit.M2)
  93.   motorbit.motor_stop(motorbit.M3)
  94.   motorbit.motor_stop(motorbit.M4)
复制代码
”鳄霸王“掌控板控制程序
小小屏幕也能接收行空板视频车图传图9
同micropython程序

  1. # MindPlus
  2. # mpython
  3. from umqtt.simple import MQTTClient
  4. from mpython import *
  5. import network
  6. my_wifi = wifi()
  7. p0=MPythonPin(0,PinMode.ANALOG)
  8. p1=MPythonPin(1,PinMode.ANALOG)
  9. my_wifi.connectWiFi("yuntian","yuntian123456")
  10. while not (my_wifi.sta.isconnected()):
  11.   pass
  12. mqtt = MQTTClient("", "192.168.1.101", 1883, "siot", "dfrobot")
  13. try:
  14.   mqtt.connect()
  15.   print('MQTT Connected Successful')
  16. except:
  17.   print('MQTT Connection Failed')
  18. oled.DispChar(my_wifi.sta.ifconfig()[0], 42, 22, 1)
  19. oled.show()
  20. BiaoShi = 0
  21. while True:
  22.   if (p0.read_analog() < 10):
  23.     if (not (BiaoShi == 1)):
  24.       BiaoShi = 1
  25.       mqtt.publish(str("car/control"), str("G").encode('utf-8'))
  26.   elif (p0.read_analog() > 4000):
  27.     if (not (BiaoShi == 2)):
  28.       BiaoShi = 2
  29.       mqtt.publish(str("car/control"), str("B").encode('utf-8'))
  30.   elif (p1.read_analog() < 10):
  31.     if (not (BiaoShi == 3)):
  32.       BiaoShi = 3
  33.       mqtt.publish(str("car/control"), str("R").encode('utf-8'))
  34.   elif (p1.read_analog() > 4000):
  35.     if (not (BiaoShi == 4)):
  36.       BiaoShi = 4
  37.       mqtt.publish(str("car/control"), str("L").encode('utf-8'))
  38.   else:
  39.     if (not (BiaoShi == 5)):
  40.       mqtt.publish(str("car/control"), str("S").encode('utf-8'))
  41.       BiaoShi = 5
复制代码
小小屏幕也能接收行空板视频车图传图10
【完整程序】
行空板视频车完整程序
  1. import cv2
  2. import numpy as np
  3. import socket
  4. import time
  5. import binascii
  6. import socket
  7. import time
  8. from pinpong.board import Board
  9. from dfrobot_motor import MOTOR
  10. import siot
  11. from pinpong.extension.unihiker import *
  12. from unihiker import GUI
  13. u_gui=GUI()
  14. xianshi=u_gui.draw_text(text="开始",x=50,y=100,font_size=50, color="#0000FF")
  15. def forward(speed):
  16.   
  17.   #前进
  18.   #电机有M1,M2, CW代表正转,CCW代表反转,255是速度,范围0-255
  19.   if speed>255:
  20.       speed=255
  21.   M.motor_run(M.ALL,M.CW,speed)
  22.   
  23. def back(speed):
  24.   #后退
  25.   #电机有M1,M2, CW代表正转,CCW代表反转,255是速度,范围0-255
  26.   if speed>255:
  27.       speed=255
  28.   M.motor_run(M.ALL,M.CCW,speed)
  29. def left_turn(speed):
  30.   #向左转
  31.   #电机有M1,M2, CW代表正转,CCW代表反转,255是速度,范围0-255
  32.   if speed>255:
  33.       speed=255
  34.   M.motor_run(M.M1,M.CW,speed)
  35.   M.motor_run(M.M2,M.CCW,speed)
  36. def right_turn(speed):
  37.   #向右转
  38.   #电机有M1,M2, CW代表正转,CCW代表反转,255是速度,范围0-255
  39.   if speed>255:
  40.       speed=255
  41.   M.motor_run(M.M1,M.CCW,speed)
  42.   M.motor_run(M.M2,M.CW,speed)
  43. def stop():
  44.   M.motor_stop(M.ALL)
  45. # 事件回调函数
  46. def on_message_callback(client, userdata, msg):
  47.   
  48.   if (msg.payload.decode("utf-8")  == 'G'):
  49.       forward(200)
  50.       xianshi.config(text="前进")
  51.      
  52.   if (msg.payload.decode("utf-8")== 'S'):
  53.       stop()
  54.       xianshi.config(text="停止")   
  55.       
  56.   if (msg.payload.decode("utf-8") == 'B'):
  57.       back(200)
  58.       xianshi.config(text="后退")  
  59.       
  60.   if (msg.payload.decode("utf-8") == 'L'):
  61.       left_turn(200)
  62.       xianshi.config(text="向左")  
  63.       
  64.   if (msg.payload.decode("utf-8") == 'R'):
  65.       right_turn(200)
  66.       xianshi.config(text="向右")
  67. siot.init(client_id="siot_192",server="192.168.1.101",port=1883,user="siot",password="dfrobot")
  68. siot.connect()
  69. siot.loop()
  70. siot.set_callback(on_message_callback)
  71. siot.getsubscribe(topic="car/control")
  72. Board().begin()
  73. M = MOTOR()
  74. cap = cv2.VideoCapture(0)
  75. cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
  76. cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
  77. cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
  78. W=128
  79. H=64
  80. size = (W,H)
  81. val=0
  82. str1=''
  83. while(1): # get a frame and show
  84.     ret, frame1 = cap.read()
  85.     if(ret):
  86.         
  87.         frame1 = cv2.resize(frame1, size)
  88.         
  89.         gray1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
  90.         
  91.         BIN1= cv2.adaptiveThreshold(gray1,1,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,7,3)
  92.         
  93.         
  94.         str1=""
  95.         for h in range(H):
  96.           for w in range(0,W,16):
  97.              for i in range(4):
  98.                   val=(int(BIN1[h][w+i*4+0])*8 + int(BIN1[h][w+i*4+1])*4 + int(BIN1[h][w+i*4+2])*2 + int(BIN1[h][w+i*4+3])*1)
  99.                   if val>=10:
  100.                     if val == 10:
  101.                       str1=str1+'A'
  102.                     if val==11:
  103.                       str1=str1+'B'
  104.                     if val==12:
  105.                       str1=str1+'C'
  106.                     if val==13:
  107.                       str1=str1+'D'
  108.                     if val==14:
  109.                       str1=str1+'E'
  110.                     if val==15:
  111.                       str1=str1+'F'
  112.                   else:
  113.                       str1=str1+str(val)
  114.              str1=str1+" "
  115.         #print(str1)
  116.         s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  117.         s.connect(('192.168.1.100',10000))
  118.         s.send(bytearray.fromhex(str1))
  119.         time.sleep(0.19)
  120. cv2.destroyAllWindows()
复制代码


”鳄霸王“掌控板完整程序
  1. from mpython import *
  2. import usocket
  3. import network
  4. from umqtt.simple import MQTTClient
  5. my_wifi = wifi()
  6. my_wifi.connectWiFi("yuntian","yuntian123456")
  7. while not my_wifi.sta.isconnected():
  8.      pass
  9. p0=MPythonPin(0,PinMode.ANALOG)
  10. p1=MPythonPin(1,PinMode.ANALOG)
  11. mqtt = MQTTClient("", "192.168.1.101", 1883, "siot", "dfrobot")
  12. try:
  13.   mqtt.connect()
  14.   print('MQTT Connected Successful')
  15. except:
  16.   print('MQTT Connection Failed')
  17. oled.fill(0)
  18. oled.DispChar(my_wifi.sta.ifconfig()[0], 0, 0, 1)
  19. oled.show()
  20. BiaoShi = 0
  21. #socket.socket() 创建了一个 socket 对象,并且支持 context manager type,你可以使用 with 语句,这样你就不用再手动调用 s.close() 来关闭 socket 了
  22. s=usocket.socket(usocket.AF_INET,usocket.SOCK_STREAM)
  23. #bind() 方法的入参取决于 socket 的地址族,在这个例子中我们使用了 socket.AF_INET (IPv4),它接收一个二元组(host, port)入参
  24. #端口号应该是 1-65535 之间的整数(0是保留的),这个整数就是用来接受客户端链接的 TCP 端口号,如果端口号小于 1024,有的操作系统会要求管理员权限
  25. s.bind((my_wifi.sta.ifconfig()[0],10000))
  26. #listen() 方法调用使服务器可以接受连接请求,这使它成为一个「监听中」的 socket
  27. #listen() 方法有一个 backlog 参数。它指定在拒绝新的连接之前系统将允许使用的 未接受的连接 数量。从 Python 3.5 开始,这是可选参数。如果不指定,Python 将取一个默认值
  28. s.listen(5)
  29. while True:
  30.       #accept() 方法阻塞并等待传入连接。当一个客户端连接时,它将返回一个新的 socket 对象,对象中有表示当前连接的 conn 和一个由主机、端口号组成的 IPv4/v6 连接的元组
  31.       con=s.accept()[0]
  32.       data=con.recv(1024)
  33.       #framebuf.FrameBuffer(buffer, width, height, format) 可以构建帧缓存对象, buffer 为缓存区数据,width 为图片宽度,height 为图片高度,format 为FrameBuffer的格式,即对应图片取模时数据输出的扫描模式:framebuf.MONO_HLSB 为水平方向;framebuf.MONO_VLSB 为垂直方向。
  34.       fbuf=framebuf.FrameBuffer(bytearray(data),128,64,framebuf.MONO_HLSB)
  35.       oled.fill(0)
  36.       #oled.blit(fbuf, x, y) 使用OLED显示图片帧,fbuf 为FrameBuffer对象,x 、y 为起始点的坐标x、y。
  37.       oled.blit(fbuf,0,0)
  38.       oled.show()
  39.       con.close()
  40.       if (p0.read_analog() < 10):
  41.           if (not (BiaoShi == 1)):
  42.                BiaoShi = 1
  43.                mqtt.publish(str("car/control"), str("G").encode('utf-8'))
  44.       elif (p0.read_analog() > 4000):
  45.           if (not (BiaoShi == 2)):
  46.                BiaoShi = 2
  47.                mqtt.publish(str("car/control"), str("B").encode('utf-8'))
  48.       elif (p1.read_analog() < 10):
  49.           if (not (BiaoShi == 3)):
  50.                BiaoShi = 3
  51.                mqtt.publish(str("car/control"), str("R").encode('utf-8'))
  52.       elif (p1.read_analog() > 4000):
  53.           if (not (BiaoShi == 4)):
  54.                BiaoShi = 4
  55.                mqtt.publish(str("car/control"), str("L").encode('utf-8'))
  56.       else:
  57.           if (not (BiaoShi == 5)):
  58.                mqtt.publish(str("car/control"), str("S").encode('utf-8'))
  59.                BiaoShi = 5
复制代码

附件: dfrobot_motor.py需拷贝到行空板,与程序在同一目录
下载附件dfrobot_motor.zip



创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(7)
Z7AoUY2D2kq8
Z7AoUY2D2kq8
厉害厉害厉害厉害
曾剑波
曾剑波
这个不错!值得学习!其实很多都是基于基础知识,就是实战应用场景切入而已
easy猿
easy猿
太牛了
rzyzzxw
rzyzzxw
确实厉害
独钓寒江雪
独钓寒江雪
小小掌控,大大用处,掌控板行空板yyds!赞一个!
花生编程
花生编程
赞!!
花生编程
花生编程
厉害厉害
- 没有更多了 -