TOPに戻る

Raspberry Pi Picoでプログラミング ⑨ i2cscanner

 ラズパイのi2ctoolsにあるi2cdetectと同じものが、pico\pico-examples\build\i2c\bus_scanに入っています。最初に、このソースを利用して、i2cscannerを作ります。

●プログラム名はi2cscanner

 pico/pico-examples/i2c/bus_scanフォルダをpico/worksフォルダへコピペし、i2cscannerという名前で保存します。

 i2cscannerフォルダには、ソースのbus_scan.cとCMakeLists.txtが入っています。まず、CMakeLists.txtを修正します。


add_executable(i2cscanner
        bus_scan.c
        )

# Pull in our (to be renamed) simple get you started dependencies
target_link_libraries(i2cscanner pico_stdlib hardware_i2c)

# create map/bin/hex file etc.
pico_add_extra_outputs(i2cscanner)

 つぎにbus_scan.cを次のように修正します。SCL、SDAのピンを変更、printf文を少し修正するだけです。


/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

// Sweep through all 7-bit I2C addresses, to see if any slaves are present on
// the I2C bus. Print out a table that looks like this:
//
// I2C Bus Scan
//   0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
// 0
// 1       @
// 2
// 3             @
// 4
// 5
// 6
// 7
//
// E.g. if slave addresses 0x12 and 0x34 were acknowledged.

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/i2c.h"

#define SDA_PIN 8  // GP8
#define SCL_PIN 9  // GP9

// I2C reserves some addresses for special purposes. We exclude these from the scan.
// These are any addresses of the form 000 0xxx or 111 1xxx
bool reserved_addr(uint8_t addr) {
    return (addr & 0x78) == 0 || (addr & 0x78) == 0x78;
}

int main() {
    // Enable UART so we can print status output
    stdio_init_all();
#if !defined(i2c_default) || !defined(PICO_DEFAULT_I2C_SDA_PIN) || !defined(PICO_DEFAULT_I2C_SCL_PIN)
#warning i2c/bus_scan example requires a board with I2C pins
    puts("Default I2C pins were not defined");
#else
    // This example will use I2C0 on the default SDA and SCL pins (4, 5 on a Pico)
    i2c_init(i2c_default, 100 * 1000);
    gpio_set_function(SDA_PIN, GPIO_FUNC_I2C);
    gpio_set_function(SCL_PIN, GPIO_FUNC_I2C);
    gpio_pull_up(SDA_PIN);
    gpio_pull_up(SCL_PIN);
    // Make the I2C pins available to picotool
    bi_decl(bi_2pins_with_func(SDA_PIN, SCL_PIN, GPIO_FUNC_I2C));

    printf("\nI2C Bus Scan. SDA=GP%d SCL=GP%d\n", SDA_PIN, SCL_PIN);
    printf("   0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F\n");

    for (int addr = 0; addr < (1 << 7); ++addr) {
        if (addr % 16 == 0) {
            printf("%02x ", addr);
        }

        // Perform a 1-byte dummy read from the probe address. If a slave
        // acknowledges this address, the function returns the number of bytes
        // transferred. If the address byte is ignored, the function returns
        // -1.

        // Skip over any reserved addresses.
        int ret;
        uint8_t rxdata;
        if (reserved_addr(addr))
            ret = PICO_ERROR_GENERIC;
        else
            ret = i2c_read_blocking(i2c0, addr, &rxdata, 1, false);

        printf(ret < 0 ? "." : "@");
        printf(addr % 16 == 15 ? "\n" : "  ");
    }
    printf("Done.\n");
    return 0;
#endif
}

 pico/worksにあるCMakeLists.txtを次のように修正します。


cmake_minimum_required(VERSION 3.12)

# Pull in SDK (must be before project)
include(pico_sdk_import.cmake)

project(pico_examples C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

set(PICO_EXAMPLES_PATH ${PROJECT_SOURCE_DIR})

# Initialize the SDK
pico_sdk_init()

# Add blink example
add_subdirectory(cmake)
add_subdirectory(blink)
add_subdirectory(serial)
add_subdirectory(clock)
add_subdirectory(i2cscanner)

 ターミナルで、pico/works/buildにおりて、

cmake ..

 pico/works/build/i2cscannerにおりて、

make -j4

 /home/pi/pico/works/build/i2cscannerフォルダに、i2cscanner.uf2ができています。

 term.shをダブルクリックして標準入出力を起動します。

 I2Cデバイスを二つ、GP9(SCL)/GP8(SDA)、GND、3.3Vに接続します。

 ここで、PicoのResetボタンを押したまま、BOOTSELボタンを押し、Resetボタンを離してから、BOOTSELボタンを離します。これでRPI-RP2ディスクがマウントができます。

 i2cscanner.uf2ファイルをRPI-RP2ディスクへドラッグします。これでマイコン(Pico)に書き込みが行われ、完了するとリセットがかかり、プログラムが動きます。

 0x48と0x5dに見つけてきました。

連載 Raspberry Pi Picoでプログラミング

(1) ラズパイ4の準備(1) USBブートの設定

(2) ラズパイ4の準備(2) 標準入出力の用意

(3) ラズパイ4の準備(3) LチカとHello, world!の実行

(4) ラズパイ4の準備(4) リモート環境の設定

(5) プログラミングの環境整備とLチカ

(6) Hello, World!

(7) 使用するピンと機能

(8) クロックの値の表示

(9) i2cscanner

(10) i2c APIと気圧センサLPS25

(11) i2c 温度センサTMP117

(12) i2c 湿度センサAHT20

(13) spi APIとA-DコンバータMCP3008

(14) spi A-DコンバータMCP3208

(15) gpioファンクション