marua が 2022年09月19日14時22分48秒 に編集
初版
タイトルの変更
I2C デバイス・スキャン
タグの変更
Arduino
I2C
メイン画像の変更
記事種類の変更
製作品
ライセンスの変更
(CC BY-SA 4+) Creative Commons Attribution-ShareAlike CC BY-SA version 4.0 or later
本文の変更
I2Cバス上で認識できるデバイスを調べるツールです。 電源を入れると、ArduinoのI2Cバスにアドレス(0x08 ~ 0X77)を出力して、ACKを返したデバイスが有ると、そのアドレスをシリアルで出力します。 (7bitアドレスのフォーマットでのみ確認) 配線ミスや断線の確認用に 活用してください。 I2Cデバイスを2個搭載した [「土壌の水分/温度センサ」](https://elchika.com/article/7f185f8e-82e2-403f-a44c-7cb504951244/)基板で実行すると、 0x32: RTC 0x3E: LCD のアドレスが、シリアルポートに出力されます。 ![シリアル出力結果](https://camo.elchika.com/f95ca8c4c23728efaba8344aba942360de792fb6/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f33633934613036612d653465342d343838392d383133342d3434636466393330333066352f64316632326562372d636639392d343037662d396139382d323632663639383465313539/) ![ACK応答を返さないケース](https://camo.elchika.com/b3eb60899eb6c8327df33a44c7ffd0dc9b6d605a/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f33633934613036612d653465342d343838392d383133342d3434636466393330333066352f31323737373762622d643066382d343231652d383935372d633166383364333765343461/) ![ACkを返すケース](https://camo.elchika.com/3e4b1c494084ec8e3e3c7fca240a39802ce8404a/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f33633934613036612d653465342d343838392d383133342d3434636466393330333066352f36643430373063622d306365322d346662382d393766332d316139373737376630646430/) ```arduino:ソースコード #include <Wire.h> #define dLED 0x04 // ■ cmd1() char cmd1_task = 0; // cmd1 タスクNo. unsigned long cmd1_tim0 = 0; // コマンド1 基準時間 unsigned char i2c_adr; // I2C スキャンアドレス // ■ LED_ctrl() char LED_task = 0; // LED制御 タスクNo. unsigned long LED_tim0 = 0; // LED制御 基準時間 // ■■ void setup() { Serial.begin(9600); Wire.begin(); DDRC |= dLED; // PC2 = 出力 Serial.println("I2C Scan v0.01"); LED_task = 20; // LED 点滅(50ms ON) } // ■ void loop() { LED_ctrl(); // LED 点滅制御 cmd1(); // コマンド1処理 } // ■■ void cmd1() { int val; unsigned long tim; switch (cmd1_task) { case 0: cmd1_tim0 = millis(); // 基準時間セット i2c_adr = 0x08; // cmd1_task ++; break; case 1: case 8: cmd1_task ++; break; case 3: case 5: if (TWCR & (1<<TWINT)) { // cmd1_task ++; } break; case 2: TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // I2C Start cmd1_task ++; break; case 4: TWDR = i2c_adr<<1; // TWCR = (1<<TWINT)|(1<<TWEN); // cmd1_task ++; break; case 6: if ((TWSR & 0xf8) == 0x18) { Serial.print(' '); Serial.println(i2c_adr,HEX); } cmd1_task ++; break; case 7: TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); // I2C Stop cmd1_task ++; break; case 9: cmd1_tim0 = millis(); // 基準時間セット cmd1_task ++; break; case 10: tim = abs(millis() - cmd1_tim0); if ( tim > 10 ) { cmd1_task ++; } break; case 11: i2c_adr ++; if (i2c_adr > 0x77) { cmd1_task ++;} else { cmd1_task = 1; } break; case 12: break; default: cmd1_task = 0; break; } } // ■■ void LED_ctrl(void) { switch(LED_task) { case 0: break; // 1秒周期の点滅 (Duty=50%) case 10: LED_tim0 = millis(); LED_on(); LED_task ++; break; case 11: if ( (millis() - LED_tim0) > 500) { LED_task ++; } break; case 12: LED_tim0 = millis(); LED_off(); LED_task ++; break; case 13: if ( (millis() - LED_tim0) > 500) { LED_task = 10; } break; // 1秒周期の点滅 (ON 50ms) case 20: LED_tim0 = millis(); LED_on(); LED_task ++; break; case 21: if ( (millis() - LED_tim0) > 10) { LED_task ++; } break; case 22: LED_tim0 = millis(); LED_off(); LED_task ++; break; case 23: if ( (millis() - LED_tim0) > 950) { LED_task = 20; } break; case 99: default: LED_off(); LED_task = 0; break; } } void LED_on(void) { PORTC |= dLED; } void LED_off(void) { PORTC &= ~dLED; } ```