当前位置:   article > 正文

esp32入门手册学习_esp32使用手册

esp32使用手册

一、开发板资源

在这里插入图片描述

HELLO WORLD

串口打印

选编译并下载固件(右箭头)
在这里插入图片描述
下载成功后按复位按钮运行程序
在这里插入图片描述

生成bin文件,下载固件

用 Arduino IDE 生成一个工程的 bin 文件,然后用 ESPFlashDownloadTool 下载固件。

先点导出 bin 文件
在这里插入图片描述
在这里插入图片描述
打开 ESPFlashDownloadTool ,选择刚导出的bin文件和bootloader , default文件,填写好地址和参数,点击下载。

Arduino ESP32 开发环境的文件结构

Core 文件夹:乐鑫提供的 ESP32 底层内核文件,包括 gpio timer iic spi touch uarts 等外设驱动,还有二次封装好的 TCP UDP Server 等常用 arduino 库文件。
libraries 文件夹:包含各厂家的 arduino 例程,我们的例程文件夹是 ESP-32F
variants 文件夹:各种 esp32 开发板的引脚定义头文件 (如果需要添加的自己开发板,则需 要在该文件夹内加入自己开发板的引脚定义头文件,添加方法可以参考其他开发板的头文 件,依样画葫芦即可)
Tools 文件夹:esp32 sdk 和编译工具链
Boards.txt:定义开发板的各项参数,这些参数将会在 arduino ide 选择开发板型号和参数的 面板中体现出来

实验

实验 1:驱动 RGB

steup 函数相当于 main 函数 ,程序从这里开始
void setup() {
// put your setup code here, to run once:
}
Loop 函数相当予 while(1){} 函数,
void loop() {
// put your main code here, to run repeatedly:
}
delay(x); arduino 系统延时函数 延时 x 毫秒
rand() 随机数函数,rand()%2 代表 0-1 这两个数取随机数

