前回の信号解析で得られた「Tの値」、「リーダー信号の長さ」、「16進数の値」を得たので、それを送信する関数を作って行きたいと思います。
#送信までの流れ
- まず16進数から2進数へと変換する。
- 次にその値に応じてON時間とOFF時間を導出し、その先頭にリーダー信号をつける。
- その時間に沿ってLEDを光らせる。
16進数から2進数へと変換
意外と難しかった。。。もっと良い方法があるかもしれないがこれでうまく動いたため採用
- 16進数の1文字ごと取り出し、2進数へ変換
- それぞれをくっつける
- 先頭bitから精査し"1"が出てくるまで消去、その"1"も消去
- 完成!!
#ON,OFF時間の導出とリーダー信号の付与
ここは解析の逆をすればいいので省略
#導出された時間に沿ってLEDを光らせる
Arduinoで赤外線リモコン信号を発信するを参考に作りましたが、信号の周期は1/(38k) = 26usとなり、ON時間中はずっと光らせるわけではなく、約33%だけ光らせるので、8.7us光らせることで送信可能です。
#送信用の関数
sendSignal
#define IRSEND_PIN 13
int last = 0;
unsigned long us = micros();
int base_time = 45; //前回求めたT
int leader_usec_on = base_time*8; //前回求めたリーダーのON時間
int leader_usec_off = base_time*4; //前回求めたリーダーのOFF時間
int data[200];
void sendSignal(String hexSignal){ //16進数の信号を受け取る
initializeSignal();
Serial.println(hexSignal);
generateSignal(hexSignal);
int dataSize = arraySize();
for (int cnt=0; cnt<dataSize; cnt++){
Serial.print(data[cnt]);
Serial.print(",");
unsigned long len = data[cnt]*10; // 10us単位で
us = micros();
do{
digitalWrite(IRSEND_PIN, 1-(cnt&1)); // cnt偶数:ON, 奇数:OFFのまま
delayMicroseconds(8.8); // 38kHz
digitalWrite(IRSEND_PIN, 0);
delayMicroseconds(17.5);
}while( long(us+len-micros()) > 0);
}
Serial.println();
}
void initializeSignal(){
for (int i=0; i<sizeof(data)/sizeof(data[0]); i++){
data[i] = 0;
}
}
int arraySize(){
int size = 0;
while(data[size] != 0) {
size++;
}
return size;
}
void generateSignal(String hexSignal){
String binSignal = hexToBin(hexSignal);
data[0] = leader_usec_on;
data[1] = leader_usec_off;
int j = 2;
for(int i = 0; i < binSignal.length(); i++){
data[j] = base_time;
data[j+1] = (int(binSignal[i]) == 48/*0*/) ? base_time : base_time*3;
j+=2;
}
}
String hexToBin(String hexSignal){
String binSignal;
int dec;
char c_hex;
for (int i = 0; i < hexSignal.length(); i++){
c_hex = hexSignal[i];
dec = (c_hex >= '0' && c_hex <= '9') ? (c_hex - '0') : (tolower(c_hex)-'a'+10);
binSignal += decToBin(dec);
}
binSignal = deleteBit(binSignal);
return binSignal;
}
String decToBin(int dec){
String bin;
int pad_num = 0;
for (int i = 0; dec > 0; i++){
bin = String(dec % 2) + bin;
dec /= 2;
}
pad_num = 4-bin.length();
for (int i = 0; i < pad_num; i++){
bin = "0" + bin;
}
return bin;
}
String deleteBit(String binStr){
while (binStr[0] == '0'){
binStr = binStr.substring(1,binStr.length());
}
binStr = binStr.substring(1,binStr.length());
return binStr;
}
#次に
次回は回路とESPr_Developerを使うための設定についてです。