Showing posts with label DIY. Show all posts
Showing posts with label DIY. Show all posts

2023/01/02

Arduino #42集, “快速取得u8g2的字型代碼” (Get u8g2 unifont code quick & easy, u8g2 のフォント コードをすばやく取得する」です, u8g2용 폰트코드 빠르게 받아보기" 입니다)

歡迎收看Weekend project with Stonez56。 
本周是Arduino #42集, “快速取得u8g2的字型代碼”
我們將使用Stonez56 這個網站來快速取得字型代碼

目前為測試版: https://stonez56.com/u8g2/

這個 Stonez56 轉碼網站過人之處:

* 簡單易用用省時
* 自動移除重複字
* 產生極小的檔案 

使用方法簡單:

* 輸入你要轉換的字詞
* 按下送出
* 下載產生的字型代碼
* 存到 Arduino 專案目錄下
* 在你的主程式中, 用 include 帶進 字型.h 程式
* 用 u8g2.setFont(u8g2_font_unifont_myfonts) 

目前為測試版: https://stonez56.com/u8g2/




===========================
Stonez56 の Weekend プロジェクトへようこそ。
今週は Arduino #42 のエピソード「u8g2 のフォント コードをすばやく取得する」です。
Web サイト Stonez56 を使用して、フォント コードをすばやく取得します。

現在ベータ版:https://stonez56.com/u8g2/

この Stonez56 トランスコーディング サイトの優れた点:
*使いやすく、時間を節約
*重複する単語を自動的に削除
* 非常に小さいファイルを生成します

使いやすい:
*変換したい単語を入力してください
※押すと送信されます
* 生成されたフォント コードをダウンロードする
* Arduino プロジェクト ディレクトリに保存します。
* メイン プログラムで、include を使用して font.h プログラムを取り込みます。
* u8g2.setFont(u8g2_font_unifont_myfonts) を使用

現在ベータ版:https://stonez56.com/u8g2/


=============================
Stonez56과 함께하는 주말 프로젝트에 오신 것을 환영합니다.
이번주는 아두이노 #42편 "u8g2용 폰트코드 빠르게 받아보기" 입니다.
Stonez56 웹 사이트를 사용하여 글꼴 코드를 빠르게 얻습니다.

현재 베타 버전: https://stonez56.com/u8g2/

이 Stonez56 트랜스코딩 사이트의 장점:
* 사용하기 쉽고 시간을 절약
* 중복 단어 자동 제거
* 매우 작은 파일 생성

사용하기 쉬운:
* 변환하려는 단어를 입력하십시오
* 누르면 보내기
* 생성된 글꼴 코드 다운로드
* Arduino 프로젝트 디렉토리에 저장
* 기본 프로그램에서 include를 사용하여 font.h 프로그램을 가져옵니다.
* u8g2.setFont(u8g2_font_unifont_myfonts) 사용

현재 베타 버전: https://kidsgo.net/u8g2/

#arduino #u8g2 #font #lcd #display #weekendprojectwithstonez56 #diy #maker #oled #esp32 #esp8266 #stonez56 #fontgenerator #kidsgo.net #CJKfonts #CJK

2018/11/28

筆記 - 岳母香魯豬腳


香魯豬腳岳母的拿手菜!每次回高雄阿蓮,岳母常常做這道料理。




最近剛好是自己的生日,再過一週就是太太的生日,所以我也來試做看看。
雖然已經做過兩三次,但有時煮起來很成功顏色好看豬腳Q又好吃,有時很好吃,但是顏色又沒那麼好看。所以這次把它紀錄下來,下次參考!

打電話給岳母,她只告訴我,"很簡單,按下面步驟去做就好了"...心情好像不大好...原來她要選的市長這次落選了...

口述做法:
1. 炒二片薑,十來個蒜頭不切,不壓扁下去爆香
2. 炒鍋下醬油,水、冰糖大支䓤段、辣椒
3. 魯約 50分鐘很Q嫩很好吃,或魯到到個人喜好的軟嫩度即可起鍋。

材料:
  • 豬腳一支約2斤半重 (我是傳統市場買,請商家都已去毛用熱水湯過)
  • 薑少許切片
  • 大支䓤段數支
  • 蒜頭十來個
  • 辣椒一個(看喜好程度自行調整)
  • 醬油半碗、水兩碗~三碗
  • 沙拉油少許
  • 黑胡椒少許
  • 冰糖 (必備,顏色好看的重要材料)
詳細做法:
  • 豬腳用熱水川燙再起鍋備用
  • 炒鍋下點沙拉油、二三片薑、十來個蒜頭不切,不壓扁下去爆香
  • 豬腳入炒鍋下去炒,到每面有點焦黄色
  • 下醬油,水、冰糖大支䓤段、辣椒、黑胡椒到鍋內
  • 把豬腳及醬料充份拌勻再蓋上鍋蓋,用小火慢魯..
  • 魯約 50分鐘很Q嫩很好吃,或魯到到個人喜好的軟嫩度即可起鍋。


2017/09/16

Testing Arduino POV (Persistent of Vision) | 試試 Arduino POV (視覺暫留)

