投稿

BMP280温度センサー・その6(メインルーチン)

簡易目次    実際のプログラムに入る前にプロジェクトフォルダーをGitHubに作成しました。   GitHubプロジェクトフォルダ 前回までの説明で(ほとんど説明してないけど)作成した、デバイスクラスやデバイスマネージャークラスを実際に使ってみます。 メインプログラムはTestProject/00_TestI2C.cppとなっており、ソースは以下の通りです。 #include <stdio.h> #include <stdlib.h> #include <time.h> #include <unistd.h> #include <linux/i2c-dev.h> #include <fcntl.h> #include <sys/ioctl.h> #include "../../SPI2C/BMP280/BMP280.h" int main() { SPI2C::CSPI2CManager i2cManager("/dev/i2c-1"); //Control & Configuration SPI2C::CSPI2CBMP280ConfigCtrl * pConfigCtrl = new SPI2C::CSPI2CBMP280ConfigCtrl( 0x76 ); pConfigCtrl->SetCtrlOsrsP(SPI2C::CSPI2CBMP280ConfigCtrl::OsrsP_x16); pConfigCtrl->SetSender(); i2cManager.AddDeviceAccess( pConfigCtrl ); SPI2C::CSPI2CBMP280TempPress * pTempPress = new SPI2C::CSPI2CBMP280TempPress( 0x76 ); SPI2C::CSPI2CBMP280Calib * pCalib = new SPI2C::CSPI2CBMP280Calib( 0x76 ); pCalib->SetTempPressInstance( pTempPress ); i2cManager

BMP280温度センサー・その5(I2Cデバイスクラスに関して)

イメージ
簡易目次    実際のプログラムに入る前にプロジェクトフォルダーをGitHubに作成しました。   GitHubプロジェクトフォルダ  I2Cデバイスのベースとなるクラスは以下の通りとなる。 class CSPI2CDeviceAccessBase { friend class CSPI2CManager; public: CSPI2CDeviceAccessBase(uint8_t ui8DeviceAddress); virtual ~CSPI2CDeviceAccessBase(); inline uint8_t GetDeviceAddress() { return this->m_ui8DeviceAddress; } inline bool GetLoopAccess() { return this->m_bLoopAccess; } virtual bool AfterProcess(); protected: CSPI2CDeviceAccessBase * m_pNextAccess; CSPI2CData m_listDataProcess; CSPI2CManager * m_pManager; bool m_bLoopAccess; uint8_t m_ui8DeviceAddress; }; このクラスのインスタンスを BMP280温度センサー・その4(I2C通信スレッド) で述べたマネージャークラスに登録することによって、I2Cとの通信が行われることになる。 I2Cで送受信するデータはCSPI2CData型のリストに CSPI2CDataElement型のデータを登録することにより行う。CSPI2CDataElement型のデータはCSPI2CDataElementからの派生クラスであるCSPI2CDataRegisterReaderかCSPI2CDataRegisterWriter, CSPI2CDataCommandWriterを使用する。 BMP280に関して、以下の3つのクラスを定義する class CSPI2CBMP280ConfigCtrl :温度センサーのコンフィギュレーションを設定するためのクラス。BMP280のメモリーマップは以下の通りとなっ

BMP280温度センサー・その4(I2C通信スレッド)

