Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Change Log MultiSpeedI2CScanner

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


https://github.com/RobTillaart/MultiSpeedI2CScanner


## 0.2.0 2025-03-25
- add wire->setWireTimeout, after selecting the wire bus ~line 160
- add **uint32_t I2C_TIMEOUT = 25000;**
- add **experimental** "e" command to toggle errorCodes in output.
- update license.
- rename releaseNotes to CHANGELOG.md.
- bumped version to 0.2.0

----

## 0.1.17 2023-11-14
- update readme.md

## 0.1.16 2023-01-20

- update build-ci
- add link to I2C scanner class in readme.md

## 0.1.15 2021-12-22

- change Khz =>KHz
- update license

## 0.1.14 2021-11-10

- update Arduino-CI build process
- add badges to readme.md
- updated readme.md
- support up to 5 Wire buses
- added an I2C bus counter sketch (very minimal)
- minor edits release notes.

## 0.1.13 2020-12-12

- Add Arduino-CI build process.
- Added a dummy examples folder with the same .ino source.
- This shows that the sketch compiles well.

## 0.1.12 2020-12-12

- Fix #4, default address range = 08...119 (0-7 and 120-127 are special)

## 0.1.11 2018-07-20

- Fix failing TWBR setting
- added yield() during scan to improve ESP behaviour.
- added disable interrupts flag
- refactor / clean up

## 0.1.10 2018-04-02

- Fix #152
- improved support for ESP32
- changed multispeed ranges a bit (option 0 and 9)
- refactor
- added experimental high speeds 1000, 3400, 5000 KHz.

verified on UNO and ESP32,
note the latter one must adjust the pins in the code.

## 0.1.9 2018-04-02

- '9' command to scan up to 400 KHz only to prevent blocking
- changed "scan up to 400 KHz" as default at startup

## 0.1.8 2017-08-03

- DUE support

## 0.1.7 2017-07-17

- TEENSY support - multiple I2C ports
- '@' command to select I2C Port
- changed # speeds steps of 100

## 0.1.6 2015-03-29

- Wire.setClock as more portable way to set I2C clock

## 0.1.5 2014-07-06

- void setSpeed() - more control about what is scanned
- void setAddress() - address range
- extended help

## older versions not documented
(started 2013-11-05 ?)


// -- END OF FILE --

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2013-2024 Rob Tillaart
Copyright (c) 2013-2025 Rob Tillaart

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
75 changes: 50 additions & 25 deletions MultiSpeedI2CScanner.ino
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// FILE: MultiSpeedI2CScanner.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.17
// VERSION: 0.2.0
// PURPOSE: I2C scanner at different speeds
// DATE: 2013-11-05
// URL: https://github.com/RobTillaart/MultiSpeedI2CScanner
Expand All @@ -12,13 +12,16 @@
#include <Arduino.h>
#include <Wire.h>


// FOR INTERNAL I2C BUS NANO 33 BLE
// #define WIRE_IMPLEMENT_WIRE1 1
// extern TwoWire Wire1;


TwoWire *wire;

const char version[] = "0.1.16";

const char version[] = "0.2.0";


// INTERFACE COUNT (TESTED TEENSY 3.5 AND ARDUINO DUE ONLY)
Expand Down Expand Up @@ -47,6 +50,7 @@ bool delayFlag = false;
// MINIMIZE OUTPUT
bool printAll = true;
bool header = true;
bool errorCode = false;
bool disableIRQ = false;


Expand All @@ -62,6 +66,12 @@ uint32_t startScan;
uint32_t stopScan;


// I2C TIMEOUT in microseconds.
// set to zero to disable.
uint32_t I2C_TIMEOUT = 25000;



///////////////////////////////////////////////////////////////////////////
//
// MAIN CODE
Expand Down Expand Up @@ -101,6 +111,9 @@ void setup()
#endif

wire = &Wire;
#if defined(WIRE_HAS_TIMEOUT)
wire->setWireTimeout(I2C_TIMEOUT, false /* NO RESET */);
#endif

Serial.println();
reset();
Expand Down Expand Up @@ -149,6 +162,9 @@ void loop()
break;
#endif
}
#if defined(WIRE_HAS_TIMEOUT)
wire->setWireTimeout(I2C_TIMEOUT, false /* NO RESET */);
#endif
break;

case 's':
Expand All @@ -164,7 +180,9 @@ void loop()
break;

case 'e':
// eeprom test TODO
errorCode = !errorCode;
Serial.print(F("<errorCode="));
Serial.println(errorCode ? F("yes>") : F("no>"));
break;

case 'h':
Expand Down Expand Up @@ -241,10 +259,11 @@ void reset()
selectedWirePort = 0;
addressStart = 8;
addressEnd = 119;

delayFlag = false;
printAll = true;
header = true;
errorCode = false;
disableIRQ = false;

