GY-63_MS5611/libraries/MultiSpeedI2CScanner/MultiSpeedI2CScanner.ino

502 lines
10 KiB
Arduino
Raw Normal View History

2021-05-30 08:23:58 -04:00
//
// FILE: MultiSpeedI2CScanner.ino
// AUTHOR: Rob Tillaart
2023-01-20 13:51:58 -05:00
// VERSION: 0.1.16
2021-05-30 08:23:58 -04:00
// PURPOSE: I2C scanner at different speeds
// DATE: 2013-11-05
// URL: https://github.com/RobTillaart/MultiSpeedI2CScanner
// URL: http://forum.arduino.cc/index.php?topic=197360
//
2021-12-22 07:02:30 -05:00
2021-05-30 08:23:58 -04:00
#include <Arduino.h>
#include <Wire.h>
2023-01-20 13:51:58 -05:00
// FOR INTERNAL I2C BUS NANO 33 BLE
// #define WIRE_IMPLEMENT_WIRE1 1
// extern TwoWire Wire1;
2021-12-22 07:02:30 -05:00
TwoWire *wire;
2021-05-30 08:23:58 -04:00
2023-01-20 13:51:58 -05:00
const char version[] = "0.1.16";
2021-05-30 08:23:58 -04:00
2023-01-20 13:51:58 -05:00
// INTERFACE COUNT (TESTED TEENSY 3.5 AND ARDUINO DUE ONLY)
2021-05-30 08:23:58 -04:00
int wirePortCount = 1;
int selectedWirePort = 0;
2023-01-20 13:51:58 -05:00
// scans devices from 50 to 800 KHz I2C speeds.
// speed lower than 50 and above 400 can cause problems
2021-05-30 08:23:58 -04:00
long speed[10] = { 100, 200, 300, 400 };
int speeds;
int addressStart = 8;
int addressEnd = 119;
2023-01-20 13:51:58 -05:00
// DELAY BETWEEN TESTS
// for delay between tests of found devices.
2021-05-30 08:23:58 -04:00
#ifndef RESTORE_LATENCY
2023-01-20 13:51:58 -05:00
#define RESTORE_LATENCY 5
2021-05-30 08:23:58 -04:00
#endif
bool delayFlag = false;
2023-01-20 13:51:58 -05:00
// MINIMIZE OUTPUT
2021-05-30 08:23:58 -04:00
bool printAll = true;
bool header = true;
bool disableIRQ = false;
2023-01-20 13:51:58 -05:00
// STATE MACHINE
2021-05-30 08:23:58 -04:00
enum states {
STOP, ONCE, CONT, HELP
};
states state = STOP;
2023-01-20 13:51:58 -05:00
// TIMING
2021-05-30 08:23:58 -04:00
uint32_t startScan;
uint32_t stopScan;
2023-01-20 13:51:58 -05:00
///////////////////////////////////////////////////////////////////////////
2021-05-30 08:23:58 -04:00
//
// MAIN CODE
//
void setup()
{
Serial.begin(115200);
2023-01-20 13:51:58 -05:00
while (!Serial);
2021-05-30 08:23:58 -04:00
#if defined (ESP8266) || defined(ESP32)
2023-01-20 13:51:58 -05:00
uint8_t sda = 14; // 21
uint8_t scl = 15; // 22
Wire.begin(sda, scl, 100000); // ESP32 - change config pins if needed.
2021-05-30 08:23:58 -04:00
#else
Wire.begin();
#endif
#if defined WIRE_IMPLEMENT_WIRE1 || WIRE_INTERFACES_COUNT > 1
Wire1.begin();
wirePortCount++;
#endif
#if defined WIRE_IMPLEMENT_WIRE2 || WIRE_INTERFACES_COUNT > 2
Wire2.begin();
wirePortCount++;
#endif
#if defined WIRE_IMPLEMENT_WIRE3 || WIRE_INTERFACES_COUNT > 3
Wire3.begin();
wirePortCount++;
#endif
2021-12-22 07:02:30 -05:00
#if defined WIRE_IMPLEMENT_WIRE4 || WIRE_INTERFACES_COUNT > 4
Wire4.begin();
wirePortCount++;
#endif
#if defined WIRE_IMPLEMENT_WIRE5 || WIRE_INTERFACES_COUNT > 5
Wire5.begin();
wirePortCount++;
#endif
2021-05-30 08:23:58 -04:00
2021-12-22 07:02:30 -05:00
wire = &Wire;
2021-05-30 08:23:58 -04:00
Serial.println();
2023-01-20 13:51:58 -05:00
reset();
2021-05-30 08:23:58 -04:00
}
void loop()
{
yield();
char command = getCommand();
switch (command)
{
case '@':
selectedWirePort = (selectedWirePort + 1) % wirePortCount;
Serial.print(F("<I2C PORT=Wire"));
Serial.print(selectedWirePort);
Serial.println(F(">"));
switch (selectedWirePort)
{
case 0:
2021-12-22 07:02:30 -05:00
wire = &Wire;
2021-05-30 08:23:58 -04:00
break;
#if defined WIRE_IMPLEMENT_WIRE1 || WIRE_INTERFACES_COUNT > 1
case 1:
2021-12-22 07:02:30 -05:00
wire = &Wire1;
2021-05-30 08:23:58 -04:00
break;
#endif
#if defined WIRE_IMPLEMENT_WIRE2 || WIRE_INTERFACES_COUNT > 2
case 2:
2021-12-22 07:02:30 -05:00
wire = &Wire2;
2021-05-30 08:23:58 -04:00
break;
#endif
#if defined WIRE_IMPLEMENT_WIRE3 || WIRE_INTERFACES_COUNT > 3
case 3:
2021-12-22 07:02:30 -05:00
wire = &Wire3;
break;
#endif
#if defined WIRE_IMPLEMENT_WIRE4 || WIRE_INTERFACES_COUNT > 4
case 4:
wire = &Wire4;
break;
#endif
#if defined WIRE_IMPLEMENT_WIRE5 || WIRE_INTERFACES_COUNT > 5
case 5:
wire = &Wire5;
2021-05-30 08:23:58 -04:00
break;
#endif
}
break;
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 'i':
disableIRQ = !disableIRQ;
Serial.print(F("<irq="));
Serial.println(disableIRQ ? F("diabled>") : F("enabled>"));
break;
case '0':
case '1':
case '2':
case '4':
case '8':
case '9':
case 'M':
case 'N':
case 'O':
case 'P':
setSpeed(command);
break;
2023-01-20 13:51:58 -05:00
case 'r':
reset();
break;
2021-05-30 08:23:58 -04:00
case 'a':
setAddress();
break;
case 'q':
case '?':
state = HELP;
break;
default:
break;
}
switch (state)
{
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;
}
}
2023-01-20 13:51:58 -05:00
//////////////////////////////////////////////////////////////////////
void reset()
{
setSpeed('9');
selectedWirePort = 0;
addressStart = 8;
addressEnd = 119;
delayFlag = false;
printAll = true;
header = true;
disableIRQ = false;
state = STOP;
displayHelp();
}
2021-05-30 08:23:58 -04:00
void setAddress()
{
if (addressStart == 0)
{
addressStart = 8;
addressEnd = 119;
}
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)
{
switch (sp)
{
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;
2021-12-22 07:02:30 -05:00
case '9': // limited to 400 KHz
2021-05-30 08:23:58 -04:00
speeds = 8;
for (int i = 1; i <= speeds; i++) speed[i - 1] = i * 50;
break;
2021-12-22 07:02:30 -05:00
case '0': // limited to 800 KHz
2021-05-30 08:23:58 -04:00
speeds = 8;
for (int i = 1; i <= speeds; i++) speed[i - 1] = i * 100;
break;
// new in 0.1.10 - experimental
case 'M':
speed[0] = 1000;
speeds = 1;
break;
case 'N':
speed[0] = 3400;
speeds = 1;
break;
case 'O':
speed[0] = 5000;
speeds = 1;
break;
case 'P':
speed[0] = 100;
speed[1] = 400;
speed[2] = 1000;
speed[3] = 3400;
speed[4] = 5000;
speeds = 5;
break;
}
Serial.print("<speeds =");
for (int i = 0; i < speeds; i++)
{
Serial.print(' ');
Serial.print(speed[i]);
}
Serial.println(" >");
}
char getCommand()
{
char c = '\0';
if (Serial.available())
{
c = Serial.read();
}
return c;
}
void displayHelp()
{
Serial.print(F("\nArduino MultiSpeed I2C Scanner - "));
Serial.println(version);
Serial.println();
Serial.print(F("I2C ports: "));
Serial.print(wirePortCount);
Serial.print(F(" Current: Wire"));
Serial.println(selectedWirePort);
2021-12-22 07:02:30 -05:00
Serial.println(F("\t@ = toggle Wire - Wire1 .. Wire5 [e.g. TEENSY or Arduino Due]"));
2021-05-30 08:23:58 -04:00
Serial.println(F("Scan mode:"));
Serial.println(F("\ts = single scan"));
Serial.println(F("\tc = continuous scan - 1 second delay"));
Serial.println(F("\tq = quit continuous scan"));
Serial.println(F("\td = toggle latency delay between successful tests. 0 - 5 ms"));
Serial.println(F("\ti = toggle enable/disable interrupts"));
Serial.println(F("Output:"));
Serial.println(F("\tp = toggle printAll - printFound."));
Serial.println(F("\th = toggle header - noHeader."));
Serial.println(F("\ta = toggle address range, 0..127 - 8..119 (default)"));
Serial.println(F("Speeds:"));
2021-12-22 07:02:30 -05:00
Serial.println(F("\t0 = 100..800 KHz - step 100 (warning - can block!!)"));
2021-05-30 08:23:58 -04:00
Serial.println(F("\t1 = 100 KHz"));
Serial.println(F("\t2 = 200 KHz"));
Serial.println(F("\t4 = 400 KHz"));
2021-12-22 07:02:30 -05:00
Serial.println(F("\t9 = 50..400 KHz - step 50 < DEFAULT >"));
2021-05-30 08:23:58 -04:00
Serial.println();
Serial.println(F("\t!! HIGH SPEEDS - WARNING - can block - not applicable for UNO"));
Serial.println(F("\t8 = 800 KHz"));
Serial.println(F("\tM = 1000 KHz"));
Serial.println(F("\tN = 3400 KHz"));
2021-12-22 07:02:30 -05:00
Serial.println(F("\tO = 5000 KHz"));
Serial.println(F("\tP = 100 400 1000 3400 5000 KHz (standards)"));
2023-01-20 13:51:58 -05:00
Serial.println(F("\n\tr = reset to startup defaults."));
Serial.println(F("\t? = help - this page"));
2021-05-30 08:23:58 -04:00
Serial.println();
}
void I2Cscan()
{
startScan = millis();
uint8_t count = 0;
if (disableIRQ) noInterrupts();
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();
2021-12-22 07:02:30 -05:00
delay(100);
2021-05-30 08:23:58 -04:00
}
for (uint8_t address = addressStart; address <= addressEnd; address++)
{
bool printLine = printAll;
bool found[speeds];
bool fnd = false;
for (uint8_t s = 0; s < speeds ; s++)
{
2021-12-22 07:02:30 -05:00
yield(); // keep ESP happy
2021-05-30 08:23:58 -04:00
#if ARDUINO < 158 && defined (TWBR)
uint16_t PREV_TWBR = TWBR;
TWBR = (F_CPU / (speed[s] * 1000) - 16) / 2;
if (TWBR < 2)
{
Serial.println("ERROR: not supported speed");
TWBR = PREV_TWBR;
2021-12-22 07:02:30 -05:00
return;
2021-05-30 08:23:58 -04:00
}
#else
2021-12-22 07:02:30 -05:00
wire->setClock(speed[s] * 1000UL);
2021-05-30 08:23:58 -04:00
#endif
2021-12-22 07:02:30 -05:00
wire->beginTransmission (address);
found[s] = (wire->endTransmission () == 0);
2021-05-30 08:23:58 -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"));
if (address < 0x10) Serial.print(0, HEX);
Serial.print(address, HEX);
Serial.print(F("\t"));
for (uint8_t s = 0; s < speeds ; s++)
{
Serial.print(F("\t"));
Serial.print(found[s] ? F("V") : F("."));
}
Serial.println();
}
}
2023-01-20 13:51:58 -05:00
/*
// FOOTER
if (header)
{
for (uint8_t s = 0; s < speeds + 5; s++)
{
Serial.print(F("--------"));
}
Serial.println();
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]"));
}
*/
2021-05-30 08:23:58 -04:00
stopScan = millis();
if (header)
{
Serial.println();
Serial.print(count);
Serial.print(F(" devices found in "));
Serial.print(stopScan - startScan);
Serial.println(F(" milliseconds."));
}
2021-12-22 07:02:30 -05:00
2021-05-30 08:23:58 -04:00
interrupts();
}
2021-12-22 07:02:30 -05:00
2021-05-30 08:23:58 -04:00
// -- END OF FILE --
2021-12-22 07:02:30 -05:00