ir remote does not work with >3 buttons

Hi all. I got a problem with a project i am working with , a meteo station with lots of functions. But i ran into a trouble, and i cannot understand it. I will write here the entire code even if just some lines are importatn for my trouble but i guess all of code is required for mistake hunting :smiley:
The project is not finished yet, and some instructions may be just for prototyping, such as printing on lcd some variables not intended in final product, but needed for debugging.
The problem i got is that i got an ir remote which works very fine.
But in my code, i got mainly 5 buttons on digital inputs. All of them work properly with physical buttons.
But when i use also the remote for same purposes, it only recognises 4 of them. WHY?
i mean , b1, b2...b5 are working fine when i press the actual switch butons, and also when i press keys on my remote. But b5 is not responding, the value of it remains 0. I dont get it why. can anyone give me some clues?
I apreciate your help.

#include <Wire.h>
#include "i2c.h"
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#include<math.h.>
#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

#define DHTTYPE DHT11
#define DHTPIN 19
uint32_t delayMS;

#include <IRremote.h>
int RECV_PIN = 43;
IRrecv irrecv(RECV_PIN);
decode_results results;
//speaker pin 7 pwm
#include "i2c_BMP280.h"
BMP280 bmp280;
DHT_Unified dht(DHTPIN, DHTTYPE);
int modeflag=0;
int b1=0; //31 , not used as variable!
int b2=0; //33
int b3=0; //35
int b4=0; //37
int b5=0; //39
int sound=0;
int led1=0;
int led2=0;
int led3=0;
int led4=0;
int lcdflag0=0;
int lcdflag1=0;
int lcdflag2=0;
int lcdflag3=0;
int lcdflag4=0;

float battery=0;
int ohmeter=0;
int magnetic=0;
int timeralarm=0;
float voltmeter=0;
float rxtemp=0;
int rxdistance=0;
int rxmessage=0;
int customhz=0;
int timedalarm=0;
int ceas=0;
int r1=0;
int r2=0;
int r3=0;
int r4=0;
int c1=0;
int c2=0;
int mastersound=1;
void alarm_clock(int timedalarm) //alarma **************
{int i;
if(mastersound==1)
for(i=0;i<=10;i++)
{analogWrite(6, 20);
delay(1);
analogWrite( 6, 0);
delay(1);
}
delay(20);
}
void clock_tick() // ceas*************************
{int i;
if(mastersound==1)
for(i=0;i<=1;i++)
{analogWrite(6, 2);
delay(2);
analogWrite(6, 3);
delay(1);
analogWrite(6, 2);
delay(1);
analogWrite( 6,0);
delay(2);
}

delay(980/ceas);

}

void freq_gen() //frecventa *****************
{if(customhz>100)
if(mastersound==1)
{analogWrite(6, 18);
delay(1000/customhz);
analogWrite( 6, 5);
delay(1000/customhz);
}
else
analogWrite(6, 0);
}

void setup()
{ lcd.begin(20, 4);
dht.begin();
bmp280.initialize();
sensor_t sensor;
dht.humidity().getSensor(&sensor);
bmp280.setEnabled(0);
bmp280.triggerMeasurement();
delayMS = sensor.min_delay / 1000;
irrecv.enableIRIn();
randomSeed(analogRead(0));

}

unsigned long int buton=0x00000000;

