初めてのRaspberry Pi Pico ⑩ C言語で7セグメントLEDを点灯 その2　温度センサTMP117

###表示部分を関数化
　前回のプログラムLED7seg_74HC595.cの表示部分を関数に変更します。ソースはLED7seg_74HC595s.cに変更し、同じフォルダ/home/pi/pico/works/LED7seg_74HC595に入っているCMakeLists.txtを修正します。ソース名を変えただけです。

```shell
add_executable(LED7seg_74HC595
        LED7seg_74HC595s.c
        )

# Pull in our pico_stdlib which pulls in commonly used features
target_link_libraries(LED7seg_74HC595 pico_stdlib  hardware_spi)

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

# add url via pico_set_program_url
example_auto_set_url(LED7seg_74HC595)
```

　更新したLED7seg_74HC595s.cです。

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

#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"

#define PIN_CS   5
#define PIN_SCK  6
#define PIN_MOSI 7

#define SPI_PORT spi0
#define READ_BIT 0x80

const uint8_t digits[] = {
  0b00111111, // 0
  0b00000110, // 1
  0b01011011, // 2
  0b01001111, // 3
  0b01100110, // 4
  0b01101101, // 5
  0b01111101, // 6
  0b00000111, // 7
  0b01111111, // 8
  0b01101111, // 9
};
const uint8_t  dot   = 0b10000000;
const uint8_t  blank = 0b00000000;
const uint8_t  minus = 0b01000000;  // -

static inline void cs_select() {
    asm volatile("nop \n nop \n nop");
    gpio_put(PIN_CS, 0);  // Active low
    asm volatile("nop \n nop \n nop");
}

static inline void cs_deselect() {
    asm volatile("nop \n nop \n nop");
    gpio_put(PIN_CS, 1);
    asm volatile("nop \n nop \n nop");
}

static void write_register(uint8_t reg, uint8_t data) {
    uint8_t buf[2];
    buf[0] = reg & 0x7f;  // remove read bit as this is a write
    buf[1] = data;
    cs_select();
    spi_write_blocking(SPI_PORT, buf, 2);
    cs_deselect();
    sleep_ms(10);
}

void clearLED(){
    // clear all segments
    cs_select();
    spi_write_blocking(SPI_PORT, &blank, 1);
    spi_write_blocking(SPI_PORT, &blank, 1);
    spi_write_blocking(SPI_PORT, &blank, 1);
    spi_write_blocking(SPI_PORT, &blank, 1);
    spi_write_blocking(SPI_PORT, &blank, 1);
    spi_write_blocking(SPI_PORT, &blank, 1);
    cs_deselect();
}
void setup_SPI(){
    // This example will use SPI0 at 0.5MHz.
    spi_init(SPI_PORT, 500 * 1000);
    gpio_set_function(PIN_SCK, GPIO_FUNC_SPI);
    gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI);

    // Chip select is active-low, so we'll initialise it to a driven-high state
    gpio_init(PIN_CS);
    gpio_set_dir(PIN_CS, GPIO_OUT);
    gpio_put(PIN_CS, 1);
}

void disp7segLED(float Temp){
  //float Temp=-1.4567;
  char sTemp[8];
  snprintf(sTemp, 8, "%f", Temp);
  puts(sTemp);
  int seisuu;
  for (int i=0; i<8; i=i+1){
      //printf("moji %d ",sTemp[i]);
      if (sTemp[i] == 46){        // 46=.
          //printf("seisuu %d\n",i);
          seisuu = i;
          break;
      }
  }
 
  cs_select();
  if (Temp > 0.0) {
    if (seisuu == 2) {  // 23.4567
      spi_write_blocking(SPI_PORT, &digits[sTemp[0]-48], 1);
      uint8_t pp = digits[sTemp[1]-48] ^ dot;
      spi_write_blocking(SPI_PORT, &pp, 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[3]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[4]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[5]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[6]-48], 1);
    }
    if (seisuu == 1) {     // 1.2345
      spi_write_blocking(SPI_PORT, &blank, 1); // blank
      uint8_t pp = digits[sTemp[0]-48] ^ dot;
      spi_write_blocking(SPI_PORT, &pp, 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[2]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[3]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[4]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[5]-48], 1);
    }
  }else{  // minus
    if (seisuu == 3) {     // -12.3456
      spi_write_blocking(SPI_PORT, &minus, 1); // -
      uint8_t pp = digits[sTemp[2] - 48] ^ dot;
      spi_write_blocking(SPI_PORT, &digits[sTemp[1]-48], 1);
      spi_write_blocking(SPI_PORT, &pp, 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[4]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[5]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[6]-48], 1);
    }
    if (seisuu == 2) {     // -1.2222
      spi_write_blocking(SPI_PORT, &blank, 1); // blank
      spi_write_blocking(SPI_PORT, &minus, 1); // -
      uint8_t pp = digits[sTemp[1]-48] ^ dot;
      spi_write_blocking(SPI_PORT, &pp, 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[3]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[4]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[5]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[6]-48], 1);   
    }
  }
  cs_deselect();
}

