Arduino学习

引脚配置

void setup {
    pinMode(1, OUTPUT);
    pinMode(2, INPUT);
}
void loop {
    digitalWrite(1, HIGH);
    delay(1000);
    digitalWrite(1, LOW);
    delay(1000);
}

hi

hi

r

Warning

Don’t install PyQt-Fluent-Widgets, PyQt6-Fluent-Widgets, PySide2-Fluent-Widgets and PySide6-Fluent-Widgets at the same time, because their package names are all qfluentwidgets.

串口

void setup {
    Serial.begin(115200);
}
void loop {
    Serial.println("Hello World");
    delay(1000);
}

电容触摸

void TouchEvent(void); // 电容触摸中断处理函数
// T1为pin 1
void setup {
    Serial.begin(115200);

    touchAttachInterrupt(T1, TouchEvent, 18000);
}

void loop {
    // 电容触摸读取值(电容外部中断时不要加这句话)
    Serial.printf("T0: %d\r\n", touchRead(T1));
    delay(200);
}

void TouchEvent(void) {
    Serial.println("Touch event.\r\n");
}

外部中断

#include <Arduino.h>

void PinEvent(); // 外部中断处理函数

void setup() {
    Serial.begin(115200);

    pinMode(1, OUTPUT);
    pinMode(2, INPUT_PULLUP);
    attachInterrupt(2, PinEvent, RISING);
    // detachInterrupt(2); //失能中断
}

void loop() {
    digitalWrite(1, HIGH);
    delay(1000);
    digitalWrite(1, LOW);
    delay(1000);
}

void PinEvent() {
    Serial.println("Pin event.\r\n");
}

定时器

// 如前文所述,在ISR对中断做出响应之后,真正的定时器中断处理操作其实是在主循环中,更有效的处理方式是,使用一个信号量将主循环锁定,然后在ISR中将其解锁。具体操作如下:
// 建议查阅互斥自旋锁
#include <Arduino.h>

volatile int interruptCounter;
int totalInterruptCounter;
hw_timer_t* timer = nullptr;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;

// 函数名称:onTimer()
// 函数功能:中断服务的功能,它必须是一个返回void(空)且没有输入参数的函数,
//    为使编译器将代码分配到IRAM内,中断处理程序应该具有 IRAM_ATTR 属性
void IRAM_ATTR onTimer() {
    portENTER_CRITICAL_ISR(&timerMux);
    interruptCounter++;
    Serial.println("onTimer");
    portEXIT_CRITICAL_ISR(&timerMux);
}
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, &onTimer, true);

    // 函数名称:timerAlarmWrite()
    // 函数功能:指定触发定时器中断的计数器值,分别有三个参数
    // 函数输入:1. 指向已初始化定时器的指针(本例子:timer)
    //    2. 第二个参数是触发中断的计数器值(1000000 us -> 1s)
    //    3. 定时器在产生中断时是否重新加载的标志
    // 函数返回:无
    timerAlarmWrite(timer, 1000000, true);
    timerAlarmEnable(timer);  // 使能定时器
}
void loop() {
    if (interruptCounter > 0) {
        portENTER_CRITICAL(&timerMux);
        interruptCounter--;
        portEXIT_CRITICAL(&timerMux);
        totalInterruptCounter++;
        Serial.print("An interrupt as occurred. Total number: ");
        Serial.println(totalInterruptCounter);
    }
}

SPIFFS

#include <Arduino.h>
#include <SPIFFS.h>

void setup() {
    Serial.begin(115200);

    if (!SPIFFS.begin(true)) {
        Serial.println("An Error has occurred while mounting SPIFFS");
        return;
    }

    File file = SPIFFS.open("/test.txt", FILE_WRITE);
    if (!file) {
        Serial.println("There was an error opening the file for writing");
        return;
    }

    if (file.print("Dolly")) {
        Serial.println("File was written");
    } else {
        Serial.println("File write failed");
    }

    file.close();

    File file = SPIFFS.open("/test.txt");
    if (!file) {
        Serial.println("Failed to open file for reading");
        return;
    }

    Serial.println("File Content:");
    while (file.available()) {
        Serial.write(file.read());
    }
    file.close();
}