void loop() //************************************************************
{ if(irrecv.decode(&results))
irrecv.resume();
buton=results.value;
if(buton == 0x39B909D9)
{modeflag++;
delay(300);

}

if(results.value == 0x2A6B6F3D)
{
b2++;
delay(300);

}
if(results.value == 0xDFE68592 )
{b3++;
delay(300);

}
if(results.value == 0x9BD7F3D0 )
{b4++;
delay(300);
}

if(results.value == 0x01C62B02 )
{
b5++;
delay(300);

}
if(digitalRead(31) == HIGH)
{modeflag++;
delay(300);
}
if(digitalRead(33) == HIGH)
{b2++;
delay(300);
}
if(digitalRead(34) == HIGH)
{b3++;
delay(300);
}
if(digitalRead(37) == HIGH)
{b4++;
delay(300);
}
if(digitalRead(39) == HIGH)
{b5++;
delay(300);
}
if(b5%2==1)
mastersound=0;
else
mastersound=1;

if(modeflag%5==0)
{ lcdflag1=0;
lcdflag2=0;
lcdflag3=0;
lcdflag4=0;
if(lcdflag0==0)
lcd.clear();
lcdflag0++;

sensors_event_t event;
dht.humidity().getEvent(&event);
bmp280.awaitMeasurement();
float temperature;
bmp280.getTemperature(temperature);
float pascal;
bmp280.getPressure(pascal);
bmp280.triggerMeasurement();
lcd.setCursor(0,0);
lcd.print("1. Weather station");
lcd.setCursor(0, 1);
lcd.print("Pressure ");
lcd.setCursor( 13, 1);
lcd.print(pascal*0.00748);
lcd.setCursor( 18, 1);
lcd.print("mm");
lcd.setCursor(0, 2);
lcd.print("Temperature");
lcd.setCursor(13, 2);
lcd.print(temperature-2);
lcd.setCursor(18, 2);
lcd.print(char(223));
lcd.setCursor(19, 2);
lcd.print("C");
lcd.setCursor(0, 3);
lcd.print("Humidity ");
lcd.setCursor(15, 3);
lcd.print(event.relative_humidity);
lcd.setCursor(17,3);
lcd.print(F(" % "));
delay(300);
results.value=0x00000000;
}

//********************************************

if(modeflag%5==1)
{ lcdflag0=0;
lcdflag2=0;
lcdflag3=0;
lcdflag4=0;

if(lcdflag1==0)
lcd.clear();
lcdflag1++;

lcd.setCursor(0,0);
lcd.print( "2. Station info");
lcd.setCursor(0,1);
lcd.print("Battery");
lcd.setCursor(16,1);
float read1=analogRead(A4)0.0048752;
float value1=8.4-read1;
int value2=value1/0.014;
lcd.print(100-value2);
lcd.setCursor(19,1);
lcd.print("%");
lcd.setCursor(0,2);
lcd.print("Timer ");
lcd.setCursor(13, 2);
lcd.print(millis()/1000);
lcd.setCursor(17, 2);
lcd.print("sec");
lcd.setCursor(0,3);
lcd.print("Sounds :");
lcd.setCursor(12, 3);
if(mastersound==1)
lcd.print("Enabled");
else
lcd.print("Disabled");
results.value=0x00000000;
}
//********************************************
if(modeflag%5==2)
{ lcdflag0=0;
lcdflag1=0;
lcdflag3=0;
lcdflag4=0;

if(lcdflag2==0)
lcd.clear();
lcdflag2++;

lcd.setCursor(0,0);
lcd.print( "3. Multimeter");
lcd.setCursor(0,1);
lcd.print("Voltmeter");
lcd.setCursor(14,1);
voltmeter=4*analogRead(A1)*0.004878;
lcd.print(voltmeter);
lcd.setCursor(19,1);
lcd.print("V");
lcd.setCursor(0,2);
lcd.print("Ohmeter ");
lcd.setCursor(13, 2);
ohmeter=5000/(5-analogRead(A2)*0.004875)-1000;
if(analogRead(A2)==1023)
lcd.print(" 0 ");
else
lcd.print(ohmeter);

lcd.setCursor(17,2);
lcd.print("ohm");
lcd.setCursor(0,3);
lcd.print("EMF sensor");
lcd.setCursor(12, 3);
magnetic=analogRead(A3);
lcd.print(magnetic);
lcd.setCursor(18,3);
lcd.print("uT");
delay(10);
results.value=0x00000000;}
//********************************************
if(modeflag%5==3)
{ lcdflag0=0;
lcdflag1=0;
lcdflag2=0;
lcdflag4=0;

if(lcdflag3==0)
lcd.clear();
lcdflag3++;

lcd.setCursor(0,0);
lcd.print( "4. IR Remote menu");
lcd.setCursor(0,1);
lcd.print("Night lamp :");
lcd.setCursor(15,1);
int phase_led=b2;

if(phase_led==0)
lcd.print("OFF");
if(phase_led==1)
lcd.print(" 25%");
if(phase_led==2)
lcd.print(" 50%");
if(phase_led==3)
lcd.print(" 75%");
if(phase_led==4)
lcd.print("100%");
if(phase_led>4)
b2=0;
analogWrite(8, phase_led*50);

lcd.setCursor(0,2);
lcd.print("Buzzer");
lcd.setCursor(10,2);
lcd.print(b2);
lcd.setCursor(13,2);
lcd.print(b3);
lcd.setCursor(15,2);
lcd.print(b4);
lcd.setCursor(17,2);
lcd.print(b5);
lcd.setCursor(0,3);
lcd.print("IR HEX nr:");

lcd.setCursor(12,3);

lcd.print(results.value, HEX);
results.value=0x0000000;
delay(20);
}

if(modeflag%5==4)//++++++++++ sounding
{
lcdflag0=0;
lcdflag2=0;
lcdflag3=0;
lcdflag1=0;

if(lcdflag4==0)
lcd.clear();
lcdflag4++;// lcd stabilizer

lcd.setCursor(0,0);
lcd.print( "5. Utilities");
lcd.setCursor(0,1);
lcd.print("Dice roll");
lcd.setCursor(0,2);
lcd.print("Alarm timer");
lcd.setCursor(0,3);
lcd.print("Clock beat");
results.value=0x00000000;
} //***************************

}