int main() {
    stdio_init_all();

    printf("\nHello, 7SegmentLED via SPI...\n");
    setup_SPI();
    clearLED();

    disp7segLED(-12.3456);

    sleep_ms(2000);;

    return 0;
}
```
###温度センサTMP117
　温度センサを用意します。GP8とGP9のI2CバスにTMP117をつなぎます。TMP117から読み出した温度を7セグLEDに表示します。

```cpp

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

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

#define PIN_CS   5
#define PIN_SCK  6
#define PIN_MOSI 7

#define SPI_PORT spi0
#define READ_BIT 0x80

//   GPIO 8 (pin 11)-> SDA on TMP117 board
//   GPIO 9 (pin 12)-> SCL on TMP117 board
#define I2C_PORT i2c0
#define TMP117address 0x48
#define TemperatureRegister 0x00

const uint8_t digits[] = {
  0b00111111, // 0
  0b00000110, // 1
  0b01011011, // 2
  0b01001111, // 3
  0b01100110, // 4
  0b01101101, // 5
  0b01111101, // 6
  0b00000111, // 7
  0b01111111, // 8
  0b01101111, // 9
};
const uint8_t  dot   = 0b10000000;
const uint8_t  blank = 0b00000000;
const uint8_t  minus = 0b01000000;  // -

static inline void cs_select() {
    asm volatile("nop \n nop \n nop");
    gpio_put(PIN_CS, 0);  // Active low
    asm volatile("nop \n nop \n nop");
}

static inline void cs_deselect() {
    asm volatile("nop \n nop \n nop");
    gpio_put(PIN_CS, 1);
    asm volatile("nop \n nop \n nop");
}

/* not test not use
static void SPI_write_register(uint8_t reg, uint8_t data) {
    uint8_t buf[2];
    buf[0] = reg & 0x7f;  // remove read bit as this is a write
    buf[1] = data;
    cs_select();
    spi_write_blocking(SPI_PORT, buf, 2);
    cs_deselect();
    sleep_ms(10);
}

static void I2C_write_register(uint8_t reg, uint8_t data) {
    uint8_t buf[2];
    //buf[0] = reg & 0x7f;  // remove read bit as this is a write
    buf[0] = reg;
    buf[1] = data;
    i2c_write_blocking(I2C_PORT, addr, buf, 2, true);
}

static void I2C_read_registers(uint8_t reg, uint8_t *buf, uint16_t len) {
    // For this particular device, we send the device the register we want to read
    // first, then subsequently read from the device. The register is auto incrementing
    // so we don't need to keep sending the register we want, just the first.
    reg = reg | READ_BIT;
    i2c_write_blocking(I2C_PORT, addr, &reg, 1, true); 
    i2c_read_blocking(I2C_PORT, addr, buf, len, false);
}
*/

void clearLED(){
    // clear all segments
    cs_select();
    spi_write_blocking(SPI_PORT, &blank, 1);
    spi_write_blocking(SPI_PORT, &blank, 1);
    spi_write_blocking(SPI_PORT, &blank, 1);
    spi_write_blocking(SPI_PORT, &blank, 1);
    spi_write_blocking(SPI_PORT, &blank, 1);
    spi_write_blocking(SPI_PORT, &blank, 1);
    cs_deselect();
}