I have been attracted to Arduino POV[1] for quite a while, but I didn't have a chance to actually make it myself.   Luckily, I found this easy to follow Arduino POV tutorial[2] on Instructable.com and within an hour, my son and me made two Arduino POV sets and have fun for the entire afternoon.


Material needed for this tutorial:

  • Arduino Nano * 1 (All other kinds of Arduino board will do)
  • LED * 7
  • 220 resistor * 7 
  • Jump wire ~ up to 10 (female to male)
  • Prefboard * 1 
  • Battery pack (If you would like have fun without tethered with USB)

Easy Wire Connection as follow:

  1. LED1 ~ LED7 negative pin to Prefboard GND
  2. Prefboard to Nano(or Uno) GND pin
  3. LED1 ~ LED7 postive pin to Nano(or Uno) D2 ~ D8 pin
  4. USB power to Nano USB port to supply power (or use a battery back to supply power)

Schematic: (I use www.tinkercad.com to draw this schematic below, just in case you interested.)



This is a fun a easy project! First, just connect LED cathode(negative) and resistors on the prefboard.
Then Preboard GND to Arduino Nano GND.


Then connect these LED positive pins to Arduino Nano.





As you can see in the picture below, I'v used Arduino Nano. It's lighter and smaller for portable devices.  I made the Red one and my son have choose the Green.



Programming logic:
When anyone sees an image, the image stays in the retina of the eyes for roughly 1/16th seconds. We can utilize the particular physical characteristic of human eyes, to crate the Arduino POV project. The basic idea is when we want to show a letter, Arduino shows each column of a letter at a time to form the letter to eyes.

See the illustration below on how to show a letter 'H'. First, Arduino displays column 1 to light up all 7 LEDs at timing 1. While column 1 image stays in human eyes, Arduino shows 2nd column, then 3, 4, and 5th columns at their respectively timing 2~5. Since all these images stays in human eyes temporarily, we will see the letter 'H'.



Actual LED image captured:



Arduino code here:
Just copy and past into Arduino IDE and it should work.
*Change your own message in the variable msgBody and remember to change msgLength*

/*
 Written by Ahmad Saeed on 22 August 2015
 
 This code is capable of displaying the following characters;
 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ .-_!%&#$,()@?
*/ 

//////////////////// Message to Customize  ///////////////////
#define msgLength 11                                       ///
String msgBody = "This is POV";                            ///
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////




#define delayInChar 3
#define delayBetweenChar 5
#define LED1 2
#define LED2 3
#define LED3 4
#define LED4 5
#define LED5 6
#define LED6 7
#define LED7 8

byte msgCode[(5 * msgLength) + 10];
boolean pintState;
int columnNum = -1;
String charToWrite;

void setup() {
  msgBody.toUpperCase();
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(LED5, OUTPUT);
  pinMode(LED6, OUTPUT);
  pinMode(LED7, OUTPUT);
}

void loop() {
//// Convert all text to binary array ////////////////////////
  if ( columnNum == -1 ) // This block needs to be done once//
  {                                                         //
    for (int c = 0; c < (msgBody.length()); c++)  {         //
      //Separate the following character                    //
      charToWrite = msgBody.substring(c, c + 1);            //
      //Send the separated characted to addChar function    //
      addChar(charToWrite);                                 //
    }                                                       //
      //Add a little space after each character             //
    addChar(" ");                                           //
    addChar(" ");                                           //
  }                                                         //  
//////////////////////////////////////////////////////////////

//// Display the binary arrays after all characters are coded //
  for (int c = 0; c < (sizeof(msgCode)); c++)  {              //
    pintState = (msgCode[c] / B1000000) % B10;                //
    digitalWrite(LED1, pintState);                            //
                                                              //
    pintState = (msgCode[c] / B100000) % B10;                 //
    digitalWrite(LED2, pintState);                            //
                                                              //
    pintState = (msgCode[c] / B10000) % B10;                  //
    digitalWrite(LED3, pintState);                            //
                                                              //
    pintState = (msgCode[c] / B1000) % B10;                   //
    digitalWrite(LED4, pintState);                            //
                                                              //
    pintState = (msgCode[c] / B100) % B10;                    //
    digitalWrite(LED5, pintState);                            //
                                                              //
    pintState = (msgCode[c] / B10) % B10;                     //
    digitalWrite(LED6, pintState);                            // 
                                                              //
    pintState = msgCode[c] % B10;;                            //
    digitalWrite(LED7, pintState);                            //
                                                              //
    delay(delayInChar);                                       //
    // if the character is finished, take a longer off period //
    if ((c + 1) % 5 == 0 ) {                                  //
      digitalWrite(LED1, LOW);                                //
      digitalWrite(LED2, LOW);                                //
      digitalWrite(LED3, LOW);                                //
      digitalWrite(LED4, LOW);                                //
      digitalWrite(LED5, LOW);                                // 
      digitalWrite(LED6, LOW);                                //
      digitalWrite(LED7, LOW);                                //
      delay(delayBetweenChar);                                //
    }                                                         //
  }                                                           //
                                                              //
////////////////////////////////////////////////////////////////
}     


