2208|5

136

帖子

2

TA的资源

一粒金砂(高级)

楼主
 

【得捷电子Follow me第2期】基于ESP32S3-FHR的联网天气时钟 [复制链接]

  本帖最后由 慕容雪花 于 2023-9-21 09:58 编辑

基于ESP32S3-FHR的联网天气时钟

Adafruit 是国外一家非常知名的创客公司。本次FOLLOW-ME活动提供的Adafruit ESP32-S3 TFT Feather是一款富有特色的开源硬件,开发板使用乐鑫ESP32-S3芯片,支持WiFi和蓝牙能,自带高清TFT彩色显示屏。板载丰富的资源与外设接口。

  • 搭载 Xtensa® 32 位 LX7 双核处理器,主频高达 240 MHz,内置 512 KB SRAM (TCM),具有 45 个可编程 GPIO 管脚和丰富的通信接口,集成 2.4 GHz Wi-Fi 和 Bluetooth 5 (LE),配备原生 USB,可用作键盘/鼠标、MIDI 设备、磁盘驱动器等;
  • 获得FCC / CE认证,带有4 MB闪存和2 MB PSRAM;
  • 彩色 1.14“ IPS TFT,240x135 像素——采用 ST7789 芯片组的高清彩色显示屏,可从任何角度观看;
  • 电源选项 - USB C 型或锂聚合物电池,通过 USB-C 供电时可为内置电池充电;
  • LiPoly 电池监控器 - LC709203 芯片主动监控电池的电压和充电状态/通过 I2C 报告电池电量百分比;
  • 重置和DFU(BOOT0)按钮以进入ROM引导加载程序;
  • 内置原生USB串行端口,不需要单独的电缆,串行调试输出引脚(可选,用于检查硬件串行调试控制台);
  • 用于 I2C 设备的 STEMMA QT 连接器,具有可切换电源,可进入低功耗模式;
  • 板载 NeoPixel 具有引脚控制电源,可实现低功耗,用于多种状态显示;
  • 在深度睡眠模式下,可从Lipoly连接获得80~100uA的电流消耗;
  • 可与Arduino或CircuitPython一起使用。

这款板卡的实物图如下:

 

 

这款板卡的引脚图如下:

 

电路原理图如下:

 

Arduino环境搭建:

ESP32S3使用自带的USB替代传统的串口芯片进行代码烧录,本文提供了简短视频:

任务0-Arduino环境起步

 

