Skip to content

Commit 834b776

Browse files
authored
Add an i2c scanner ping (#40)
* Add an i2c scanner ping * pylint * lint again * Add release note and verbose mode * Update * Fixup
1 parent e5bca7e commit 834b776

4 files changed

Lines changed: 82 additions & 0 deletions

File tree

HISTORY.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# History
22

3+
## 0.10.0 (2025-05-26)
4+
5+
* Provide an i2c scan capabilities through the python api as well as a command
6+
line utility: `teensytoany_i2c_scan`.
7+
38
## 0.9.0 (2025-05-16)
49

510
* Provide capabilities to program devices with board specific firmwares. #38

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def get_version_and_cmdclass(pkg_path):
5252
entry_points={
5353
'console_scripts': [
5454
'teensytoany_programmer=teensytoany.programmer:teensytoany_programmer',
55+
'teensytoany_i2c_scan=teensytoany.i2c_scan:main',
5556
],
5657
},
5758
packages=find_packages(include=['teensytoany']),

teensytoany/i2c_scan.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import click
2+
3+
import teensytoany
4+
from teensytoany import TeensyToAny
5+
6+
7+
@click.command(epilog=f"Version {teensytoany.__version__}")
8+
@click.option('--serial-number', '-s', type=str, default=None,
9+
help='Serial number of the Teensy device.')
10+
@click.option('--interface', '-i', type=int, default=0,
11+
help='I2C interface to use (0 for I2C, 1 for I2C1).')
12+
@click.option('--seven-bit-mode', '-7', is_flag=True, default=False,
13+
help='Report addresses in 7-bit mode instead of 8-bit mode.')
14+
@click.option('--verbose', is_flag=True, default=False,
15+
help='Report in verbose mode, print out all pinged addresses.')
16+
@click.version_option(teensytoany.__version__)
17+
def main(
18+
serial_number=None,
19+
interface=0,
20+
seven_bit_mode=False,
21+
verbose=False,
22+
):
23+
i2c_scan(
24+
serial_number=serial_number,
25+
interface=interface,
26+
seven_bit_mode=seven_bit_mode,
27+
verbose=verbose,
28+
)
29+
30+
31+
def _scan_and_print(teensy, interface, seven_bit_mode, verbose):
32+
for address_7bit in range(1, 128):
33+
address = address_7bit << 1
34+
try:
35+
if interface == 0:
36+
teensy.i2c_ping(address=address)
37+
elif interface == 1:
38+
teensy.i2c_1_ping(address=address)
39+
if seven_bit_mode:
40+
print(f"Found device at address 0x{address_7bit:02X}")
41+
else:
42+
print(f"Found device at address 0x{address:02X}")
43+
finally:
44+
if verbose and seven_bit_mode:
45+
print(f"No device found at addr 0x{address_7bit:02X}")
46+
elif verbose and not seven_bit_mode:
47+
print(f"No device found at addr 0x{address:02X}")
48+
# else not verbose:
49+
# pass
50+
51+
52+
def i2c_scan(serial_number=None, interface=0, seven_bit_mode=False, verbose=False):
53+
teensy = TeensyToAny(serial_number=serial_number)
54+
try:
55+
_scan_and_print(
56+
teensy,
57+
interface=interface,
58+
seven_bit_mode=seven_bit_mode,
59+
verbose=verbose,
60+
)
61+
finally:
62+
teensy.close()
63+
64+
65+
if __name__ == "__main__":
66+
main()

teensytoany/teensytoany.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,11 @@ def i2c_read_payload_no_register(self, address: int, num_bytes: int):
595595
register_data = [int(val, base=0) for val in returned.split()] # returns big endian
596596
return register_data
597597

598+
def i2c_ping(self, address: int):
599+
"""Return None if device found. Raises error if no device found."""
600+
cmd = f"i2c_ping 0x{address:02x}"
601+
self._ask(cmd)
602+
598603
def i2c_1_init(self, baud_rate: int=100_100, timeout=200_000, register_space=1):
599604
cmd = f"i2c_1_init {baud_rate:d} {timeout:d} {register_space:d}"
600605
self._ask(cmd)
@@ -687,6 +692,11 @@ def i2c_1_read_payload_no_register(self, address: int, num_bytes: int):
687692
register_data = [int(val, base=0) for val in returned.split()] # returns big endian
688693
return register_data
689694

695+
def i2c_1_ping(self, address: int):
696+
"""Return None if device found. Raises error if no device found."""
697+
cmd = f"i2c_1_ping 0x{address:02x}"
698+
self._ask(cmd)
699+
690700
def gpio_digital_write(self, pin, value):
691701
"""Call the ardunio DigitalWrite function.
692702

0 commit comments

Comments
 (0)