Beetle ESP32-C3是一款基于ESP32-C3 RISC-V 32位单核处理器芯片的主控板,专为物联网 (IoT) 设备而设计。
Beetle ESP32-C3在仅硬币大小的体积上引出了多达13个IO口,制作项目时不必再担心IO口不够用的情况,同时主控板还集成锂电池充电管理功能,可以直接连接锂电池,不需要外围模块,同时保证应用体积和安全性。
Beetle ESP32-C3配套的扩展板在未增加太大体积的情况下,引出了更多的电源,在制作项目时焊接更加方便,板载的GDI显示屏接口解决使用屏幕时的接线烦恼。
Beetle ESP32-C3支持Wi-Fi 和 Bluetooth 5 (LE) 双模通讯,降低了设备配网难度,同时还支持蓝牙 Mesh (Bluetooth Mesh) 协议和乐鑫 Wi-Fi Mesh可以实现更高的通讯稳定性和更大的覆盖面积,适用于广泛的物联网应用场景。
Beetle ESP32-C3拥有详细的示例教程,通过教程可以轻松的使用控制器的无线功能,连接阿里云、IFTTT等物联网平台,同时DFRobot商城提供了上千种传感器和执行器,这些传感器和执行器也有详细的教程,因此你可以轻松搭建出自己的物联网系统。
Beetle ESP32-C3可以使用Arduino IDE、ESP-IDF、MicroPython进行编程(MicroPython教程后续推出),C语言、python都可以轻松的操纵硬件。
WIFI
蓝牙
接口引脚
此接口为DFRbot专用GDI显示屏接口,使用18pin-FPC线连接,单线材连接屏幕,为您提供最简捷的屏幕使用方式。
以下是GDI接口使用的引脚列表
FPC PINS | Beetle ESP32 C3 PINS | Description |
---|---|---|
VCC | 3V3 | 3.3V |
BLK(PWM调光) | 10 | 背光 |
GND | GND | GND |
SCLK | 4/SCK | SPI时钟 |
MOSI | 6/MOSI | 主机输出,从机输入 |
MISO | 5/MISO | 主机输入,从机输出 |
DC | 1 | 数据/命令 |
RES | 2 | 复位 |
CS | 7 | TFT片选 |
SDCS | 0 | SD卡片选 |
FCS | NC | 字库 |
TCS | 3 | 触摸 |
SCL | 9/SCL | I2C时钟 |
SDA | 8/SDA | I2C数据 |
INT | NC | INT |
BUSY-TE | NC | 防撕裂引脚 |
X1 | NC | 自定义引脚1 |
X2 | NC | 自定义引脚2 |
使用FPC链接屏幕时根据GDL demo配置所需对应的引脚号即可,通常只需要根据不同主控配置三个引脚
支持GDI的显示屏:
当您首次使用Beetle-ESP32-C3,您需要了解以下步骤
配置URL网址到Arduino IDE
打开Arduino IDE,点击File->Preferences,如下图所示:
板载LED灯默认为引脚10
int led = 10;
void setup() {
pinMode(led,OUTPUT);
}
void loop() {
digitalWrite(led,HIGH);
delay(1000);
digitalWrite(led,LOW);
delay(1000);
}
Copy
如图所示及烧录成功
您会看见板载LED灯开始闪烁
仍不能烧录?请点击此处
ledcAttachPin(GPIO, Channel)
说明:指定信号将出现在哪些 GPIO 上
参数:
ledcWrite(Channel, dutyCycle)
说明:设置PWM信号生成通道
参数:
ledcSetup(Channel, freq, resolution)
说明:设置PWM信号生成通道
参数:
ESPC3的PWM由于其可以自由映射到其它端口进行输出,您需要进行几步设置,该案例将使用帮助您理解其中的步骤 该案例你可以看到LED灯逐渐变亮变暗
/*
* LED呼吸灯示例
*/
const int ledPin = 10; // PWM生成后实际输出引脚
//设置PWM参数
const int freq = 5000;//PWM频率
const int ledChannel = 0;//信号生成GPIO
const int resolution = 8;//8位分辨率
void setup(){
//PWM参数设置
ledcSetup(ledChannel, freq, resolution);
//将生成信号通道绑定到输出通道上
ledcAttachPin(ledPin, ledChannel);
}
void loop(){
//逐渐变亮
for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){
// changing the LED brightness with PWM
ledcWrite(ledChannel, dutyCycle);
delay(15);
}
//逐渐变暗
for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
// changing the LED brightness with PWM
ledcWrite(ledChannel, dutyCycle);
delay(15);
}
}
Copy
pinMode(GPIO,INPUT_PULLUP);
说明:外部中断引脚定义
参数:
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode)
说明:外部中断
参数:
detachInterrupt(digitalPinToInterrupt(pin))
说明:关闭给定的中断。
参数:
interrupts()
说明:重新启用中断(在被noInterrupts()禁用之后。中断允许某些重要任务在后台发生并默认启用。当禁用中断时,某些功能将不起作用,并且传入通信可能会被忽略。可能会稍微破坏代码的时序,但是对于特别关键的代码部分可能会被禁用。
noInterrupts()
说明:禁用中断(您可以使用来重新启用它们interrupts())。中断允许某些重要任务在后台发生,并且默认情况下启用。禁用中断时,某些功能将不起作用,并且传入的通信可能会被忽略。但是,中断可能会稍微破坏代码的时序,并且可能会在代码的特别关键的部分将其禁用。
Serial1.begin(9600,SERIAL_8N1,/*rx =*/0,/*Tx =*/1);
Copy
ESP32-C3通过Servo库不能驱动舵机,可以在项目->加载库->管理库中搜索安装ESP32_C3_ISR_Servo库驱动舵机
begin(cspin)
说明:初始化SD卡库和 SD卡。当使用SD.begin()时﹐默认将Arduino SPI的SS引脚连接到SD卡的CS使能选择端;也可以使用begin(cspin)指定一个引脚连接到SD卡的CS使能选择端,但仍需保证 SPI 的SS引脚为输出模式,否则SD卡库将无法运行。
参数:cspin:连接到SD 卡CS端的Arduino引脚。
返回值: boolean型值,为 true表示初始化成功;为 false表示初始化失败。
exists()
说明:检查文件或文件夹是否存在于SD卡中。语法:SD. exists( filename)
参数: filename:需要检测的文件名。其中可以包含路径,路径用“/”分隔。
返回值: boolean型值,为 true表示文件或文件夹存在;为false表示文件或文件夹不存在。
open()
说明:打开SD卡上的一个文件。如果文件不存在,且以写入方式打开,则Arduino会创建一个指定文件名的文件。(所在路径必须事先存在)
语法:SD.open( filename)SD.open(filename,mode)
参数:
filename:需要打开的文件名。其中可以包含路径,路径用“/”分隔。
mode(可选):打开文件的方式,默认使用只读方式打开。也可以使用以下两种方式打开文件:
FILE_READ:只读方式打开文件;FILE_WRITE,写入方式打开文件。
返回值:返回被打开文件对应的对象﹔如果文件不能打开,则返回false。
FILE_WRITE,写入方式打开文件。
返回值:返回被打开文件对应的对象;如果文件不能打开,则返回false。
remove()
说明:从SD卡移除一个文件。如果文件不存在,则函数返回值是不确定的,因此在移除文件之前,最好使用SD. exists(filename)先检测文件是否存在。
语法:SD. remove( filename)
参数: filename,需要移除的文件名。其中可以包含路径,路径用“!”分隔。
返回值: boolean型值,为true表示文件移除成功;为false表示文件移除失败。
mkdir(filename)
说明:创建文件夹。
参数:
rmdir(filename)
说明:移除文件夹。被移除的文件夹必须是空的。语法:SD.rmdir( filename)
参数:
File类提供了读/写文件的功能,该类的功能与之前使用的串口相关函数的功能非常类似。其成员函数如下。
available()
说明:检查当前文件中可读数据的字节数。语法:file. available()
参数:
close()
说明:关闭文件,并确保数据已经被完全写入SD卡中。语法:file. close()
参数:
flush()
说明:确保数据已经写入SD卡。当文件被关闭时,flush()会自动运行。语法: file.flush
参数:
peek()
说明:读取当前所在字节,但并不移动到下一个字节。
参数
position( )
说明:获取当前在文件中的位置(即下一个被读/写的字节的位置)。语法:file. position()
参数:
print()
说明:输出数据到文件。要写入的文件应该已经被打开,且等待写入。语法:file. print(data)file. print(data,BASE)
参数:
println()
说明:输出数据到文件,并回车换行。语法:file. println(data)file,println(data,BASE)
参数:
seek()
说明;跳转到指定位置。该位置必须在·到该文件大小之间。语法:file. seek( pos)
参数:
size()
说明:获取文件的大小。语法:filue. size()
参数:
read()
说明:读取1B数据。语法:file.read参数:
write()
说明;写入数据到文件。语法:file. write(data)file. write(buf,len)
参数:
isDirectory()
说明:判断当前文件是否为目录。语法:file.isDirectory()
参数:
openNextFile()
说明:打开下一个文件。语法:file.openNextFile()
参数:
rewindDirectory()
说明:回到当前目录中的第一个文件。语法:file.rewindDirectory()
参数: file,一个File类型的对象。返回值:无。
使用该实例演示ESP32-C3与手机之间的数据传输,如果需要修改或使用数据,只需更改数据接收部分或数据发送部分代码
/*
Video: https://www.youtube.com/watch?v=oCMOYS71NIU
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp
Ported to Arduino ESP32 by Evandro Copercini
Create a BLE server that, once we receive a connection, will send periodic notifications.
The service advertises itself as: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
Has a characteristic of: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E - used for receiving data with "WRITE"
Has a characteristic of: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E - used to send data with "NOTIFY"
The design of creating the BLE server is:
1. Create a BLE Server
2. Create a BLE Service
3. Create a BLE Characteristic on the Service
4. Create a BLE Descriptor on the characteristic
5. Start the service.
6. Start advertising.
*/
/* 该示例演示了蓝牙数据透传,烧录代码,打开串口监视器,打开手机的BLE调试助手
* 1.即可看见ESP32-C3发送的数据--见APP使用图
* 2.通过BLE调试助手的输入框可向ESP32-C3发送数据--见APP使用图
* 该示例由BLE_uart示例更改而来
*/
#include
#include
#include
#include
BLEServer *pServer = NULL;
BLECharacteristic * pTxCharacteristic;
bool deviceConnected = false;
uint8_t txValue = 0;
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
//蓝牙连接/断开处理。当有连接/断开事件发生时自动触发
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) { //当蓝牙连接时会执行该函数
Serial.println("蓝牙已连接");
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) { //当蓝牙断开连接时会执行该函数
Serial.println("蓝牙已断开");
deviceConnected = false;
delay(500); // give the bluetooth stack the chance to get things ready
pServer->startAdvertising(); // restart advertising
}
};
/****************数据接收部分*************/
/****************************************/
//蓝牙接收数据处理。当收到数据时自动触发
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();//接收数据,并赋给rxValue
//if(rxValue == "ON"){Serial.println("开灯");} //判断接收的字符是否为"ON"
if (rxValue.length() > 0) {
Serial.println("*********");
Serial.print("Received Value: ");
for (int i = 0; i < rxValue.length(); i++){
Serial.print(rxValue[i]);
}
Serial.println();
Serial.println("*********");
}
}
};
/***************************************/
/****************************************/
void setup() {
Serial.begin(115200);
BLEBegin(); //初始化蓝牙
}
void loop() {
/****************数据发送部分*************/
/****************************************/
if (deviceConnected) { //如果有蓝牙连接,就发送数据
pTxCharacteristic->setValue("Hello"); //发送字符串
pTxCharacteristic->notify();
delay(10); // bluetooth stack will go into congestion, if too many packets are sent
pTxCharacteristic->setValue("DFRobot"); //发送字符串
pTxCharacteristic->notify();
delay(10); // bluetooth stack will go into congestion, if too many packets are sent
}
/****************************************/
/****************************************/
}
void BLEBegin(){
// Create the BLE Device
BLEDevice::init(/*BLE名称*/"UART Service");
// Create the BLE Server
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create a BLE Characteristic
pTxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY
);
pTxCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic * pRxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_WRITE
);
pRxCharacteristic->setCallbacks(new MyCallbacks());
// Start the service
pService->start();
// Start advertising
pServer->getAdvertising()->start();
Serial.println("Waiting a client connection to notify...");
}
Copy
使用该实例演示ESP32-C3与ESP32-C3之间的数据传输,如果需要修改或使用数据,只需更改数据接收部分或数据发送部分代码
主机代码
/**
* A BLE client example that is rich in capabilities.
* There is a lot new capabilities implemented.
* author unknown
* updated by chegewara
*/
#include "BLEDevice.h"
//#include "BLEScan.h"
// The remote service we wish to connect to.
static BLEUUID serviceUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b");
// The characteristic of the remote service we are interested in.
static BLEUUID charTXUUID("beb5483e-36e1-4688-b7f5-ea07361b26a8");
static BLEUUID charRXUUID("beb5483f-36e1-4688-b7f5-ea07361b26a8");
static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic* pTXRemoteCharacteristic;
static BLERemoteCharacteristic* pRXRemoteCharacteristic;
static BLEAdvertisedDevice* myDevice;
/****************数据接收部分*************/
/****************************************/
//蓝牙接收数据处理,当收到数据时自动触发
static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) { //传入uint8_t* pData用于存放数据
String BLEData = "";
for(int i = 0; i < length; i++) //
BLEData += (char)pData[i];
Serial.println("*********");
Serial.print("Received Value: ");
Serial.println(BLEData);
Serial.println("*********");
//if(BLEData == "ON"){Serial.println("开灯");} //判断接收的字符是否为"ON"
//Serial.print("Notify callback for characteristic ");
//Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
//Serial.print(" of data length ");
//Serial.println(length);
}
/****************************************/
/****************************************/
//蓝牙连接/断开处理。当有连接/断开事件发生时自动触发
class MyClientCallback : public BLEClientCallbacks {
void onConnect(BLEClient* pclient) {
}
void onDisconnect(BLEClient* pclient) {
connected = false;
Serial.println("onDisconnect");
}
};
/**
* Scan for BLE servers and find the first one that advertises the service we are looking for.
*/
//蓝牙扫描处理事件。当开启扫描时自动触发
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
/**
* Called for each advertising BLE server.
*/
void onResult(BLEAdvertisedDevice advertisedDevice) {
//Serial.print("BLE Advertised Device found: ");
//Serial.println(advertisedDevice.toString().c_str());
// We have found a device, let us now see if it contains the service we are looking for.
if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {
BLEDevice::getScan()->stop();
myDevice = new BLEAdvertisedDevice(advertisedDevice);
doConnect = true;
doScan = true;
} // Found our server
} // onResult
}; // MyAdvertisedDeviceCallbacks
void setup() {
Serial.begin(115200);
Serial.println("Starting Arduino BLE Client application...");
bleBegin();
}
void loop() {
// If the flag "doConnect" is true then we have scanned for and found the desired
// BLE Server with which we wish to connect. Now we connect to it. Once we are
// connected we set the connected flag to be true.
if (doConnect == true) {
if (connectToServer()) {
Serial.println("We are now connected to the BLE Server.");
} else {
Serial.println("We have failed to connect to the server; there is nothin more we will do.");
}
doConnect = false;
}
/****************数据发送部分*************/
/****************************************/
if (connected) { //当连接到蓝牙从机时发送数据
pTXRemoteCharacteristic->writeValue("我是主机");
pTXRemoteCharacteristic->writeValue("Hello client");
}
if(!connected){ //当没有连接到蓝牙从机时重新扫描
BLEDevice::getScan()->start(5,false); // this is just example to start scan after disconnect, most likely there is better way to do it in arduino
}
/****************************************/
/****************************************/
delay(1000);
}
void bleBegin()
{
BLEDevice::init("");
// Retrieve a Scanner and set the callback we want to use to be informed when we
// have detected a new device. Specify that we want active scanning and start the
// scan to run for 5 seconds.
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());//扫描处理函数
pBLEScan->setInterval(1349);//设置扫描间隔时间
pBLEScan->setWindow(449);//主动扫描时间
pBLEScan->setActiveScan(true);
pBLEScan->start(5, false);//扫描时间,单位秒
}
//蓝牙连接处理
bool connectToServer() {
Serial.print("Forming a connection to ");
Serial.println(myDevice->getAddress().toString().c_str());
BLEClient* pClient = BLEDevice::createClient();
Serial.println(" - Created client");
pClient->setClientCallbacks(new MyClientCallback());
// Connect to the remove BLE Server.
pClient->connect(myDevice); // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
Serial.println(" - Connected to server");
pClient->setMTU(517); //set client to request maximum MTU from server (default is 23 otherwise)
// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService == nullptr) {
Serial.print("Failed to find our service UUID: ");
Serial.println(serviceUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Found our service");
// Obtain a reference to the characteristic in the service of the remote BLE server.
pTXRemoteCharacteristic = pRemoteService->getCharacteristic(charTXUUID);
if (pTXRemoteCharacteristic == nullptr) {
Serial.print("Failed to find our characteristic UUID: ");
Serial.println(charTXUUID.toString().c_str());
pClient->disconnect();
return false;
}
pRXRemoteCharacteristic = pRemoteService->getCharacteristic(charRXUUID);
if (pRXRemoteCharacteristic == nullptr) {
Serial.print("Failed to find our characteristic UUID: ");
Serial.println(charRXUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Found our characteristic");
if(pRXRemoteCharacteristic->canNotify())
pRXRemoteCharacteristic->registerForNotify(notifyCallback);
connected = true;
return true;
}
Copy
从机代码
/*
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleServer.cpp
Ported to Arduino ESP32 by Evandro Copercini
updates by chegewara
*/
#include
#include
#include
#include
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID_RX "beb5483e-36e1-4688-b7f5-ea07361b26a8"
#define CHARACTERISTIC_UUID_TX "beb5483f-36e1-4688-b7f5-ea07361b26a8"
uint8_t txValue = 0;
bool deviceConnected = false;
BLECharacteristic *pTxCharacteristic;
//蓝牙连接/断开处理。当有连接/断开事件发生时自动触发
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) { //当蓝牙连接时会执行该函数
Serial.println("蓝牙已连接");
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) { //当蓝牙断开连接时会执行该函数
Serial.println("蓝牙已断开");
deviceConnected = false;
delay(500); // give the bluetooth stack the chance to get things ready
BLEDevice::startAdvertising(); // restart advertising
}
};
/****************数据接收部分*************/
/****************************************/
//蓝牙接收数据处理。当收到数据时自动触发
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue(); //使用rxValue接收数据
//if(rxValue == "ON"){Serial.println("开灯");} //判断接收的字符是否为"ON"
if (rxValue.length() > 0) {
Serial.println("*********");
Serial.print("Received Value: ");
for (int i = 0; i < rxValue.length(); i++)
Serial.print(rxValue[i]); //将接收的数据打印出来
Serial.println();
Serial.println("*********");
}
}
};
/****************************************/
/****************************************/
void setup() {
Serial.begin(115200);
Serial.println("Starting BLE work!");
bleBegin();
}
/****************数据发送部分*************/
/****************************************/
void loop() {
if(deviceConnected){ //当有设备连接时发送数据
pTxCharacteristic->setValue("我是从机");
pTxCharacteristic->notify();
pTxCharacteristic->setValue("Hello Sever");
pTxCharacteristic->notify();
}
/****************************************/
/****************************************/
delay(1000);
}
void bleBegin()
{
BLEDevice::init(/*BLE名称*/"Long name works now");
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
BLEService *pService = pServer->createService(SERVICE_UUID);
BLECharacteristic *pRxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_WRITE
);
pRxCharacteristic->setCallbacks(new MyCallbacks());
pTxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY
);
pTxCharacteristic->addDescriptor(new BLE2902());
pService->start();
// BLEAdvertising *pAdvertising = pServer->getAdvertising(); // this still is working for backward compatibility
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
pAdvertising->setMinPreferred(0x12);
BLEDevice::startAdvertising();
}
Copy
ESP32C3具有WIFI功能,以下示例使用ESP32C3创建了一个wifi服务器,使用客户端连接到该服务器,控制LED的亮灭
1.连接到WIFI”Beetle ESP32 C3“,已设置WIFI密码:12345678
2.访问网址 http://192.168.4.1/ON 来打开灯 访问 http://192.168.4.1/OFF 来关闭灯
3.在访问后通过点击上下 here 来便捷控制灯的亮灭而不需要输入网址进行
/*
步骤:
1.连接到WIFI”Beetle ESP32 C3“,已设置WIFI密码:12345678
2.访问网址 http://192.168.4.1/ON 来打开灯 访问 http://192.168.4.1/OFF 来关闭灯
3.在访问后通过点击上下 here 来便捷控制灯的亮灭而不需要输入网址进行
*/
#include
#include
#include
#define myLED 10 //设置引脚10为LED引脚
// 设置WIFI名称以及密码
const char *ssid = "Beetle ESP32 C3";//WIFI名称
const char *password = "12345678";//密码
WiFiServer server(80);//网页服务端口默认为80
void setup() {
pinMode(myLED, OUTPUT);
Serial.begin(115200);
Serial.println();
Serial.println("Configuring access point...");
//如果想要无密码开放网络请删除password
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.begin();
Serial.println("Server started");
}
void loop() {
WiFiClient client = server.available(); // 检测等待连接
if (client) { // 检测是否连接
Serial.println("New Client.");
String currentLine = ""; // 创建String变量来保存数据
while (client.connected()) { // 保持连接时一直循环
if (client.available()) { // 检测连接是否有数据
char c = client.read(); // 读取接收的数据
//Serial.write(c); // 打印在串行监视器
if (c == '\n') { // 如果读取的是换行符
//结尾用换行符提醒结束
if (currentLine.length() == 0) {
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
//将字符与here连接
client.print("Click here to turn ON the LED.");
client.print("Click here to turn OFF the LED.");
// HTTP响应为空行
client.println();
// 跳出循环
break;
} else { // 如果有一个换行符就清除变量缓存的数据
currentLine = "";
}
} else if (c != '\r') { // 如果获得回车以外的字符
currentLine += c; // 获得的字符添加到变量末尾
}
// 检查是否获得/ON或者/OFF
if (currentLine.endsWith("/ON")) {
digitalWrite(myLED, HIGH); //得到/ON时打开灯
}
if (currentLine.endsWith("/OFF")) {
digitalWrite(myLED, LOW); //得到/OFF时关闭灯
}
}
}
// 关闭连接
client.stop();
Serial.println("Client Disconnected.");
}
}
Copy
使用手机连接该wifi,通过浏览器访问192.168.4.1,如图所示显示ip地址为192.168.4.1,服务已开启
使用浏览器访问该ip地址得到如下图所示
尝试分别点击链接控制LED吧
WiFiServer server()
说明:设置服务器端口
softAP(ssid,password)
说明:将WiFi配置为AP模式,并设置名称以及密码
参数:
server.available()
说明:检测服务端口是否有连接(WIFI是否连接)
client.connected()
说明:检测连接状态
返回值:true/false
client.available()
说明:检测连接WIFI是否有数据输入
client.read()
说明*:读取WIFI接收数据
currentLine.endsWith()
说明*:检测是否获得括号内容
client.stop()
说明*:断开连接
获取温湿度显示在OLED屏幕上是非常直观有趣的项目,下面你将学会基础的OLED显示以及使用I2C接口获取温湿度传感器数据。
1.您需要先安装SHT3x库
关于如何安装库点击这里
2.接线图
按照上图连接好线拷贝下面代码,您将看见你周围的温湿度状况。
#include
#include //导入字库
//#include
#include
#include
/*
---显示屏硬件I2C接口---
U8G2_R0 不旋转,横向,绘制方向从左到右
U8G2_R1 顺时针旋转90度,绘制方向从上到下
U8G2_R2 顺时针旋转180度,绘制方向从右到左
U8G2_R3 顺时针旋转270度,绘制方向从下到上
U8G2_MIRROR 正常显示镜像内容(v2.6.x版本以上使用) 注意:U8G2_MIRROR需要与setFlipMode()配搭使用.
U8x8_PIN_NONE 表示引脚为空,不会使用复位引脚
---显示屏硬件SPI接口---
cs 按引脚接上即可(引脚可自己选择)
dc 按引脚接上即可(引脚可自己选择)
*/
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(/* rotation=*/U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//当ADR接VDD时可选择0x45当ADR接GND时可选择0x44
//默认为0x45,RST(复位脚)不用连接
DFRobot_SHT3x sht3x(&Wire,/*address=*/0x45,/*RST=*/4);
//使用SPI需要注释上方代码,使用下方代码
//DFRobot_SHT3x sht3x;
void setup() {
Serial.begin(115200);
u8g2.begin();
u8g2.setFontPosTop();//使用drawStr显示字符串时,默认标准为显示字符的左下角坐标。本函数的功能可理解为将坐标位置改为显示字符串的左上角为坐标标准。
//初始化传感器
while (sht3x.begin() != 0) {
Serial.println("Failed to Initialize the chip, please confirm the wire connection");
delay(1000);
}
Serial.print("Chip serial number");
Serial.println(sht3x.readSerialNumber());
if(!sht3x.softReset()){
Serial.println("Failed to Initialize the chip....");
}
}
void loop() {
//清理屏幕
u8g2.clearBuffer();
//将温度、湿度读取赋值用于显示
float temp = sht3x.getTemperatureC();
float humi = sht3x.getHumidityRH();
//显示温度
u8g2.setFont(u8g2_font_osb18_tf); // 选择字体以及大小(见官方)
u8g2.drawStr(5,10,"Temp");//在指定位置写出字符
u8g2.setFont(u8g2_font_t0_18b_tr);
u8g2.setCursor(75, 15);//显示从该位置开始
u8g2.print(temp);
//显示湿度
u8g2.setFont(u8g2_font_osb18_tf);
u8g2.drawStr(5,40,"Humi");
u8g2.setFont(u8g2_font_t0_18b_tr);
u8g2.setCursor(75, 45);
u8g2.print(humi);
u8g2.sendBuffer();
delay(1000);
}
Copy
u8g2.drawStr(x,y,"Temp")
说明:指定屏幕位置显示自定义内容
参数:
u8g2.setCursor(x,y)和u8g2.print()
说明:搭配使用,前者为显示开始位置,后者同Arduino的print相同作用
参数:
本示例参照示例8.3而来,进一步学会局域网下Wifi的信息传递,你可以学会如何访问局域网下的IP地址来获得在另一处的SHT30的温湿度传感器状态
您还需要按照示例9.1中步骤安装传感器库以及将其与ESP32连接。
1.连接到WIFI”Beetle ESP32 C3“,已设置WIFI密码:12345678
2.访问网址 http://192.168.4.1/GET 来获取局域网中的温湿度信息
3.在温湿度显示网页您可以通过刷新来更新传感器的数据
/*
本示例是SHT30连接上ESPC3通过局域网获取温湿度
*/
#include
#include
#include
#include
//当ADR接VDD时可选择0x45当ADR接GND时可选择0x44
//默认为0x45,RST(复位脚)不用连接
DFRobot_SHT3x sht3x(&Wire,/*address=*/0x45,/*RST=*/4);
//使用SPI需要注释上方代码,使用下方代码
//DFRobot_SHT3x sht3x;
// 设置WIFI名称以及密码
const char *ssid = "Beetle ESP32 C3";//WIFI名称
const char *password = "12345678";//密码
WiFiServer server(80);//网页服务端口默认为80
// 显示上次传感器状态反馈状态
void setup() {
//pinMode(myLED, OUTPUT);
Serial.begin(115200);
Serial.println();
Serial.println("Configuring access point...");
//如果想要无密码开放网络请删除password
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.begin();
Serial.println("Server started");
//初始化传感器
while (sht3x.begin() != 0) {
Serial.println("Failed to Initialize the chip, please confirm the wire connection");
delay(1000);
}
Serial.print("Chip serial number");
Serial.println(sht3x.readSerialNumber());
if(!sht3x.softReset()){
Serial.println("Failed to Initialize the chip....");
}
}
void loop() {
WiFiClient client = server.available(); // 检测等待连接
if (client) { // 检测是否连接
Serial.println("New Client.");
String currentLine = ""; // 创建String变量来保存数据
while (client.connected()) { // 保持连接时一直循环
if (client.available()) { // 检测连接是否有数据
char c = client.read(); // 读取接收的数据
//Serial.write(c); // 打印在串行监视器
if (c == '\n') { // 如果读取的是换行符
//清除掉缓存的内容
if (currentLine.length() == 0) {
client.print(" ");
break;
} else { // 如果有一个换行符就清除变量缓存的数据
currentLine = "";
}
} else if (c != '\r') { // 如果获得回车以外的字符
currentLine += c; // 获得的字符添加到变量末尾
}
// 检查是否有/GET在末尾
if (currentLine.endsWith("/GET")) {
//把温度、湿度读出
float temp = sht3x.getTemperatureC();
float humi = sht3x.getHumidityRH();
//打印在网页
client.print("temp (C): "); client.println(temp);
client.print("humi (%RH): "); client.println(humi);
}
}
}
// 关闭连接
client.stop();
Serial.println("Client Disconnected.");
}
}
Copy
您可以通过手机,电脑等访问网址以获得如下结果(局域网下的温湿度传感器的温湿度)。
WiFi.softAP(ssid, password)
说明:类似将设置好的WIFI账号密码开热点
参数:
WiFi.softAPIP()
说明:WIFI的IP地址
本实例演示了从网络时间服务器获取时间,并使用ESP32自带的RTC时钟保持时间更新
本示例来自CSDN博主「Naisu Xu」,原文链接:https://blog.csdn.net/Naisu_kun/article/details/115627629
#include
const char *ssid = "********"; //WIFI名称
const char *password = "********"; //WIFI密码
const char *ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 8 * 3600;
const int daylightOffset_sec = 0;
void printLocalTime()
{
struct tm timeinfo;
if (!getLocalTime(&timeinfo))
{
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%F %T %A"); // 格式化输出
}
void setup()
{
Serial.begin(115200);
Serial.println();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected!");
// 从网络时间服务器上获取并设置时间
// 获取成功后芯片会使用RTC时钟保持时间的更新
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime();
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
Serial.println("WiFi disconnected!");
}
void loop()
{
delay(1000);
printLocalTime();
}
Copy
struct tm结构体
struct tm {
int tm_sec; // 秒,取值0~59;
int tm_min; // 分,取值0~59;
int tm_hour; // 时,取值0~23;
int tm_mday; // 月中的日期,取值1~31;
int tm_mon; // 月,取值0~11;
int tm_year; // 年,其值等于实际年份减去1900;
int tm_wday; // 星期,取值0~6,0为周日,1为周一,依此类推;
int tm_yday; // 年中的日期,取值0~365,0代表1月1日,1代表1月2日,依此类推;
int tm_isdst; // 夏令时标识符,实行夏令时的时候,tm_isdst为正;不实行夏令时的进候,tm_isdst为0;不了解情况时,tm_isdst()为负
};
struct tm结构体格式化输出
格式化字符 | 输出 |
---|---|
%a | 星期几的简写 |
%A | 星期几的全称 |
%b | 月份的简写 |
%B | 月份的全称 |
%c | 标准的日期的时间串 |
%C | 年份的后两位数字 |
%d | 十进制表示的每月的第几天 |
%D | 月/天/年 |
%e | 在两字符域中,十进制表示的每月的第几天 |
%F | 年-月-日 |
%g | 年份的后两位数字,使用基于周的年 |
%G | 年分,使用基于周的年 |
%h | 简写的月份名 |
%H | 24小时制的小时 |
%I | 12小时制的小时 |
%j | 十进制表示的每年的第几天 |
%m | 十进制表示的月份 |
%M | 十时制表示的分钟数 |
%p | 本地的AM或PM的等价显示 |
%r | 12小时的时间 |
%R | 显示小时和分钟:hh:mm |
%S | 十进制的秒数 |
%t | 水平制表符 |
%T | 显示时分秒:hh:mm:ss |
%u | 每周的第几天,星期一为第一天 (值从0到6,星期一为0) |
%U | 第年的第几周,把星期日做为第一天(值从0到53) |
%V | 每年的第几周,使用基于周的年 |
%w | 十进制表示的星期几(值从0到6,星期天为0) |
%W | 每年的第几周,把星期一做为第一天(值从0到53) |
%x | 标准的日期串 |
%X | 标准的时间串 |
%y | 不带世纪的十进制年份(值从0到99) |
%Y | 带世纪部分的十进制年份 |
%z | 时区名称,如果不能得到时区名称则返回空字符 |
本示例用于让你学会如何获取天气信息并让你体会HTTP中获取的信息通过Json提取数据并打印的
1.您需要安装Arduino_JSON库。通过 Arduino IDE Tools -> Manage Libraries 中输入 Arduino_JSON 并安装该库
2.注册OpenWeather的账号以获取我们想要的天气信息 打开浏览器并转到 https://openweathermap.org/appid/ 按注册按钮并创建一个免费帐户。
点击 My API Keys 进入获取API界面
复制这里的Key(这个Key是你从OpenWeather上获取天气信息的唯一钥匙)
你可以将Key填入以下URL并填写城市名以及它的国家以获取城市天气信息
http://api.openweathermap.org/data/2.5/weather?q=yourCityName,yourCountryCode&APPID=yourAPIkey
下面做个示例更换yourCityName你想要的数据的城市(比如成都),yourCountryCode与该城市的国家代码(比如CN),填入yourAPIkey就是前面获得的API密钥,下面为中国成都加上API后的URL:
http://api.openweathermap.org/data/2.5/weather?q=ChengDu,CN&APPID=4de305d0a52ddaceaecba50a757e9968
将你的 URL 复制到您的浏览器中将返回一组与您当地天气相对应的信息。编写本教程的那天,我们获得了以下有关中国成都的天气的信息。
/*
该示例通过学习以了解如何获得天气信息
*/
#include
#include
#include
//修改WIFI名称以及密码
const char* ssid = "******";//WIFI名称
const char* password = "******";//WIFI密码
//填入你获得的API Key
String openWeatherMapApiKey = "4de305d0a52ddaceaecba50a757e9968";
//示例:
//String openWeatherMapApiKey = "4de305d0a52ddaceaecba50a757e9968";
// 填写你的城市名以及国家简写
String city = "ChengDu";
String countryCode = "CN";
//示例:
//String city = "ChengDu";
//String countryCode = "CN";
//设置获取信息的间隔时间,以下用于测试所以设置为10秒
//您应当根据你需要获取数据的网站,规定时间内访问数据的次数上限来限制访问时间的最小间隔
unsigned long lastTime = 0;
//设置每10分钟获得一次天气数据
//unsigned long timerDelay = 600000;
//设置每10秒获得一次天气数据
unsigned long timerDelay = 10000;
String jsonBuffer;
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("Connecting");
//判断WIFI是否连接
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
Serial.println("Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.");
}
void loop() {
//发送HTTP获取请求
if ((millis() - lastTime) > timerDelay) {
//检测WIFI是否已经连接
if(WiFi.status()== WL_CONNECTED){
String serverPath = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "," + countryCode + "&APPID=" + openWeatherMapApiKey;
//将组合好的URL放入httpGETRequest函数中通过HTTP获取请求以获得文本
jsonBuffer = httpGETRequest(serverPath.c_str());
Serial.println(jsonBuffer);
//将解析的Json对象值储存在Jsonu缓冲区中
JSONVar myObject = JSON.parse(jsonBuffer);
//判断解析是否成功
if (JSON.typeof(myObject) == "undefined") {
Serial.println("Parsing input failed!");
return;
}
Serial.print("JSON object = ");
Serial.println(myObject);
Serial.print("Temperature: ");
//获取到的温度其实是开氏度。
//开氏度 = 摄氏度+273.15
double c = myObject["main"]["temp"];
c = c-273.15;
Serial.println(c);
Serial.print("Pressure: ");
//myObject["main"]["pressure"]前为{}前的引号内容,后为读取哪一个引号后数据
Serial.println(myObject["main"]["pressure"]);
Serial.print("Humidity: ");
Serial.println(myObject["main"]["humidity"]);
Serial.print("Wind Speed: ");
Serial.println(myObject["wind"]["speed"]);
}
else {
Serial.println("WiFi Disconnected");
}
lastTime = millis();
}
}
String httpGETRequest(const char* serverName) {
WiFiClient client;
HTTPClient http;
//连接网址
http.begin(client, serverName);
//发送HTTP站点请求
int httpResponseCode = http.GET();
//该数组用于储存获得的数据
String payload = "{}";
//将获得的数据放入数组
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
payload = http.getString();
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
//释放资源
http.end();
//返回获得的数据用于Json处理
return payload;
}
Copy
httpGETRequest(serverPath.c_str());
说明:解析获取的对象
JSON.typeof(myObject)
说明:判断对象是否为已被解析的格式
阿里云IoT致力于实现万物互联的美好世界,为生态合作伙伴提供基于云端一体化、安全物联网基础平台等,在通过该平台高效连接,管理设备的同时,其开放能力使合作伙伴更高效、低成本地构建各种创新的物联网应用场景。 阿里云物联网平台为设备提供安全可靠的连接通信能力,向下连接海量设备,支撑设备数据采集上云;向上提供云端API,指令数据通过API调用下发至设备端,实现远程控制。 此外阿里云IoT还提供了丰富的开发服务,用户可以直接在该平台上搭建Web可视化、移动应用、服务开发等开发服务,这降低了物联网项目开发的难度,有了它,用户无需任何专业的开发技巧也可开发自己的项目。
点击下载DFRobot_Iot库
通过该代码可使用乐鑫的ESP-TOUCH进行一键配网。
点击下载安卓版
IOS版请在App Store搜索Espressif Esptouch
#include
void SmartConfig()
{
WiFi.mode(WIFI_STA);
Serial.println("\r\nWait for Smartconfig...");
WiFi.beginSmartConfig();
while (1)
{
Serial.print(".");
delay(500); // wait for a second
if (WiFi.smartConfigDone())
{
Serial.println("SmartConfig Success");
Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str());
Serial.printf("PSW:%s\r\n", WiFi.psk().c_str());
break;
}
}
}
bool AutoConfig()
{
WiFi.begin();
for (int i = 0; i < 20; i++)
{
int wstatus = WiFi.status();
if (wstatus == WL_CONNECTED)
{
Serial.println("WIFI SmartConfig Success");
Serial.printf("SSID:%s", WiFi.SSID().c_str());
Serial.printf(", PSW:%s\r\n", WiFi.psk().c_str());
Serial.print("LocalIP:");
Serial.print(WiFi.localIP());
Serial.print(" ,GateIP:");
Serial.println(WiFi.gatewayIP());
return true;
}
else
{
Serial.print("WIFI AutoConfig Waiting......");
Serial.println(wstatus);
delay(1000);
}
}
Serial.println("WIFI AutoConfig Faild!" );
return false;
}
void setup() {
Serial.begin(115200);
delay(100);
if (!AutoConfig())
{
SmartConfig();
}
}
void loop() {
}
Copy
原因
如果Loop中延时过短或者不加延时会导致烧录超时
错误的调用一些函数会导致计算机不能识别USB
解决办法
解决办法
更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !