チーム1466

課題名

通信式温度計

研究者名

2年14組48番 Yamashita Yuuki
2年14組49番 Yokoyama Masahiro

概要

温度センサLM35を用いて、温度を測定し、それをAD変換したものをLCDに表示する。
親機と子機を作成し、子機で測定した温度が親機のLCDに表示されるようにした。
親機では、温度の変化に合わせてモーターの回転数を変更するようにした。
温度変化に合わせて動作する扇風機として扱える。

使用機材

親機 : 温度センサ(LM35)× 1
    モーター × 1
    ジャンパ線(1本は子機との接続用)× 4

子機 : 温度センサ(LM35)× 1
    モーター × 1
    ジャンパ線 × 3

ブロック図

親機 :
parent.png

子機 :
child.png

ソースコード

親機 :

#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#include <stdlib.h>


void main(void)
{
  // M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts
   // Insert your main routine code here.
   
   unsigned int get_data;
   int i;
   char str_p[5];
   char temp_p[9];
   char *temp_c;
   
   PGA_1_Start(PGA_1_HIGHPOWER);
   PGA_2_Start(PGA_2_HIGHPOWER);
   LCD_Start();
   LCD_InitBG(LCD_SOLID_BG);
   RX8_CmdReset();
   RX8_EnableInt();
   M8C_EnableGInt;
   ADCINC_Start(ADCINC_HIGHPOWER);
   ADCINC_GetSamples(0);
   Counter8_Start();
   RX8_Start(RX8_PARITY_NONE);
   
   while(1) {
       while(ADCINC_fIsDataAvailable() == 0);
       get_data = ADCINC_wClearFlagGetData(); // 符号なし16ビット2進数(0 ~ 65535)

      // AD変換により入力アナログ電圧を0~4095に割り当てているため、実際の電圧とは異なる値となっている。
       // 元の電圧に近づけるため、5V / 4096 ~ 1.22mV倍する。
       get_data *= 1.22;
       
       // PGAのゲインの変更。温度が30℃以上ならゲインを大きい値、
    // 25℃以上30℃以上なら、中間の値、
    // 25℃未満なら、小さい値に設定。
      if(get_data >= 0b0000000100101100) {
           PGA_2_SetGain(PGA_2_G48_0);
       }
       else if (get_data >= 0b0000000011111010 && get_data < 0b0000000100101100) {
           PGA_2_SetGain(PGA_2_G2_67);
       }
       else {
           PGA_2_SetGain(PGA_2_G1_00);
       }
       
       // 16ビット2進数を10進数文字列に変換し、
    // 表示用の配列に、温度表示用に小数点と単位を加えながらコピー。
      itoa(str_p, get_data, 10); 
       temp_p[0] = str_p[0];
       temp_p[1] = str_p[1];
       temp_p[2] = '.';
       for(i = 2; i < 5; i++) {
         temp_p[i + 1] = str_p[i];
         if(temp_p[i + 1] == '\0') {
           temp_p[++i] = 'C';
           break;
         }
       }
       temp_p[++i] = '\0';

      // 子機から温度を表す文字列を受信
       if(RX8_bCmdCheck()) {
         if(temp_c = RX8_szGetParam()){ // temp_cに受信バッファから文字列を受け取る。

          // 文字列を受信したら、LCDに表示する。
           LCD_Init(); // 表示バグの防止策
           LCD_Position(1, 0);
           LCD_PrString(temp_c);
         }
         RX8_CmdReset(); // 受信バッファの初期化
       }

       // 親機で計測した温度をLCDに表示する。
        LCD_Position(0, 0);
        LCD_PrString(temp_p);
   }
}

子機 :

#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#include <stdlib.h>

void wait(int n) {
   while(n--);
}

void main(void)
{
  // M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts
   // Insert your main routine code here.
   
   unsigned int get_data;
   int i;
   char str[5];
   char temp[9];
   
   PGA_1_Start(PGA_1_HIGHPOWER);
   PGA_2_Start(PGA_2_HIGHPOWER);
   LCD_Start();
   LCD_InitBG(LCD_SOLID_BG);
   M8C_EnableGInt;
   ADCINC_Start(ADCINC_HIGHPOWER);
   ADCINC_GetSamples(0);
   Counter8_Start();
   TX8_Start(TX8_PARITY_NONE);
   
   while(1) {
   
       while(ADCINC_fIsDataAvailable() == 0);
       get_data = ADCINC_wClearFlagGetData(); //符号なし16ビット進数(0 ~ 65535)
       
       //AD変換により入力アナログ電圧を0 ~ 4095に割り当てているため、実際の電圧とは異なる値となっている。
       //元の電圧に近づけるため、5V / 4096 ~ 1.22mV倍する。
       get_data *= 1.22;
       
       //PGAのゲインの変更、温度が30度以上ならゲインを大きい値、
       // 25℃以上30℃以上なら、中間の値、
    // 25℃未満なら、小さい値に設定。
    // 子機では未使用
      if(get_data >= 0b0000000100101100){
       PGA_2_SetGain(PGA_2_G48_0);
       }
       else if(get_data >= 0b0000000011111010 && get_data < 0b0000000100101100){
       PGA_2_SetGain(PGA_2_G2_67);
       }
       else{
       PGA_2_SetGain(PGA_2_G1_00);
       }
   
      // 16ビット2進数を10進数文字列に変換し、    
      // 表示用の配列に、温度表示用に小数点と単位を加えながらコピー。
       itoa(str, get_data, 10);
       temp[0] = str[0];
       temp[1] = str[1];
       temp[2] = '.';
       for(i = 2; i < 5; i++) {
         temp[i + 1] = str[i];
         if(temp[i + 1] == '\0') {
           temp[++i] = 'C';
           break;
         }
       }
       temp[++i] = '\0';
       
       // 計測した温度をLCDに表示する。
       LCD_Position(0, 0);
       LCD_PrString(temp);
       
       // 文字列送信の終端文字
       temp[i] = '\r';
       // 親機に温度を表す文字列を送信
       TX8_PutString(temp);
       // 一定時間、送信の間隔をあける。
       wait(10000);
   }    
}

考察

 子機でもモーターの制御を行いたかったが、子機ではポーリングのループ中で、AD変換後のデータ処理と
モーター制御のためのPGAの設定、温度を表す文字列の送信を行っており、その中で文字列の送信時間の間隔を確保するため
wait関数を用いていることから、これによる待機時間のせいでモーターの回転と静止が目立つようになってしまい、
連続的な回転を実現できなかった。解決策としては、タイマー割り込みで文字列の送信を行い、AD変換後のデータ処理と
モーター制御のためのPGAの設定に対してのみポーリングを用いることを考える。これによって、ポーリング中に毎回
wait関数を実行する必要がなくなるため、連続的なモーターの回転が実現できるのではないかと予想する。
 親機と子機の通信を赤外線を用いてコードレスで行うことができれば、建物の離れた階など遠距離の2地点の温度の
比較が行えるのではないかと想像する。


  • 最終更新:2014-12-16 23:35:04

このWIKIを編集するにはパスワード入力が必要です

認証パスワード