当前位置:   article > 正文

学习记录:自平衡莱洛三角形v2(RGB版本)学习记录_立创开源社区

立创开源社区


来源:

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有关

依照作者所提供原理图,RGB接口接在了ESP32的IO16端口。状态指示灯接在IO4端口。RGB灯组使用的WS2812通过Adafruit_NeoPixel库控制。

(发表一下自己的小看法:RGB和touch的函数文件非常不规范,引以为戒!!不要这么操作!)

在RGB.h文件中调用了Adafruit_NeoPixel库并且宏定义WS2812控制端口

  1. //RGB.h
  2. #include <Adafruit_NeoPixel.h>
  3. // Which pin on the Arduino is connected to the NeoPixels?
  4. #define LED_PIN 16
  5. // How many NeoPixels are attached to the Arduino?
  6. #define LED_COUNT 21

在main函数中的setup配置了RGB

  1. //RGB.h
  2. unsigned char brightness = 30;
  3. //main
  4. void setuo()
  5. {
  6. .........................
  7. strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
  8. //调用此函数显示,操作后必须调用显示
  9. strip.show(); // Turn OFF all pixels ASAP
  10. //设置亮度,在RGB.h中配置了
  11. strip.setBrightness(brightness); // Set BRIGHTNESS to about 1/5 (max = 255)
  12. colorWipe_delay(strip.Color(255, 106, 106),50); //R,G,B
  13. colorWipe_delay(strip.Color(0, 255, 255),50);
  14. colorWipe_delay(strip.Color(148, 0, 211),50);
  15. .........................
  16. }

colorWipe_delay

  1. //RGB.h
  2. void colorWipe_delay(uint32_t c, uint8_t wait) {
  3. for(uint16_t i=0; i<strip.numPixels(); i++) {
  4. strip.setPixelColor(i, c);
  5. strip.show();
  6. delay(wait);
  7. }
  8. }

RGB.h文件下面包含了部分RGB灯效,通过判断触摸调用改变灯效。

  1. //RGB.h
  2. void strip1();
  3. void strip2();
  4. void strip3();
  5. void rainbow1();
  6. void rainbow2();
  7. void pulse_rainbow1();
  8. void rgb_off();
  9. ....................

触摸函数

触摸函数相关定义

  1. //tourch.h
  2. const int threshold_top = 40; //触摸阈值
  3. const int single_count[3] = {10,10,10}; //单击时间 实际时间为20*10 = 200ms
  4. const int long_count[3] = {80,80,80}; //长按时间 实际时间为80*10 = 800ms
  5. unsigned long touch_last_time;
  6. int touch_count[3] = {0,0,0}; //持续触摸计数
  7. int touch_touched[3] = {0,0,0}; //单击,长按判断 单击值为1,长按值为2 没点击为0
  8. bool touch_STATE[3] = {1, 1, 1}; // 定义按键触发对象状态变量初始值为true默认开启 T2 T3 T4
  9. int rgb_flag = 1;
  10. int rgb_modle = 8;//有几种RGB效果就写几

触摸感应判断

  1. //tourch.h
  2. //在main中loop函数调用touchAttach(touchID,touchPin)
  3. void touchAttach(int touchID, uint8_t touchPin) {
  4. int touchread = touchRead(touchPin); //触摸返回函数
  5. if ( touchread <= threshold_top ) { //达到触发值的计数
  6. //delay(38); // 0.038秒
  7. touch_count[touchID]++; //持续触摸计数
  8. }
  9. //没有触摸时才进入触摸类型判断函数
  10. else
  11. {
  12. if ( touch_count[touchID] >= single_count[touchID] &&
  13. touch_count[touchID] < long_count[touchID])
  14. touch_touched[touchID] = 1;//持续触摸时间达到单击
  15. else if(touch_count[touchID] >= long_count[touchID])
  16. touch_touched[touchID] = 2;
  17. else
  18. touch_touched[touchID]= 0;
  19. touch_count[touchID] = 0; //持续触摸计数清零
  20. }
  21. }

