2014-07-05 04:50:56 -04:00
|
|
|
//
|
|
|
|
// FILE: MultiSpeedI2CScanner.ino
|
|
|
|
// AUTHOR: Rob Tillaart
|
2018-04-03 13:30:49 -04:00
|
|
|
// VERSION: 0.1.9
|
2017-07-15 07:43:41 -04:00
|
|
|
// PURPOSE: I2C scanner at different speeds
|
2014-07-05 04:50:56 -04:00
|
|
|
// DATE: 2013-11-05
|
2014-07-05 04:57:33 -04:00
|
|
|
// URL: http://forum.arduino.cc/index.php?topic=197360
|
2014-07-05 04:50:56 -04:00
|
|
|
//
|
|
|
|
// Released to the public domain
|
|
|
|
//
|
|
|
|
|
|
|
|
#include <Wire.h>
|
|
|
|
#include <Arduino.h>
|
|
|
|
|
2017-07-15 07:43:41 -04:00
|
|
|
TwoWire *wi;
|
|
|
|
|
2018-04-03 13:30:49 -04:00
|
|
|
const char version[] = "0.1.9";
|
2017-07-15 07:43:41 -04:00
|
|
|
|
|
|
|
|
2017-08-02 14:55:39 -04:00
|
|
|
// INTERFACE COUNT (TESTED TEENSY 3.5 AND ARDUINO DUE ONLY)
|
2017-07-15 07:43:41 -04:00
|
|
|
int wirePortCount = 1;
|
|
|
|
int selectedWirePort = 0;
|
|
|
|
|
2014-07-06 16:26:33 -04:00
|
|
|
|
2014-07-05 04:50:56 -04:00
|
|
|
// scans devices from 50 to 800KHz I2C speeds.
|
|
|
|
// lower than 50 is not possible
|
|
|
|
// DS3231 RTC works on 800 KHz. TWBR = 2; (?)
|
2014-07-06 16:39:00 -04:00
|
|
|
const long allSpeed[] = {
|
2017-07-15 07:43:41 -04:00
|
|
|
50, 100, 200, 300, 400, 500, 600, 700, 800
|
2014-12-17 14:51:52 -05:00
|
|
|
};
|
|
|
|
long speed[sizeof(allSpeed) / sizeof(allSpeed[0])];
|
2014-07-06 16:26:33 -04:00
|
|
|
int speeds;
|
|
|
|
|
|
|
|
int addressStart = 0;
|
|
|
|
int addressEnd = 127;
|
2014-07-05 04:50:56 -04:00
|
|
|
|
2017-07-15 07:43:41 -04:00
|
|
|
|
2014-07-05 04:50:56 -04:00
|
|
|
// DELAY BETWEEN TESTS
|
|
|
|
#define RESTORE_LATENCY 5 // for delay between tests of found devices.
|
|
|
|
bool delayFlag = false;
|
|
|
|
|
2017-07-15 07:43:41 -04:00
|
|
|
|
2014-07-05 04:50:56 -04:00
|
|
|
// MINIMIZE OUTPUT
|
|
|
|
bool printAll = true;
|
|
|
|
bool header = true;
|
|
|
|
|
2017-07-15 07:43:41 -04:00
|
|
|
|
2014-07-05 04:50:56 -04:00
|
|
|
// STATE MACHINE
|
|
|
|
enum states {
|
2014-12-17 14:51:52 -05:00
|
|
|
STOP, ONCE, CONT, HELP
|
|
|
|
};
|
2014-07-05 04:50:56 -04:00
|
|
|
states state = STOP;
|
|
|
|
|
2017-07-15 07:43:41 -04:00
|
|
|
|
|
|
|
// TIMING
|
2014-07-05 04:50:56 -04:00
|
|
|
uint32_t startScan;
|
|
|
|
uint32_t stopScan;
|
|
|
|
|
2017-07-15 07:43:41 -04:00
|
|
|
|
2014-07-06 16:39:00 -04:00
|
|
|
void setup()
|
2014-07-05 04:50:56 -04:00
|
|
|
{
|
|
|
|
Serial.begin(115200);
|
|
|
|
Wire.begin();
|
2017-07-15 07:43:41 -04:00
|
|
|
|
2017-08-02 14:55:39 -04:00
|
|
|
#if defined WIRE_IMPLEMENT_WIRE1 || WIRE_INTERFACES_COUNT > 1
|
2017-07-15 07:43:41 -04:00
|
|
|
Wire1.begin();
|
|
|
|
wirePortCount++;
|
|
|
|
#endif
|
2017-08-02 14:55:39 -04:00
|
|
|
#if defined WIRE_IMPLEMENT_WIRE2 || WIRE_INTERFACES_COUNT > 2
|
2017-07-15 07:43:41 -04:00
|
|
|
Wire2.begin();
|
|
|
|
wirePortCount++;
|
|
|
|
#endif
|
2017-08-02 14:55:39 -04:00
|
|
|
#if defined WIRE_IMPLEMENT_WIRE3 || WIRE_INTERFACES_COUNT > 3
|
2017-07-15 07:43:41 -04:00
|
|
|
Wire3.begin();
|
|
|
|
wirePortCount++;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
wi = &Wire;
|
|
|
|
|
2018-04-03 13:30:49 -04:00
|
|
|
setSpeed('9');
|
2014-07-05 04:50:56 -04:00
|
|
|
displayHelp();
|
|
|
|
}
|
|
|
|
|
2014-07-06 16:39:00 -04:00
|
|
|
void loop()
|
2014-07-05 04:50:56 -04:00
|
|
|
{
|
2014-07-06 16:26:33 -04:00
|
|
|
char command = getCommand();
|
|
|
|
switch (command)
|
2014-07-05 04:50:56 -04:00
|
|
|
{
|
2017-07-15 07:43:41 -04:00
|
|
|
case '@':
|
|
|
|
selectedWirePort = (selectedWirePort + 1) % wirePortCount;
|
|
|
|
Serial.print(F("I2C PORT=Wire"));
|
|
|
|
Serial.println(selectedWirePort);
|
|
|
|
switch (selectedWirePort)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
wi = &Wire;
|
|
|
|
break;
|
|
|
|
case 1:
|
2017-08-02 14:55:39 -04:00
|
|
|
#if defined WIRE_IMPLEMENT_WIRE1 || WIRE_INTERFACES_COUNT > 1
|
2017-07-15 07:43:41 -04:00
|
|
|
wi = &Wire1;
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
case 2:
|
2017-08-02 14:55:39 -04:00
|
|
|
#if defined WIRE_IMPLEMENT_WIRE2 || WIRE_INTERFACES_COUNT > 2
|
2017-07-15 07:43:41 -04:00
|
|
|
wi = &Wire2;
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
case 3:
|
2017-08-02 14:55:39 -04:00
|
|
|
#if defined WIRE_IMPLEMENT_WIRE3 || WIRE_INTERFACES_COUNT > 3
|
2017-07-15 07:43:41 -04:00
|
|
|
wi = &Wire3;
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2014-12-17 14:51:52 -05:00
|
|
|
case 's':
|
|
|
|
state = ONCE;
|
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
state = CONT;
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
delayFlag = !delayFlag;
|
|
|
|
Serial.print(F("<delay="));
|
|
|
|
Serial.println(delayFlag ? F("5>") : F("0>"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'e':
|
|
|
|
// eeprom test TODO
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'h':
|
|
|
|
header = !header;
|
|
|
|
Serial.print(F("<header="));
|
|
|
|
Serial.println(header ? F("yes>") : F("no>"));
|
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
printAll = !printAll;
|
|
|
|
Serial.print(F("<print="));
|
|
|
|
Serial.println(printAll ? F("all>") : F("found>"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '0':
|
|
|
|
case '1':
|
|
|
|
case '2':
|
|
|
|
case '4':
|
|
|
|
case '8':
|
2018-04-03 13:30:49 -04:00
|
|
|
case '9':
|
2014-12-17 14:51:52 -05:00
|
|
|
setSpeed(command);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'a':
|
|
|
|
setAddress();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'q':
|
|
|
|
case '?':
|
|
|
|
state = HELP;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2014-07-05 04:50:56 -04:00
|
|
|
}
|
|
|
|
|
2014-12-17 14:51:52 -05:00
|
|
|
switch (state)
|
2014-07-05 04:50:56 -04:00
|
|
|
{
|
2014-12-17 14:51:52 -05:00
|
|
|
case ONCE:
|
|
|
|
I2Cscan();
|
|
|
|
state = HELP;
|
|
|
|
break;
|
|
|
|
case CONT:
|
|
|
|
I2Cscan();
|
|
|
|
delay(1000);
|
|
|
|
break;
|
|
|
|
case HELP:
|
|
|
|
displayHelp();
|
|
|
|
state = STOP;
|
|
|
|
break;
|
|
|
|
case STOP:
|
|
|
|
break;
|
|
|
|
default: // ignore all non commands
|
|
|
|
break;
|
2014-07-05 04:50:56 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-06 16:26:33 -04:00
|
|
|
void setAddress()
|
|
|
|
{
|
|
|
|
if (addressStart == 0)
|
|
|
|
{
|
|
|
|
addressStart = 8;
|
|
|
|
addressEnd = 120;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
addressStart = 0;
|
|
|
|
addressEnd = 127;
|
|
|
|
}
|
|
|
|
Serial.print(F("<address Range = "));
|
|
|
|
Serial.print(addressStart);
|
|
|
|
Serial.print(F(".."));
|
|
|
|
Serial.print(addressEnd);
|
|
|
|
Serial.println(F(">"));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void setSpeed(char sp)
|
|
|
|
{
|
2014-12-17 14:51:52 -05:00
|
|
|
switch (sp)
|
2014-07-06 16:26:33 -04:00
|
|
|
{
|
2014-12-17 14:51:52 -05:00
|
|
|
case '1':
|
|
|
|
speed[0] = 100;
|
|
|
|
speeds = 1;
|
|
|
|
break;
|
|
|
|
case '2':
|
|
|
|
speed[0] = 200;
|
|
|
|
speeds = 1;
|
|
|
|
break;
|
|
|
|
case '4':
|
|
|
|
speed[0] = 400;
|
|
|
|
speeds = 1;
|
|
|
|
break;
|
|
|
|
case '8':
|
|
|
|
speed[0] = 800;
|
|
|
|
speeds = 1;
|
|
|
|
break;
|
2018-04-03 13:30:49 -04:00
|
|
|
case '9': // limited to 400KHz
|
|
|
|
speeds = 5;
|
|
|
|
for (int i = 0; i < speeds; i++)
|
|
|
|
{
|
|
|
|
speed[i] = allSpeed[i];
|
|
|
|
}
|
|
|
|
break;
|
2014-12-17 14:51:52 -05:00
|
|
|
case '0': // reset
|
|
|
|
speeds = sizeof(allSpeed) / sizeof(allSpeed[0]);
|
|
|
|
for (int i = 0; i < speeds; i++)
|
|
|
|
{
|
|
|
|
speed[i] = allSpeed[i];
|
|
|
|
}
|
|
|
|
break;
|
2014-07-06 16:26:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-05 04:50:56 -04:00
|
|
|
char getCommand()
|
|
|
|
{
|
|
|
|
char c = '\0';
|
|
|
|
if (Serial.available())
|
|
|
|
{
|
|
|
|
c = Serial.read();
|
|
|
|
}
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
void displayHelp()
|
|
|
|
{
|
2017-07-15 07:43:41 -04:00
|
|
|
Serial.print(F("\nArduino MultiSpeed I2C Scanner - "));
|
2014-07-06 16:26:33 -04:00
|
|
|
Serial.println(version);
|
|
|
|
Serial.println();
|
2017-07-15 07:43:41 -04:00
|
|
|
Serial.print(F("I2C ports: "));
|
|
|
|
Serial.println(wirePortCount);
|
2017-08-02 14:55:39 -04:00
|
|
|
Serial.println(F("\t@ = toggle Wire - Wire1 - Wire2 [TEENSY 3.5 or Arduino Due]"));
|
2014-07-06 16:26:33 -04:00
|
|
|
Serial.println(F("Scanmode:"));
|
2014-07-05 04:50:56 -04:00
|
|
|
Serial.println(F("\ts = single scan"));
|
|
|
|
Serial.println(F("\tc = continuous scan - 1 second delay"));
|
|
|
|
Serial.println(F("\tq = quit continuous scan"));
|
2014-07-06 16:26:33 -04:00
|
|
|
Serial.println(F("\td = toggle latency delay between successful tests. 0 - 5 ms"));
|
|
|
|
Serial.println(F("Output:"));
|
2014-07-05 04:50:56 -04:00
|
|
|
Serial.println(F("\tp = toggle printAll - printFound."));
|
|
|
|
Serial.println(F("\th = toggle header - noHeader."));
|
2014-07-06 16:26:33 -04:00
|
|
|
Serial.println(F("\ta = toggle address range, 0..127 - 8..120"));
|
|
|
|
Serial.println(F("Speeds:"));
|
2018-04-03 13:30:49 -04:00
|
|
|
Serial.println(F("\t0 = 50 - 800 Khz (warning - can block!!)"));
|
2014-07-06 16:26:33 -04:00
|
|
|
Serial.println(F("\t1 = 100 KHz only"));
|
|
|
|
Serial.println(F("\t2 = 200 KHz only"));
|
|
|
|
Serial.println(F("\t4 = 400 KHz only"));
|
2018-04-03 13:30:49 -04:00
|
|
|
Serial.println(F("\t8 = 800 KHz only (warning - can block!)"));
|
|
|
|
Serial.println(F("\t9 = 50 - 400 Khz <<< DEFAULT >>>"));
|
2014-07-06 16:26:33 -04:00
|
|
|
Serial.println(F("\n\t? = help - this page"));
|
2014-07-05 04:50:56 -04:00
|
|
|
Serial.println();
|
|
|
|
}
|
|
|
|
|
|
|
|
void I2Cscan()
|
|
|
|
{
|
|
|
|
startScan = millis();
|
|
|
|
uint8_t count = 0;
|
|
|
|
|
|
|
|
if (header)
|
|
|
|
{
|
|
|
|
Serial.print(F("TIME\tDEC\tHEX\t"));
|
|
|
|
for (uint8_t s = 0; s < speeds; s++)
|
|
|
|
{
|
|
|
|
Serial.print(F("\t"));
|
|
|
|
Serial.print(speed[s]);
|
|
|
|
}
|
|
|
|
Serial.println(F("\t[KHz]"));
|
|
|
|
for (uint8_t s = 0; s < speeds + 5; s++)
|
|
|
|
{
|
|
|
|
Serial.print(F("--------"));
|
|
|
|
}
|
|
|
|
Serial.println();
|
|
|
|
}
|
|
|
|
|
|
|
|
// TEST
|
2014-07-05 04:57:33 -04:00
|
|
|
// 0.1.04: tests only address range 8..120
|
|
|
|
// --------------------------------------------
|
2017-08-02 14:55:39 -04:00
|
|
|
// Address R/W Bit Description
|
|
|
|
// 0000 000 0 General call address
|
|
|
|
// 0000 000 1 START byte
|
|
|
|
// 0000 001 X CBUS address
|
|
|
|
// 0000 010 X reserved - different bus format
|
|
|
|
// 0000 011 X reserved - future purposes
|
|
|
|
// 0000 1XX X High Speed master code
|
|
|
|
// 1111 1XX X reserved - future purposes
|
|
|
|
// 1111 0XX X 10-bit slave addressing
|
2014-07-06 16:26:33 -04:00
|
|
|
for (uint8_t address = addressStart; address <= addressEnd; address++)
|
2014-07-05 04:50:56 -04:00
|
|
|
{
|
|
|
|
bool printLine = printAll;
|
|
|
|
bool found[speeds];
|
|
|
|
bool fnd = false;
|
|
|
|
|
|
|
|
for (uint8_t s = 0; s < speeds ; s++)
|
|
|
|
{
|
2014-12-17 14:51:52 -05:00
|
|
|
#if ARDUINO >= 158
|
2017-07-15 07:43:41 -04:00
|
|
|
wi->setClock(speed[s] * 1000);
|
2014-12-17 14:51:52 -05:00
|
|
|
#else
|
|
|
|
TWBR = (F_CPU / (speed[s] * 1000) - 16) / 2;
|
|
|
|
#endif
|
2017-07-15 07:43:41 -04:00
|
|
|
wi->beginTransmission (address);
|
|
|
|
found[s] = (wi->endTransmission () == 0);
|
2014-07-05 04:50:56 -04:00
|
|
|
fnd |= found[s];
|
|
|
|
// give device 5 millis
|
|
|
|
if (fnd && delayFlag) delay(RESTORE_LATENCY);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fnd) count++;
|
|
|
|
printLine |= fnd;
|
|
|
|
|
|
|
|
if (printLine)
|
|
|
|
{
|
|
|
|
Serial.print(millis());
|
|
|
|
Serial.print(F("\t"));
|
|
|
|
Serial.print(address, DEC);
|
|
|
|
Serial.print(F("\t0x"));
|
2014-07-06 16:26:33 -04:00
|
|
|
if (address < 0x10) Serial.print(0, HEX);
|
2014-07-05 04:50:56 -04:00
|
|
|
Serial.print(address, HEX);
|
|
|
|
Serial.print(F("\t"));
|
|
|
|
|
|
|
|
for (uint8_t s = 0; s < speeds ; s++)
|
|
|
|
{
|
|
|
|
Serial.print(F("\t"));
|
2014-12-17 14:51:52 -05:00
|
|
|
Serial.print(found[s] ? F("V") : F("."));
|
2014-07-05 04:50:56 -04:00
|
|
|
}
|
|
|
|
Serial.println();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
stopScan = millis();
|
|
|
|
if (header)
|
|
|
|
{
|
|
|
|
Serial.println();
|
|
|
|
Serial.print(count);
|
|
|
|
Serial.print(F(" devices found in "));
|
|
|
|
Serial.print(stopScan - startScan);
|
|
|
|
Serial.println(F(" milliseconds."));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-06 16:26:33 -04:00
|
|
|
|