25/1/14 嵌入式笔记 学习ESP32

Wi-Fi

相关函数

#include<WiFi.h>

//定义WiFi 名与密码
const char *ssid = "青椒大仙";
const char *password = "11111111";

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

  //连接WiFi
  WiFi.begin(ssid,password);

  Serial.print("正在连接 Wi-Fi");

  //检测是否连接成功
  while(WiFi.status() != WL_CONNECTED){
    delay(500);
    Serial.print(".");
  }
  Serial.println("连接成功");
  Serial.print("IP 地址:");
  Serial.println(WiFi.localIP());
}

创建热点

#include<WiFi.h>

//设置名称
const char* ssid="ESP32_AP";
const char* password="123456qq.";
void setup(){
  Serial.begin(9600);

  //创建热点
  WiFi.softAP(ssid,password);

  //打印 热点IP
  Serial.print("Wi-Fi 接入的IP:");
  Serial.println(WiFi.softAPIP());


}
void loop(){

}

获取网络请求

HTTPClient库

通过HTTP请求从天气API获取指定城市的天气数据

#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>

// 设置名称
const char* ssid = "青椒大仙";
const char* password = "11111111";
String url = "http://apis.juhe.cn/simpleWeather/query";
String city = "江苏";
String key = "a702b975fa48a063bla57c938bafb47a";

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

  // 连接Wi-Fi
  WiFi.begin(ssid, password);

  Serial.print("正在连接WiFi.");

  // 检测是否连接成功
  unsigned long startTime = millis();
  while (WiFi.status() != WL_CONNECTED && millis() - startTime < 10000) {
    delay(500);
    Serial.print(".");
  }
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("Wi-Fi 连接失败");
    return;
  }
  Serial.println("连接成功");

  // 创建HTTPClient对象
  HTTPClient http;

  // 指定访问URL
  http.begin(url + "?city=" + city + "&key=" + key);

  // 接受HTTP响应状态码
  int http_code = http.GET();
  Serial.printf("HTTP状态码:%d\n", http_code);

  if (http_code == HTTP_CODE_OK) {
    // 获取响应正文
    String response = http.getString();
    Serial.print("响应数据:");
    Serial.println(response);

    // 创建DynamicJsonDocument对象
    DynamicJsonDocument doc(1024);

    // 解析Json数据
    deserializeJson(doc, response);

    // 从解析的Json数据中获取值
    unsigned int temp = doc["result"]["realtime"]["temperature"].as<unsigned int>();
    String info = doc["result"]["realtime"]["info"].as<String>();
    int api = doc["result"]["realtime"]["aqi"].as<int>();

    Serial.printf("温度:%d, 天气:%s, 空气指数:%d\n", temp, info.c_str(), api);
  } else {
    Serial.println("HTTP 请求失败");
  }

  // 关闭连接
  http.end();
}

void loop() {
  // 主循环无需操作
}

ULN2003控制步进电机

#define IN_1 13
#define IN_2 12
#define IN_3 14
#define IN_4 27

int delay_time = 2;
int step = 2048/4*degree/360;
int degree = 180;

void setup(){
  //设置输出模式
  pinMode(IN_1,OUTPUT);
  pinMode(IN_2,OUTPUT);
  pinMode(IN_3,OUTPUT);
  pinMode(IN_4,OUTPUT);
  
  //单四拍模式
  for(int i =0;i<50;i++){
    digitalWrite(IN_1,1);
    digitalWrite(IN_2,0);
    digitalWrite(IN_3,0);
    digitalWrite(IN_4,0);
    delay(delay_time);

    digitalWrite(IN_1,0);
    digitalWrite(IN_2,1);
    digitalWrite(IN_3,0);
    digitalWrite(IN_4,0);
    delay(delay_time);

    digitalWrite(IN_1,0);
    digitalWrite(IN_2,0);
    digitalWrite(IN_3,1);
    digitalWrite(IN_4,0);
    delay(delay_time);

    digitalWrite(IN_1,0);
    digitalWrite(IN_2,0);
    digitalWrite(IN_3,0);
    digitalWrite(IN_4,1);
    delay(delay_time);
  }
  //复位
  digitalWrite(IN_1,0);
  digitalWrite(IN_2,0);
  digitalWrite(IN_3,0);
  digitalWrite(IN_4,0);
}

第三方库控制电机

#include <CheapStepper.h>

//创建对象
CheapSteper stepper(13,12,14,27);

bool moveClockwise = true;

void setup(){
  //设置转速
  stepper.setRpm(10);

  //根据步数旋转
  stepper.moveTo(moveClockwise,2048);
  delay(1000);

  //根据角度旋转
  stepper.moveDegrees(moveClockwise,90);
} 
void loop(){

}

