I2C-Scanner
Nachfolgende eine Liste mit den I2C-Bauteilen, die ich bisher in Verwendung gehabt habe, sowie ein kleines Programm, welches die I2C-Adresse eines Bauteiles ermittelt oder prüft, welche Bauteile auf einem I2C-Bus ansprechbar sind.
Ja, ich weiß, im Internet kann gibt es genügend I2C-Scanner zum Herunterladen. Warum ich dann selber einen geschrieben habe? Ich hatte einfach Lust dazu und was man selber geschrieben hat, kann man auch leichter verändern, erweitern, anpassen, etc.
Meine I2C-Bauteile, geordnet nach der Adresse (HEX-Format):
Arduino Uno, Mega 0x01 - 0x05 (eigene Festlegung)
Attiny45/85 0x06 - 0x09 (eigene Festlegung)
Temperatursensor MCP9808 0x18 - 0x1F
Beschleunigungssensor MMA8451 0x1D, 0x1C
Beschleunigungssensor ADXL345 0x1D, 0x53
Portexpander MCP23017 / MCP23S17 0x20 - 0x27
Portexpander PCF8574N / PCF8574P 0x20 - 0x27
Lichtsensor GY-30 (Chip BH1750FVI) 0x23, 0x5C
LCD 20x4 mit PCF8574T 0x27 (fest eingestellt?)
OLED-Display 128x64 SSD1306 0x3C (eventuell auf 0x3D umlötbar) 1)
LCD 16x2 mit PCF8574AT 0x3F (über Lötbr. einstellbar 0x38 - 0x3F)
Portexpander PCF8574AN 0x38 - 0x3F
RGB- u. Gestik-Sensor APDS-9930 0x39
Stromsensor INA219 0x40 - 0x4F
Stromsensor INA219 0x40, 0x41, 0x44, 0x45 (auf Adafruit Breakout)
Luftfeuchtesensor SHT3x-D 0x44, 0x45
ADC ADS1015, ADS1115 0x48 - 0x4B
EEPROM AT24C32 0x50 (auf DS1307 Breakout)
EEPROM AT24C32 0x57 (auf DS3231 Breakout, einstellbar über Lötbr.)
EEPROM z.B. AT24C32/64 0x50 - 0x57
EEPROM z.B. 24LC024, 24LC256 0x50 - 0x57
FRAM z.B. MP85RC256V 0x50 - 0x57
DAC MCP4725 0x62, 0x63
RTC DS1307 0x68
RTC DS3231 0x68
ADC MCP3421 0x68 - 0x6F (je nach Fabrikseinstellung)
LED Controller Driver HT16K33 0x70 (20-Pin package)
LED Controller Driver HT16K33 0x70 - 0x73 (24-Pin package)
LED Controller Driver HT16K33 0x70 - 0x77 (28-Pin package)
I2C-Multiplexer TCA9548A 0x70 - 0x77
7-Segm.Anz. Sparkfun 0x71 (0x01 - 0x7E softwaremäßig einstellbar)
Luftdruck u. -feuchtesensor BME280 0x76, 0x77
Luftdrucksensor BMP280 0x76, 0x77
Luftdrucksensor BMP280 0x77, 0x76 (auf Breakout von Adafruit)
Luftdrucksensor BMP085 0x77
Luftdrucksensor BMP180 0x77
Luftfeuchtesensor AM2320 0xB8 2)
1) Es gibt 0,96 Zoll SSD1306-OLED-Module, mit 2 unterschiedlichen Farbbereichen, der obere Bereich des Displays (25%) mit gelber Schrift und der untere Bereich (75%) mit blauer Schrift. Die I2C-Adresse dieser Module sind, meines Wissens nicht veränderbar, sondern haben fix die I2C-Adresse 0x3C. Andere Module, mit nur blauer oder weißer Schrift, können zwischen den 7-Bit-Adressen 0x3C und 0x3D umgelötet werden, dort sind aber irreführenderweise die 8-Bit-Adressen 0x78 und 0x7A aufgedruckt. Das jeweils niederwertigste Bit der 8-Bit-Adressen ist allerdings das Read/Write-Bit und wird normalerweise bei der Adressangabe nicht mit angegeben. Nimmt man also z.B. von der Adresse 0x78 nur die 7 höherwertigeren Bits, so ergibt das genau die Adresse 0x3C.
2) Keine I2C-Standard-Schnittstelle, wird vom Scanprogramm nicht erkannt (siehe Luftfeuchtesensor AM2320)
I2C-Scanprogramm
Das Programm überprüft im 10-Sekundentakt den Adressbereich von 0x01 bis 0x7F, ob Bauteile im Normalmodus (100 kHz) ansprechbar sind. Wird ein Bauteil gefunden, erfolgt eine weitere Prüfung im Schnellmodus (400 kHz). Am Seriellen Monitor (Einstellung 115200 Baud) werden die gefundenen I2C-Adressen und die Anzahl der ansprechbaren Bauteile je Modus ausgegeben (siehe Bild 1).
Bild 1: Ausgabebeispiel meines I2C-Scanprogramm
//I2C-Scanner
//My_I2C-Scanner.ino
//Code fuer Arduino
//Author Retian
//Version 1.0
//Der Sketch testet die Standard-7-Bit-Adressen von 1 bis 127
//mit den Frequenzen 100 kHz und 400 kHz
#include <Wire.h>
byte I2CAdd;
byte fehler;
byte anzahl100 = 0;
byte anzahl400 = 0;
void setup() {
Serial.begin(115200);
Wire.begin();
Serial.println("****** I2C-Scanner *****");
}
void loop() {
Serial.println("\nStarte Scan (100 kHz) ... ");
Wire.setClock(100000L);
for (I2CAdd = 1; I2CAdd < 128; I2CAdd++)
{
Wire.beginTransmission(I2CAdd);
fehler = Wire.endTransmission();
if (fehler == 0)
{
anzahl100++;
Serial.print("Baustein mit Adresse 0x");
Serial.print(I2CAdd, HEX);
Serial.println(" gefunden!");
}
}if (anzahl100 > 0)
{
Serial.println("\nStarte Scan (400 kHz) ... ");
Wire.setClock(400000L);
for (I2CAdd = 1; I2CAdd < 128; I2CAdd++)
{
Wire.beginTransmission(I2CAdd);
fehler = Wire.endTransmission();
if (fehler == 0)
{
anzahl400++;
Serial.print("Baustein mit Adresse 0x");
Serial.print(I2CAdd, HEX);
Serial.println(" gefunden!");
}
}
Serial.println("\nScan beendet!");
Serial.print("Anzahl gefunden 100/400 kHz: ");
Serial.print(anzahl100);
Serial.print("/");
Serial.print(anzahl400);
Serial.println(" Baustein(e)");
}
else Serial.println("\nKeinen I2C-Baustein gefunden!");anzahl100 = 0;
anzahl400 = 0;
Serial.println(); Serial.println();
delay(10000);
}