イメージ
簡易目次    実際のプログラムに入る前にプロジェクトフォルダーをGitHubに作成しました。   GitHubプロジェクトフォルダ  ブログにまとめていないだけでプログラム自体はそれなりに進んでいます。その都度参照していこうと思います。  まずはI2Cとの通信の実装から行います。I2Cとの通信はI2Cマスター毎に動作する専用のスレッドとスレッドに関連付けられたクラス内で行っていきます。  I2Cとの通信を受け持つクラスとして「SPI2C::CSPI2CManager」と言うクラスを実装します。クラスのインスタンスは別スレッド内で実行され、クラス内にはミューテックスで保護されたリストがあり、そのリストに並んでいるI2Cデバイスアクセス用のクラスをFIFOでリストからチェックアウトして、I2Cとの通信を行うことにより様々なデバイスとのアクセスを一元的に行っていくことにします。説明だけでは分かりにくいのでソースを提示します。 CSPI2CManagerクラス(抜粋) namespace SPI2C { class CSPI2CManager { public: static void * ThreadProc( void * pVoidParameter ); CSPI2CManager(const char * pcszI2CName); virtual ~CSPI2CManager(); void AddDeviceAccess( class CSPI2CDeviceAccessBase * pDevice ); inline void StopThread() { this->m_bStopLoop = true; } protected: void ReleaseAllDevice(); class CSPI2CDeviceAccessBase * CheckoutAccess(); class CSPI2CDeviceAccessBase * m_pFirstAccess; class CSPI2CDeviceAccessBase * m_pLastAccess; bool CommunicationLoop(); bool WriteI2C( uint8_t ui8DeviceAddress, CSPI2CD

BMP280温度センサー・その3

イメージ
簡易目次  BMP280温度センサーのデータシートをダウンロードします。  メジャーな商品なので、「BMP280」と検索するとすぐに見つかります。ただメジャーすぎて色んなショッピングサイトがヒットしてしまいますが、こういう海外製品の公式ドキュメントを探したければ検索結果のうち全て英語で書いてあるページの最初にヒットするのが公式っぽいですね(経験則ですが)  BMP280のBOSCHの公式ページは Pressure Sensor BMP280 | Bosch Sensortec ここになります。スクロールしていくと、  こんな感じでデータシートのダウンロードができます。  自分がダウンロードしたのは2015/10作成のVersion1.15でした。  結構前の物なんですねぇ。後で触れますが、データシートの誤記が結構あります。もうバージョンアップはしないんでしょうか?  さて、ドキュメントを読み進めましょう。まずは、RaspberryPiとつなぐのに何Vの電圧線をつなげればよいかです。一応Amazonの商品ページには「PowerSupply 1.8V-3.6V」と表記がありました。しかしこの商品ページ、BMP280の紹介なのに「湿度も測れるよ」とか書いてあってイマイチ信頼できません。なのでデータシートを確認します。 Page7に以下のような表記を見つけました。  通常1.8V、最大3.6Vという事なので、Amazonに書いてある表記はOKという事が確認できました。モジュールの方のVCCにも特に抵抗などは入っていないようなので、大丈夫でしょう。Page9には以下のような表記もありました。  どのピンにも4.25V以上の電圧は繋げるなという事らしいです。  なので、RaspberryPiの3.3Vの出力を使う事にします。  あと、BMP280はI2Cのアドレスとして0x76と0x77が使えるようです。切り替え方に関してはPage28で以下のようにありました。    SDOピンをグラウンドにつなげると0x76、VCCにつなげると0x77になるとの事でした。SDOピンは開放するとアドレスが未定義になるから開放しないでねともありました。  さてここまでドキュメントを読めば十分でしょう。Raspberry PiとBMP280を接続してみます。 RaspberryPi BMP280

BMP280温度センサー・その2

イメージ
簡易目次  Raspberry Pi とBMP280モジュールをI2Cで接続し、通信テストを行ってみます。  Raspberry Pi を扱った人なら良く知っていると思いますが、Raspberry Piには40本のGPIOポートがついています。  この40pinがそれぞれ様々な役割を持っているわけですが、これもみんなが色々と説明しているので、詳細は省きます。一次ソースとして RaspberryPi公式 を見て下さい。以下に上げているのは公式ドキュメントのイメージです。  左側の図面に書いてあるRaspberryPiは多分Raspberry Pi 4ですね。公式の説明によると現在売り出し中のRaspberryPiのGPIOはすべて同じレイアウトのようです。  今回はRaspberry Pi Zero WHを使おうと思います。Raspberry Pi Zero WHの外観は以下の通りです。 こう置いた状態の左上が1番pinとなります。 ちなみに裏返すとこんな感じになっていて、  ここのところをよく見ると、  ヘッダーピンの半田付けが一つだけ四角くなっています。この四角くなっているところが1番pinと言うのがハードウェアの常識っぽいです。  公式ドキュメントからRaspberry Pi Zero WH の GPIOの2番がI2CのSDA、3番がI2CのSCLという事が分かります。  あ、今までの説明で1点忘れていました。   Raspberry Pi OSは初期セットアップ状態ではI2Cの通信が無効になっています。必ず有効にしましょう (うっかり忘れるにしては大問題じゃね?)。  raspi-configで有効にできます。TeraTerm等でSSHでログインして sudo raspi-config   を実行すると  こんな画面が出てきます。矢印の↑↓で「3 Interface Options」にカーソルを合わせ、「Enter」キーを押します。  次にこの画面で「P5 I2C」を選択して「Enter」を押します。  有効にしますか?と聞かれるので「Yes」で「Enter」を押します。  これでI2Cが使えるようになりました。  さて、ここからはBOSCHのBMP280のデータシートを見ながら進めていきます。  長いのでいったん切ります。

BMP280温度センサー・その1

イメージ
簡易目次  さて、開発環境が整ったので、早速何か作ってみようと思います。  SPOONsoftwareの入っているテナントは2階建ての倉庫の2階で窓が多く外壁は薄く、屋根はトタンです。また部屋が広いため冷暖房の効きが悪いんです。何が言いたいかと言うと、 夏はものすごく暑くて、冬は死ぬほど寒い です。夏の一番暑いときには室温が体温を超えることもあり、冬の一番寒いときには日中でさえ室内で息が白くなるという...。  そんなわけで(どんなわけだ?)温度計を作成して、室温の履歴をとってみたいと思います。  温度センサーとしてはBOSCHのBMP280を使用してみたいと思います。BOSCHと言うと電動工具でよく見かけますが、センサーも作ってるんですねぇ。  購入したのはこちらのBMP280を搭載したセンサーモジュールです。 表 裏  ちなみに上の写真の真ん中にある  このチップがBMP280本体ですね。こんな小さなチップなのにわざわざモジュール化して大きくしてしまうのはなんか勿体ないですが、チップだけだと自分みたいなハードウェア素人には扱えないので仕方ないです。BOSCHからダウンロードしたデータシート(後で紹介します)によると、サイズは2mm×2.5mm、厚さが0.95mmだそうです。こんなに小さいのにSPIとI2Cに対応しています。BMP280は温度と気圧を測ることが出来ますが、この上位機種にBME280と言うものがあり、これを使うと湿度も測れるようです。知っていたらBME280の方を買ったんですが、後で知りました。  ちなみにこちらのモジュールはAmazonで3つ入り950円くらいでした。    このモジュールはI2CとSPIに対応しているようなのですが、今回はI2Cで通信しようと思います。  I2Cについて色々調べていくと、「プルアップ」抵抗と言う言葉を耳にします。I2CはSDAとSCLの2本の信号線によって通信していますが、そこに適切な大きさの抵抗を入れてあげないとACKがうまく受信できずに通信不良を起こしてしまうそうです。  それで通信が上手くいくことを確認しようと  こんなものを作ってみました。これで1kΩ毎に抵抗を増やしていって、通信が上手くいく抵抗を調べようというわけです。試してみた結果...   抵抗をつなぐ必要はありませんでした。  さっきのモジュールを

Raspberry Pi セットアップ

イメージ
簡易目次   ラズパイをセットアップしていきます。  と言ってもセットアップ方法はいろんな人が書いているので、あえて書かなくても良いかなと思います。ラズパイをセットアップするうえで色々方法があるのですが、自分のお気に入りは 「Raspberry Pi Zero W」をWindows10PCだけでセットアップ   この方法です。  自分はWin32DiskImagerではなく、 DD for Windows を使って書き込みました。  やり方としては RaspberryPi OS のイメージをダウンロード ⇒ MicroSDにイメージ書き込み ⇒ 無線LAN設定情報書き込み ⇒ ssh有効化 ⇒ RaspberryPiにセット  とやるとssh接続が出来るようになるので、Teratermで「raspberrypi.local」を指定して接続します。ログインは「pi」「raspberry」で行います。  色んなセットアップする時に「sudo」しても良いのですが、面倒なので、「sudo passwod root」でルートのパスワードを設定し、「su」でルート化して作業するのもありです。raspi-configを使用してタイムゾーンもJSTに変えておきましょう。  あと、自分の開発環境は以下の通りとなっています。  メインの開発マシンはWindows10でこのPCのハードディスクの共有ディレクトリをプロジェクトフォルダーとして使っています。プロジェクトフォルダーは定期バックアップやRAID1構成となっているため、開発関係は全てここに保存するようにしています。CentOSのPCにはEclipseが入っており、LinuxのC++環境やクロスコンパイラがセットアップされています。EclipseのワークスペースはWindows10のプロジェクトフォルダーをSambaClientでマウントしたものとなっています。  今回RaspberryPiのクロスコンパイル環境をCentOS内に作りますが、ワークスペースはプロジェクトフォルダー内に作成します。それでRaspberryPiからもプロジェクトフォルダーをのぞけるようにRaspberryPi側にもSambaとSmbClientをインストールしておき、マウントしておきます。 クロスコンパイラーのセットアップ  Raspberry Pi O