あらきけいすけのメモ帳

あらきけいすけの雑記帳2

pigpio ライブラリの spi_xfer() 関数を用いて Raspberry Pi 3B から SPI 接続のA/Dコンバータ MCP3208 を利用する

自分用の覚書。ようやく pigpio の spi_open() と spi_xfer() のパラメータの与え方が分かったので、Python と C のミニマルコードをメモしておく。

Python

参考にしたサイト
tomosoft.jp

#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
# Raspberry Pi 3B から MCP3208 を利用するコード (終了は Ctrl-C)
#
# ピンの接続
#   Raspberry Pi 3B           MCP3208
#   [19] GPIO_10 SPI_MOSI  -> [11] D_IN
#   [21] GPIO_09 SPI_MISO  <- [12] D_OUT
#   [23] GPIO_11 SPI_CLK   -> [13] CLK
#   [24] GPIO_08 SPI_CE0_N -> [10] ~CS/SHDN
#
# MCP3208 の [1]CH0 のA/D変換値(0~4095)を表示する
#
# 参考にしたサイト (2018年10月27日アクセス)
#   http://abyz.me.uk/rpi/pigpio/python.html
#     pigpio library: Python Interface
#   https://tomosoft.jp/design/?p=10477
#     TomoSoft: pigpioによるI2CとSPIインタフェースの実装
#     注: MCP3208 は12bitのA/Dコンバータだが testspi.py では
#         そのうちの上位10bitのデータ(0~1023)を利用していた。
#

import time
import pigpio

slct = 0 # +1 +1 # SPI接続機器の番号 chip select
baud = 50000     # 通信速度
flag = 0 # +256  # bin(256) = 0b100000000 は Aux SPI の利用フラグ
adch = 0         # MCP3208のCH0の番号

pi = pigpio.pi()
hndl = pi.spi_open(slct, baud, flag) # デバイスオープン

try:
  while True:
    cmnd = ( 0b00011000 + adch ) << 2
    c, raw = pi.spi_xfer(hndl,[cmnd,0,0]) # 最初の要素が命令の入力
    #
    #    [0][1][1][D2][D1][D0][0][0]
    #        |  |   |   |   |
    #        |  |  読み出しチャネルの指定
    #        | 1: シングルエンド
    #       [スタートビット]
    #
    data = ((raw[1] & 0b11111111) <<  4) + \
           ((raw[2] & 0b11110000) >>  4)
    print(c,raw,bin(data),data)
    time.sleep(1)

except KeyboardInterrupt:
    pi.spi_close(hndl)
    pi.stop()

C言語

参考にしたサイト
Raspberry Pi 3とADS7843を使ってタッチスクリーンの情報を受け取る(Cでpigpioを使ってSPI通信→Nodejs) - Qiita
gpio - pigpio spiXfer in C++ - Raspberry Pi Stack Exchange

/*
  pigpio の spiOpen(), spiXfer() を利用する最小限コード
  Raspberry Pi 3B と MCP3208 の接続は上の Python コードと同じ
  動作: A/Dコンバータを1秒間隔で10回読んで、表示する(終了は自動)

  参考にしたサイト
    https://qiita.com/yuji_miyano/items/e86150759818c3c12fa4
    https://raspberrypi.stackexchange.com/questions/79127/pigpio-spixfer-in-c/79128#79128
*/
#include <stdio.h>
#include <unistd.h>
#include <pigpio.h>

int main (void) {
  if ( gpioInitialise() < 0 ) {
    printf("gpioInitialise() failed\n");
  } else {
    printf("gpioInitialise() succeeded\n");
    int slct = 0;//+2   // SPI接続機器の番号 chip select
    int baud = 50000;   // 通信速度
    int flag = 0;//+256 // 256: Aux SPI の利用フラグ
    int hndl = spiOpen(slct, baud, flag);
    if ( hndl < 0 ) {
      printf("spiOpen() failed\n");
    } else {
      printf("spiOpen() succeeded\n");
      int count = 0;
      while ( count < 10 ) {
        int adch = 0;  // MCP3208のCHの番号(0-7)
        char txBuf[3]; // 読み出し命令, AD変換データの入れ物
        txBuf[0]= ( 0x18 + adch ) << 2;
        txBuf[1]= txBuf[2]= 0;
        spiXfer(hndl,txBuf,txBuf,3); // pigpio: SPI読み出し
        int data =  // 読み出したバッファからの移し替え
          ( txBuf[1] & 0xff ) << 4 |
          ( txBuf[2] & 0xf0 ) >> 4;
        printf("%d %d\n",count,data);
        count++;
        sleep(1);
      }
      spiClose(hndl);
    }
    gpioTerminate();
  }
}