|
(注)dude-wrapngは素晴らしいソフトですが、Arduino-0018専用です。Arduino-0019が公開されるにあたり、dude-wrapngより汎用性の高い avrdude-GUI(含avrdude改)が開発されました。今後は「アルディ」ノススメで紹介している Arduino-IDEオリジナル+avrdude-GUI の使用が適当です。 dude-wrapng 2010-0528版よりこの名になりました(Next Generation) メモ IDE窓のサイズ IDEエディタ文字サイズ コンソールの文字 水晶発振 日本語リファレンス UARTの抵抗 dude-wrap mega88を使ってみる dude-wrap mega328を使う dude-wrap pic18spxライタの実験 adpy プログラミング(?) RTCを読み出す I2Cを使う 7セグメントLED 2桁表示 I2C受信 7セグメントLED 2桁表示 wsNak中尾氏の1バイト送信データ I2C受信 7セグメントLED 4桁表示 5バイトデータを受け取って4桁の数値を表示する |


手動書き込み(リセットボタンを手で押して書き込む) 2010.04.29
上に書いたようにarduinoはDTR信号でavrをリセットしています。このリセットのタイミングが合わなければ書き込めないのですが、実験をしてみると以外に簡単なようです。 リセットスイッチを左手でちょこっと押して、すぐに右手でクリックする、という感じで確実に書き込めました。
手元にあるUSB-シリアルコンバータは、
@FT232RL自作
Acp2102自作
Bpic18spx(PIC18F14K50使用)
Cusbrs232(tiny2313使用)
の4種ですがいずれもDTRを使わない(使えない)状態でうまく書き込むことができました。
初期の頃avrライタで書き込み時はスイッチをONにするものがありましたが、書き込む前にONにして書き込み後にOFFにするという2段の操作が必要でしたが、今回は1段で済みますから負担は少ないようです。
何度か書いてみましたがスイッチの手動操作は気にしなくても良いのではないかと思えてきました。
素人考えでは手動リセットが無難なようです。これで困る場面に出会うまでは手動で行きましょう。アマチュアの実験レベルではCの充放電によってコンバータが壊れてもAVRが壊れても大事には至りません。0.1uFで続行するのも一つの方法でしょう。
DTR信号雑考 2010.04.29
arduino書き込み起動に関係するエラーを体験する中で、DTR信号について少し学びました。
DTR信号(Data Terminal Ready)は RS-232C の中にある信号線の1つで、通常は、シリアルポートが使用可能な状態になっている間ONになります。
RS232C信号線はデータ信号は負論理でその他の制御信号は正論理になっています。また、RS232Cのインターフェイスで論理が逆になりますから、TTLレベル(機器の中)では データ信号は正論理(ON=1=H)、制御信号は負論理(ON=0=L)になります。
自作の機器間ではTTLレベルで通信しますから、この太字の論理になります。
すなわち、PCからarduinoに書き込み信号を送るときは DTRをL にして使用可能状態をarduinoに知らせ(aruduinoは本来のDTRは受け付けないが)、通信終了後に DTRをH に戻します。
AVRデバイスはリセットされるとブートローダモードになって(そう思います)、プログラム(スケッチ)(が入ってくればそれ)を受け取ります。
通信を受け取る時にリセットが必要ですから、DTRのLを利用します。通信中にずっとLでは困りますから、立ち下がりのエッジだけを利用するために0.1μFのコンデンサでDTR信号を受けてリセット端子に取り込んでいます。
これらは確かな情報と言えませんが、このように解釈するとDTRの働きが矛盾無く理解できました。
このあたりが確定している素子として FT232RL と cp2102 の動きを調べました。 PCに通信準備OKの信号を出させるためにターミナルソフトの teraterm と ハイパーターム を使ってこれらのターミナルソフトの開始と終了時のDTR信号をアナログテスタで調べました。
結果はともに同じで、ターミナルソフト立ち上げ前は H で、立ちあがると L になり、ターミナルソフトを終了すると H に戻りました。 もちろんHはVcc電圧で、Lは0Vです。
DTR信号は本来別の働きがあるはずです。これをリセットに使うのは単なる思いつきによるものとも聞きます。確かに書き込みでなくAVRとUART通信を行うときもリセットされることになるようです。
dude-wrapng 2010.05.01 → 2010.05.30
dude-wrapngはsenshuさんの考案で、Arduino-IDEを使ってhidspx制御のHIDaspxで書き込むことができるソフトウエアです。これを使うと単独のAVRmcuにHIDaspxライタを繋ぐだけでArduinoの多くのライブラリを利用してArduinoと同じプログラムを実行することができます。もちろんUSB-シリアル変換モジュールは必要ありません。
HIDaspxがあればAVRmcuだけ(わずかの部品が必要ですが)で、Arduinoと同じ実験ができます。
当初はIDEが使用しているavr-dudeを指定時にはhidspxを使うようにラッピングしたものでdude-wrapの名でしたが、2010-0528版よりラッピングではなく指定時にはIDEが直接hidspxを使用するように変更されました。そのため名が変わっています。
ここに導入の経過を報告しますが、「最良の方法」であるとは限りません。
Arduino-IDEはWinAVR(gcc)を含みますが、WinAVRをインストールすることなく使えるそうです。したがってこのシステムではすべてについてインストールの必要はないようです。
|
原作者のsenshuさんからいただいたメッセージを再掲します。 私は、Arduino IDEが持つ不具合を解決するために改良作業を行っています。dude-wrapngではArduino IDE自体を修正して不具合を改善しています。 dude-wrapngとdude-wrapは結果として機能が似ているだけで、仕組みは全く異なります。後継という意味でこの名称にしただけなのです。 こうしたことから、dude-wrapngの特徴という表現は適当ではなく、「dude-wrapngを導入したArduino IDEの特徴」と紹介していただければ幸です。 |

