· 

ArduinoのEEPROMに書き込、、、めた

再挑戦。ここに話の流れがちょっと理解できない投稿がある。先週は読み飛ばしていたけど、よく見ると古いbootloaderならいけるっぽい記述がある。で、まず、bootloaderの中身を見てみようと思った。

現在ArduinoUNOのbootloaderはoptibootてやつ。何もいじらずにArduinoをインストールすると、ここ

C:\Users\hoge\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\bootloaders\optiboot

にソースコードが入っている。

コメントにEEPROM読み書きは対応していないって書いてある。早く言ってよー

ここにもそれらしいことが書いてある。

 

古いブートローダーは通常

C:\Users\hoge\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\bootloaders\atmega

にある。atmega328p用は

ATmegaBOOT_168_atmega328.hex

で、うちはAVRISPMKIIをつかって、AtmelStudioから書き込めるけど、AVRISPMKIIを持ってない場合によくつかわれるArduino as ISP※ではどうするんや?

 

※ArduinoをISPライターにしちゃうやつ。Arduinoから「ブートローダーを書き込む」ってメニューでISPでつながっているArduino(正しく表現するとATMEGA328P)にブートローダーを書き込む(「Arduino を AVR  プログラマ(ISP: In-System Programmer)として使う」に詳しい説明がある)。

 

 まずは、Arduino as ISPを作る。

 ところで、我が家にはArduinoUNOがない。正規品、非正規品ともかなりの数所持してたはずなんだけど、、、で「Arduino を AVR  プログラマ(ISP: In-System Programmer)として使う」の通りにできない。うちにあるやつで何とかしよう。5V系だとこれしかなかったので、いつ買ったかわからんこれで。

いちおうまだ購入できるっぽい。

Arduino Leonard互換で、pinoutはシルク印字で確認できる。

 

では、

ArduinoIDEを起動して、スケッチ例-->11.ArduinoISP-->AesuinoISP、って選んでArduinoISPを開く。

そういえばArduinoIDE2系がリリースされて、VSCodeに近いUIになって、いろいろ便利になったんだけど、ありとあらゆる動作が遅い、色々な設定の変更方法がわからない、ので、1系に戻しました。

ボードをArduino LeonardoにしてPortを選ぶ、、、AeduinoLeonardoと主張しているので、それを選ぶ。

Goする。

当然、成功する。

結線する。超手抜き空中配線。

BEETLE-->UNOもどき

MO-->MOSI

MI-->MISO

SCK-->SCK

D10-->RESET

GND-->GND

 

RESETがD10ってのはArduinoISPのソースコードに書いてある。VTargetは不要。ArduinoISPはターゲットが電源ONであることを信じている。

 

で、ATmegaBOOT_168_atmega328.hexを書き込んでもらうにはどうしたらいいんや?

 

C:\Users\hoge\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\boards.txt

にボードとしてどれを選択したらどのbootloaderが書き込まれるのかが書かれているので、のぞく。で、

Arduino Duemilanove or Diecimila w/ ATmega328P

Arduino Nano w/ ATmega328P (old bootloader)

Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328P

のいずれかだと、ATmegaBOOT_168_atmega328.hexが書き込まれるらしい。たぶんどれでもいいけど、ホビーユーザーの自作ArduinoはArduino Proの回路が使いなじみがあるので、Arduino Proを選ぶ。

 

うちの場合はLeonardo互換なのでArduino as ISP (ATmega32U4)だけど、UNOを使う場合はArduino as ISPを選ぶんだと思う。

で、「ブートローダーを書き込む」を押す。

たぶん成功した。

これでbootloaderがUNO用からPro用に変わって、EEPROM書き込み出来るはず。

で、BEETLEをはずす。

で、VSCODEからトライする。(前回、実行時書き込みでEEPROMを書いてしまい、動作確認できない状態なので、ひそやかにAtmelStudio+AVRISPMKIIでEEPROMを削除した。)

#include <avr/eeprom.h>
#include <EEPROM.h>
 
