エアコンのリモコンをやってみる。

今年も猛暑になりそう。前からやってみようと思っていたエアコンのリモコンをやってみよう。
1時間おきに電源がOn/Offするくらいでもいいかなと思っている。調子に乗って温度センサもつけるかもしれない。

070818
連日のとんでもない猛暑も今日はやっと一息かな、明け方近くは冷えてくるので、エアコンのON,OFFのDutyを徐々に短くするといいみたい。

070727
ここのところ、寝苦しい日が続くので、連日、使う機会が出てきました。
クーラーには温度設定があるんですが、やはりつけっぱなしだと冷えすぎてしまうんで、時々、on/offするのは、なかなか調子が良いです。
妻にも好評です。

DSC02540-w320.jpg IRremocon1.gif
H8/3069Fボードと赤外線リモコン受信モジュールPL−IRM0101
回路は簡単
赤外線発光ダイオードは秋月の店頭販売では1個から売ってました。
h83069f のページに飛んでいく

070723
最終的なプログラムも載せておこう。
受信のほうは、かなり手を抜いていて、600個のエッジが来るまで止まらない。
スイッチを付けて、それを押すと受信が止まるようにすれば、良いかもしれない。
何回かリモコンを送信して、あとでデータの区切れを眼で見つけて、cooler._pon.hのような配列をエクセルやエディタで作ってみた。
送信のほうは30分おきにON/OFFを6回繰り返すようなものにしてみた。
まだ、1日使っただけですけど。
送受信を組み合わせれば、学習リモコンも出来そうですね。
あやっ、関東はなかなか梅雨があけませんけど。(*_*)
送信プログラム
#include <mes2.h>
#include <h8/reg3067.h>
#include "cooler_pon.h"
#include "cooler_poff.h"
//#include "tv_pon.h"

#define DUMMY (*(volatile unsigned char *)0x500000)
#define TCNT0_16 *(volatile unsigned short *)0xffff88

void irtrans(unsigned short *);

int main(){
PADR = 0x00;
PADDR = 0x44; // A6 ,A2 - outout

irtrans(&toff_value[0]);
sleep(10 * 1000);

irtrans(&ton_value[0]);
sleep(30 * 60 * 1000);
irtrans(&toff_value[0]);

sleep(30 * 60 * 1000);
irtrans(&ton_value[0]);
sleep(30 * 60 * 1000);
irtrans(&toff_value[0]);

sleep(30 * 60 * 1000);
irtrans(&ton_value[0]);
sleep(30 * 60 * 1000);
irtrans(&toff_value[0]);

sleep(30 * 60 * 1000);
irtrans(&ton_value[0]);
sleep(30 * 60 * 1000);
irtrans(&toff_value[0]);

sleep(30 * 60 * 1000);
irtrans(&ton_value[0]);
sleep(30 * 60 * 1000);
irtrans(&toff_value[0]);

sleep(30 * 60 * 1000);
irtrans(&ton_value[0]);
sleep(30 * 60 * 1000);
irtrans(&toff_value[0]);

}

void irtrans(unsigned short *t_value){
volatile unsigned char c;
char signal =0;
int_disable();

while(*t_value != 0){
TCR0_8 =0;
TCR1_8 =0;
TCNT0_16 = 0;
TCR0_8 =0x4;// clock is 8TCNT1 OverFlow
TCR1_8 =0x2;// clock / 64

if(signal ==0){
while(TCNT0_16 < *t_value){
/* IrLED On */
PADR =0x44;
c =DUMMY;
/* IrLED Off */
PADR =0x00;
char value =8;
while(--value >0){
c =DUMMY;
}
}

}else{
while(TCNT0_16 < *t_value){}
}
t_value++;
signal ^= 1;
}

/* IrLED Off */
PADR =0x00;
int_enable();

}

[cooler_pon.h] 送信プログラムに必要

static unsigned short ton_value[] ={
93,
49843,
99,
19451,
90,

189,
0
};
受信プログラム
リモコンのパルスの時間をprintfするだけのものです。