任务1:控制屏幕显示中文(要求:完成屏幕的控制,并且能显示中文

首先是屏幕的驱动,本文选择的是Arduino开发平台,在库管理器里面找到本开发板的屏幕驱动库。

 

 

之后在源代码中包含相应的头文件:

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>

接着进行屏幕初始化:

void setup(void) {
  Serial.begin(9600);
  Serial.println("***************************************************");
  Serial.println(F("Hello! Feather TFT Test. Today is August 31th."));
  Serial.println("***************************************************");

  // turn on backlite
  pinMode(TFT_BACKLITE, OUTPUT);
  digitalWrite(TFT_BACKLITE, HIGH);

  // turn on the TFT / I2C power supply
  pinMode(TFT_I2C_POWER, OUTPUT);
  digitalWrite(TFT_I2C_POWER, HIGH);
  delay(10);

  // initialize TFT
  tft.init(135, 240); // Init ST7789 240x135
  tft.setRotation(3);
  tft.fillScreen(ST77XX_BLACK);

  Serial.println(F("Initialized"));
  
}

其次是中文显示,参考了论坛网友[1]的字模提取方案,针对要显示的中文,提前准备好16*16大小的字模,

 

在源代码中,

const uint8_t PROGMEM str_f_DIAN[]={0x00,0x00,0x00,0x00,0x03,0x00,0x02,0x00,0x02,0x70,0x3F,0xB0,0x12,0x30,0x17,0xA0,0x1A,0x20,0x13,0xC0,0x0E,0x00,0x02,0x04,0x02,0x04,0x01,0xFC,0x00,0x00,0x00,0x00};/*"电",0*/
const uint8_t PROGMEM str_f_ZI[]={0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0x20,0x00,0x40,0x01,0x80,0x00,0x9C,0x0F,0xE0,0x30,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x04,0x80,0x03,0x00,0x00,0x00};/*"子",1*/
const uint8_t PROGMEM str_f_GONG[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x0F,0xC0,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x01,0x00,0x01,0x00,0x01,0x7E,0x7E,0x80,0x00,0x00,0x00,0x00,0x00,0x00};/*"工",2*/
const uint8_t PROGMEM str_f_CHENG[]={0x00,0x00,0x00,0x00,0x02,0x08,0x04,0xFC,0x0C,0x48,0x04,0x58,0x1C,0x20,0x68,0x08,0x16,0x70,0x1A,0x20,0x24,0xF0,0x44,0x20,0x04,0x3E,0x0B,0xC0,0x00,0x00,0x00,0x00};/*"程",3*/
const uint8_t PROGMEM str_f_SHI[]={0x00,0x00,0x00,0x00,0x00,0x30,0x01,0x30,0x01,0x20,0x09,0x20,0x09,0x2E,0x0F,0xF0,0x39,0x20,0x09,0x20,0x09,0xC0,0x08,0x00,0x08,0x78,0x0F,0x80,0x00,0x00,0x00,0x00};/*"世",4*/
const uint8_t PROGMEM str_f_JIE[]={0x00,0x00,0x00,0x00,0x17,0xF0,0x09,0x10,0x0F,0xE0,0x09,0x20,0x0F,0xC0,0x06,0x40,0x04,0x20,0x0C,0x58,0x14,0x44,0x64,0x40,0x04,0x40,0x08,0x40,0x10,0x40,0x00,0x00};/*"界",5*/
const uint8_t PROGMEM str_f_DE[]={0x00,0x00,0x00,0x00,0x04,0x78,0x09,0x88,0x10,0xC8,0x24,0xB0,0x08,0x40,0x19,0xF0,0x10,0x20,0x30,0xFE,0x53,0x10,0x10,0x90,0x10,0x10,0x10,0x10,0x00,0x70,0x00,0x20};/*"得",6*/
const uint8_t PROGMEM str_f_JIE2[]={0x00,0x00,0x00,0x40,0x08,0x40,0x08,0x70,0x08,0xC0,0x0C,0x78,0x38,0xDC,0x0D,0xF0,0x0A,0x70,0x18,0xC0,0x69,0x78,0x09,0xC0,0x0A,0x40,0x1C,0x38,0x00,0x0E,0x00,0x00};/*"捷",7*/
const uint8_t PROGMEM str_f_WANG[]={0x00,0x00,0x00,0x00,0x00,0x10,0x1F,0xF8,0x10,0x08,0x11,0x28,0x12,0x48,0x16,0xC8,0x12,0xA8,0x15,0x88,0x18,0x08,0x10,0x08,0x10,0x28,0x10,0x18,0x00,0x00,0x00,0x00};/*"网",10*/
const uint8_t PROGMEM str_f_LUO[]={0x00,0x00,0x00,0x00,0x00,0x40,0x08,0x40,0x10,0x80,0x14,0xF0,0x25,0x20,0x18,0xE0,0x10,0x60,0x39,0x98,0x02,0x24,0x0D,0xD8,0x71,0x10,0x01,0x30,0x00,0xC0,0x00,0x00};/*"络",11*/
const uint8_t PROGMEM str_f_LIAN[]={0x00,0x00,0x00,0x80,0x00,0xC0,0x10,0xB0,0x0B,0xC0,0x01,0x40,0x01,0x50,0x13,0xE0,0x10,0x44,0x17,0xF8,0x10,0x40,0x10,0x40,0x7C,0x40,0x03,0xFE,0x00,0x38,0x00,0x00};/*"连",12*/
const uint8_t PROGMEM str_f_JIE3[]={0x00,0x00,0x08,0x00,0x08,0x60,0x08,0x20,0x08,0x38,0x0C,0xD0,0x38,0xA0,0x08,0xAC,0x0D,0xD0,0x18,0x46,0x6F,0xF8,0x08,0xA0,0x08,0x70,0x08,0xC8,0x0B,0x04,0x00,0x00};/*"接",13*/
const uint8_t PROGMEM str_f_ZHONG[]={0x00,0x00,0x01,0x00,0x01,0x80,0x01,0x00,0x01,0x38,0x1F,0xD8,0x11,0x08,0x11,0x10,0x09,0xF0,0x0F,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00};/*"中",14*/

最后可以通过调用tft.drawBitmap()像绘制图片一下把想要显示的中文显示出来。

  tft.fillScreen(ST77XX_BLACK);
  tft.setCursor(0, 0);

  static uint8_t i, j;
  tft.drawBitmap(0,    0, str_f_DIAN, 16, 16, ST77XX_GREEN);
  tft.drawBitmap(16,   0, str_f_ZI, 16, 16, ST77XX_GREEN);
  tft.drawBitmap(16*2, 0, str_f_GONG, 16, 16, ST77XX_GREEN);
  tft.drawBitmap(16*3, 0, str_f_CHENG, 16, 16, ST77XX_GREEN);
  tft.drawBitmap(16*4, 0, str_f_SHI, 16, 16, ST77XX_GREEN);
  tft.drawBitmap(16*5, 0, str_f_JIE, 16, 16, ST77XX_GREEN);
  
  tft.drawBitmap(16*7,  0, str_f_DE, 16, 16, ST77XX_GREEN);
  tft.drawBitmap(16*8,  0, str_f_JIE2, 16, 16, ST77XX_GREEN);
  tft.drawBitmap(16*9,  0, str_f_DIAN, 16, 16, ST77XX_GREEN);
  tft.drawBitmap(16*10, 0, str_f_ZI, 16, 16, ST77XX_GREEN);
  
  tft.drawBitmap(16*0, 32, str_f_WANG, 16, 16, ST77XX_GREEN);
  tft.drawBitmap(16*1, 32, str_f_LUO,  16, 16, ST77XX_GREEN);
  tft.drawBitmap(16*2, 32, str_f_LIAN, 16, 16, ST77XX_GREEN);
  tft.drawBitmap(16*3, 32, str_f_JIE3,  16, 16, ST77XX_GREEN);
  tft.drawBitmap(16*4, 32, str_f_ZHONG, 16, 16, ST77XX_GREEN);

效果展示:

 

代码: Proj1-graphicstest_feather_esp32s3_tft_CN_V2.ino (13.45 KB, 下载次数: 4)
 

任务2:网络功能使用(任务要求:完成网络功能的使用,能够创建热点和连接到WiFi

要使用Wi-Fi相关功能,首先要包含如下头文件:

#include <WiFi.h>

针对STA与AP混合模式,需要定义各自的SSID与PASSWORD:

// Set WiFi credentials
#define WIFI_SSID "TP-LINK_XXX"
#define WIFI_PASS "XXXXXXXXXXX"

// Set AP credentials
#define AP_SSID "Adafruit-S3-FTHR"
#define AP_PASS "followme"

接着启动AP与STA模式:

// Begin Access Point
  WiFi.mode(WIFI_AP_STA);
  WiFi.softAP(AP_SSID, AP_PASS);

  // Begin WiFi
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  // Connecting to WiFi...
  Serial.print("Connecting to ");
  Serial.print(WIFI_SSID);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(100);
    Serial.print(".");
  }

STA模式启动成功后,开发板连接到指定的AP即家里的路由器。可以看到S3已经有了自己对IP地址,并且电脑也连接到了路由器,可以PING通S3开发板。

 

接下来测试一下AP接入点模式,即电脑或者手机可以连接到S3开发板。

 

任务2-Wi-Fi-AP-STA

可以看到电脑已经连接成功到S3开发板提供的AP。

实物展示:

 

代码: Proj2-Wi-Fi-AP-STA_V1 - eeworld.ino (21.73 KB, 下载次数: 3)

 

任务3:控制WS2812B(要求:使用按键控制板载Neopixel LED的显示和颜色切换

本节介绍了如何在Arduino环境下驱动本次活动板卡自带的一颗WS2812 RGB灯珠(即Adafruit称之为NeoPixel)

 

板载的这颗NeoPixel与S3的IO33引脚相连接,可以从电路图看出:

 

首先在库管理器中下载“Adafruit NeoPixel”库:

 

之后包含该库的头文件:

#include <Adafruit_NeoPixel.h>

//NeoPixel Related:
// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1:
#define LED_PIN     33

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT  1

// NeoPixel brightness, 0 (min) to 255 (max)
#define BRIGHTNESS 50 // Set BRIGHTNESS to about 1/5 (max = 255)

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);

题目要求按键控制NeoPixel,板载一个RST按键,一个BOOT按键。BOOT连接到GPIO0,在程序运行期间可以拿来当作普通的GPIO使用。并且使能上拉,配置中断输入源。

Setup(){
 pinMode(BUTTON_BOOT, INPUT_PULLUP);
 attachInterrupt( digitalPinToInterrupt(BUTTON_BOOT), onButtonPressed, FALLING);

} 

void onButtonPressed(void){
    colorSelector = buttonPressedNum%4;
    buttonPressedNum++;  
    Serial.println("Inside ISR. buttonPressedNum = " + String(buttonPressedNum));
    
}

void loop() { 
  switch(colorSelector){
    case 0:
      tft.fillRect(16*7,64,32,16,ST77XX_BLACK);
      tft.drawBitmap(16*7, 64, str_f_HONG, 16, 16, ST77XX_RED);
      tft.drawBitmap(16*8, 64, str_f_SE, 16, 16, ST77XX_RED);
      tft.fillCircle(16*11, 64, 20, ST77XX_RED);
      colorWipe(strip.Color(255,   0,   0)     , 1000); // Red
      break;
      
    case 1:
      tft.fillRect(16*7,64,32,16,ST77XX_BLACK);
      tft.drawBitmap(16*7, 64, str_f_LV, 16, 16, ST77XX_GREEN);
      tft.drawBitmap(16*8, 64, str_f_SE, 16, 16, ST77XX_GREEN);
      tft.fillCircle(16*11, 64, 20, ST77XX_GREEN);
      colorWipe(strip.Color(  0, 255,   0)     , 1000); // Green
      break;

    case 2:
      tft.fillRect(16*7,64,32,16,ST77XX_BLACK);
      tft.drawBitmap(16*7, 64, str_f_LV, 16, 16, ST77XX_BLUE);
      tft.drawBitmap(16*8, 64, str_f_SE, 16, 16, ST77XX_BLUE);
      tft.fillCircle(16*11, 64, 20, ST77XX_BLUE);
      colorWipe(strip.Color(  0,   0, 255)     , 1000); // Blue
      break; 

    case 3:
      tft.fillRect(16*7,64,32,16,ST77XX_BLACK);
      tft.fillCircle(16*11, 64, 20, ST77XX_BLACK);
      rainbowFade2White(3, 3, 1);
      break;
      
    default:
      break;
}

效果展示:

任务3-视频-按键屏幕与RGB操作

代码: Proj3-RGBWstrandtest_V4.ino (20.17 KB, 下载次数: 2)
 

任务4:分任务1:日历&时钟——完成一个可通过互联网更新的万年历时钟,并显示当地的天气信息

之前注册过心知天气,所以任务4的天气部分继续使用这个免费的天气API服务。如果是第一次使用心知天气,需要去注册然后获取key。

本任务我选择的API是:https://seniverse.yuque.com/hyper_data/api_v3/nyiu3t。获取指定城市的天气实况。付费用户可获取全部数据,免费用户只返回天气现象文字、代码和气温 3 项数据。

 

//心知天气
const char *host = "api.seniverse.com";
const char *privateKey = "替换成自己的KEY哦";
const char *city = "shanghai";
const char *language = "en";

struct WetherData{
    char city[32];
    char weather[64];
    char high[32];
    char low[32];
    char humi[32];
};

 

在Arduino环境下,需要使用到ArduinoJson库来解析心知天气返回的JSON格式的数据,因此先要安装一下这个库。

 

#include <ArduinoJson.h>

 

在尝试FreeRTOS的过程中,遇到了问题,板卡反复重启。后来把线程的Stack从1024字节调整到4096字节,问题解决。

 

对于天气和时间,分别需要与心知天气服务器与NTP时间服务器进行交互,因此在setup()里面分别创建两个线程来对应处理。

  xTaskCreatePinnedToCore(
    Task_Weather_Get
    ,  "Task_Weather_Get"
    ,  4096  // Stack size
    ,  NULL
    ,  1  // Priority
    ,  NULL 
    ,  0);  

  xTaskCreatePinnedToCore(
    Task_NTP_Time_Get
    ,  "Task_NTP_Time_Get"
    ,  4096  // Stack size
    ,  NULL
    ,  1  // Priority
    ,  NULL 
    ,  0);

天气获取核心代码:

void Task_Weather_Get(void *pvParameters){
  (void) pvParameters;
  // 建立心知天气API当前天气请求资源地址
  String reqRes = "/v3/weather/now.json?key=" + reqUserKey +
                  + "&location=" + reqLocation + 
                  "&language=en&unit=" +reqUnit;

  for(;;){
    // 向心知天气服务器服务器请求信息并对信息进行解析
    httpRequest(reqRes);
    Serial.println("Next Weather Query will be " + String(weather_query_delay/1000/60) + " min later");
    delay(weather_query_delay);    
  }
 
}
// 向心知天气服务器服务器请求信息并对信息进行解析
void httpRequest(String reqRes){
  WiFiClient client;
 
  // 建立http请求信息
  String httpRequest = String("GET ") + reqRes + " HTTP/1.1\r\n" + 
                              "Host: " + host + "\r\n" + 
                              "Connection: close\r\n\r\n";
  Serial.println(""); 
  Serial.print("Connecting to "); Serial.print(host);
 
  // 尝试连接服务器
  if (client.connect(host, 80)){
    Serial.println(" Success!");
 
    // 向服务器发送http请求信息
    client.print(httpRequest);
    Serial.println("Sending request: ");
    Serial.println(httpRequest);  
 
    // 获取并显示服务器响应状态行 
    String status_response = client.readStringUntil('\n');
    Serial.print("status_response: ");
    Serial.println(status_response);
 
    // 使用find跳过HTTP响应头
    if (client.find("\r\n\r\n")) {
      Serial.println("Found Header End. Start Parsing.");
    }
    weather_query_delay = 1000*60*5;
    // 利用ArduinoJson库解析心知天气响应信息
    parseInfo(client); 
  } else {
    weather_query_delay = 3000;
    Serial.println(" connection failed!");
  }   
  //断开客户端与服务器连接工作
  client.stop(); 
}

心知天气返回的是Json格式的数据,因此需要用ArduinoJson来解析,提取感兴趣的天气内容。

 

NTP时间获取需要先初始化NTP Server,国内还是选择阿里云的NTP服务稳定些,端口号123

接着初始化Ntp服务器 

void Ntp_Init(void){
// Initialize a NTPClient to get time
  timeClient.begin();
  // Set offset time in seconds to adjust for your timezone, for example:
  // GMT +1 = 3600
  // GMT +8 = 28800
  // GMT -1 = -3600
  // GMT 0 = 0
  timeClient.setTimeOffset(28800);  
}

void Task_NTP_Time_Get(void *pvParameters){
  (void) pvParameters;
  // 通过NTP Server获取时间,日期

  for(;;){
      while(!timeClient.update()) {
        timeClient.forceUpdate();
      }
      // The formattedDate comes with the following format:
      // 2018-05-28T16:00:13Z
      // We need to extract date and time
      formattedDate = timeClient.getFormattedDate();
      Serial.println(formattedDate);
    
      // Extract date
      int splitT = formattedDate.indexOf("T");
      dayStamp = formattedDate.substring(0, splitT);
      Serial.print("DATE: ");
      Serial.println(dayStamp);
      // Extract time
      timeStamp = formattedDate.substring(splitT+1, formattedDate.length()-1);
      Serial.print("HOUR: ");
      Serial.println(timeStamp);

  tft.fillRect(0,0,240,16,ST77XX_BLACK);
  tft.setCursor(0, 0);
  tft.setTextColor(ST77XX_WHITE);
  tft.setTextSize(2);
  tft.print(dayStamp);
  tft.setCursor(136, 0);
  tft.print(timeStamp); 
        
      delay(1000);  
  }
 
}

 

实物展示:

任务4-时间-天气

 

代码: Proj4-Weather-Date_V3 - eeworld.ino (27.66 KB, 下载次数: 1)

 

总结:

非常感谢这次的Follow-Me活动。学习到了国外优秀的开源团队Adafruit的ESP32S3作品,设计非常精美。在Arduino环境里面也学会了如何显示汉字,如何联网,如何控制WS2812灯珠以及获取网络时间等,最终实现了一个具有天气和时间功能的小作品。

 

参考网友:

1. Lucheni  【得捷电子Follow me第2期】Arduino速通教程 bbs.eeworld.com.cn/thread-1254565-1-1.html

2. ESP32 BLE Server and Client (Bluetooth Low Energy) https://randomnerdtutorials.com/esp32-ble-server-client/

3. ESP32 WebSocket Server: Display Sensor Readings https://randomnerdtutorials.com/esp32-websocket-server-sensor/

4. ESP32 Useful Wi-Fi Library Functions (Arduino IDE) https://randomnerdtutorials.com/esp32-useful-wi-fi-functions-arduino/

5. 太极创客 物联网平台 www.taichi-maker.com/homepage/iot-development/iot-platform/

6. Getting Date and Time with ESP32 on Arduino IDE (NTP Client) https://randomnerdtutorials.com/esp32-ntp-client-date-time-arduino-ide/

补充内容 (2023-10-14 13:54): 审核老师您好:任务3,控制neo-pixel部分增加了旋转编码器,详细内容在评论区。原帖已经无法编辑。谢谢理解。

最新回复

在深度睡眠模式下,可从Lipoly连接获得80~100uA的电流消耗;不错不错!   详情 回复 发表于 2023-10-14 13:14
点赞 关注
 
 

回复
举报

7097

帖子

11

TA的资源

版主

沙发
 
用ardunio来玩成,相比python又多了一个开发选项。

点评

是的,Arduino比较适合我这种菜鸡  详情 回复 发表于 2023-9-22 08:27
 
 
 

回复

136

帖子

2

TA的资源

一粒金砂(高级)

板凳
 
lugl4313820 发表于 2023-9-21 16:13 用ardunio来玩成,相比python又多了一个开发选项。

是的,Arduino比较适合我这种菜鸡

 
 
 

回复

136

帖子

2

TA的资源

一粒金砂(高级)

4
 

任务3-改进:

 

参加本次follow-me活动的时候,还手痒痒凑单了一个DFROT家的旋转编码器,型号是:SEN0235,官方WIKI: https://wiki.dfrobot.com.cn/_SKU_SEN0235_360%E5%BA%A6%E7%BC%96%E7%A0%81%E5%99%A8%E5%BC%80%E5%85%B3

 

编码器有VCC, GND, A相输出,B相输出,以及按键按下输出的低电平信号,共5个信号。分别连接到TFT FTHR开发板的,3.3V, GND以及GPIO 18,17,16

 

之后初始化相关引脚为输入,并设置中断:

/** Oct 13rd add code for SEN0235 ---- Begin---- **/
  pinMode(encoderPinA, INPUT);
  pinMode(encoderPinB, INPUT);
  pinMode(buttonPin, INPUT);

  digitalWrite(encoderPinA, HIGH); //turn pullup resistor on
  digitalWrite(encoderPinB, HIGH); //turn pullup resistor on
  digitalWrite(buttonPin, HIGH); //turn pullup resistor on

  //call updateEncoder() when any high/low changed seen
  //on interrupt 0 (pin 2), or interrupt 1 (pin 3)
  attachInterrupt(digitalPinToInterrupt(encoderPinA), updateEncoder, CHANGE);
  attachInterrupt(digitalPinToInterrupt(encoderPinB), updateEncoder, CHANGE);
  attachInterrupt(digitalPinToInterrupt(buttonPin),   updateEncoder_BtnPressed, FALLING);

/** Oct 13rd add code for SEN0235 ---- End---- **/

下面是官方提供的解析旋转编码器顺时针还是逆时针旋转的参考代码:

void updateEncoder() {
  int MSB = digitalRead(encoderPinA); //MSB = most significant bit
  int LSB = digitalRead(encoderPinB); //LSB = least significant bit

  int encoded = (MSB << 1) | LSB; //converting the 2 pin value to single number
  int sum  = (lastEncoded << 2) | encoded; //adding it to the previous encoded value

  if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
  if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;

  lastEncoded = encoded; //store this value for next time
}

最终在循环中,根据编码器的值来决定NEO-PIXEL的色彩:

 switch(readEncoderValue()%4){
    case 0:
      tft.fillRect(16*10,32,32,16,ST77XX_BLACK);
      tft.drawBitmap(16*10, 32, str_f_HONG, 16, 16, ST77XX_RED);
      tft.drawBitmap(16*11, 32, str_f_SE, 16, 16, ST77XX_RED);
      tft.fillCircle(16*13, 38, 10, ST77XX_RED);
      colorWipe(strip.Color(255,   0,   0)     , 1000); // Red
      break;
      
    case 1:
      tft.fillRect(16*10,32,32,16,ST77XX_BLACK);
      tft.drawBitmap(16*10, 32, str_f_LV, 16, 16, ST77XX_GREEN);
      tft.drawBitmap(16*11, 32, str_f_SE, 16, 16, ST77XX_GREEN);    
      tft.fillCircle(16*13, 38, 10, ST77XX_GREEN);
      colorWipe(strip.Color(  0, 255,   0)     , 1000); // Green
      break;

    case 2:
      tft.fillRect(16*10,32,32,16,ST77XX_BLACK);
      tft.drawBitmap(16*10, 32, str_f_LAN, 16, 16, ST77XX_BLUE);
      tft.drawBitmap(16*11, 32, str_f_SE, 16, 16, ST77XX_BLUE);    
      tft.fillCircle(16*13, 38, 10, ST77XX_BLUE);
      colorWipe(strip.Color(  0,   0, 255)     , 1000); // Blue
      break; 

    case 3:
      tft.fillRect(16*10,32,32,16,ST77XX_BLACK);
      tft.fillCircle(16*13, 38, 10, ST77XX_BLACK);
      rainbowFade2White(3, 3, 1);
      break;
      
    default:
      break;
  }
完整代码: 任务3改进版_AddSEN0235.ino (32.44 KB, 下载次数: 0)

实物照片:

 

 
 
 
 
演示视频:
1527761623
 

 

 

 
 
 

回复

136

帖子

2

TA的资源

一粒金砂(高级)

5
 
审核老师您好:任务3,控制neo-pixel部分增加了旋转编码器,详细内容在评论区。原帖已经无法编辑。谢谢理解。
 
 
 

回复

7097

帖子

11

TA的资源

版主

6
 
  • 在深度睡眠模式下,可从Lipoly连接获得80~100uA的电流消耗;不错不错!
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表