how exactly do you read a button and what do you consider a button press?

i see b5 being incremented both based on a results.value and a digitalRead. And it looks like you assume there is a single event for a press that toggles it's state (%2 being interpreted as it's state).

and i'm curious how have you wired your switch to pin? most common is to configure the pin as INPUT_PULLUP which normally make the pin HIGH and have the switch pull it to ground making it LOW

Where did you get the hex codes for the remote? Maybe you got 1 wrong out of 5.

The hex codes are from remote itself. I read them on screen of lcd and here they are,pasted in code. The ir remote library works well on decoding. They cannot be wrong.. I think... And the switches I wired one end to 5v and other end to both gnd trough 4.7k resistor and digital pins directly. So they are grounded forcely if no 5v goes through.

Please edit your post and put the code inside code tags.

I want to use it both remotely and from buttons if necessary. Obviously not in the same time. So that's why there are 2 possibilities of events increasing the b1, b2... States. I go trough menus (5 screens ) with b1 state, that's why I used the % operator, to go beyond one full cycle. But all buttons values work just fine...why does b5 not working? I tried with other remote key codes and I got same result. And, I forgot to mention.. First it was b2 not working then I deleted it and replaced all of "if" cases. Now b5 is not OK. It seems it cannot handle more than 4 if cases. Does this make sense?

Possibly. But very few capable people are going to wade through your code if it's not in code tags.

I am not sure hot to modify first post so i will repost it with code tags this time. Also, i modified it a little these past hours. Nothing important just lcd more eyecandyes and stuff.

#include <Wire.h>
#include "i2c.h"
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#include<math.h.>
#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

#define DHTTYPE    DHT11   
#define DHTPIN 19 
uint32_t delayMS;

#include <IRremote.h>
int RECV_PIN = 43;
IRrecv irrecv(RECV_PIN);
decode_results results;
//speaker pin 7 pwm
#include "i2c_BMP280.h"
BMP280 bmp280;
DHT_Unified dht(DHTPIN, DHTTYPE);
int modeflag=0;
int b1=0; //31 , not used as variable!
int b2=0; //33
int b3=0; //35
int b4=0; //37
int b5=0; //39
int sound=0;
int led1=0;
int led2=0;
int led3=0;
int led4=0;
int lcdflag0=0;
int lcdflag1=0;
int lcdflag2=0;
int lcdflag3=0;
int lcdflag4=0;

float battery=0;
int ohmeter=0;
int magnetic=0;
int timeralarm=0;
float voltmeter=0;
float rxtemp=0;
int rxdistance=0;
int rxmessage=0;
int customhz=0;
int timedalarm=0;
int ceas=0;
int r1=0;
int r2=0;
int r3=0;
int r4=0;
int c1=0;
int c2=0;
int mastersound=1;
void alarm_clock() //alarma **************
{int i;
if(mastersound==1)
 for(i=0;i<=10;i++)
{analogWrite(6, 20);
delay(1);
analogWrite( 6, 0);
delay(1);
  }
 delay(20); 
}
void clock_tick()  // ceas*************************
{int i;
if(mastersound==1)
for(i=0;i<=5;i++)
{analogWrite(6, 6-i);
delay(1);
analogWrite( 6,0);
delay(20-i);
  }
  
 delay(1950/ceas);

}