#include <mes2.h>
#include <h8/reg3067.h>

#define TCNT0_16 *(volatile unsigned short *)0xffff88
//#define DATASIZE 10
#define DATASIZE 600

void init_timer0(void);
int t_value[DATASIZE];

int main(){
int sdata;
int t =0;
char signal;
int_disable();
TCR0_8 =0;
TCR1_8 =0;
TCNT0_16 = 0;

while((P7DR & 0x80)!=0){}
TCR0_8 =0x4;// clock is 8TCNT1 OverFlow
TCR1_8 =0x2;// clock / 64
// TCR1_8 =0x3;// clock / 8192
signal =0;

while(t <DATASIZE){
/* Wait for signal go down */
if(signal ==1){
while((P7DR & 0x80)!=0){}
t_value[t++] =TCNT0_16;
signal =0;
TCR0_8 =0;
TCR1_8 =0;
TCNT0_16 = 0;
TCR0_8 =0x4;// clock is 8TCNT1 OverFlow
TCR1_8 =0x2;// clock / 64
// TCR1_8 =0x3;// clock / 8192
}else{
/* Wait for signal go up */
while((P7DR & 0x80)==0){}
t_value[t++] =TCNT0_16;
signal =1;
TCR0_8 =0;
TCR1_8 =0;
TCNT0_16 = 0;
TCR0_8 =0x4;// clock is 8TCNT1 OverFlow
TCR1_8 =0x2;// clock / 64
// TCR1_8 =0x3;// clock / 8192
}
}
int_enable();
printf("t =%d\r",t);
t =0;
signal =0;
while(t <DATASIZE){
printf("%d,\r",t_value[t++]);
// printf("%d ,%d\r",signal,t_value[t++]);
// printf("%d ,%d\r",signal^1,0);
signal ^= 1;
}

}

void init_timer0(void){
TCR0_8 =0;
TCR1_8 =0;
TCNT0_16 = 0;
}


070716
赤外線LEDの点滅は、デジカメで確認できた。
なかなかエアコンが反応しないので、難航していたが、どうもリモコンのパルス幅の測定でタイマーがオーバーフローしていた模様。
16ビットタイマーはもっとも遅いクロックで原発振25MHzの8分周なので、16ビットタイマーでも20mSほどでオーバーフローしてしまうようだ。
何とかならないか考えたところ、8ビットタイマーは原発振25MHzの64もしくは8192分周も選べるようなので、これとさらに8ビットタイマーの0,1をカスケードに接続して、64/25*65536/1000 (ms)=167msまでの計測時間にして、ようやく、エアコンのON/OFFができるようになった。
赤外線LEDは、赤外光の放射角度が狭いので、ねらいをつけないと上手く動作しないのも辛いところ。
TVのON/OFFも試してみたが、こちらも上手くいった。


070712
こんな回路にしてます。

070710
いよいよ送信部を作ってみる。送信のプログラムを作ってみた。
38KHzのキャリアは、赤外線LEDを1/10のDUTYでONすることにした。
電気的には、このDUTYで100mAまで流せる。
ただし、何かの間違いでONしっぱなしになるとLEDが破損してしまう。
PA6端子を出力にして実測で合わせこんだ。37KHzでON時間は2.4μSほどになった。
H8のDRAMのアクセスサイクルの設定によっては、上手くキャリアの周波数が出ないかもしれない。
LEDの回路の組み立ては、来週頭かな?
#include <mes2.h>
#include <h8/reg3067.h>
#include "test.h"

#define DUMMY (*(volatile unsigned char *)0x500000)
void m_loop(int);
void init_timer0(void);

