Arduino ESP32 oled显示,增量式编码器测距程序

    ESP32 14引脚接编码器A,13引脚接编码器B,21、22为I2C默认引脚,程序根据编码器A触发ESP32的22脚中断,然后判断编码器B在ESP32的21脚状态是高电平还是低电平,来决定编码器是正转还是反转,也就是数值应该加还是减。

     程序设计为编码器转一圈为1000个脉冲也就是编码器分辨率为1000,编码器连接轮转一圈和编码器转一圈为同速,如果你在实际应用当中要看编码器分辨率和连接轮和编码器之间有没有变速器,如果不愿意计算,拿个尺子让编码器转动一米,看记录了多少个脉冲,来修改自己的程序。

 

#include <Arduino.h>
#include <U8g2lib.h>
#include <esp_task_wdt.h>
#include <SSD1306Wire.h>

// 自定义CLK和SDA引脚
#define OLED_CLK 22
#define OLED_SDA 21
#define WDT_TIMEOUT 10000  //定义看门狗时间 单位毫秒
// 构造对象
U8G2_SSD1306_128X64_NONAME_F_SW_I2C OLED(U8G2_R0, OLED_CLK, OLED_SDA, U8X8_PIN_NONE);
SSD1306Wire display(0x3c, 21, 22);

int zhong_duan_yin_jiao = 14;
int pan_duan_yin_jiao = 13;
volatile int zong_ma_zhi = 0;
int hao_mi, mi, qian_mi;
int xian_shi_yi_ci;

void TaskBlink1(void *pvParameters);
void TaskBlink2(void *pvParameters);
void TaskBlink3(void *pvParameters);


const unsigned char qian_xian_shi[] = {
  0x00, 0x08, 0x00, 0x1F, 0xFC, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xFF, 0x7F,
  0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /*"千",0*/
};
const unsigned char mi_xian_shi[] = {
  0x80, 0x00, 0x84, 0x10, 0x88, 0x10, 0x90, 0x08, 0x90, 0x04, 0x80, 0x00, 0xFE, 0x3F, 0xC0, 0x01,
  0xA0, 0x02, 0xA0, 0x02, 0x90, 0x04, 0x88, 0x08, 0x84, 0x10, 0x83, 0x60, 0x80, 0x00, 0x80, 0x00, /*"米",1*/
};
const unsigned char hao_xian_shi[] = {
  0x80, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xF8, 0x0F, 0x08, 0x08, 0xF8, 0x0F, 0x00, 0x00, 0xFE, 0x7F,
  0x02, 0x40, 0x81, 0x2F, 0x7C, 0x00, 0xC0, 0x0F, 0x7C, 0x00, 0xC0, 0x5F, 0x7E, 0x40, 0x80, 0x7F, /*"毫",0*/

};

void zhong_duan() {
  delayMicroseconds(10);//中断内可以使用的延时微妙
  if (digitalRead(zhong_duan_yin_jiao) == 0)  //现在是低电平
  {
    if (digitalRead(pan_duan_yin_jiao) == 1) {
      if (zong_ma_zhi < 1000) {
        zong_ma_zhi++;
        hao_mi = zong_ma_zhi;
      } else {
        if (mi < 1000) {
          mi++;
          hao_mi = 0;
          zong_ma_zhi = 0;
        } else {
          qian_mi++;
          mi = 0;
          hao_mi = 0;
          zong_ma_zhi = 0;
        }
      }
    }
    if (digitalRead(pan_duan_yin_jiao) == 0) {
      if (zong_ma_zhi > 0) {
        zong_ma_zhi--;
        hao_mi = zong_ma_zhi;
      } else {
        if (mi > 0) {
          mi--;
          zong_ma_zhi = 999;
          hao_mi = 999;
        } else {
          if (qian_mi > 0) {
            qian_mi--;
            mi = 999;
            hao_mi = 999;
            zong_ma_zhi = 999;
          } else {
            qian_mi = 0;
            mi = 0;
            hao_mi = 0;
            zong_ma_zhi = 0;
          }
        }
      }
    }
  }
}


