esp32-Arduino开发学习

本指南全面介绍了ESP32与Arduino平台结合开发的基础知识和技术要点,包括开发环境搭建、GPIO操作、串口通信、ADC/DAC使用、PWM控制、触摸开关应用等内容,并深入探讨了低功耗模式、蓝牙及Wi-Fi功能实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.Arduino开发环境的搭建以及esp32驱动的安装

1.arduino编译器的安装
(1)进入www.arduino.cc;
(2)点击SOFTWARE;
在这里插入图片描述
(3)选择 Windows Win 7 and never,然后点击JUST DOWNLOAD,将安装包另存为;
在这里插入图片描述
(4)双击刚才保存的安装包,一路向下点击;(可安装在其他盘)
2.下载ESP32的插件
方式一:可通过github下载,https://github.com/espressif/arduino-eso32
方式二:已有的压缩包安装;

这里为了方便选择方式二
(1)输入网址:http://www.mjkdz.com;(感谢b站博主的分享)
(2)点击下载,找到arduino插件包;
在这里插入图片描述
(3)文件配置

  • 打开arduino的文件路径,将压缩包里的ESP32和espressif两个文件复制到hardware文件夹下;
  • 返回上一级文件夹,将压缩包里的drivers和libraries复制进该路径下;(重复的可以跳过)

(4)驱动安装
_1.如果是ch341驱动;
点击 drivers–>CH341SER–>CH341SER.EXE
_2.如果是CP210X驱动;
点击 drivers–>CP210x_Universal_Windows_Driver–>CP210xVCPInstaller_x64.exe (64位安装, 32位选择x86)

也可安装dpinst-amd64.exe;

此时插上单片机,可通过设备管理器看到端口;
在这里插入图片描述
(5)打开arduino编译器,点击工具(左上角),选择开发板型号进行配置;
(6)点击 文件–>示例中的任何一个代码 ,进行下载测试;
在这里插入图片描述

二.GPIO输入输出

1.流水灯:

void setup()
{
	pinMode(2, OUTPUT);//设置GPIO2为输出模式
}
void loop()
{
	digitalWrite(2, LOW);//设置GPIO2输出低电平
	delay(1000);  // 延时1000ms
	digitalWrite(2, HIGH);
	delay(1000);
	
}

2.按键控制开关灯

//GPIO2为低电平时,led灯亮;GPIO2为高电平时,led灯灭;
const int KEY=4;
const int LED=2;
int flag=0;
void setup()
{
  pinMode(LED, OUTPUT);//设置GPIO2为输出模式
  pinMode(KEY, INPUT);
  digitalWrite(LED, HIGH);//设置GPIO2输出高电平
  Serial.begin(9600);
}
void loop()
{
   
  if( digitalRead(KEY) == 1 )    //查看按键是否按下  
  {
    flag = !flag;
    digitalWrite(LED, flag);
    Serial.println(flag);
    delay(500);
  }
}

三.串口(UART)的使用

1.Serial.write()

byte x=150;
void setup()
{
  Serial.begin(9600);
}
void loop()
{
   Serial.write(x);//串口以十六进制方式输出
   delay(100);
}

2.Serial.print() Serial.println()

int x=55;
void setup()
{
  Serial.begin(9600);
}
void loop()
{
   Serial.print(x);//串口输出十进制
   delay(500);
   Serial.println(x);//串口输出十进制换行
   delay(500);
   Serial.println(x,HEX);//串口输出字符,以十六进制方式输出
   delay(500);
   Serial.println(x,OCT);//串口输出字符,以八进制方式输出
   delay(500);
   Serial.println(x,BIN);//串口输出字符,以二进制方式输出
   delay(500);
}

3.串口控制led的亮灭

const int led=2;
char x=0;
void setup()
{
  Serial.begin(9600);
  pinMode(led,OUTPUT);
  digitalWrite(led,HIGH);
}
void loop()
{
   while(Serial.available()>0) // 判断串口是否有数据
   {
      x=Serial.read();//读取串口值
      if(x == 'A')
      {
          digitalWrite(led,LOW);
      }
      else if(x == 'B')
      {
          digitalWrite(led,LOW);
      }
      
   }
}

四.模拟输入(ADC)和数模输出(DAC)

1.读取模拟口的值

