首页 ESP01————舵机
文章
取消

ESP01————舵机

理性计划会减少错误、节省时间

目标

  1. 学会舵机的使用
  2. 学会esp8266的烧录
  3. 实现远程控制舵机

锻炼能力

  1. 合理规划时间计划,尽可能的高效
  2. 尽可能的将做、写、思考结合在一起,养成习惯

规划安排(5min)

时间:2-2.5h

  1. 学会烧录、电亮一个led灯:
    • 收集esp8066的资料、收集esp8266的烧录资料、撰写实验步骤(20min)
    • 根据实验步骤进行操作、记录结果(10min)
  2. 学会舵机的使用:
    • 收集舵机的资料、收集舵机的使用资料、撰写使用方法(20min)
    • 根据资料写代码、实验、记录结果(10min)
  3. 结合前两步、实现远程控制(20min)

预测:顺利的话,应该能在1.5h内完成、但不顺利的话可能一个下午都完不成,再查找一个又一个的问题中过去,若是不顺利、重心就放在了锻炼能力、锻炼思考这边,而不是放在完成目标这边。

相关资料

一、收集esp8266的资料、收集esp8266的烧录资料、撰写实验步骤(20min)

  1. esp8266资料

image-9 什么是固件

固件(Firmware)是指嵌入式系统中的一种软件,它是安装在硬件设备上的一组指令和数据,用于控制设备的操作和功能。固件位于硬件和操作系统之间,负责管理硬件设备的低级操作,例如启动、初始化和控制硬件功能。

与传统软件不同,固件是直接存储在硬件设备的非易失性存储器中,例如闪存或只读存储器(ROM)。它通常以二进制形式存储,并由硬件设备的制造商预先安装或通过固件更新进行更新。

固件的主要目的是为硬件设备提供基本的操作和功能。它可以实现设备的启动和关机过程、处理输入和输出、管理存储器、控制外围设备等。例如,固件可用于控制打印机的打印过程、路由器的网络连接、智能手机的硬件功能等。

固件还可以包含操作系统的一部分,称为嵌入式操作系统。这种情况下,固件不仅负责硬件的控制,还提供了一些高级功能和服务,例如文件系统、网络协议栈、驱动程序等。

由于固件直接与硬件交互,因此对设备的性能和功能有着重要的影响。固件更新是常见的做法,用于改进设备的性能、修复错误、增加新功能或提供安全性补丁。

ESP8266芯片具有自己的固件,被称为ESP8266固件或NodeMCU固件。

NodeMCU固件是一种开源固件,基于Lua脚本语言,特别设计用于ESP8266芯片。它提供了一套易于使用的功能和API,使开发者能够快速开发物联网应用程序。

NodeMCU固件提供了一系列的功能模块和库,包括Wi-Fi连接管理、网络协议支持(例如HTTP、MQTT等)、GPIO控制、PWM输出、ADC采集、文件系统访问等。它还支持通过串口进行编程和调试,并提供了命令行交互界面。

使用NodeMCU固件,开发者可以使用简单的Lua脚本语言来编写应用程序,而无需深入了解底层的Wi-Fi和网络协议。这使得ESP8266芯片的开发变得更加容易和快速。

除了NodeMCU固件,ESP8266芯片还可以使用其他固件,例如官方提供的Espressif Systems的AT固件,或者第三方开发者基于ESP8266芯片开发的其他固件。这些固件提供了不同的功能和编程接口,以满足不同的开发需求。

ESP8266的存储系统是32MB的 Flash + 80KB的SRAM。(可以理解为电脑的SSD和内存条)

闪存通常分为以下几个部分:

Bootloader(引导加载程序):引导加载程序是在芯片上电时首先执行的代码,它负责初始化芯片、加载固件和跳转到固件的执行点。这个是你无法修改或者擦除的。

Firmware(固件):固件是主要的应用程序代码,它包含了设备的功能和逻辑。固件部分占据了闪存的大部分空间。这是我们可以修改的。

File System(文件系统):ESP8266芯片的闪存中的一部分可以用于文件系统,用于存储应用程序的配置文件、网页文件、数据文件等。通常采用SPIFFS(SPI Flash File System)作为文件系统。

OTA(Over-The-Air)固件区域:这个区域用于存储通过OTA方式进行固件更新所需的数据。

ESP8266的内存包括32 KiB指令RAM,32 KiB指令缓存RAM,80 KiB用户数据RAM(存储程序代码、变量、堆栈和其他运行时数据)和16 KiB ETS系统数据RAM

固件和用户程序

