2012/12/16

Arduino UNO R3 無法進入 DFU 模式



又再增購了兩片 Arduino UNO R3, 但這次每片的成本是第一片的一半...

使用後發現這次買的板子無法像原廠的板子可以直接 Reset Atmega16U2 進入 DFU 模式, 每次 Reset 系統也只能抓到串列通道, 真是傷腦筋.
爬了一下官網的討論區, 判斷可能是 Atmega16U2 中的程式版本的問題, 但是無法進入 DFU 模式也無法用 Flip 進行程式更新, 還好板子上有提供燒入接口, 並且因為成本一半多買了另外的一片, 問題總算有解決的方式.

方法如下:
1. 將其中一片 Arduino 燒入開發系統中提供的 ArduinoISP 程式, 模擬成 AVRISP.
2. 連接另外一片進行程式更新, 因要更新 Atmega16U2 於是要使用板上之ICSP for USB Interface 接口.
紅色(1)為pin1
燒錄僅需使用 MISO, SCk, Reset, MOSI pin.
接到 Arduino AVRISP 上的對應:
Target           AVRISP
pin 1 MISO   ->  pin 12
pin 3 SCk      -> pin 13
pin 5 Reset   -> pin 10
pin 4 MOSI   -> pin 11

GND               -> GND
5V                   -> 5V
3. 以 avrdude 工具經由模擬成 AVRISP 之 Arduino 對 另一 Arduino 之 Atmega16U2 進行程式更新.

指令:
avrdude.exe -p m16u2 -c avrisp -C "avrdude.conf"  -P com5
-U flash:w:"Arduino-COMBINED-dfu-usbserial-atmega16u2-Uno-Rev3.hex":a
-U flash:v:"Arduino-COMBINED-dfu-usbserial-atmega16u2-Uno-Rev3.hex":a
-U lfuse:w:FF
-U hfuse:w:D9
-U lock:w:0F
-U efuse:w:F4
-b 19200

其中 "com5" 為 Arduino AVRISP 在系統上辨識到的串列接口,  "-b 19200" 為ArduinoISP 程式中設定的速度 19200bps.


所需要的程式 avrdude , WinAVR, avrdude gui 等. 其中需要 WinAVR 是因為如果執行avrdude 時, 出現找不到 usblib0.dll 錯誤, 可以安裝 WinAVR來提供所需要的 dll . 另為 avrdude gui 為一視窗介面, 經由他可以更簡易的使用 avrdude.


原始碼 Arduino-COMBINED-dfu-usbserial-atmega16u2-Uno-Rev3.hex



Arduino UNO R3 的第一次

偶然的情況下看到一網路廣告, 認識了 Arduino .

"Arduino is an open-source electronics prototyping platform based on flexible, easy-to-use hardware and software. It's intended for artists, designers, hobbyists, and anyone interested in creating interactive objects or environments."
節錄於 http://www.arduino.cc

被他的宗旨吸引...
第一片Arduino UNO由原廠在台灣的代理商取得, 因為Arduino UNO模擬 USB Serial 介面的 Atmega16U2是可再程式化, 並可將它程式化為 HID Keyboard Device, 於是一個想到的應用利用這個功能實現了.

使用Arduino的程式開發環境編譯及上傳至 Mega328.

鍵盤模擬程式的範例:
#define KEY_A 0x04
long currentMillis = 0;
unsigned long fun1_Millis = 0;
unsigned long temp_fun_Millis =0;
unsigned long interval_fun1 = 180000; // 180 sec
uint8_t buf[8] = { 0 }; /* Keyboard report buffer */
void setup(){
  Serial.begin(9600);
  delay(2000);
  Send_key(1500, KEY_A);
}
void loop(){
  fun1_Millis = Fun_Check(fun1_Millis, interval_fun1, 1000, KEY_A);
}
void Send_key(int dtime, uint8_t KEY){
  buf[2] = KEY;
  Serial.write(buf, 8); // Send keystroke
  delay(dtime);
  Release_Key();
}
long Fun_Check(unsigned long fun_Millis, unsigned long interval_fun, int time_d, uint8_t KEY) {
  long temp_fun_Millis = 0;
  currentMillis = millis();
  temp_fun_Millis = fun_Millis;
  if(currentMillis - fun_Millis > interval_fun ) {
    temp_fun_Millis = currentMillis;
    buf[2] = KEY;
    Serial.write(buf, 8); // Send keystroke
    delay(time_d);
    Release_Key();
  }
  return temp_fun_Millis;
}

其中使用的鍵盤字元對照表可由 USB HID table 資料找到.

完成程式上傳後再使用 Atmel 的 flip 進行 Atmega16U2 的程式變更, 將 USB Serial port 轉成 HID Keyborad Drvice.

步驟:
1. Reset Arduino 上的 Atmega16U2 , 進入 DFU (Device Firmware Update)模式.
2. 以 Flip程式館將 arduino-keyborad-0.3.hex 上傳.

完成後將Arduino接上電腦, 於是一USB鍵盤模擬產生, 並會於設定的時間送出所要的按鍵 "a".
....

FLIP 取得 www.atmel.com/tools/FLIP.aspx