双轴遥感控制电机

#define PS2_X 15 PS2遥感的X轴和Y轴引脚    
#define PS2_Y 2  
#define SW    4 PS2摇杆的按钮引脚
#define RESOLUTION 12 分辨率
#define CHANNEL 0 LEDC通道编号
#define FREQ 50  PWM频率
#define SERVO 13 // 假设舵机连接在 GPIO 13

int min_width, max_width; //舵机的最小和最大占空比
int value;          //存储映射后的 PWM 占空比。

void setup() {
  // 配置输入模式
  pinMode(PS2_X, INPUT);
  pinMode(PS2_Y, INPUT);
  pinMode(SW, INPUT_PULLUP);

  // 配置串口通信波特率
  Serial.begin(9600); 初始化串口通信

  // 计算最小和最大占空比
  min_width = 0.6 / 20.0 * pow(2, RESOLUTION);
  max_width = 2.5 / 20.0 * pow(2, RESOLUTION);

  // 设置LEDC通道的频率和分辨率
  ledcSetup(CHANNEL, FREQ, RESOLUTION);
  // 关联通道号与GPIO引脚
  ledcAttachPin(SERVO, CHANNEL);
}

void loop() {
  int y_value = analogRead(PS2_Y);  //读取PS2遥感Y轴的模拟值
  if (abs(y_value - 2048) < 100) { // 死区处理
    y_value = 2048; // 中间位置
  }
  value = map(y_value, 0, 4095, min_width, max_width);

  // 读取数值
  Serial.printf("x: %d, y: %d, z: %d, 映射后的 y: %d\n", analogRead(PS2_X),
                y_value, digitalRead(SW), value);

  // 输出PWM,控制舵机
  ledcWrite(CHANNEL, value);

  delay(100);
}

第三方库控制

#include <ESP32PWM.h>
#include <Servo.h>

#define PS2_X 15
#define PS2_Y 2
#define SW    4
#define RESOLUTION 12
#define FREQ 50
#define SERVO 13

Servo my_servo;
int value;

void setup() {
  pinMode(PS2_X, INPUT);
  pinMode(PS2_Y, INPUT);
  pinMode(SW, INPUT_PULLUP);

  // 配置串口通信波特率
  Serial.begin(9600);

  // 分配硬件定时器
  ESP32PWM::allocateTimer(0);
  // 设置频率
  my_servo.setPeriodHertz(FREQ);
  // 关联servo对象与GPIO引脚,设置脉宽范围
  my_servo.attach(SERVO, 500, 2500);
}

void loop() {
  int y_value = analogRead(PS2_Y);
  if (abs(y_value - 2048) < 100) { // 死区处理
    y_value = 2048; // 中间位置
  }
  value = map(y_value, 0, 4095, 0, 180);

  // 读取数值
  Serial.printf("x: %d, y: %d, z: %d, 映射后的 y: %d\n", analogRead(PS2_X),
                y_value, digitalRead(SW), value);

  // 输出PWM
  my_servo.write(value);

  delay(100);
}

脉宽决定了舵机的转动角度,舵机的控制信号是一个周期为20ms的PWM信号的最小脉宽和最大脉宽。

  • 最小脉宽(如 500 µs):对应舵机的最小角度(通常为 0°)。

  • 最大脉宽(如 2500 µs):对应舵机的最大角度(通常为 180°)。

  • 中间脉宽(如 1500 µs):对应舵机的中间角度(通常为 90°)。

设置脉宽范围的作用

  • 适配不同舵机代码

    • 不同品牌或型号的舵机可能对脉宽范围的要求不同。通过设置脉宽范围,可以适配多种舵机。

  • 校准舵机角度

    • 如果舵机的实际转动范围与理论值不符,可以通过调整脉宽范围进行校准。

  • 限制舵机转动范围

    • 设置脉宽范围可以限制舵机的转动范围,避免舵机转动到极限位置时产生过大的机械应力

8*8点阵屏

// 定义行引脚数组
int row_array[8] = {13, 25, 2, 27, 23, 4, 22, 18};
// 定义列引脚数组
int col_array[8] = {26, 21, 19, 12, 5, 14, 33, 32};

void setup() {
  // 配置行引脚,初始化为高电平
  for (int i = 0; i < 8; i++) {
    pinMode(row_array[i], OUTPUT);
    digitalWrite(row_array[i], HIGH);
  }

  // 配置列引脚,初始化为低电平
  for (int i = 0; i < 8; i++) {
    pinMode(col_array[i], OUTPUT);
    digitalWrite(col_array[i], HIGH); // 初始化为高电平(关闭 LED)
  }
}

