ラズパイを使って自作の温度計を作りたいのですが、ラズパイってADコンバーターがないんですよね。。
なのでADコンバーターICを外付けで接続します。ADコンバーターとして選んだのは秋月電子で販売している10bit 2ch ADコンバータ MCP3002-I/P。
SPI通信でデータをやりとりするのでライブラリとしてwiringPiSPIを使ってc++のクラスを作成しました。
サンプルプログラムと一緒にご紹介します(◍•ᴗ•◍)♡ ✧*。
MCP3002のスペックは?
MCP3002のスペックをご紹介します。
- 10bitの分解能を持つADコンバーターです。
- 2CHついています。
- データのやり取りはSPI通信で行います。
- 価格はひとつ180円と安いです。
ちなみにこちらにスペックシートがあります。
wiringPiSPIを使おう
WiringPiのサイトにSPIのライブラリの使い方が紹介されていますので使う関数をご紹介します。
まずはheaderの取り込み
専用のライブラリが用意されています。こちらをincludeしましょう。
1 |
#include <wiringPiSPI.h> |
wiringPiSPISetupコマンドで通信の設定
実際にSPIでデータのやり取りをする前にSPIの設定をします。
1 |
int wiringPiSPISetup(int channel, int speed); |
ラズパイにはSPIのチャネルが2つあるのでchannelでどちらを使うのかを設定します。
通信速度はspeedで設定でき、500,000から32,000,000Hzの間で値を選ぶことができます。
ちなみに返り値はLinuxのFD(File Descriptor)です。-1の場合にはエラーとなります。
wiringPiSPIDataRWでデータの書き込みと読み込み
次に実際にデータを送受信します。
1 |
int wiringPiSPIDataRW(int channel, unsigned char *data, int len) ; |
設定したchannelに対し、*data bufferを介して書き込み読み込みを行います。
送りたいデータをdata bufferに設定しこのコマンドを実行すると、データがdata bufferに上書きされて返ってきます。
コンパイルの時はライブラリの指定を忘れずに
コンパイルの時には”-lwiringPi”と指定するのを忘れないようにしましょう。
MCP3002のサンプルプログラムはこちら
それでは実際にwiringPiSPIを使ってMCP3002とSPI通信ができるプログラムをご紹介します。
ちなみにラズパイへのSPIの設定方法はラズパイでSPI通信を有効にするにはどうすればいい?で記載しているので参考にしてください。
チャネルの設定は設定しなくても済むようにデフォルト引数を渡すようにしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
#ifndef _MCP30002_H_ #define _MCP30002_H_ /* Sample program of MCP3002 from jitaku-yasai.com MCP3002 specification : http://ww1.microchip.com/downloads/en/DeviceDoc/21294E.pdf */ #define MCP3002_START_BIT 0b01000000 #define MCP3002_SGL_BIT 0b00000000 #define MCP3002_DIF_BIT 0b00100000 #define MCP3002_ODD_BIT 0b00000000 #define MCP3002_SIGH_BIT 0b00010000 #define MCP3002_MSBF_BIT 0b00001000 #define MCP3002_SPEED 500000 // SPI clock range : 500,000 through 32,000,000 #define MCP3002_CHANNEL0 0 #define RP_SPI_CHANNEL0 0 // Raspberry Pi has two SPI channel. #define DATALEN 2 #define MCP3002_RESOLUTION 1024 class MCP3002 { public: MCP3002( // Constructor with default value int theChannelOfRP = RP_SPI_CHANNEL0, int theMCP3002lChannel = MCP3002_CHANNEL0, int theMCP3002Speed = MCP3002_SPEED); virtual ~MCP3002(); // Destructor int SPISetUp(); // SPI setup int WriteRead(); // Send setting and recieve return value. private: struct MCP3002Parameters{ int channel; // A/D converter channel 0/1 int speed; // SPI speed } MCP3002Param ; // Struct for A/D channel and SPI speed with RP unsigned char data[DATALEN]; // buffer to send/recieve for SPI communication int channelOfRP; // channel for RP communication }; #endif |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
/* Sample program of MCP3002 from jitaku-yasai.com MCP3002 specification : http://ww1.microchip.com/downloads/en/DeviceDoc/21294E.pdf */ #include <stdio.h> #include <unistd.h> #include <wiringPi.h> #include <wiringPiSPI.h> #include "mcp3002.hpp" MCP3002::MCP3002(int theChannelOfRP, int theMCP3002lChannel, int theMCP3002Speed) { // Parameters channelOfRP = theChannelOfRP; MCP3002Param.channel = theMCP3002lChannel; MCP3002Param.speed = theMCP3002Speed; } int MCP3002::SPISetUp() { return wiringPiSPISetup(channelOfRP, MCP3002Param.speed); } int MCP3002::WriteRead() { // set buffer for inquiry data[0] = MCP3002_START_BIT | MCP3002_SGL_BIT | MCP3002_MSBF_BIT | MCP3002_MSBF_BIT; // if host requests to use other than channel #0 of MCP3002, set to use channel #1 data[0] |= (MCP3002Param.channel != MCP3002_CHANNEL0) ? MCP3002_SIGH_BIT : 0; wiringPiSPIDataRW(channelOfRP, data, DATALEN); // Write and receive from same buffer return (int)((data[0] << 8 | data[1]) & 0x3FF); } MCP3002::~MCP3002() { } |
まとめ
MCP3002でSPI通信を使ってデータのやりとりをするサンプルプログラムをご紹介しました。次回は実際にこのサンプルプログラムを使ってサーミスタの温度を取得します!
記事を読んでいただいてありがとうございます。この記事がいいなと思ったら下記のSNSボタンのクリックをお願いします。励みになります😁