loop函数中,通过触摸改变RGB灯效

  1. //main
  2. void loop()
  3. {
  4. .........................
  5. // 触摸效果以及RGB灯效
  6. unsigned long currentMillis = millis(); //获取开机后运行的时间长度ms
  7. if(currentMillis - voltage_last_time >=1000)
  8. {
  9. voltage_last_time = currentMillis;
  10. voltage_detection(); //有关电池电压检测加输出结果的函数!
  11. }
  12. if(currentMillis - touch_last_time >= 10) // Check for expired time
  13. {
  14. touch_last_time = currentMillis; // Run current frame
  15. /*******************************************************
  16. ESP32LED闪烁
  17. 功能:实现触摸按键按一下改变LED得状态
  18. 引脚:
  19. T0:GPIO 4
  20. T1:GPIO 0
  21. T2:GPIO 2
  22. T3:GPIO 15
  23. T4:GPIO 13
  24. T5:GPIO 12
  25. T6:GPIO 14
  26. T7:GPIO 27
  27. T8:GPIO 33
  28. T9:GPIO 32
  29. arduino 也内置有相应的语法:touchRead(Touch Pin *);
  30. https://img-blog.csdnimg.cn/d117f52b602e45f78ed63ca82a610b32.png
  31. *******************************************************/
  32. touchAttach(0,T2);
  33. touchAttach(1,T3);
  34. touchAttach(2,T4);
  35. int i;
  36. for(i = 0;i<3;i++)
  37. {
  38. if(touch_STATE[i]&&touch_touched[i]) //开启检测&&有按下
  39. {
  40. if(touch_touched[i] == 1)
  41. {
  42. single_event(i); //触摸单击函数
  43. }
  44. else
  45. long_event(i); //触摸长按函数
  46. }
  47. }
  48. }
  49. .........................
  50. }

按键模式处理函数

  1. //main
  2. void loop()
  3. {
  4. .........................
  5. // Update current time 更新RGB效果
  6. //就是隔一段时间运行一次
  7. if(currentMillis - pixelPrevious >= pixelInterval) // Check for expired time
  8. {
  9. pixelPrevious = currentMillis; // Run current frame
  10. switch(rgb_flag)
  11. {
  12. case 0 :
  13. rgb_off();
  14. break;
  15. case 1 :
  16. if(motor.shaft_velocity>0)
  17. {
  18. pixelInterval = 150 - motor.shaft_velocity;
  19. strip2();
  20. }
  21. else
  22. {
  23. pixelInterval = 150 + motor.shaft_velocity;
  24. strip3();
  25. }
  26. break;
  27. case 2 :
  28. pixelInterval = 100;
  29. strip2();
  30. break;
  31. case 3 :
  32. pixelInterval = 100;
  33. strip3();
  34. break;
  35. case 4 :
  36. strip1();
  37. break;
  38. case 5 :
  39. rainbow1();
  40. break;
  41. case 6 :
  42. rainbow2();
  43. break;
  44. case 7 :
  45. pulse_rainbow1();
  46. break;
  47. }
  48. }
  49. .........................
  50. }

触摸单机函数

  1. //main
  2. //触摸单击函数处理
  3. void single_event(int touchID)
  4. {
  5. switch(touchID){
  6. case 0 : //亮度减
  7. if(brightness<=15) //亮度
  8. brightness = 15;
  9. brightness-=15;
  10. EEPROM.writeUChar(28, brightness); EEPROM.commit();
  11. strip.setBrightness(brightness); // Set BRIGHTNESS to about 1/5 (max = 255)
  12. break;
  13. case 1 : //亮度加
  14. if(brightness>=240)
  15. brightness = 240;
  16. brightness+=15;
  17. EEPROM.writeUChar(28, brightness); EEPROM.commit();
  18. strip.setBrightness(brightness); // Set BRIGHTNESS to about 1/5 (max = 255)
  19. break;
  20. case 2 : //RGB开关
  21. if(rgb_flag)
  22. rgb_flag = 0;
  23. else
  24. rgb_flag = EEPROM.readUChar(32);
  25. break;
  26. }
  27. }

触摸长按函数

  1. //main
  2. //触摸长按函数处理
  3. void long_event(int touchID)
  4. {
  5. switch(touchID){
  6. case 0 : //长按投币 //切换RGB
  7. if(rgb_flag == 0)
  8. rgb_flag = rgb_modle;
  9. rgb_flag--;
  10. strip.setBrightness(brightness); // Set BRIGHTNESS to about 1/5 (max = 255)
  11. EEPROM.writeUChar(32, rgb_flag); EEPROM.commit();
  12. break;
  13. case 1 : //长按收藏 //切换RGB
  14. rgb_flag++;
  15. if(rgb_flag>=rgb_modle)
  16. rgb_flag = 0;
  17. strip.setBrightness(brightness); // Set BRIGHTNESS to about 1/5 (max = 255)
  18. EEPROM.writeUChar(32, rgb_flag); EEPROM.commit();
  19. break;
  20. case 2 : //长按点赞
  21. if(wifi_on_off)
  22. {
  23. motor.enable();
  24. WiFi.disconnect();
  25. WiFi.mode(WIFI_OFF);
  26. Serial.println("WIFI_OFF");
  27. }
  28. else
  29. {
  30. motor.disable();
  31. AutoWifiConfig();//打开wifi
  32. Serial.println("WIFI_ON");
  33. }
  34. wifi_on_off = !wifi_on_off;
  35. Motor_enable_flag = !Motor_enable_flag;
  36. break;
  37. }
  38. }