void addChar(String y) {
  if (y == "1") {
    addColumn(B0010001);
    addColumn(B0100001);
    addColumn(B1111111);
    addColumn(B0000001);
    addColumn(B0000001);
  }
  else if (y == "2") {
    addColumn(B0100001);
    addColumn(B1000011);
    addColumn(B1000101);
    addColumn(B1001001);
    addColumn(B0110001);
  }
  else if (y == "3") {
    addColumn(B0100010);
    addColumn(B1000001);
    addColumn(B1001001);
    addColumn(B1001001);
    addColumn(B0110110);
  }
  else if (y == "4") {
    addColumn(B0001100);
    addColumn(B0010100);
    addColumn(B0100100);
    addColumn(B1111111);
    addColumn(B0000100);
  }
  else if (y == "5") {
    addColumn(B1110010);
    addColumn(B1010001);
    addColumn(B1010001);
    addColumn(B1010001);
    addColumn(B1001110);
  }
  else if (y == "6") {
    addColumn(B0111110);
    addColumn(B1001001);
    addColumn(B1001001);
    addColumn(B1001001);
    addColumn(B0100110);
  }
  else if (y == "7") {
    addColumn(B1000000);
    addColumn(B1000111);
    addColumn(B1001000);
    addColumn(B1010000);
    addColumn(B1100000);
  }
  else if (y == "8") {
    addColumn(B0110110);
    addColumn(B1001001);
    addColumn(B1001001);
    addColumn(B1001001);
    addColumn(B0110110);
  }
  else if (y == "9") {
    addColumn(B0110010);
    addColumn(B1001001);
    addColumn(B1001001);
    addColumn(B1001001);
    addColumn(B0111110);
  }
  else if (y == "0") {
    addColumn(B0111110);
    addColumn(B1000101);
    addColumn(B1001001);
    addColumn(B1010001);
    addColumn(B0111110);
  }
  else if (y == "A") {
    addColumn(B0011111);
    addColumn(B0100100);
    addColumn(B1000100);
    addColumn(B1000100);
    addColumn(B1111111);
  }
  else if (y == "B") {
    addColumn(B1111111);
    addColumn(B1001001);
    addColumn(B1001001);
    addColumn(B1001001);
    addColumn(B0110110);
  }
  else if (y == "C") {
    addColumn(B0111110);
    addColumn(B1000001);
    addColumn(B1000001);
    addColumn(B1000001);
    addColumn(B0100010);
  }
  else if (y == "D") {
    addColumn(B1111111);
    addColumn(B1000001);
    addColumn(B1000001);
    addColumn(B1000001);
    addColumn(B0111110);
  }
  else if (y == "E") {
    addColumn(B1111111);
    addColumn(B1001001);
    addColumn(B1001001);
    addColumn(B1001001);
    addColumn(B1000001);
  }
  else if (y == "F") {
    addColumn(B1111111);
    addColumn(B1001000);
    addColumn(B1001000);
    addColumn(B1001000);
    addColumn(B1000000);
  }
  else if (y == "G") {
    addColumn(B0111110);
    addColumn(B1000001);
    addColumn(B1000001);
    addColumn(B1000101);
    addColumn(B0100110);
  }
  else if (y == "H") {
    addColumn(B1111111);
    addColumn(B0001000);
    addColumn(B0001000);
    addColumn(B0001000);
    addColumn(B1111111);
  }
  else if (y == "I") {
    addColumn(B0000000);
    addColumn(B1000001);
    addColumn(B1111111);
    addColumn(B1000001);
    addColumn(B0000000);
  }
  else if (y == "J") {
    addColumn(B0000000);
    addColumn(B0000010);
    addColumn(B1000001);
    addColumn(B1000001);
    addColumn(B1111110);
  }
  else if (y == "K") {
    addColumn(B1111111);
    addColumn(B0001000);
    addColumn(B0010100);
    addColumn(B0100010);
    addColumn(B1000001);
  }
  else if (y == "L") {
    addColumn(B1111111);
    addColumn(B0000001);
    addColumn(B0000001);
    addColumn(B0000001);
    addColumn(B0000001);
  }
  else if (y == "M") {
    addColumn(B1111111);
    addColumn(B0100000);
    addColumn(B0011000);
    addColumn(B0100000);
    addColumn(B1111111);
  }
  else if (y == "N") {
    addColumn(B1111111);
    addColumn(B0010000);
    addColumn(B0001000);
    addColumn(B0000100);
    addColumn(B1111111);
  }
  else if (y == "O") {
    addColumn(B0111110);
    addColumn(B1000001);
    addColumn(B1000001);
    addColumn(B1000001);
    addColumn(B0111110);
  }
  else if (y == "P") {
    addColumn(B1111111);
    addColumn(B1001000);
    addColumn(B1001000);
    addColumn(B1001000);
    addColumn(B0110000);
  }
  else if (y == "Q") {
    addColumn(B0111100);
    addColumn(B1000010);
    addColumn(B1000010);
    addColumn(B1000010);
    addColumn(B0111101);
  }
  else if (y == "R") {
    addColumn(B1111111);
    addColumn(B1001000);
    addColumn(B1001100);
    addColumn(B1001010);
    addColumn(B0110001);
  }
  else if (y == "S") {
    addColumn(B0110010);
    addColumn(B1001001);
    addColumn(B1001001);
    addColumn(B1001001);
    addColumn(B0100110);
  }
  else if (y == "T") {
    addColumn(B1000000);
    addColumn(B1000000);
    addColumn(B1111111);
    addColumn(B1000000);
    addColumn(B1000000);
  }
  else if (y == "U") {
    addColumn(B1111110);
    addColumn(B0000001);
    addColumn(B0000001);
    addColumn(B0000001);
    addColumn(B1111110);
  }
  else if (y == "V") {
    addColumn(B1111100);
    addColumn(B0000010);
    addColumn(B0000001);
    addColumn(B0000010);
    addColumn(B1111100);
  }
  else if (y == "W") {
    addColumn(B1111110);
    addColumn(B0000001);
    addColumn(B0000110);
    addColumn(B0000001);
    addColumn(B1111110);
  }
  else if (y == "X") {
    addColumn(B1100011);
    addColumn(B0010100);
    addColumn(B0001000);
    addColumn(B0010100);
    addColumn(B1100011);
  }
  else if (y == "Y") {
    addColumn(B1110000);
    addColumn(B0001000);
    addColumn(B0001111);
    addColumn(B0001000);
    addColumn(B1110000);
  }
  else if (y == "Z") {
    addColumn(B1000011);
    addColumn(B1000101);
    addColumn(B1001001);
    addColumn(B1010001);
    addColumn(B1000011);
  }
  else if (y == "Z") {
    addColumn(B1000011);
    addColumn(B1000101);
    addColumn(B1001001);
    addColumn(B1010001);
    addColumn(B1000011);
  }
  else if (y == " ") {
    addColumn(B0000000);
    addColumn(B0000000);
    addColumn(B0000000);
    addColumn(B0000000);
    addColumn(B0000000);
  }
  else if (y == ".") {
    addColumn(B0000000);
    addColumn(B0000011);
    addColumn(B0000011);
    addColumn(B0000000);
    addColumn(B0000000);
  }
  else if (y == "_") {
    addColumn(B0000001);
    addColumn(B0000001);
    addColumn(B0000001);
    addColumn(B0000001);
    addColumn(B0000001);
  }
  else if (y == "-") {
    addColumn(B0000000);
    addColumn(B0001000);
    addColumn(B0001000);
    addColumn(B0001000);
    addColumn(B0000000);
  }
  else if (y == "!") {
    addColumn(B0000000);
    addColumn(B0000000);
    addColumn(B1111101);
    addColumn(B0000000);
    addColumn(B0000000);
  }
  else if (y == "(") {
    addColumn(B0000000);
    addColumn(B0000000);
    addColumn(B0000000);
    addColumn(B0111110);
    addColumn(B1000001);
  }
  else if (y == ")") {
    addColumn(B1000001);
    addColumn(B0111110);
    addColumn(B0000000);
    addColumn(B0000000);
    addColumn(B0000000);
  }
  else if (y == "%") {
    addColumn(B1100010);
    addColumn(B1100100);
    addColumn(B0001000);
    addColumn(B0010011);
    addColumn(B0100011);
  }
  else if (y == ",") {
    addColumn(B0000000);
    addColumn(B0000101);
    addColumn(B0000110);
    addColumn(B0000000);
    addColumn(B0000000);
  }
  else if (y == "?") {
    addColumn(B0100000);
    addColumn(B1000101);
    addColumn(B1001000);
    addColumn(B0110000);
    addColumn(B0000000);
  }
  else if (y == "#") {
    addColumn(B0010100);
    addColumn(B0111110);
    addColumn(B0010100);
    addColumn(B0111110);
    addColumn(B0010100);
  }
  else if (y == "@") {
    addColumn(B0111110);
    addColumn(B1000001);
    addColumn(B1011101);
    addColumn(B1011101);
    addColumn(B0111000);
  }
  else if (y == "$") {
    addColumn(B0110010);
    addColumn(B1001001);
    addColumn(B1111111);
    addColumn(B1001001);
    addColumn(B0100110);
  }
}