固件与底层硬件打交道如果要字节编写固件,就需要了解ESP8266 芯片的寄存器等信息,通常是一件麻烦的事情。所以我们通常使用厂商开发好的固件,直接用,或者基于固件编写上层应用。

固件也是一种程序,开机就运行,通过编写不同的固件,他也能提供很多不同功能。

通常使用AT指令来运行固件中设计好的各种功能,比如链接一个WiFi,固件为上层应用提供了友好的接口。我们可以使用Ardunio IDE来进行上层应用的开发,在我们的应用中,可以通过AT指令使用固件中开发好的功能。

我们的程序下载到ESP8266上并不会修改固件内容,就像你给电脑安装一个软件一样,并不会修改系统功能。

通常,也可以使用其他MCU连接ESP8266,通过发送AT指令和接收回复来进行编程。比如使用STM32与ESP8266进行串口通信,实现某些功能。

烧录

  1. https://zhuanlan.zhihu.com/p/669132595

下载、配置arduino(已完成)

设置开发板NodeMCU 1.0(ESP-12E Module)

驱动下载:

官网下载地址:https://cn.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers

网盘: https://pan.baidu.com/s/101cJq2-qOyC_uRbNJ_vjqw?pwd=486z

如果电脑上没有安装相应的驱动,是无法正常识别COM口的,成功安装驱动之后,将NodeMCU-ESP8266通过USB线连接到电脑上,就可以在设备管理器中看到COM3口设备了;

下载测试用例

image

image-1

image-2

image-3

  1. https://blog.csdn.net/weixin_64344153/article/details/130354145

1.我们将使用Arduino IDE对ESP8266进行代码编译。

这是Arduino IDE下载地址:SoftwareArduino

Arduino安装好后我们选择开发板

image-4

2.选好开发板后,我们进行代码的烧录。我们在原有的例程上另外接了一颗LED灯,通过这两个灯的控制来更好理解blinker对开发板的控制。

我们用官网的例程时要注意将例程中的这部分进行修改:

image-5

  1. https://blog.csdn.net/weixin_49861340/article/details/123792561

烧录时的按键手法《最重要的要点》!!!!!!!! esp8266开发板上有两个按钮,FLASH和RST 按下FLASH(或叫BOOT)不丢,然后按一下复位键(RST)松开复位键(RST),开发板上的灯会闪一下,此时FLASH(或叫BOOT)不要松,然后点上传,上传完毕后松开。

现在就可以把开发板插入电脑了,右键我的电脑->管理->端口,我的esp8266开发板的串口号为COM5,记住你的开发板的串口号

打开Arduino,点击工具->开发板->(选择如同,esp8266)

image-6

点击工具->端口->选择你的端口(可用点击获取开发板信息,如果出来一个小窗口并带有信息,说明连接正常)

点击文件->示例->ESP8266->Blink

image-7

会弹出一个新的窗口,里面是实例代码,将其全选复制下来粘贴到一个新建的里面并保存,可以把里面的数值改小一点100和200,效果更明显

左上角的√,验证代码是否正确

开始烧录,用刚才的烧录手法进行上传!!!

拔下esp8266开发板,再重新插上,这时开发板上的灯会不停闪烁,证明烧录成功(只要上电都会闪烁,因为代码已经被烧录到开发板中)(闪烁的频率就是刚才改的数值)

dddouble 2022.08.01 1 点赞 上传的时候不需要在nodeMCU上按任何按键,也能成功,这是为什么? 应该是上面的USB转串口有信号线自动连接到相应的管脚上了,所以不需要按。我用的板子也是不需要按。

泡泡枪超人 2022.12.11 点赞 Timed out waiting for packet header如何解决 weixin_46396206 Hello,World. 回复 @starry& 2023.07.20 点赞 首先:拔出usb 然后按住:mcu上的flash按钮不松开 然后插入usb。调处程序,点击上传,出现connecting时松开flash即可。

  1. https://blog.csdn.net/zz531987464/article/details/83447583
  2. https://blog.csdn.net/qq_44366571/article/details/107334239

收集舵机的资料、收集舵机的使用资料、撰写使用方法(20min)

代码 image-8

https://www.basemu.com/servo-motor-sg90-with-nodemcu.html

介绍资料 image-10

伺服电机在工业领域已经出现很长时间了。由于它们的体积小,力量大,而且非常节能,所以人们在许多时候都会用到它。正因为具备这样的优点,普通的伺服电机常被用来制作遥控飞机或遥控汽车、机器人等。高精密的伺服电机也用于工业领域,如:机器人、自动化生产线、医药和食品生产等。但是伺服电机是如何工作的呢?