void freq_gen()  //frecventa *****************
{if(customhz>100)
if(mastersound==1)
 {analogWrite(6, 18);
 delay(1000/customhz);
 analogWrite( 6, 5);
 delay(1000/customhz);
 }
 else
  analogWrite(6, 0);
}

void setup()
{   lcd.begin(20, 4);
    dht.begin();
    bmp280.initialize();
    sensor_t sensor;
    dht.humidity().getSensor(&sensor);
    bmp280.setEnabled(0);
    bmp280.triggerMeasurement();
    delayMS = sensor.min_delay / 1000;
    irrecv.enableIRIn();
    randomSeed(analogRead(0));

}

unsigned long int buton=0x00000000;


void loop()  //************************************************************
{ if(irrecv.decode(&results))
    irrecv.resume();
  buton=results.value;
  if(buton == 0x39B909D9)
  {modeflag++;
  delay(300);
 
  }
  
  
   if(results.value ==  0x2A6B6F3D)
  {
  b2++;
  delay(300);

  }
    if(results.value == 0xDFE68592 )
  {b3++;
  delay(300);

  }
    if(results.value == 0x9BD7F3D0 )
  {b4++;
  delay(300);
  }

  if(results.value == 0x01C62B02 )
  {
  b5++;
  delay(300);

  }
  if(digitalRead(31) == HIGH)
  {modeflag++;
  delay(300);
  }
 if(digitalRead(33) == HIGH)
  {b2++;
 delay(300);
 }
  if(digitalRead(34) == HIGH)
  {b3++;
  delay(300);
  }
   if(digitalRead(37) == HIGH)
  {b4++;
  delay(300);
  }
   if(digitalRead(39) == HIGH)
  {b5++;
  delay(300);
  }
  if(b5%2==1)
  mastersound=0;
  else
  mastersound=1; 
  

 if(modeflag%5==0) 
  { lcdflag1=0;
    lcdflag2=0;
    lcdflag3=0;
    lcdflag4=0;
    if(lcdflag0==0)
   lcd.clear();
  lcdflag0++;
  
   sensors_event_t event;
   dht.humidity().getEvent(&event);
   bmp280.awaitMeasurement();
   float temperature;
   bmp280.getTemperature(temperature);
   float pascal;
   bmp280.getPressure(pascal);
   bmp280.triggerMeasurement();
   lcd.setCursor(0,0);
   lcd.print("1. Weather station");
   lcd.setCursor(0, 1);
   lcd.print("Pressure  ");
   lcd.setCursor( 13, 1);
   lcd.print(pascal*0.00748);
   lcd.setCursor( 18, 1);
   lcd.print("mm");
   lcd.setCursor(0, 2);
   lcd.print("Temperature");
   lcd.setCursor(13, 2);
   lcd.print(temperature-2);
   lcd.setCursor(18, 2);
   lcd.print(char(223));
   lcd.setCursor(19, 2);
   lcd.print("C");
   lcd.setCursor(0, 3);
   lcd.print("Humidity  ");
   lcd.setCursor(15, 3);
   lcd.print(event.relative_humidity);
   lcd.setCursor(17,3);
   lcd.print(F(" % "));
   delay(300);
 results.value=0x00000000;
  } 

   //********************************************
  
  if(modeflag%5==1)
  { lcdflag0=0;
    lcdflag2=0;
    lcdflag3=0;
    lcdflag4=0;
 
    if(lcdflag1==0)
   lcd.clear();
  lcdflag1++;
  
  lcd.setCursor(0,0);
  lcd.print( "2. Station info");
  lcd.setCursor(0,1);
  lcd.print("Battery");
  lcd.setCursor(16,1);
  float read1=analogRead(A4)*0.004875*2;
  float value1=8.4-read1;
  int value2=value1/0.014;
  lcd.print(100-value2);
  lcd.setCursor(19,1);
  lcd.print("%");
  lcd.setCursor(0,2);
  lcd.print("Timer ");
  lcd.setCursor(13, 2);
  lcd.print(millis()/1000);
  lcd.setCursor(17, 2);
  lcd.print("sec");
  lcd.setCursor(0,3);
  lcd.print("Sounds :");
  lcd.setCursor(12, 3);
  if(mastersound==1)
  lcd.print("Enabled");
  else
  lcd.print("Disabled");
   results.value=0x00000000;
   }
 //********************************************
   if(modeflag%5==2)
  { lcdflag0=0;
    lcdflag1=0;
   lcdflag3=0;
   lcdflag4=0;
 
    if(lcdflag2==0)
   lcd.clear();
  lcdflag2++;
  
  lcd.setCursor(0,0);
  lcd.print( "3. Multimeter");
  lcd.setCursor(0,1);
  lcd.print("Voltmeter");
  lcd.setCursor(14,1);
  voltmeter=4*analogRead(A1)*0.004878;
  lcd.print(voltmeter);
  lcd.setCursor(19,1);
  lcd.print("V");
  lcd.setCursor(0,2);
  lcd.print("Ohmeter ");
  lcd.setCursor(13, 2);
  ohmeter=5000/(5-analogRead(A2)*0.004875)-1000;
  if(analogRead(A2)==1023)
  lcd.print("  0 ");
  else
  lcd.print(ohmeter);
  
  lcd.setCursor(17,2);
  lcd.print("ohm");
  lcd.setCursor(0,3);
  lcd.print("EMF sensor");
  lcd.setCursor(12, 3);
  magnetic=analogRead(A3);
  lcd.print(magnetic);
  lcd.setCursor(18,3);
  lcd.print("uT");
 delay(10);
  results.value=0x00000000;}
 //********************************************
 if(modeflag%5==3)
  { lcdflag0=0;
    lcdflag1=0;
    lcdflag2=0;
    lcdflag4=0;
 
    if(lcdflag3==0)
   lcd.clear();
   lcdflag3++;
   

  
   lcd.setCursor(0,0);
   lcd.print( "4. IR Remote menu");
   lcd.setCursor(0,1);
   lcd.print("Night lamp :");
   lcd.setCursor(15,1);
   int phase_led=b2;
   
   if(phase_led==0)
   lcd.print("OFF");
   if(phase_led==1)
   lcd.print(" 25%");
  if(phase_led==2)
  lcd.print(" 50%");
  if(phase_led==3)
  lcd.print(" 75%");
  if(phase_led==4)
  lcd.print("100%");
  if(phase_led>4)
  b2=0;
  analogWrite(8, phase_led*50);
   
    lcd.setCursor(0,2);
    lcd.print("Buzzer");
    lcd.setCursor(10,2);
    lcd.print(b2);
    lcd.setCursor(13,2);
    lcd.print(b3);
    lcd.setCursor(15,2);
    lcd.print(b4);
    lcd.setCursor(17,2);
    lcd.print(b5);
    lcd.setCursor(0,3); 
    lcd.print("IR HEX nr:");
    
    lcd.setCursor(12,3);
    
    lcd.print(results.value, HEX);
  results.value=0x0000000;
  delay(20);
 }
     
   if(modeflag%5==4)//++++++++++ sounding
  {     lcdflag0=0;
    lcdflag2=0;
    lcdflag3=0;
    lcdflag1=0;

    if(lcdflag4==0)
   lcd.clear();
  lcdflag4++;// lcd stabilizer 
  
  lcd.setCursor(0,0);
  lcd.print( "5. Utilities");
   lcd.setCursor(0,1);
   lcd.print("Dice roll");
   lcd.setCursor(10,1);
   if(b2>0)
   {r1=random(1,7);
   r2=random(1,7);
   r3=random(1,7);
   r4=random(1,7);
   b2=0;}
   lcd.print(r1);
     lcd.setCursor(12,1);
   lcd.print(r2);
     lcd.setCursor(14,1);
   lcd.print(r3);
     lcd.setCursor(16,1);
   lcd.print(r4);
   lcd.setCursor(0,2);
   lcd.print("Alarm timer");
   lcd.setCursor(14,2);
   if(b3==0)
   {timedalarm=9999;
     lcd.print("0");
     lcd.setCursor(17,2);
     lcd.print("min");
     }
     else
   {timedalarm=b3*60*5;
    lcd.print(timedalarm/60);
   lcd.setCursor(17,2);
   lcd.print("min");
   }
     lcd.setCursor(0,3);
  lcd.print("Clock beat");
  lcd.setCursor(12,3);
    if(b4>4)
    b4=0;
    ceas=b4;
  if (ceas==1)
  {clock_tick();
   lcd.print(" 1/2 bps");
    }
      if (ceas==2)
  {clock_tick();
   lcd.print(" 1 bps  ");
    }
      if (ceas==3)
  {clock_tick();
   lcd.print(" 2 bps  ");
    }
      if (ceas==4)
  {clock_tick();
   lcd.print(" 4 bps  ");
    }
  
  if(millis()/1000 >= timedalarm)
  alarm_clock();
     results.value=0x00000000;
  } //***************************

 

  


      
}