void addColumn(byte x) {
  columnNum += 1;
  msgCode[columnNum] = (x);
}



Image captured with my POV set:




Image captured with my son's POV set:


How to capture the image:
I used HTC U11 to shot these photos. First, you have change HTC camera to Pro mode and set the exposure time to greater than 2 seconds to capture this image. Hold the Arduino POV set steadily on one hand and move the POV set slowly towards to left from right.  I believe any camera with Bulb exposure time greater than 2 seconds should be able to capture this image. 

That's all for this tutorial. See you next time!

Article feferences:
  1. Wikipedia for POV
  2. How to Make a POV Display Using LEDs and Arduino 
  3. Simple-Arduino-POV-Wand 


Done.

==== 中 文 版 本 ====

自從我看個幾個 Arduino POV[1] 專案之後,一直想自己試試做一個來玩玩,但一直有點懶惰,遲遲沒有動手。最近看到一篇很簡單的教學 Arduino POV tutorial[2] ,剛好兒子也在家,我們決定一起動手來做一個來玩。只需約一小時,我們就各自做了一組 Arduino POV,而且整個下午都在試著不同的字串及拿著 HTC U11 拍出很一些有趣的照片。這是一個很好的親子活動的安排哩!現在就看著這篇教學一起動手吧!


這篇教學所需材料:

  • Arduino Nano * 1 (Nano, Pro mini, Uno 都可以)
  • LED * 7
  • 220 歐姆電阻 * 7 
  • 杜邦線 ~ 約 10條 (母對母)
  • 洞洞板 * 1 
  • 電池盒 (不用連接USB,可以更方便的玩,但可有可無)