const int adc=14; //具有ADC功能的引脚,可自行查看开发板引脚功能
int x=0;
void setup()
{
	Serial.begin(115200);
}
void loop()
{
	x=analogRead(adc);//读取模拟口的值,可调节
	Serial.println(x);
	delay(100);
}

2.DAC输出电压值

#define DAC1 25 // 宏定义
int x=255; 
void setup()
{
	Serial.begin(115200);
}
void loop()
{
	dacWrite(DAC1,x);//DAC输出电压值,此管脚接LED也可用万用表测量
}

3.电位器旋钮调节led的亮灭(电压大小)

#define DAC1 25 // 宏定义
#define ADC1 14
int x=0; // 存储ADC读取的变量 
void setup()
{
	Serial.begin(115200);
}
void loop()
{
	x=analogRead(ADC1);
	Serial.print(x);
	Serial.print(',');
	x=map(x,0,4096,0,255);//将0-4096转换成0-255,DAC是8位
	Serial.println(x);// 串口输出转换后的值
	dacWrite(DAC1,x);//DAC输出电压值
}

五.脉冲宽度调制(pwm)

1.led由亮到灭,再由灭到亮

const int led=2;//GPIO2接LED
const int pl=1000;//定义PWM频率为1KHZ
const int td=0;//定义PWM通道0
const int bit1=8;//定义PWM(8位或者12位)
void setup()
{
	ledcSetup(td,pl,bit1);//配置PWM功能
	ledcAttachPin(led,td);//将通道连接到要控制的GPIO
}
void loop()
{
	for(int i=0;i<256;i++)
	{
		ledcWrite(td,i);// 控制led从灭到亮
		delay(15);
	}
	for(int x=256;x>=0;x--)
	{
		ledcWrite(td,x);// 控制led从亮到灭
		delay(15);
	}
}

2.电位器(可调电阻控制led)

const int adc=14;
const int led=2;//GPIO2接LED
const int pl=1000;//定义PWM频率为1KHZ
const int td=0;//定义PWM通道0
const int bit1=8;//定义PWM(8位或者12位)
int x=0; // 存储ADC读取的变量 
void setup()
{
	ledcSetup(td,pl,bit1);//配置PWM功能
	ledcAttachPin(led,td);//将通道连接到要控制的GPIO
}
void loop()
{
	x=analogRead(adc);
	ledcWrite(td,x);
}

六.触摸开关touch

1.通过触摸开关控制led亮灭

#define tm T0  // 触摸开关T0,杜邦线接GPIO4
const int led=2;
const int threshold=48;//阀值,可根据情况调节
int x=0;//存储触摸开关的值
void setup()
{
	delay(1000);// 启动延时防误触
	pinMode(led,OUTPUT);
	Serial.begin(115200);
}
void loop()
{
	x=touchRead(T0);//读取触摸开关的值
	Serial.println(x);
	if(x <= threshold)
	{
		digitalWrite(led,LOW);
	}
	else
	{
		digitalWrite(led,HIGH);
	}
}

七.外部中断

外部中断控制led

#define key 35
#define led 2
byte ZH=0;
void IRAM_ATTR interrupt1()// 中断函数
{
	ZH=!ZH;
	digitalWrite(led,ZH);
}
void setup()
{
	pinMode(led,OUTPUT);
	pinMode(key,INPUT);
	/*
	1 LOW     每当引脚为低电平(LOW)时触发中断
	2 HIGH    每当引脚为高电平(HIGH)时触发中断
	3 CHANGE  在引脚状态改变时触发中断
	4 FALLING 每当引脚从高变低时触发,(上升沿)
	5 RISING  每当引脚从低变高时触发,(下降沿)
	*/
	attachInterrupt(key,interrupt1,FALLING);// 外部中断设置
}
void loop()
{
}

什么是IRAM_ATTR?
通过使用IRAM_ATTR属性标记一段代码,我们声明编译后的代码放置在ESP32的内部RAM(IRAM)中。ESP32上的闪存比内部RAM慢的多。如果我们要运行的代码是一个中断服务程序(ISR),我们通常希望尽快执行它,如果我们不得不“等待”从闪存加载ISR,那可能中断就会失败。

八.计数函数和定时器使用

millis() 定时1msmicros() 定时1us

1.定时1s, led 1s亮,1s灭