伺服电机内部包含了伺服电路,还有一根可定位的输出轴,输出轴安装有齿轮机构(如下图所示),电机由一个电子信号进行控制,这个信号也决定了轴的运动量。

伺服电机里面有什么?

image-11

要完全理解伺服器的工作原理,需要打开伺服电机的外壳,就可以看到里面有一些装置:一个小型的直流电机,电位器和一个控制电路。小电机和输出轴之间由减速齿轮组连接,输出轴与电位器的转轴连接,当小电机旋转时,减速齿轮组带动输出轴和电位器运动,电位器的电阻也会随着发生变化。当伺服电机输出轴转动到预定位置时,电机停止供电,反之,电机就会向既定方向继续转动,这样控制电路就可以精确地调节运动量和运动方向了。

控制脉冲信号是通过信号线发送的。电机的速度与实际位置和理想位置的差成正比,所以伺服电机越接近理想位置,它的转动速度会越慢,反之它的转动速度越快,这就是伺服电机的比例控制,这也意味着伺服电机是非常高效的。

伺服电机的控制是如何实现的?

伺服系统通过控制线发送可变宽度的脉冲信号,脉冲宽度调制(PWM)信号。PWM信号包含一个最小脉冲,一个最大脉冲和一个重复频率。通常,伺服电机只能在两个不同的方向上旋转90° ,总共180° 。伺服电机的中立位置被定义90° ,在中立位置上伺服电机向顺时针或逆时针方向旋转的距离相同。PWM信号和脉冲的持续时间决定了转轴的位置,伺服电机脉冲间隔是20ms(毫秒)。例如,宽度为1.5ms(毫秒)的脉冲将使电机转向90位,脉冲宽度小于1.5 ms时电机将朝顺时针方向转动到0°位置,当脉冲宽度大于1.5ms时,电机将向逆时针方向旋转到180度。

image-12

伺服器接收到脉冲信号后,它将会移动指定的位置并保持在这个位置上,如果我们认为对它施加一定的外力,伺服机构产生抵抗力,并始终保持在既定位置上。伺服机构所能产生的最大力量称为伺服电机的转矩。伺服电机只有在接收到连续的重复脉冲时才能一直保持既定位置。

伺服电机的种类

image-13

伺服电机分为两种:AC 和 DC。交流伺服电机的工作电流更高,它更倾向于在工业制造领域使用。直流伺服电机不是为高电流而设计的,通常更适合一些小型化的应用。通常,直流伺服电机比交流伺服电机便宜。精度较好的伺服电机在输出轴上安装有两个滚珠轴承,这样可以减少摩擦力,位置控制也相对精准。

伺服电机的应用

伺服电机常见的应用,如在遥控飞机上使用伺服电机来控制机翼摆动,机器人运用伺服电机作为关节,遥控汽车运用伺服电机实现转向等等。在食品生产、药品生产等领域,伺服电机也被设计用于高压和高温、高腐蚀性的严苛环境中,在工业运用时,对伺服电机的质量和精度要求也更高。无论是业余爱好,还是专业工程师,只有我们越了解伺服电机,才会有更多的设想,伺服电机也会带给我们更多的可能。

实验步骤

学会烧录、电亮一个led灯(用时1h)

1.选择开发板

有说NodeMCU 1.0(ESP-12E Module),有说LOLIN(WEMOS) D1 R2 & mini,也有Generic ESP8266 Module,先试试第一个

2.点击文件->示例->ESP8266->Blink

结果,三个开发板可以用的示例文件都可以用,用时候不需要太多的计划,或许边查找资料,边记录,边实操会更省时间。

结论:不需要太多的计划,大多数问题凭借直觉就足以解决,只需要查阅资料的时候,做好记录以及分类,方便再次使用

烧录舵机代码(25min)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <Servo.h>

Servo myServo;  // 定义Servo对象来控制
int pos = 0;    // 角度存储变量

void setup() {
  myServo.attach(14); //D5   
}

void loop() { 
 for (pos = 0; pos <= 180; pos ++) { // 0°到180°
    // in steps of 1 degree
    myServo.write(pos);              // 舵机角度写入
    delay(15);                       // 等待转动到指定角度
  } 
  delay(2000);//延时2s
  for (pos = 180; pos >= 0; pos --) { // 从180°到0°
    myServo.write(pos);              // 舵机角度写入
    delay(15);                       // 等待转动到指定角度
  }
  delay(2000);//延时2s 
}