state = STOP;
Expand Down Expand Up @@ -368,6 +387,7 @@ void displayHelp()
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("\te = toggle . or errorCode e.g. E02"));

Serial.println(F("Speeds:"));
Serial.println(F("\t0 = 100..800 KHz - step 100 (warning - can block!!)"));
Expand Down Expand Up @@ -418,7 +438,7 @@ void I2Cscan()
for (uint8_t address = addressStart; address <= addressEnd; address++)
{
bool printLine = printAll;
bool found[speeds];
char found[speeds][8];
bool fnd = false;

for (uint8_t s = 0; s < speeds ; s++)
Expand All @@ -438,8 +458,14 @@ void I2Cscan()
wire->setClock(speed[s] * 1000UL);
#endif
wire->beginTransmission (address);
found[s] = (wire->endTransmission () == 0);
fnd |= found[s];
int code = wire->endTransmission();
fnd |= (code == 0);
if (code == 0) strcpy(found[s], "OK");
else
{
if (errorCode) sprintf(found[s], "E%02d", code);
else strcpy(found[s], ".");
}
// give device 5 millis
if (fnd && delayFlag) delay(RESTORE_LATENCY);
}
Expand All @@ -460,31 +486,31 @@ void I2Cscan()
for (uint8_t s = 0; s < speeds ; s++)
{
Serial.print(F("\t"));
Serial.print(found[s] ? F("V") : F("."));
Serial.print(found[s]);
}
Serial.println();
}
}

/*
// FOOTER
if (header)
{
for (uint8_t s = 0; s < speeds + 5; s++)
/*
// FOOTER
if (header)
{
Serial.print(F("--------"));
}
Serial.println();
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.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]"));
}
Serial.println(F("\t[KHz]"));
}
*/
*/

stopScan = millis();
if (header)
Expand All @@ -501,4 +527,3 @@ void I2Cscan()


// -- END OF FILE --

49 changes: 44 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ not used.
# Arduino MultiSpeed I2C Scanner


## Version: 0.1.17
## Version: 0.2.0


## Description
Expand All @@ -29,7 +29,21 @@ The scanner provides an overview of which addresses can be found
at which speed. This allows one to optimize the I2C performance of
many devices above the standard 100KHz speed.

#### Related
### I2C TIMEOUT

Since version 0.2.0 the MultiSpeed I2C Scanner has a time out
of default 25 milliseconds on the I2C transactions.
This feature prevents locking of the I2C scanner and is large
enough even for low I2C speeds.

Not all platforms support the I2C timeout, so it is implemented
conditional.

Set the value of **I2C_TIMEOUT** to zero to disable it.
Note this is not a menu option and must be done compile time (for now).


### Related

build your own I2C scanner with:
- https://github.com/RobTillaart/I2C_SCANNER
Expand All @@ -54,6 +68,7 @@ Output:
p = toggle printAll - printFound.
h = toggle header - noHeader.
a = toggle address range, 0..127 - 8..119 (default)
e = toggle . or errorCode e.g. E02
Speeds:
0 = 100..800 KHz - step 100 (warning - can block!!)
1 = 100 KHz
Expand Down Expand Up @@ -106,6 +121,26 @@ PrintFound will only generate a line if an I2C device is found on that address.
**a** toggles the range of addresses scanned, default the range 8 .. 119 is scanned,
but one can extend this range to 0 .. 127. **Note:** some addresses are reserved.

Experimental in 0.2.0

**e** toggles the output between . and the code returned by **endTransmission()**.
When an device is found it will print OK. Might help for diagnosis, but one need
to dive in the source code of the board. See table below for AVR.

#### ErrorCodes AVR

Based on twi_writeTo(), other boards might have different codes.

```
Value Meaning
0 .. success
E01 .. length to long for buffer
E02 .. address send, NACK received
E03 .. data send, NACK received
E04 .. other twi error (lost bus arbitration, bus error, ..)
E05 .. timeout
```


### Speeds

Expand All @@ -125,19 +160,23 @@ Check your datasheet to see which speeds are applicable for the processor in use
#### Must

- update documentation
- test on RP2040
- test on RP2040 and other platforms.

#### Should


#### Could

- add watchdog reset (at least AVR - 8 seconds 0.2.0 )
- add "T" command to toggle I2C_TIMEOUT 0 - 25000 ?
- non-AVR command behind a ```#ifdef``` ?
- rename releaseNotes.md to changelog.md (in line with libraries)
- I2C GENERIC RESET address 0x00 CMD 0x06
- I2C GENERIC DEVICEID -> under investigation in PCA9671


#### Wont

- add watchdog reset (at least AVR - 8 seconds 0.2.0 ) => solved with I2C_TIMEOUT.


## Support

Expand Down
Loading