const int led=2;
byte ZH=0;//led状态
unsigned long X=0;
const long Y=1000; //1000ms == 1s
void setup()
{
	pinMode(led,OUTPUT);
	Serial.begin(9600);
}
void loop()
{
	unsigned long Z=millis(); //将定时1ms送给变量
	Serial.print(Z);
	Serial.print(",");
	Serial.println(X);
	if(Z-X>=Y)
	{	
		X=Z;
		ZH=!ZH;
		digitalWrite(led,ZH);
	}
}

2.定时器中断控制led

#include <Arduino.h>
/*
 * esp32共有4个定时器0-3,这些都是基于64位的通用定时器。
 * 每个定时器都有个16位预分频器(2-65536)以及可自动
 * 重新加载的64位递增/递减计数器
*/
hw_timer_t *timer = NULL;
volatile int led=2; // GPIO2
volatile byte ZH=0;//volatile关键字说明我们需要在中断中修改这个变量

//	函数名称:onTimer()
//	函数功能:中断服务的功能,它必须是一个返回void(空)且没有输入参数的函数
//  为使编译器将代码分配到IRAM内,中断处理程序应该具有 IRAM_ATTR 属性
//  https://docs.espressif.com/projects/esp-idf/zh_CN/release-v4.3/esp32/api-reference/storage/spi_flash_concurrency.html
void IRAM_ATTR TimerEvent()
{
	ZH=!ZH;
    digitalWrite(led,ZH);
}
void setup()
{
    Serial.begin(115200);
    pinMode(led,OUTPUT);
    //	函数名称: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()
{
}

九.霍尔功能的使用

什么是霍尔传感器,它有什么用?
霍尔传感器是一种检测磁场的传感器, 可以用来检测磁场的存在和变化, 广泛用在测量、 自动化控制、 交通运输和日常生活等领域。

int hallRead();

void setup()
{
	Serial.begin(9600);
}
void loop()
{
	int x=hallRead();
	Serial.println(x);
	delay(200);
}

十.EEPROM在ESP32中的函数用法

EEPROM (Electrically Erasable Programmable read only memory)是指带电可擦可编程只读存储器。是一种掉电后数据不丢失的存储芯片。 EEPROM 可以在电脑上或专用设备上擦除已有信息,重新编程。一般用在即插即用。

#include<Arduino.h>
#include"EEPROM.h"

int EEPROMDZ1=0,EEPROMDZ2=10; // 0-255个地址
int intdata=11000;
String stringdata="flg666";
void setup()
{
   Serial.begin(115200);
   EEPROM.begin(512);//ESP32最大EEPROM为4096字节(4kb),我们这里只是用512字节,你可以根据自己的需要选择大小
   delay(500); //防止过快出错
}
void loop()
{
  if(Serial.available())
  {
    String str=Serial.readString();
    delay(10);
    if(str == "read") //读取EEPROM的数据 
    {
        int rInt=EEPROM.readInt(EEPROMDZ1);//读取对应地址的Int值
        String rStr=EEPROM.readString(EEPROMDZ2);//读取对应地址的String值
        Serial.print(rInt);
        Serial.print(',');
        Serial.println(rStr);
    }
    else if(str == "int")
    {
        EEPROM.writeInt(EEPROMDZ1,intdata);//对应地址写入变量的值
        EEPROM.commit();// 确定是否写入成功
    }
    else if(str == "string")
    {
        EEPROM.writeString(EEPROMDZ2,stringdata);//对应地址写入变量的值
        EEPROM.commit();// 确定是否写入成功
    }
    else if(str == "clear")
    {
        for(int i=0;i<512;i++)
        {
            EEPROM.write(i,0);//对应位写入0
        }
        EEPROM.end();//结束EEPROM
    }
    // 如果输入不回复,请提供回复
    else
    {
        Serial.println("输入代码错误!");
    }
  }
}

十一.低功耗模式

参考esp32低功能模式 ,这里就不做介绍。

1.深度睡眠定时器唤醒

#define wmm 1000000  //微妙到秒的转换系数
#define miao 5 // esp32进入睡眠的时间,以秒为单位
const int led=2;

void setup()
{
  pinMode(led,OUTPUT);
  esp_sleep_enable_timer_wakeup(miao*wmm);//esp32睡眠使能,定时器唤醒   5秒
}
void loop()
{
    for(byte i=0;i<5;i++)
    {
        digitalWrite(led,HIGH);
        delay(200);
        digitalWrite(led,LOW);
        delay(200);
    }
    esp_deep_sleep_start();// esp32深度睡眠开始
}

2.深度睡眠触摸开关唤醒

#define FZ 40 //触摸阀值
const int led=2;

void callback()  //触摸中断函数
{
}

void setup()
{
  pinMode(led,OUTPUT);
  touchAttachInterrupt(T3,callback,FZ);// T3对应GPIO15
  esp_sleep_enable_touchpad_wakeup();//设置触摸唤醒
}
void loop()
{
    for(byte i=0;i<5;i++)
    {
        digitalWrite(led,HIGH);
        delay(200);
        digitalWrite(led,LOW);
        delay(200);
    }
    esp_deep_sleep_start();// esp32深度睡眠开始
}

3.外部中断唤醒

//外部中断口GPIO  0,2,4,12-15,25-27,32-39
#define led 2
void setup()
{
  pinMode(led,OUTPUT);
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_4,0);//1=HIGH   0=LOW
}
void loop()
{
    for(byte i=0;i<5;i++)
    {
        digitalWrite(led,HIGH);
        delay(200);
        digitalWrite(led,LOW);
        delay(200);
    }
    esp_deep_sleep_start();// esp32深度睡眠开始
}