在setup函数中,写了brighyness、rgb_flag到EEPROM

  1. //main
  2. EEPROM.writeUChar(28,brightness); delay(10);EEPROM.commit();
  3. EEPROM.writeUChar(32,rgb_flag); delay(10);EEPROM.commit();

电池检测的函数

这一部分比较简单

  1. void voltage_detection()
  2. {
  3. #if defined(BAT_VOLTAGE_SENSE_PIN) //电池电压检测
  4. bat_voltage = return_voltage_value(BAT_VOLTAGE_SENSE_PIN);
  5. //driver.voltage_power_supply = bat_voltage;
  6. //Serial.println(driver.voltage_power_supply);
  7. if (bat_voltage < min_voltage && !battery_low)
  8. {
  9. battery_low = 1;
  10. Serial.print(driver.voltage_power_supply);
  11. Serial.println("V ");
  12. Serial.print(bat_voltage);
  13. Serial.println("V battery_low!!");
  14. while (battery_low)
  15. {
  16. rgb_off();
  17. motor.disable();
  18. bat_voltage = return_voltage_value(BAT_VOLTAGE_SENSE_PIN);
  19. if (bat_voltage >= (min_voltage + 0.5)) {
  20. Serial.print(driver.voltage_power_supply);
  21. Serial.println("V");
  22. Serial.print(bat_voltage);
  23. Serial.println("V battery ok");
  24. digitalWrite(ACTIVE_PIN, 0); //电池电压恢复则常亮,需reset重启
  25. //battery_low = 0;
  26. } else { //电池电压低闪灯
  27. if (millis() % 500 < 250)
  28. digitalWrite(ACTIVE_PIN, 0);
  29. else
  30. digitalWrite(ACTIVE_PIN, 1);
  31. }
  32. }
  33. }
  34. #endif
  35. }

return_voltage_value(int pin_on)

  1. double return_voltage_value(int pin_no)
  2. {
  3. double tmp;
  4. double ADCVoltage;
  5. double inputVoltage;
  6. analogSetPinAttenuation(pin_no, ADC_6db); //制定引脚输入衰减
  7. for (int i = 0; i < 20; i++)
  8. {
  9. //默认12位分辨率
  10. ADCVoltage = analogReadMilliVolts(pin_no) / 1000.0;
  11. inputVoltage = (ADCVoltage * R1_VOLTAGE) / R2_VOLTAGE;
  12. tmp = tmp + inputVoltage + ADCVoltage;
  13. // formula for calculating voltage in i.e. GND
  14. }
  15. inputVoltage = tmp / 20;
  16. if(inputVoltage!=0)
  17. inputVoltage = inputVoltage + 0.001;
  18. /*
  19. for (int i = 0; i < 20; i++)
  20. {
  21. tmp = tmp + analogRead(pin_no);
  22. }
  23. tmp = tmp / 20;
  24. ADCVoltage = ((tmp * 3.3) / 4095.0) + 0.165;
  25. inputVoltage = ADCVoltage / (R2_VOLTAGE / (R1_VOLTAGE + R2_VOLTAGE));
  26. // formula for calculating voltage in i.e. GND
  27. */
  28. return inputVoltage;
  29. }

有关OTA的问题没有探讨

最后、原作者代码很乱、引以为戒。

编译成功了!重装了好几个库,不知道是不是我的版本不对~

项目v1,v2的代码和实现方法有了简要的理解,嗯~ ~ ~ 对我的工作还是比较满意~硬件电路比较简单啦~ 看看作者给的原理图基本上就清晰啦!!总之,这个项目就这样吧,如果以后想继续研究SimpleFOC和Kalman的原理和代码实现的时候,再更新这个专栏吧~ ~ ~  !

加油学习~ 多看项目~ 多学原理~

一定要多看原理,不要单纯复刻,烧录谁不会

再次感谢大佬提供的开源项目!!!

最后附上大佬的B站链接:455555菌的个人空间_哔哩哔哩_Bilibili

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/754328
推荐阅读
相关标签
  

闽ICP备14008679号