Arduino LED Matrix 中文 Running Text 迷你版

制作分享:
不久前已有自己尝试实作的念头, 在没有专门做 LED Driving IC 及手头上有限的零件条件下, 初步总算完成了.
最初设定的目标:
1. 萤幕能显示中文字或中文句子.
2. 萤幕上文字能简单移动.
3. 电脑那边, 利用简单界面输入欲显示的文字和设定Font的Family, Size, Style 和文字移动速度, 之后即时更新.

最初设计及掣作中问题, 自问自答:
Q1: 为甚么要做 16x16 的 LED Dot Matrix, 只用一个 8x8 的不可以吗?
A1: 因为目标是能显示中文字, 而一般中文字型最少也要 10x10 的解像点数才看得清楚(可用小画家测试), 因此决定要用4个 8x8 组成 16x16, 及后观察巿面上大部份的中文 LED Display 最少也有10多点的高度. 若只须显示英文字, 一个 8x8 已足够, 而且线路会比较简单了.

Q2: 中文字型的编码字库储存在那里?
A2: 中文字型的编码是有须要显示出来是才会从电脑那边传送到Arduino 的记忆体上.
现在的设计是每个字都系 fixed 16x16 dot, 即系要每个字要 32 bytes (因为16x16=256 点 LED, 每Byte 8个Bits 能储存8点, 所以256/8=32)
字样有用到先send 过去 arduino
没选择在arduino建立字库系因为我觉得:
1. ATmega328 上的Flash or EEPROM 都应该唔系几够位, 但可能可以只储存某些常用字,
2. 不计理由1, 若果字库在arduino 那边, 输入中文后我要考虑send 码过去时要用正常的big5 or utf-8 的话 , arduino 要有一个mapping table 小弟觉得较困难.
若重新跟据字型在记忆上的地址做编码, pc 那边又要有一个table,

其他的问题:
关于字型的储蓄, 编码
待修

使用硬件:
1. Arduino Duemilanove
2. 8x8 LED Dot Matrix x 4
    四个组成16x16 LED Dot Matrix
3. 74LS138 x 2
    74LS138 是 1-of-8 Demultiplexer, 两个便组成 1-of-16 Demultiplexer, 用在逐行LED column scan
4. MCP23017 IO Port Expander
    Arduino 用 I2C Interface (Wire Library) 与它连接扩充16 个Digitial Out. LED row 的控掣
5. KSP2907A PNP Transistor x 16
    用作整行 (垂直) LED Switch On/Off
6. Resistor
    用在LED限流及 Transistor
7. Breadboard

PC 软件:
1. Arduino IDE
2. Eclipse IDE for Java

套用的有关技术: (可上网搜查更详细资料)
PNP Transistor Switch LED
LED Multiplexing
利用 IC 74LS138 做 1-of-8 Demultiplexer (与LED Multiplexing 有关)

影片一
http://www.youtube.com/watch?v=3mzN5QnAiSE

影片二
http://www.youtube.com/watch?v=8cHiBezWQTM

其他资料整理后再放上来...

[ 本帖最后由 sscm 于 2009-6-24 09:49 编辑 ]
附件: 您需要登录才可以下载或查看附件。没有帐号?註册

Arduino Source Code
如果有足够脚位如Arduino Mega, 根本可以不用Wire Library 控掣外加的 IO Port Expander,
直接改为控掣Arduino 的Port 就可以了.

#include <Wire.h>

int colIdx = 0;           
int dataLen = 0;      // 共多少byte作储存 字型,  =msgLen x32 (每个字佔32byte)
int mode = 0;          // mode 0 与PC连拉作接收文字资料, mode 1 作显示文字
int msgLen = 0;      //   共多少个字位
int msgSpeed = 6;   // 文字移动速度

int inByte;
byte data[640];    // 每个字佔32byte, 分配最多20个字位

int pause = 400;

void setup() {
    DDRB = B11111111;
    Serial.begin(9600);
    Wire.begin();
}

