以前に製作した、簡易湿度計の強化見直しを図りました。
<強化ポイント>
湿度センサーに直列に接続した抵抗(R:10kΩ)に、信号(500Hz矩形波)を印加すると、湿度に応じて、湿度センサーのインピーダンス®が変化するため、抵抗(R)の両端電圧(V)が変化します。
これらの条件(結果)より、演算を行い湿度を求めます。
◎湿度センサー
HS-15Pを使用します。本センサーの詳細については、簡易湿度計を参照して下さい。
◎印加信号発生
PIC内蔵のCPPモジュールをPWMモードで使用し、約500Hzの矩形波(デューティ50%)を発生させます。
この信号をHS-15Pの入力信号(V1)として印加します。この信号をPICでA/D変換して取り込みます。
◎信号の増幅
HS-15Pの出力信号(V2)を、インピーダンス変換(ボルテージフォロア)した後(V2同等)で、11倍に増幅(V3)します。
11倍に増幅する前と後の信号を各々PICでA/D変換して取り込みます。
◎信号の取り込み
V1、V2、V3の電圧をA/D変換して取り込みます。
取り込む際には、信号の矩形波の立ち上がっている期間を、5回取り込みその平均値を求めます。
◎インピーダンスの算出
HS-15Pのインピーダンス®は、オームの法則で求めることができます。
インピーダンス®=(V1-V2)÷(V2÷10kΩ)
◎レンジ切り替え
11倍された電圧(V3)の値が、4900mV以下であれば、信号が飽和(saturate)していないと判断し、上記の式のV2の変わりに、V3を1/11した値を、V2とみなし計算します。
◎インピーダンス→湿度への換算
算出したインピーダンス®を、下表のテーブルを使用して、簡易的な方法で湿度に変換します。
尚、このテーブルで採用している値は、HS-15Pの25℃の時の特性値です。
| 湿度範囲 | インピーダンス範囲 | 1/10単位のインピーダンス | ||
|---|---|---|---|---|
| 20% | 40% | 8MΩ | 220kΩ | 389kΩ |
| 40% | 60% | 220kΩ | 23kΩ | 9.85kΩ |
| 60% | 80% | 23kΩ | 3.5kΩ | 975Ω |
| 80% | 100% | 3.5kΩ | 750Ω | 138Ω |
//********************************************************************** /* <簡易湿度計V3(オートレンジ)> */ //********************************************************************** //LCD sbit LCD_RS at RA6_bit; sbit LCD_EN at RA7_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 TRISA6_bit; sbit LCD_EN_Direction at TRISA7_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; // #define BYTE unsigned short #define WORD unsigned int #define DWORD unsigned long //********************************************************************** //■関数宣言 extern void main(); extern WORD ADC_Get_Sample_Average(unsigned short channel); //********************************************************************** //■A/D変換(5回平均)関数 WORD ADC_Get_Sample_Average(unsigned short channel) { WORD ad; short cnt; // while (ADC_Get_Sample(2) > (1024 * 0.1)) { } while (ADC_Get_Sample(2) < (1024 * 0.9)) { } // ad = 0; for (cnt = 0; cnt < 5; cnt++) { ad += ADC_Get_Sample(channel); } return (ad / 5); } //********************************************************************** //■抵抗→湿度変換関数(HS-15P) struct tbl { short s; short e; long s_r; long e_r; long n_r; } hygro_tbl[4] = { {20, 40, 8000000, 220000, 389000}, {40, 60, 220000, 23000, 9850}, {60, 80, 23000, 3500, 975}, {80, 100, 3500, 750, 138} }; short hygro_cnv(long h) { if ((hygro_tbl[0].s_r >= h) && (hygro_tbl[0].e_r <= h)) { h = (h - hygro_tbl[0].e_r) / hygro_tbl[0].n_r; h = hygro_tbl[0].e - h; return (h); } if ((hygro_tbl[1].s_r >= h) && (hygro_tbl[1].e_r <= h)) { h = (h - hygro_tbl[1].e_r) / hygro_tbl[1].n_r; h = hygro_tbl[1].e - h; return (h); } if ((hygro_tbl[2].s_r >= h) && (hygro_tbl[2].e_r <= h)) { h = (h - hygro_tbl[2].e_r) / hygro_tbl[2].n_r; h = hygro_tbl[2].e - h; return (h); } if ((hygro_tbl[3].s_r >= h) && (hygro_tbl[3].e_r <= h)) { h = (h - hygro_tbl[3].e_r) / hygro_tbl[3].n_r; h = hygro_tbl[3].e - h; return (h); } } //********************************************************************** //■メイン関数 void main() { long v1, v2, v3, r; char buf[16]; int cnt; // OSCCON = 0b01110000; ANSEL = 0b00011100; TRISA = 0b00111111; TRISB = 0b00000110; // ADC_Init(); // Lcd_Init(); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1, 1, "hygrometer v3"); Delay_ms(1000); Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1, 4, "%"); Lcd_Chr(1, 16, 0xF4); Lcd_Out(2, 5, "mV"); Lcd_Out(2, 14, "mV"); // PWM1_Init(500); //500Hz PWM1_Set_Duty(PR2 / 2); PWM1_Start(); // while (1) { v1 = 0; for (cnt = 0; cnt < 200; cnt++) { v1 += ADC_Get_Sample_Average(2); } v1 = v1 / 200; v2 = 0; for (cnt = 0; cnt < 200; cnt++) { v2 += ADC_Get_Sample_Average(3); } v2 = v2 / 200; v3 = 0; for (cnt = 0; cnt < 200; cnt++) { v3 += ADC_Get_Sample_Average(4); } v3 = v3 / 200; // v1 = (double)v1 * 4.8828125; v2 = (double)v2 * 4.8828125; v3 = (double)v3 * 4.8828125; if (v3 < 4900) { v2 = v3 / 11; Lcd_Chr(2, 16, '_'); } else { Lcd_Chr(2, 16, ' '); } r = (double)(v1 - v2) / ((double)v2 / 10000); // ByteToStr(hygro_cnv(r), buf); Lcd_Out(1, 1, buf); LongToStr(r, buf); Lcd_Out(1, 8, &buf[3]); WordToStr(v1, buf); Lcd_Out(2, 1, &buf[1]); WordToStr(v2, buf); Lcd_Out(2, 9, buf); } } //**********************************************************************