回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页
best-icon

Arduino - 使用Beetle ESP32-C6开发板,通过浏览器控制微型震动马达模块震动 简单

头像 小牛哥 2024.04.27 80 0

 

本文主要知识点

- 连接WIFI

- 使用Preferences库保存数据

- 使用ESPAsyncWebServer提供Web服务

- 板载LED灯做指示灯

 

1. 物料准备

 

1.1 Beetle ESP32 C6

Beetle ESP32-C6是一款基于ESP32-C6芯片设计的迷你体积的Arduino低功耗物联网开发板,该开发板仅有硬币大小(25*20.5mm)。ESP32-C6搭载160MHz的高性能RISC-V 32位处理器,支持Wi-Fi 6、Bluetooth 5、Zigbee 3.0、Thread 1.3通讯协议,可接入多种通讯协议的物联网网络。该开发板集成锂电池充电管理,无需外围模块即可对锂电池进行充电,可以使项目体积更加小巧。

高度集成,超小体积

​ Beetle ESP32-C6在仅硬币大小的体积上引出了多达13个IO口,制作项目时不必担心IO不够用的情况。Beetle ESP32-C6集成锂电池充电管理功能,可以安全的对锂电池进行充电,该开发板还支持电池电压监测,以便在电量不足时采取措施,确保设备持续运行。

 

1.2震动马达模块

image.png

智能可穿戴式产品震动提醒模块,微型震动马达模块

 

微型振动马达主要用于手机的微型振动马达是属于直流有刷电机,马达轴上面有一个偏心轮,当马达转动的时候,偏心轮的圆心质点不在电机的转心上,使得马达处于不断的失去平衡状态,由于惯性作用引起震动。

 

震动马达模块
这是适合作为非可听指示器的小型振动马达模块。当输入为高电平时,电动机会震动,就像你的静音模式的手机一样。

特征:

- 额定电压:5.0VDC

- 工作电压:3.0 - 5.3VDC

- 额定转速:最小9000转每分

- 额定电流:最大60毫安

- 起动电流:最大90毫安

- 启动电压:DC3.7V

- 绝缘电阻:10Mohm

- 兼容性:与UNO R3/ Mega2560 兼容

技术规格/specifications
尺寸 21*30mm
固定孔 3mm
孔距 15mm
电压 3-5V
端口 数字量
马达 直径10mm 厚度2.7mm 扁平马达
驱动 MOS管 高电平触发,低电平截止
平台 Arduino、单片机

模块特性
采用高品质手机震动马达,震动效果明显
mos放大驱动,可以直接通过啊rduino的数字口进行控制
可通过PWM控制马达的震动强度
通过此模块可以方便的完成电信号到机械震动感的转换
适用于震动感互动产品的制作,可穿戴智能设备震动提醒等

 

Beetle ESP32-C6的3.3v引脚可以为这个震动马达模块供电。

 

1.3 杜邦线

白色杜邦线1根,蓝色杜邦线1根,白色杜邦线1根,都是公母头

 

2. 如何接线

 

1714159680986.png

白色杜邦线公头接Beetle ESP32-C6的GND,母头接震动马达模块的GND。

image.png

红色杜邦线公头接Beetle ESP32-C6的3.3v,母头接震动马达模块的VCC。

1714159814057.png

蓝色杜邦线是信号线,公头接Beetle ESP32-C6的GPIO6,母头接震动马达模块的IN。

 

3. 代码解读

 

打开电脑浏览器,通过CMD获取开发板的IP地址192.168.66.219

image.png

输入网址 192.168.66.219/command?output=HIGH

板载LED灯点亮, 1027手机扁平马达振动

    else if(output.equalsIgnoreCase("HIGH")){

      // 板载LED灯亮

      digitalWrite(LED, HIGH);

      delay(1000);

 

      preferences.begin(HOSTNAME, false);

      preferences.putBool(PARAM_OUTPUT, true);

      preferences.end();


 

      request->send(200, "text/plain", "板载LED灯点亮, 1027手机扁平马达振动");

    }

 

输入网址 192.168.66.219/command?output=LOW

板载LED灯熄灭, 清空NVS数据, 1027手机扁平马达停止振动

 

    if(output.equalsIgnoreCase("LOW")){

      // 板载LED灯灭                    

      digitalWrite(LED, LOW);

      delay(1000);


 

      preferences.begin(HOSTNAME, false);

      preferences.clear();

      preferences.end();


 

      request->send(200, "text/plain", "板载LED灯熄灭, 清空NVS数据");

    }

 