成功,但usb线插在电脑上运行舵机时,会出现串口断开脸上断开连上的情况,再次烧录时,直接蓝屏

实物接线图: 9eaa58799eb9829323d35366178eda2

1c34d72e60d6e8aa090d2d25b54b9f9

image-14 烧录wifi远程控制舵机代码(10min)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <ESP8266WiFi.h>
#include <Servo.h>

const char ssid[] = "";      // WiFi名
const char pass[] = "";    // WiFi密码
WiFiClient client;                   // 创建一个WiFiClient对象
const char* server = "192.168.1.6";   // 服务器的IP地址
const int port = 8888;                // 服务器的端口号
Servo myServo;                        // 定义Servo对象来控制
int pos = 0;                          // 角度存储变量

// 初始化
void setup()
{
  Serial.begin(115200);
  Serial.println("esp8266 test");
  initWiFi();
  myServo.attach(14); // D5 
}

// 主循环
void loop()
{
  Serial.println("hello esp8266");
  delay(1000);
  // 如果WiFi连接正常,尝试连接服务器
  if (WiFi.status() == WL_CONNECTED) {
    Serial.print("Connecting to ");
    Serial.println(server);
    // 如果连接成功,发送HTTP请求
    if (client.connect(server, port)) {
      Serial.println("Connected to server");
      // 发送GET请求,请求服务器发送LED的状态
      client.println("GET_STATE_DUOJI&duoji_ready");
      // 等待服务器的响应
      while (client.connected() || client.available()) {
        // 如果有数据可读,读取并处理
        if (client.available()) {
          String line = client.readStringUntil('\n');
          Serial.println(line);
          // 如果读到了LED的状态,根据状态控制LED灯,并向服务器发送反馈
          if (line.startsWith("DUOJI:")) {
            int duojiState = line.substring(4).toInt();
            Serial.print("DUOJI state: ");
            Serial.println(duojiState);
            if (duojiState == 1) {
              // To 0°
              myServo.write(0);
              delay(1000);
            }
            else if (duojiState == 2) {
              // To 90°
              myServo.write(90);
              delay(1000);
            }
            else if (duojiState == 0) {
              // To 180°
              myServo.write(180);
              delay(1000);
            }
          }
        }
      }
      // 断开连接
      client.stop();
      Serial.println("Disconnected from server");
    }
    else {
      // 如果连接失败,打印错误信息
      Serial.println("Connection failed");
    }
  }
  else {
    // 如果WiFi连接断开,打印错误信息
    Serial.println("WiFi disconnected");
  }
}

// 初始化WIFI
void initWiFi()
{
  Serial.print("Connecting WiFi...");
  WiFi.mode(WIFI_STA); // 配置WIFI为Station模式
  // 设置静态IP地址,网关,子网掩码,DNS
  IPAddress local_IP(192, 168, 1, 20);
  IPAddress gateway(192, 168, 1, 1);
  IPAddress subnet(255, 255, 255, 0);
  IPAddress primaryDNS(8, 8, 8, 8);
  IPAddress secondaryDNS(8, 8, 4, 4);
  if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
    Serial.println("STA Failed to configure");
  }
  WiFi.begin(ssid, pass); // 传入WIFI热点的ssid和密码
  while (WiFi.status() != WL_CONNECTED) // 等待连接成功
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP()); // 打印自己的IP地址
}


总结

这次实验共花费时间不到2h,在可接受范围内。开始的第一个小时,我一直在查阅资料,查阅esp8266的烧录方法,心理想着尽可能的减少失误的概率,认为失误出错等于浪费时间,所以要尽可能的减小失误出错的概率,因而多方对比,大约用了45min的时间发现了2个方法,其中我主要查询的是arduino方法,因为这个是我最近在用的,其中有3中方法,,但选择的板子都不同,而且还有一个方法里说要注意按键手法,而评论区里面有人说要,有一些却不用,本打算继续查阅下去,找出最保险的方法,但已超出预期时间近25min。(计划还是有用的,避免了更大的错误),这里说明这类的小问题不需要这般大惊小怪的,试错成本极低,按照直觉来就可以了,有什么试什么就可以了。只有像树莓派那样下载安装个环境需要几十分钟甚至是几个小时的时候,试错成本极大,就需要多方对比。

总之,计划是有必要的,做、写、反思结合在一起进行,计划和记录有时也不需要太详细、太循规蹈矩,小问题,快速解决就可以了,未来再次遇到可能也可以快速解决,甚至是会懒得翻着个,有价值的东西才需要记录和计划。

本文由作者按照 CC BY 4.0 进行授权