int main(){
PADR = 0x00;
PADDR = 0x40; // A6 - outout
int t =0;
char signal =0;
int_disable();
init_timer0();
TSTR = 0;
TCNT0 =0;
TSTR = 1;

while(t_value[t] != 0){
if(signal ==0){
while(TCNT0 < t_value[t]){
volatile unsigned char c;
/* IrLED On */
PADR =0x40;
c =DUMMY;
/* IrLED Off */
PADR =0x00;
char value =8;
while(--value >0){
c =DUMMY;
}
}

}else{
while(TCNT0 < t_value[t]){}
}
TSTR = 0;
TCNT0 =0;
TSTR = 1;
t++;
signal ^= 1;
}

/* IrLED Off */
PADR =0x00;
int_enable();

}

void init_timer0(void){
TSTR = 0;
TCR0 = 3;// CLK/8 320nS
}

[test.h]

static unsigned short t_value[] ={
48864,
485,
28563,
10817,
5055,
1506,
3732,
1508,
1102,
1491,
1173,
1425,
1170,
1427,
1170,


17594,
393,
19830,
410,
0
};


070702
H8/3069Fボードで取得したデータをExcelで処理。エアコンの「電源」スイッチを押したときの、モジュールの出力の様子を波形にしてみた。
これが結構なデータ量で270パルスほどもある。エアコンなので、コードを複雑にしているのだろうか?
Pon_code.gif

#include <mes2.h>
#include <h8/reg3067.h>

#define DATASIZE 1000
void init_timer0(void);
int t_value[DATASIZE];

int main(){
int sdata;
int t =0;
char signal =1;
int_disable();
init_timer0();
TSTR = 0;
TCNT0 =0;
TSTR = 1;

while(t <DATASIZE){
/* Wait for signal go down */
if(signal ==1){
while((P7DR & 0x80)>0){}
t_value[t++] =TCNT0;
signal =0;
TSTR = 0;
TCNT0 =0;
TSTR = 1;
}else{
/* Wait for signal go up */
while((P7DR & 0x80)==0){}
t_value[t++] =TCNT0;
signal =1;
TSTR = 0;
TCNT0 =0;
TSTR = 1;
}
}
int_enable();
t =0;
signal =1;
while(t <DATASIZE){
printf("%d ,%d\r",signal,t_value[t++]);
printf("%d ,%d\r",signal^1,0);
signal ^= 1;
}

}

void init_timer0(void){
TSTR = 0;
TCR0 =3;// CLK/8 312.5nS
}


070701
H8 Timer0をカウンタとして、起動するテストをしたが、ときどきデータがふらつく。
20回に一回程度、20μSほど処理がもたつくようだが、そんなに複雑な分岐はないのだが。。。
それでも、今回の計測では何とかなりそう。
#include <mes2.h>
#include <h8/reg3067.h>

void init_timer0(void);
void restart_timer0(void);
unsigned short read_timeconstant0(void);
int t_value[100];

int main(){
int sdata;
char t =0;
int_disable();
init_timer0();
restart_timer0();

while(t <100){
t_value[t++] =TCNT0;
TSTR = 0;
TCNT0 =0;
TSTR = 1;
// restart_timer0();
}
int_enable();
t =0;
while(t <100){
printf("%d\r",t_value[t++]);
}

}

void init_timer0(void){
TSTR = 0;
TCR0 =3;// CLK/8 320nS
}

void restart_timer0(void){
TSTR = 0;
TCNT0 =0;
TSTR = 1;
}

unsigned short read_timeconstant0(void){
return TCNT0;
}

070630
とりあえず、秋月電子で赤外線リモコン受信モジュールと赤外発光ダイオードを買ってきた。
今日は、センサをつけて、少しプログラムから読んでみた。
矢印が赤外線リモコン受信モジュール
モジュールの出力信号をH8/3069のP77につないでみた。
DSC02540-w320.jpg
#include <mes2.h>
#include <h8/reg3067.h>

int main(){
int sdata;
while(1){
sdata =(P7DR & 0x80) >> 7;
printf("%d",sdata);
}

}
現在、1/0の変化がプログラムで読めたところ。
成松さんのページを見て勉強中。

h83069f のページに飛んでいく v(^o^)