void qing_pin(int x0,int y0,int x1,int y1)
{
  int i=0;
  int j=0;
  for(i=x0;i<x1;i++)
  {
    display.clearPixel(i,j);
    display.display();
    for(j=y0;j<y1;j++)
    {
      display.clearPixel(i,j);
      display.display();
    }
  }
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  esp_task_wdt_init(WDT_TIMEOUT, true);  //初始化看门狗
  pinMode(pan_duan_yin_jiao, INPUT_PULLUP);
  pinMode(zhong_duan_yin_jiao, INPUT_PULLUP);                                        //设定引脚上拉_PULLUP  设定引脚下拉_PULLDOWN
  attachInterrupt(digitalPinToInterrupt(zhong_duan_yin_jiao), zhong_duan, FALLING);  //中断指定引脚函数LOW低电平触发CHANGE电平变化RISING上升沿触发FALLING下降沿触发HIGH高电平触发
  
  display.init();                           //初始化屏幕
  display.flipScreenVertically();           //反转180度
  display.setFont(ArialMT_Plain_16);        //字体大小
  /*OLED.begin();                             //初始化屏幕
  OLED.enableUTF8Print();                   //设置字体
  OLED.setFont(u8g2_font_wqy16_t_gb2312b);  //设置字体gb2312字符数7539字节208228 ,chinese1字符数411字节9491
  //OLED.setFontDirection(0);//方向反转角度*/
  
  xTaskCreate(
    TaskBlink1, "TaskBlink1"  // 任务名
    ,
    4096  // This stack size can be checked & adjusted by reading the Stack Highwater
    ,
    NULL, 0  // 任务优先级, with 3 (configMAX_PRIORITIES - 1) 是最高的,0是最低的.
    ,
    NULL);

  xTaskCreate(
    TaskBlink2, "TaskBlink2"  //任务名
    ,
    4096  // 栈大小
    ,
    NULL, 0  // 任务优先级
    ,
    NULL);

  xTaskCreate(
    TaskBlink3, "TaskBlink3"  //任务名
    ,
    4096  // 栈大小
    ,
    NULL, 0  // 任务优先级
    ,
    NULL);  
}

void loop() {
  // put your main code here, to run repeatedly:
}

void TaskBlink1(void *pvParameters)  // 多线程1 主程序
{
  while (1)  // for死循环// 多线程,每个任务必须是死循环
  {

    display.clear();
    display.drawIco16x16(0, 0, qian_xian_shi, 0);
    display.drawIco16x16(17, 0, mi_xian_shi, 0);
    display.drawIco16x16(17, 17, mi_xian_shi, 0);
    display.drawIco16x16(0, 34, hao_xian_shi, 0);
    display.drawIco16x16(17, 34, mi_xian_shi, 0);
    display.drawString(34, 0, String(qian_mi));
    display.drawString(34, 17, String(mi));
    display.drawString(34, 34, String(hao_mi));
    display.display();
  }
}

void TaskBlink2(void *pvParameters)  // 多线程1 主程序
{
  while (1)  // for死循环// 多线程,每个任务必须是死循环
  {
    //OLED.setBufferCurrTileRow(3);//只清除第四行数字
    /*OLED.clearBuffer();
    OLED.setCursor(0, 0);
    OLED.print("千米");
    OLED.setCursor(34, 0);
    OLED.print(qian_mi);
    OLED.setCursor(17, 17);
    OLED.print("米");
    OLED.setCursor(34, 17);
    OLED.print(mi);
    OLED.setCursor(0, 34);
    OLED.print("毫米");
    OLED.setCursor(34, 34);
    OLED.print(hao_mi);
    OLED.sendBuffer();

    Serial.print(zong_ma_zhi);
    Serial.print("-");
    Serial.print(qian_mi);
    Serial.print("-");
    Serial.print(mi);
    Serial.print("-");
    Serial.println(hao_mi);*/
    /*delay(1000);

    OLED.setBufferCurrTileRow(4);//只清除第四行数字
    OLED.clearBuffer();
    OLED.sendBuffer();
    delay(1000);*/
  }
}


void TaskBlink3(void *pvParameters)  // 多线程1 主程序
{
  while (1)  // for死循环// 多线程,每个任务必须是死循环
  {
    Serial.print(zong_ma_zhi);Serial.print("-");Serial.print(qian_mi);Serial.print("-");Serial.print(mi);Serial.print("-");Serial.println(hao_mi);

  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值