2022-08-29 09:17:44 -04:00
|
|
|
|
|
|
|
[![Arduino CI](https://github.com/RobTillaart/I2C_SCANNER/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
|
|
|
|
[![Arduino-lint](https://github.com/RobTillaart/I2C_SCANNER/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/I2C_SCANNER/actions/workflows/arduino-lint.yml)
|
|
|
|
[![JSON check](https://github.com/RobTillaart/I2C_SCANNER/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/I2C_SCANNER/actions/workflows/jsoncheck.yml)
|
2023-08-24 15:35:58 -04:00
|
|
|
[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/I2C_SCANNER.svg)](https://github.com/RobTillaart/I2C_SCANNER/issues)
|
|
|
|
|
|
|
|
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/RobTillaart/I2C_SCANNER/blob/master/LICENSE)
|
|
|
|
[![GitHub Release](https://img.shields.io/github/release/RobTillaart/I2C_SCANNER.svg?maxAge=3600)](https://github.com/RobTillaart/I2C_SCANNER/releases)
|
|
|
|
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/I2C_SCANNER.svg)](https://registry.platformio.org/libraries/robtillaart/I2C_SCANNER)
|
2022-08-29 09:17:44 -04:00
|
|
|
|
|
|
|
|
|
|
|
# I2C_SCANNER
|
|
|
|
|
|
|
|
Arduino class to implement an I2C scanner.
|
|
|
|
|
|
|
|
|
|
|
|
## Description
|
|
|
|
|
|
|
|
I2C_SCANNER is a class to build an I2C scanner, either minimal or more complex.
|
|
|
|
|
2022-08-30 06:39:55 -04:00
|
|
|
The class provides different functions to analyse the connectivity of devices
|
|
|
|
on the I2C bus. There are functions to adjust the frequency and functions to
|
2023-08-24 15:35:58 -04:00
|
|
|
select the bus in case of multiple I2C ports.
|
|
|
|
|
|
|
|
A typical other use is to see if all devices are available (breadboard test).
|
2022-08-30 06:39:55 -04:00
|
|
|
|
|
|
|
Furthermore there are different functions to scan the I2C port,
|
|
|
|
see the section scanning below.
|
|
|
|
|
2023-08-24 15:35:58 -04:00
|
|
|
The address range for "normal" I2C devices is from 9 to 119.
|
|
|
|
The user may use other values for address at his own risk.
|
|
|
|
|
|
|
|
If there is missing functionality in this library, please file an issue.
|
|
|
|
|
|
|
|
|
2023-12-05 10:33:52 -05:00
|
|
|
#### 0.3.0 Breaking change
|
|
|
|
|
|
|
|
Version 0.3.0 introduced a breaking change.
|
|
|
|
You cannot set the pins in **begin()** any more.
|
|
|
|
This reduces the dependency of processor dependent Wire implementations.
|
|
|
|
The user has to call **Wire.begin()** and can optionally set the Wire pins
|
|
|
|
before calling **begin()**.
|
|
|
|
|
|
|
|
|
2023-08-24 15:35:58 -04:00
|
|
|
#### Testing
|
|
|
|
|
|
|
|
The library is tested with the following boards:
|
|
|
|
|
|
|
|
| board | works |
|
|
|
|
|:---------:|:-------:|
|
|
|
|
| UNO | yes |
|
|
|
|
| MEGA | yes |
|
|
|
|
| NANO | ? |
|
|
|
|
| ESP8266 | ? |
|
|
|
|
| ESP32 | yes |
|
|
|
|
|
|
|
|
Please file an issue if your board does work (or not).
|
|
|
|
|
|
|
|
|
|
|
|
#### Related
|
|
|
|
|
|
|
|
- https://github.com/RobTillaart/MultiSpeedI2CScanner
|
2022-08-29 09:17:44 -04:00
|
|
|
|
|
|
|
|
|
|
|
## Interface
|
|
|
|
|
2023-08-24 15:35:58 -04:00
|
|
|
```cpp
|
|
|
|
#include "I2C_SCANNER.h"
|
|
|
|
```
|
|
|
|
|
|
|
|
#### Constructor
|
|
|
|
|
2022-08-30 06:39:55 -04:00
|
|
|
- **I2C_SCANNER(TwoWire \*wire = &Wire)** Constructor with the default Wire I2C bus.
|
|
|
|
- **bool begin()** To start the Wire library.
|
2022-08-29 09:17:44 -04:00
|
|
|
|
|
|
|
|
2023-08-24 15:35:58 -04:00
|
|
|
#### Configuration
|
2022-08-29 09:17:44 -04:00
|
|
|
|
2022-08-30 06:39:55 -04:00
|
|
|
- **bool setClock(uint32_t clockFrequency = 100000UL)** sets the speed of the I2C bus.
|
2022-08-31 05:08:07 -04:00
|
|
|
Returns true.
|
2023-08-24 15:35:58 -04:00
|
|
|
Note the supported frequency is board dependent. Check your boards datasheet.
|
2022-08-31 05:08:07 -04:00
|
|
|
- **uint32_t getClock()** supported by some platforms, including ESP32.
|
2023-08-24 15:35:58 -04:00
|
|
|
Please fill in issue if your board is missing here.
|
2022-08-30 06:39:55 -04:00
|
|
|
- **uint8_t getWireCount()** returns the number of Wire ports (hardware I2C).
|
2023-08-24 15:35:58 -04:00
|
|
|
To be used by **setWire(uint8_t n)**.
|
2022-08-30 06:39:55 -04:00
|
|
|
- **bool setWire(uint8_t n)** sets the Wire port by number.
|
2023-08-24 15:35:58 -04:00
|
|
|
Assumes there exist Wire, Wire1 ... Wire5.
|
|
|
|
The number n should not exceed the value returned by **getWireCount()**
|
|
|
|
- **bool setWire(TwoWire \*wire = &Wire)** set a Wire port by 'name' e.g. Wire1.
|
2022-08-30 06:39:55 -04:00
|
|
|
- **TwoWire \* getWire()** returns the Wire object set.
|
2022-08-29 09:17:44 -04:00
|
|
|
|
|
|
|
|
2023-08-24 15:35:58 -04:00
|
|
|
#### Scanning
|
2022-08-29 09:17:44 -04:00
|
|
|
|
2023-08-24 15:35:58 -04:00
|
|
|
- **uint16_t ping(uint8_t address, uint16_t count = 1)** Tries to make contact with I2C address.
|
|
|
|
Returns the number of successful "contacts / connections" with the address.
|
|
|
|
Typical number of retries is 1..5, however one can also do a long test up to 65535 retries.
|
|
|
|
Can be used for endurance test / diagnosis of responsiveness.
|
|
|
|
Note the function does not call **yield()** intern so use with care.
|
|
|
|
Note that when count is large, the function call will block for a long time.
|
|
|
|
Better use a loop of e.g. 100 retries at a time.
|
2022-08-30 06:39:55 -04:00
|
|
|
- **int diag(uint8_t address)** Tries to make contact with I2C address.
|
2023-08-24 15:35:58 -04:00
|
|
|
Returns Wire status code 0 == OK, other return values might depend on platform used.
|
2022-08-30 06:39:55 -04:00
|
|
|
- **int32_t pingTime(uint8_t address)** Tries to make contact with I2C address.
|
2023-08-24 15:35:58 -04:00
|
|
|
Returns time used in micros. Returns a negative time (< 0) if failed to contact.
|
2022-08-30 06:39:55 -04:00
|
|
|
- **uint8_t count(uint8_t start = 0, uint8_t end = 127)** pings address range.
|
|
|
|
Includes start and end address too. Returns the number of addresses found.
|
2022-08-29 09:17:44 -04:00
|
|
|
|
|
|
|
|
2023-08-24 15:35:58 -04:00
|
|
|
#### Reset
|
2022-08-31 05:08:07 -04:00
|
|
|
|
|
|
|
(needs testing)
|
|
|
|
|
|
|
|
- **int softwareReset(uint8_t method = 0)** sends a I2C SWRST command over the configured I2C bus.
|
|
|
|
This will cause all devices that support this command to do a "power on" reset.
|
|
|
|
The code implements two methods,
|
|
|
|
- 0 = NXP spec (default)
|
|
|
|
- 1 = from PCA9634 issue.
|
|
|
|
|
|
|
|
The **softwareReset()** function should return 0 for success.
|
|
|
|
The value -999 indicates invalid method selected.
|
|
|
|
Other are I2C specific error codes.
|
|
|
|
|
|
|
|
|
2023-09-24 15:08:41 -04:00
|
|
|
#### Timeout
|
|
|
|
|
|
|
|
Experimental
|
|
|
|
|
|
|
|
Not all platforms support this functionality, you need to patch I2C_SCANNER.cpp file to get
|
|
|
|
this working for your platform.
|
|
|
|
- **bool setWireTimeout(uint32_t timeOut)**
|
|
|
|
- **uint32_t getWireTimeout()**
|
|
|
|
|
|
|
|
|
2023-08-24 15:35:58 -04:00
|
|
|
## Future ideas
|
2022-08-29 09:17:44 -04:00
|
|
|
|
2023-08-24 15:35:58 -04:00
|
|
|
#### Must
|
2022-08-29 09:17:44 -04:00
|
|
|
|
2023-08-24 15:35:58 -04:00
|
|
|
- documentation.
|
2022-08-30 06:39:55 -04:00
|
|
|
|
2022-08-29 09:17:44 -04:00
|
|
|
#### Should
|
|
|
|
|
2022-08-30 06:39:55 -04:00
|
|
|
- add examples.
|
2022-08-31 05:08:07 -04:00
|
|
|
- add **setWireTimeOut(uint32_t timeout, bool reset_with_timeout = true)**
|
2023-08-24 15:35:58 -04:00
|
|
|
- portable? clear? reset? default?
|
|
|
|
- needs to be set for every Wire interface
|
|
|
|
- ESP8266 does have a **setClockStretchLimit(timeout)**
|
2022-08-30 06:39:55 -04:00
|
|
|
|
|
|
|
#### Could
|
|
|
|
|
2022-08-31 05:08:07 -04:00
|
|
|
- add **bool hardwareReset()**
|
2022-08-30 06:39:55 -04:00
|
|
|
- keep data HIGH for X clock pulses - google this.
|
2022-08-31 05:08:07 -04:00
|
|
|
- (needs investigation)
|
2023-08-24 15:35:58 -04:00
|
|
|
- https://github.com/esp8266/Arduino/issues/1025
|
|
|
|
- read the state of the I2C pins
|
|
|
|
- **uint8_t readSDA()** diagnose the I2C bus. Board specific!
|
|
|
|
- **uint8_t readSCL()** diagnose the I2C bus. Board specific!
|
2022-08-31 05:08:07 -04:00
|
|
|
- implement **getClock()** for AVR based platforms
|
2023-08-24 15:35:58 -04:00
|
|
|
- reverse calculate TWBR and pre-scaler.
|
|
|
|
- needs investigation
|
|
|
|
- support for RP2040
|
|
|
|
- needs investigation
|
|
|
|
- add table with default I2C pins per platform / board
|
|
|
|
- https://www.arduino.cc/reference/en/language/functions/communication/wire/
|
2022-08-30 06:39:55 -04:00
|
|
|
|
|
|
|
|
|
|
|
#### Won't
|
|
|
|
|
|
|
|
- device analysis
|
|
|
|
- add **bool send(address, uint8_t \*buffer, uint8_t length)**
|
|
|
|
- add **bool receive(address, uint8_t \*buffer, uint8_t length)**
|
|
|
|
- add iterator
|
2022-08-31 05:08:07 -04:00
|
|
|
- **uint8_t first(uint8_t start = 0)** returns address or 255
|
|
|
|
- **uint8_t next()** returns address or 255.
|
|
|
|
- **uint8_t \_devices[16]** cache hits ?
|
|
|
|
- No
|
2023-08-24 15:35:58 -04:00
|
|
|
- implement a **SW_I2C**
|
|
|
|
- No, user may use a SW_I2C that derives from TwoWire.
|
|
|
|
|
|
|
|
|
|
|
|
## Support
|
|
|
|
|
|
|
|
If you appreciate my libraries, you can support the development and maintenance.
|
|
|
|
Improve the quality of the libraries by providing issues and Pull Requests, or
|
|
|
|
donate through PayPal or GitHub sponsors.
|
|
|
|
|
|
|
|
Thank you,
|
|
|
|
|