2024-9-19 16:36:25 只看该作者
1039浏览
查看: 1039|回复: 0
打印 上一主题 下一主题

[ESP8266/ESP32] 用ESP12E做一个3D打印的6轮摇臂火星探测车

[复制链接]
本帖最后由 RRoy 于 2024-9-19 16:36 编辑

火星探测器作为一种遥控机器人,可以在不平坦的地形上运行。

你有没有想过火星车是如何在火星崎岖的地形上航行的?

秘密武器是巧妙的摇臂转向架(rocker-bogie)悬架系统。

用ESP12E做一个3D打印的6轮摇臂火星探测车图1

摇臂转向架悬架系统是一种特殊的车轮悬挂装置,最主要用于火星探测车等需要在复杂地形行驶的车辆上。

它的主要特点有:
  • 结构简单:没有使用弹簧,而是通过特殊的机械结构来实现悬挂功能。
  • 六轮设计:通常有六个车轮,分为左右两组。
  • 摇臂(Rocker):每侧有一个大的摇臂连接车身和车轮。
  • 转向架(Bogie):每个摇臂末端连接一个小的转向架,转向架两端各有一个车轮。
  • 灵活性强:这种设计让车辆能够轻松越过高度达到车轮直径两倍的障碍物。
  • 稳定性好:即使在崎岖不平的地形上,也能保持车身相对平稳。
  • 适应性强:六个车轮可以独立运动,使车辆能够适应各种复杂地形。

简单来说,这种悬架系统就像是给车子装上了六条灵活的"腿",让它能够像昆虫一样轻松地爬过各种障碍物,非常适合在火星这样地形复杂的环境中使用。

今天就和大家分享一辆3D打印的6轮摇臂转向架模型火星车。

用ESP12E做一个3D打印的6轮摇臂火星探测车图2

用ESP12E做一个3D打印的6轮摇臂火星探测车图3

用ESP12E做一个3D打印的6轮摇臂火星探测车图4

用ESP12E做一个3D打印的6轮摇臂火星探测车图5

用ESP12E做一个3D打印的6轮摇臂火星探测车图6

这个简单模型的主体部分是3D打印的,火星车使用 ESP12E 作为大脑,L293D 作为电机控制器。遥控器使用相同的 ESP12E 微控制器。

除了可以用专用的遥控器控制,也可以使用手机应用程序控制。通过火星车上的传感器,可以在遥控器的OLED屏幕上看到实时的数据。流动站和遥控器之间的通信使用ESP-NOW协议。






这个项目非常适合对机器人感兴趣的小伙伴,下面是具体的制作过程。

ESP-NOW通讯
ESP-NOW 是由乐鑫开发的通信协议,专为 ESP8266 和 ESP32 设备之间的低功耗点对点通信而设计,无需传统的 Wi-Fi 网络或互联网连接即可实现高效的数据交换。

ESP-NOW 提供消息加密等基本安全功能,以保护传输的数据免受未经授权的访问。但是,需要注意的是,它无法提供与传统 Wi-Fi 网络中使用的更强大的协议(如 WPA2)相同的安全级别。

