Infrared Rays library
See http://developer.mbed.org/users/yasuyuki/notebook/IRmbed/
IR.cpp
- Committer:
- yasuyuki
- Date:
- 2015-09-25
- Revision:
- 1:71ca050c4d05
- Parent:
- 0:c74b212c3cbf
File content as of revision 1:71ca050c4d05:
//**********************
// IR.cpp for mbed
//
// IR ir(P0_12);
//
// (1)NEC format
// IR carrier=38KHz
// Time unit=0.56ms
// logical 0 = on 1T + off 1T
// logical 1 = on 1T + off 3T
// reader=on 16T + off 8T
// stop=on 1T
// frame=108ms
//
// (2)AEHA format
// IR carrier=33 - 40KHz
// Time unit=0.35 - 0.50ms
// logical 0 = on 1T + off 1T
// logical 1 = on 1T + off 3T
// reader=on 8T + off 4T
// trailer=on 1T + 8ms
//
// (3)SONY format
// IR carrier=40KHz
// Time unit=0.6ms
// logical 0 = off 1T + on 1T
// logical 1 = off 1T + on 2T
// reader=on 4T
// frame=45ms
//
// caution:
// no detecting repeat code, return bits=0;
//
// (C)Copyright 2014-2015 All rights reserved by Y.Onodera
// http://einstlab.web.fc2.com
//**********************
#include "mbed.h"
#include "IR.h"
IR::IR (PinName irin, PinName irout) : _irin(irin),_irout(irout){
init();
}
void IR::init()
{
_irin.mode(PullUp);
_irout=0;
}
unsigned char IR::countHigh(){
unsigned char i=0;
while(_irin==1); // wait
while(_irin==0){
++i;
wait_us(26);
wait_us(26);
if(i==0) return 0; // timeout
}
// NEC:i=19*8=152, i*2*26.5us=8056us
// AEHA:i=19*4=76, i*2*26.5us=4028us
// 1T:i=19*1=19
return i;
}
unsigned char IR::countLow(){
unsigned char i=0;
while(_irin==0); // wait
while(_irin==1){
++i;
wait_us(26);
if(i==0) return 0; // timeout
}
// NEC:i=19*8=152, i*26.5us=4028us
// AEHA:i=19*4=76, i*26.5us=2014us
// 1T:i=19*1=19
// 3T:i=19*3=57
return i;
}
void IR::getIR2(){
unsigned char i;
unsigned short j; // capable 32768 bits = 4096 bytes
unsigned char k;
bits=0;
for(j=0;j<IR_LIMITS;j++){ // buffer bytes LIMITS
for(i=0;i<8;i++){ // 8 bits
k = countHigh()*2;
if(mode==3){
buf[j]>>=1;
// Threschold = 35, 23 = 1T, 46 = 2T; for SONY
buf[j]+=((k>30) ? 0x80: 0);
++bits;
}
k = countLow();
if(k==0){
buf[j]>>=(8-i);
return;
}
if(mode!=3){
buf[j]>>=1;
// Threschold = 38, 19 = 1T, 57 = 3T; for NEC
// Threschold = 30, 15 = 1T, 45 = 3T; for AEHA
buf[j]+=((k>30) ? 0x80: 0);
++bits;
}
}
}
}
void IR::getIR(){
unsigned char i;
i = countHigh(); // Start
mode=0;
if(40<i){
if(i<51){
mode=3; // SONY, 46
}else{
if(100<i){
mode=1; // NEC, 173
}else{
mode=2; // AEHA, 54-77
}
}
i = countLow();
getIR2();
}
}
// out ON with 38KHz
void IR::outON(char n, char t)
{
unsigned char i,j;
for(j=0;j<t;j++){
for(i=0;i<n;i++){
// 38KHz, 1/3duty
_irout=1; // LED ON=8.6ms
wait_us(6);
_irout=0; // LED OFF=17.4ms
wait_us(15);
}
}
}
// out OFF without 38KHz
void IR::outOFF(char n, char t)
{
unsigned char i,j;
for(j=0;j<t;j++){
for(i=0;i<n;i++){
// 38KHz, 1/3duty
_irout=0; // LED OFF
wait_us(6);
_irout=0; // LED OFF
wait_us(15);
}
}
}
void IR::setIR()
{
unsigned char j,t;
unsigned short i,n;
if(bits==0)return; // no data
// reader
switch(mode){
case 1:
if(bits!=32)return;
outON(NEC,16); // ON(16T)
outOFF(NEC,8); // OFF(8T)
t=16+8;
break;
case 2:
if(bits>IR_LIMITS*8)return;
outON(AEHA,8); // ON(8T)
outOFF(AEHA,4); // OFF(4T)
t=8+4;
break;
case 3:
if(!(bits==12 || bits==15 || bits==20))return;
outON(SONY,4); // ON(4T)
t=4;
break;
}
// data
switch(mode){
case 1:
for(i=0;i<4;i++){
for(j=0;j<8;j++){
if(buf[i] & (0x1<<j)){
outON(NEC,1); // ON(1T)
outOFF(NEC,3); // OFF(3T)
t+=4;
}else{
outON(NEC,1); // ON(1T)
outOFF(NEC,1); // OFF(1T)
t+=2;
}
}
}
break;
case 2:
i=0;
n=0;
do{
for(j=0;j<8;j++){
if(buf[i] & (0x1<<j)){
outON(AEHA,1); // ON(1T)
outOFF(AEHA,3); // OFF(3T)
t+=4;
}else{
outON(AEHA,1); // ON(1T)
outOFF(AEHA,1); // OFF(1T)
t+=2;
}
if(++n == bits)break;
}
++i;
}while(n < bits && i<IR_LIMITS);
break;
case 3:
i=0;
n=0;
do{
for(j=0;j<8;j++){
if(buf[i] & (0x1<<j)){
outOFF(SONY,1); // OFF(1T)
outON(SONY,2); // ON(2T)
t+=3;
}else{
outOFF(SONY,1); // OFF(1T)
outON(SONY,1); // ON(1T)
t+=2;
}
if(++n == bits)break;
}
++i;
}while(n < bits && i<IR_LIMITS);
break;
}
// stop
switch(mode){
case 1:
t=192-t;
outON(NEC,1); // ON(1T)
outOFF(NEC,t); // frame=108ms=192T
break;
case 2:
outON(AEHA,1); // ON(1T)
outOFF(AEHA,16); // 8ms=16T
break;
case 3:
t=75-t;
outOFF(SONY,t); // frame=45ms=75T
break;
}
}