I hope this time is ok. Anyway, with exception of few starting lines in loop() function and in the last two if() casese i guess there is nothing wrong going in my code,so not man people will bother to read it. As long as those physical buttons work and the ir receiver also is working fine for those other 4 variables...i really dont know what else i can check.

I suggest you auto-format your code and repost because it will be much easier to see where the code blocks begin and end. Definitely, more people will read it.

I will try. Anyway, I got another clue which may help. When I go to the 4th screen,the one with ir, and I press the remote key corresponding to b5, the hex code that I wrote into program displays on lcd... So it is processed. Why b5 is not incremented like all other b's?

Have you written and tested programs to independently, separately operate each hardware device? You should do this to eliminate the possibility of a hardware bug.

Also, it would be a good idea to respond to reply #1.

What about debug prints? Especially the IR.

Ithink I already answered reply #1. I've said that i consider a "button press" ( in code) giving HIGH reading ( 5v) on those digitalReads,which are wired to gnd, keeping them on 0 (LOW) unless i press the physical button. Or, a matching code from the remote for each b, also i consider a button press. The event of b's increases is only one ,tough it has effects in many menus.
And i already told that i printed values on screen for debugging. Look at the 4-th screen mode ( that's how i call it ) ,starting with (if modeflag%5==3). This screen looks something like this:

  1. IR Remote menu
    Night lamp : OFF
    Buzzer: 0 0 0 0
    IR HEX nr: 2A6B6F3D
    As you can see, this menu has 3 functions but untill i finish the code i modified it for debuggind. Buzzer intended to be a speaker tone, but not it is only showing b's values on lcd to see if they are really incremented. first 0 is b2, second is b4 etc... B1 is not shown because it is setting screen mode and , if i am in screen 4 already,it is obvious is working fine.
    And the last row shows the hex code given by the remote when i press buttons.
    Everything goes fine on this debug screen except one thing which drives me mad...at the b5, ( last 0) it does not increse , it remains zero...even if i got the positive feedback that the signal has been decoded. The ir number matches my code so it is processed. why b5 is not incremented?

And about hardware, what further testing should i do? All 5 butttons are working well ,when i push them they do exactly what they should.The remote is ok also, because as i said, it gives right hex numbers and the arduino decodes them as it should. The only thing i can imagine is that the irdecoder stores somehow the button codes as variables and it has a limited capacity or something like that...dont know.
i noticed some weird thing about ir, tough. Sometimes if i press a button on remote too long or too short, on lcd i read 0FFFFFFF no matter any button I press. I have to pres it again to give the right hex nr. So i guess it may be a sync error for some of my keys?

0xFFFFFFFF is a standard "repeat" code that most IR remotes use when a button is held down. It simply means repeat the previous code sent.

Steve

So, what else could be the problem?

Don't call resume() until you've finished key processing.

what exactly does irrecv.resume() and where should i put it?

ravenclaws777:
what exactly does irrecv.resume() and where should i put it?

It re-starts the IR receive decoding. You should put it after you have finished processing the current received data. The programmer is responsible for determining when that is.