接線方式:
  1. LED1 ~ LED7 負級 to 220 歐姆電阻
  2. 電阻 to Nano(or Uno) GND
  3. LED1 ~ LED7 正級 to Nano(or Uno) D2 ~ D8 腳位
  4. USB 電源接 Nano USB 來提供電源 (這可以用電池盒來取代)

電路圖: (我是用 www.tinkercad.com 來製作這張電路圖)



這真的是一個很簡單又好玩的範例! 
道先, 先把 LED 負級連到220歐姆的電阻再由電阻連接到洞洞板的負極上。


接著,把LED 1 ~ 7 的正極接到 Arduino 上的 D2 ~ D8 腳位上。





我這次是使用了 Arduino Nano,因為它的體積比較小。下圖中可以看到我們做了兩組,我做了紅色的這組,我兒子則做了綠色的這一組。



程式的邏輯如下:
原理是當我們看到一個影像時,這個影像會暫留在視網膜上約 1/16 秒。當影像一個接著一個的顯示後,我們即會看到好像是數個影像的重疊,這些重疊的影像看起來就會形成一幅影像;卡通或動畫即是這樣的原理。Arduino POV 就是利用同樣的原理。

看下例如何顯示 H 字母。首先,Arduino 在 Time 1 顯示了欄位 1 的 7 個 LED,然後 Arduino 在 Time 2 ~ 5 個別的顯示欄位 2 ~ 5。 由於每個欄位都會在視網膜上暫留,我們就可以在到字母 'H'。


你可以參考這幾個字母放大後的影像如下:



Arduino 程式碼在上方,直接拷貝就可以使用:

*如果你要改變顯示的字串,請記得改變 msgBody 字串以及 msgLength 的字串長度*





下方是我用 HTC U11 照出來的 POV 照片:




這張是用我兒子那一組所拍下來的POV照片


如何照下 Arduino POV 的照片:
我是使用 HTC U11 來拍攝這些照片的。首先,你必需把手機設定到 PRO 模式 ,然後選定曝光時間到 2 秒以上才能拍的出來。拍攝時,拿著洞洞板,把 LED 朝相機方向,慢慢的由左到右的移動。不過,任何可以選定手動曝光到 2 秒以上的相機應該都可以拍的。

這就是這次的Arduino 範例,下次見!

文章參考:
  1. Wikipedia for POV
  2. How to Make a POV Display Using LEDs and Arduino 
  3. Simple-Arduino-POV-Wand 

2015/11/15

Arduino - IR Repeater Tutorial (Part 2)

If you want to see the complete tutorial, please visit IR Repeater Tutorial Part 1 first.

Test out everything on the proton board:
It's always a good practice to test out the wiring before solder components together. 
Connect IR receiver LED to Arduino Pro Mini



Connect IR emitter LED through 100 Ohm resister

The program below was created by Lauszus that I found on Gighub. The original program was written to receive IR code and decode IR then save the IR code in the memory until a button is pressed to emit IR code. To meet my requirement, I made few modifications to make it receive IR, decode IR, and then emit the IR immediately. Here is my code:

[Programming code]

/*
 * IRrecord: record and play back IR signals as a minimal 
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * An IR LED must be connected to the output PWM pin 3.
 * A button must be connected to the input BUTTON_PIN; this is the
 * send button.
 * A visible LED can be connected to STATUS_PIN to provide status.
 *
 * The logic is:
 * If the button is pressed, send the IR code.
 * If an IR code is received, record it.
 *
 * Version 0.11 September, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 *
 * 
 * Version 0.2 October, 2015
 * Modified to remove button function 
 * This module acts a IR Repeater to just 
 * "Read the IR Code " and "Send the IR Code" immediately
 * By En-Lin Chen / Stonez56
 *
 */

#include <IRremote.h>

int RECV_PIN = 2;
int STATUS_PIN = 13;

IRrecv irrecv(RECV_PIN);
IRsend irsend;

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(STATUS_PIN, OUTPUT);
}

// Storage for the recorded code
int codeType = -1; // The type of code
unsigned long codeValue; // The code value if not raw
unsigned int rawCodes[RAWBUF]; // The durations if raw
int codeLen; // The length of the code
int toggle = 0; // The RC5/6 toggle state

