新規記事の投稿を行うことで、非表示にすることが可能です。
2016年06月15日
I2C経由でデバッグするための自動コード埋め込みツール
デバッグするための自動コード埋め込みツールを、EXCELのVBAで作りました。
でも欠点が2つあります。
1.Arduino IDEで作成したinoファイルの改行コードはLFなのに、VBAで読み込み書き込みをすると改行コードはCR+LFになってしまうことです。対応策はTeraPadというエディターで改行コードの変換ができます。
2.日本語が文字化けしてしまう。VBAでは日本語が読めていても、Arduino IDEでスケッチを開くと文字化けしてしまいます。改善策はあると思うのですが、調べるのにちょっと時間がかかりそうです。
でも欠点が2つあります。
1.Arduino IDEで作成したinoファイルの改行コードはLFなのに、VBAで読み込み書き込みをすると改行コードはCR+LFになってしまうことです。対応策はTeraPadというエディターで改行コードの変換ができます。
2.日本語が文字化けしてしまう。VBAでは日本語が読めていても、Arduino IDEでスケッチを開くと文字化けしてしまいます。改善策はあると思うのですが、調べるのにちょっと時間がかかりそうです。
【このカテゴリーの最新記事】
-
no image
-
no image
-
no image
2016年06月11日
Arduino IDE 環境にて、UncompatinoへI2C接続してデバッグする
UncompatinoにはUSB端子がありますが、これをデバッグ用にしてしまうと、USBを使うアプリはデバッグできません。そこで、デバッグの情報はI2Cでやり取りし、USBはアプリ側で使用できるようにしました。でも、無いよりはマシですが、物凄く便利というわけのものでもありません。その辺りをよく理解した上でもしご興味があればどうぞ試してみてください。
Arduino IDE を使用しますので、Uncompatinoともう一つのUNO互換機はPCとUSBで接続されます。Uncompatino側のUSBは、アプリが動き始めるとアプリが使用することになります。UNO互換機側のUSBは、I2C経由でUncompatinoから受け取ったデバッグ情報をPCに出力します。
デバッガー用にUNO互換機を買うつもりなら、Uncompatinoをお勧めします。Uncompatinoは、ISPライターの機能もあるので、これ1台でUncompatino上のATmega328Pにヒューズバイトとブートローダー、EEPROMを書くことができます。USB-シリアル変換ICのFTDI製FT232RLの機能です。写真の四角で囲ったISPのところがそうです。
I2Cの配線もA4、A5ピンをそれぞれ接続するだけです。ブレッドボードの一番右にはブレークポイントを抜けるためのstartButtonを配置しました。
You can write keywords is 234
TWBR is 0x48
TWSR is 0xF8
You can write keywords is 235
TWBR is 0x48
TWSR is 0xF8
You can write keywords is 236
TWBR is 0x48
TWSR is 0xF8
You can write keywords is 237
TWBR is 0x48
TWSR is 0xF8
私の環境では、ターゲット側のMaster-Writer2はCOM7をシリアルポートに指定しました。デバッガー側は、Arduino IDEをもう一つ起動して、COM8をシリアルポートに指定しました。くどいようですが、Arduino IDEを2つ起動するということは、Arduino IDEのスケッチを2つ開くということとは違います。お間違えのないようにご注意ください。Arduino IDEを2つ起動して初めて、別々のCOMをそれぞれ選べるようになります。Arduino IDEでソースコードを表示したら、COMポートを選択して、シリアルモニターを開いてください。ターゲット側とデバッガー側でそれぞれ別のCOMポートを選択できたかは、ウィンドウの下部にCOM番号が表示されますのでそれでも確認できます。
1.関数名などの文字列と、何番目のブレークポイントなのかを示す通し番号の2つを表示させる。
実装したものが下記となります。シリアル番号の表現としてint型で宣言して上位バイトと下位バイトに分離してバイト表現するやり方もあると思います。ここではbyte型のものを受信側(デバッガー側)でint型に合成することにしました。
Wire.beginTransmissionから始まってWire.write、Wire.endTransmissionで終わる一連の動作が一つのI2Cシーケンスとなります。
void debugPrint(char thisStr[]) { ← thisStr[]が任意の文字列となります。
Wire.beginTransmission(8); // transmit to device #8
Wire.write(thisStr); // sends charcters ← 文字列を送ります。
Wire.write(x[0]); // sends one byte ← シリアル番号の下位バイトを送ります。
Wire.write(x[1]); // sends one byte ← シリアル番号の上位バイトを送ります。
Wire.endTransmission(); // stop transmitting
if (x[0] == 255){
x[1]++; ← シリアル番号の更新です。
}
x[0]++; ← シリアル番号の更新です。
}
2.レジスター名とその内容(HEX形式)を表示させる。
実装したものが下記となります。
(レジスターによっては2バイト返すものがあるらしいのですが勉強不足で未対応です。そのうちに改良します。)
void debugRegPrint(char thisStr[], byte regValue) { ← レジスター名、その内容(1バイト)の順です。
Wire.beginTransmission(8); // transmit to device #8
Wire.write(thisStr); // sends charcters ← レジスター名の送信
Wire.write(regValue); // sends one byte ← レジスターの内容の送信 Arduino IDE では変数としてレジスタ名を書くだけでレジスタの内容が表示される仕様となっています。便利と言えばかなりお手軽な使い勝手です。これは、wire.hをインクルードしたので、幾重にもネストされたどこかのヘッダーファイルにマクロ定義がされているものと思います。そこまで調べて突き止める気力がありませんでした。
Wire.write(0); // dummy byte(debugPrintと揃える為) ← ダミーバイトの送信
Wire.endTransmission(); // stop transmitting
}
3.スタートボタンを押したらブレークポイントから抜けることができる。
実装したものが下記となります。
void breakPoint(void) { ← 引数も戻り値もありません。
while (1) { ← 無限ループです。
if (digitalRead(startButton) == LOW) { ← スタートボタンを押すとLOWになります。
delay(500);//wait a finger to take off ← 500ms待つのは、ボタンを押してから離すまでの時間です。ボタンを押してから離すまでは500ms以内に行わないと次のブレークポイントもすり抜けることになりますので注意してください。逆に長押しするということは、ブレークポイントを複数個所スルーできるので、適宜使い分けると便利かも。
break;//when the startButton got pushed ← 無限ループを抜けます。
}
}
}
4.上記1と2で送られたデータを解析して表示する。
実装したものが下記となります。
I2Cシーケンスが始まると割り込みが発生します。割り込みを処理する関数を割り込みハンドラーと呼びます。
void receiveEvent(int howMany) { ← 割り込みハンドラーです
while (2 < Wire.available()) { // loop through all but the last ← 受信したデータが最後の2バイトになるまでループします。
c = Wire.read(); // receive byte as a character ← 1バイトずつ文字として読みます。
if (c == '*'){ ← 読んだ文字が*なら、ここで打ち切りします。
break;
}
Serial.print(c); // print the character ← USB経由で1文字ずつPCに表示させます。
}
Serial.print(" is "); ← USB経由で文字列「 is 」をPCに表示させます。
if (c == '*'){ ← レジスターとしての処理を行います
//debugRegPrint
z = Wire.read(); // receive byte as a byte ← 1バイトをbyte型として読みます。
Serial.print("0x"); ← PCに「0x」を送ります。
Serial.println(z, HEX);// print the regValue as a hex ← 読んだデータをHEX形式でPCに送ります。
z = Wire.read(); // throw out a dummy byte ← ダミーバイトを読み捨てします。
} else { ← 任意の文字列の処理となります。
//debugPrint
x = Wire.read(); ← シリアル番号の下位バイトをint型として読みます。
y = Wire.read(); // receive byte as an integer ← シリアル番号の上位バイトをint型として読みます。
x = 256 * y + x; ← シリアル番号に戻しています。x += 256*y とも表現できますが分かり難いですよね。
Serial.println(x);// print the integer ← シリアル番号PCに送ります。
}
}
全体のサンプルコードは下記の通りです。Arduino IDE に付属していたコードを参考にさせていただきました。
(元ファイルは、Arduino IDEを立ち上げたら、メニューバーの「ファイル」−「スケッチの例」−「Wire」と開いて行くとあります)
loop()の中の、debugPrint、debugRegPrint、breakPointの3点で一組と考えていますが、debugPrint、breakPointの2点だけもありかなと思います。ここでは、レジスターTWBRとTWSRの値を読んでいますが、この2つのレジスターの値を読むとI2CのSCLの速度が計算できるからです。
最大の注意点なのですが、レジスタ名としてデバッガーに認識させるためには文字列の最後はアスタリスク(*)で終わってください。これが任意の文字列とレジスター名の文字列との識別子となります。
負の数字は扱わないのでx,yは、intではなくunsigned intとしました。そんな大きなプログラムは扱わないと思うのですが、気になったのでそうしておきました。
ATmega328Pの日本語データシートだとP136の「22.5.2.ビット速度発生器」のところに計算式があります。
SCL周波数=CPUクロック周波数/(16+2×(TWBR)×前置分周値)
前置分周値:P153の表22-7参照。→そのページに行くと、TWSRレジスターのbit1、bit0が、TWPS1、TWPS0とあり、表22-7から前置分周値が読み取れる。
今回の場合、TWBRが0x48で、TWSRが0xF8でした。0x48は10進で72、0xF8の下位2ビットは00なので分周値は1である。これを式に代入すると、SCL=16MHz/(16+2×72×1)=100kHz となりました。
後の問題は、ここで考えたブレークポイントを<どうやってターゲットのソースコードに埋め込むか>ですね。
まさか、関数ごとに手打ちで入れ込むなんて気が遠くなりそうだし間違えそう。なんとかしなくては。
接続図の説明
Arduino IDE を使用しますので、Uncompatinoともう一つのUNO互換機はPCとUSBで接続されます。Uncompatino側のUSBは、アプリが動き始めるとアプリが使用することになります。UNO互換機側のUSBは、I2C経由でUncompatinoから受け取ったデバッグ情報をPCに出力します。
実物写真
デバッガー用にUNO互換機を買うつもりなら、Uncompatinoをお勧めします。Uncompatinoは、ISPライターの機能もあるので、これ1台でUncompatino上のATmega328Pにヒューズバイトとブートローダー、EEPROMを書くことができます。USB-シリアル変換ICのFTDI製FT232RLの機能です。写真の四角で囲ったISPのところがそうです。
I2Cの配線もA4、A5ピンをそれぞれ接続するだけです。ブレッドボードの一番右にはブレークポイントを抜けるためのstartButtonを配置しました。
デバッガー側のシリアルポートの表示例
You can write keywords is 234
TWBR is 0x48
TWSR is 0xF8
You can write keywords is 235
TWBR is 0x48
TWSR is 0xF8
You can write keywords is 236
TWBR is 0x48
TWSR is 0xF8
You can write keywords is 237
TWBR is 0x48
TWSR is 0xF8
Arduino IDEの起動の仕方
私の環境では、ターゲット側のMaster-Writer2はCOM7をシリアルポートに指定しました。デバッガー側は、Arduino IDEをもう一つ起動して、COM8をシリアルポートに指定しました。くどいようですが、Arduino IDEを2つ起動するということは、Arduino IDEのスケッチを2つ開くということとは違います。お間違えのないようにご注意ください。Arduino IDEを2つ起動して初めて、別々のCOMをそれぞれ選べるようになります。Arduino IDEでソースコードを表示したら、COMポートを選択して、シリアルモニターを開いてください。ターゲット側とデバッガー側でそれぞれ別のCOMポートを選択できたかは、ウィンドウの下部にCOM番号が表示されますのでそれでも確認できます。
デバッグ仕様
1.関数名などの文字列と、何番目のブレークポイントなのかを示す通し番号の2つを表示させる。
実装したものが下記となります。シリアル番号の表現としてint型で宣言して上位バイトと下位バイトに分離してバイト表現するやり方もあると思います。ここではbyte型のものを受信側(デバッガー側)でint型に合成することにしました。
Wire.beginTransmissionから始まってWire.write、Wire.endTransmissionで終わる一連の動作が一つのI2Cシーケンスとなります。
void debugPrint(char thisStr[]) { ← thisStr[]が任意の文字列となります。
Wire.beginTransmission(8); // transmit to device #8
Wire.write(thisStr); // sends charcters ← 文字列を送ります。
Wire.write(x[0]); // sends one byte ← シリアル番号の下位バイトを送ります。
Wire.write(x[1]); // sends one byte ← シリアル番号の上位バイトを送ります。
Wire.endTransmission(); // stop transmitting
if (x[0] == 255){
x[1]++; ← シリアル番号の更新です。
}
x[0]++; ← シリアル番号の更新です。
}
2.レジスター名とその内容(HEX形式)を表示させる。
実装したものが下記となります。
(レジスターによっては2バイト返すものがあるらしいのですが勉強不足で未対応です。そのうちに改良します。)
void debugRegPrint(char thisStr[], byte regValue) { ← レジスター名、その内容(1バイト)の順です。
Wire.beginTransmission(8); // transmit to device #8
Wire.write(thisStr); // sends charcters ← レジスター名の送信
Wire.write(regValue); // sends one byte ← レジスターの内容の送信 Arduino IDE では変数としてレジスタ名を書くだけでレジスタの内容が表示される仕様となっています。便利と言えばかなりお手軽な使い勝手です。これは、wire.hをインクルードしたので、幾重にもネストされたどこかのヘッダーファイルにマクロ定義がされているものと思います。そこまで調べて突き止める気力がありませんでした。
Wire.write(0); // dummy byte(debugPrintと揃える為) ← ダミーバイトの送信
Wire.endTransmission(); // stop transmitting
}
3.スタートボタンを押したらブレークポイントから抜けることができる。
実装したものが下記となります。
void breakPoint(void) { ← 引数も戻り値もありません。
while (1) { ← 無限ループです。
if (digitalRead(startButton) == LOW) { ← スタートボタンを押すとLOWになります。
delay(500);//wait a finger to take off ← 500ms待つのは、ボタンを押してから離すまでの時間です。ボタンを押してから離すまでは500ms以内に行わないと次のブレークポイントもすり抜けることになりますので注意してください。逆に長押しするということは、ブレークポイントを複数個所スルーできるので、適宜使い分けると便利かも。
break;//when the startButton got pushed ← 無限ループを抜けます。
}
}
}
4.上記1と2で送られたデータを解析して表示する。
実装したものが下記となります。
I2Cシーケンスが始まると割り込みが発生します。割り込みを処理する関数を割り込みハンドラーと呼びます。
void receiveEvent(int howMany) { ← 割り込みハンドラーです
while (2 < Wire.available()) { // loop through all but the last ← 受信したデータが最後の2バイトになるまでループします。
c = Wire.read(); // receive byte as a character ← 1バイトずつ文字として読みます。
if (c == '*'){ ← 読んだ文字が*なら、ここで打ち切りします。
break;
}
Serial.print(c); // print the character ← USB経由で1文字ずつPCに表示させます。
}
Serial.print(" is "); ← USB経由で文字列「 is 」をPCに表示させます。
if (c == '*'){ ← レジスターとしての処理を行います
//debugRegPrint
z = Wire.read(); // receive byte as a byte ← 1バイトをbyte型として読みます。
Serial.print("0x"); ← PCに「0x」を送ります。
Serial.println(z, HEX);// print the regValue as a hex ← 読んだデータをHEX形式でPCに送ります。
z = Wire.read(); // throw out a dummy byte ← ダミーバイトを読み捨てします。
} else { ← 任意の文字列の処理となります。
//debugPrint
x = Wire.read(); ← シリアル番号の下位バイトをint型として読みます。
y = Wire.read(); // receive byte as an integer ← シリアル番号の上位バイトをint型として読みます。
x = 256 * y + x; ← シリアル番号に戻しています。x += 256*y とも表現できますが分かり難いですよね。
Serial.println(x);// print the integer ← シリアル番号PCに送ります。
}
}
全体のサンプルコードは下記の通りです。Arduino IDE に付属していたコードを参考にさせていただきました。
(元ファイルは、Arduino IDEを立ち上げたら、メニューバーの「ファイル」−「スケッチの例」−「Wire」と開いて行くとあります)
ターゲット側のソースコード(Master-Writer2)
loop()の中の、debugPrint、debugRegPrint、breakPointの3点で一組と考えていますが、debugPrint、breakPointの2点だけもありかなと思います。ここでは、レジスターTWBRとTWSRの値を読んでいますが、この2つのレジスターの値を読むとI2CのSCLの速度が計算できるからです。
最大の注意点なのですが、レジスタ名としてデバッガーに認識させるためには文字列の最後はアスタリスク(*)で終わってください。これが任意の文字列とレジスター名の文字列との識別子となります。
#include <Wire.h>
byte x[2]; //as a serial number
const int startButton = 7;
void setup() {
Wire.begin(); // join i2c bus (address optional for master)
pinMode(startButton, INPUT);
x[0] = 0;
x[1] = 0;
}
void debugPrint(char thisStr[]) {
Wire.beginTransmission(8); // transmit to device #8
Wire.write(thisStr); // sends charcters
Wire.write(x[0]); // sends one byte
Wire.write(x[1]); // sends one byte
Wire.endTransmission(); // stop transmitting
if (x[0] == 255){
x[1]++;
}
x[0]++;
}
void debugRegPrint(char thisStr[], byte regValue) {
Wire.beginTransmission(8); // transmit to device #8
Wire.write(thisStr); // sends charcters
Wire.write(regValue); // sends one byte
Wire.write(0); // dummy byte(debugPrintと揃える為)
Wire.endTransmission(); // stop transmitting
}
void breakPoint(void) {
while (1) {
if (digitalRead(startButton) == LOW) {
delay(500);//wait a finger to take off
break;//when the startButton got pushed
}
}
}
void loop() {
debugPrint("You can write keywords");//ここは適当な文字列
debugRegPrint("TWBR*", TWBR); //read TWBR reg. レジスター名には*をつける
debugRegPrint("TWSR*", TWSR); //read TWSR reg.
breakPoint();
}
デバッガー側のソースコード(Slave-Receiver2)
負の数字は扱わないのでx,yは、intではなくunsigned intとしました。そんな大きなプログラムは扱わないと思うのですが、気になったのでそうしておきました。
#include <Wire.h>
void setup() {
Wire.begin(8); // join i2c bus with address #8
Wire.onReceive(receiveEvent); // register event
Serial.begin(230400); // start serial for output
}
void loop() {
delay(100);
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
char c;
unsigned int x, y;
byte z;
void receiveEvent(int howMany) {
while (2 < Wire.available()) { // loop through all but the last
c = Wire.read(); // receive byte as a character
if (c == '*'){
break;
}
Serial.print(c); // print the character
}
Serial.print(" is ");
if (c == '*'){
//debugRegPrint
z = Wire.read(); // receive byte as a byte
Serial.print("0x");
Serial.println(z, HEX);// print the regValue as a hex
z = Wire.read(); // throw out a dummy byte
} else {
//debugPrint
x = Wire.read();
y = Wire.read(); // receive byte as an integer
x = 256 * y + x;
Serial.println(x);// print the integer
}
}
I2CのSCLの周波数計算
ATmega328Pの日本語データシートだとP136の「22.5.2.ビット速度発生器」のところに計算式があります。
SCL周波数=CPUクロック周波数/(16+2×(TWBR)×前置分周値)
前置分周値:P153の表22-7参照。→そのページに行くと、TWSRレジスターのbit1、bit0が、TWPS1、TWPS0とあり、表22-7から前置分周値が読み取れる。
今回の場合、TWBRが0x48で、TWSRが0xF8でした。0x48は10進で72、0xF8の下位2ビットは00なので分周値は1である。これを式に代入すると、SCL=16MHz/(16+2×72×1)=100kHz となりました。
一休み
後の問題は、ここで考えたブレークポイントを<どうやってターゲットのソースコードに埋め込むか>ですね。
まさか、関数ごとに手打ちで入れ込むなんて気が遠くなりそうだし間違えそう。なんとかしなくては。
2016年06月08日
Arduino IDE デバッグやり辛いですよね?
前提条件:Arduino UNO 互換機をターゲットとします。UNO互換機からUSBで大量のデータをPCに送るアプリのデバッグをしようとしています。
Arduino IDE って、デバッグのことは深く考えてないですよね。Visual Studioみたいにブレークポイントの設定ができるとよいのですが、そういうものは一切無いですよねえ。これって贅沢な意見なのでしょうか。残念ですね。
Arduino IDE for Visual Studio extention というものがあるらしいのですが、PCとターゲットボード間はシリアルポート(USB)で接続するみたいです。そうなると、ターゲットの機能でシリアルポート(USB)を使う仕様だった場合はどうなるのでしょうか? 複数のシリアルポート(USB)をターゲットボードが持っていないといけないですよね。う〜む。
Arduino IDE for Visual Studio extentionが、I2CかSPIでターゲットボードと通信する仕様なら実用性があると思うのですが、実際のところどうなのでしょう? シリアル接続じゃあ、シリアルポート使うアプリだとデバッグできないということでしょ? これは絶対に不便だと思うなあ。これって実際にデバッグ記事の投稿ありませんよね。
やはり現実的な方法としては、ターゲットボードのパラメーターを、別のArduino(互換機)とI2C通信で取得して、それを別のArduino(互換機)のシリアルポートからPCへ出力するのがベストですよね。
みなさんはどうされていますか。もしご存じでしたら教えていただけないでしょうか。
Arduino IDE って、デバッグのことは深く考えてないですよね。Visual Studioみたいにブレークポイントの設定ができるとよいのですが、そういうものは一切無いですよねえ。これって贅沢な意見なのでしょうか。残念ですね。
Arduino IDE for Visual Studio extention というものがあるらしいのですが、PCとターゲットボード間はシリアルポート(USB)で接続するみたいです。そうなると、ターゲットの機能でシリアルポート(USB)を使う仕様だった場合はどうなるのでしょうか? 複数のシリアルポート(USB)をターゲットボードが持っていないといけないですよね。う〜む。
Arduino IDE for Visual Studio extentionが、I2CかSPIでターゲットボードと通信する仕様なら実用性があると思うのですが、実際のところどうなのでしょう? シリアル接続じゃあ、シリアルポート使うアプリだとデバッグできないということでしょ? これは絶対に不便だと思うなあ。これって実際にデバッグ記事の投稿ありませんよね。
やはり現実的な方法としては、ターゲットボードのパラメーターを、別のArduino(互換機)とI2C通信で取得して、それを別のArduino(互換機)のシリアルポートからPCへ出力するのがベストですよね。
みなさんはどうされていますか。もしご存じでしたら教えていただけないでしょうか。
タグ:デバッグ Arduino IDE
2016年06月07日
arduino IDEを使う
前提条件:ボードは、Uncompatino または、ちびでぃ〜の2とする。
どういう設定で使うのかというところが知りたいところですよね。
aruduino IDE のボード指定は、Arduino/Genuino UNO を選択します。(本当は互換機なんだけど)
どのシリアルポートを使うのかはとても重要です。自分のターゲットボードはCOMの何番になるのかは、デバイスマネージャーを起動して、ボードを抜き差しして確認しておいてください。
COMの速度ですが、私は、115200bpsでやっています。シリアルモニタのところをクリックするとCOM windowが出ますので、そこで速度を変えて試してみてください。
書き込み装置はデフォルトのままいじりません。"AVRISP mkII" のままです。
以上でスケッチを書き込めるようになった筈です。
どういう設定で使うのかというところが知りたいところですよね。
aruduino IDE のボード指定は、Arduino/Genuino UNO を選択します。(本当は互換機なんだけど)
どのシリアルポートを使うのかはとても重要です。自分のターゲットボードはCOMの何番になるのかは、デバイスマネージャーを起動して、ボードを抜き差しして確認しておいてください。
COMの速度ですが、私は、115200bpsでやっています。シリアルモニタのところをクリックするとCOM windowが出ますので、そこで速度を変えて試してみてください。
書き込み装置はデフォルトのままいじりません。"AVRISP mkII" のままです。
以上でスケッチを書き込めるようになった筈です。
2016年06月06日
ちびでぃ〜の2にヒューズバイトとブートローダーを書く
Uncompatinoはヒューズバイトとブートローダーを自己書き込みできますが、ちびでぃ〜の2は自己書き込みに対応していません。
そこで、私はUncompatinoとちびでぃ〜の2をISP接続して書き込みました。まだUSB-シリアル変換ICをマウントする前に書きました。
PC--(USB接続)-->Uncompatino--(自作ジャンパーコード接続)-->ちびでぃ〜の2
自作ジャンパーコード接続
Uncompatino--ちびでぃ〜の2
CTS--MISO
DCD--MOSI
DSR--SCK
RI--RESET
+5VとGNDも、Uncompatinoから、ちびでぃ〜の2へ接続すること。
開発環境はavrdudeを使いました。やり方は、「avrdudeを使ってATmega328Pにヒューズバイトとブートローダを書き込む」と全く同じです。参照してください。
そこで、私はUncompatinoとちびでぃ〜の2をISP接続して書き込みました。まだUSB-シリアル変換ICをマウントする前に書きました。
PC--(USB接続)-->Uncompatino--(自作ジャンパーコード接続)-->ちびでぃ〜の2
自作ジャンパーコード接続
Uncompatino--ちびでぃ〜の2
CTS--MISO
DCD--MOSI
DSR--SCK
RI--RESET
+5VとGNDも、Uncompatinoから、ちびでぃ〜の2へ接続すること。
開発環境はavrdudeを使いました。やり方は、「avrdudeを使ってATmega328Pにヒューズバイトとブートローダを書き込む」と全く同じです。参照してください。
ちびでぃ〜の2の修理(USB-シリアル変換ICの交換)
ちびでぃ〜の2のUSB-シリアル変換ICは、 prolific製のPL2303を使っています。私が購入したちびでぃ〜の2はしかもICのバージョンがかなり古くて、メーカーprolificがデバイスドライバーの対応をやめてしまい、Windows8.1には対応していないものでした。
ちびでぃ〜の2の販売者に質問状を出して解決策を教えてほしいと連絡したのですが、回答はありませんでした。Uncompatinoに比較すると、ちびでぃ〜の2はちょっと安いので、色気を出して購入したのですが、裏目に出ました。安いだけじゃダメなのです。PL2303は評判の良くないICでした。数年前からこの手の問題が表面化していたのでした。私はとんでもないものを掴んでしまいました。今回の件は反面教師としたいと思います。
結局、自分なりに考えて、USB-シリアル変換ICをメーカーFTDIのFT232RLに置き換えるしか手立てはないという結論に至り、秋月電子にてFT232RLを420円で購入しました。IC交換の大変な作業と余分な部品代でずいぶん高い買い物になりました。最初からUncompatinoを買っておけば良かった。失敗した〜。
IC交換したら何事もなくすんなりとCOMポートの識別が出来ました。もうこれからはこのボードは単に互換ボードと呼ぶべきですね。
ちびでぃ〜の2の販売者に質問状を出して解決策を教えてほしいと連絡したのですが、回答はありませんでした。Uncompatinoに比較すると、ちびでぃ〜の2はちょっと安いので、色気を出して購入したのですが、裏目に出ました。安いだけじゃダメなのです。PL2303は評判の良くないICでした。数年前からこの手の問題が表面化していたのでした。私はとんでもないものを掴んでしまいました。今回の件は反面教師としたいと思います。
結局、自分なりに考えて、USB-シリアル変換ICをメーカーFTDIのFT232RLに置き換えるしか手立てはないという結論に至り、秋月電子にてFT232RLを420円で購入しました。IC交換の大変な作業と余分な部品代でずいぶん高い買い物になりました。最初からUncompatinoを買っておけば良かった。失敗した〜。
IC交換したら何事もなくすんなりとCOMポートの識別が出来ました。もうこれからはこのボードは単に互換ボードと呼ぶべきですね。
avrdudeを使ってATmega328Pにヒューズバイトとブートローダを書き込む
avrdudeのダウンロードとインストールは、「USB−シリアル変換IC FT232RLを使ったブートローダの書き込み」を参考にしてください。
URL・・・https://fanblogs.jp/papas56/archive/6/0
ターゲットはUncompatinoとします。PCとUncompatinoをUSB接続します。UncompatinoのISPはジャンパー線で下記のようにショートしておきます。
CTS--MISO
DCD--MOSI
DSR--SCK
RI--RESET
最後にavrdudeを起動します。
@avrdude.exeの場所を指定する。
APrgrammerに、FT232R Synchronous BitBang(diecimila)を指定する。
BUncompatinoのPort番号を指定する。デバイスマネージャーを起動しておき、UncompatinoをPCに接続すると新たにCOMが表示されるので、その番号を指定する。
CDeviceに、ATmage328P(m328p)を指定する。
DCommand line Optionに、-P ft0 B 115200 と指定する。
EReadボタンをクリックしてまず値を読んでみる。書き込む値は下記を指定する。
hFuse・・・DA
lFuse・・・DF
eFuse・・・05
Writeボタンをクリックして書き込む。もう一度Readボタンをクリックして値を確認する。
Fブートローダーを指定する。下記の値を使用する。
インストールしたフォルダ\arduino-nightly\hardware\arduino\avr\bootloaders\optiboot\optiboot_atmega328.hex
エラーが無ければ何事も表示されないので、あっけなく書き込みは完了する。エラーがあるとダイアログが開きエラー内容が表示される。
URL・・・https://fanblogs.jp/papas56/archive/6/0
ターゲットはUncompatinoとします。PCとUncompatinoをUSB接続します。UncompatinoのISPはジャンパー線で下記のようにショートしておきます。
CTS--MISO
DCD--MOSI
DSR--SCK
RI--RESET
最後にavrdudeを起動します。
@avrdude.exeの場所を指定する。
APrgrammerに、FT232R Synchronous BitBang(diecimila)を指定する。
BUncompatinoのPort番号を指定する。デバイスマネージャーを起動しておき、UncompatinoをPCに接続すると新たにCOMが表示されるので、その番号を指定する。
CDeviceに、ATmage328P(m328p)を指定する。
DCommand line Optionに、-P ft0 B 115200 と指定する。
EReadボタンをクリックしてまず値を読んでみる。書き込む値は下記を指定する。
hFuse・・・DA
lFuse・・・DF
eFuse・・・05
Writeボタンをクリックして書き込む。もう一度Readボタンをクリックして値を確認する。
Fブートローダーを指定する。下記の値を使用する。
インストールしたフォルダ\arduino-nightly\hardware\arduino\avr\bootloaders\optiboot\optiboot_atmega328.hex
エラーが無ければ何事も表示されないので、あっけなく書き込みは完了する。エラーがあるとダイアログが開きエラー内容が表示される。
2016年06月05日
USB−シリアル変換IC FT232RLを使ったブートローダの書き込み
Aruduino IDE(開発環境)を使用してもISPにてブートローダを書き込めるとのことですが、Aruduino(ハードウエア)をライターとして用意し、ライターソフトも書き込む必要があります。
avrdude(開発環境)は、ターゲット(例えばUncompatino)のATmega328Pに直接ヒューズビットやブートローダを書き込めるとのことです。これは、USB-シリアル変換ICのFT232RLのCTS、DSR、DCD、RIの4つの制御線を以下のようにATmega328Pに接続することによって、ヒューズビットとブートローダを書き込めるようになっているとのことです。
CTS--MISO
DCD--MOSI
DSR--SCK
RI--RESET
+5VとGNDはUSB経由でPCから供給されることが前提。
参考にしたサイトです。
http://engawa.kakaku.com/userbbs/1681/Page=2/SortType=ThreadID/#1681-6
avrdude(開発環境)は、ターゲット(例えばUncompatino)のATmega328Pに直接ヒューズビットやブートローダを書き込めるとのことです。これは、USB-シリアル変換ICのFT232RLのCTS、DSR、DCD、RIの4つの制御線を以下のようにATmega328Pに接続することによって、ヒューズビットとブートローダを書き込めるようになっているとのことです。
CTS--MISO
DCD--MOSI
DSR--SCK
RI--RESET
+5VとGNDはUSB経由でPCから供給されることが前提。
参考にしたサイトです。
http://engawa.kakaku.com/userbbs/1681/Page=2/SortType=ThreadID/#1681-6
タグ:avrdude
ATmega328P ヒューズビットに設定する値
日本語データシートからヒューズビットの項目P182を抜き出しました。ATmega328Pとしてのヒューズビットの設定値を決定します。
前提条件:USB電源、16MHz水晶発振器、3.3V動作にも対応しておく。水晶発振器の出力は外部に供給しない(全振幅発振器にはしない)。
P182は下記。
拡張ヒューズバイト:
BODLEVEL0~2の設定 電源電圧低下検出レベルの設定。 BODLEVELの値の説明についてはP197参照。
P197は下記。電源が+5V固定なら100とすべきだが、+3.3Vで駆動させることは十分想定されるので、101の設定にしておくのが無難と思われる。よって拡張ヒューズバイトは、FDhとする。しかしながら実際にこの値を書いても拡張ヒューズバイトは下3ビットしか自由に書き込めない。上位5ビットは何を書いても0になるので、拡張ヒューズバイトは、05hとする。
ヒューズ上位バイト:
RSTDISBLは、PC6はRESETピンとするので1を指定。
DWENは、デバッグのやり方の知識がないのでとりあえず無効として1を指定。
SPIENは、直列プログラミングを許可するので、0を指定。
WDTONは、ウォッチドッグ タイマは常時有効にしないので1を指定。
EESAVEは、チップ消去からEEPROM内容を保護しないので1を指定。
BOOTSZ1,0ブートローダのサイズ指定。ブートローダのファイルサイズで決めるべきものだが、自分ではブートローダを作成しないので、出来合いのもののサイズから、2048ワードとなる01を指定する。
BOOTRSTリセットベクタをブートローダ領域にするかどうかの指定。ブートローダ領域にするので0を指定する。
表27-7は下記。
ヒューズ上位バイトは、DAhとする。
ヒューズ下位バイト:
システムクロックは、16MHz水晶発振器としますのでこれを前提とする。パワーダウンパワーセーブ機能は使用しないことにする。
CKDIV8 システムクロックを8分周するかどうか。分周しないので、1を指定。
CKOUT システムクロックは出力しないので、1を指定。
水晶発振器だが、出力を外部に供給しないので全振幅発振器にはしない。よって、表9-3から、CKSEL3〜1 111を指定。
USB電源(電池駆動しない)なので、パワーダウン、パワーセーブ機能は使用しない。表9-4から、CKSEL0は1、SUT1,0は01とする。
ヒューズ下位バイトは、DFhとする。
前提条件:USB電源、16MHz水晶発振器、3.3V動作にも対応しておく。水晶発振器の出力は外部に供給しない(全振幅発振器にはしない)。
P182は下記。
拡張ヒューズバイト:
BODLEVEL0~2の設定 電源電圧低下検出レベルの設定。 BODLEVELの値の説明についてはP197参照。
P197は下記。電源が+5V固定なら100とすべきだが、+3.3Vで駆動させることは十分想定されるので、101の設定にしておくのが無難と思われる。よって拡張ヒューズバイトは、FDhとする。しかしながら実際にこの値を書いても拡張ヒューズバイトは下3ビットしか自由に書き込めない。上位5ビットは何を書いても0になるので、拡張ヒューズバイトは、05hとする。
ヒューズ上位バイト:
RSTDISBLは、PC6はRESETピンとするので1を指定。
DWENは、デバッグのやり方の知識がないのでとりあえず無効として1を指定。
SPIENは、直列プログラミングを許可するので、0を指定。
WDTONは、ウォッチドッグ タイマは常時有効にしないので1を指定。
EESAVEは、チップ消去からEEPROM内容を保護しないので1を指定。
BOOTSZ1,0ブートローダのサイズ指定。ブートローダのファイルサイズで決めるべきものだが、自分ではブートローダを作成しないので、出来合いのもののサイズから、2048ワードとなる01を指定する。
BOOTRSTリセットベクタをブートローダ領域にするかどうかの指定。ブートローダ領域にするので0を指定する。
表27-7は下記。
ヒューズ上位バイトは、DAhとする。
ヒューズ下位バイト:
システムクロックは、16MHz水晶発振器としますのでこれを前提とする。パワーダウンパワーセーブ機能は使用しないことにする。
CKDIV8 システムクロックを8分周するかどうか。分周しないので、1を指定。
CKOUT システムクロックは出力しないので、1を指定。
水晶発振器だが、出力を外部に供給しないので全振幅発振器にはしない。よって、表9-3から、CKSEL3〜1 111を指定。
USB電源(電池駆動しない)なので、パワーダウン、パワーセーブ機能は使用しない。表9-4から、CKSEL0は1、SUT1,0は01とする。
ヒューズ下位バイトは、DFhとする。
タグ:USB電源 ATmega328P