void setup() {
  // put your setup code here, to run once:
  pinMode(32,OUTPUT);
  pinMode(33,OUTPUT); 
  pinMode(27,OUTPUT);//IO27 IO32 IO33 三个引脚设置为输出模式
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(32,rand()%2); //三个 LED 随机点亮,组成不同的颜色 
  digitalWrite(33,rand()%2); 
  digitalWrite(27,rand()%2); 
  delay(1000);//延时 1000ms
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

请添加图片描述

请添加图片描述
请添加图片描述
请添加图片描述

实验 2:Serial 的使用

Arduino 串口通讯会用到 Stream 这个类,Stream 类是二进制数据或者字符串数据流传输的基础类,不能被直接调用,但可以被继承。

available()获取数据流中接收到的字节数,返回值是 int 类型。
read()获取数据流中第一个字节数据,获取数据后会清除当前字节数据。返回值是 读取数据字符的第一个字节(8bit)
peek()从数据流中读取当前的一个字节,不会清除数据流中当前字节数据
flush()清除数据流所有未向外发送的数据。返回bool 类型。
find() 从数据流中查找目标字符串,找到目标字符串后返回值 = true,超时则返回值 = false。
findUntil() 从数据流中读取目标字符串或者终止目标字符串,找到目标字符串后返回值 = true,超时则返回值 = false。
Serial 类 用于对串口数据流的读写。

String buf; 
char temp; 
void setup() {
  // put your setup code here, to run once: 
  Serial.begin(115200); 
  Serial.setTimeout(10);//设置串口接收超时时间 10ms (如果不明白可以改成 1000 ,用串 口助手看效果) 
  Serial.println("Goouuu HelloWorld!"); 
  }
  void loop() { 
    // put your main code here, to run repeatedly:
    if(Serial.available()!=0)//如果接收缓冲区非空 
    { 
      buf=Serial.readString();//将收到的数据以字符串形式存到 buf 
      Serial.print(buf);//串口打印 buf } }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

如图,串口正常打印输入信息。
在这里插入图片描述

实验3:触摸按键

ESP-32F 开发板上的触摸通道是用了 T0(IO4) 和 T2(IO2)
在这里插入图片描述
uint16_t touchRead(uint8_t pin); 获取某个通道采集的数值。

// Just test touch pin - Touch0 is T0 which is on GPIO 2. 
int T0_Cul=0;
int T2_Cul=0; 
void LED_Init(void)//LED 初始化 
{ 
  pinMode(33,OUTPUT);
  pinMode(27,OUTPUT);
}
void setup() 
{ 
  LED_Init(); 
  Serial.begin(115200); 
  Serial.println("ESP32 Touch Test"); 
}
void Touch_Pad_Check(void) 
{ 
  Serial.print("T0_Value:"); 
  Serial.println(touchRead(T0)); // get value using T0 
  T0_Cul=touchRead(T0); 
  Serial.print("T2_Value:"); // get value using T2 
  Serial.println(touchRead(T2)); //
  T2_Cul=touchRead(T2);
  if(T0_Cul<=15)//通道采集数值低于 15 被认为按键按下 
  { 
    digitalWrite(33,0);//点亮 LEDA
  }
  else if(T0_Cul>20)//通道采集数值高于 20 被认为按键被释放 
  {
    digitalWrite(33,1);//熄灭 LEDA 
  }
  if(T2_Cul<=15)
  {
    digitalWrite(27,0); 
  }
  else if(T2_Cul>20)
  {
    digitalWrite(27,1); 
  } 
}
void loop() 
{ 
  Touch_Pad_Check(); 
}
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

在这里插入图片描述
在这里插入图片描述

当我按住触摸按键 T1 不放时,T0 通 道输出值都是保持在 15 以下,这时候这个通道触发的阀值就很清楚了。此时LED点亮。

if(T0_Cul<=15)//通道采集数值低于 15 被认为按键按下
{ 
 digitalWrite(33,0);//点亮 LEDA
}
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述
在这里插入图片描述

实验 4:定时器

hw_timer_t *timer=NULL;//创建一个定时器结构体 
volatile SemaphoreHandle_t timerSemaphore;//创建一个定时器信号量 
int time_count=0; 
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR Timer_Hander() 
{ 
portENTER_CRITICAL_ISR(&timerMux);//进入临界段 
time_count++; 
portEXIT_CRITICAL_ISR(&timerMux);//退出临界段 
xSemaphoreGiveFromISR(timerSemaphore, NULL);//释放一个二值信号量 timerSemaphore 
}
void setup() { 
// put your setup code here, to run once:
Serial.begin(115200); 
timerSemaphore=xSemaphoreCreateBinary();//定义信号量
timer = timerBegin(0, 80, true);//初始化定时器 0 80 分频 向上计数 
 // 配置定时器中断函数 
timerAttachInterrupt(timer, &Timer_Hander, true); 
// Set alarm to call onTimer function every second (value in microseconds). 
// Repeat the alarm (third parameter) 
timerAlarmWrite(timer, 5000000, true);//每计数 5000000 次触发定时器中断 自动重载开启 
// Start an alarm 
timerAlarmEnable(timer);//使能定时器函数 
}
void loop() { 
// put your main code here, to run repeatedly:收到定时器触发后置位的二值信号量后打印 计数值if (xSemaphoreTake(timerSemaphore,0) == pdTRUE){ 
	portENTER_CRITICAL_ISR(&timerMux); 
	Serial.println(millis());//打印系统已经运行了多少时间 
	Serial.println(time_count);//计数值 
	portEXIT_CRITICAL_ISR(&timerMux); 
	} 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

串口打印系统程序已经运行的时间和定时器计数的次数。
在这里插入图片描述

实验 5:读取 DHT11 温湿度传感器

DHT11 输出两个字节湿度数据,两个字节温度数据 ,一个校验字节,共五个字节。

建立自己封装的 c++类库

1.点击下拉箭头 新建标签,输入文件名 xxx.cpp 后确定。
在这里插入图片描述

构造函数:

在类实例化对象时自动执行,对类中的数据进行初始化

构造函数可以从载,可以有多个, 但是只能有一个缺省构造函数。

构造函数必须和类同名 。

析构函数:

撤销对象占用的内存之前,进行一些操作的函数。

析构函数不能被重载,只能有一个。

析构函数如果我们不写的话,C++ 会帮我们自动的合成一个,C++ 会自动的帮我们写一个析构函数。自动生成的析构函数可以很好的工作,但是一些重要的事迹, 就必须我们自己去写析构函数。

析构函数和构造函数是一对。构造函数用于创建对象,而析构函数是用来撤销对象。一个对象出生的时候,使用构造函数,死掉的时候,使用析构函数。
定义
类名::方法名

实验 6:ADC 采集 GP2Y1014AU 粉尘传感器

ESP32 ADC 库函数

void analogSetSamples(uint8_t samples); 设置分频 1-255
bool adcAttachPin(uint8_t pin); 设置 ADC 采集引脚
uint16_t analogRead(uint8_t pin); 读取 ADC 通道值
bool adcStart(uint8_t pin); 开始 ADC 采集

GP2Y1014AU 粉尘传感器

检测原理
传感器中心有个洞可以让空气自由流过,定向发射LED光,通过检测经过空气中灰尘折射过后的光线来判断灰尘的含量。

#include "Arduino.h" 
#define dustPin 35 //定义 adc 采集引脚 
#define ledPower 21 //定义 led 发射引脚 

int value; 
float dustVal=0; 
int delayTime=280; 
int delayTime2=40; 
float offTime=9680; 

void setup() { 
// put your setup code here, to run once: 
pinMode(ledPower,OUTPUT); 
adcAttachPin(dustPin); //设置 ADC 采集引脚
adcStart(dustPin); //开始 ADC 采集
Serial.begin(115200); 
}
void loop() { 
// put your main code here, to run repeatedly: 
digitalWrite(ledPower,LOW); 
delayMicroseconds(delayTime); 
dustVal=analogRead(dustPin); 
// Serial.write(value>>8); Serial.write(value); 
delayMicroseconds(delayTime2); 
digitalWrite(ledPower,HIGH); 
delayMicroseconds(offTime); 

delay(1000); 
if (dustVal>36.455) 
Serial.println((float(dustVal/4096)-0.0356)*120000*0.035); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

引脚问题,需要拿个中介板焊到一起。

实验 7:ESP32 I2C 驱动 OLED

0.96 OLED 和开发板的连线
VCC ----3.3V
GND----GND
SCL----- GPIO14
SDA---- GPIO15

#include "SSD1306.h"
#include "images.h" 
SSD1306 oled(0x3c,15,14); //实例化 SSD1306 类 
void drawCircle(void) { 
//画圆形
for (int16_t i=0; i<DISPLAY_HEIGHT; i+=2) { 
   oled.drawCircle(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, i); 
   oled.display(); 
   delay(10); 
}
delay(1000); 
oled.clear(); //清屏
// This will draw the part of the circel in quadrant 1 
// Quadrants are numberd like this: 
// 0010 | 0001 
// ------|----- // 0100 | 1000 //
oled.drawCircleQuads(DISPLAY_WIDTH/2,DISPLAY_HEIGHT/2,DISPLAY_HEIGHT/4,0b00000001); oled.display(); 
delay(200); oled.drawCircleQuads(DISPLAY_WIDTH/2,DISPLAY_HEIGHT/2,DISPLAY_HEIGHT/4,0b00000011); oled.display(); 
delay(200); oled.drawCircleQuads(DISPLAY_WIDTH/2,DISPLAY_HEIGHT/2,DISPLAY_HEIGHT/4,0b00000111); oled.display(); 
delay(200); oled.drawCircleQuads(DISPLAY_WIDTH/2,DISPLAY_HEIGHT/2,DISPLAY_HEIGHT/4,0b00001111); oled.display(); 
}
void setup() { 
// put your setup code here, to run once: 
oled.init();//初始化 
OLED oled.flipScreenVertically();// 
oled.setContrast(255);//设置对比度 255
drawCircle();//画动态圆形的函数 
//oled.drawXbm(0,0, Logo_width,Logo_height, Logo_bits); 
oled.display();//显示内容 
}
void loop() { 
// put your main code here, to run repeatedly:
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

错误1
在这里插入图片描述
解决:
安装ESP8266 and ESP32 Oled Driver for SSD1306 display
错误2
在这里插入图片描述
解决方法:
换一个安装路径。
仍存在此问题,未解决,没有images.h,但是路径中有呀,要再下载一个esp32-expressf-master,我虽然有,但是库中文件不全。
多次下载失败,以上例程未实现,少库,应该是master中文件不全,再下载。
以下例程都是此问题,均未实现。
在这里插入图片描述

打印字符串

如果是要打印字符串可以在主函数下添加如下代码

oled.setFont(ArialMT_Plain_16);//设置字体为 16 号 
  • 1

如果想变其他字体可以看下 OLEDDisplayFonts.h 这个文件,选择自己需要的字体。

oled.drawString(1,1,"Goouuu");//打印字符串
  • 1

打印位图

如果想打印一张位图 那么可以用这个函数

oled.drawXbm(0,0, Logo_width,Logo_height, Logo_bits);
  • 1

图片取模过程如下:
1.先用美图秀秀,将图片尺寸强制变成 128x64 并保存为 png 格式。
2.用画图软件打开修改后的 png 图片设置为黑白点确定。
3.打开取模软件,调入黑白图像,点 c51 格式,然后把取到的数据复制到 arduino 里图像的数 组即可。
4.打开取模软件,调入黑白图像,点 c51 格式,然后把取到的数据复制到 arduino 里图像的数 组即可。
之前笔记更简单。
参考之前学习笔记

实验 8:ESP32 SPI 驱动 LCD

例程一:画线

#include"lcd.h" 
#include"icon.h" 
LCD lcd; //实例化这个类 
void setup() { 
// put your setup code here, to run once: 
lcd.LCD_GPIOInit(); 
lcd.LCD_Init(); 
lcd.LCD_Clear(BLACK); //清屏幕,并把背景设为黑色 
POINT_COLOR=BLUE;//设置画笔颜色蓝色 
lcd.LCD_DrawLine(0,127,127,0); // 画两条直线 
lcd.LCD_DrawLine(0,0,127,127); // 
}
void loop() { 
// put your main code here, to run repeatedly: 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

例程二:显示英文和中文字符

#include"lcd.h" 
#include"icon.h" 
LCD lcd; //实例化这个类 
void setup() { 
// put your setup code here, to run once: 
lcd.LCD_GPIOInit(); 
lcd.LCD_Init(); 
lcd.LCD_Clear(BLACK); //清屏幕,并把背景设为黑色 
POINT_COLOR=BLUE;//设置画笔颜色蓝色 
lcd.Show_Str(40,25,BLUE,BLACK,"Goouuu",16,1); 
lcd.Show_Str(32,50,BLUE,BLACK,"果 云 科 技 ",8,1);
}
void loop() { 
// put your main code here, to run repeatedly: 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

实验 9:ESP32 DAC 驱动扬声器播放 PCM 音乐

扬声器就是通常我们说的音箱。可以播放各种声音,例如音乐。
蜂鸣器则是单纯只发出一种声音的报警装置。它会通过声音的长短来报告错误。

#include "Speaker.h" 
#include "music_8bit.h" 
SPEAKER Speaker; 
void setup() { 
// put your setup code here, to run once: 
Speaker.begin(); //初始化
Speaker.setVolume(10); //设置音量为10
Speaker.playMusic(data, 22500); //播放 pcm 格式数据,并设定采样率
}
void loop() { 
// put your main code here, to run repeatedly: 
Speaker.update(); 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

实验 10:ESP32 读写 MicroSD 卡操作

列出指定目录下的文件

#include "FS.h"
#include "SD.h"
#include "SPI.h" 
#include "Speaker.h" 
SPEAKER Speaker; 
  /*---------------------------------------------------- 
  列出指定目录下的文件
   -----------------------------------------------------*/ 
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){ 
Serial.printf("Listing directory: %s\n", dirname); 
File root = fs.open(dirname); 
if(!root){ 
	Serial.println("Failed to open directory"); 
	return; 
}
if(!root.isDirectory()){ 
	Serial.println("Not a directory"); 
	return; 
}
File file = root.openNextFile(); 
while(file){ 
	if(file.isDirectory()){ 
		Serial.print(" DIR : "); 
		Serial.println(file.name()); 
		if(levels){ 
			listDir(fs, file.name(), levels -1); 
		} 
	} 
	else {
		Serial.print(" FILE: "); 
		Serial.print(file.name()); 
		Serial.print(" SIZE: "); 
		Serial.println(file.size()); 
	}
	file = root.openNextFile(); 
	} 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

在这里插入图片描述

创建目录

void createDir(fs::FS &fs, const char * path){ 
	Serial.printf("Creating Dir: %s\n", path); 
	if(fs.mkdir(path)){ 
		Serial.println("Dir created"); 
	} else {
		Serial.println("mkdir failed"); 
	} 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

移除目录

void removeDir(fs::FS &fs, const char * path){ 
Serial.printf("Removing Dir: %s\n", path); 
if(fs.rmdir(path)){ 
	Serial.println("Dir removed"); 
} else {
	Serial.println("rmdir failed"); 
	} 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

读取指定文件的内容

void readFile(fs::FS &fs, const char * path){ 
uint8_t buf[2]; 
uint16_t delay_interval = ((uint32_t)1000000/25000); 
Serial.printf("Reading file: %s\n", path); 
File file = fs.open(path); 
if(!file){ 
	Serial.println("Failed to open file for reading"); 
	return; 
}
Serial.print("Read from file: "); 
while(file.available()){ 
	buf[0]=file.read(); 
	dacWrite(SPEAKER_PIN,buf[0]); 
	delayMicroseconds(delay_interval-20);
}
file.close(); 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

写入指定内容到指定文件

void writeFile(fs::FS &fs, const char * path, const char * message){ 		Serial.printf("Writing file: %s\n", path); 
File file = fs.open(path, FILE_WRITE); //打开指定的某个文件
if(!file){ 
	Serial.println("Failed to open file for writing"); 
	return; 
}
if(file.print(message)){ 
	Serial.println("File written"); 
} else {
	Serial.println("Write failed"); 
}file.close(); 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

写入指定内容到指定文件,如果这个文件不存在,则创建一个新的指定名字的文件,再写入内容。

void appendFile(fs::FS &fs, const char * path, const char * message){ 	Serial.printf("Appending to file: %s\n", path); 
File file = fs.open(path, FILE_APPEND); 
if(!file){ 
	Serial.println("Failed to open file for appending"); 
	return; 
}
if(file.print(message)){ 
	Serial.println("Message appended"); 
} else {
	Serial.println("Append failed"); 
}file.close(); 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

重命名文件

void renameFile(fs::FS &fs, const char * path1, const char * path2){ 	Serial.printf("Renaming file %s to %s\n", path1, path2); 
if (fs.rename(path1, path2)) { 
	Serial.println("File renamed"); 
} else {
	Serial.println("Rename failed"); 
	} 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

删除指定文件

void deleteFile(fs::FS &fs, const char * path){ 
	Serial.printf("Deleting file: %s\n", path); 
	if(fs.remove(path)){ 
		Serial.println("File deleted"); 
	} else {Serial.println("Delete failed"); 
	} 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

读写文件测试

void testFileIO(fs::FS &fs, const char * path){ 
File file = fs.open(path); 
static uint8_t buf[512]; 
size_t len = 0; uint32_t start = millis(); 
uint32_t end = start; 
if(file){
	len = file.size(); 
	size_t flen = len; 
	start = millis(); 
	while(len){
		size_t toRead = len; 
		if(toRead > 512){ 
			toRead = 512; 
		}
		file.read(buf, toRead); 
		len -= toRead; 
	}
	end = millis() - start; 
	Serial.printf("%u bytes read for %u ms\n", flen, end); 
	file.close(); 
} else {
	Serial.println("Failed to open file for reading"); 
}
file = fs.open(path, FILE_WRITE); 
if(!file){ 
	Serial.println("Failed to open file for writing"); 
	return; 
}size_t i; 
start = millis(); 
for(i=0; i<2048; i++){ 
	file.write(buf, 512); 
}
end = millis() - start; 
Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end); 
file.close(); 
}
void setup(){ 
	Serial.begin(115200); 
	if(!SD.begin()){ //初始化 SD 卡 
		Serial.println("Card Mount Failed"); 
		return; 
	}
	uint8_t cardType = SD.cardType(); //读取 SD 卡类型
	//判断 SD 卡类型 
	if(cardType == CARD_NONE){ 
		Serial.println("No SD card attached"); 
		return; 
	}
	Serial.print("SD Card Type: "); 
	if(cardType == CARD_MMC){ 
		Serial.println("MMC"); 
	} else if(cardType == CARD_SD){ 
		Serial.println("SDSC"); 
	} else if(cardType == CARD_SDHC){ 
		Serial.println("SDHC"); 
	} else {
		Serial.println("UNKNOWN"); 
	}
	//读取 SD 卡尺寸 
	uint64_t cardSize = SD.cardSize() / (1024 * 1024); 
	Serial.printf("SD Card Size: %lluMB\n", cardSize); 
	listDir(SD, "/", 0);//列出目录 
	createDir(SD, "/mydir");//创建 1 个 mydir 的文件夹目录 
	listDir(SD, "/", 0);//列出目录 
	removeDir(SD, "/mydir");//删除 mydir 的文件夹目录 
	listDir(SD, "/", 2);//列出目录 
	writeFile(SD, "/hello.txt", "Hello ");//对 hello.txt 这个文件写内容 Hello appendFile(SD, "/hello.txt", "World!\n");//检测 hello.txt 这个是否存在,不存在则创建并写 //入内容,如果存在则直接写入内容 
	readFile(SD, "/hello.txt");//读取 hello.txt 文件 
	deleteFile(SD, "/foo.txt");//删除 foo.txt 文件 
	renameFile(SD, "/hello.txt", "/foo.txt");//把 hello.txt 这个文件重命名为 foo.txt 	  readFile(SD, "/jqm.pcm");//读取 jqm.pcm 这个文件,并播放 
	}
	void loop(){ 
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

ESP32 WiFi 的使用

STA 模式下的 TCP 通讯实验:

ESP32 作为 Station 模式,连接路由器,然后连接我们的公网测试服务器端,惊醒 tcp 通讯。

#include<WiFi.h> 
#include<WiFiMulti.h> 
WiFiMulti WiFiMulti; 
WiFiClient client; 
#define WIFISSID "yq" 
#define Password "goouuu8266" 
uint8_t test[6]={0x12,0x34,0x56,0x78,0x0c,0x0b};//6 个字节的测试数据 
const uint16_t port = 8266;//主机端口 
const char * host = "39.106.163.29"; // ip or dns 远程主机 ip 
void Connect_Router(void);//连接到你的路由器 
void Connect_Host(void);//连接到远程服务器 
void setup() { // put your setup code here, to run once: 
	Serial.begin(115200); 
	Connect_Router();//连接到你的路由器 
}void loop() { 
// put your main code here, to run repeatedly: 
	Connect_Host();//连接到远程服务器 // This will send the request to the server client.write(test,6);//发送 6 个字节数据 
	client.print("Hello_Goouuu!\r\n");//发送字符串 //read back one line from server
	String line = client.readStringUntil('\r');读取服务器发来的数据 	Serial.println(line);//打印服务器发来的数据 
	client.stop();//关闭端口 
	Serial.println("closing connection"); 
	Serial.println("wait 5 sec..."); 
	delay(5000); 
	}void Connect_Router(void) { 
	// We start by connecting to a WiFi network 
	WiFiMulti.addAP(WIFISSID,Password); 
	Serial.println(); 
	Serial.println(); 
	Serial.print("Wait for WiFi... "); 
	while(WiFiMulti.run() != WL_CONNECTED) { 
		Serial.print("."); 
		delay(500); 
	}
	Serial.println(""); 
	Serial.println("WiFi connected"); 
	Serial.println("IP address: "); 
	Serial.println(WiFi.localIP()); 
	delay(500); 
	}void Connect_Host(void) 
	{ 
		if (!client.connect(host, port)) { 
			Serial.println("connection failed"); 
			Serial.println("wait 5 sec..."); 
			delay(5000); 
			return; 
		} 
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

Sta 模式下扫描周围热点:

 #include "WiFi.h" 
 void setup() 
 { 
 	Serial.begin(115200); 
 	// Set WiFi to station mode and disconnect from an AP if it was previously connected 	 WiFi.mode(WIFI_STA);//设置为 STA 模式 
 	WiFi.disconnect();//断开连接 delay(100); 
 	Serial.println("Setup done"); 
}
void loop() 
{ 
	Serial.println("scan start"); 
	// WiFi.scanNetworks will return the number of networks found 
	int n = WiFi.scanNetworks();//获取可以正常连接的热点数量 
	Serial.println("scan done"); 
	if (n == 0) { 
		Serial.println("no networks found"); } 
	else {
		Serial.print(n); 
		Serial.println(" networks found"); 
		for (int i = 0; i < n; ++i) { 
		// Print SSID and RSSI for each network found 
			Serial.print(i + 1); 
			Serial.print(": "); 
			Serial.print(WiFi.SSID(i));//打印热点 SSID 
			Serial.print(" ("); 
			Serial.print(WiFi.RSSI(i));//打印热点信号强度 
			Serial.print(")"); 
			Serial.print(" ("); 
			Serial.print(WiFi.channel(i));//打印热点信道 
			Serial.print(")"); 
			Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*"); 	 delay(10); 
			} 
		}
		Serial.println(""); 
		// Wait a bit before scanning again 
		delay(5000); 
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

Smartconfig 一键连接原理

首先 WiFi 模块进入初始化状态,处于一个待收包状态。
手机点下配置键后,将已知 AP 的 SSID 和密码等信息,通过 UDP 广播发送出去。
WiFi 模块收到 UDP 包后解析得到 AP 的 SSID 和密码等信息后,切换到 STA 状态,对目标 AP 发起连接,连上目标 AP 后,配置就结束了。

#include "WiFi.h" 
void setup() { 
	Serial.begin(115200); 
	//Init WiFi as Station, start SmartConfig 
	WiFi.mode(WIFI_AP_STA); 
	WiFi.beginSmartConfig(); 
	//Wait for SmartConfig packet from mobile 
	Serial.println("Waiting for SmartConfig."); 
	while (!WiFi.smartConfigDone()) { 
		delay(500); 
		Serial.print("."); 
	}
	Serial.println(""); 
	Serial.println("SmartConfig received."); 
	//Wait for WiFi to connect to AP 
	Serial.println("Waiting for WiFi"); 
	while (WiFi.status() != WL_CONNECTED) { 
		delay(500); 
		Serial.print("."); 
	}
	Serial.println("WiFi Connected."); 
	Serial.print("IP Address: "); 
	Serial.println(WiFi.localIP()); 
}
void loop() { 
// put your main code here, to run repeatedly: 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/554165
推荐阅读
相关标签
  

闽ICP备14008679号