Signed-off-by: myperworld <myperworld@126.com>

This commit is contained in:
myperworld committed 2025-10-06 12:34:26 +08:00
1 parent 0986832fd1
commit aacd052c06
3403 files changed
+597376 -12

No files matched your search

@@ -0,0 +1,261 @@
#ifndef ESPNOW_H
#define ESPNOW_H
#include <WiFi.h>
#include <esp_now.h>
//全0xFF的Mac地址时广播到附近所有ESPNOW设备
uint8_t broadcastAddress[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
//uint8_t PairAddress[6] = {};
//
//esp_now_peer_info_t peerInfo = {};
//
//#define MAC_ADDRESS_OFFSET 10 // 存MAC地址的EEPROM地址,从10开始
// Global copy of slave
#define NUMSLAVES 5
esp_now_peer_info_t slaves[NUMSLAVES] = {};
int SlaveCnt = 0;
#define CHANNEL 1
#define PRINTSCANRESULTS 0
//bool SCAN=1;
//int8_t scanResults = 0;
//
//// 初始化一个二维字符数组,用于存储MAC地址
//char PairMacAddress[5][18]; // 5表示你可以存储5个MAC地址,18是因为一个MAC地址的长度是17个字符,再加一个'\0'字符用于字符串结束
//int macCount = 0; // 记录已存储的MAC地址数量
//配对连接pair with another ESP-NOW device
void BroadcastMode(){
SlaveCnt=1;
memcpy(&slaves[0].peer_addr, broadcastAddress, 6);
if (!esp_now_is_peer_exist(broadcastAddress))
{
esp_now_add_peer(&slaves[0]);
}
}
// Scan for slaves in AP mode
void ScanForSlave() {
int8_t scanResults = WiFi.scanNetworks();
//reset slaves
memset(slaves, 0, sizeof(slaves));
SlaveCnt = 0;
Serial.println("");
if (scanResults == 0) {
Serial.println("No WiFi devices in AP Mode found");
} else {
Serial.print("Found "); Serial.print(scanResults); Serial.println(" devices ");
for (int i = 0; i < scanResults; ++i) {
// Print SSID and RSSI for each device found
String SSID = WiFi.SSID(i);
int32_t RSSI = WiFi.RSSI(i);
String BSSIDstr = WiFi.BSSIDstr(i);
if (PRINTSCANRESULTS) {
Serial.print(i + 1); Serial.print(": "); Serial.print(SSID); Serial.print(" ["); Serial.print(BSSIDstr); Serial.print("]"); Serial.print(" ("); Serial.print(RSSI); Serial.print(")"); Serial.println("");
}
delay(10);
// Check if the current device starts with `Slave`
if (SSID.indexOf("Slave") == 0) {
// SSID of interest
Serial.print(i + 1); Serial.print(": "); Serial.print(SSID); Serial.print(" ["); Serial.print(BSSIDstr); Serial.print("]"); Serial.print(" ("); Serial.print(RSSI); Serial.print(")"); Serial.println("");
// Get BSSID => Mac Address of the Slave
int mac[6];
if ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ) ) {
for (int ii = 0; ii < 6; ++ii ) {
slaves[SlaveCnt].peer_addr[ii] = (uint8_t) mac[ii];
}
}
slaves[SlaveCnt].channel = CHANNEL; // pick a channel
slaves[SlaveCnt].encrypt = 0; // no encryption
SlaveCnt++;
}
}
}
if (SlaveCnt > 0) {
Serial.print(SlaveCnt); Serial.println(" Slave(s) found, processing..");
} else {
Serial.println("No Slave Found, trying again.");
}
// clean up ram
WiFi.scanDelete();
}
// Check if the slave is already paired with the master.
// If not, pair the slave with master
void manageSlave() {
if (SlaveCnt > 0) {
for (int i = 0; i < SlaveCnt; i++) {
Serial.print("Processing: ");
for (int ii = 0; ii < 6; ++ii ) {
Serial.print((uint8_t) slaves[i].peer_addr[ii], HEX);
if (ii != 5) Serial.print(":");
}
Serial.print(" Status: ");
// check if the peer exists
bool exists = esp_now_is_peer_exist(slaves[i].peer_addr);
if (exists) {
// Slave already paired.
Serial.println("Already Paired");
} else {
// Slave not paired, attempt pair
esp_err_t addStatus = esp_now_add_peer(&slaves[i]);
if (addStatus == ESP_OK) {
// Pair success
Serial.println("Pair success");
} else if (addStatus == ESP_ERR_ESPNOW_NOT_INIT) {
// How did we get so far!!
Serial.println("ESPNOW Not Init");
} else if (addStatus == ESP_ERR_ESPNOW_ARG) {
Serial.println("Add Peer - Invalid Argument");
} else if (addStatus == ESP_ERR_ESPNOW_FULL) {
Serial.println("Peer list full");
} else if (addStatus == ESP_ERR_ESPNOW_NO_MEM) {
Serial.println("Out of memory");
} else if (addStatus == ESP_ERR_ESPNOW_EXIST) {
Serial.println("Peer Exists");
} else {
Serial.println("Not sure what happened");
}
delay(100);
}
}
} else {
// No slave found to process
Serial.println("No Slave found to process,Switch to Broadcast Mode");
}
}
// 设置数据结构体
typedef struct Data_Package {
byte j1PotX; //左右摇杆
byte j1PotY;
byte j2PotX;
byte j2PotY;
bool buttonR1; //左右按键
bool buttonR2;
bool j1Button; //左右摇杆按键
bool j2Button;
bool buttonLB; //左右扳机按键
bool buttonRB;
bool tSwitch1; //拨动开关
byte roll; //用于M5StackCore2或未来增加的陀螺仪功能
byte pitch;
bool buttonR3;
};
Data_Package data; //Create a variable with the above structure
void resetData() { //数据重置
// Reset the values when there is no radio connection - Set initial default values
data.j1PotX = 127;
data.j1PotY = 127;
data.j2PotX = 127;
data.j2PotY = 127;
data.buttonR1 = 1;
data.buttonR2 = 1;
data.j1Button = 1;
data.j2Button = 1;
data.buttonLB = 1;
data.buttonRB = 1;
data.tSwitch1 = 1;
data.roll=127;
data.pitch=127;
data.buttonR3 = 1;
}
/////////////////////////////////////////
// 数据发送回调函数
// callback when data is sent from Master to Slave
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
// Serial.print("Last Packet Sent to: "); Serial.println(macStr);
// Serial.print("Last Packet Send Status: "); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
// 数据接收回调函数
// callback when data is received from Slave to Master
void OnDataRecv(const uint8_t *mac_addr, const uint8_t *incomingData, int data_len) {
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
memcpy(&data, incomingData, sizeof(data));
// Serial.print("j1PotX: ");
// Serial.print(data.j1PotX);
// Serial.print("; j1PotY: ");
// Serial.print(data.j1PotY);
// Serial.print("; j2PotX: ");
// Serial.print(data.j2PotX);
// Serial.print("; j2PotY: ");
// Serial.println(data.j2PotY);
}
// Init ESP Now with fallback
void InitESPNow() {
WiFi.disconnect();
if (esp_now_init() == 0) { //ESP_OK=0
Serial.println("ESPNow Init Success");
}
else {
Serial.println("ESPNow Init Failed");
// Retry InitESPNow, add a counte and then restart?
// InitESPNow();
// or Simply Restart
ESP.restart();
}
}
////配对连接pair with another ESP-NOW device
//void pair_device(){
// memcpy(&peerInfo.peer_addr, broadcastAddress, 6);
// if (!esp_now_is_peer_exist(broadcastAddress))
// {
// esp_now_add_peer(&peerInfo);
// }
//}
//// 发送数据 send data
//void sendData() { //uint8_t data
// esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &data, sizeof(data));
//}
// 发送数据 send data
void sendData() {
for (int i = 0; i < SlaveCnt; i++) {
const uint8_t *peer_addr = slaves[i].peer_addr;
esp_err_t result = esp_now_send(peer_addr, (uint8_t *) &data, sizeof(data));
// Serial.print("Send Status: ");
// if (result == ESP_OK) {
// Serial.println("Success");
// } else if (result == ESP_ERR_ESPNOW_NOT_INIT) {
// // How did we get so far!!
// Serial.println("ESPNOW not Init.");
// } else if (result == ESP_ERR_ESPNOW_ARG) {
// Serial.println("Invalid Argument");
// } else if (result == ESP_ERR_ESPNOW_INTERNAL) {
// Serial.println("Internal Error");
// } else if (result == ESP_ERR_ESPNOW_NO_MEM) {
// Serial.println("ESP_ERR_ESPNOW_NO_MEM");
// } else if (result == ESP_ERR_ESPNOW_NOT_FOUND) {
// Serial.println("Peer not found.");
// } else {
// Serial.println("Not sure what happened");
// }
// delay(10);
}
}
#endif
@@ -0,0 +1,217 @@
#ifndef MAPDATA_H
#define MAPDATA_H
#include <EEPROM.h>
#define EEPROM_SIZE 64
// TRIGGER BUTTONS
#define LB 19
#define RB 25
// LEFT-JOYSTICK
#define LH 34
#define LV 35
#define LS 5
// RIGHT-JOYSTICK
#define RH 36
#define RV 32
#define RS 4
#define R1 2
#define R2 13
// BATTERY VOLTAGE
#define ADC 39 //电池ADC
// RGB
//#define DATA_PIN 17
//OTHERS
#define BK 23 //拨动开关
int buttons[7] = {R1,R2,LS,RS,LB,RB,BK};
const int numberOfPotSamples = 5; // Number of pot samples to take (to smooth the values)
const int delayBetweenSamples = 2; // Delay in milliseconds between pot samples
int LX_read = 0;
int LY_read = 0;
int RX_read = 0;
int RY_read = 0;
byte LX_zero = 127;
byte LY_zero = 127;
byte RX_zero = 127;
byte RY_zero = 127;
int LX_to_send = 0;
int LY_to_send = 0;
int RX_to_send = 0;
int RY_to_send = 0;
bool LY_inverted = false;
bool LX_inverted = false;
bool RY_inverted = false;
bool RX_inverted = false;
int counter = 0;
int invert_counter = 0;
float voltage = 3.00;
int percentage = 0;
void pinmode_pullup(){
for (int i = 0; i < 7; i++) {
pinMode(buttons[i], INPUT_PULLUP);
}
}
/**************************************************/
int map_normal(int val, int lower, int middle, int upper, bool reverse)
{
val = constrain(val, lower, upper);
if ( val < middle )
val = map(val, lower, middle, 0, 127);
else
val = map(val, middle, upper, 127, 255);
return ( reverse ? 255 - val : val );
}
// Returns a corrected value for a joystick position that takes into account
// the values of the outer extents and the middle of the joystick range.
int map_exponential(int val, bool reverse)
{
val = constrain(val, 0, 1023);
float cube = ((pow((val - 512),3)/520200) + 258.012) / 2;
return ( reverse ? 255 - cube : cube );
}
/**************************************************/
void read_joydata(){
int potValues[numberOfPotSamples];
for (int i = 0 ; i < numberOfPotSamples ; i++) {
potValues[i] = analogRead(LH);
delay(delayBetweenSamples);
}
int potValue = 0;
for (int i = 0 ; i < numberOfPotSamples ; i++) {
potValue += potValues[i];
}
potValue = potValue / numberOfPotSamples;
LX_read = map(potValue, 0, 4095, 255, 0);
int potValues2[numberOfPotSamples];
for (int i = 0 ; i < numberOfPotSamples ; i++) {
potValues2[i] = analogRead(LV);
delay(delayBetweenSamples);
}
int potValue2 = 0;
for (int i = 0 ; i < numberOfPotSamples ; i++) {
potValue2 += potValues2[i];
}
potValue2 = potValue2 / numberOfPotSamples;
LY_read = map(potValue2, 0, 4095, 255, 0);
int potValues3[numberOfPotSamples];
for (int i = 0 ; i < numberOfPotSamples ; i++) {
potValues3[i] = analogRead(RH);
delay(delayBetweenSamples);
}
int potValue3 = 0;
for (int i = 0 ; i < numberOfPotSamples ; i++) {
potValue3 += potValues3[i];
}
potValue3 = potValue3 / numberOfPotSamples;
RX_read = map(potValue3, 0, 4095, 255, 0);
int potValues4[numberOfPotSamples];
for (int i = 0 ; i < numberOfPotSamples ; i++) {
potValues4[i] = analogRead(RV);
delay(delayBetweenSamples);
}
int potValue4 = 0;
for (int i = 0 ; i < numberOfPotSamples ; i++) {
potValue4 += potValues4[i];
}
potValue4 = potValue4 / numberOfPotSamples;
RY_read = map(potValue4, 0, 4095, 255, 0);
}
void zero_test(){ //摇杆原点纠偏程序
Serial.println(" joy_zero_testing... ");
read_joydata();
delay (300);
LX_to_send = map_normal(LX_read, 0, 127, 255, 0);
LY_to_send = map_normal(LY_read, 0, 127, 255, 0);
RX_to_send = map_normal(RX_read, 0, 127, 255, 0);
RY_to_send = map_normal(RY_read, 0, 127, 255, 0);
LX_to_send = constrain(LX_to_send,0,255);
LY_to_send = constrain(LY_to_send,0,255);
RX_to_send = constrain(RX_to_send,0,255);
RY_to_send = constrain(RY_to_send,0,255);
LX_zero = LX_to_send;
LY_zero = LY_to_send;
RX_zero = RX_to_send;
RY_zero = RY_to_send;
Serial.println(" Writing in EEPROM... ");
delay (300);
if( EEPROM.read(1) != LX_zero) EEPROM.write(1, LX_zero);
if( EEPROM.read(2) != LY_zero) EEPROM.write(2, LY_zero);
if( EEPROM.read(3) != RX_zero) EEPROM.write(3, RX_zero);
if( EEPROM.read(4) != RY_zero) EEPROM.write(4, RY_zero);
EEPROM.commit();
Serial.println(" Done... ");
Serial.print(" LX_zero: ");Serial.print(EEPROM.read(1));
Serial.print(" LY_zero: ");Serial.print(EEPROM.read(2));
Serial.print(" RX_zero: ");Serial.print(EEPROM.read(3));
Serial.print(" RY_zero: ");Serial.println(EEPROM.read(4));
}
void eeprom_ini(){
EEPROM.begin(EEPROM_SIZE);
if( EEPROM.read(0) != 55){ //判断是否首次使用(新的所有地址貌似是255的值)
zero_test();
EEPROM.write(0, 55);
EEPROM.commit();
}
LX_zero = EEPROM.read(1);
LY_zero = EEPROM.read(2);
RX_zero = EEPROM.read(3);
RY_zero = EEPROM.read(4);
}
void batteryLevel() {
int sensorValue = analogRead(ADC);
voltage = sensorValue/4095.0 * 7.27; //7.23乘数具体数值用万用表实测纠偏
percentage = (voltage-3.2) * 100;
// percentage = 2808.3808 * pow(voltage,4) - 43560.9157 * pow(voltage,3) + 252848.5888 * pow(voltage,2)
// - 650767.4615 * voltage + 626532.5703; //这段计算公式参考https://www.youtube.com/watch?v=qKUrXwkr3cc
if (voltage>4.19) percentage = 100; //限制到0-100范围
if (voltage<3.20) percentage = 0;
if (voltage>3.00){
// Serial.print("Lipo: ");Serial.print(voltage);Serial.print("V || ");
// Serial.print(percentage);Serial.println("%");
}
}
#endif
@@ -0,0 +1,210 @@
#ifndef WEMOS_OLED_H
#define WEMOS_OLED_H
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// SCL GPIO5
// SDA GPIO4
#define OLED_RESET 0 // GPIO0
Adafruit_SSD1306 display(OLED_RESET);
//取64*30 逐行式 顺向高位在前
static const unsigned char PROGMEM pic1[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0xC0,0x00,
0x1F,0xE0,0x00,0x00,0x07,0xFF,0xF0,0x00,0x1F,0xF8,0x00,0x00,0x0F,0xFF,0xFC,0x00,
0x1F,0xFC,0x00,0x00,0x0F,0xFF,0xFE,0x00,0x1F,0xFE,0x00,0x00,0x0F,0xFF,0xFF,0x00,
0x1F,0xFF,0x00,0x00,0x0F,0xFF,0xFF,0x80,0x0F,0xFF,0x3F,0xC0,0x0F,0xFF,0x1F,0x80,
0x07,0xFF,0x7F,0xF8,0x0F,0xE0,0x01,0xC0,0x00,0x07,0x7F,0xFC,0x07,0xE0,0x00,0xC0,
0x1C,0x03,0x7F,0xFE,0x07,0xC0,0x1C,0xC0,0x3E,0x03,0x7F,0xFE,0x07,0xDC,0x3E,0xC0,
0x3E,0x03,0x7F,0xFE,0x07,0xDE,0x7E,0x40,0x3E,0x02,0x3F,0xFE,0x07,0xDF,0xFE,0x40,
0x3E,0x06,0x01,0xFC,0x07,0xC7,0xFE,0x40,0x3E,0x08,0xC0,0x1C,0x0F,0xC7,0xFC,0x40,
0x1F,0x00,0xF8,0x38,0x0F,0xCF,0xF8,0x40,0x0F,0xFC,0xFF,0x70,0x0F,0x9F,0xF8,0x40,
0x07,0xE6,0x7F,0xE0,0x0F,0x9F,0xF8,0x40,0x00,0x06,0x3F,0xF8,0x0F,0x9F,0xCC,0x60,
0x03,0xE6,0x0F,0xF8,0x0F,0x9F,0x06,0x70,0x0F,0xE6,0x0F,0xF8,0x0F,0x0E,0x00,0x3C,
0x1F,0x8C,0x18,0x30,0x0F,0x00,0x00,0x00,0x0F,0x08,0x00,0x00,0x0E,0x00,0x00,0x00,
0x0C,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
#if (SSD1306_LCDHEIGHT != 48)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
void oleddisplay(){ //WEMOS_OLED扩展板屏幕显示
display.clearDisplay();//清屏
display.setCursor(1,23);
display.print("X:");
display.print(data.j1PotX);
display.setCursor(1,35);
display.print("Y:");
display.print(data.j1PotY);
display.setCursor(34,23);
display.print("X:");
display.print(data.j2PotX);
display.setCursor(34,35);
display.print("Y:");
display.print(data.j2PotY);
if(!data.buttonLB) display.fillCircle(0, 0, 3, WHITE);
if(!data.buttonR2) display.fillCircle(0, 48, 3, WHITE);
if(!data.buttonRB) display.fillCircle(64, 0, 3, WHITE);
if(!data.buttonR1) display.fillCircle(64, 48, 3, WHITE);
display.invertDisplay((data.tSwitch1?0:1));
display.drawLine(0, 14, 64, 14, WHITE);
display.setCursor(31,4);display.print(voltage);display.print("V");
display.drawRoundRect(3,4,20,7,1,WHITE);
display.fillRoundRect(3,4,map(percentage,0,100,0,20),7,1,WHITE);
display.fillRect(23,6,2,3,WHITE);
display.display();
}
//在CORE0上运行OLED相关程序(Arduino默认在CORE1上运行)
/*************************************/
TaskHandle_t Task1;
//Task1code: blinks an LED every 1000 ms
void Task1code( void * pvParameters ){
//
Serial.print("Task1 running on core ");
Serial.println(xPortGetCoreID());
/************************************************/
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //注:有时地址不是0x3C,可能是0x3D等,若屏幕不亮可以试试用wire库中的示例程序扫描地址
/************************************************/
display.setTextColor(WHITE);//开像素点发光
display.setTextSize(1);
for(int i=0;i<=18;i++){
display.clearDisplay();//清屏
display.drawBitmap(0, i, pic1, 64, 30, WHITE); //画出字符对应点阵数据
display.display();//开显示
delay(20);
}
for(int i=18;i>=9;i--){
display.clearDisplay();//清屏
display.drawBitmap(0, i, pic1, 64, 30, WHITE); //画出字符对应点阵数据
display.display();//开显示
delay(20);
}
delay(600);
for(;;){
oleddisplay();//WEMOS_OLED扩展板屏幕显示
delay(10);
/************************************************/
//同时按下四键及拨动开关 关 3秒后进行摇杆原点纠偏,此时不要碰摇杆
if (!data.buttonR1&&!data.buttonR2&&!data.buttonLB&&!data.buttonRB&&!data.tSwitch1){
delay (2000);
if (!data.buttonR1&&!data.buttonR2&&!data.buttonLB&&!data.buttonRB&&!data.tSwitch1){
display.clearDisplay();//清屏
display.setCursor(6,6); display.print("Zero_test");
display.setCursor(4,22); display.print("Testing...");
display.display();//开显示
delay (1000);
display.clearDisplay();//清屏
display.setCursor(6,6); display.print("Zero_test");
display.setCursor(1,18);
display.print("X:");
display.print(EEPROM.read(1));
display.setCursor(1,30);
display.print("Y:");
display.print(EEPROM.read(2));
display.setCursor(34,18);
display.print("X:");
display.print(EEPROM.read(3));
display.setCursor(34,30);
display.print("Y:");
display.print(EEPROM.read(4));
display.display();//开显示
delay (2000);
}
}
//同时按下四键及拨动开关 开 2秒后进行扫描MAC地址及配对
if (!data.buttonR1&&!data.buttonR2&&!data.buttonLB&&!data.buttonRB&&data.tSwitch1){
delay (2000);
if (!data.buttonR1&&!data.buttonR2&&!data.buttonLB&&!data.buttonRB&&data.tSwitch1){
display.clearDisplay();//清屏
display.setCursor(6,6); display.print("Scan&Pair");
display.setCursor(4,22); display.print("Scaning...");
display.display();//开显示
// delay (1000);
display.clearDisplay();//清屏
ScanForSlave();
// If Slave is found, it would be populate in `slave` variable
// We will check if `slave` is defined and then we proceed further
manageSlave();
if (SlaveCnt > 0) { // check if slave channel is defined
//屏幕空间受限,只显示两个MAC地址
for (int i = 0; i < 2; i++) { //屏幕空间受限,只显示两个MAC地址
display.setCursor(0,8+i*20);
// 将MAC地址数组中的值转换为字符串并显示
char macStr[18]; // 假设MAC地址以冒号分隔的形式显示,需要18个字符的缓冲区(包括结尾的'\0')
for (int j = 0; j < 6; j++) {
sprintf(&macStr[j*3], "%02X:", slaves[i].peer_addr[j]); // 将每个字节转换为两位的十六进制字符串并拼接到macStr中
}
macStr[17] = '\0'; // 结尾的冒号是多余的,需要删除
display.print(macStr); // 显示MAC地址字符串
}
} else {
BroadcastMode();
display.setCursor(6,6);
display.print("No Slave");
display.setCursor(4,15);
display.print("Broadcast");
display.setCursor(0,28);
// 将MAC地址数组中的值转换为字符串并显示
char macStr[18]; // 假设MAC地址以冒号分隔的形式显示,需要18个字符的缓冲区(包括结尾的'\0')
for (int j = 0; j < 6; j++) {
sprintf(&macStr[j*3], "%02X:", slaves[0].peer_addr[j]); // 将每个字节转换为两位的十六进制字符串并拼接到macStr中
}
macStr[17] = '\0'; // 结尾的冒号是多余的,需要删除
display.print(macStr); // 显示MAC地址字符串
}
display.display();//开显示
delay (3000);
}
}
//同时按下四键后变换背光RGB模式
if (!data.j1Button&&!data.j2Button&&!data.buttonLB&&!data.buttonRB){
delay (300);
if (!data.j1Button&&!data.j2Button&&!data.buttonLB&&!data.buttonRB){
display.clearDisplay();//清屏
display.setCursor(8,16); display.print("Back_RGB:");
display.setCursor(15,28); display.print("Mode:");
display.setCursor(47,28); display.print(lightState);
display.display();//开显示
delay (1500);
}
}
/************************************************/
}
}
void run_OLED_on_Core_0(){
//create a task that will be executed in the Task1code() function, with priority 1 and executed on core 0
xTaskCreatePinnedToCore(
Task1code, /* Task function. */
"Task1", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task1, /* Task handle to keep track of created task */
0); /* pin task to core 0 */
delay(500);
}
/*************************************/
#endif
@@ -0,0 +1,107 @@
#ifndef WS2812_FASTLED_H
#define WS2812_FASTLED_H
#include <FastLED.h> //控制RGB灯的库文件
#define NUM_LEDS 8 //灯珠的数量,若改造成其他数量自行更改
#define LED_DT 17 //RGB灯上DI信号输入接引脚
#define LED_TYPE WS2812 //WS2812LED灯内置芯片对应的型号
#define COLOR_ORDER GRB //WS2812LED灯对应的色彩顺序
uint8_t max_bright=127; //可改变此值调节LED灯的最大亮度(0-255)建议不要太亮对眼睛不好
uint8_t min_bright=5; //可改变此值调节LED灯的最小亮度(0-255)
uint8_t rgb_bright=50; //可改变此值调节LED灯的默认亮度(0-255)建议不要太亮对眼睛不好
uint8_t lightState=0; //可改变此值调节默认的灯开关模式,默认为模式1,0为关
//可增加更多的变化模式
#define LED_DT1 14 //左摇杆RGB灯上DI信号输入接引脚
#define LED_DT2 16 //右摇杆RGB灯上DI信号输入接引脚
#define twinkleInterval 200 // 摇杆LED星闪模式,闪烁间隔时间 (毫秒)
#define twinkleChance 20 // 闪烁数量,数值越大闪烁越多(0-255)
CRGB leds[NUM_LEDS]; //LED建立对象等
CHSV myHSVcolor(0,255,rgb_bright);
CRGB leds1[NUM_LEDS]; //左摇杆LED建立对象等
CRGB leds2[NUM_LEDS]; //右摇杆LED建立对象等
//int thisdelay = 15; // Standard delay
uint8_t thisdiff = 1; // Standard palette jump
bool thisdir = 0; // Standard direction
uint8_t thisindex = 0; // Standard palette index
uint8_t thisrot = 1; // You can change how quickly the hue rotates for this wave. Currently 0.
//uint8_t thatrot = 0; // You can change how quickly the hue rotates for the other wave. Currently 0.
void FastLED_ini(){
// LEDS.addLeds<LED_TYPE,LED_DT,COLOR_ORDER>(leds,NUM_LEDS); //LED初始化
// LEDS.addLeds<LED_TYPE,LED_DT1,COLOR_ORDER>(leds1,NUM_LEDS); //LED初始化
// LEDS.addLeds<LED_TYPE,LED_DT2,COLOR_ORDER>(leds2,NUM_LEDS); //LED初始化
FastLED.setBrightness(rgb_bright); //设置LED亮度
}
void rainbow_march() { // The fill_rainbow call doesn't support brightness levels
if (thisdir == 0) thisindex += thisrot; else thisindex-= thisrot; // I could use signed math, but 'thisdir' works with other routines.
fill_rainbow(leds, NUM_LEDS, thisindex, thisdiff); // I don't change deltahue on the fly as it's too fast near the end of the strip.
} // rainbow_march()
void addGlitter(uint8_t chanceofGlitter){ //随机闪光灯效果
if (random8()<chanceofGlitter){
leds[random8(NUM_LEDS)]=CRGB::White;
}
}
void runLED(){
lightState = 0;
if (lightState==0){
fill_solid (leds,NUM_LEDS,CRGB::Black); //关灯
FastLED.show();
}else if(lightState==1){ //特效1
thisrot=1; thisdiff=1;
rainbow_march();
// addGlitter(2); //随机闪光灯效果,调节数值改变闪光频率
FastLED.show();
// delay(thisdelay);
}else if(lightState==2){ //特效2
thisrot=2; thisdiff=10;
rainbow_march();
// addGlitter(2); //随机闪光灯效果,调节数值改变闪光频率
FastLED.show();
// delay(thisdelay);
}else if(lightState==3){ //特效3
thisrot=1; thisdiff=5;
rainbow_march();
// addGlitter(2); //随机闪光灯效果,调节数值改变闪光频率
FastLED.show();
// delay(thisdelay);
}
}
void joy1_led_blink(){ //星闪模式
int pos1 = random8(NUM_LEDS);
EVERY_N_MILLISECONDS( twinkleInterval ) {
if( random8() < twinkleChance) {
leds1[pos1] = ColorFromPalette( PartyColors_p, random8(255), max_bright/2, LINEARBLEND);
}
}
EVERY_N_MILLISECONDS( 10 ) {
fadeToBlackBy( leds1, NUM_LEDS, 10);
}
FastLED.show();
}
void joy2_led_blink(){ //星闪模式
int pos2 = random8(NUM_LEDS);
EVERY_N_MILLISECONDS( twinkleInterval ) {
if( random8() < twinkleChance) {
leds2[pos2] = ColorFromPalette( PartyColors_p, random8(255), max_bright/2, LINEARBLEND);
}
}
EVERY_N_MILLISECONDS( 10 ) {
fadeToBlackBy( leds2, NUM_LEDS, 10);
}
FastLED.show();
}
#endif