如何使用ESPAsyncWebServer提供Web服务

  server.on("/", HTTP_GET, [] (AsyncWebServerRequest *request) {

    request->send(200, "text/plain", "WebLeds v1.0.0.0");

  });

 

  // Start TCP (HTTP) server

  server.begin();

  Serial.println("TCP server started");

 

如何使用mDNS

  // Set up mDNS responder:

  // mDNS 可以在非 AP 模式下使用但也有局限,局域网中其它设备也必须开启 mDNS 服务互相间才能通过域名访问。

  // bool begin(const String &hostName);

  // bool begin(const char *hostName)

  if (MDNS.begin(HOSTNAME)) {

    Serial.print("[MDNS] MDNS responder started: ");

    Serial.print(HOSTNAME);    

    Serial.println(".local");

  } else {

    Serial.println("Error setting up MDNS responder!");

  }


 

  // Start TCP (HTTP) server

  server.begin();

  Serial.println("TCP server started");


 

  // Add service to MDNS-SD

  MDNS.addService("http", "tcp", 80);

 

image.png

这种情况需要确认电脑是否和ESP32C6处于同一个WIFI网络。

 

image.png

ping Arduino1027 和 ping Arduino1027.local都可以ping通。

 

如何使用 Beetle ESP32 C6 的Preferences库永久保存数据。

闪存中保存的数据在Beetle ESP32 C6开发板重启后或电源故障后仍会保留。使用Preferences库可用于保存WIFI凭据、API 密钥、阈值甚至 GPIO 的最后状态等数据。我们这里使用Preferences库保存是否让1027手机扁平马达振动,闪存保存1027手机扁平马达的状态值。

 

#include <Preferences.h>

先应用Preferences库

 

使用 Preferences库保存数据,数据结构如下:

namespace {
 key1: value1
 key2: value2
}

在同一命名空间上可以保存不同的键值。在实际项目中,此配置可用于保存网络凭据:

credentials {
 ssid: "your_ssid"
 pass: "your_pass"
}

 

credentials 是命名空间,ssid和pass是键,"your_ssid"和"your_pass"是值。

使用Preferences库,定义要保存的数据类型。如果要读取该数据,则必须知道保存的数据类型。换句话说,写入和读取的数据类型应该是相同的。

更多内容请参考 arduino-esp32/libraries/Preferences/src/Preferences.cpp at master · espressif/arduino-esp32 (github.com)

 

Preferences preferences;

启动Preferences库的实例。

 

      preferences.begin(HOSTNAME, false);

      preferences.putBool(PARAM_OUTPUT, true);

      preferences.end();

打开命名空间,记录键值,这个操作是接收API请求,让1027手机扁平马达状态为震动状态。

putBool(const char* key, const bool value) 第一个入参是key,第二个入参是布尔值,表示震动状态。使用end()关闭命名空间。

 

      preferences.begin(HOSTNAME, false);

      preferences.clear();

      preferences.end();

清除打开的命名空间下的所有键值(它不会删除命名空间),这个操作是接收API请求,让1027手机扁平马达状态为非震动状态。

 

      preferences.begin(HOSTNAME, true);    

      bool storedCommand = preferences.getBool(PARAM_OUTPUT, false);

      preferences.end();

这begin()方法打开一个具有定义命名空间的“存储空间”。布尔参数意味着我们将在读/写模式下使用它。用true以只读模式打开或创建命名空间。用false以写模式使用它。

getBool(const char* key, const bool defaultValue),第一个入参是key,第二个入参是布尔值,表示震动状态。注意命名空间名称限制为 15 个字符。

 

控制震动马达模块是否震动

    digitalWrite(PIN, HIGH);

    delay(1000);

当输入为高电平时,震动马达模块会震动
 

    digitalWrite(PIN, LOW);

    delay(1000);

当输入为高电平时,震动马达模块会停止震动

代码
#include <ESPmDNS.h>
#include <AsyncJson.h>
#include <ArduinoJson.h>
#include <Preferences.h>

#if defined(ESP8266)
  #define HARDWARE "ESP8266"
  #include <ESP8266WiFi.h>
  #include <ESPAsyncTCP.h>