简单来说,我们可以在不使用任何外部组件的情况下将数据从一个ESP板传输和接收到另一个ESP板。通过使用ESP-NOW,我们可以降低项目的总成本。
所需组件
用ESP12E做一个3D打印的6轮摇臂火星探测车图7


  • NodeMCU ESP8266 Breakout 开发板 X2
  • 模拟环境光线传感器(Arduino兼容)
  • L293D 电机驱动器
  • N20减速电机(60-100rpm
  • 3.7v 锂离子电池
  • 3.7v 至 5v 升压器
  • ESP12E X1 (以下组件适用于 DIY PCB)
  • 3.3V稳压器 AMS1117
  • 4 针母 JST 连接器、2 针母 JST 连接器 、4 针接头 X1
  • WS2812B neopixel X2
  • 阻容等其他组件

电路图

用ESP12E做一个3D打印的6轮摇臂火星探测车图8

在这个电路图中,使用了 ESP12E 微控制器作为大脑。它有足够的引脚来控制电机,并且有一个模拟引脚来检测传感器数据。选择此模块的另一个主要原因是因为就是WiFi,通过 WiFi 和 ESP-NOW 通信来控制此模块。

为了控制电机,使用了 L293D 双通道 H 桥驱动器,一次双向控制两个电机。此外,还在电路中添加了电池充电模块。

PCB设计
用ESP12E做一个3D打印的6轮摇臂火星探测车图9

用ESP12E做一个3D打印的6轮摇臂火星探测车图10

用ESP12E做一个3D打印的6轮摇臂火星探测车图11

用ESP12E做一个3D打印的6轮摇臂火星探测车图12

在面包板上使用 NodeMCU 测试和验证电路后,最终确定 PCB 设计。

用ESP12E做一个3D打印的6轮摇臂火星探测车图13

将组件焊接在设计的 PCB 上非常容易,正常30分钟可以搞定。
3D设计与安装
接下来,就是为火星车造个身体了。

3D模型文件下载:https://www.thingiverse.com/thing:6545945/files

用ESP12E做一个3D打印的6轮摇臂火星探测车图14


ESP32代码接收器代码

  1. //RX TEST
  2. #include <ESP8266WiFi.h>
  3. #include <espnow.h>
  4. #include <FastLED.h>
  5. #define NUM_LEDS 2
  6. #define DATA_PIN 0
  7. CRGB leds[NUM_LEDS];
  8. const int motor1a = 2;
  9. const int motor1b = 14;
  10. const int motor2a = 13;
  11. const int motor2b = 12;
  12. uint8_t broadcastAddress[] = {0xAC, 0x0B, 0xFB, 0xCE, 0x8B, 0x16};//MASTER ESP8266 Board MAC Address:  AC:0B:FB:CF:16:91
  13. String success;
  14. typedef struct struct_message {
  15.   int button;
  16. } struct_message;
  17. int IN_button_state;
  18. int OUT_button_state;
  19. // Create a struct_message called DHTReadings to hold sensor readings
  20. struct_message outgoingmsg;
  21. // Create a struct_message to hold incoming sensor readings
  22. struct_message incomingmsg;
  23. // Callback when data is sent
  24. void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
  25.   Serial.print("Last Packet Send Status: ");
  26.   if (sendStatus == 0){
  27.     Serial.println("Delivery success");
  28.   }
  29.   else{
  30.     Serial.println("Delivery fail");
  31.   }
  32. }
  33. // Callback when data is received
  34. void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
  35.   memcpy(&incomingmsg, incomingData, sizeof(outgoingmsg));
  36.   Serial.print("Bytes received: ");
  37.   Serial.println(len);
  38. //store incoming data in variable
  39.   IN_button_state = incomingmsg.button;
  40.   if (IN_button_state==1){forward();}
  41.   if (IN_button_state==2){backward();}
  42.   if (IN_button_state==3){turnleft();}
  43.   if (IN_button_state==4){turnright();}
  44.   if (IN_button_state==5){nomotion();}
  45.   
  46.   
  47. }
  48. void getReadings(){
  49.   // Read
  50. OUT_button_state = analogRead(A0);
  51. delay(100);
  52. //OUT
  53.   Serial.println("OUTGOING MESSAGES");
  54.   
  55.   Serial.println(OUT_button_state);
  56. }
  57. void printIncomingMessage(){
  58.   // Display Readings in Serial Monitor
  59.   //IN
  60.   Serial.println("INCOMING MESSAGES");
  61.   
  62.   Serial.println(IN_button_state);
  63.   
  64. }
  65. void setup() {
  66. FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  67.   pinMode(motor1a,OUTPUT);
  68.     pinMode(motor1b,OUTPUT);
  69.       pinMode(motor2a,OUTPUT);
  70.         pinMode(motor2b,OUTPUT);
  71.         pinMode(A0,INPUT);
  72.   
  73.   // Set device as a Wi-Fi Station
  74.   WiFi.mode(WIFI_STA);
  75.   WiFi.disconnect();
  76.   // Init ESP-NOW
  77.   if (esp_now_init() != 0) {
  78.     Serial.println("Error initializing ESP-NOW");
  79.     return;
  80.   }
  81.   // Set ESP-NOW Role
  82.   esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
  83.   // Once ESPNow is successfully Init, we will register for Send CB to
  84.   // get the status of Trasnmitted packet
  85.   esp_now_register_send_cb(OnDataSent);
  86.   
  87.   // Register peer
  88.   esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_COMBO, 1, NULL, 0);
  89.   
  90.   // Register for a callback function that will be called when data is received
  91.   esp_now_register_recv_cb(OnDataRecv);
  92. }
  93. void loop() {
  94.     getReadings();
  95.    
  96.     //Set values to send
  97.     outgoingmsg.button = OUT_button_state;
  98.    
  99.     // Send message via ESP-NOW
  100.     esp_now_send(broadcastAddress, (uint8_t *) &outgoingmsg, sizeof(outgoingmsg));
  101.     printIncomingMessage();
  102.   }
  103.   void forward()
  104. {digitalWrite(motor1a,1);
  105. digitalWrite(motor2a,1);
  106. digitalWrite(motor1b,0);
  107. digitalWrite(motor2b,0);
  108. leds[0] = CRGB::Green;
  109. leds[1] = CRGB::Green;
  110.   FastLED.show();
  111.   delay(50);
  112.   }
  113. void backward()
  114. {digitalWrite(motor1a,0);
  115. digitalWrite(motor2a,0);
  116. digitalWrite(motor1b,1);
  117. digitalWrite(motor2b,1);
  118. leds[0] = CRGB::Red;
  119. leds[1] = CRGB::Red;
  120.   FastLED.show();
  121.   delay(50);
  122.   }
  123. void turnleft()
  124. {digitalWrite(motor1a,1);
  125. digitalWrite(motor2a,0);
  126. digitalWrite(motor1b,0);
  127. digitalWrite(motor2b,1);
  128. leds[0] = CRGB::Green;
  129.   FastLED.show();
  130.   delay(50);
  131.   }
  132. void turnright()
  133. {
  134.   digitalWrite(motor1a,0);
  135. digitalWrite(motor2a,1);
  136. digitalWrite(motor1b,1);
  137. digitalWrite(motor2b,0);
  138. leds[1] = CRGB::Green;
  139.   FastLED.show();
  140.   delay(50);}
  141. void nomotion()
  142. {digitalWrite(motor1a,0);
  143. digitalWrite(motor2a,0);
  144. digitalWrite(motor1b,0);
  145. digitalWrite(motor2b,0);}
