IR.cpp
/*
* IR.cpp
*
* Created on: 11.08.2017
* Author: Wolle
* Updated on: 04.07.2022
*----------------------------------------------------------------
* Changed for use with datalink: Kurt Nielsen kurtn.nypost@hotmail.dk
*/
#include "IR.h"
// global var
DRAM_ATTR int8_t ir_resp; // set from isr
IR::IR(uint8_t IR_PIN){
ir_pin=IR_PIN;
ir_result=0;
ir_resp=(-1);
t0=0;
//log_i("init");
}
IR::~IR(){
}
void IR::begin(){
if(ir_pin >= 0){
pinMode(ir_pin, INPUT);
attachInterrupt(ir_pin, isr_IR, CHANGE); // Interrupts will be handle by isr_IR
}
}
void IRAM_ATTR IR::setIRresult(uint8_t result){
ir_resp=result;
}
void IR::loop(){
// transform raw data from IR to ir_result
if(f_entry == false){t0 = millis(); f_entry = true;}
if((t0 + 49 > millis()) && (t0 <= millis()))
return; // wait 50ms (not if millis overflow)
f_entry = false;
// entry every 50ms in this routine
if(downcount)
downcount--;
// 1.5 sec countdown
else{
if(f_send){
if(ir_res) ir_res(ir_num);
//log_i("ir_res %i", ir_num);
idx = 0;
ir_num = 0;
f_send =false;
}
}
if(tmp_resp == ir_resp) return; // new value from IR?
tmp_resp = ir_resp;
ir_resp =
(-1);
// yes, set ir_resp to default
if(tmp_resp
>=
10){
// it is a function key in ir_result
switch(tmp_resp){
case 10: ir_resultstr[0] = 'k'; break; //OK
case 11: ir_resultstr[0] = 'u'; break; //up
case 12: ir_resultstr[0] = 'd'; break; //down
case 13: ir_resultstr[0] = 'r'; break; //up volume
case 14: ir_resultstr[0] = 'l'; break; //down volume
case 15: ir_resultstr[0] = '#'; break; //mute
case 16: ir_resultstr[0] = '*'; break; //toogle RADIO / SLEEP
}
ir_resultstr[1] = 0;
if(ir_key) ir_key(ir_resultstr);
//log_i("ir_key %s", ir_resultstr);
downcount = 0;
ir_num = 0;
f_send=false;
tmp_resp = -1;
return;
}
if(tmp_resp > (-1)){ // it is a number key in ir_result, can be 0...9
if(idx < 3){
ir_resultstr[idx] = tmp_resp + 48; // convert in ASCII
idx++;
ir_resultstr[idx] =
0;
// terminate
if(ir_number) ir_number(ir_resultstr);
//log_i("ir_number %s", ir_resultstr);
ir_num = ir_num * 10 + tmp_resp;
f_send = true;
downcount =
30;
// await nex tmp_resp
tmp_resp = -1;
}
}
}
//**************************************************************************************************
//
I S R _ I
R
*
//**************************************************************************************************
//
Interrupts received from VS1838B on every change of the
signal.
*
// Intervals are 640 or 1640 microseconds for data.
syncpulses are 3400 micros or
longer. *
// Input
is complete after 65 level
changes.
*
// Only the last 32 level changes are
significant.
*
//**************************************************************************************************
void IRAM_ATTR isr_IR()
{
extern IR ir;
int8_t ir_resp=(-1);
uint16_t
address=0;
// The first 4 bytes of IR code
uint16_t
command=0;
// The last 4 bytes of IR code
uint32_t t1,
intval;
// Current time and interval since last change
static uint8_t
levelcounter=0;
// Counts the level changes
static uint8_t
pulsecounter=0;
// Counts the pulse
static uint32_t
t0=0;
// To get the interval
static uint32_t
ir_value=0;
// IR code
static boolean ir_begin=false; // set if HIGH/LOW change
static boolean last = 1;
static int i = 0;
t1=micros();
// Get current time
intval=t1 -
t0;
// Compute interval
t0=t1;
// Save for next compare
if(intval > 50000)//&&(intval <= 5500)) // begin sequence of code?
{
pulsecounter=0;
// Reset counter
ir_value=0;
last = 1;
levelcounter=0;
ir_begin=true;
return;
}
/*if(ir_begin==false) return;
levelcounter++;
if(levelcounter%2==1)return;*/
// only falling edge can pass
if ((pulsecounter == 8) && ir_begin)
{
ir_begin=false;
ir_resp=(-1);
pulsecounter = 0;
//Serial.println(ir_value);
address=255;//(ir_value&0xFFFF0000)>>16;
command=ir_value;(ir_value&0x0000FFFF);
ir_value = 0;
if(address==0x00FF){
switch(command){
case 126: ir_resp=0; break; //ZERO
case 124: ir_resp=1; break; //ONE
case 122: ir_resp=2; break; //TWO
case 120: ir_resp=3; break; //THREE
case 118: ir_resp=4; break; //FOUR
case 116 : ir_resp=5; break; //FIVE
case 114: ir_resp=6; break; //SIX
case 112 : ir_resp=7; break; //SEVEN
case 110: ir_resp=8; break; //EIGHT
case 108: ir_resp=9; break; //NINE
case 44: ir_resp=10; break; //OK
case
78: ir_resp=10; break; //OK
case 106: ir_resp=11; break; //UP
case 102: ir_resp=11; break; //UP
case 12: ir_resp=12; break; //DOWN
case 76: ir_resp=12; break; //DOWN
//case 44: ir_resp=13; break; //RIGHT
//case 46: ir_resp=14; break; //LEFT
//case 74: ir_resp=15; break; //HASH
//case 50: ir_resp=15; break; //HASH
case 80: ir_resp=16; break; //STAR
case 46: ir_resp=16; break; //STAR
default: ir_resp=(-1);
}
if(ir_resp>(-1))ir.setIRresult(ir_resp);
}
}
if (intval < 20000)
{
if((intval > 2600) && (intval < 3600))
{
if (last == 0)
{
ir_value=(ir_value << 1) +
1;
// Shift in a "one" bit
pulsecounter = pulsecounter +
1; // Count number of
received bits
last = 1;
}
else
{
ir_value=(ir_value << 1) + 0;
pulsecounter = pulsecounter + 1;
last = 0;
}
}
if ((intval > 5700) && (intval < 6700))
{
if (last == 0)
{
ir_value=(ir_value << 1) +
1;
// Shift in a "one" bit
ir_value=(ir_value << 1) + 1;
pulsecounter = pulsecounter +
2;
// Count number of received bits
last = 1;
}
else
{
ir_value=(ir_value << 1) + 0;
ir_value=(ir_value << 1) + 0;
pulsecounter = pulsecounter + 2;
last = 0;
}
}
if ((intval > 8800) && (intval < 9800))
{
if (last == 0)
{
for (i = 1; i < 4; i++)
ir_value=(ir_value << 1) +
1;
// Shift in a "one" bit
pulsecounter = pulsecounter +
3;
// Count number of received bits
last = 1;
}
else
{
for (i = 1; i < 4; i++)
ir_value=(ir_value << 1) + 0;
pulsecounter = pulsecounter + 3;
last = 0;
}
}
if ((intval > 11900) && (intval < 12900))
{
if (last == 0)
{
for (i = 1; i < 5; i++)
ir_value=(ir_value << 1) +
1;
// Shift in a "one" bit
pulsecounter = pulsecounter +
4;
// Count number of received bits
last = 1;
}
else
{
for (i = 1; i < 5; i++)
ir_value=(ir_value << 1) + 0;
pulsecounter = pulsecounter + 4;
last = 0;
}
}
if ((intval > 15000) && (intval < 16000))
{
if (last == 0)
{
for (i = 1; i < 6; i++)
ir_value=(ir_value << 1) +
1;
// Shift in a "one" bit
pulsecounter = pulsecounter +
5;
// Count number of received bits
last = 1;
}
else
{
for (i = 1; i < 6; i++)
ir_value=(ir_value << 1) + 0;
pulsecounter = pulsecounter + 5;
last = 0;
}
}
if ((intval > 18100) && (intval < 19100))
{
if (last == 0)
{
for (i = 1; i < 7; i++)
ir_value=(ir_value << 1) +
1;
// Shift in a "one" bit
pulsecounter = pulsecounter +
6;
// Count number of received bits
last = 1;
}
else
{
for (i = 1; i < 7; i++)
ir_value=(ir_value << 1) + 0;
pulsecounter = pulsecounter + 6;
last = 0;
}
}
}
//Serial.println(pulsecounter);
}
Bemærk:
dette er ekspermentel software der er ingen garanti for brugbarhed, det
kan derimod sandsynligvis være skadeligt, kun til brug i Danmark.