// LED (PB1)の点滅
int led0Pin = 10; // LED ATtiny2313 PB1
void setup() // run once, when the sketch starts
{
pinMode(led0Pin, OUTPUT); // sets the digital pin as output
}
void loop() // run over and over again
{
digitalWrite(led0Pin, HIGH); // sets the LED on
delay(500); // waits for a second
digitalWrite(led0Pin, LOW); // sets the LED off
delay(500); // waits for a second
}
を貼り付けて、ビルドします。○の中に横向き△のアイコンのクリックです。コンパイル後のスケッチのサイズ:756バイト(最大容量2,048バイト) #=> hidspx -d4 -ph --new-mode -d1 C:\DOCUME~1\y\LOCALS~1\Temp\build548829602125802808.tmp\sketch_may02a.cpp.hex Detected device is ATtiny2313. Erase Flash memory. Flash memory... Writing [##################################################] 756, 0.20s Verifying [##################################################] 756, 0.11s Passed. Total read/write size = 1512 B / 0.58 s (2.55 kB/s)と表示されて、すぐにLEDが点滅をはじめました。arduinoの待ち時間がここにはありません。
|
IDE窓のサイズ: 「ファイル」→「環境設定」の下部に表示される preferences.txt を変更します。 IDEエディタ文字サイズ: 「ファイル」→「環境設定」の「文字サイズ」を変更します。 コンソールの文字サイズと色: 2010.05.08 黒字に赤文字でかつ小さいために見にくく感じていました。 senshuさんが文字の大きさと文字色を変更する方法を見つけてくれました。 C:\_ard\arduino-0018\lib\theme\theme.txt を変更します。 # GUI - CONSOLE #console.font = Monospaced,plain,11 console.font = Monospaced,plain,14 ←14ポイントに変更している console.font.macosx = Monaco,plain,10 console.color = #000000 console.output.color = #cccccc #console.error.color = #ff3000 console.error.color = #cc9900 ←私はffff00の方が見やすいと思う 水晶発振: 2010.05.08 あるチップで内臓RC発振のままUART通信をPCと行っていました。RC発振でも以外とできるものだな、と思っていたのですがチップが変わると誤動作でどうにもならない状態になりました。通信速度を落としてもダメで、一部分が送られるだけです。 通常の使用であれば水晶を付加して、fuse設定とボーレートの設定値を変えれば済むのですが、Arduino-IDEでは クロック別の boards.txt を作る必要があります。 次のものは mega88 12MHz 水晶発振 のボードのために自作した(修正しただけの)ものです ############################################################## 2010.05.30一部変更 mym88.name=My Arduino(hidspx) 12MHz / ATmega88 mym88.upload.protocol=hidspx mym88.upload.delay=-d1 mym88.upload.maximum_size=8192 mym88.upload.speed=19200 mym88.upload.disable_flushing=true mym88.upload.using=hidspx mym88.bootloader.low_fuses=0xff mym88.bootloader.high_fuses=0xdd mym88.bootloader.extended_fuses=0xFF mym88.bootloader.path=atmega mym88.bootloader.file=BOOT_void.hex mym88.bootloader.unlock_bits=0x3F mym88.bootloader.lock_bits=0x0F mym88.build.mcu=atmega88 mym88.build.f_cpu=12000000L mym88.build.core=arduino ##############################################################この変更を追加すると新しいボード項目ができて使えました。ブートローダ書き込みは正常に終了します。 結果はもちろん正常に通信できました。UART通信を考えるなら水晶発振にしておくのが結局近道のようです。 Arduinoは製品の関係で 発振形式 と クロック は決め打ちになります。 AVRデバイス と 発振形式 と クロック をセットにしていくつかのモデルを決めておくのが良いのでしょう。 日本語リファレンス: 2010.05.08 これは便利です。→IDEのメニューからたどれます。 UART接続の抵抗: 2010.05.09 pic18spxシリアルコンバータの入出力端子を直接AVRのRD,TDに接続して実験してきました。USBハブを使うようになってPCの電源を切るとUSBの電源も切れます(直接のUSBは切れません)。 AVRは外部5V電源で駆動しています。AVRは起動したままでPCの電源を切ることがあるのですが、ふと気付くと電源の電流が異常に多くなっていました。 UARTの信号線を通じてAVR側からPIC18F14K50へ60〜70mAほど流れているようです。 早速、TDとRDにそれぞれ1kΩの制限抵抗を付けました。異常電流は解消しました。通常の使用時には起こらない不都合にも対応が必要でした。PIC18F14K50は死んでいなかったようです。 AVRのUARTを他のものとも接続するときはそのチップの出力とコンバータ出力の衝突(ショート)を防ぐために必要とは知っていたのですが、思わぬ伏兵であったようです。 |