void loop() {
    Wire.beginTransmission(B100000);
    Wire.send(0x00);
    Wire.send(0x00);
    Wire.send(0x00);
    Wire.endTransmission();
   
    Wire.beginTransmission(B100000);
    Wire.send(0x12);
    Wire.send(0xFF);
    Wire.send(0xFF);
    Wire.endTransmission();
   
    while (true) {
        while (mode == 0) {
            digitalWrite(13, HIGH);
            if (Serial.available() > 0) {
                inByte = Serial.read();
                switch (inByte) {
                   case 255:
                       mode = 1;
                       digitalWrite(13, LOW);
                       break;
                   case 0:
                       while (true) {
                           if (Serial.available() > 0) {
                               msgSpeed = Serial.read();
                               break;
                           }
                       }
                       break;
                   case 1:
                       int i = 0;
                       while (i < 32) {
                           if (Serial.available() > 0)
                             data[msgLen * 32 + i++] = Serial.read();
                       }
                       msgLen++;
                       dataLen = msgLen * 32;
                       break;
               }
            }
        }
        
        int i, j, k, l;
        unsigned long t = millis();
        while (true) {
            for (i = 0; i < 16; i++) {
                PORTB = i;
               
                j = (colIdx*2)+ (i*2);
                if (j < dataLen) {
                    k = data[j];
                    l = data[j + 1];
                } else {
                    k = data[j-dataLen];
                    l = data[j + 1-dataLen];
                    if (i == 0 && j - dataLen == 0) {
                        colIdx = 0;
                    }
                }
               
                // Turn on row LED
                Wire.beginTransmission(B100000);
                Wire.send(0x12);
                Wire.send(k);
                Wire.send(l);
                Wire.endTransmission();
               
                delayMicroseconds(pause);
               
                // Turn off all row LED
                Wire.beginTransmission(B100000);
                Wire.send(0x12);
                Wire.send(0xFF);
                Wire.send(0xFF);
                Wire.endTransmission();
               
                if (millis() - t > (msgSpeed*50)) {
                    t = millis();
                    colIdx++;
                }
            }
        }
    }
}

[ 本帖最后由 sscm 于 2009-6-18 23:26 编辑 ]
附件: 您需要登录才可以下载或查看附件。没有帐号?註册

TOP

测试中文显示

[ 本帖最后由 sscm 于 2009-6-17 00:05 编辑 ]
附件: 您需要登录才可以下载或查看附件。没有帐号?註册

TOP

好正喎!PC用乜野造界面呀?

TOP

原帖由 zonebaby 于 2009-6-17 00:23 发表
好正喎!PC用乜野造界面呀?


用 Eclipse 写 Java, 界面系输入文字后编番 code, serial send 去 Arduino.

TOP

原帖由 sscm 于 2009-6-17 00:33 发表


用 Eclipse 写 Java, 界面系输入文字后编番 code, serial send 去 Arduino.


中文字要唔要逐只字编定有字库用呀?

TOP

原帖由 zonebaby 于 2009-6-17 00:41 发表


中文字要唔要逐只字编定有字库用呀?


开始时我也想过这个问题, 最后选择系逐只字编,
现在的设计是每个字都系 fixed 16x16 dot, 即系要每个字要 32 bytes
字样有用到先send 过去 arduino

没选择字库系因为我觉得:
1. ATmega328 上的Flash or EEPROM 都应该唔系几够位, 但可能可以只储存某些常用字,
2. 不计理由1, 若果字库在arduino 那边, 输入中文后我要考虑send 码过去时要用正常的big5 or utf-8 的话 , arduino 要有一个mapping table 小弟觉得较困难.
若重新跟据字型在记忆上的地址做编码, pc 那边又要有一个table,
所以最后都系用了较简单的方法来实作

其实我不清楚巿面上那些怎様做, 若果其他师兄知道请指教

TOP

多谢指教。

另外请问咁大块Breadboard系边处买架?

TOP

原帖由 zonebaby 于 2009-6-17 01:19 发表
多谢指教。

另外请问咁大块Breadboard系边处买架?

华辉有,几块Breadboard可以构起一齐
留意下边位 有凸有凹

[ 本帖最后由 rutellor 于 2009-6-17 01:55 编辑 ]

TOP

呢件 breadboard 晌华辉买相当贵...过百蚊...

TOP