Arduino 紅外線發射實習 EPSON 投影機控制

學習如何學習!

設備與材料

個人電腦 × 1
arduino Uno × 1
麵包板 × 1
紅外線發射器 模組 × 1
4×4按鍵 × 1
電晶體 × 1
電阻 22Ω× 1
電阻 100Ω× 1
連接線 若干

實體接線圖

輸出波形

輸出 mark 載波波形放大
紅外線輸出波形

參考程式

因為要產生精準的38kHz方波載波來驅動紅外線,因此不用 arduino 提供的 delay() 或 delayMicroseconds() 函式,而是在 arduino 內使用組合語言指令 nop ,1個 nop 指令需要1個週期的時間,以 arduino Uno 16MHz的石英振盪器來說,1個週期的時間=0.0625μs,16個 nop 指令,剛好是 1μs。因此定義一個 delay1us 巨集,delay1us 就等於 插入 16 個 nop 指令的組合語言。

/* Arduino 紅外線發射實習 EPSON 投影機控制
*  S1 電源鍵  S2 黑幕鍵 S3 鎖定鍵
*/
#define   NEC
#define   IR_send_pin       3       //紅外線控制腳
#define   EPSON_START_MARK  9000
#define   EPSON_START_SPACE 4500
#define   EPSON_ONE_MARK    550
#define   EPSON_ONE_SPACE   1550
#define   EPSON_ZERO_MARK   550
#define   EPSON_ZERO_SPACE  600
#define   EPSON_END_MARK    600
#define   EPSON_END_SPACE   30000


//定義巨集 直接插入組合語言 16次 nop 指令
#define   delay1us           __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");

const int PB[4] = {10, 11, 12};                     //輸入接腳
boolean s1;       //按鈕狀態變數
boolean s2;       //按鈕狀態變數
boolean s3;       //按鈕狀態變數

unsigned char POWER[] = {0x83, 0x55, 0x90, 0x6F };
unsigned char FREEZE[] = {0x83, 0x55, 0x92, 0x6D };
unsigned char MUTE[] = {0x83, 0x55, 0x93, 0x6C };


void setup() {
  pinMode( IR_send_pin, OUTPUT );        // 設定輸出腳 
  pinMode( 13, OUTPUT );                 // 設定輸出腳
  digitalWrite(IR_send_pin, LOW);
   //設定 Arduino 輸入接腳 上接電阻模式
  for (int i = 0; i < 3; i++) {
    pinMode(PB[i],INPUT_PULLUP);
  }
}

void loop() {
  s1 = !digitalRead(PB[0]); // 讀取S1按鈕的狀態
  s2 = !digitalRead(PB[1]); // 讀取S2按鈕的狀態
  s3 = !digitalRead(PB[2]); // 讀取S3按鈕的狀態
  if(s1){
    //電源
    digitalWrite(13, HIGH);
    NECsend(POWER, 4);
    delay(300);
    digitalWrite(13, LOW);
  }else  if(s2){
    //設定鎖定畫面取消
    digitalWrite(13, HIGH);
    NECsend(FREEZE, 4);
    delay(300);
    digitalWrite(13, LOW);
  }else  if(s3){
    //設定黑畫面或取消黑畫面
    digitalWrite(13, HIGH);
    NECsend(MUTE, 4);
    delay(300);
    digitalWrite(13, LOW);
  }  
  
}

void NECsend(unsigned char buf[], int len) {
  byte data;
  //啟始位元
  mark(EPSON_START_MARK);
  space(EPSON_START_SPACE);
  //資料位元
  for (byte i = 0; i < len; i++) {
    data = buf[i];
    for (byte j = 0; j < 8; j++) {
      if ((1 << j & data)) {
        mark(EPSON_ZERO_MARK);        
        space(EPSON_ONE_SPACE);
      } else {        
        mark(EPSON_ZERO_MARK);
        space(EPSON_ZERO_SPACE);
      }
    }
  }
  //結束位元
  mark(EPSON_END_MARK);
  space(EPSON_END_SPACE);
}

//紅外線接腳輸出38kHz方波 time us
//16M 石英振盪器 產生 38kHz 方波,高電位 12.2us  低電位 14.4us 共 time us  
void mark(int time) {

  unsigned long beginTime = micros();
  unsigned long endTime = (unsigned long)time;
  unsigned long nowTime = micros();

  while (nowTime - beginTime < endTime) {

    /****************************************
    * HI = 3+8 = 11us 從示波器觀察約12.2us,   *
    * 有1.2us誤差                            *
    *****************************************/
    digitalWrite(IR_send_pin, HIGH);       //48 clock = 48*0.0625 u = 3us
    delay1us;delay1us;delay1us;delay1us;
    delay1us;delay1us;delay1us;delay1us;   //8*16*0.0625 us = 8 us
    
    /**************************************************  
    *   LOW = 3+6+1.8125=10.8125us + while 迴圈時間    *
    *   從示波器觀察一週約26.6us;26.6-12.2-10.8=3.6us,*
    *   while 1次迴圈自己佔用的時間約3.6us              *
    ***************************************************/
    digitalWrite(IR_send_pin, LOW); //48 clock = 48*0.0625 u = 3us
    delay1us;delay1us;delay1us;
    delay1us;delay1us;delay1us;     //6*16*0.0625 us = 6 us    
    nowTime = micros();             //29 clock = 29*0.0625 u = 1.8125 us
  }
}


//紅外線接腳低電位 time us
void space(int time) {
  digitalWrite(IR_send_pin, LOW);                  //48 clock = 48*0.0625 u = 3us
  unsigned long beginTime = micros();              //29 clock = 29*0.0625 u = 1.8125 us
  unsigned long endTime = (unsigned long)time-6;
  unsigned long nowTime = micros();               //29 clock = 29*0.0625 u = 1.8125 us
  while (nowTime - beginTime < endTime) {
    nowTime = micros();                           //29 clock = 29*0.0625 u = 1.8125 us
  }
}    

其它功能鍵

Menu        0x659A5583
ESC            0x7B845583
向上          0x4FB05583
向下          0x4DB25583
computer 0x6B945583
Video        0x8F705583
1                 0xC03F5583
3                 0xDC235583
4                 0xBC435583
5                0xBE415583 
7                0x619E5583

入門
知識
語法
流程
函式
實習

發佈留言