typedef struct tag_test_data_element_struct{
    uint8_t upper:4;
    uint8_t lower:4;
}test_data_element_struct_t;
 
typedef union tag_test_data_struct{
    uint8_t asByte;
    test_data_element_struct_t elm;
}test_data_struct_t;
 
typedef struct tag_test_struct{
    uint8_t len;
    test_data_struct_t data[247];
    uint8_t cmd1[4];
    uint8_t cmd2[4];
}test_struct_t;
 
volatile test_struct_t test_mem EEMEM = {
    23,{ 0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x9A,0xAB,0xBC,0xCD,0xDE,0xEF,0xF0,
    0x01,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x9A,0xAB,0xBC,0xCD,0xDE,0xEF,0xF0,
    0x02,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x9A,0xAB,0xBC,0xCD,0xDE,0xEF,0xF0,
    0x03,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x9A,0xAB,0xBC,0xCD,0xDE,0xEF,0xF0,
    0x04,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x9A,0xAB,0xBC,0xCD,0xDE,0xEF,0xF0,
    0x05,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x9A,0xAB,0xBC,0xCD,0xDE,0xEF,0xF0,
    0x06,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x9A,0xAB,0xBC,0xCD,0xDE,0xEF,0xF0,
    0x07,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x9A,0xAB,0xBC,0xCD,0xDE,0xEF,0xF0,
    0x08,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x9A,0xAB,0xBC,0xCD,0xDE,0xEF,0xF0,
    0x09,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x9A,0xAB,0xBC,0xCD,0xDE,0xEF,0xF0,
    0x0A,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x9A,0xAB,0xBC,0xCD,0xDE,0xEF,0xF0,
    0x0B,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x9A,0xAB,0xBC,0xCD,0xDE,0xEF,0xF0,
    0x0C,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x9A,0xAB,0xBC,0xCD,0xDE,0xEF,0xF0,
    0x0D,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x9A,0xAB,0xBC,0xCD,0xDE,0xEF,0xF0,
    0x0E,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x9A,0xAB,0xBC,0xCD,0xDE,0xEF,0xF0,
    0x0F,0x12,0x23,0x34,0x45,0x56,0x67,0x78},{0x01,0x02,0x03,0x04},{0xDE,0xAD,0xBE,0xEF}
};
 
test_struct_t test_data;
 
void setup(){
    uint8_t d[256];
    char line[100];
    Serial.begin(115200);
    for(int i=0;i<256;i++){
        d[i]=EEPROM.read(i);
    }
    for(int i=0;i<16;i++){
        sprintf(
            line,
            "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
            d[i*16+0],d[i*16+1],d[i*16+2],d[i*16+3],d[i*16+4],d[i*16+5],d[i*16+6],d[i*16+7],
            d[i*16+8],d[i*16+9],d[i*16+10],d[i*16+11],d[i*16+12],d[i*16+13],d[i*16+14],d[i*16+15]
        );
        Serial.println(line);
    }
#if 0    
    EEPROM.get(0, test_data);
    Serial.println(test_data.len);
    for(int i=0;i<247;i++){
        Serial.print(test_data.data[i].elm.upper);
        Serial.print("/");
        Serial.println(test_data.data[i].elm.lower);
    }
    for(int i=0;i<4;i++){
        Serial.print(test_data.cmd1[i]);
    }
    Serial.println("");
    for(int i=0;i<4;i++){
        Serial.print(test_data.cmd2[i]);
    }
    Serial.println("");
#endif
}
void loop(){
 
}

こんなコードで、

まぁ、こんな感じですよね。Arduino Proに変更してから書き込んでみます。そして実行してみます。

まぁこういう状態です。で、Terminalを停止して、前回の「悶絶の記録」で作ったtaskを実行します。"-b","115200"は"-b","57600"に変更しておきます。

verify成功したって言ってます。ではターミナルを見てみよう。

ぃやーいけましたねー。宇宙の意思と調和できたのかもしれません。