1.触摸中断和外部中断

  1. // 定义外部中断的Mode
  2. // 0: 无中断,读取Touch值
  3. // 1:Touch中断,执行 TouchEvent()
  4. // 2: 外部IO的中断
  5. #define EXT_ISR_MODE 2
  6. void TouchEvent()
  7. {
  8. Serial.printf("Touch Event.\r\n");
  9. }
  10. void PinIntEvent()
  11. {
  12. Serial.printf("PinInt Event.\r\n");
  13. }
  14. void setup()
  15. {
  16. // put your setup code here, to run once:
  17. Serial.begin(115200);
  18. #if 1 == EXT_ISR_MODE
  19. // Pin: T0(GPIO4), 函数指针:TouchEvent, 阈值: 40
  20. touchAttachInterrupt(T0, TouchEvent, 40);
  21. #elif 2 == EXT_ISR_MODE
  22. pinMode(0, INPUT_PULLUP);
  23. attachInterrupt(0, PinIntEvent, FALLING);
  24. #endif
  25. }
  26. void loop()
  27. {
  28. // put your main code here, to run repeatedly:
  29. #if 0 == EXT_ISR_MODE
  30. Serial.printf("touch:%d\r\n", touchRead(T0));
  31. #endif
  32. delay(200);
  33. }

2.定时器

  1. // 函数名称:onTimer()
  2. // 函数功能:中断服务的功能,它必须是一个返回void(空)且没有输入参数的函数
  3. // 为使编译器将代码分配到IRAM内,中断处理程序应该具有 IRAM_ATTR 属性
  4. // https://docs.espressif.com/projects/esp-idf/zh_CN/release-v4.3/esp32/api-reference/storage/spi_flash_concurrency.html
  5. void IRAM_ATTR TimerEvent()
  6. {
  7. Serial.println(interruptCounter++);
  8. if (interruptCounter > 5)
  9. {
  10. interruptCounter = 1;
  11. }
  12. }
  13. void setup()
  14. {
  15. Serial.begin(115200);
  16. // 函数名称:timerBegin()
  17. // 函数功能:Timer初始化,分别有三个参数
  18. // 函数输入:1. 定时器编号(0到3,对应全部4个硬件定时器)
  19. // 2. 预分频器数值(ESP32计数器基频为80M,80分频单位是微秒)
  20. // 3. 计数器向上(true)或向下(false)计数的标志
  21. // 函数返回:一个指向 hw_timer_t 结构类型的指针
  22. timer = timerBegin(0, 80, true);
  23. // 函数名称:timerAttachInterrupt()
  24. // 函数功能:绑定定时器的中断处理函数,分别有三个参数
  25. // 函数输入:1. 指向已初始化定时器的指针(本例子:timer)
  26. // 2. 中断服务函数的函数指针
  27. // 3. 表示中断触发类型是边沿(true)还是电平(false)的标志
  28. // 函数返回:无
  29. timerAttachInterrupt(timer, &TimerEvent, true);
  30. // 函数名称:timerAlarmWrite()
  31. // 函数功能:指定触发定时器中断的计数器值,分别有三个参数
  32. // 函数输入:1. 指向已初始化定时器的指针(本例子:timer)
  33. // 2. 第二个参数是触发中断的计数器值(1000000 us -> 1s)
  34. // 3. 定时器在产生中断时是否重新加载的标志
  35. // 函数返回:无
  36. timerAlarmWrite(timer, 1000000, true);
  37. timerAlarmEnable(timer); // 使能定时器
  38. }
  39. void loop()
  40. {
  41. }

3.PWM

  1. #include <Arduino.h>
  2. #include "../lib/Motor/Motor.h"
  3. int interruptCounter = 0;
  4. hw_timer_t *timer = NULL;
  5. // 绑定的IO
  6. const int Motor_PWM_PinA = 2;
  7. const int Motor_PWM_PinB = 4;
  8. // PWM的通道,共16个(0-15),分为高低速两组,
  9. // 高速通道(0-7): 80MHz时钟,低速通道(8-15): 1MHz时钟
  10. // 0-15都可以设置,只要不重复即可,参考上面的列表
  11. // 如果有定时器的使用,千万要避开!!!
  12. const int Motor_channel_PWMA = 2;
  13. const int Motor_channel_PWMB = 3;
  14. // PWM频率,直接设置即可
  15. int Motor_freq_PWM = 10;
  16. // PWM分辨率,取值为 0-20 之间,这里填写为10,那么后面的ledcWrite
  17. // 这个里面填写的pwm值就在 0 - 2的10次方 之间 也就是 0-1024
  18. int Motor_resolution_PWM = 10;
  19. void IRAM_ATTR TimerEvent()
  20. {
  21. Serial.println(interruptCounter++);
  22. if (interruptCounter > 5)
  23. {
  24. interruptCounter = 1;
  25. }
  26. }
  27. void Motor_Init(void)
  28. {
  29. ledcSetup(Motor_channel_PWMA, Motor_freq_PWM, Motor_resolution_PWM); // 设置通道
  30. ledcSetup(Motor_channel_PWMB, Motor_freq_PWM, Motor_resolution_PWM); // 设置通道
  31. ledcAttachPin(Motor_PWM_PinA, Motor_channel_PWMA); //将 LEDC 通道绑定到指定 IO 口上以实现输出
  32. ledcAttachPin(Motor_PWM_PinB, Motor_channel_PWMB);
  33. }
  34. void PWM_SetDuty(uint16_t DutyA, uint16_t DutyB)
  35. {
  36. ledcWrite(Motor_channel_PWMA, DutyA);
  37. ledcWrite(Motor_channel_PWMB, DutyB);
  38. }
  39. void setup()
  40. {
  41. Serial.begin(115200);
  42. Motor_Init();
  43. timer = timerBegin(0, 80, true);
  44. timerAttachInterrupt(timer, &TimerEvent, true);
  45. timerAlarmWrite(timer, 1000000, true);
  46. timerAlarmEnable(timer); // 使能定时器
  47. }
  48. void loop()
  49. {
  50. PWM_SetDuty(200 * interruptCounter, 200 * interruptCounter);
  51. }

