Arduino R4 WIFI橫向滾動顯示16×16LED屏

實現一個從左向右橫向滾動的"吉祥如意"顯示效果。

arduino r4 WiFi滾動顯示16*16led

#include <SPI.h>// 引腳定義
const int RowA = 2, RowB = 3, RowC = 4, RowD = 5;
const int OE = 6;
const int LATCH = 10;// 字模數據 (吉祥如意)
const PROGMEM byte characterData[4][32] = {// 吉{0x01,0x00,0x01,0x00,0x01,0x04,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x10,0x3F,0xF8,0x00,0x00,0x00,0x10,0x1F,0xF8,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10},// 祥{0x22,0x08,0x11,0x10,0x10,0xA0,0xFB,0xFC,0x08,0x40,0x10,0x40,0x3B,0xF8,0x54,0x40,0x94,0x40,0x10,0x44,0x17,0xFE,0x10,0x40,0x10,0x40,0x10,0x40,0x10,0x40,0x10,0x40},// 如{0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x04,0xFE,0xFE,0x22,0x84,0x22,0x84,0x22,0x84,0x22,0x84,0x42,0x84,0x24,0x84,0x14,0x84,0x08,0x84,0x14,0xFC,0x22,0x84,0x40,0x00},// 意{0x01,0x00,0x3F,0xF8,0x08,0x20,0x04,0x44,0xFF,0xFE,0x00,0x00,0x1F,0xF0,0x10,0x10,0x1F,0xF0,0x10,0x10,0x1F,0xF0,0x02,0x08,0x51,0x04,0x51,0x24,0x90,0x20,0x0F,0xE0}
};SPISettings spiSettings(10000000, MSBFIRST, SPI_MODE0);// 橫向滾動緩沖區 (64列 x 16行)
byte scrollBuffer[16][8]; // 每行8字節=64位 (4個漢字)// 滾動狀態
int scrollOffset = 0;
unsigned long lastScrollTime = 0;
const int scrollDelay = 50; // 滾動速度 (毫秒)// 顯示控制
unsigned long lastFrameTime = 0;
const int targetFPS = 200;  // 目標幀率 (200幀/秒)
const int frameInterval = 1000 / targetFPS; // 5ms/幀void setup() {// 初始化引腳pinMode(RowA, OUTPUT); pinMode(RowB, OUTPUT);pinMode(RowC, OUTPUT); pinMode(RowD, OUTPUT);pinMode(OE, OUTPUT); pinMode(LATCH, OUTPUT);digitalWrite(OE, HIGH);digitalWrite(LATCH, HIGH);SPI.begin();// 初始化橫向滾動緩沖區initializeScrollBuffer();Serial.begin(115200);Serial.println("橫向滾動顯示器準備就緒");
}// 設置行選擇
void setRow(byte row) {digitalWrite(RowA, row & 0x01);digitalWrite(RowB, (row >> 1) & 0x01);digitalWrite(RowC, (row >> 2) & 0x01);digitalWrite(RowD, (row >> 3) & 0x01);
}// 初始化橫向滾動緩沖區
void initializeScrollBuffer() {// 將四個漢字轉換為橫向排列的緩沖區for (int row = 0; row < 16; row++) {for (int charIndex = 0; charIndex < 4; charIndex++) {// 獲取每個漢字的左右字節byte leftByte = pgm_read_byte(&characterData[charIndex][row * 2]);byte rightByte = pgm_read_byte(&characterData[charIndex][row * 2 + 1]);// 將每個漢字的16位分為兩個字節存儲scrollBuffer[row][charIndex * 2] = leftByte;scrollBuffer[row][charIndex * 2 + 1] = rightByte;}}
}// 橫向滾動內容
void scrollContent() {scrollOffset++;if (scrollOffset >= 64) { // 64列 = 4漢字 * 16列scrollOffset = 0;}
}// 獲取當前列的數據
byte getColumnData(byte row, int column) {int byteIndex = column / 8;int bitIndex = 7 - (column % 8); // 高位在前return (scrollBuffer[row][byteIndex] >> bitIndex) & 0x01;
}// 顯示單幀內容
void displayFrame() {// 確保固定幀率unsigned long currentTime = micros();unsigned long elapsed = currentTime - lastFrameTime;if (elapsed < frameInterval * 1000) {delayMicroseconds(frameInterval * 1000 - elapsed);}lastFrameTime = micros();// 逐行顯示for (byte row = 0; row < 16; row++) {digitalWrite(OE, HIGH);  // 關閉顯示// 準備SPI傳輸SPI.beginTransaction(spiSettings);// 構建當前行的16位數據 (從右向左排列)uint16_t rowData = 0;// 從滾動偏移位置開始,取16列數據for (int col = 0; col < 16; col++) {int actualCol = (scrollOffset + col) % 64;byte pixel = getColumnData(row, actualCol);// 設置位 (從最高位開始)rowData = (rowData << 1) | pixel;}// 發送數據 (高8位和低8位)SPI.transfer(~(rowData >> 8));   // 高8位SPI.transfer(~(rowData & 0xFF)); // 低8位// 結束SPI傳輸SPI.endTransaction();// 設置當前行setRow(row);// 鎖存數據digitalWrite(LATCH, LOW);digitalWrite(LATCH, HIGH);// 開啟顯示digitalWrite(OE, LOW);// 行顯示時間 (100μs)delayMicroseconds(100);}// 所有行顯示完畢后立即關閉顯示digitalWrite(OE, HIGH);
}void loop() {// 滾動控制if (millis() - lastScrollTime > scrollDelay) {scrollContent();lastScrollTime = millis();}// 顯示當前幀displayFrame();
}

橫向滾動實現原理

數據結構設計

圖表

橫向滾動過程

  1. 緩沖區初始化

    • 將四個漢字按順序排列在64列×16行的緩沖區中

    • 每個漢字占據16列空間

  2. 滾動顯示

    圖表

  1. 取數據邏輯

    • scrollOffset位置開始取16列

    • 構建16位行數據

    • 發送給74HC595

關鍵優化

  1. 高效數據結構

    • 使用16×8字節緩沖區存儲64列數據

    • 直接訪問列數據,無需實時計算

  2. 平滑滾動

    arduino

  • const int scrollDelay = 50; // 每50ms滾動1列
  • 視覺效果優化

    • 從左向右滾動符合閱讀習慣

    • 完整顯示每個漢字的時間:16列 × 50ms = 800ms

    • 四個漢字完整顯示時間:3.2秒

  • 亮度均衡

    arduino

  1. delayMicroseconds(100); // 每行顯示時間一致

參數調整指南

  1. 滾動速度

    arduino

  • // 較慢速度 (約每秒10列)
    const int scrollDelay = 100;// 中等速度 (約每秒20列)
    const int scrollDelay = 50;// 較快速度 (約每秒33列)
    const int scrollDelay = 30;
  • 顯示亮度

    arduino

  • // 較低亮度
    delayMicroseconds(80);// 中等亮度
    delayMicroseconds(100);// 較高亮度
    delayMicroseconds(120);
  • 刷新率

    arduino

  1. // 減少閃爍 (推薦)
    const int targetFPS = 200;// 更高刷新率 (需要更快的硬件)
    const int targetFPS = 300;

常見問題解決

  1. 顯示方向反了
    如果文字從右向左滾動,修改數據構建方式:

    arduino

  • // 原代碼 (從左向右)
    rowData = (rowData << 1) | pixel;// 改為從右向左
    rowData = (rowData >> 1) | (pixel << 15);
  • 亮度不均勻

    • 檢查OE信號是否在每行結束后立即拉高

    • 確保每行顯示時間嚴格一致

    • 增加幀間延時:

      arduino

    • const int frameInterval = 1000 / 150; // 降低刷新率
  • 漢字顯示不完整

    • 確認緩沖區初始化正確

    • 檢查字模數據是否正確加載

    • 增加滾動延遲:

      arduino

    • const int scrollDelay = 80; // 更慢的滾動

擴展功能

  1. 添加新文字

    arduino

  • // 添加第五個字
    const PROGMEM byte characterData[5][32] = {// 原有四個字...// 新字數據...
    };// 更新緩沖區大小
    byte scrollBuffer[16][10]; // 5漢字 * 16列/8 = 10字節
  • 雙向滾動

    arduino

  • bool scrollDirection = true; // true=向右, false=向左void scrollContent() {if(scrollDirection) {scrollOffset++;} else {scrollOffset--;}// 邊界檢查...
    }
  • 暫停功能

    arduino

  1. const int pauseButton = 7;void setup() {pinMode(pauseButton, INPUT_PULLUP);
    }void loop() {if (digitalRead(pauseButton) == LOW) {// 顯示當前幀但不滾動while (digitalRead(pauseButton) == LOW) {displayFrame();}}// 正常滾動...
    }

這個橫向滾動方案解決了之前縱向滾動時文字看不清的問題,同時保持了流暢的動畫效果和均衡的亮度顯示。每個漢字都有足夠的時間完整顯示,便于觀看。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/85435.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/85435.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/85435.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

html css js網頁制作成品——HTML+CSS+js力學光學天文網頁設計(4頁)附源碼

目錄 一、&#x1f468;?&#x1f393;網站題目 二、??網站描述 三、&#x1f4da;網站介紹 四、&#x1f310;網站效果 五、&#x1fa93; 代碼實現 &#x1f9f1;HTML 六、&#x1f947; 如何讓學習不再盲目 七、&#x1f381;更多干貨 一、&#x1f468;?&#x1f…

嵌入式開發之freeRTOS移植

FreeRTOS 是一款廣泛應用于嵌入式系統的開源實時操作系統&#xff08;RTOS&#xff09;&#xff0c;其移植過程需要結合具體硬件平臺和編譯器進行適配。以下是 FreeRTOS 移植的詳細步驟和關鍵注意事項&#xff1a; 一、移植前的準備工作 1. 硬件平臺確認 處理器架構&#xf…

【算法 day07】LeetCode 344.反轉字符串 | 541. 反轉字符串II | 卡碼網:54.替換數字

344.反轉字符串 題目鏈接 | 文檔講解 |視頻講解 : 鏈接 1.思路&#xff1a; 采用雙指針&#xff0c;left從0開始移動,right從尾元素進行移動 循環判斷條件&#xff1a;left< right,邊界值使用舉例法&#xff0c;eg: [ h ,e ,l,o ]偶數個不會相遇, [h ,e ,l ,l ,o ]奇數個&…

從檢索到生成:RAG 如何重構大模型的知識邊界?

引言&#xff1a;知識邊界的突破與重構 在人工智能技術快速發展的今天&#xff0c;大型語言模型&#xff08;LLMs&#xff09;已經展現出強大的文本生成和理解能力。然而&#xff0c;這些模型在實際應用中仍面臨著知識時效性、事實準確性和可溯源性等核心挑戰。檢索增強生成&a…

前端基礎知識CSS系列 - 05(BFC的理解)

一、是什么 我們在頁面布局的時候&#xff0c;經常出現以下情況&#xff1a; 這個元素高度怎么沒了&#xff1f;這兩欄布局怎么沒法自適應&#xff1f;這兩個元素的間距怎么有點奇怪的樣子&#xff1f;...... 原因是元素之間相互的影響&#xff0c;導致了意料之外的情況&…

Prompt Engineering 學習指南:從入門到精通的最佳路徑與資源

本 Prompt Engineering 技術報告,旨在提供一個從入門到精通的清晰學習路徑、核心方案,并附上最關鍵的 GitHub 倉庫資源。您可以將此報告作為快速提升 Prompt 能力的“速查手冊”和“成長地圖”。 Prompt Engineering 學習指南:從入門到精通的最佳路徑與資源 技術報告摘要 (…

fastmcp MCPConfig多服務器使用案例;sse、stdio、streamable-http使用

1、sse、stdio、streamable-http使用 參考&#xff1a;https://gofastmcp.com/deployment/running-server#the-run-method stdio本地使用&#xff1b;sse、streamable-http遠程調用&#xff08; Streamable HTTP—New in version: 2.3.0&#xff09; 調用&#xff1a; stdio、…

網站服務器被DDOS攻擊打不開,是要換高防服務器還是加CDN能防護住?

高防云服務器、高防 IP 和高防 CDN 作為常見應對網絡攻擊的重要利器&#xff0c;它們各自有著獨特的特點和應用場景&#xff0c;從技術架構看&#xff0c;高防云服務器是資源型防護&#xff0c;深度整合計算與防御資源&#xff1b;高防IP是流量型防護&#xff0c;以代理模式實現…

深入解析原型模式:從理論到實踐的全方位指南

深入解析原型模式&#xff1a;從理論到實踐的全方位指南 引言&#xff1a;為什么需要原型模式&#xff1f; 在軟件開發過程中&#xff0c;對象創建是一個頻繁且關鍵的操作。傳統方式&#xff08;如直接使用new關鍵字&#xff09;在某些場景下會顯得效率低下且不夠靈活。想象這…

HuggingFace鏡像配置失效問題深度解析:Python模塊導入機制的陷阱

前言 在使用HuggingFace的transformers和datasets庫時&#xff0c;國內用戶經常會遇到網絡連接問題。雖然設置了鏡像源環境變量&#xff0c;但仍然報錯無法連接到huggingface.co。本文將深入分析這個問題的根因&#xff0c;并從Python模塊導入機制的角度解釋為什么環境變量設置…

leetcode146-LRU緩存

leetcode 146 思路 什么是LRU緩存&#xff1f; LRU&#xff08;Least Recently Used&#xff09;緩存是一種常見的緩存淘汰策略&#xff0c;核心思想是&#xff1a;當緩存容量滿時&#xff0c;優先淘汰最久未使用的數據。LeetCode 146 題要求實現一個支持get和put操作的 LR…

MQTT:構建高效物聯網通信的輕量級協議

MQTT – 輕量級物聯網消息推送協議 MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是機器對機器(M2M)/物聯網(IoT)連接協議。它被設計為一個極其輕量級的發布/訂閱消息傳輸協議。對于需要較小代碼占用空間和/或網絡帶寬非常寶貴的遠程連接非常有用&#xf…

AI自動生成復雜架構圖,流程圖,思維導圖

AI自動生成復雜架構圖&#xff0c;流程圖&#xff0c;思維導圖方案 1. 背景 在我們自己去繪制架構圖&#xff0c;流程圖&#xff0c;思維導圖的時候&#xff0c;我們通常需要花費大量的時間去繪制。 目前的一些直接生圖的模型也只能生成簡單的流程圖&#xff0c;不能生成復雜…

129. 求根節點到葉節點數字之和 --- DFS +回溯(js)

129. 求根節點到葉節點數字之和 --- DFS 回溯&#xff08;js&#xff09; 題目描述解題思路完整代碼 題目描述 129. 求根節點到葉節點數字之和 解題思路 和 257. 二叉樹的所有路徑&#xff08;js&#xff09; 是一樣的思路。 不一樣的地方就是遇到葉子節點的時候把路徑拼接…

SpringBoot電腦商城項目--修改默認收貨地址

1. 修改默認收貨地址-持久層 1.1 規劃sql語句 檢測當前用戶向設置為默認收貨地址的這條數據是否存在 SELECT * FROM t_address WHERE aid#{aid} 在修改用戶的收獲默認地址之前&#xff0c;先將所有的收貨地址設置為非默認 UPDATE t_address SET is_default0 WHERE uid#{uid} …

LabVIEW FPGA 資源擴展

針對NI CompactRIO 9045 控制器 Kintex-7 70T FPGA 資源不足問題&#xff0c;通過 NI 9151 R 系列可重配置 I/O 模塊擴展外部 FPGA 處理能力&#xff0c;在保留原有機箱架構下實現實時任務分流&#xff0c;解決Slice、LUT 等資源緊張問題&#xff0c;提升系統并行處理能力。 ?…

【漏洞復現】Apache Kafka Connect 任意文件讀取漏洞(CVE-2025-27817)

文章目錄 前言一、Apache Kafka 簡介二、漏洞描述三、影響版本四、FOFA查詢語句五、漏洞原理分析六、漏洞復現七、修復建議前言 由于Apache Kafka客戶端未對用戶輸入進行嚴格驗證和限制,未經身份驗證的攻擊者可通過構造惡意配置讀取環境變量或磁盤任意內容,或向非預期位置發…

day13-軟件包管理

1.每日復盤與今日內容 1.1復盤 yum源/apt源配置文件,核心下載地址.二進制部署服務.編譯安裝軟件. 2.軟件包管理-實戰部分 2.1 yum源/apt源配置 源下載軟件的地址配置多種源 1??系統也有默認的源&#xff0c;里面也包含很多常用的軟件. 2??安裝nginx、yum源 3??安…

榕壹云快遞寄件系統:聚合快遞、智能追蹤、二次開發,一站式物流解決方案

在電商物流高速發展的今天&#xff0c;快遞寄件需求呈現爆炸式增長。傳統分散的寄件方式效率低下&#xff0c;用戶迫切需要一個整合多家快遞公司的便捷平臺。榕壹云公司開發的快遞寄件系統應運而生&#xff0c;通過聚合多家快遞資源、優化操作流程、提供豐富的功能模塊&#xf…

一款功能強大的專業CSV編輯工具

Rons Data Edit是一款為Windows操作系統設計的現代CSV文件編輯器&#xff0c;它結合了優雅、強大和易用性&#xff0c;它可以打開任何格式的分隔文本文件(如CSV、TSV等)&#xff0c;并允許用戶完全控制文件的內容和結構。 功能特點 支持明暗主題&#xff0c;可以在預定義的20多…