作者: dulllou 時間: 2009-5-15 16:14 標題: 晌 Arduino 上用 LCD Smartie (附 code / 圖)
經板頭的精華文介紹, 原來竟然有 LCD Smartie 呢隻咁正o既 software, (之前唔知, 要自己寫 python + proxy 先可以晌 internet feed 到野落 Arduino 度) 而家可以經用 LCD Smartie 晌 Arduino feed 到野落o黎啦...好正.... 正如我之前講, Arduino 係唔識電子o既 IT 佬用的恩物...
[attach]848028[/attach]
[attach]848029[/attach]
[attach]848030[/attach]
廢話少講, 講下點樣做
首先, download 左 LCD Smartie 先
如果你係用 LCD Shield / LCD Keypad Shield (冇 ? 自己 build 一個吧 (上淘寶買 16*2 廿蚊人仔左右, 六粒微動最少六蚊啦, 萬用板又十幾廿蚊...) 不如索性上淘寶買一個 LCD Keypad Shield吧 (我買七十蚊人仔))
用 LCD Shield 要先 download 改過o既 LCD_4bit library
然後就download 呢個 Sketch, upload 前可以 compile 一次, 如無意外應該會成功 complie (失敗的話九成係因為未裝好上一步o既 LCD_4bit library), OK 左就可以 upload 去 arduino
Upload 完後 Arduino 就會 show 呢個畫面
[attach]848031[/attach]
Arduino 部份就已經攪掂晒喇, 然而再整電腦部份
=============我是 Arduino 和 電腦之間的分界線=============
電腦部份就當然係要download LCD Smartie
http://lcdsmartie.sourceforge.net/
Run 左 LCD Smartie 之後有少少野要 set, 話俾 LCD Smartie 知點樣同 Arduino 溝通
要 Set o既只有 "LCD Feature" 一板. 晌 "Plugin" -> LCD Plugin 內選 matrix.dll
Startup Parameters 內就set 返o岩你 Arduino 用的 COM (唔記得左 ? 晌 Arduino IDE 度 click Tools > Serial Port 睇返啦). 速度用 19200 (跟返上便個 Sketch o既 Serial.begin(19200);)
可以參考下圖:
[attach]848032[/attach]
然後晌同一板 click "Screen" 然後選返適當o既 screen size (LCD shield 用o既係 2x16, 如果你 DIY o既就跟返你自己用o既 Screen size)
可以參考下圖
[attach]848033[/attach]
攪掂 Click "OK" 你就會見 Arduino 個畫面轉左做 LCD Smartie o既畫面喇
如果 LCD Smartie 出 Error 話 matrix.dll load 唔到, 常見原因有 3
- 一係你 Arduino IDE 開左 Serial monitor 佔用左個 COM port. 停左 Serial monitor 或者閂左 Arduino IDE 就可以
- 一係你跟本晌 LCD Smartie set 錯左 COM port. 去 Arduino IDE > Tools > Serial Port check 下你自己用緊個 COM port 係 COM 幾
- 仲有一個可能係你晌 LCD Smart 打錯左. 留意係 COMx,19200, COM 同 x 中間冇係 space o既, 之後一個 comma, space 之後 19200
禮成~ 感謝閱讀~
[attach]848029[/attach]
[attach]848030[/attach]
[attach]848031[/attach]
[ 本帖最後由 dulllou 於 2009-5-15 16:27 編輯 ]
作者: dulllou 時間: 2009-5-15 16:17
Code 如下
#include <avr/interrupt.h>
#include <avr/io.h>
#include "LCD4Bit_mod.h"
#define DEBOUNCE_MAX 17 // max value for debounce count
#define DEBOUNCE_ON 12 // debounce pressed threshold 12x4ms = 48ms
#define DEBOUNCE_OFF 2 // debounce released threshold 8ms
//create object to control an LCD.
//number of lines in display=1
LCD4Bit_mod lcd = LCD4Bit_mod(2);
int adc_key_val[5] ={30, 150, 360, 535, 760 };
byte NUM_KEYS = 5;
char key=-1;
char oldkey=-1;
// debounce counters
byte button_count[5];
// button status - pressed/released
byte button_status[5];
// button on flags
byte button_flag[5];
// Timer2 interrupt routine -
// 1/(160000000/256/(256-6)) = 4ms interval
ISR(TIMER2_OVF_vect) {
TCNT2 = 6;
update_adc_key();
}
// Convert ADC value to key number
char get_key(unsigned int input)
{
char k;
for (k = 0; k < NUM_KEYS; k++)
{
if (input < adc_key_val[k])
{
return k;
}
}
if (k >= NUM_KEYS)
k = -1; // No valid key pressed
return k;
}
void update_adc_key(){
int adc_key_in;
char key_in;
byte i;
adc_key_in = analogRead(0);
key_in = get_key(adc_key_in);
for(i=0; i<NUM_KEYS; i++)
{
if(key_in==i) //one key is pressed
{
if(button_count<DEBOUNCE_MAX)
{
button_count++;
if(button_count>DEBOUNCE_ON)
{
if(button_status == 0)
{
button_flag = 1; // pressed state flag ON
button_status = 1; //button debounced to 'pressed' status
}
}
}
}
else // no button pressed
{
if (button_count >0)
{
button_count--;
if(button_count<DEBOUNCE_OFF){
button_status=0; //button debounced to 'released' status
}
}
}
// output button pressed state
if(button_flag==1)
{
button_flag=0; // clear flag to avoid repeats
Serial.print('A'+i,BYTE); // output MO button code
}
}
}
void setup() {
pinMode(13, OUTPUT); //we'll use the debug LED to output a heartbeat
digitalWrite(13,LOW);
Serial.begin(19200);
// reset button arrays
for(byte i=0; i<5; i++){
button_count=0;
button_status=0;
button_flag=0;
}
// Setup timer2 -- Prescaler/256
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
TCCR2B &= ~(1<<WGM22);
TCCR2B = (1<<CS22)|(1<<CS21);
ASSR |=(0<<AS2);
// Use normal mode
TCCR2A =0;
//Timer2 Overflow Interrupt Enable
TIMSK2 |= (0<<OCIE2A);
TCNT2=0x6; // counting starts from 6;
TIMSK2 = (1<<TOIE2);
SREG|=1<<SREG_I;
lcd.init();
lcd.clear();
lcd.printIn("**LCD SMARTIE**");
lcd.cursorTo(2,3);
lcd.printIn("on Arduino");
}
byte serial_getch(){
int incoming;
while (Serial.available()==0){}
// read the incoming byte:
incoming = Serial.read();
return (byte) (incoming &0xff);
}
void loop(){
byte rxbyte;
byte temp;
rxbyte = serial_getch();
if (rxbyte == 254) //Matrix Orbital uses 254 prefix for commands
{
switch (serial_getch())
{
case 66: //backlight on (at previously set brightness)
// not implemented
break;
case 70: //backlight off
// not implemented
break;
case 71: //set cursor position
temp = (serial_getch() - 1); //get column byte
switch (serial_getch()) //get row byte
{
//line 1 is already set up
case 2:
temp += 0x40;
break;
case 3:
temp += 0x14;
break;
case 4:
temp += 0x54;
break;
default:
break;
}
lcd.commandWrite(0b10000000 + temp);
break;
case 72: //cursor home (reset display position)
lcd.commandWrite(2);
break;
case 74: //show underline cursor
lcd.commandWrite(0b00001110);
break;
case 75: //underline cursor off
case 84: //block cursor off
lcd.commandWrite(0b00001100);
break;
case 76: //move cursor left
lcd.commandWrite(16);
break;
case 77: //move cursor right
lcd.commandWrite(20);
break;
case 78: //define custom char
lcd.commandWrite(64 + (serial_getch() * 8)); //get+set char address
for (temp = 7; temp != 0; temp--)
{
lcd.print(serial_getch()); //get each pattern byte
}
break;
case 83: //show blinking block cursor
lcd.commandWrite(0b00001111);
break;
case 86: //GPO OFF
//implement later
break;
case 87: //GPO ON
/*temp = serial_getch();
if (temp == 1)
{
GPO1 = GPO_ON;
}*/
break;
case 88: //clear display, cursor home
lcd.commandWrite(1);
break;
case 152: //set and remember (doesn't save value, though)
case 153: //set backlight brightness
//not implemented
break;
//these commands ignored (no parameters)
case 35: //read serial number
case 36: //read version number
case 55: //read module type
case 59: //exit flow-control mode
case 65: //auto transmit keypresses
case 96: //auto-repeat mode off (keypad)
case 67: //auto line-wrap on
case 68: //auto line-wrap off
case 81: //auto scroll on
case 82: //auto scroll off
case 104: //init horiz bar graph
case 109: //init med size digits
case 115: //init narrow vert bar graph
case 118: //init wide vert bar graph
break;
default:
//all other commands ignored and parameter byte discarded
temp = serial_getch(); //dump the command code
break;
}
return;
} //END OF COMMAND HANDLER
//change accented char to plain, detect and change descenders
//NB descenders only work on 5x10 displays. This lookup table works
// with my DEM-20845 (Display Elektronik GmbH) LCD using KS0066 chip.
switch (rxbyte)
{
//chars that have direct equivalent in LCD charmap
/* case 0x67: //g
rxbyte = 0xE7;
break;
case 0x6A: //j
rxbyte = 0xEA;
break;
case 0x70: //p
rxbyte = 0xF0;
break;
case 0x71: //q
rxbyte = 0xF1;
break;
case 0x79: //y
rxbyte = 0xF9;
break;
*/ case 0xE4: //ASCII "a" umlaut
rxbyte = 0xE1;
break;
case 0xF1: //ASCII "n" tilde
rxbyte = 0xEE;
break;
case 0xF6: //ASCII "o" umlaut
rxbyte = 0xEF; //was wrong in v0.86
break;
case 0xFC: //ASCII "u" umlaut
rxbyte = 0xF5;
break;
//accented -> plain equivalent
//and misc symbol translation
case 0xA3: //sterling (pounds)
rxbyte = 0xED;
break;
/* case 0xB0: //degrees symbol
rxbyte = 0xDF;
break;
*/ case 0xB5: //mu
rxbyte = 0xE4;
break;
case 0xC0: //"A" variants
case 0xC1:
case 0xC2:
case 0xC3:
case 0xC4:
case 0xC5:
rxbyte = 0x41;
break;
case 0xC8: //"E" variants
case 0xC9:
case 0xCA:
case 0xCB:
rxbyte = 0x45;
break;
case 0xCC: //"I" variants
case 0xCD:
case 0xCE:
case 0xCF:
rxbyte = 0x49;
break;
case 0xD1: //"N" tilde -> plain "N"
rxbyte = 0x43;
break;
case 0xD2: //"O" variants
case 0xD3:
case 0xD4:
case 0xD5:
case 0xD6:
case 0xD8:
rxbyte = 0x4F;
break;
case 0xD9: //"U" variants
case 0xDA:
case 0xDB:
case 0xDC:
rxbyte = 0x55;
break;
case 0xDD: //"Y" acute -> "Y"
rxbyte = 0x59;
break;
/* case 0xDF: //beta //mucks up LCDSmartie's degree symbol??
rxbyte = 0xE2;
break;
*/ case 0xE0: //"a" variants except umlaut
case 0xE1:
case 0xE2:
case 0xE3:
case 0xE5:
rxbyte = 0x61;
break;
case 0xE7: //"c" cedilla -> "c"
rxbyte = 0x63;
break;
case 0xE8: //"e" variants
case 0xE9:
case 0xEA:
case 0xEB:
rxbyte = 0x65;
break;
case 0xEC: //"i" variants
case 0xED:
case 0xEE:
case 0xEF:
rxbyte = 0x69;
break;
case 0xF2: //"o" variants except umlaut
case 0xF3:
case 0xF4:
case 0xF5:
case 0xF8:
rxbyte = 0x6F;
break;
case 0xF7: //division symbol
rxbyte = 0xFD;
break;
case 0xF9: //"u" variants except umlaut
case 0xFA:
case 0xFB:
rxbyte = 0x75;
break;
default:
break;
}
lcd.print(rxbyte); //otherwise a plain char so we print it to lcd
return;
}
[ 本帖最後由 dulllou 於 2009-5-19 18:20 編輯 ]
作者: 薯餅v.v 時間: 2009-5-15 16:27
d制全部都可以用?
作者: dulllou 時間: 2009-5-15 16:33
要用得o個幾粒制的話其實都唔係太難, 我估應該 20 行以內就寫到, 問題係既然晌 LCD Smartie 已經控制到所有 function... 其實都唔太必要再用o個五粒 buttons (第六粒係 reset...). 再者, 其實我都未摸索完 LCD Smartie, 唔太 sure 佢會唔會收 input / 點樣整到佢收 Arduino 的 input.... 加上我今日攪左成日...未食早餐又未食晏...都係要食完野返來先再摸索 / 改 code 會好d
作者: 薯餅v.v 時間: 2009-5-15 21:23
ching 加油
成品好貴
作者: dulllou 時間: 2009-5-15 23:53
哈哈, 攪掂左
加返個menu plugin 就可以~
[attach]848266[/attach]
[attach]848267[/attach]
[attach]848268[/attach]
[attach]848269[/attach]
[attach]848270[/attach]
[ 本帖最後由 dulllou 於 2009-5-15 23:55 編輯 ]
作者: 薯餅v.v 時間: 2009-5-16 07:53
咁樓主如果自己砌一舊要買d咩
作者: dulllou 時間: 2009-5-16 08:34
砌一隻 full function o既 arduino 睇呢度
http://itp.nyu.edu/physcomp/Tutorials/ArduinoBreadboard
如果淨係打算用來做 LCD display o既用 atmega8 就夠
[attach]848405[/attach]
另外如果你部電腦已經冇 Serial port (com port), 加多粒 FT232 來做 USB -> Serial. 將 FT232 的 RX 同 TX 分別駁入 atmeta8 o既 pin2 (rx) 同 pin3 (tx) 就可以
最後當然仲要買件 LCD.... 淘寶網六蚊件 2*16...
[ 本帖最後由 dulllou 於 2009-5-16 08:35 編輯 ]
作者: 薯餅v.v 時間: 2009-5-16 10:42
咁d制可以連去邊
作者: dulllou 時間: 2009-5-16 10:47
你睇返我份 code.
為左慳 pin, 我將五粒連晒去一個analog pin
每粒有一粒唔同 resistance o既 resistor, 然後用 analogRead() 去讀返個電壓就知道press 左邊個 button
唔想咁麻煩亦都可以一粒 button 連去一個 pin
冇咩所謂
[ 本帖最後由 dulllou 於 2009-5-16 10:47 編輯 ]
作者: pc1697 時間: 2009-5-18 18:12
dulllou 可唔可以轉載?
作者: dulllou 時間: 2009-5-18 23:19
隨便
Arduino 本來就係 GPL + CC 野~

