赞
踩
来源:
v1版本::【开源】百元内可自制的自平衡莱洛三角形_哔哩哔哩_bilibili
v2版本: 【开源】自平衡莱洛三角形V2 | 我加了RGB性能翻倍_哔哩哔哩_bilibili
原作者开源链接:https://gitee.com/coll45/foc
(本篇文章所有函数均为此开源网站下载函数)
说明:第一次接触Arduino和ESP32
关于此作品,作者在立创开源社区做了详细描述:
立创社区链接:v1:自平衡的莱洛三角_esp32_可充电_10*10版本 - 立创EDA开源硬件平台
v2:莱洛三角V2-esp32-无刷驱动EG2133 - 立创EDA开源硬件平台
灯哥开源FOC:【发布】不足百元!双路无刷电机驱动器 -灯哥双路无刷FOC驱动板正式开源!支持四足机器人!_哔哩哔哩_bilibili
simpleFOC库
KalmanFilter
FOC算法入门:FOC算法入门_梦如南伐的博客-CSDN博客_foc
爱转的光凌 :CH32读取MPU6050姿态数据(卡尔曼滤波法)_哔哩哔哩_bilibili
由于之前分析了v1版本的基本代码,v2版本和v1版本基本差不多,此次只考虑v2版本的RGB和he触摸按键的实现。
依照作者所提供原理图,RGB接口接在了ESP32的IO16端口。状态指示灯接在IO4端口。RGB灯组使用的WS2812通过Adafruit_NeoPixel库控制。
(发表一下自己的小看法:RGB和touch的函数文件非常不规范,引以为戒!!不要这么操作!)
在RGB.h文件中调用了Adafruit_NeoPixel库并且宏定义WS2812控制端口
- //RGB.h
-
- #include <Adafruit_NeoPixel.h>
-
- // Which pin on the Arduino is connected to the NeoPixels?
- #define LED_PIN 16
-
- // How many NeoPixels are attached to the Arduino?
- #define LED_COUNT 21
在main函数中的setup配置了RGB
- //RGB.h
- unsigned char brightness = 30;
-
- //main
-
- void setuo()
- {
- .........................
-
- strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
- //调用此函数显示,操作后必须调用显示
- strip.show(); // Turn OFF all pixels ASAP
- //设置亮度,在RGB.h中配置了
- strip.setBrightness(brightness); // Set BRIGHTNESS to about 1/5 (max = 255)
-
- colorWipe_delay(strip.Color(255, 106, 106),50); //R,G,B
- colorWipe_delay(strip.Color(0, 255, 255),50);
- colorWipe_delay(strip.Color(148, 0, 211),50);
-
-
- .........................
- }
colorWipe_delay
- //RGB.h
-
- void colorWipe_delay(uint32_t c, uint8_t wait) {
- for(uint16_t i=0; i<strip.numPixels(); i++) {
- strip.setPixelColor(i, c);
- strip.show();
- delay(wait);
- }
- }
RGB.h文件下面包含了部分RGB灯效,通过判断触摸调用改变灯效。
- //RGB.h
-
- void strip1();
- void strip2();
- void strip3();
- void rainbow1();
- void rainbow2();
- void pulse_rainbow1();
- void rgb_off();
- ....................
触摸函数相关定义
- //tourch.h
-
- const int threshold_top = 40; //触摸阈值
- const int single_count[3] = {10,10,10}; //单击时间 实际时间为20*10 = 200ms
- const int long_count[3] = {80,80,80}; //长按时间 实际时间为80*10 = 800ms
- unsigned long touch_last_time;
- int touch_count[3] = {0,0,0}; //持续触摸计数
- int touch_touched[3] = {0,0,0}; //单击,长按判断 单击值为1,长按值为2 没点击为0
- bool touch_STATE[3] = {1, 1, 1}; // 定义按键触发对象状态变量初始值为true默认开启 T2 T3 T4
-
- int rgb_flag = 1;
- int rgb_modle = 8;//有几种RGB效果就写几
触摸感应判断
- //tourch.h
-
- //在main中loop函数调用touchAttach(touchID,touchPin)
- void touchAttach(int touchID, uint8_t touchPin) {
- int touchread = touchRead(touchPin); //触摸返回函数
-
- if ( touchread <= threshold_top ) { //达到触发值的计数
- //delay(38); // 0.038秒
- touch_count[touchID]++; //持续触摸计数
- }
- //没有触摸时才进入触摸类型判断函数
- else
- {
- if ( touch_count[touchID] >= single_count[touchID] &&
- touch_count[touchID] < long_count[touchID])
- touch_touched[touchID] = 1;//持续触摸时间达到单击
- else if(touch_count[touchID] >= long_count[touchID])
- touch_touched[touchID] = 2;
- else
- touch_touched[touchID]= 0;
- touch_count[touchID] = 0; //持续触摸计数清零
- }
- }
loop函数中,通过触摸改变RGB灯效
- //main
-
- void loop()
- {
- .........................
-
- // 触摸效果以及RGB灯效
- unsigned long currentMillis = millis(); //获取开机后运行的时间长度ms
- if(currentMillis - voltage_last_time >=1000)
- {
- voltage_last_time = currentMillis;
- voltage_detection(); //有关电池电压检测加输出结果的函数!
- }
- if(currentMillis - touch_last_time >= 10) // Check for expired time
- {
- touch_last_time = currentMillis; // Run current frame
-
- /*******************************************************
- ESP32LED闪烁
- 功能:实现触摸按键按一下改变LED得状态
- 引脚:
- T0:GPIO 4
- T1:GPIO 0
- T2:GPIO 2
- T3:GPIO 15
- T4:GPIO 13
- T5:GPIO 12
- T6:GPIO 14
- T7:GPIO 27
- T8:GPIO 33
- T9:GPIO 32
- arduino 也内置有相应的语法:touchRead(Touch Pin *);
- https://img-blog.csdnimg.cn/d117f52b602e45f78ed63ca82a610b32.png
- *******************************************************/
- touchAttach(0,T2);
- touchAttach(1,T3);
- touchAttach(2,T4);
- int i;
- for(i = 0;i<3;i++)
- {
- if(touch_STATE[i]&&touch_touched[i]) //开启检测&&有按下
- {
- if(touch_touched[i] == 1)
- {
- single_event(i); //触摸单击函数
- }
- else
- long_event(i); //触摸长按函数
- }
- }
- }
-
-
- .........................
-
- }
按键模式处理函数
- //main
-
- void loop()
- {
- .........................
-
- // Update current time 更新RGB效果
-
- //就是隔一段时间运行一次
- if(currentMillis - pixelPrevious >= pixelInterval) // Check for expired time
- {
- pixelPrevious = currentMillis; // Run current frame
- switch(rgb_flag)
- {
- case 0 :
- rgb_off();
- break;
- case 1 :
- if(motor.shaft_velocity>0)
- {
- pixelInterval = 150 - motor.shaft_velocity;
- strip2();
- }
- else
- {
- pixelInterval = 150 + motor.shaft_velocity;
- strip3();
- }
- break;
- case 2 :
- pixelInterval = 100;
- strip2();
- break;
- case 3 :
- pixelInterval = 100;
- strip3();
- break;
- case 4 :
- strip1();
- break;
- case 5 :
- rainbow1();
- break;
- case 6 :
- rainbow2();
- break;
- case 7 :
- pulse_rainbow1();
- break;
- }
- }
-
- .........................
-
- }
触摸单机函数
- //main
-
-
- //触摸单击函数处理
- void single_event(int touchID)
- {
- switch(touchID){
- case 0 : //亮度减
- if(brightness<=15) //亮度
- brightness = 15;
- brightness-=15;
- EEPROM.writeUChar(28, brightness); EEPROM.commit();
- strip.setBrightness(brightness); // Set BRIGHTNESS to about 1/5 (max = 255)
- break;
- case 1 : //亮度加
- if(brightness>=240)
- brightness = 240;
- brightness+=15;
- EEPROM.writeUChar(28, brightness); EEPROM.commit();
- strip.setBrightness(brightness); // Set BRIGHTNESS to about 1/5 (max = 255)
- break;
- case 2 : //RGB开关
- if(rgb_flag)
- rgb_flag = 0;
- else
- rgb_flag = EEPROM.readUChar(32);
- break;
- }
- }
触摸长按函数
- //main
-
-
- //触摸长按函数处理
- void long_event(int touchID)
- {
- switch(touchID){
- case 0 : //长按投币 //切换RGB
- if(rgb_flag == 0)
- rgb_flag = rgb_modle;
- rgb_flag--;
- strip.setBrightness(brightness); // Set BRIGHTNESS to about 1/5 (max = 255)
- EEPROM.writeUChar(32, rgb_flag); EEPROM.commit();
- break;
- case 1 : //长按收藏 //切换RGB
- rgb_flag++;
- if(rgb_flag>=rgb_modle)
- rgb_flag = 0;
- strip.setBrightness(brightness); // Set BRIGHTNESS to about 1/5 (max = 255)
- EEPROM.writeUChar(32, rgb_flag); EEPROM.commit();
- break;
- case 2 : //长按点赞
- if(wifi_on_off)
- {
- motor.enable();
- WiFi.disconnect();
- WiFi.mode(WIFI_OFF);
- Serial.println("WIFI_OFF");
- }
- else
- {
- motor.disable();
- AutoWifiConfig();//打开wifi
- Serial.println("WIFI_ON");
- }
- wifi_on_off = !wifi_on_off;
- Motor_enable_flag = !Motor_enable_flag;
- break;
- }
- }
在setup函数中,写了brighyness、rgb_flag到EEPROM
- //main
-
- EEPROM.writeUChar(28,brightness); delay(10);EEPROM.commit();
- EEPROM.writeUChar(32,rgb_flag); delay(10);EEPROM.commit();
这一部分比较简单
-
-
-
- void voltage_detection()
- {
- #if defined(BAT_VOLTAGE_SENSE_PIN) //电池电压检测
- bat_voltage = return_voltage_value(BAT_VOLTAGE_SENSE_PIN);
- //driver.voltage_power_supply = bat_voltage;
- //Serial.println(driver.voltage_power_supply);
- if (bat_voltage < min_voltage && !battery_low)
- {
- battery_low = 1;
- Serial.print(driver.voltage_power_supply);
- Serial.println("V ");
- Serial.print(bat_voltage);
- Serial.println("V battery_low!!");
- while (battery_low)
- {
- rgb_off();
- motor.disable();
-
- bat_voltage = return_voltage_value(BAT_VOLTAGE_SENSE_PIN);
- if (bat_voltage >= (min_voltage + 0.5)) {
- Serial.print(driver.voltage_power_supply);
- Serial.println("V");
- Serial.print(bat_voltage);
- Serial.println("V battery ok");
- digitalWrite(ACTIVE_PIN, 0); //电池电压恢复则常亮,需reset重启
- //battery_low = 0;
- } else { //电池电压低闪灯
- if (millis() % 500 < 250)
- digitalWrite(ACTIVE_PIN, 0);
- else
- digitalWrite(ACTIVE_PIN, 1);
- }
- }
- }
- #endif
- }
return_voltage_value(int pin_on)
- double return_voltage_value(int pin_no)
- {
- double tmp;
- double ADCVoltage;
- double inputVoltage;
- analogSetPinAttenuation(pin_no, ADC_6db); //制定引脚输入衰减
-
- for (int i = 0; i < 20; i++)
- {
- //默认12位分辨率
- ADCVoltage = analogReadMilliVolts(pin_no) / 1000.0;
- inputVoltage = (ADCVoltage * R1_VOLTAGE) / R2_VOLTAGE;
-
- tmp = tmp + inputVoltage + ADCVoltage;
- // formula for calculating voltage in i.e. GND
- }
- inputVoltage = tmp / 20;
- if(inputVoltage!=0)
- inputVoltage = inputVoltage + 0.001;
- /*
- for (int i = 0; i < 20; i++)
- {
- tmp = tmp + analogRead(pin_no);
- }
- tmp = tmp / 20;
- ADCVoltage = ((tmp * 3.3) / 4095.0) + 0.165;
- inputVoltage = ADCVoltage / (R2_VOLTAGE / (R1_VOLTAGE + R2_VOLTAGE));
- // formula for calculating voltage in i.e. GND
- */
-
- return inputVoltage;
- }
最后、原作者代码很乱、引以为戒。
编译成功了!重装了好几个库,不知道是不是我的版本不对~
项目v1,v2的代码和实现方法有了简要的理解,嗯~ ~ ~ 对我的工作还是比较满意~硬件电路比较简单啦~ 看看作者给的原理图基本上就清晰啦!!总之,这个项目就这样吧,如果以后想继续研究SimpleFOC和Kalman的原理和代码实现的时候,再更新这个专栏吧~ ~ ~ !
加油学习~ 多看项目~ 多学原理~
一定要多看原理,不要单纯复刻,烧录谁不会
再次感谢大佬提供的开源项目!!!
最后附上大佬的B站链接:455555菌的个人空间_哔哩哔哩_Bilibili
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。