// Stores the code for later playback
// Most of this code is just logging
void storeCode(decode_results *results) {
  codeType = results->decode_type;
  int count = results->rawlen;
  if (codeType == UNKNOWN) {
    Serial.println("Received unknown code, saving as raw");
    codeLen = results->rawlen - 1;
    // To store raw codes:
    // Drop first value (gap)
    // Convert from ticks to microseconds
    // Tweak marks shorter, and spaces longer to cancel out IR receiver distortion
    for (int i = 1; i <= codeLen; i++) {
      if (i % 2) {
        // Mark
        rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS;
        Serial.print(" m");
      } 
      else {
        // Space
        rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS;
        Serial.print(" s");
      }
      Serial.print(rawCodes[i - 1], DEC);
    }
    Serial.println("");
  }
  else {
    if (codeType == NEC) {
      Serial.print("Received NEC: ");
    } 
    else if (codeType == SONY) {
      Serial.print("Received SONY: ");
    } 
    else if (codeType == RC5) {
      Serial.print("Received RC5: ");
    } 
    else if (codeType == RC6) {
      Serial.print("Received RC6: ");
    } 
    else {
      Serial.print("Unexpected codeType ");
      Serial.print(codeType, DEC);
      Serial.println("");
    }
    Serial.println(results->value, HEX);
    codeValue = results->value;
    codeLen = results->bits;
  }
}

void sendCode(int repeat) {
  if(codeValue == 0xFFFFFFFF) return;  //ignore FFFFFFF IR code
  if (codeType == NEC) {
      irsend.sendNEC(codeValue, codeLen);
      Serial.print("Sent NEC ");
      Serial.println(codeValue, HEX);
  } 
  else if (codeType == SONY) {
    irsend.sendSony(codeValue, codeLen);
    Serial.print("Sent Sony ");
    Serial.println(codeValue, HEX);
  } 
  else if (codeType == RC5 || codeType == RC6) {
    if (!repeat) {
      // Flip the toggle bit for a new button press
      toggle = 1 - toggle;
    }
    // Put the toggle bit into the code to send
    codeValue = codeValue & ~(1 << (codeLen - 1));
    codeValue = codeValue | (toggle << (codeLen - 1));
    if (codeType == RC5) {
      Serial.print("Sent RC5 ");
      Serial.println(codeValue, HEX);
      irsend.sendRC5(codeValue, codeLen);
    } 
    else {
      irsend.sendRC6(codeValue, codeLen);
      Serial.print("Sent RC6 ");
      Serial.println(codeValue, HEX);
    }
  } 
  else if (codeType == UNKNOWN /* i.e. raw */) {
    // Assume 38 KHz
    irsend.sendRaw(rawCodes, codeLen, 38);
    Serial.println("Sent raw");
  }
}


void loop() {

  if (irrecv.decode(&results)) {
    /* Receive IR code */
    Serial.println("Pressed!");
    digitalWrite(STATUS_PIN, HIGH);
    storeCode(&results);
    irrecv.resume(); // resume receiver
    digitalWrite(STATUS_PIN, LOW);
    delay(50);
    
    /* Send IR code */
    Serial.println("Sending!");
    digitalWrite(STATUS_PIN, HIGH);
    sendCode(true);
    digitalWrite(STATUS_PIN, LOW);
    delay(50); // Wait a bit between retransmissions
    irrecv.enableIRIn(); // Re-start the receiver
    Serial.println("--------------------------------");
  } 
}

After programming code is copied into Arduino IDE, upload it to your Arduino Pro Mini.

Power it up and then use any remote control to point to IR receiver and observe the Arduino IDE Serial output screen.  Turn on Serial Monitor: Arduino -> Tools->Serial Monitor


Here shows you the IR command received through the serial port monitor.

Received NFC: FFA252D (Remote type is NEC, and the code is 0xFFA25D)
Sent NEC: FFA25D


After fully tested, it's time to solder everything together.
First, solder IR emitter LED to the extended long wires. Although not showing at the photo below, an 100 Omh resistor is needed on the data pin 2.



I soldered the IR receiver LED on small proton board to allow me to fix it into the IR BOX easier. 
To provide constant power, I decided to use a smart phone power adaptor through a USB connector.


There are 4 tiny wires in the USB cable and you only need black and red wire to supply power to Arduino Pro Mini.  Red connects to VCC and Black connects to Ground.


I've chosen to use a name card case as the enclosure. I drilled a tiny hole in the front of the name card case (see below), to expose IR receiver LED towards the edge.


Too often, accidentally pulling the wires will break the soldering part, so I tight a knot on the extended long wires to secure wires in place. 

Now, every parts are soldered together as you see below.

Emitter board and Arduino Pro Mini placement is looked like this below.

Then, I glue the entire board with a glue gun to secure PCBs inside the name card box.

Plug the USB adaptor to power it up. Great! It's working.

Below is how this project looked like. As you can see, the extended wires are almost five to seven meters long.


Setup:
Follow IR Repeater Setup Illustration in Tutorial Part 1 
  1. Place IR BOX next to your TV and plug the USB adapter
  2. Pull the IR emitter with the wire through the wall into the living room
  3. Make sure the IR emitter is aiming towards the IR receiver on the Set Top Box
  4. I glue the IR emitter LED next to my couch and it working fine
  5. Done