十二.蓝牙通讯

1.经典蓝牙串口通讯

#include"BluetoothSerial.h"  //调用串口蓝牙函数

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run ‘make menuconfig‘ #to and enable it
#endif  //判断蓝牙是否已启用,没有的话请运行病启用它

BluetoothSerial SerialBT;
void setup()
{
    Serial.begin(9600);
    SerialBT.begin("ESP32BT");//蓝牙开始并设置名称
}
void loop()
{
    if(Serial.available())
    {
        SerialBT.write(Serial.read());//write 只能发送十六进制
    }
    else if(SerialBT.available())
    {
        Serial.write(SerialBT.read());
    }
}

在这里插入图片描述
2.低功耗蓝牙(BLE)
可观看b站视频:MJKDZ分享的低功耗蓝牙(BLE)服务模式

低功耗蓝牙控制led:低功耗蓝牙 控制led

(BLE)服务端和客户端通讯:(BLE)服务端和客户端通讯

十三. WIFI功能使用

可观看视频详细了解::WIFI入门STA站点模式

一.esp32有三种连接模式::
1.STA站点模式
STA站点,每一个连接到无线网络中的终端(如笔记本电脑、PDA及其它可以联网的用户设备)都可称为一个站点。

ESP32接入到接入点 (路由器);
手机只要在局域网内就可以控制esp32;
2. AP接入点模式
AP,也就是无线接入点,是一个无线网络的创建者,是网络的中心节点。一般家庭或办公室使用的无线路由器就一个AP。

也就是说,其他站点可连接esp32;
这样,esp32作为一个中心节点,就可以和多个外部设备进行通讯;

3. STA+AP站点和接入点连接模式
综合上述两点;
esp32可以连接到路由器上,其他设备连接到esp32;
这样可以我们就可以通过手机连接到家里的路由器上,就可以控制多个带有wifi的设备。
在这里插入图片描述
sta模式

//STA模式
#include<WiFi.h> //调用WiFi函数库

const char *ssid="";//wifi名字
const char *password="";//wifi密码
void wifi_init()
{
    WiFi.mode(WIFI_STA);//将WiFi模式设置为STA模式
    WiFi.begin(ssid,password);//wifi连接
    Serial.print("连接到wifi...");
    while(WiFi.status() != WL_CONNECTED) //等待wifi是否连接成功
    {
        Serial.print('.');
        delay(1000);
    }
    Serial.println(WiFi.localIP());//当连接上时,串口输出连接的IP地址
}
void setup()
{
    Serial.begin(115200);
    wifi_init();//调用初始化wifi函数
    Serial.print("RSSI:");
    Serial.println(WiFi.RSSI());// 串口输出信号强度值
}
void loop()
{
}

扫描wifi设备网络