void loop() {
  // 遍历所有的LED
  for (int i = 0; i < 8; i++) {
    digitalWrite(row_array[i], LOW); // 激活当前行
    for (int j = 0; j < 8; j++) {
      digitalWrite(col_array[j], LOW); // 点亮 LED
      delay(1); // 短暂延时
      digitalWrite(col_array[j], HIGH); // 关闭 LED
    }
    digitalWrite(row_array[i], HIGH); // 关闭当前行
  }
}

点阵屏显示图案

// 定义图案逻辑数组
int hex_array[8] = {0x00, 0x66, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18};

// 定义行引脚数组
int row_array[8] = {13, 25, 2, 27, 23, 4, 22, 18};
// 定义列引脚数组
int col_array[8] = {26, 21, 19, 12, 5, 14, 33, 32};

void setup() {
  // 设置串口波特率
  Serial.begin(9600);

  // 配置行引脚,初始化为高电平
  for (int i = 0; i < 8; i++) {
    pinMode(row_array[i], OUTPUT);
    digitalWrite(row_array[i], HIGH);
  }

  // 配置列引脚,初始化为低电平
  for (int i = 0; i < 8; i++) {
    pinMode(col_array[i], OUTPUT);
    digitalWrite(col_array[i], HIGH); // 初始化为高电平(关闭 LED)
  }
}

void loop() {
  for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 8; j++) {
      digitalWrite(col_array[j], !bitRead(hex_array[i], j)); // 点亮或关闭 LED
    }
    digitalWrite(row_array[i], LOW); // 激活当前行
    delayMicroseconds(100); // 短暂延时
    digitalWrite(row_array[i], HIGH); // 关闭当前行
  }
}

PS2遥感控制点阵屏

// 定义行引脚数组
int row_array[8] = {13, 25, 2, 27, 23, 4, 22, 18};
// 定义列引脚数组
int col_array[8] = {26, 21, 19, 12, 5, 14, 33, 32};

// 定义LED位置
int led_pos[2] = {1, 2};

// 初始化摇杆信号变量
int x_value;
int y_value;

void setup() {
  // 配置PS2引脚模式
  pinMode(PS2_X, INPUT);
  pinMode(PS2_Y, INPUT);

  // 配置行引脚,初始化为高电平
  for (int i = 0; i < 8; i++) {
    pinMode(row_array[i], OUTPUT);
    digitalWrite(row_array[i], HIGH);
  }
  // 配置列引脚,初始化为低电平
  for (int i = 0; i < 8; i++) {
    pinMode(col_array[i], OUTPUT);
    digitalWrite(col_array[i], HIGH); // 初始化为高电平(关闭 LED)
  }
}

void loop() {
  // 读取摇杆信号
  x_value = analogRead(PS2_X);
  y_value = analogRead(PS2_Y);

  // 关闭之前的LED
  digitalWrite(row_array[led_pos[0]], HIGH);
  digitalWrite(col_array[led_pos[1]], HIGH);

  // 检测X轴是否移动
  if (x_value > 4095 / 2 + 300 && led_pos[0] < 7) {
    led_pos[0] += 1;
  } else if (x_value < 4095 / 2 - 300 && led_pos[0] > 0) {
    led_pos[0] -= 1;
  }

  // 检测Y轴是否移动
  if (y_value > 4095 / 2 + 300 && led_pos[1] < 7) {
    led_pos[1] += 1;
  } else if (y_value < 4095 / 2 - 300 && led_pos[1] > 0) {
    led_pos[1] -= 1;
  }

  // 显示LED位置
  digitalWrite(row_array[led_pos[0]], LOW);
  digitalWrite(col_array[led_pos[1]], LOW);

  // 延时
  delay(100);
}

继电器模块

继电器是一种电气控制设备,用于在低电路中控制高电压电路的开关,它是由一个线圈,一组可触机械部件组成,当线圈通电时,机械部件会移动,使可触点连接或断开高电压电路。

#define RELAY_FIN 15

//初始化定时器
hw_timer_t*timer = NULL;

void timer_interrupt(){
  digitalWrite(RELAY_PIN,!digitalRead(RELAY_PIN));

}

void setup(){
  //设置为输出模式
  pinMode(RELAY_PIN,OUTPUT);

  //初始化定时器
  timer = timerBegin(0,80,true);
  
  //注册中断处理函数
  timerAttachInterrupt(timer,timer_interrupt,true);
  
  //设置定时器模式
  timerAlarmWrite(timer,500000,true);

  //启动定时器  
  timerAlarmEnable(timer);
}
void loop(){

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值