After the setup, I've been use this IR repeater for 2~3 weeks and it's working perfectly without any issue. If you would like to make your own, you can follow this tutorial!

See the video below, if you haven't!


END.

==================================================

如果你要閱讀完整的教學,請參考第一篇教學

在洞洞板上試著做做看:
把所有電子零件都焊起來之前,我們最好利用洞洞板來測試一下,可以正常運作後才做焊接。請參考上圖,先用跳線把紅外線接收LED連線到  Arduino Pro Mini。



連接100歐姆電阻到紅外線發射 LED 正極

簡單的連線後,大致就完成了。接下來把下面的程式碼上傳到 Arduino 。

[程式碼請參考英文版內文]

上方的程式碼的原作者是 Lauszus  (Github) ,此程式原本是要接受到紅外線解碼後,儲存在記憶體中,在使用者按下一個按鈕後才由紅外線發射 LED 發射出訊號。
為了符合這個 IR BOX 的需求,我做了一些修改,讓它收到後直接發射出紅外線編碼。
接上 5V 電源,利用 MOD 的搖控器對準 IR 接收LED。你可以在 Arduino IDE 的 Serial Monitor 上觀查 IR BOX 接收與傳出 IR Code 的資料。
打開 Serial Monitor 的方式: Arduino -> Tools->Serial Monitor 參考下圖:




Received NFC: FFA252D (Remote type is NEC, and the code is 0xFFA25D)
(IR 接收解碼為:FFA252D 搖控器類型 NEC)
(IR 發射碼)Sent NEC: FFA25D

一切測試無誤後,可以開始動手把零件焊在一起。
先把 IR 發射 LED 焊到加長的電線上,別忘了在 LED 資料前焊上一個 100 歐姆的電阻(我底下的照片沒有這個電阻)。這個 IR 發射 LED 和兩條 7.5 公尺的電線就是要穿過牆放到到客廳裡。


我把 IR 接收 LED 焊在一塊洞洞板上,這樣可以讓 IR LED 固定的更好。
這個模組需要一個 5V 的電源長期供電才能運作,所以我找來一個手機的 5V 充電器來供電。


先把 USB 電源線剪一小段並剝去外面包覆的絕緣層。裡面有四條電線,我們只需要把紅色的焊接到 Arduino 正極(VCC),黑色的焊接到 Arduino 負極(GND),再把 USB 插到手機充電插頭即可以供電。


手上臨時找到了一個名片盒,就拿它來當做 IR BOX 的外殻吧!(好...我承認它不太美觀 ...Orz..)先在名片盒的側面鑽個小孔,只要讓 IR 接收 LED 可以外露出來,接受紅外訊號即可;如下圖:


接著,把延長的電線穿到名片盒後打上一個結固定好,以避免不小心拉扯電線時,把焊點拔斷了!

再接著,把電源焊到Arduino Pro Mini,並把線路依圖示都焊上。

再把焊有紅外接收 LED 的洞洞皮放到名片盒裡試試看那個位置合適。

確定 IR LED 有露出到剛剛鑽孔的位置,再把Arduino Pro Mini 位置確定後,用很多的膠固定電路板的位置;如下:

接上 USB 電源後紅色 LED 亮起,表示 IR BOX 已正常的運作了,太好了!

我做的 IR BOX(紅外線轉發器)整個看起來就像下面一樣。IR BOX 連著長長的電線(7.5公尺),電線的尾端則是 IR 發射LED 。

安裝:
依照教學的 Part 1 紅外線轉發器安裝方法圖示:
  1. 把 IR BOX 放在房間適當位置固定並插入電源
  2. 把長長的電源線和 IR 發射LED 穿過牆壁,
  3. 確認IR 發射LED 拉到能正對著機上盒的紅外接收位置 (Set Top Box)
  4. 我用膠槍把 IR LED 固定在沙發旁邊。
  5. 完成

安裝好後,我已經用了兩三個星期了,而且整個 IR 轉發器運作都很順利。
如果你也想要自己 DIY 一個話,可以自己開始動手了!!

如果你還沒有看過實際運作的影片,請按底下播放。


全文完.

2015/11/08

Arduino - IR Repeater Tutorial (Part 1)

Goal: 
To share a Set Top Box in living room with Bedroom TV using the same Remote Control.

Preface: 
Recently, I subscribed a VOD (Video On Demand) service that came with a Set Top Box in the living room. However, I would like to occasionally watch VOD in the bedroom, but the Set Top Box is in the living room. As you know, there is no way to control the Set Top Box in the living room from the bedroom.  Yeah, an IR repeater is all I need. There are commercial products available in the market already, but I quickly thought about the Control celling light with a TV remote Arduino project I have done before might be an replacement for the IR repeater I need. After all, this is why I learn Arduino - May my life easier!!

Drawbacks of this project:
Either one VOD TV program can be watched from living or bedroom at a time, since the Set Top Box is shared. 


Arduino Programming Logic:
The programming logic to repeat the IR signal is quite simple
  • Receive remote control signal from IR receiver
  • Decode the IR code
  • Send the decoded IR code from the IR emitter