/*
 扫描WiFi设备网络。
*/
#include "WiFi.h"
void setup()
{
  Serial.begin(115200);//打开串口波特率设置成115200
  WiFi.mode(WIFI_STA);//将WiFi设置为站点模式
  WiFi.disconnect();//断开WIFI
  delay(100);//延时100毫秒
}
void loop()
{
    Serial.println("开始搜索WIFI信号....");
    int n = WiFi.scanNetworks();//扫描WIFI信号,并将得到的WIFI数量存储在变量里
    Serial.println("扫描完成");
    if (n == 0) {//判读如果接收到的WIFI数量是0.说明没有搜到WIFI设备
        Serial.println("没有扫描到WIFI设备");
    } else {
        Serial.print("WIFI设备数量:");
        Serial.print(n);//输出WIFI数量
        Serial.println("个");
        for (int i = 0; i < n; ++i) {//找到的WIFI设备,每个都输出名称和信号强度
            Serial.print(i + 1);
            Serial.print(": ");
            Serial.print(WiFi.SSID(i));//输出WIFI设备名称
            Serial.print(" (");
            Serial.print(WiFi.RSSI(i));//输出WIFI信号强度
            Serial.print(")");
            Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");//输出WIFI加密类型 WPA 、WPA2、WPA_WPA2、WEP,WPA2_PKS,WPA_WPA2_PKS
            delay(10);//延时10毫秒
        }
    }
    delay(5000);//等5秒在扫描
}

AP模式接入测试

#include <WiFi.h>
const char *ssid = "ESP32_WIFI";
const char *password = "12345678";

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_AP);//设置为(AP)接入点模式
  WiFi.softAP(ssid, password);//设置接入点的名称和密码
  Serial.print("接入点IP地址:");
  Serial.println(WiFi.softAPIP());//串口输出IP地址
}

void loop() {
}

AP (自己设定 IP)

#include <WiFi.h>
const char *ssid = "ESP32_WIFI";
const char *password = "12345678";

IPAddress local_IP(192,168,4,10);//IP地址,对应自身
IPAddress gateway(192,168,4,1);//网关
IPAddress subnet(255,255,255,0);//网络掩码

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_AP);//设置为(AP)接入点模式
  WiFi.softAPConfig(local_IP,gateway,subnet);//设置IP地址
  WiFi.softAP(ssid, password);//设置接入点的名称和密码
  WiFi.softAPsetHostname("ssss");//设置主机名字
  Serial.println(WiFi.softAPgetHostname());//输出主机名字 
  Serial.print("接入点IP地址:");
  Serial.println(WiFi.softAPIP());//串口输出IP地址
}

void loop() {
  Serial.println(WiFi.softAPgetStationNum());//串口输客户端连接数量
  delay(1000);
}

AP+STA模式

#include <WiFi.h>
const char* wifi_network_ssid = "********";//连接家庭的路由器的名称
const char* wifi_network_password =  "********";连接家庭的路由器的密码

const char *soft_ap_ssid = "ESP32_WIFI";//AP的名称
const char *soft_ap_password = "123456789";//AP的密码

void setup() {
  Serial.begin(115200);//打开串口波特率设置成115200
  WiFi.mode(WIFI_MODE_APSTA);//设置WIFI模式为AP+STA模式
  WiFi.softAP(soft_ap_ssid, soft_ap_password);//设置AP的名称和密码
  WiFi.begin(wifi_network_ssid, wifi_network_password);//设置STA连接的WIFI名称和密码
  while (WiFi.status() != WL_CONNECTED) {//判断是否已连接到家庭网路
    delay(500);//500毫秒
    Serial.println("等待连接WiFi..");
  }
  Serial.print("AP地址: ");
  Serial.println(WiFi.softAPIP());//串口输出AP的地址
  Serial.print("STA连接IP地址:");
  Serial.println(WiFi.localIP());//串口输出STA的地址  
}
void loop() {}

二.TCP双向通讯:

1.服务端代码(server)

//传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议
#include <WiFi.h>
WiFiServer server; //设置ESP32设置成服务器
const char *ssid = "********";
const char *password = "********";
String readTCP; //存储客户端发送来的字符串
String readUART;//存储串口接收到的字符串
void setup()
{
    Serial.begin(115200); 
    WiFi.mode(WIFI_STA);
    WiFi.setSleep(false); //STA模式下关闭wifi睡眠,提高响应速度
    WiFi.begin(ssid, password);//连接家庭种的路由器
    while (WiFi.status() != WL_CONNECTED)  
    {
      delay(500);
      Serial.print(".");
    }
    Serial.print("IP地址:");
    Serial.println(WiFi.localIP());
    server.begin(2001); //设置服务器端口号2001
}

void loop()
{
    WiFiClient client = server.available(); //创建一个客户端对象
    if (client) //判断有没有客户端连接
    {
        Serial.println("客户端已连接");
        while (client.connected()) //判断客户端是否已连接
        {
            if (client.available()) //如果有客户端发送来的数据
            {
               readTCP=client.readString();//读取客户端发送来的字符串
               Serial.println(readTCP); //打印接收到的字符
               readTCP = "";
            }

            if (Serial.available())// 我们判断串口是否有数据
            {
              readUART=Serial.readString();//读取串口发送来的字符串
              client.println(readUART); //将接收到的字符串发送到客户端
              readUART = "";//将接收到的字符清空
            }
        }
     }
     client.stop(); //停止当前连接:
     Serial.println("没有连接客户端..");
    }

2.客户端代码(cilent)

#include <WiFi.h>
WiFiClient client; //ESP32设置成客户端,用于连接服务器
const char *ssid = "********";
const char *password = "********";
const IPAddress serverIP(192,168,3,2); //访问服务器的IP地址 
uint16_t serverPort = 2001; //连接服务器的端口号 
String readTCP; //存储客户端发送来的字符串
String readUART;//存储串口接收到的字符串
void setup() { 
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.setSleep(false); //关闭STA模式下的wifi休眠,可提高响应速度 
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) 
  { 
    delay(500);
    Serial.print(".");
    } 
    Serial.print("IP地址:");
    Serial.println(WiFi.localIP());
    } 
void loop() {
  Serial.println("连接服务器");
  if (client.connect(serverIP,serverPort)) //我们连接服务器对应的IP地址和端口
  { 
    Serial.println("连接服务器成功");
    while (client.connected() || client.available()) //如果已连接,或有收到的未读取的数据 
    { 
      if (client.available()) //如果有收到数据
      { 
        readTCP = client.readString(); //读取服务器发送的数据
        Serial.println(readTCP); //串口输出服务器发送来的数据
        readTCP = "";//将接收到的字符清空
        }
       if (Serial.available())// 我们判断串口是否有数据
           {
              readUART=Serial.readString();//读取串口发送来的字符串
              client.println(readUART); //将接收到的字符串发送到客户端
              readUART = "";//将接收到的字符清空
           } 
     } 
        Serial.println("关闭当前连接");
        client.stop(); //关闭客户端 
    } 
    else { 
          Serial.println("连接服务器失败");
          client.stop(); //关闭客户端 
          } 
          delay(5000); 
}

3.esp32设置为客户端,通过服务端发送命令控制led

#include <WiFi.h>
WiFiClient client; //ESP32设置成客户端,用于连接服务器
const char *ssid = "********";
const char *password = "********";
const IPAddress serverIP(192,168,3,2); //访问服务器的IP地址 
uint16_t serverPort = 2001; //连接服务器的端口号 
const int led=2;
void setup() { 
  pinMode(led, OUTPUT);
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.setSleep(false); //关闭STA模式下的wifi休眠,可提高响应速度 
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) 
  { 
    delay(500);
    Serial.print(".");
    } 
    Serial.print("IP地址:");
    Serial.println(WiFi.localIP());
    } 
void loop() {
  Serial.println("连接服务器");
  if (client.connect(serverIP,serverPort)) //我们连接服务器对应的IP地址和端口
  { 
    Serial.println("连接服务器成功");
    while (client.connected() || client.available()) //如果已连接,或有收到的未读取的数据 
    { 
      if (client.available()) //如果有收到数据
      { 
        char x = client.read(); //读取服务器发送的数据
        if(x=='A'){
           digitalWrite(led, HIGH); 
          }
        else if(x=='B'){
           digitalWrite(led, LOW);
          }
        }
     } 
        Serial.println("关闭当前连接");
        client.stop(); //关闭客户端 
    } 
    else { 
          Serial.println("连接服务器失败");
          client.stop(); //关闭客户端 
          } 
          delay(5000); 
}

三.UDP双向通讯 :
1.服务端代码

#include <WiFi.h>
#include <WiFiUdp.h>//调用WIFIUDP库
WiFiUDP Udp; // 创建wifiUdp
char Rdata[255];//接收客户端发送的字符串
String readUART="";//串口接收存储的字符串
unsigned int localPort = 2001;//通讯端口
const char * ssid = "********";//家中路由器名称
const char * password = "********";//家中路由器密码
void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);//将WiFi设置为STA站点模式
  WiFi.begin(ssid, password);//打开WIFI,连接到家里的路由器
  while (WiFi.status() != WL_CONNECTED)//等待连接
  {
    delay(500);
    Serial.print(".");
  }
  if(Udp.begin(localPort)){//启动Udp监听服务
    Serial.println("监听开始");
    Serial.printf("现在收听IP:%s, UDP端口:%d\n", WiFi.localIP().toString().c_str(), localPort);//输出服务器的IP地址和端口
  }else{
    Serial.println("监听失败");
  }
}

