晌 Arduino 上用 LCD Smartie (附 code / 圖)

經板頭的精華文介紹, 原來竟然有 LCD Smartie 呢隻咁正o既 software, (之前唔知, 要自己寫 python + proxy 先可以晌 internet feed 到野落 Arduino 度) 而家可以經用 LCD Smartie 晌 Arduino feed 到野落o黎啦...好正.... 正如我之前講,  Arduino 係唔識電子o既 IT 佬用的恩物...




廢話少講, 講下點樣做

首先, 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 呢個畫面

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);)

可以參考下圖:


然後晌同一板 click "Screen" 然後選返適當o既 screen size (LCD shield 用o既係 2x16, 如果你 DIY o既就跟返你自己用o既 Screen size)

可以參考下圖

攪掂 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

禮成~ 感謝閱讀~




[ 本帖最後由 dulllou 於 2009-5-15 16:27 編輯 ]
附件: 您需要登錄才可以下載或查看附件。沒有帳號?註冊

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 編輯 ]

TOP

d制全部都可以用?

TOP

原帖由 薯餅v.v 於 2009-5-15 16:27 發表
d制全部都可以用?


  未得
要用得o個幾粒制的話其實都唔係太難, 我估應該 20 行以內就寫到, 問題係既然晌 LCD Smartie 已經控制到所有 function... 其實都唔太必要再用o個五粒 buttons (第六粒係 reset...). 再者, 其實我都未摸索完 LCD Smartie, 唔太 sure 佢會唔會收 input / 點樣整到佢收 Arduino 的 input.... 加上我今日攪左成日...未食早餐又未食晏...都係要食完野返來先再摸索 / 改 code 會好d

TOP

ching 加油 想玩下有key既lcd display~.~
成品好貴

TOP

哈哈, 攪掂左

加返個menu plugin 就可以~






[ 本帖最後由 dulllou 於 2009-5-15 23:55 編輯 ]
附件: 您需要登錄才可以下載或查看附件。沒有帳號?註冊

TOP

咁樓主如果自己砌一舊要買d咩

TOP

砌一隻 full function o既 arduino 睇呢度
http://itp.nyu.edu/physcomp/Tutorials/ArduinoBreadboard

如果淨係打算用來做 LCD display o既用 atmega8 就夠


另外如果你部電腦已經冇 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 編輯 ]
附件: 您需要登錄才可以下載或查看附件。沒有帳號?註冊

TOP

咁d制可以連去邊

TOP

你睇返我份 code.
為左慳 pin, 我將五粒連晒去一個analog pin
每粒有一粒唔同 resistance o既 resistor, 然後用 analogRead() 去讀返個電壓就知道press 左邊個 button

唔想咁麻煩亦都可以一粒 button 連去一個 pin
冇咩所謂

[ 本帖最後由 dulllou 於 2009-5-16 10:47 編輯 ]

TOP