IR Repeater Setup Illustration:
The illustration below shows you how the whole IR Repeater is setup in my apartment to share Set Top Box in two rooms.
  1. Living Room TV
  2. Bedroom TV
  3. Set Top Box (HDMI out connect to a HDMI switch, yes you need this!)
  4. HDMI cable from Set Top Box to bedroom TV
  5. Arduino IR Box 
  6. IR Emitter
  7. A hole on the wall
* The IR remotes shown below are actually the same remote

Working IR Repeater Prototype Video:
See the working prototype in the video below. As you can see, even through the IR repeater, the Set Top Box response time is fairly quick!


Material Needed:
  1. Arduino Mini Pro
  2. IR Emitter 940nm * 1 
  3. IR Receiver LED, Aixin AX-1838HS 38KHz * 1 (Other brand 38KHz should work)
  4. ProtoBoard * 1
  5. 100 ohm resistor * 1
  6. Short Jump wires * 10 
  7. 5 meter long single wires * 2 

LED Lineup:
Starts from the left: IR LED receiver, IR LED emitter, green LED, and red LED.
In the end, I didn't use red and green and LED, but relied on the Arduino built-in red LED on pin 13 and Serial port green LED in this project.



IR Repeater Wiring:
Wiring up is quite easy as you can see below. (I forgot to draw the 100 Ohm resistor in the illustration below, but you need it.)
  1. IR Emitter GND to GND
  2. IR Emitter Data to 100 Ohm resistor to Arduino pin 3
  3. IR Receiver Data to Arduino pin 2
  4. IR Receiver GND to Arduino GND
  5. IR Receiver VCC to Arduino VCC
  6. Proton board GND to power source GND
  7. Proton board VCC to power source VCC (USB power adapter)

In part 2, I will show you how I made the IR Repeater box, schematic, and Arduino code I modified from github by Lauszus. If you are interested, you may take a look at the code first.

To be continued. 

------------------------------

目的: 
不用另外租用一個額外的 MOD 機上盒,只要使用同一個搖控器,該你在臥室裡也可以觀看客廳所訂閱的中華電信 MOD! 

前言: 
最近,我訂閱了中華電信MOD系統,我把機上盒放在客廳裡。但是,我偶爾想在臥室裡收看MOD。可是機上盒在客廳裡,要怎麼辦呢?大家都知道,我不可能從臥室裡控制位於客廳的MOD。是的,我只需要一個紅外線(轉發器, 這個名詞正確嗎?)。市面上的相關產品有一大堆,但是我很快的想起我以前做的 以電視遙控器控臥室天花板電燈開關。這就是為什麼我要學Arduino - 讓我生活的更方便!

此作品之缺點:
因為機上盒是共用的,所以無法同時在客廳和臥室一起觀看不同的頻道。

Arduino 程式邏輯:
要讓紅外線信號重複的邏輯還蠻簡單的

  • 用紅外線接收器接收遙控器的信號
  • 將紅外線信號解碼
  • 從紅外線發射器傳送出解過碼的IR信號

紅外線轉發器安裝方法示圖
下圖展示出整個紅外線轉發器是如何安裝在我的家裡,使得兩個房間能分享機上盒。
  1. 客廳電視
  2. 臥室電視
  3. 機上盒
  4. HDMI延長線要從臥室電視連到機上盒
  5. Arduino紅外線轉發器
  6. 紅外線發射器
  7. 牆上的鑽孔
*下圖中的兩個遙控器代表同一個遙控器



紅外線轉發器原型運作影片:
請看以下的原型運作影片  可以看到即使經過轉接器 機上盒的反應仍舊相當迅速

所需材料:
  1. Arduino Mini Pro * 1
  2. 紅外線發射 LED 940nm * 1
  3. 紅外線接收 LED Aixin AX-1838HS 38KHz * 1 (只要是 38KHz 應該就能用)
  4. 麵包板 * 1
  5. 100歐姆電阻 * 1
  6. 短跳線*10
  7. 7.5 米長電線


各式 LED:
由左算起,IR 接收 LED, IR 發射 LED, 綠色 LED, 紅色 LED
這個專案裡,我最後沒有用到綠色 LED, 紅色 LED,我用的 Arduino 內建在13腳的紅色 LED, 和 Serial port 訊號的 LED.



紅外線轉發器接線方式:
接線很簡單,請參考下圖:(我忘了畫 100 Ohm 電阻,不過我們需要這個電阻)
  1. IR Emitter GND to GND
  2. IR Emitter Data to 100 Ohm resistor to Arduino pin 3
  3. IR Receiver Data to Arduino pin 2
  4. IR Receiver GND to Arduino GND
  5. IR Receiver VCC to Arduino VCC
  6. Proton board GND to power source GND
  7. Proton board VCC to power source VCC (USB power adapter)

接好了嗎?很簡單吧!
在第二段教學裡,我會把我如何用手邊棄不用的東西來製作紅外線轉發器的外盒(不是很好看,但墈用),及分享我用的程式碼。如果你等不及,那你可以參考 Github by Lauszus. 我就是用這位前輩的程式碼來修改完成這個作品的。

未完待續...