4.WIFI

  1. #include <WiFi.h>
  2. // WiFi的初始化和连接
  3. void WiFi_Connect()
  4. {
  5. WiFi.begin("123456", "1234567891");
  6. while (WiFi.status() != WL_CONNECTED)
  7. { //这里是阻塞程序,直到连接成功
  8. delay(300);
  9. Serial.print(".");
  10. }
  11. }

5.ArduinoJson

  1. #include <HTTPClient.h>
  2. #include <ArduinoJson.h>
  3. // bilibili api: follower
  4. String UID = "247883432";
  5. String followerUrl = "http://api.bilibili.com/x/relation/stat?vmid=" + UID; // 粉丝数
  6. long follower = 0; // 粉丝数
  7. DynamicJsonDocument doc(1024);
  8. // 获取粉丝数
  9. void getBiliBiliFollower()
  10. {
  11. HTTPClient http;
  12. http.begin(followerUrl); //HTTP begin
  13. int httpCode = http.GET();
  14. if (httpCode > 0)
  15. {
  16. // httpCode will be negative on error
  17. Serial.printf("HTTP Get Code: %d\r\n", httpCode);
  18. if (httpCode == HTTP_CODE_OK) // 收到正确的内容
  19. {
  20. String resBuff = http.getString();
  21. // 输出示例:{"mid":123456789,"following":226,"whisper":0,"black":0,"follower":867}}
  22. Serial.println(resBuff);
  23. // 使用ArduinoJson_6.x版本,具体请移步:https://github.com/bblanchon/ArduinoJson
  24. deserializeJson(doc, resBuff); //开始使用Json解析
  25. follower = doc["data"]["follower"];
  26. Serial.printf("Follers: %ld \r\n", follower);
  27. }
  28. }
  29. else
  30. {
  31. Serial.printf("HTTP Get Error: %s\n", http.errorToString(httpCode).c_str());
  32. }
  33. http.end();
  34. }