void setup_SPI(){
    // This example will use SPI0 at 0.5MHz.
    spi_init(SPI_PORT, 500 * 1000);
    gpio_set_function(PIN_SCK, GPIO_FUNC_SPI);
    gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI);

    // Chip select is active-low, so we'll initialise it to a driven-high state
    gpio_init(PIN_CS);
    gpio_set_dir(PIN_CS, GPIO_OUT);
    gpio_put(PIN_CS, 1);
}

void setup_I2C(){
    // This example will use I2C0 on GPIO8 (SDA) and GPIO9 (SCL) running at 100kHz.
    i2c_init(I2C_PORT, 100 * 1000);
    gpio_set_function(8, GPIO_FUNC_I2C);
    gpio_set_function(9, GPIO_FUNC_I2C);
    gpio_pull_up(8);
    gpio_pull_up(9);
}

void disp7segLED(float Temp){
  //float Temp=-1.4567;
  char sTemp[8];
  snprintf(sTemp, 8, "%f", Temp);
  puts(sTemp);
  int seisuu;
  for (int i=0; i<8; i=i+1){
      //printf("moji %d ",sTemp[i]);
      if (sTemp[i] == 46){        // 46=.
          //printf("seisuu %d\n",i);
          seisuu = i;
          break;
      }
  }
 
  cs_select();
  if (Temp > 0.0) {
    if (seisuu == 2) {  // 23.4567
      spi_write_blocking(SPI_PORT, &digits[sTemp[0]-48], 1);
      uint8_t pp = digits[sTemp[1]-48] ^ dot;
      spi_write_blocking(SPI_PORT, &pp, 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[3]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[4]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[5]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[6]-48], 1);
    }
    if (seisuu == 1) {     // 1.2345
      spi_write_blocking(SPI_PORT, &blank, 1); // blank
      uint8_t pp = digits[sTemp[0]-48] ^ dot;
      spi_write_blocking(SPI_PORT, &pp, 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[2]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[3]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[4]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[5]-48], 1);
    }
  }else{  // minus
    if (seisuu == 3) {     // -12.3456
      spi_write_blocking(SPI_PORT, &minus, 1); // -
      uint8_t pp = digits[sTemp[2] - 48] ^ dot;
      spi_write_blocking(SPI_PORT, &digits[sTemp[1]-48], 1);
      spi_write_blocking(SPI_PORT, &pp, 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[4]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[5]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[6]-48], 1);
    }
    if (seisuu == 2) {     // -1.2222
      spi_write_blocking(SPI_PORT, &blank, 1); // blank
      spi_write_blocking(SPI_PORT, &minus, 1); // -
      uint8_t pp = digits[sTemp[1]-48] ^ dot;
      spi_write_blocking(SPI_PORT, &pp, 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[3]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[4]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[5]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[6]-48], 1);   
    }
  }
  cs_deselect();
}


static int16_t tmp117_read_raw() {
    uint8_t buffer[2];
    uint8_t val = TemperatureRegister; // | READ_BIT;
    i2c_write_blocking(I2C_PORT, TMP117address, &val, 1, true);
    i2c_read_blocking(I2C_PORT, TMP117address, buffer, 2, false);
    int16_t temperature = buffer[0] << 8 | buffer[1];
    return ( -(temperature & 0b1000000000000000) | (temperature & 0b0111111111111111) );
}


int main() {
    stdio_init_all();

    printf("\nHello, 7SegmentLED via SPI...\n");
    setup_SPI();
    clearLED();

    setup_I2C();

    while (1){
        float Temp = tmp117_read_raw() * 7.8125 /1000.0;
        printf("Temp = %.1fC\n", Temp);

        disp7segLED(Temp);
        sleep_ms(2000);
    }
    return 0;
}
```

  i2Cのライブラリの記述を追加したCMakeLists.txtの内容です。

```shell
add_executable(LED7seg_74HC595
        LED7seg_74HC595s.c
        )

# Pull in our pico_stdlib which pulls in commonly used features
target_link_libraries(LED7seg_74HC595 pico_stdlib  hardware_spi  hardware_i2c)

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

# add url via pico_set_program_url
example_auto_set_url(LED7seg_74HC595)
```

　実行中の様子です。

![IMGP0184.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/e4a1f193-8e22-1988-a253-91eee8704254.png)