04-基础例程4

基础例程4

1、RGB彩灯

  • 实验介绍

​ WS2812B是一款智能控制的LED光源,控制电路和RGB芯片集成在一个5050组件的封装中。

​ 可以将多个RGB灯珠级联,如下图所示:

04-基础例程4_第1张图片

​ 3个最基本的颜色为红、绿、蓝(RGB),均是0-255。

​ 使用ESP32控制RGB彩灯循环点亮,且按照红、橙、黄、绿、青、蓝、紫的颜色循环变化。

  • 硬件设计

04-基础例程4_第2张图片

使用ESP32的16引脚进行控制

  • 软件设计
/* 深圳市普中科技有限公司(PRECHIN 普中)
   技术支持:www.prechin.net
 * 
 * 实验名称:RGB彩灯实验
 * 
 * 接线说明:RGB彩灯模块-->ESP32 IO
 *         WS-->(16)
 * 
 * 实验现象:程序下载成功后,RGB彩灯循环点亮且循环变化颜色
 * 
 * 注意事项:需要在软件中选择"项目"-->"加载库"-->"管理库"-->输入"Adafruit_NeoPixel"安装即可。
 * 
 */

#include "public.h"
#include 

// 设置灯珠数量
#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、数码管显示

  • 实验介绍

数码管的显示有共阳和共阴两种

04-基础例程4_第3张图片

由于多数码管需要的电流比较大,故选择使用TM1637驱动控制。共阳

04-基础例程4_第4张图片

GRIDx:位选信号,选择使用哪个数码管

SGIx:段选,选择使用哪个

CLK:时钟的输入

  • 硬件设计

04-基础例程4_第5张图片

  • 软件设计

使用的是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 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时钟

  • 硬件设计

04-基础例程4_第6张图片

由图可知,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 

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);
}

结果

04-基础例程4_第7张图片

5、DS18B20温度传感器

  • 实验介绍

​ 控制DS18B20数字温度传感器,实时读取环境温度。

​ 这是常用的数字温度传感器,输出为数字信号,具有体积小,硬件开销第,抗干扰能力强,精度高,多点组网的特点。

  • 硬件设计

04-基础例程4_第8张图片

​ 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 

#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 ℃
*/

04-基础例程4_第9张图片

平面朝内部;弧度朝外部。接下面3个引脚

6、DHT11温湿度传感器

  • 实验介绍

​ DHT11传感器具有小体积,极低的功耗,与DS18B20一样是单总线接口,为4针的单排引脚封装,连接方便。

04-基础例程4_第10张图片

​ 也可以使用DHT11模块[使用单线连接]

04-基础例程4_第11张图片

+:电源正极(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

你可能感兴趣的:(ESP32系列,单片机,嵌入式硬件)