文書の表示以前のリビジョンバックリンクPDF の出力全て展開する/折り畳むODT 出力文書の先頭へ この文書は読取専用です。文書のソースを閲覧することは可能ですが、変更はできません。もし変更したい場合は管理者に連絡してください。 ====== 簡易気圧&温度計(SCP1000) ====== ===== 概要 ===== 気圧と温度が測定できるセンサーが手に入りましたので、早速、簡易な「気圧&温度計」を製作してみました。 使用したセンサーモジュールは、VTIテクノロジー社製の気圧(絶対圧)センサー「SCP1000」を、更に使いやすくした、8ピンDIP型の「SCP1000モジュール」です。(秋月電子にて販売) <SCP1000のモジュールの概観> {{:imgpaste:202004:htmikan-20200430-133917.png}} <SCP1000モジュールの特長> * 扱いやすい8ピンDIP型になっており、気圧計、高度計などに最適 * 電源電圧<2.4~3.3V> * インターフェース<SPI> * 測定範囲<30kPa~120kPa(300ヘクトパスカル~1200ヘクトパスカル)> ===== 動作原理 ===== SCP1000との通信は、SPI(Serial Peripheral Interface)方式で行います。 実際の制御は、SCP1000のレジスタにデータを、書き込んだり読み込んだりすることにより行います。 <処理の流れ> - LCDを初期化します。 - SPIを初期化します。 - SCP1000をソフトウエアリセットします。 - SCP1000のオペレーションモードを設定します。(高精度モード) - SCP1000のリビジョン番号を取得します。(必ず必要なわけではありません) - SCP1000のステータスを取得し、「スタートアップ状態」、「データレディー状態」であるかをチェックします。 - 気圧を取得し、パスカル値に変換し、LCDに表示します。 - 温度を取得し、℃値に変換し、LCDに表示します。 - 6.に戻ります。 <SCP1000のブロックダイアグラム> {{:imgpaste:202004:htmikan-20200430-134041.png?500}} <SCP1000の回路図> {{:imgpaste:202004:htmikan-20200430-134052.png?500}} <SCP1000のマスター/スレーブの構成> {{:imgpaste:202004:htmikan-20200430-134100.png?500}} <SCP1000のレジスタ> {{:imgpaste:202004:htmikan-20200430-134110.png?500}} <SCP1000の通信フォーマット(8ビット書き込み、8ビット読み込み、16ビット読み込み)> {{:imgpaste:202004:htmikan-20200430-134119.png?500}} ===== 回路図 ===== {{:imgpaste:202004:htmikan-20200430-134207.png}} ===== ソースコード ===== ※気圧の取得箇所に誤りがありましたので、訂正版を掲載いたしました。 <code c pressure_v110.c> //********************************************************************** /* 「簡易気圧測定器(SCP1000)」 */ //********************************************************************** //SCP1000 #define OPARATION 0x03 #define RSTR 0x06 #define STATUS 0x07 #define DATARD8 0x1F #define DATARD16 0x20 #define TEMPOUT 0x21 //SPI sbit SoftSpi_CSB at RA0_bit; sbit SoftSpi_SDI at RA7_bit; sbit SoftSpi_SDO at RA6_bit; sbit SoftSpi_CLK at RA1_bit; sbit SoftSpi_CSB_Direction at TRISA0_bit; sbit SoftSpi_SDI_Direction at TRISA7_bit; sbit SoftSpi_SDO_Direction at TRISA6_bit; sbit SoftSpi_CLK_Direction at TRISA1_bit; //LCD sbit LCD_RS at RB3_bit; sbit LCD_EN at RB2_bit; sbit LCD_D7 at RB7_bit; sbit LCD_D6 at RB6_bit; sbit LCD_D5 at RB5_bit; sbit LCD_D4 at RB4_bit; sbit LCD_RS_Direction at TRISB3_bit; sbit LCD_EN_Direction at TRISB2_bit; sbit LCD_D7_Direction at TRISB7_bit; sbit LCD_D6_Direction at TRISB6_bit; sbit LCD_D5_Direction at TRISB5_bit; sbit LCD_D4_Direction at TRISB4_bit; //other #define BYTE unsigned short #define WORD unsigned int #define WWORD unsigned long //********************************************************************** //SCP1000への1バイトデータの書き込み void scp1000_write(BYTE addr, BYTE dat) { SoftSpi_CSB = 0; Soft_Spi_Write((addr << 2) | 2); Soft_Spi_Write(dat); SoftSpi_CSB = 1; // Delay_ms(100); } //********************************************************************** //SCP1000からの1バイトデータの読み込み BYTE scp1000_read8(BYTE addr) { BYTE dummy, tmp; // SoftSpi_CSB = 0; Soft_Spi_Write(addr << 2); tmp = Soft_Spi_Read(dummy); SoftSpi_CSB = 1; // Delay_ms(100); return (tmp); } //********************************************************************** //SCP1000からの2バイトデータの読み込み WORD scp1000_read16(BYTE addr) { BYTE dummy; WORD tmp; // SoftSpi_CSB = 0; Soft_Spi_Write(addr << 2); tmp = Soft_Spi_Read(dummy) << 8; tmp |= Soft_Spi_Read(dummy); SoftSpi_CSB = 1; // Delay_ms(100); return (tmp); } //********************************************************************** void main() { BYTE buf[16]; BYTE tmp; WORD temperature; WWORD pressure; // OSCCON = 0b01110000; CMCON = 0b00000111; ANSEL = 0b00000000; TRISA = 0b10111010; TRISB = 0b00000000; //LCDの初期化 Lcd_Init(); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1, 1, "Pressure v1.10"); Delay_ms(1000); Lcd_Cmd(_LCD_CLEAR); //SPIの初期化 Soft_Spi_Init(); SoftSpi_CSB = 1; Delay_ms(100); //ソフトウエアリセット&オペレーションモード設定 scp1000_write(RSTR, 0x01); scp1000_write(OPARATION, 0x0A); tmp = scp1000_read8(0x00); Lcd_Out(1, 1, "SCP1000 start!"); Delay_ms(1000); Lcd_Cmd(_LCD_CLEAR); // while (1) { //ステータスの取得 tmp = scp1000_read8(STATUS); if ((tmp.F0 != 0) || (tmp.F5 != 1)) { continue; } if (tmp.F4 == 1) { Lcd_Chr(2, 16, '*'); //Real time error! } else { Lcd_Chr(2, 16, ' '); } //気圧の取得→換算(パスカル)→表示 pressure = scp1000_read8(DATARD8) & 0x03; pressure <<= 16; pressure |= scp1000_read16(DATARD16); LongToStr((pressure * 10) / 4, buf); buf[0] = buf[1]; buf[1] = buf[2]; buf[2] = buf[3]; buf[3] = buf[4]; buf[4] = buf[5]; buf[5] = buf[6]; buf[6] = buf[7]; buf[7] = buf[8]; buf[8] = buf[9]; buf[9] = '.'; Lcd_Out(1, 1, buf); Lcd_Out(1, 12, "(Pa)"); //温度の取得→換算(℃)→表示 temperature = scp1000_read16(TEMPOUT) & 0x3FFF; if ((temperature & 0x2000) == 0) { Lcd_Chr(2, 1, ' '); } else { Lcd_Chr(2, 1, '-'); } temperature &= 0x1FFFF; WordToStr((temperature * 10) / 20, buf); buf[0] = buf[1]; buf[1] = buf[2]; buf[2] = buf[3]; buf[3] = '.'; Lcd_Out(2, 7, buf); Lcd_Out(2, 12, "(\xDFC)"); } } //********************************************************************** </code> ===== 動作確認 ===== ※ブレッドボードでの動作確認では、レベル変換用の抵抗(回路図参照)を省略しているので、ご注意ください。 {{:imgpaste:202004:htmikan-20200430-134325.png?500}} 左側=2階のベランダ、右側=家の前の路上※高度差は約5mです。 表示内容は、上段がPA(パスカル)表示、下段が温度表示です。 {{:imgpaste:202004:htmikan-20200430-134337.png}}{{:imgpaste:202004:htmikan-20200430-134341.png}} 左側=2階の室内、右側=1階の室内※室内では、殆ど差がでません。 {{:imgpaste:202004:htmikan-20200430-134348.png}}{{:imgpaste:202004:htmikan-20200430-134352.png}} <callout type="warning" title="著作権表示 copyright notice"> このページは稲崎様の閉鎖したHPのコピーで、著作権は稲崎様にあります。[[elechobby:picdic:picdic|詳細]] This page is a copy of Mr. Inasaki's closed website, and the copyright is held by him.[[elechobby:picdic:picdic|Details]] </callout> elechobby/picdic/pic16f88/134.txt 最終更新: 2025/10/17 14:29by 127.0.0.1