I need to recognize a signal from an IR remote, not to use a library for working with IR remotes/receivers. How can when the button is clicked to display its name. I have PIC12F615 microcontroller with this code: code and 5 buttons connected to him and I need recognise which button pressed. I have some code but it gives different hex codes if I pressed the same button.
Keep it simple and stupid firstly.
Run some tutorials for the hardware selected.
Develop a program that "recognizes" three buttons pressed on the IR remote and outputs their names to the serial port without libraries.
will this code work correctly:
#define IR_PIN 2
volatile unsigned int pulsewidth = 0;
volatile unsigned long int pulsevalue = 0;
volatile boolean received = false;
volatile unsigned long int bitstream = 0;
void setup() {
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(IR_PIN), handleIR, CHANGE);
}
void loop() {
if (received) {
decodeIR();
received = false;
}
}
void handleIR() {
static unsigned long int lasttime = 0;
static unsigned int timer = 0;
unsigned long int thistime = micros();
pulsewidth = thistime - lasttime;
lasttime = thistime;
if (pulsewidth >= 10000 && pulsewidth <= 11000) {
pulsevalue = 0;
timer = 0;
} else if (pulsewidth >= 2000 && pulsewidth <= 3000) {
pulsevalue = pulsevalue << 1;
pulsevalue |= (timer > 12) ? 1 : 0;
timer = 0;
} else if (pulsewidth >= 300 && pulsewidth <= 600) {
timer++;
} else if (pulsewidth >= 1500 && pulsewidth <= 1800) {
received = true;
}
}
void decodeIR() {
unsigned long int address = (bitstream >> 16) & 0xFFFF;
unsigned long int command = bitstream & 0xFFFF;
if ((address ^ command) == 0xFFFF) {
switch (command) {
case 0x00FF6897: Serial.println("Button 1 pressed"); break;
case 0x00FF9867: Serial.println("Button 2 pressed"); break;
case 0x00FFB04F: Serial.println("Button 3 pressed"); break;
case 0x00FF30CF: Serial.println("Button 4 pressed"); break;
case 0x00FF18E7: Serial.println("Button 5 pressed"); break;
default: break;
}
}
bitstream = 0;
}
Schema:
by such long pulses can be used simple digitalRead() and/or pulseIn()
Take a view into the libary how the signal is decoded.
which library?
I need to recognize a signal from an IR remote, not to use a library for working with IR remotes/receivers. When I press the button, it outputs endless zeros.
code:
volatile uint8_t inputCaptureData[32];
volatile uint8_t isFirstTriggerOccured = 0; //First Trigger Flag
volatile uint8_t receiveCounter = 0; //Receiver Counter
volatile uint8_t receiveComplete = 0; //Receive Complete Flag
int IR_PIN = 2;
void handleIR() {
uint32_t currentMicros = micros();
if (isFirstTriggerOccured) { //Capturing will start after first falling edge detected by ICP1 Pin
inputCaptureData[receiveCounter] = (currentMicros - inputCaptureData[receiveCounter-1]); //Calculate the time period between the falling edges
if (inputCaptureData[receiveCounter] > 2500) { // if the value is greater than 2500us (~2.5ms), then
receiveCounter = 0; //reset "receiveCounter"
receiveComplete = 0; //reset "receiveComplete"
} else {
receiveCounter++;
if (receiveCounter == 32) { //if all the bits are detected,
receiveComplete = 1; //then set the "receiveComplete" flag to "1"
}
}
} else {
isFirstTriggerOccured = 1; //First falling edge occured! Start capturing from the second falling edge.
}
}
void setup() {
Serial.begin(9600);
pinMode(IR_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(IR_PIN), handleIR, CHANGE);
}
void loop() {
if (receiveComplete) { //If receive complete, start decoding process
uint32_t receiveStream = 0; //To store decoded value
for (int i = 0; i < 32; i++) { //Decode all 32 bits receive as time periods
if (inputCaptureData[i] < 1300 && inputCaptureData[i] > 1000 && i != 31) { //if the time period t* -> 1.0ms < t < 1.3ms
receiveStream = (receiveStream << 1); //Only bit shift the current value
} else if (inputCaptureData[i] < 2500 && inputCaptureData[i] > 2000) { //if the time period t* -> 2.0ms < t < 2.5ms
receiveStream |= 0x0001; //increment value by 1 using Logic OR operation
if (i != 31) { //Only shift the bit unless it is the last bit of the captured stream
receiveStream = (receiveStream << 1); //Only bit shift the current value
}
receiveComplete = 0; //Set the receive complete to 0 for next data to be captured
}
}
Serial.println(receiveStream, HEX); //Print the value in serial monitor for debugging
}
}
Schema:
Check your IRL1 wiring. A circuit requires 2 wires.
i think there are even 3 wires. he use DS1838 decoder or similar
I need to recognize a signal from an IR remote, not to use a library for working with IR remotes/receivers. If I pressed the same button irCode change, why.
code:
byte IRpin = 2;
volatile boolean remote = false;
volatile unsigned long irCode = 0;
void remoting ()
{
if ( remote )
{
remote = false;
unsigned long T;
for ( byte n = 0; n < 32; n ++ )
{
do
{
T = pulseIn ( IRpin, HIGH, 2200 );
}
while ( T < 64 );
bitWrite ( irCode, n, T > 1120 );
}
}
}
void setup ()
{
Serial.begin ( 9600 );
Serial.println ( "\n\tReady for keyboard reading!\n" );
pinMode ( IRpin, INPUT_PULLUP );
attachInterrupt ( digitalPinToInterrupt ( IRpin ), remoting, FALLING );
}
void loop ()
{
if (irCode)
{
Serial.println (irCode, HEX);
irCode = 0;
}
delay (40);
remote = true;
}
what you think it should do? in ISR handler?
It ensures that the pulse duration is at least 64 microseconds before proceeding to decode the signal.
How?
Inside the decoding loop, the code waits until it detects a high signal on IRpin
using the pulseIn()
function. The pulseIn()
function measures the duration of a pulse in microseconds. It waits until the pin goes high, times the pulse duration, and returns the result. Once a high signal is detected, the code waits until the signal goes low again, indicating the end of the pulse.
Yes, but why in an ISR?
Why an ISR at all?
why not, so, why does irCode
change when I click the same button
Because time wasted blocking in an ISR affects other processes, usually adversely.
and because of that irCode
change when I click the same button?
if interrupt is happen - everything stops. Commands in ISR doing simple things just like X-Men Quicksilver. no comunication, no timer/millis/micros/pulseIn, no interrupts.