6.蓝牙

  1. /*
  2. Video: https://www.youtube.com/watch?v=oCMOYS71NIU
  3. Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp
  4. Ported to Arduino ESP32 by Evandro Copercini
  5. Create a BLE server that, once we receive a connection, will send periodic notifications.
  6. 创建一个BLE服务器,一旦我们收到连接,将会周期性发送通知
  7. T使用步骤:
  8. 1. 创建一个 BLE Server
  9. 2. 创建一个 BLE Service
  10. 3. 创建一个 BLE Characteristic
  11. 4. 创建一个 BLE Descriptor
  12. 5. 开始服务
  13. 6. 开始广播
  14. */
  15. #include <Arduino.h>
  16. #include <BLEDevice.h>
  17. #include <BLEServer.h>
  18. #include <BLEUtils.h>
  19. #include <BLE2902.h>
  20. #include "common.h"
  21. uint8_t txValue = 0;
  22. BLEServer *pServer = NULL; //BLEServer指针 pServer
  23. BLECharacteristic *pTxCharacteristic = NULL; //BLECharacteristic指针 pTxCharacteristic
  24. bool deviceConnected = false; //本次连接状态
  25. bool oldDeviceConnected = false; //上次连接状态
  26. // See the following for generating UUIDs: https://www.uuidgenerator.net/
  27. #define SERVICE_UUID "12a59900-17cc-11ec-9621-0242ac130002" // UART service UUID
  28. #define CHARACTERISTIC_UUID_RX "12a59e0a-17cc-11ec-9621-0242ac130002"
  29. #define CHARACTERISTIC_UUID_TX "12a5a148-17cc-11ec-9621-0242ac130002"
  30. class MyServerCallbacks : public BLEServerCallbacks
  31. {
  32. void onConnect(BLEServer *pServer)
  33. {
  34. deviceConnected = true;
  35. };
  36. void onDisconnect(BLEServer *pServer)
  37. {
  38. deviceConnected = false;
  39. }
  40. };
  41. class MyCallbacks : public BLECharacteristicCallbacks
  42. {
  43. void onWrite(BLECharacteristic *pCharacteristic)
  44. {
  45. std::string rxValue = pCharacteristic->getValue(); //接收信息
  46. if (rxValue.length() > 0)
  47. { //向串口输出收到的值
  48. Serial.print("RX: ");
  49. for (int i = 0; i < rxValue.length(); i++)
  50. Serial.print(rxValue[i]);
  51. Serial.println();
  52. }
  53. }
  54. };
  55. void setup()
  56. {
  57. Serial.begin(115200);
  58. // 创建一个 BLE 设备
  59. BLEDevice::init("UART_BLE");
  60. // 创建一个 BLE 服务
  61. pServer = BLEDevice::createServer();
  62. pServer->setCallbacks(new MyServerCallbacks()); //设置回调
  63. BLEService *pService = pServer->createService(SERVICE_UUID);
  64. // 创建一个 BLE 特征
  65. pTxCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY);
  66. pTxCharacteristic->addDescriptor(new BLE2902());
  67. BLECharacteristic *pRxCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE);
  68. pRxCharacteristic->setCallbacks(new MyCallbacks()); //设置回调
  69. pService->start(); // 开始服务
  70. pServer->getAdvertising()->start(); // 开始广播
  71. Serial.println(" 等待一个客户端连接,且发送通知... ");
  72. }
  73. void loop()
  74. {
  75. // deviceConnected 已连接
  76. if (deviceConnected)
  77. {
  78. pTxCharacteristic->setValue(&txValue, 1); // 设置要发送的值为1
  79. pTxCharacteristic->notify(); // 广播
  80. txValue++; // 指针地址自加1
  81. delay(2000); // 如果有太多包要发送,蓝牙会堵塞
  82. }
  83. // disconnecting 断开连接
  84. if (!deviceConnected && oldDeviceConnected)
  85. {
  86. delay(500); // 留时间给蓝牙缓冲
  87. pServer->startAdvertising(); // 重新广播
  88. Serial.println(" 开始广播 ");
  89. oldDeviceConnected = deviceConnected;
  90. }
  91. // connecting 正在连接
  92. if (deviceConnected && !oldDeviceConnected)
  93. {
  94. // do stuff here on connecting
  95. oldDeviceConnected = deviceConnected;
  96. }
  97. }

7.多线程

  1. /*
  2. // 多线程基于FreeRTOS,可以多个任务并行处理;
  3. // ESP32具有两个32位Tensilica Xtensa LX6微处理器;
  4. // 实际上我们用Arduino进行编程时只使用到了第一个核(大核),第0核并没有使用
  5. // 多线程可以指定在那个核运行;
  6. */
  7. #include <Arduino.h>
  8. #define USE_MULTCORE 1
  9. void xTaskOne(void *xTask1)
  10. {
  11. while (1)
  12. {
  13. Serial.printf("Task1 \r\n");
  14. delay(500);
  15. }
  16. }
  17. void xTaskTwo(void *xTask2)
  18. {
  19. while (1)
  20. {
  21. Serial.printf("Task2 \r\n");
  22. delay(1000);
  23. }
  24. }
  25. void setup()
  26. {
  27. Serial.begin(115200);
  28. delay(10);
  29. }
  30. void loop()
  31. {
  32. #if !USE_MULTCORE
  33. xTaskCreate(
  34. xTaskOne, /* Task function. */
  35. "TaskOne", /* String with name of task. */
  36. 4096, /* Stack size in bytes. */
  37. NULL, /* Parameter passed as input of the task */
  38. 1, /* Priority of the task.(configMAX_PRIORITIES - 1 being the highest, and 0 being the lowest.) */
  39. NULL); /* Task handle. */
  40. xTaskCreate(
  41. xTaskTwo, /* Task function. */
  42. "TaskTwo", /* String with name of task. */
  43. 4096, /* Stack size in bytes. */
  44. NULL, /* Parameter passed as input of the task */
  45. 2, /* Priority of the task.(configMAX_PRIORITIES - 1 being the highest, and 0 being the lowest.) */
  46. NULL); /* Task handle. */
  47. #else
  48. //最后一个参数至关重要,决定这个任务创建在哪个核上.PRO_CPU 为 0, APP_CPU 为 1,或者 tskNO_AFFINITY 允许任务在两者上运行.
  49. xTaskCreatePinnedToCore(xTaskOne, "TaskOne", 4096, NULL, 1, NULL, 0);
  50. xTaskCreatePinnedToCore(xTaskTwo, "TaskTwo", 4096, NULL, 2, NULL, 1);
  51. #endif
  52. while (1)
  53. {
  54. Serial.printf("XTask is running\r\n");
  55. delay(1000);
  56. }
  57. }