1.触摸中断和外部中断
// 定义外部中断的Mode// 0: 无中断,读取Touch值// 1:Touch中断,执行 TouchEvent()// 2: 外部IO的中断#define EXT_ISR_MODE 2void TouchEvent(){ Serial.printf("Touch Event.\r\n");}void PinIntEvent(){ Serial.printf("PinInt Event.\r\n");}void setup(){ // put your setup code here, to run once: Serial.begin(115200);#if 1 == EXT_ISR_MODE // Pin: T0(GPIO4), 函数指针:TouchEvent, 阈值: 40 touchAttachInterrupt(T0, TouchEvent, 40);#elif 2 == EXT_ISR_MODE pinMode(0, INPUT_PULLUP); attachInterrupt(0, PinIntEvent, FALLING);#endif}void loop(){ // put your main code here, to run repeatedly:#if 0 == EXT_ISR_MODE Serial.printf("touch:%d\r\n", touchRead(T0));#endif delay(200);}
2.定时器
// 函数名称:onTimer()// 函数功能:中断服务的功能,它必须是一个返回void(空)且没有输入参数的函数// 为使编译器将代码分配到IRAM内,中断处理程序应该具有 IRAM_ATTR 属性// https://docs.espressif.com/projects/esp-idf/zh_CN/release-v4.3/esp32/api-reference/storage/spi_flash_concurrency.htmlvoid IRAM_ATTR TimerEvent(){ Serial.println(interruptCounter++); if (interruptCounter > 5) { interruptCounter = 1; }}void setup(){ Serial.begin(115200); // 函数名称:timerBegin() // 函数功能:Timer初始化,分别有三个参数 // 函数输入:1. 定时器编号(0到3,对应全部4个硬件定时器) // 2. 预分频器数值(ESP32计数器基频为80M,80分频单位是微秒) // 3. 计数器向上(true)或向下(false)计数的标志 // 函数返回:一个指向 hw_timer_t 结构类型的指针 timer = timerBegin(0, 80, true); // 函数名称:timerAttachInterrupt() // 函数功能:绑定定时器的中断处理函数,分别有三个参数 // 函数输入:1. 指向已初始化定时器的指针(本例子:timer) // 2. 中断服务函数的函数指针 // 3. 表示中断触发类型是边沿(true)还是电平(false)的标志 // 函数返回:无 timerAttachInterrupt(timer, &TimerEvent, true); // 函数名称:timerAlarmWrite() // 函数功能:指定触发定时器中断的计数器值,分别有三个参数 // 函数输入:1. 指向已初始化定时器的指针(本例子:timer) // 2. 第二个参数是触发中断的计数器值(1000000 us -> 1s) // 3. 定时器在产生中断时是否重新加载的标志 // 函数返回:无 timerAlarmWrite(timer, 1000000, true); timerAlarmEnable(timer); // 使能定时器}void loop(){}
3.PWM
#include <Arduino.h>#include "../lib/Motor/Motor.h"int interruptCounter = 0;hw_timer_t *timer = NULL;// 绑定的IOconst int Motor_PWM_PinA = 2;const int Motor_PWM_PinB = 4;// PWM的通道,共16个(0-15),分为高低速两组,// 高速通道(0-7): 80MHz时钟,低速通道(8-15): 1MHz时钟// 0-15都可以设置,只要不重复即可,参考上面的列表// 如果有定时器的使用,千万要避开!!!const int Motor_channel_PWMA = 2;const int Motor_channel_PWMB = 3;// PWM频率,直接设置即可int Motor_freq_PWM = 10;// PWM分辨率,取值为 0-20 之间,这里填写为10,那么后面的ledcWrite// 这个里面填写的pwm值就在 0 - 2的10次方 之间 也就是 0-1024int Motor_resolution_PWM = 10;void IRAM_ATTR TimerEvent(){ Serial.println(interruptCounter++); if (interruptCounter > 5) { interruptCounter = 1; }}void Motor_Init(void){ ledcSetup(Motor_channel_PWMA, Motor_freq_PWM, Motor_resolution_PWM); // 设置通道 ledcSetup(Motor_channel_PWMB, Motor_freq_PWM, Motor_resolution_PWM); // 设置通道 ledcAttachPin(Motor_PWM_PinA, Motor_channel_PWMA); //将 LEDC 通道绑定到指定 IO 口上以实现输出 ledcAttachPin(Motor_PWM_PinB, Motor_channel_PWMB);}void PWM_SetDuty(uint16_t DutyA, uint16_t DutyB){ ledcWrite(Motor_channel_PWMA, DutyA); ledcWrite(Motor_channel_PWMB, DutyB);}void setup(){ Serial.begin(115200); Motor_Init(); timer = timerBegin(0, 80, true); timerAttachInterrupt(timer, &TimerEvent, true); timerAlarmWrite(timer, 1000000, true); timerAlarmEnable(timer); // 使能定时器}void loop(){ PWM_SetDuty(200 * interruptCounter, 200 * interruptCounter);}
4.WIFI
#include <WiFi.h>// WiFi的初始化和连接void WiFi_Connect(){ WiFi.begin("123456", "1234567891"); while (WiFi.status() != WL_CONNECTED) { //这里是阻塞程序,直到连接成功 delay(300); Serial.print("."); }}
5.ArduinoJson
#include <HTTPClient.h>#include <ArduinoJson.h>// bilibili api: followerString UID = "247883432";String followerUrl = "http://api.bilibili.com/x/relation/stat?vmid=" + UID; // 粉丝数long follower = 0; // 粉丝数DynamicJsonDocument doc(1024);// 获取粉丝数void getBiliBiliFollower(){ HTTPClient http; http.begin(followerUrl); //HTTP begin int httpCode = http.GET(); if (httpCode > 0) { // httpCode will be negative on error Serial.printf("HTTP Get Code: %d\r\n", httpCode); if (httpCode == HTTP_CODE_OK) // 收到正确的内容 { String resBuff = http.getString(); // 输出示例:{"mid":123456789,"following":226,"whisper":0,"black":0,"follower":867}} Serial.println(resBuff); // 使用ArduinoJson_6.x版本,具体请移步:https://github.com/bblanchon/ArduinoJson deserializeJson(doc, resBuff); //开始使用Json解析 follower = doc["data"]["follower"]; Serial.printf("Follers: %ld \r\n", follower); } } else { Serial.printf("HTTP Get Error: %s\n", http.errorToString(httpCode).c_str()); } http.end();}
6.蓝牙
/* 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. 创建一个BLE服务器,一旦我们收到连接,将会周期性发送通知 T使用步骤: 1. 创建一个 BLE Server 2. 创建一个 BLE Service 3. 创建一个 BLE Characteristic 4. 创建一个 BLE Descriptor 5. 开始服务 6. 开始广播*/#include <Arduino.h>#include <BLEDevice.h>#include <BLEServer.h>#include <BLEUtils.h>#include <BLE2902.h>#include "common.h"uint8_t txValue = 0;BLEServer *pServer = NULL; //BLEServer指针 pServerBLECharacteristic *pTxCharacteristic = NULL; //BLECharacteristic指针 pTxCharacteristicbool deviceConnected = false; //本次连接状态bool oldDeviceConnected = false; //上次连接状态// See the following for generating UUIDs: https://www.uuidgenerator.net/#define SERVICE_UUID "12a59900-17cc-11ec-9621-0242ac130002" // UART service UUID#define CHARACTERISTIC_UUID_RX "12a59e0a-17cc-11ec-9621-0242ac130002"#define CHARACTERISTIC_UUID_TX "12a5a148-17cc-11ec-9621-0242ac130002"class MyServerCallbacks : public BLEServerCallbacks{ void onConnect(BLEServer *pServer) { deviceConnected = true; }; void onDisconnect(BLEServer *pServer) { deviceConnected = false; }};class MyCallbacks : public BLECharacteristicCallbacks{ void onWrite(BLECharacteristic *pCharacteristic) { std::string rxValue = pCharacteristic->getValue(); //接收信息 if (rxValue.length() > 0) { //向串口输出收到的值 Serial.print("RX: "); for (int i = 0; i < rxValue.length(); i++) Serial.print(rxValue[i]); Serial.println(); } }};void setup(){ Serial.begin(115200); // 创建一个 BLE 设备 BLEDevice::init("UART_BLE"); // 创建一个 BLE 服务 pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); //设置回调 BLEService *pService = pServer->createService(SERVICE_UUID); // 创建一个 BLE 特征 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()); //设置回调 pService->start(); // 开始服务 pServer->getAdvertising()->start(); // 开始广播 Serial.println(" 等待一个客户端连接,且发送通知... ");}void loop(){ // deviceConnected 已连接 if (deviceConnected) { pTxCharacteristic->setValue(&txValue, 1); // 设置要发送的值为1 pTxCharacteristic->notify(); // 广播 txValue++; // 指针地址自加1 delay(2000); // 如果有太多包要发送,蓝牙会堵塞 } // disconnecting 断开连接 if (!deviceConnected && oldDeviceConnected) { delay(500); // 留时间给蓝牙缓冲 pServer->startAdvertising(); // 重新广播 Serial.println(" 开始广播 "); oldDeviceConnected = deviceConnected; } // connecting 正在连接 if (deviceConnected && !oldDeviceConnected) { // do stuff here on connecting oldDeviceConnected = deviceConnected; }}
7.多线程
/*// 多线程基于FreeRTOS,可以多个任务并行处理;// ESP32具有两个32位Tensilica Xtensa LX6微处理器;// 实际上我们用Arduino进行编程时只使用到了第一个核(大核),第0核并没有使用// 多线程可以指定在那个核运行; */#include <Arduino.h>#define USE_MULTCORE 1void xTaskOne(void *xTask1){ while (1) { Serial.printf("Task1 \r\n"); delay(500); }}void xTaskTwo(void *xTask2){ while (1) { Serial.printf("Task2 \r\n"); delay(1000); }}void setup(){ Serial.begin(115200); delay(10);}void loop(){#if !USE_MULTCORE xTaskCreate( xTaskOne, /* Task function. */ "TaskOne", /* String with name of task. */ 4096, /* Stack size in bytes. */ NULL, /* Parameter passed as input of the task */ 1, /* Priority of the task.(configMAX_PRIORITIES - 1 being the highest, and 0 being the lowest.) */ NULL); /* Task handle. */ xTaskCreate( xTaskTwo, /* Task function. */ "TaskTwo", /* String with name of task. */ 4096, /* Stack size in bytes. */ NULL, /* Parameter passed as input of the task */ 2, /* Priority of the task.(configMAX_PRIORITIES - 1 being the highest, and 0 being the lowest.) */ NULL); /* Task handle. */#else //最后一个参数至关重要,决定这个任务创建在哪个核上.PRO_CPU 为 0, APP_CPU 为 1,或者 tskNO_AFFINITY 允许任务在两者上运行. xTaskCreatePinnedToCore(xTaskOne, "TaskOne", 4096, NULL, 1, NULL, 0); xTaskCreatePinnedToCore(xTaskTwo, "TaskTwo", 4096, NULL, 2, NULL, 1);#endif while (1) { Serial.printf("XTask is running\r\n"); delay(1000); }}