#elif defined(ESP32)
  #define HARDWARE "ESP32"
  #include <WiFi.h>
  #include <AsyncTCP.h>
#else
	#error Platform not supported
#endif
#include <ESPAsyncWebServer.h>

#define PIN      6
#define LED      15
#define HOSTNAME "Arduino1027"

const char* PARAM_OUTPUT  = "output";
String      ssid          = "Wallexbot"; // my WiFi SSID
String      password      = "18502339831"; // my WiFi Password

AsyncWebServer server(80);
Preferences preferences;

void setup() {
  // start serial port
  Serial.begin(115200);
  Serial.println("Serial begin...");
  pinMode(PIN, OUTPUT);
  pinMode(LED, OUTPUT);

  WiFi.begin(ssid.c_str(), password.c_str());
  Serial.print("[WiFi] Connecting to ");
  Serial.print(ssid.c_str());
  Serial.print("..");
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.print(".");
    // wait 1.5 seconds for connection
    delay(1500);
  }

  Serial.println("[WiFi] WiFi connected!");
  
  Serial.print("[WiFi] IP Address: ");
  Serial.println(WiFi.localIP());
  
  Serial.print("[WIFI] Mac: ");
  Serial.println(WiFi.macAddress());

  server.on("/", HTTP_GET, [] (AsyncWebServerRequest *request) {
    request->send(200, "text/plain", "WebLeds v1.0.0.0");
  });

  // http://192.168.66.219/command?output=HIGH
  Serial.println("[WebServer] /command");
  server.on("/command", HTTP_GET, [] (AsyncWebServerRequest *request) {
    Serial.println("[WebServer] request /command");

    if(!request->hasParam(PARAM_OUTPUT)) {
      request->send(400, "text/plain", "Invalid command.");
      return;
    }

    // 控制PIN引脚状态
    String output = request->getParam(PARAM_OUTPUT)->value();
    Serial.print("Digital Write: ");
    Serial.println(output);
    if(output.equalsIgnoreCase("LOW")){
      // 板载LED灯灭                     
      digitalWrite(LED, LOW);
      delay(1000);

      preferences.begin(HOSTNAME, false);
      preferences.clear();
      preferences.end();

      request->send(200, "text/plain", "板载LED灯熄灭, 清空NVS数据");
    } else if(output.equalsIgnoreCase("HIGH")){
      // 板载LED灯亮
      digitalWrite(LED, HIGH);
      delay(1000);
  
      preferences.begin(HOSTNAME, false);
      preferences.putBool(PARAM_OUTPUT, true);
      preferences.end();

      request->send(200, "text/plain", "板载LED灯点亮, 1027手机扁平马达振动");
    } else {
      request->send(400, "text/plain", "错误命令");
      return;
    }
  });

  // Set up mDNS responder:
  // mDNS 可以在非 AP 模式下使用但也有局限,局域网中其它设备也必须开启 mDNS 服务互相间才能通过域名访问。
  // bool begin(const String &hostName);
  // bool begin(const char *hostName)
  if (MDNS.begin(HOSTNAME)) {
    Serial.print("[MDNS] MDNS responder started: ");
    Serial.print(HOSTNAME);    
    Serial.println(".local");
  } else {
    Serial.println("Error setting up MDNS responder!");
  }

  // Start TCP (HTTP) server
  server.begin();
  Serial.println("TCP server started");

  // Add service to MDNS-SD
  MDNS.addService("http", "tcp", 80);
}

void loop() {

  preferences.begin(HOSTNAME, true);    
  bool storedCommand = preferences.getBool(PARAM_OUTPUT, false);
  preferences.end();
  Serial.print("Stored Command: ");
  Serial.println(storedCommand);

  if(storedCommand){ // .equalsIgnoreCase("HIGH")
    
    digitalWrite(PIN, HIGH);
    delayMicroseconds(900); 			// 输出PWM,占空比为100/1000=10%
    digitalWrite(PIN, LOW);
    delayMicroseconds(1000 - 900); 	// 修改这里的1000可以调整频率,总周期为1000us,所以频率为1000Hz.

    digitalWrite(PIN, HIGH);
    delay(1000);

    digitalWrite(PIN, LOW);
    delay(1000);
  }
  else {
    delay(1000);
  }
}

评论

user-avatar