チーム1466
課題名
通信式温度計
研究者名
2年14組48番 Yamashita Yuuki
2年14組49番 Yokoyama Masahiro
概要
温度センサLM35を用いて、温度を測定し、それをAD変換したものをLCDに表示する。
親機と子機を作成し、子機で測定した温度が親機のLCDに表示されるようにした。
親機では、温度の変化に合わせてモーターの回転数を変更するようにした。
温度変化に合わせて動作する扇風機として扱える。
使用機材
親機 : 温度センサ(LM35)× 1
モーター × 1
ジャンパ線(1本は子機との接続用)× 4
子機 : 温度センサ(LM35)× 1
モーター × 1
ジャンパ線 × 3
ブロック図
親機 :
子機 :
ソースコード
親機 :
#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