32浏览
查看: 32|回复: 2

[项目] 【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...

[复制链接]


B-robot EVO 2:
极快、稳定、可定制的自平衡机器人。检查机器人的运行情况!

零件清单
1 x PCB ESP32 平衡机器人防护罩 (https://www.pcbway.com/project/s ... g_Robot_Shield.html
1 个 ESP32 DEVKIT V1 板
2 x 步进电机驱动器 A4988
1 x 3 轴传感器和陀螺仪传感器MPU6050
2 x 步进电机 Nema17
1 x 伺服电机 MG90S
1 x LED 3 毫米
2 x LED 3mm 白色超亮
1 x 有源 BUzzer
2 x V 稳压器 5V AMS1117 (SMD)
1 x 电阻器 1K 欧姆
1 x 电容器 0.1uF
1 x 电容器 100uF/16V
2 x 电容器 220uF/16V
1 x 翘板开关直径 20 毫米
2 x 锂离子电池 18650 3,7V
1 x 电池座 2x 18650
1 x 微型 USB 数据线
1 x OTG 适配器
1 x 端子螺钉 2 针 5mm
2 x 母头 15 针
5 x 母头 8 针
2 x 母头 4 针
1 x 公头 2 针
1 x 公头接头 3 针
1 x 跳线帽
1 x 固定螺钉 5mm
1 x 套装 M3 固定螺钉 10mm
2 x O 形圈 3mm 内径 82mm
1 x 套装 3D 打印零件

B-robot EVO 2 是一款开源、基于 Arduino 的自平衡机器人,具有许多功能(看看下面的描述)现在带有战斗臂和附加组件来与另一个机器人战斗(或在您跌倒时站起来)。

使用智能手机或平板电脑 (WIFI) 进行远程控制。
该机器人是 B-robot ORIGINAL 的自然演变,并使用创建所需的相同电子设备和电机:

空气曲棍球机器人
Sphere-O-Bot (蛋机器人 MOD)
iBoard机器人
PyBot 机械臂
相机滑块机器人
厌倦了一台机器人?创建另一个仅打印 3D 零件!

B-robot EVO 2 是一款基于 Arduino 的机器人。开放的软件和硬件创建。您可以轻松修改其行为,在 Arduino CODE 中或通过 CONTROL APP 实时更改加速度/速度/稳定性参数。

新功能:
通过 GOOGLE PLAY 上的免费应用程序使用智能手机/平板电脑控制它(适用于 Android 或适用于 iOS 设备的 Apple 商店
谷歌块可控!
非常适合在学习机器人技术时获得乐趣(看看机器人挑战!
现在可以使用普通 AA 电池(或 3 芯锂聚合物电池)
二 SERVO 输出(一个用于 ARM)
更易于打印,使用更少的塑料
PRO MODE 可以从您的智能手机/平板电脑激活(提高敏捷性和速度)
增加 WIFI范围(最远40米)
新功能:使用 Thingiverse 定制器创建您自己的保险杠!
新增功能: 用于丁腈 O 形圈的新车轮型号 [V11]
新增功能: 全新 100% 正面和背面 3D 打印保险杠“BUMPER 3D 打印 V1”
您需要打印的内容:
2x 轮子
2x 集线器
手臂
2x 侧面板
顶层货架
电机架
电子货架
2x 保险杠(要创建您的定制保险杠,请点击此链接)

--------------------------------------------------

附加组件:
可选:2x 保险杠(顶部前保险杠)
自选:战斗手臂:雷神之锤
自选:战斗武器:战斧
自选:GoPro 相机支持
自选:汽水罐顶部搁板支撑
自选:O 形圈轮 (x2)


【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图2

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图1

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图3

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图4

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图5

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图6

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图7

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图8

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图9

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图10

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图11

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图13

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图12

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图14

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图15

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图16


驴友花雕  中级技神
 楼主|

发表于 昨天 11:00

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...

项目代码

  1. /*
  2. * esp32_wifi_balancing_robot.ino
  3. *
  4. *  Created on: 23.02.2021
  5. *      Author: anonymous
  6. */
  7. #include <Wire.h>
  8. #include <WiFi.h>
  9. #include <ArduinoOTA.h>
  10. #include <Arduino.h>
  11. #include <AsyncTCP.h>
  12. #include <ESPAsyncWebServer.h>
  13. #include "Control.h"
  14. #include "MPU6050.h"
  15. #include "Motors.h"
  16. #include "defines.h"
  17. #include "globals.h"
  18. #include <stdio.h>
  19. #include "esp_types.h"
  20. #include "soc/timer_group_struct.h"
  21. #include "driver/periph_ctrl.h"
  22. #include "driver/timer.h"
  23. #include "driver/ledc.h"
  24. #include "esp32-hal-ledc.h"
  25. const char* PARAM_FADER1 = "fader1";
  26. const char* PARAM_FADER2 = "fader2";
  27. const char* PARAM_PUSH1 = "push1";
  28. const char* PARAM_PUSH2 = "push2";
  29. const char* PARAM_PUSH3 = "push3";
  30. const char* PARAM_PUSH4 = "push4";
  31. const char* PARAM_TOGGLE1 = "toggle1";
  32. const char* PARAM_FADER3 = "fader3";
  33. const char* PARAM_FADER4 = "fader4";
  34. const char* PARAM_FADER5 = "fader5";
  35. const char* PARAM_FADER6 = "fader6";
  36. /* Wifi Crdentials */
  37. String sta_ssid = "$your_ssid_maximum_32_characters";     // set Wifi network you want to connect to
  38. String sta_password = "$your_pswd_maximum_32_characters";        // set password for Wifi network
  39. unsigned long previousMillis = 0;
  40. AsyncWebServer server(80);
  41. void initMPU6050() {
  42.   MPU6050_setup();
  43.   delay(500);
  44.   MPU6050_calibrate();
  45. }
  46. void initTimers();
  47. void notFound(AsyncWebServerRequest *request) {
  48.   request->send(404, "text/plain", "Not found");
  49. }
  50. void setup() {
  51.   Serial.begin(115200);         // set up seriamonitor at 115200 bps
  52.   Serial.setDebugOutput(true);
  53.   Serial.println();
  54.   Serial.println("*ESP32 Camera Balancing Robot*");
  55.   Serial.println("--------------------------------------------------------");
  56.   pinMode(PIN_ENABLE_MOTORS, OUTPUT);
  57.   digitalWrite(PIN_ENABLE_MOTORS, HIGH);
  58.   
  59.   pinMode(PIN_MOTOR1_DIR, OUTPUT);
  60.   pinMode(PIN_MOTOR1_STEP, OUTPUT);
  61.   pinMode(PIN_MOTOR2_DIR, OUTPUT);
  62.   pinMode(PIN_MOTOR2_STEP, OUTPUT);
  63.   pinMode(PIN_SERVO, OUTPUT);
  64.   pinMode(PIN_LED, OUTPUT);
  65.   digitalWrite(PIN_LED, LOW);
  66.   pinMode(PIN_WIFI_LED, OUTPUT);
  67.   digitalWrite(PIN_WIFI_LED, LOW);
  68.   
  69.   pinMode(PIN_BUZZER, OUTPUT);
  70.   digitalWrite(PIN_BUZZER, LOW);
  71.   ledcSetup(6, 50, 16); // channel 6, 50 Hz, 16-bit width
  72.   ledcAttachPin(PIN_SERVO, 6);   // GPIO 22 assigned to channel 1
  73.   delay(50);
  74.   ledcWrite(6, SERVO_AUX_NEUTRO);
  75.   
  76.   Wire.begin();
  77.   initMPU6050();
  78.   // Set NodeMCU Wifi hostname based on chip mac address
  79.   char chip_id[15];
  80.   snprintf(chip_id, 15, "%04X", (uint16_t)(ESP.getEfuseMac()>>32));
  81.   String hostname = "esp32brobot-" + String(chip_id);
  82.   Serial.println();
  83.   Serial.println("Hostname: "+hostname);
  84.   // first, set NodeMCU as STA mode to connect with a Wifi network
  85.   WiFi.mode(WIFI_STA);
  86.   WiFi.begin(sta_ssid.c_str(), sta_password.c_str());
  87.   Serial.println("");
  88.   Serial.print("Connecting to: ");
  89.   Serial.println(sta_ssid);
  90.   Serial.print("Password: ");
  91.   Serial.println(sta_password);
  92.   // try to connect with Wifi network about 8 seconds
  93.   unsigned long currentMillis = millis();
  94.   previousMillis = currentMillis;
  95.   while (WiFi.status() != WL_CONNECTED && currentMillis - previousMillis <= 8000) {
  96.     delay(500);
  97.     Serial.print(".");
  98.     currentMillis = millis();
  99.   }
  100.   // if failed to connect with Wifi network set NodeMCU as AP mode
  101.   IPAddress myIP;
  102.   if (WiFi.status() == WL_CONNECTED) {
  103.     Serial.println("");
  104.     Serial.println("*WiFi-STA-Mode*");
  105.     Serial.print("IP: ");
  106.     myIP=WiFi.localIP();
  107.     Serial.println(myIP);
  108.     digitalWrite(PIN_WIFI_LED, HIGH);    // Wifi LED on when connected to Wifi as STA mode
  109.     delay(2000);
  110.   } else {
  111.     WiFi.mode(WIFI_AP);
  112.     WiFi.softAP(hostname.c_str());
  113.     myIP = WiFi.softAPIP();
  114.     Serial.println("");
  115.     Serial.println("WiFi failed connected to " + sta_ssid);
  116.     Serial.println("");
  117.     Serial.println("*WiFi-AP-Mode*");
  118.     Serial.print("AP IP address: ");
  119.     Serial.println(myIP);
  120.     digitalWrite(PIN_WIFI_LED, LOW);   // Wifi LED off when status as AP mode
  121.     delay(2000);
  122.   }
  123.   // Send a GET request to <ESP_IP>/?fader=<inputValue>
  124.     server.on("/", HTTP_GET, [] (AsyncWebServerRequest *request) {
  125.     String inputValue;
  126.     String inputMessage;
  127.     OSCnewMessage = 1;
  128.    
  129.     // Get value for Forward/Backward
  130.     if (request->hasParam(PARAM_FADER1)) {
  131.       OSCpage = 1;
  132.       inputValue = request->getParam(PARAM_FADER1)->value();
  133.       inputMessage = PARAM_FADER1;
  134.       OSCfader[0] = inputValue.toFloat();
  135.     }
  136.     // Get value for Right/Left
  137.     else if (request->hasParam(PARAM_FADER2)) {
  138.       OSCpage = 1;
  139.       inputValue = request->getParam(PARAM_FADER2)->value();
  140.       inputMessage = PARAM_FADER2;
  141.       OSCfader[1] = inputValue.toFloat();
  142.     }
  143.     // Get value for Servo0
  144.     else if (request->hasParam(PARAM_PUSH1)) {
  145.       OSCpage = 1;
  146.       inputValue = request->getParam(PARAM_PUSH1)->value();
  147.       inputMessage = PARAM_PUSH1;
  148.       if(inputValue.equals("1")) OSCpush[0]=1;
  149.       else OSCpush[0]=0;
  150.     }
  151.     // Get value for Setting
  152.     else if (request->hasParam(PARAM_PUSH2)) {
  153.       OSCpage = 2;
  154.       inputValue = request->getParam(PARAM_PUSH2)->value();
  155.       inputMessage = PARAM_PUSH2;
  156.       if(inputValue.equals("1")) OSCpush[2]=1;
  157.       else OSCpush[2]=0;
  158.     }
  159.     // Get value for Buzzer
  160.     else if (request->hasParam(PARAM_PUSH3)) {
  161.       inputValue = request->getParam(PARAM_PUSH3)->value();
  162.       inputMessage = PARAM_PUSH3;
  163.       if(inputValue.equals("1")) {
  164.         digitalWrite(PIN_BUZZER, HIGH);
  165.         delay(150);
  166.         digitalWrite(PIN_BUZZER, LOW);
  167.         delay(80);
  168.         digitalWrite(PIN_BUZZER, HIGH);
  169.         delay(150);
  170.         digitalWrite(PIN_BUZZER, LOW);
  171.         delay(80);
  172.       }
  173.     }
  174.     // Get value for Led
  175.     else if (request->hasParam(PARAM_PUSH4)) {
  176.       inputValue = request->getParam(PARAM_PUSH4)->value();
  177.       inputMessage = PARAM_PUSH4;
  178.       if(inputValue.equals("1")) digitalWrite(PIN_LED, HIGH);
  179.       else digitalWrite(PIN_LED, LOW);
  180.     }
  181.     // Get value for mode PRO
  182.     else if (request->hasParam(PARAM_TOGGLE1)) {
  183.       OSCpage = 1;
  184.       inputValue = request->getParam(PARAM_TOGGLE1)->value();
  185.       inputMessage = PARAM_TOGGLE1;
  186.       if(inputValue.equals("1")) OSCtoggle[0]=1;
  187.       else OSCtoggle[0]=0;
  188.     }
  189.     // Get value for P-Stability
  190.     else if (request->hasParam(PARAM_FADER3)) {
  191.       OSCpage = 2;
  192.       inputValue = request->getParam(PARAM_FADER3)->value();
  193.       inputMessage = PARAM_FADER3;
  194.       OSCfader[0] = inputValue.toFloat();
  195.     }
  196.     // Get value for D-Stability
  197.     else if (request->hasParam(PARAM_FADER4)) {
  198.       OSCpage = 2;
  199.       inputValue = request->getParam(PARAM_FADER4)->value();
  200.       inputMessage = PARAM_FADER4;
  201.       OSCfader[0] = inputValue.toFloat();
  202.     }
  203.     // Get value for P-Speed
  204.     else if (request->hasParam(PARAM_FADER5)) {
  205.       OSCpage = 2;
  206.       inputValue = request->getParam(PARAM_FADER5)->value();
  207.       inputMessage = PARAM_FADER5;
  208.       OSCfader[0] = inputValue.toFloat();
  209.     }
  210.     // Get value for I-Speed
  211.     else if (request->hasParam(PARAM_FADER6)) {
  212.       OSCpage = 2;
  213.       inputValue = request->getParam(PARAM_FADER6)->value();
  214.       inputMessage = PARAM_FADER6;
  215.       OSCfader[0] = inputValue.toFloat();
  216.     }
  217.     else {
  218.       inputValue = "No message sent";
  219.     }
  220.     Serial.println(inputMessage+'='+inputValue);
  221.     request->send(200, "text/text", "");
  222.   });
  223.   server.onNotFound (notFound);    // when a client requests an unknown URI (i.e. something other than "/"), call function "handleNotFound"
  224.   server.begin();                           // actually start the server
  225.   initTimers();
  226.   // default neutral values
  227.   OSCfader[0] = 0.5;
  228.   OSCfader[1] = 0.5;
  229.   OSCfader[2] = 0.5;
  230.   OSCfader[3] = 0.5;
  231.   digitalWrite(PIN_ENABLE_MOTORS, LOW);
  232.   for (uint8_t k = 0; k < 5; k++) {
  233.     setMotorSpeedM1(5);
  234.     setMotorSpeedM2(5);
  235.     ledcWrite(6, SERVO_AUX_NEUTRO + 250);
  236.     delay(200);
  237.     setMotorSpeedM1(-5);
  238.     setMotorSpeedM2(-5);
  239.     ledcWrite(6, SERVO_AUX_NEUTRO - 250);
  240.     delay(200);
  241.   }
  242.   ledcWrite(6, SERVO_AUX_NEUTRO);
  243.   ArduinoOTA.begin();   // enable to receive update/upload firmware via Wifi OTA
  244. }
  245. void loop() {
  246.   ArduinoOTA.handle();
  247.   if (OSCnewMessage) {
  248.     OSCnewMessage = 0;
  249.     processOSCMsg();
  250.   }
  251.   timer_value = micros();
  252.   if (MPU6050_newData()) {
  253.    
  254.     MPU6050_read_3axis();
  255.    
  256.     dt = (timer_value - timer_old) * 0.000001; // dt in seconds
  257.     //Serial.println(timer_value - timer_old);
  258.     timer_old = timer_value;
  259.     angle_adjusted_Old = angle_adjusted;
  260.     // Get new orientation angle from IMU (MPU6050)
  261.     float MPU_sensor_angle = MPU6050_getAngle(dt);
  262.     angle_adjusted = MPU_sensor_angle + angle_offset;
  263.     if ((MPU_sensor_angle > -15) && (MPU_sensor_angle < 15))
  264.       angle_adjusted_filtered = angle_adjusted_filtered * 0.99 + MPU_sensor_angle * 0.01;
  265.     // We calculate the estimated robot speed:
  266.     // Estimated_Speed = angular_velocity_of_stepper_motors(combined) - angular_velocity_of_robot(angle measured by IMU)
  267.     actual_robot_speed = (speed_M1 + speed_M2) / 2; // Positive: forward
  268.     int16_t angular_velocity = (angle_adjusted - angle_adjusted_Old) * 25.0; // 25 is an empirical extracted factor to adjust for real units
  269.     int16_t estimated_speed = -actual_robot_speed + angular_velocity;
  270.     estimated_speed_filtered = estimated_speed_filtered * 0.9 + (float) estimated_speed * 0.1; // low pass filter on estimated speed
  271.     if (positionControlMode) {
  272.       // POSITION CONTROL. INPUT: Target steps for each motor. Output: motors speed
  273.       motor1_control = positionPDControl(steps1, target_steps1, Kp_position, Kd_position, speed_M1);
  274.       motor2_control = positionPDControl(steps2, target_steps2, Kp_position, Kd_position, speed_M2);
  275.       // Convert from motor position control to throttle / steering commands
  276.       throttle = (motor1_control + motor2_control) / 2;
  277.       throttle = constrain(throttle, -190, 190);
  278.       steering = motor2_control - motor1_control;
  279.       steering = constrain(steering, -50, 50);
  280.     }
  281.     // ROBOT SPEED CONTROL: This is a PI controller.
  282.     //    input:user throttle(robot speed), variable: estimated robot speed, output: target robot angle to get the desired speed
  283.     target_angle = speedPIControl(dt, estimated_speed_filtered, throttle, Kp_thr, Ki_thr);
  284.     target_angle = constrain(target_angle, -max_target_angle, max_target_angle); // limited output
  285.     // Stability control (100Hz loop): This is a PD controller.
  286.     //    input: robot target angle(from SPEED CONTROL), variable: robot angle, output: Motor speed
  287.     //    We integrate the output (sumatory), so the output is really the motor acceleration, not motor speed.
  288.     control_output += stabilityPDControl(dt, angle_adjusted, target_angle, Kp, Kd);
  289.     control_output = constrain(control_output, -MAX_CONTROL_OUTPUT,  MAX_CONTROL_OUTPUT); // Limit max output from control
  290.     // The steering part from the user is injected directly to the output
  291.     motor1 = control_output + steering;
  292.     motor2 = control_output - steering;
  293.     // Limit max speed (control output)
  294.     motor1 = constrain(motor1, -MAX_CONTROL_OUTPUT, MAX_CONTROL_OUTPUT);
  295.     motor2 = constrain(motor2, -MAX_CONTROL_OUTPUT, MAX_CONTROL_OUTPUT);
  296.     int angle_ready;
  297.     if (OSCpush[0])     // If we press the SERVO button we start to move
  298.       angle_ready = 82;
  299.     else
  300.       angle_ready = 74;  // Default angle
  301.     if ((angle_adjusted < angle_ready) && (angle_adjusted > -angle_ready)) // Is robot ready (upright?)
  302.         {
  303.       // NORMAL MODE
  304.       digitalWrite(PIN_ENABLE_MOTORS, LOW);  // Motors enable
  305.       // NOW we send the commands to the motors
  306.       setMotorSpeedM1(motor1);
  307.       setMotorSpeedM2(motor2);
  308.     } else   // Robot not ready (flat), angle > angle_ready => ROBOT OFF
  309.     {
  310.       digitalWrite(PIN_ENABLE_MOTORS, HIGH);  // Disable motors
  311.       setMotorSpeedM1(0);
  312.       setMotorSpeedM2(0);
  313.       PID_errorSum = 0;  // Reset PID I term
  314.       Kp = KP_RAISEUP;   // CONTROL GAINS FOR RAISE UP
  315.       Kd = KD_RAISEUP;
  316.       Kp_thr = KP_THROTTLE_RAISEUP;
  317.       Ki_thr = KI_THROTTLE_RAISEUP;
  318.       // RESET steps
  319.       steps1 = 0;
  320.       steps2 = 0;
  321.       positionControlMode = false;
  322.       OSCmove_mode = false;
  323.       throttle = 0;
  324.       steering = 0;
  325.     }
  326.    
  327.     // Push1 Move servo arm
  328.     if (OSCpush[0]) {
  329.       if (angle_adjusted > -40)
  330.         ledcWrite(6, SERVO_MAX_PULSEWIDTH);
  331.       else
  332.         ledcWrite(6, SERVO_MIN_PULSEWIDTH);
  333.     } else
  334.       ledcWrite(6, SERVO_AUX_NEUTRO);
  335.     // Servo2
  336.     //ledcWrite(6, SERVO2_NEUTRO + (OSCfader[2] - 0.5) * SERVO2_RANGE);
  337.     // Normal condition?
  338.     if ((angle_adjusted < 56) && (angle_adjusted > -56)) {
  339.       Kp = Kp_user;            // Default user control gains
  340.       Kd = Kd_user;
  341.       Kp_thr = Kp_thr_user;
  342.       Ki_thr = Ki_thr_user;
  343.     } else // We are in the raise up procedure => we use special control parameters
  344.     {
  345.       Kp = KP_RAISEUP;         // CONTROL GAINS FOR RAISE UP
  346.       Kd = KD_RAISEUP;
  347.       Kp_thr = KP_THROTTLE_RAISEUP;
  348.       Ki_thr = KI_THROTTLE_RAISEUP;
  349.     }
  350.   } // End of new IMU data
  351. }
  352. void processOSCMsg() {
  353.   if (OSCpage == 1) {
  354.     if (modifing_control_parameters)  // We came from the settings screen
  355.     {
  356.       OSCfader[0] = 0.5; // default neutral values
  357.       OSCfader[1] = 0.5; // default neutral values
  358.       OSCtoggle[0] = 0;  // Normal mode
  359.       mode = 0;
  360.       modifing_control_parameters = false;
  361.     }
  362.     if (OSCmove_mode) {
  363.       Serial.print("M ");
  364.       Serial.print(OSCmove_speed);
  365.       Serial.print(" ");
  366.       Serial.print(OSCmove_steps1);
  367.       Serial.print(",");
  368.       Serial.println(OSCmove_steps2);
  369.       positionControlMode = true;
  370.       OSCmove_mode = false;
  371.       target_steps1 = steps1 + OSCmove_steps1;
  372.       target_steps2 = steps2 + OSCmove_steps2;
  373.     } else {
  374.       positionControlMode = false;
  375.       throttle = (OSCfader[0] - 0.5) * max_throttle;
  376.       // We add some exponential on steering to smooth the center band
  377.       steering = OSCfader[1] - 0.5;
  378.       if (steering > 0)
  379.         steering = (steering * steering + 0.5 * steering) * max_steering;
  380.       else
  381.         steering = (-steering * steering + 0.5 * steering) * max_steering;
  382.     }
  383.     if ((mode == 0) && (OSCtoggle[0])) {
  384.       // Change to PRO mode
  385.       max_throttle = MAX_THROTTLE_PRO;
  386.       max_steering = MAX_STEERING_PRO;
  387.       max_target_angle = MAX_TARGET_ANGLE_PRO;
  388.       mode = 1;
  389.     }
  390.     if ((mode == 1) && (OSCtoggle[0] == 0)) {
  391.       // Change to NORMAL mode
  392.       max_throttle = MAX_THROTTLE;
  393.       max_steering = MAX_STEERING;
  394.       max_target_angle = MAX_TARGET_ANGLE;
  395.       mode = 0;
  396.     }
  397.   } else if (OSCpage == 2) { // OSC page 2
  398.     if (!modifing_control_parameters) {
  399.       for (uint8_t i = 0; i < 4; i++)
  400.         OSCfader[i] = 0.5;
  401.       OSCtoggle[0] = 0;
  402.       modifing_control_parameters = true;
  403.       //OSC_MsgSend("$P2", 4);
  404.     }
  405.     // User could adjust KP, KD, KP_THROTTLE and KI_THROTTLE (fadder3,4,5,6)
  406.     // Now we need to adjust all the parameters all the times because we dont know what parameter has been moved
  407.     Kp_user = KP * 2 * OSCfader[0];
  408.     Kd_user = KD * 2 * OSCfader[1];
  409.     Kp_thr_user = KP_THROTTLE * 2 * OSCfader[2];
  410.     Ki_thr_user = KI_THROTTLE * 2 * OSCfader[3];
  411.     // Send a special telemetry message with the new parameters
  412.     char auxS[50];
  413.     sprintf(auxS, "$tP,%d,%d,%d,%d", int(Kp_user * 1000), int(Kd_user * 1000), int(Kp_thr_user * 1000), int(Ki_thr_user * 1000));
  414.     //OSC_MsgSend(auxS, 50);
  415.     // Calibration mode??
  416.     if (OSCpush[2] == 1) {
  417.       Serial.print("Calibration MODE ");
  418.       angle_offset = angle_adjusted_filtered;
  419.       Serial.println(angle_offset);
  420.     }
  421.     // Kill robot => Sleep
  422.     while (OSCtoggle[0] == 1) {
  423.       //Reset external parameters
  424.       PID_errorSum = 0;
  425.       timer_old = millis();
  426.       setMotorSpeedM1(0);
  427.       setMotorSpeedM2(0);
  428.       digitalWrite(PIN_ENABLE_MOTORS, HIGH);  // Disable motors
  429.     }
  430.   }
  431. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 昨天 11:05

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32 Arduino 编程
项目链接:https://www.instructables.com/DI ... bot-B-Robot-ESP32-/
项目作者:bluino_electronics
参考资料:https://blogdaichan.hatenablog.com/entry/%3Fp%3D7129

项目视频:https://www.youtube.com/watch?v=tZynIj1StpM
项目代码:https://github.com/bluino/esp32_wifi_balancing_robot
3D打印文件:https://www.thingiverse.com/thing:2306541
PCB项目链接:https://www.pcbway.com/project/s ... g_Robot_Shield.html
Android 应用程序:https://play.google.com/store/ap ... 2wifibalancingrobot

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图2

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图1

【Arduino 动手做】DIY ESP32 Wifi 自平衡机器人 - B-Robot ESP32...图3

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail