基础例程4
1、RGB彩灯
- 实验介绍
WS2812B是一款智能控制的LED光源,控制电路和RGB芯片集成在一个5050组件的封装中。
可以将多个RGB灯珠级联,如下图所示:
3个最基本的颜色为红、绿、蓝(RGB),均是0-255。
使用ESP32控制RGB彩灯循环点亮,且按照红、橙、黄、绿、青、蓝、紫的颜色循环变化。
- 硬件设计
使用ESP32的16引脚进行控制
- 软件设计
/* 深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net
*
* 实验名称:RGB彩灯实验
*
* 接线说明:RGB彩灯模块-->ESP32 IO
* WS-->(16)
*
* 实验现象:程序下载成功后,RGB彩灯循环点亮且循环变化颜色
*
* 注意事项:需要在软件中选择"项目"-->"加载库"-->"管理库"-->输入"Adafruit_NeoPixel"安装即可。
*
*/
#include "public.h"
#include <Adafruit_NeoPixel.h>
// 设置灯珠数量
#define NUMPIXELS 5
// 设置输出数据引脚
#define PIN_NEOPIXEL 16
// 初始化灯珠控制实例
//在GPIO上创建了一个Adafruit_NeoPixel实例,包含了5个灯珠
Adafruit_NeoPixel pixels(NUMPIXELS, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);
// 当前灯珠指向
int16_t idx = 0;
// 启动设置
void setup() {
// 调试串口速率设置
Serial.begin(115200);
// 灯珠控制开始
pixels.begin();
// 设置亮度为255
pixels.setBrightness(255);
// 设置灯珠颜色,全部关闭
pixels.fill(0x000000);
delay(100);
// 设置灯珠颜色
pixels.fill(0xFF0000);
delay(100);
pixels.clear();
}
//(0,0,0)——(255,255,255),c1、c2、c3分别代表三个位
uint16_t c1 = 0;
uint16_t c2 = 0;
uint16_t c3 = 0;
uint16_t sign_bit =0;
uint16_t sign = 1;
/*
初始:(0,0,0)->(255,0,0)->(255,255,0)->(0,255,0)->(0,255,255)->(0,0,255)->(255,0,255)->(255,0,0)->(255,255,0)
白----------->红---橙--->黄---------->绿--------->青---------->蓝---紫--->品红-------->红---橙--->黄
后续:(0,255,0)->(0,255,255)->(0,0,255)->(255,0,255)->(255,0,0)->(255,255,0)->
绿--------->青---------->蓝---紫--->品红-------->红---橙--->黄
*/
// 循环主体程序
void loop() {
if(sign_bit == 0)
{
//这个if语句在循环体内只运行一次,该if语句及下方if语句可以用switch代替
if(sign)
{
c1++;
if(c1>=255)
sign=0;
}
else
{
c2++;
if(c2>=255)
{
sign=1;
sign_bit = 1;
}
}
}
if(sign_bit == 1)
{
if(sign)
{
c1--;
if(c1<=0)
sign=0;
}
else
{
c3++;
if(c3>=255)
{
sign=1;
sign_bit = 2;
}
}
}
if(sign_bit == 2)
{
if(sign)
{
c2--;
if(c2<=0)
sign=0;
}
else
{
c1++;
if(c1>=255)
{
sign=1;
sign_bit = 3;
}
}
}
if(sign_bit == 3)
{
if(sign)
{
c3--;
if(c3<=0)
sign=0;
}
else
{
c2++;
if(c2>=255)
{
sign=1;
sign_bit = 1;
}
}
}
//在这里注释的是一个一个将灯珠点亮并实现渐变
idx++;
if(idx > 5)
{
idx = 0;
}
pixels.setPixelColor(idx, pixels.Color(c1,c2,c3));
/*=======================================
全部点亮用该函数
pixels.fill(pixels.Color(c1,c2,c3));
=======================================*/
delay(10);//延时,改变速度
// 显示
pixels.show();
}
2、数码管显示
- 实验介绍
数码管的显示有共阳和共阴两种
由于多数码管需要的电流比较大,故选择使用TM1637驱动控制。共阳
GRIDx:位选信号,选择使用哪个数码管
SGIx:段选,选择使用哪个
CLK:时钟的输入
- 硬件设计
- 软件设计
使用的是Grove 4-Digit Display库
#include "TM1637.h"
#define CLK 16 //Set the CLK pin connection to the display
#define DIO 17 //Set the DIO pin connection to the display
TM1637 tm1637(CLK, DIO); //set up the 4-Digit Display.
int numCounter = 0;
bool dian = false;
void setup() {
// put your setup code here, to run once:
tm1637.init();
tm1637.point(1);//小数点开关,1为打开,0为关闭
tm1637.set(BRIGHT_TYPICAL);//BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;
}
void loop() {
// put your main code here, to run repeatedly:
for (numCounter = 0; numCounter < 9999; numCounter++) //Iterate numCounter
{
tm1637.display(0, (numCounter / 1000%10));
tm1637.display(1, (numCounter / 100%10));
tm1637.display(2, (numCounter / 10%10));
tm1637.display(3, (numCounter % 10));
dian = !dian;
tm1637.point(dian);
delay(200);
}
}
参考
ESP32 & TM1637显示4位数码管_esp32 tm1637_UPUPUPEveryday的博客-CSDN博客
arduino笔记28:使用TM1637四位数码管显示模块_tm1637引脚功能__低头写作业的博客-CSDN博客
3、RTC实时时钟
下载使用ESP32Time库
/* 深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net
*
* 实验名称:RTC实时时钟实验
*
* 接线说明:
*
* 实验现象:程序下载成功后,软件串口控制台间隔1S输出RTC实时时钟年月日时分秒星期
*
* 注意事项:需要在软件中选择"项目"-->"加载库"-->"管理库"-->输入"ESP32Time"安装即可。
*
*/
#include "public.h"
#include <ESP32Time.h>
ESP32Time rtc(3600); // offset in seconds GMT+1
void setup(){
Serial.begin(115200);
rtc.setTime(30, 24, 15, 17, 9, 2022);//2022年9月17日15点24分30秒
}
void loop(){
// Serial.println(rtc.getTime()); // (String) 15:24:38
// Serial.println(rtc.getDate()); // (String) Sun, Jan 17 2021
// Serial.println(rtc.getDate(true)); // (String) Sunday, January 17 2021
// Serial.println(rtc.getDateTime()); // (String) Sun, Jan 17 2021 15:24:38
// Serial.println(rtc.getDateTime(true)); // (String) Sunday, January 17 2021 15:24:38
// Serial.println(rtc.getTimeDate()); // (String) 15:24:38 Sun, Jan 17 2021
// Serial.println(rtc.getTimeDate(true)); // (String) 15:24:38 Sunday, January 17 2021
//
// Serial.println(rtc.getMicros()); // (long) 723546
// Serial.println(rtc.getMillis()); // (long) 723
// Serial.println(rtc.getEpoch()); // (long) 1609459200
// Serial.println(rtc.getSecond()); // (int) 38 (0-59)
// Serial.println(rtc.getMinute()); // (int) 24 (0-59)
// Serial.println(rtc.getHour()); // (int) 3 (0-12)
// Serial.println(rtc.getHour(true)); // (int) 15 (0-23)
// Serial.println(rtc.getAmPm()); // (String) pm
// Serial.println(rtc.getAmPm(true)); // (String) PM
// Serial.println(rtc.getDay()); // (int) 17 (1-31)
// Serial.println(rtc.getDayofWeek()); // (int) 0 (0-6)
// Serial.println(rtc.getDayofYear()); // (int) 16 (0-365)
// Serial.println(rtc.getMonth()); // (int) 0 (0-11)
// Serial.println(rtc.getYear()); // (int) 2021
// Serial.println(rtc.getLocalEpoch()); // (long) 1609459200 epoch without offset
Serial.println(rtc.getTime("%A, %B %d %Y %H:%M:%S")); // (String) returns time with specified format 星期-月-日-年 时-分-秒
// formating options http://www.cplusplus.com/reference/ctime/strftime/
delay(1000);
}
4、DS1302时钟
- 硬件设计
由图可知,J10端子的CLK、IO、CE引脚为DS1302的控制口,可将这些引脚与ESP32的引脚相连接
RTC时钟在断电后会没有。但是DS1302始终会一直存在
- 软件设计
需要使用RTCLib by NeiroN库
/* 深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net
*
* 实验名称:DS1302实时时钟实验
*
* 接线说明:DS1302时钟模块-->ESP32 IO
(CE)-->(23)
(IO)-->(19)
(CK)-->(18)
*
* 实验现象:程序下载成功后,软件串口控制台间隔1S输出DS1302实时时钟年月日时分秒星期
*
* 注意事项:需要在软件中选择"项目"-->"加载库"-->"管理库"-->输入"RTCLib by NeiroN"安装即可。
* API函数使用参考https://github.com/NeiroNx/RTCLib
*
*/
#include "public.h"
#include <RTClib.h>
DS1302 rtc(23, 18, 19);
char buf[20];
void setup(){
Serial.begin(115200);
rtc.begin();
if (!rtc.isrunning())
{
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(__DATE__, __TIME__));
}
rtc.adjust(DateTime(__DATE__, __TIME__));
}
void loop(){
DateTime now = rtc.now(); //获取电脑本地时间
Serial.println(now.tostr(buf));
delay(1000);
}
结果
5、DS18B20温度传感器
- 实验介绍
控制DS18B20数字温度传感器,实时读取环境温度。
这是常用的数字温度传感器,输出为数字信号,具有体积小,硬件开销第,抗干扰能力强,精度高,多点组网的特点。
- 硬件设计
DS18B20模块DS18B20的引脚与J2的对应引脚相连,可以将该引脚与ESP32的GPIO相连接。
- 软件设计
/* 深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net
*
* 实验名称:DS18B20温度传感器实验
*
* 接线说明:DS18B20温度传感器模块-->ESP32 IO
(DS)-->(13)
*
* 实验现象:程序下载成功后,软件串口控制台间隔1S输出DS18B20温度传感器采集的温度
*
* 注意事项:需要在软件中选择"项目"-->"加载库"-->"添加一个.ZIP库..."-->选择到本实验目录下的两个压缩文件包“OneWire-master.zip”和“Arduino-Temperature-Control-Library-master.zip”安装即可。
* 该库使用方法可参考:https://blog.csdn.net/Naisu_kun/article/details/88420357
*/
#include "public.h"
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 13 //1-wire数据总线连接
OneWire oneWire(ONE_WIRE_BUS); //声明
DallasTemperature sensors(&oneWire); //声明
void setup(){
Serial.begin(115200);
sensors.begin();
}
void loop(){
Serial.println("发起温度转换");
sensors.requestTemperatures(); //向总线上所有设备发送温度转换请求,默认情况下该方法会阻塞
Serial.println("温度转换完成");
float tempC = sensors.getTempCByIndex(0); //获取索引号0的传感器摄氏温度数据
if (tempC != DEVICE_DISCONNECTED_C) //如果获取到的温度正常
{
Serial.print("当前温度是: ");
Serial.print(tempC);
Serial.println(" ℃\n");
}
delay(2000);
}
/*
发起温度转换
温度转换完成
当前温度是: 26.31 ℃
发起温度转换
温度转换完成
当前温度是: 26.37 ℃
发起温度转换
温度转换完成
当前温度是: 26.31 ℃
*/
平面朝内部;弧度朝外部。接下面3个引脚
6、DHT11温湿度传感器
- 实验介绍
DHT11传感器具有小体积,极低的功耗,与DS18B20一样是单总线接口,为4针的单排引脚封装,连接方便。
也可以使用DHT11模块[使用单线连接]
+:电源正极(3-5.5V);OUT:数据库;-:电源负极。
DHT11性价比较高,但是精度与响应速度有点低,有高级的DHT22
- 硬件设计
同上面的实验5-DS18B20温度传感器。将DHT11插入位置。ESP32引脚与J2-DS引脚相连接
- 软件设计
主函数
/* 深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net
*
* 实验名称:DHT11温湿度传感器实验
*
* 接线说明:DHT11温湿度传感器模块-->ESP32 IO
(VCC)-->(5V)
(DATA)-->(27)
(GND)-->(GND)
*
* 实验现象:程序下载成功后,软件串口控制台间隔2S输出DHT11温湿度传感器采集的温度和湿度
*
* 注意事项:
*/
#include "public.h"
#include "dht11.h"
u8 temp;
u8 humi;
void setup(){
Serial.begin(115200);
while(DHT11_Init()) //检测是否纯在
{
Serial.printf("DHT11 Check Error!\r\n");
delay(500);
}
Serial.printf("DHT11 Check OK!\r\n");
}
void loop(){
DHT11_Read_Data(&temp,&humi);
Serial.printf("温度=%d°C 湿度=%d%%RH\r\n",temp,humi);
delay(2000);
}
DHT11
#include "dht11.h"
//复位DHT11
void DHT11_Rst()
{
DHT11_MODE_OUT; //SET OUTPUT
DHT11_DQ_LOW; //拉低DQ
delay(20); //拉低至少18ms
DHT11_DQ_HIGH; //DQ=1
delayMicroseconds(30); //主机拉高20~40us
}
//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
u8 DHT11_Check()
{
u8 retry=0;
DHT11_MODE_IN;//SET INPUT
while (DHT11_READ&&retry<100)//DHT11会拉低40~50us
{
retry++;
delayMicroseconds(1);
};
if(retry>=100)return 1;
else retry=0;
while (!DHT11_READ&&retry<100)//DHT11拉低后会再次拉高40~50us
{
retry++;
delayMicroseconds(1);
};
if(retry>=100)return 1;
return 0;
}
//从DHT11读取一个位
//返回值:1/0
u8 DHT11_Read_Bit(void)
{
u8 retry=0;
while(DHT11_READ&&retry<100)//等待变为低电平 12-14us 开始
{
retry++;
delayMicroseconds(1);
}
retry=0;
while(!DHT11_READ&&retry<100)//等待变高电平 26-28us表示0,116-118us表示1
{
retry++;
delayMicroseconds(1);
}
delayMicroseconds(40);//等待40us
if(DHT11_READ)return 1;
else return 0;
}
//从DHT11读取一个字节
//返回值:读到的数据
u8 DHT11_Read_Byte(void)
{
u8 i,dat;
dat=0;
for (i=0;i<8;i++)
{
dat<<=1;
dat|=DHT11_Read_Bit();
}
return dat;
}
//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
u8 DHT11_Read_Data(u8 *temp,u8 *humi)
{
u8 buf[5];
u8 i;
DHT11_Rst();
if(DHT11_Check()==0)
{
for(i=0;i<5;i++)//读取40位数据
{
buf[i]=DHT11_Read_Byte();
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
*humi=buf[0];
*temp=buf[2];
}
}else return 1;
return 0;
}
//DHT11初始化
//返回0:初始化成功,1:失败
u8 DHT11_Init(void)
{
DHT11_Rst();
return DHT11_Check();
}
//.h
#ifndef _dht11_H
#define _dht11_H
#include "public.h"
//DHT11管脚定义
#define dht11_pin 27
#define DHT11_DQ_LOW digitalWrite(dht11_pin, LOW)
#define DHT11_DQ_HIGH digitalWrite(dht11_pin, HIGH)
#define DHT11_READ digitalRead(dht11_pin)
#define DHT11_MODE_IN pinMode(dht11_pin, INPUT_PULLUP)
#define DHT11_MODE_OUT pinMode(dht11_pin, OUTPUT)
//函数声明
void DHT11_IO_OUT(void);
void DHT11_IO_IN(void);
u8 DHT11_Init(void);
void DHT11_Rst(void);
u8 DHT11_Check(void);
u8 DHT11_Read_Bit(void);
u8 DHT11_Read_Byte(void);
u8 DHT11_Read_Data(u8 *temp,u8 *humi);
#endif