コンパイル後のスケッチのサイズ:1,048バイト(最大容量8,192バイト) #=> hidspx -d4 -ph --new-mode -d3 C:\DOCUME~1\y\LOCALS~1\Temp\build401071476509345139.tmp\Fading.cpp.hex Detected device is ATmega88P. Erase Flash memory. Flash memory... Writing [##################################################] 1048, 0.42s Verifying [##################################################] 1048, 0.44s Passed. Total read/write size = 2096 B / 1.12 s (1.82 kB/s)と表示があってLEDが蛍火のように明滅します。C言語でPWMを書くとかなり手間ですがここでは簡単に書くことができるようです。
############################################################## Mymega328.name=My Arduino w/ ATmega328 Mymega328.upload.protocol=hidspx,-d3 Mymega328.upload.maximum_size=32768 Mymega328.upload.speed=19200 Mymega328.bootloader.low_fuses=0xe2 Mymega328.bootloader.high_fuses=0xdd Mymega328.bootloader.extended_fuses=0x00 Mymega328.bootloader.unlock_bits=0x3F Mymega328.bootloader.lock_bits=0x0F Mymega328.build.mcu=atmega328p Mymega328.build.f_cpu=8000000L Mymega328.build.core=arduino ##############################################################ブートローダ書き込みは例によってエラーが出ますが、fuseは書き込まれていますので続行します。
|
RTCの接続 1:CLKOE 2:CLKOUT→LED 3:INT 4:Vss→GND 5:SDA→27番 6:SCK→28番 7:NC 8:Vcc |
#include <Wire.h>
int RTCDATA[16]; //read buf. from RTC unit
#define RTCaddress 0xa2 >> 1
//TWI address of RTC-unit
#define inPin 8
//set digital8 as input
void setup() {
pinMode(inPin, INPUT);
digitalWrite(inPin, HIGH); //pull up
Serial.begin(9600);
Serial.println("initializing RTC unit");
//init message
delay(1000);
Wire.begin(); // join the TWI as bus-master
Wire.beginTransmission(RTCaddress);
//send to RTC address (write mode)
Wire.send(0x00);
//set internal register address
// of RTC as 0 (auto increment)
//set initial time & date & year
// as 2010.05.05 08:00:00
Wire.send(0x00);
//control1 = 0x00
Wire.send(0x03);
//control2 = 0x03
Wire.send(0x00);
//seconds = 0x00
Wire.send(0x00);
//minutes = 0x00
Wire.send(0x08);
//hours = 0x08
Wire.send(0x05);
//days = 0x05
Wire.send(0x03);
//weekdays = 0x03 (Wednesday)
Wire.send(0x85);
//month/century = 0x85 (0x80 | 0x05)
Wire.send(0x10);
//years = 0x10
Wire.send(0x00);
//minutes alarm = 0x00
Wire.send(0x12);
//hours alarm = 0x12
Wire.send(0x25 | 0x80);
//days alarm = 0x25
Wire.send(0x04 | 0x80);
//weekdays alarm = 0x04 (Thursday)
Wire.send(0b10000011);
//clk out = 0x10000011 (1hz)
Wire.endTransmission();
delay(10);
Serial.println("finished initializing RTC unit");
//init message
}
void loop(void){
int i;
Wire.beginTransmission(RTCaddress);
//send to RTC address with write mode
Wire.send(0x00);
//set internal register address of RTC as 0
Wire.endTransmission();
//
Wire.requestFrom(RTCaddress,16);
//request 16byte data from RTC
//reading loop
for (i=0; i<16; i++)
{
while (Wire.available() == 0 ){
}
RTCDATA[i] = Wire.receive();
}
//read data from RTC unit
Serial.print(RTCDATA[8],HEX);
Serial.print(" ");
Serial.print(RTCDATA[7]& 0x1f,HEX);
Serial.print(" ");
Serial.print(RTCDATA[5] & 0x3f,HEX);
Serial.print(" ");
Serial.print(RTCDATA[6] & 0x07,HEX);
Serial.print(" ");
Serial.print(RTCDATA[4] & 0x3f,HEX);
Serial.print(" ");
Serial.print(RTCDATA[3] & 0x7f,HEX);
Serial.print(" ");
Serial.print(RTCDATA[2] & 0x7f,HEX);
Serial.print(" ");
Serial.print(RTCDATA[11] & 0x3f,HEX);
Serial.print(" ");
Serial.print(RTCDATA[12] & 0x07,HEX);
Serial.print(" ");
Serial.print(RTCDATA[10] & 0x3f,HEX);
Serial.print(" ");
Serial.println(RTCDATA[9] & 0x7f,HEX);
if (digitalRead(inPin) == LOW){
Wire.beginTransmission(RTCaddress);
//send to RTC address (write mode)
Wire.send(0x01);
//set internal register address of RTC as 1
Wire.send(0x03);
//clear control2 as 0x03
Wire.endTransmission();
}
delay(100);
}
コピーして、コンパイルに入るとwebページのための全角<>を半角に戻すだけでエラー無くコンパイルできました。
#define SEG_A 0 // PD0
#define SEG_B 1 // PD1
#define SEG_C 2 // PD2
#define SEG_D 3 // PD3
#define SEG_E 4 // PD4
#define SEG_F 5 // PD5
#define SEG_G 6 // PD6
#define SEG_DP 7 // PD7
#define DISP_1 8 // PB1
#define DISP_2 9 // PB0
uint8_t cnt = 0;
uint8_t target = 0;
uint8_t data;
uint8_t dig10;
uint8_t dig1;
uint16_t i;
void setup()
{
pinMode(SEG_A, OUTPUT);
pinMode(SEG_B, OUTPUT);
pinMode(SEG_C, OUTPUT);
pinMode(SEG_D, OUTPUT);
pinMode(SEG_E, OUTPUT);
pinMode(SEG_F, OUTPUT);
pinMode(SEG_G, OUTPUT);
pinMode(SEG_DP, OUTPUT);
pinMode(DISP_1, OUTPUT);
pinMode(DISP_2, OUTPUT);
data=0;
}
void loop()
{
dig10 = data / 16;
dig1 = data - (dig10 * 16);
digitalWrite(DISP_1, HIGH);
digitalWrite(DISP_2, HIGH);
digitalWrite(SEG_DP,HIGH);
if(target == 0 ){
seven_seg_out( dig1 );
digitalWrite(DISP_1, LOW);
digitalWrite(DISP_2, HIGH);
target = 1;
}
else {
seven_seg_out( dig10 );
digitalWrite(DISP_1, HIGH);
digitalWrite(DISP_2, LOW);
target = 0;
}
i++;
if(i==10000){
data++;
i=0;
}
}
void seven_seg_out(uint8_t input)
{
input = input & 0xf;
switch(input){
case 0:
digitalWrite(SEG_A,LOW);
digitalWrite(SEG_B,LOW);
digitalWrite(SEG_C,LOW);
digitalWrite(SEG_D,LOW);
digitalWrite(SEG_E,LOW);
digitalWrite(SEG_F,LOW);
digitalWrite(SEG_G,HIGH);
break;
case 1:
digitalWrite(SEG_A,HIGH);
digitalWrite(SEG_B,LOW);
digitalWrite(SEG_C,LOW);
digitalWrite(SEG_D,HIGH);
digitalWrite(SEG_E,HIGH);
digitalWrite(SEG_F,HIGH);
digitalWrite(SEG_G,HIGH);
break;
case 2:
digitalWrite(SEG_A,LOW);
digitalWrite(SEG_B,LOW);
digitalWrite(SEG_C,HIGH);
digitalWrite(SEG_D,LOW);
digitalWrite(SEG_E,LOW);
digitalWrite(SEG_F,HIGH);
digitalWrite(SEG_G,LOW);
break;
case 3:
digitalWrite(SEG_A,LOW);
digitalWrite(SEG_B,LOW);
digitalWrite(SEG_C,LOW);
digitalWrite(SEG_D,LOW);
digitalWrite(SEG_E,HIGH);
digitalWrite(SEG_F,HIGH);
digitalWrite(SEG_G,LOW);
break;
case 4:
digitalWrite(SEG_A,HIGH);
digitalWrite(SEG_B,LOW);
digitalWrite(SEG_C,LOW);
digitalWrite(SEG_D,HIGH);
digitalWrite(SEG_E,HIGH);
digitalWrite(SEG_F,LOW);
digitalWrite(SEG_G,LOW);
break;
case 5:
digitalWrite(SEG_A,LOW);
digitalWrite(SEG_B,HIGH);
digitalWrite(SEG_C,LOW);
digitalWrite(SEG_D,LOW);
digitalWrite(SEG_E,HIGH);
digitalWrite(SEG_F,LOW);
digitalWrite(SEG_G,LOW);
break;
case 6:
digitalWrite(SEG_A,LOW);
digitalWrite(SEG_B,HIGH);
digitalWrite(SEG_C,LOW);
digitalWrite(SEG_D,LOW);
digitalWrite(SEG_E,LOW);
digitalWrite(SEG_F,LOW);
digitalWrite(SEG_G,LOW);
break;
case 7:
digitalWrite(SEG_A,LOW);
digitalWrite(SEG_B,LOW);
digitalWrite(SEG_C,LOW);
digitalWrite(SEG_D,HIGH);
digitalWrite(SEG_E,HIGH);
digitalWrite(SEG_F,HIGH);
digitalWrite(SEG_G,HIGH);
break;
case 8:
digitalWrite(SEG_A,LOW);
digitalWrite(SEG_B,LOW);
digitalWrite(SEG_C,LOW);
digitalWrite(SEG_D,LOW);
digitalWrite(SEG_E,LOW);
digitalWrite(SEG_F,LOW);
digitalWrite(SEG_G,LOW);
break;
case 9:
digitalWrite(SEG_A,LOW);
digitalWrite(SEG_B,LOW);
digitalWrite(SEG_C,LOW);
digitalWrite(SEG_D,LOW);
digitalWrite(SEG_E,HIGH);
digitalWrite(SEG_F,LOW);
digitalWrite(SEG_G,LOW);
break;
case 10:
digitalWrite(SEG_A,LOW);
digitalWrite(SEG_B,LOW);
digitalWrite(SEG_C,LOW);
digitalWrite(SEG_D,HIGH);
digitalWrite(SEG_E,LOW);
digitalWrite(SEG_F,LOW);
digitalWrite(SEG_G,LOW);
break;
case 11:
digitalWrite(SEG_A,HIGH);
digitalWrite(SEG_B,HIGH);
digitalWrite(SEG_C,LOW);
digitalWrite(SEG_D,LOW);
digitalWrite(SEG_E,LOW);
digitalWrite(SEG_F,LOW);
digitalWrite(SEG_G,LOW);
break;
case 12:
digitalWrite(SEG_A,LOW);
digitalWrite(SEG_B,HIGH);
digitalWrite(SEG_C,HIGH);
digitalWrite(SEG_D,LOW);
digitalWrite(SEG_E,LOW);
digitalWrite(SEG_F,LOW);
digitalWrite(SEG_G,HIGH);
break;
case 13:
digitalWrite(SEG_A,HIGH);
digitalWrite(SEG_B,LOW);
digitalWrite(SEG_C,LOW);
digitalWrite(SEG_D,LOW);
digitalWrite(SEG_E,LOW);
digitalWrite(SEG_F,HIGH);
digitalWrite(SEG_G,LOW);
break;
case 14:
digitalWrite(SEG_A,LOW);
digitalWrite(SEG_B,HIGH);
digitalWrite(SEG_C,HIGH);
digitalWrite(SEG_D,LOW);
digitalWrite(SEG_E,LOW);
digitalWrite(SEG_F,LOW);
digitalWrite(SEG_G,LOW);
break;
case 15:
digitalWrite(SEG_A,LOW);
digitalWrite(SEG_B,HIGH);
digitalWrite(SEG_C,HIGH);
digitalWrite(SEG_D,HIGH);
digitalWrite(SEG_E,LOW);
digitalWrite(SEG_F,LOW);
digitalWrite(SEG_G,LOW);
break;
default:
break;
}
}
出力ピンを自由に使えるのですが、その分プログラムが大きくなります。一長一短です。Wire.begin(0x20); // join i2c bus with address #0x20 7ビット Wire.onReceive(receiveEvent); // receive event Wire.onRequest(requestEvent); // request eventを書くだけで受信できるようです。割り込みの指定はありませんがデフォルトで割り込み動作になっています。
/* **********************************************************
wsNak氏の1バイトデータ通信スレーブ 2010.05.26
インクリメントするデータを受信して2桁の7セグメントLEDに
表示する
*********************************************************** */
#include <Wire.h>
#define SEG_A 0
#define SEG_B 1
#define SEG_C 2
#define SEG_D 3
#define SEG_E 4
#define SEG_F 5
#define SEG_G 6
#define SEG_DP 7
#define DISP_1 8
#define DISP_2 9
byte target = 0;
byte data;
byte dig10;
byte dig1;
volatile byte dat = 0;
void setup(){
pinMode(SEG_A, OUTPUT);
pinMode(SEG_B, OUTPUT);
pinMode(SEG_C, OUTPUT);
pinMode(SEG_D, OUTPUT);
pinMode(SEG_E, OUTPUT);
pinMode(SEG_F, OUTPUT);
pinMode(SEG_G, OUTPUT);
pinMode(SEG_DP, OUTPUT);
pinMode(DISP_1, OUTPUT);
pinMode(DISP_2, OUTPUT);
data=0;
Wire.begin(0x20); // join i2c bus with address #0x20
Wire.onReceive(receiveEvent); // receive event
Wire.onRequest(requestEvent); // request event
}
void loop(){
data=dat;
dig10 = data / 16;
dig1 = data % 16;
digitalWrite(DISP_1, HIGH);
digitalWrite(DISP_2, HIGH);
digitalWrite(SEG_DP,HIGH);
if(target == 0 ){
seven_seg_out( dig1 );
digitalWrite(DISP_1, LOW);
digitalWrite(DISP_2, HIGH);
target = 1;
}
else {
seven_seg_out( dig10 );
digitalWrite(DISP_1, HIGH);
digitalWrite(DISP_2, LOW);
target = 0;
}
}
void seven_seg_out(byte input)
{ //内容は上記と同じのため省略
}
void receiveEvent(int howMany){
while (1 < Wire.available()){
;
} // loop through all but the last
dat = Wire.receive(); // receive byte as a character
}
void requestEvent(){
Wire.send(dat);
}
webで頂戴したサンプルを変形して使っていますのでゴミとなったものが残っています(謝)。