复制代码




发送端代码

  1. #include <ESP8266WiFi.h>
  2. #include <espnow.h>
  3. #include <Wire.h>
  4. #include <Adafruit_GFX.h>
  5. #include <Adafruit_SSD1306.h>
  6. #define SCREEN_WIDTH 128 // OLED display width, in pixels
  7. #define SCREEN_HEIGHT 64 // OLED display height, in pixels
  8. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
  9. uint8_t broadcastAddress[] = {0xAC, 0x0B, 0xFB, 0xCF, 0x16, 0x91};//SLAVE ESP8266 Board MAC Address: AC:0B:FB:CE:8B:16
  10. String success;
  11. #define upButton 2
  12. #define downButton 14
  13. #define leftButton 13
  14. #define rightButton 12
  15. typedef struct struct_message
  16. {
  17. int button;
  18. }
  19. struct_message;
  20. int IN_button_state;
  21. int OUT_button_state;
  22. struct_message outgoingmsg;
  23. struct_message incomingmsg;
  24. // Callback when data is sent
  25. void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
  26.   Serial.print("Last Packet Send Status: ");
  27.   if (sendStatus == 0){
  28.     Serial.println("Delivery success");
  29.   }
  30.   else{
  31.     Serial.println("Delivery fail");
  32.   }
  33. }
  34. // Callback when data is received
  35. void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
  36.   memcpy(&incomingmsg, incomingData, sizeof(outgoingmsg));
  37.   Serial.print("Bytes received: ");
  38.   Serial.println(len);
  39. //store incoming data in variable
  40.   IN_button_state = incomingmsg.button;
  41.   
  42. }
  43. void getReadings(){
  44. if((digitalRead(upButton)==0)&&(digitalRead(downButton)==1)&&(digitalRead(leftButton)==1)&&(digitalRead(rightButton)==1))
  45. {
  46. OUT_button_state = 1;
  47. }
  48. if((digitalRead(upButton)==1)&&(digitalRead(downButton)==0)&&(digitalRead(leftButton)==1)&&(digitalRead(rightButton)==1))
  49. {
  50. OUT_button_state = 2;
  51. }
  52. if((digitalRead(upButton)==1)&&(digitalRead(downButton)==1)&&(digitalRead(leftButton)==0)&&(digitalRead(rightButton)==1))
  53. {
  54. OUT_button_state = 3;
  55. }
  56.   if((digitalRead(upButton)==1)&&(digitalRead(downButton)==1)&&(digitalRead(leftButton)==1)&&(digitalRead(rightButton)==0))
  57. {
  58. OUT_button_state = 4;
  59. }
  60.   if((digitalRead(upButton)==1)&&(digitalRead(downButton)==1)&&(digitalRead(leftButton)==1)&&(digitalRead(rightButton)==1))
  61. {
  62. OUT_button_state = 5;
  63. }
  64. }
  65. void setup() {
  66.   
  67.   Serial.begin(115200);
  68.   pinMode(upButton,INPUT_PULLUP);
  69.   pinMode(downButton,INPUT_PULLUP);
  70.   pinMode(leftButton,INPUT_PULLUP);
  71.   pinMode(rightButton,INPUT_PULLUP);
  72.   if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
  73.     Serial.println(F("SSD1306 allocation failed"));
  74.     for(;;);
  75.   }
  76.   
  77.   // Set device as a Wi-Fi Station
  78.   WiFi.mode(WIFI_STA);
  79.   WiFi.disconnect();
  80.   // Init ESP-NOW
  81.   if (esp_now_init() != 0) {
  82.     Serial.println("Error initializing ESP-NOW");
  83.     return;
  84.   }
  85.   // Set ESP-NOW Role
  86.   esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
  87.   // Once ESPNow is successfully Init, we will register for Send CB to
  88.   // get the status of Trasnmitted packet
  89.   esp_now_register_send_cb(OnDataSent);
  90.   
  91.   // Register peer
  92.   esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_COMBO, 1, NULL, 0);
  93.   
  94.   // Register for a callback function that will be called when data is received
  95.   esp_now_register_recv_cb(OnDataRecv);
  96. }
  97. void printIncomingMessage(){
  98.   // Display Readings in Serial Monitor
  99.   //IN
  100.   Serial.println("INCOMING MESSAGES");
  101.   
  102.   Serial.println(IN_button_state);
  103.   display.clearDisplay();
  104.   display.setTextSize(2);
  105.   display.setTextColor(WHITE);
  106.   display.setCursor(10, 20);
  107.   display.println("LIGHT: ");
  108.   display.setCursor(80, 20);
  109.   display.println(IN_button_state);
  110.   display.display();
  111.   delay(10);
  112.   
  113. }
  114. void loop() {
  115.   
  116.     //Get DHT readings
  117.     getReadings();
  118.     //Set values to send
  119.     outgoingmsg.button = OUT_button_state;
  120.    
  121.     // Send message via ESP-NOW
  122.     esp_now_send(broadcastAddress, (uint8_t *) &outgoingmsg, sizeof(outgoingmsg));
  123.     printIncomingMessage();
  124. }
复制代码



原文地址:
https://www.hackster.io/e_s_c/3d-printeed-mars-rover-using-esp12e-03d609


项目作者:edison science corner

译文首发于:达尔闻说

转载请注明来源信息




MARS ROVER USING NODEMCU - 6545945.zip

16.77 MB, 下载次数: 4

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

本版积分规则

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

硬件清单

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

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

mail