void loop() {
    int Shu = Udp.parsePacket();//接收收到的数据包大小
    if (Shu>0)//判断是否有数据
    {
      Serial.printf("已收到 %d 字节%s, 端口 %d\n", Shu, Udp.remoteIP().toString().c_str(), Udp.remotePort());//串口输出接收到的数据数量,发送客户端的IP和端口
      Udp.read(Rdata, 255);//读取接收到的数据
      Serial.printf(Rdata);//串口输出接收到的数据
    }
     Shu=0;
    if (Serial.available())// 我们判断串口是否有数据
         {
           readUART=Serial.readString();//读取串口发送来的字符串
           Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());//准备发送数据包,设置对应的IP地址和端口的客户端
           Udp.print(readUART);//将要发送的数据发送给客户端
           Udp.endPacket();//结束发送
           readUART = "";//将接收到的字符清空
         } 
}

2.客户端代码

#include <WiFi.h>
#include <WiFiUdp.h>//调用WIFIUDP库
WiFiUDP Udp;  // 创建wifiUdp
char Rdata[255];//接收服务器发送的字符串
String readUART="";//串口接收存储的字符串
unsigned int localPort = 2002;//通讯端口
const char * ssid = "********";//家中路由器名称
const char * password = "********";//家中路由器密码
IPAddress ipServidor(192, 168, 3, 2);   // 服务器默认IP地址设置
/* 
 客户端的IP地址必须与服务器不同,否则会与客户端连接发生冲突
 */
IPAddress ipCliente(192, 168, 3, 59);//与服务器不同的IP
IPAddress Subnet(255, 255, 255, 0);

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA); //将WiFi设置为STA站点模式
  WiFi.begin(ssid, password);//打开WIFI,连接到家里的路由器
  while (WiFi.status() != WL_CONNECTED)//等待连接
  {
    delay(500);
    Serial.print(".");
  }
  Serial.printf("已连接");
  WiFi.config(ipCliente, ipServidor, Subnet);//设置WIFI连接的本机IP和服务器IP,和网络掩码
  Udp.begin(localPort);//打开端口
}

void loop() {   
    int Shu = Udp.parsePacket();//接收收到的数据包大小
    if (Shu)//判断是否有数据
    {
      Serial.printf("已收到 %d 字节%s, 端口 %d\n", Shu, Udp.remoteIP().toString().c_str(), Udp.remotePort());//串口输出接收到的数据数量,发送客户端的IP和端口
      Udp.read(Rdata, 255);//读取接收到的数据
      Serial.printf(Rdata);//串口输出接收到的数据
     }
     if (Serial.available())// 我们判断串口是否有数据
         {
           readUART=Serial.readString();//读取串口发送来的字符串
           Udp.beginPacket(ipServidor,localPort);//准备发送数据包,设置对应的IP地址和端口的客户端
           Udp.print(readUART);//将要发送的数据发送给客户端
           Udp.endPacket();//结束发送
           readUART = "";//将接收到的字符清空
         } 
}

十四.外部设备的使用

项目名称观看地址(感谢 MJKDZ老师的分享)
1. 8位led灯的控制第一节
2.三色发光二极管RGB led第二节
3.门磁开关的使用第三节
4.水位开关第四节
5.外部触摸开关第五节
6.震动传感器第六节
7.人体感应模块第七节
8.外部霍尔元件第八节
9.光电(光敏电阻)模块第九节
10.遥感模块第十节
11.蜂鸣器和压电陶瓷片使用第十一节
12.土壤湿度模块第十二节
13.继电器模块(注:在使用时要防止触电事故第十三节
14.直流有刷电机第十四节
15.直流水泵的使用第十五节
16.伺服电机(舵机)第十六节
17.数字彩色led(RGB)第十七节
18.超声波测距第十八节
19.AHT21温湿度模块第十九节
20.VEML7700环境光传感器第二十节
21.红外遥控收发模块第二十一节
22.oled显示屏第二十二节

以上内容为本人在学arduino时做的笔记,能力有限,可能有错误之处,望谅解。
也十分感谢up主的视频教程,非常详细。

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值