内容介绍
内容介绍
项目背景
首先由衷的祝愿电子森林发展的越来越好,自从参与Funpack项目以来,接触了越来越多的开发板,也拓宽了很多知识面,所以无需犹豫,果断参与第四期。
本项目即是实现一个赛车模拟器的配套外设,用于玩家在使用赛车模拟器的时候,可以像驾驶真实汽车一样,直观的获取到比赛中最重要的时速、转速、挡位等信息,以达到更好的成绩,Adruino UNO R4 WIFI(以下简称Arduino)有一个12x8 的LED矩阵,用作赛车模拟器的挡位指示非常合适。
项目详情
项目使用ESP32作为联网模块,将Arduino连接到局域网后,与上位机建立通讯,上位机实时获取游戏里赛车的遥测数据并通过局域网发送给Arduino,Arduino驱动LED矩阵显示挡位信息。项目架构如下:
设计思路
- 上位机通过UDP与游戏建立通讯,获取到游戏中赛车的实时遥测数据。
- 上位机和Arduino之间建立UDP通讯,将遥测数据下发到Arduino
- Arduino有挂载ESP32的WIFI模组,可以与上位机在局域网内建立通讯。
- Arduino有8x12的LED矩阵,可以用来自由定制要显示的数字或字母等信息
硬件介绍
Pin Out信息
系统框图
LED矩阵Map
软件流程
如上图所示,Arduino在上电后,通过配置的WIFI SSID和PassWord连接到局域网,确定网络连接成功后,开启UDP与上位机建立通讯,当收到上位机下发的数据后,使用结构体解析出需要的Gear挡位信息,并更新LED矩阵的内容显示。
开发过程
Ardruino官方提供了非常丰富的资料,跟随官方文档和示例,能够很快速的完成本次项目的开发
https://docs.arduino.cc/tutorials/uno-r4-wifi/wifi-examples/
显示内容准备
const uint32_t gear_0[] = {
0xf009009,
0x900900,
0x900f0000
};
const uint32_t gear_1[] = {
0xc014004,
0x400400,
0x401f0000
};
const uint32_t gear_2[] = {
0xf001001,
0xf00800,
0x800f0000
};
//......其余0-8的显示内容省略
UDP通讯
#include "Arduino_LED_Matrix.h" // Include the LED_Matrix library
#include "frames.h" // Include a header file containing some custom icons
#include <WiFiS3.h>
#include <string.h>
#define SECRET_SSID "Arilink"
#define SECRET_PASS "********"
int status = WL_IDLE_STATUS;
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key index number (needed only for WEP)
unsigned int localPort = 2390; // local port to listen on
char packetBuffer[256]; //buffer to hold incoming packet
uint8_t recvBuffer[4];
char ReplyBuffer[] = "acknowledged\n"; // a string to send back
WiFiUDP Udp;
ArduinoLEDMatrix matrix; // Create an instance of the ArduinoLEDMatrix class
#pragma pack(push) // 将当前对齐方式推入堆栈
#pragma pack(1) // 设置一字节对齐
typedef struct {
int8_t gear;
uint8_t reserved;
uint16_t led_num;
uint16_t speed;
uint16_t rpm;
}CarStatus;
#pragma pack(pop) // 将对齐方式设置回之前的值
void setup() {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to WiFi");
printWifiStatus();
Serial.println("\nStarting connection to server...");
// if you get a connection, report back via serial:
Udp.begin(localPort);
matrix.begin(); // Initialize the LED matrix
}
遥测数据解析
void loop() {
// Load and display the "chip" frame on the LED matrix
// for(int i = -1; i < 9; i++)
// {
// update_gear_ind(i);
// delay(500); // Pause for 500 milliseconds (half a second)
// }
// // Turn off the display
// matrix.clear();
// delay(1000);
// // Print the current value of millis() to the serial monitor
// Serial.println(millis());
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if (packetSize) {
// Serial.print("Received packet of size ");
// Serial.println(packetSize);
//Serial.print("From ");
// IPAddress remoteIp = Udp.remoteIP();
// Serial.print(remoteIp);
// Serial.print(", port ");
// Serial.println(Udp.remotePort());
// read the packet into packetBuffer
int len = Udp.read(recvBuffer, 8);
// if (len > 0) {
// packetBuffer[len] = 0;
// }
CarStatus *curCarStatus = (CarStatus*)recvBuffer;
char logBuffer[50];
//snprintf(logBuffer,sizeof(logBuffer),"Speed:%d Gear:%d RPM:%d",curCarStatus->speed,curCarStatus->gear,curCarStatus->rpm);
if((curCarStatus->speed)!=0)
{
update_gear_ind(curCarStatus->gear);
}
Udp.endPacket();
}
}
挡位信息更新
void update_gear_ind(int gear)
{
switch(gear)
{
case 0:
matrix.loadFrame(gear_0);
break;
case 1:
matrix.loadFrame(gear_1);
break;
case 2:
matrix.loadFrame(gear_2);
break;
case 3:
matrix.loadFrame(gear_3);
break;
case 4:
matrix.loadFrame(gear_4);
break;
case 5:
matrix.loadFrame(gear_5);
break;
case 6:
matrix.loadFrame(gear_6);
break;
case 7:
matrix.loadFrame(gear_7);
break;
case 8:
matrix.loadFrame(gear_8);
break;
case -1:
matrix.loadFrame(gear_r);
break;
default:
matrix.loadFrame(gear_0);
break;
}
}
//........
项目展示
项目演示视频已上传到B站,链接如下:
附件下载
RacingGear.rar
RacingGear源代码
团队介绍
self
评论
0 / 100
查看更多
猜你喜欢
Funpack S3#5 Arduino UNO R4 WiFi 点灯该项目使用了Arduino UNO R4 WiFi 开发板,Arduino云,实现了点亮LED灯并显示太阳图标的设计,它的主要功能为:通过网络连接到智能云端,尝试将设备模拟成可以控制的灯,远程端发送指令,将灯光开启关闭,或调整灯光的亮度,0到90%时,矩阵亮起逐渐变大的范围,90%以上时,灯板显示出太阳的图标。。
动植物
161
Funpack - S4 - Teensy - 模拟赛车速度指示器(RacingSpeed)该项目使用了Teensy 4.1,实现了模拟赛车时速仪表的设计,它的主要功能为:实时显示赛车的车速信息,便于车手更好的驾驶赛车。
arilink
22
Funpack - S3-5 - BeagleBoneBlack - 模拟赛车转速灯(RacingRPM)该项目使用了BeagleBoneBlack,实现了模拟赛车转速灯(RacingRPM)的设计,它的主要功能为:实时显示赛车游戏里车辆的转速信息。
arilink
17