void receiveEvent(int howMany){
while (1 < Wire.available()){
;
} // loop through all but the last
dat = Wire.receive(); // receive byte as a character
}
となっていますが、whileループの空文の理解を間違えていてずいぶん苦労をした上でアドバイスとしていただいたサンプルからヒントを得て成功しました。
void receiveEvent(int howMany){
i=1;
while (1 < Wire.available()){ // 最後のデータを残してそれまではwhileループで取り込みます。
d[i] = Wire.receive();
i++;
}
d[i] = Wire.receive(); // 最後のデータはここで取り込みます、
}
割り込みも自動で設定されますから考えることはほとんどありません。メモリを多く必要としますがそのメリットは感じられました。Wire.beginTransmission(Slaveaddress); Wire.send(data*,バイト数); //(配列,バイト数)型送信 Wire.endTransmission();を書けば良いだけですから、表示をスレーブに任せることでマスタの負担は大きく軽減されます。


L H Ex
----------------------------------------------------------------------
mega328P 16MHz f7 d9 fc -fL11110111 -fH11011001 -fx11111011 4.3V
f7 d9 fd -fL11110111 -fH11011001 -fx11111101 2.7V
----------------------------------------------------------------------
mega168 16MHz f7 dc f9 -fL11110111 -fH11011100 -fx11111001 4.3V
f7 dd f9 -fL11110111 -fH11011101 -fx11111001 2.7V
----------------------------------------------------------------------
mega88 16MHz ↑(mega168に同じ)
----------------------------------------------------------------------
mrga48 16MHz f7 dc ff -fL11110111 -fH11011100 -fx11111111 4.3V
f7 dd ff -fL11110111 -fH11011101 -fx11111111 2.7V
----------------------------------------------------------------------
mega8 16MHz 3f d9 ff -fL00111111 -fH11011001 -fx11111111 4.0V (fxは無い)
bf d9 ff -fL10111111 -fH11011001 -fx11111111 2.7V
----------------------------------------------------------------------
|
IDE窓のサイズ: 「ファイル」→「環境設定」の下部に表示される preferences.txt を変更します。 IDEエディタ文字サイズ: 「ファイル」→「環境設定」の「文字サイズ」を変更します。 コンソールの文字サイズと色: 2010.05.08 黒字に赤文字でかつ小さいために見にくく感じていました。 senshuさんが文字の大きさと文字色を変更する方法を見つけてくれました。 C:\_ard\arduino-0018\lib\theme\theme.txt を変更します。 # GUI - CONSOLE #console.font = Monospaced,plain,11 console.font = Monospaced,plain,14 ←14ポイントに変更している console.font.macosx = Monaco,plain,10 console.color = #000000 console.output.color = #cccccc #console.error.color = #ff3000 console.error.color = #cc9900 ←私はffff00の方が見やすいと思う 水晶発振: 2010.05.08 あるチップで内臓RC発振のままUART通信をPCと行っていました。RC発振でも以外とできるものだな、と思っていたのですがチップが変わると誤動作でどうにもならない状態になりました。通信速度を落としてもダメで、一部分が送られるだけです。 通常の使用であれば水晶を付加して、fuse設定とボーレートの設定値を変えれば済むのですが、Arduino-IDEでは クロック別の boards.txt を作る必要があります。 次のものは mega88 12MHz 水晶発振 のボードのために自作した(修正しただけの)ものです ############################################################## 2010.05.30一部変更 mym88.name=My Arduino(hidspx) 12MHz / ATmega88 mym88.upload.protocol=hidspx mym88.upload.delay=-d1 mym88.upload.maximum_size=8192 mym88.upload.speed=19200 mym88.upload.disable_flushing=true mym88.upload.using=hidspx mym88.bootloader.low_fuses=0xff mym88.bootloader.high_fuses=0xdd mym88.bootloader.extended_fuses=0xFF mym88.bootloader.path=atmega mym88.bootloader.file=BOOT_void.hex mym88.bootloader.unlock_bits=0x3F mym88.bootloader.lock_bits=0x0F mym88.build.mcu=atmega88 mym88.build.f_cpu=12000000L mym88.build.core=arduino ##############################################################この変更を追加すると新しいボード項目ができて使えました。ブートローダ書き込みは正常に終了します。 結果はもちろん正常に通信できました。UART通信を考えるなら水晶発振にしておくのが結局近道のようです。 Arduinoは製品の関係で 発振形式 と クロック は決め打ちになります。 AVRデバイス と 発振形式 と クロック をセットにしていくつかのモデルを決めておくのが良いのでしょう。 日本語リファレンス: 2010.05.08 これは便利です。→avrdude-GUI右クリックメニューからたどれます。 UART接続の抵抗: 2010.05.09 pic18spxシリアルコンバータの入出力端子を直接AVRのRD,TDに接続して実験してきました。USBハブを使うようになってPCの電源を切るとUSBの電源も切れます(直接のUSBは切れません)。 AVRは外部5V電源で駆動しています。AVRは起動したままでPCの電源を切ることがあるのですが、ふと気付くと電源の電流が異常に多くなっていました。 UARTの信号線を通じてAVR側からPIC18F14K50へ60〜70mAほど流れているようです。 早速、TDとRDにそれぞれ1kΩの制限抵抗を付けました。異常電流は解消しました。通常の使用時には起こらない不都合にも対応が必要でした。PIC18F14K50は死んでいなかったようです。 AVRのUARTを他のものとも接続するときはそのチップの出力とコンバータ出力の衝突(ショート)を防ぐために必要とは知っていたのですが、思わぬ伏兵であったようです。 |