IR Control

I am in the process of writing control for infrared controlled AC single phase triac control.
The part that is being designed is to increment/decrement the seven segment digit from 0 to 9. using the up/down keys on an NEC IR remote. The value is stored in the EEPROM with the idea that the last state will be available when the power is recycled.

In the code below I am able to increment/decrement the display and write it to EEPROM. When the power is recycled. the last value is displayed.

However after power recycle when the up key is pressed the display changes to 1, and when the down key is pressed the display changes to zero.

#include <EEPROM.h>
#include <boarddefs.h>
#include <IRremote.h>
#include <IRremoteInt.h>
#include <ir_Lego_PF_BitStreamEncoder.h>



#define setbit(port, bit) (port) |= (1<< (bit))
#define clearbit(port, bit) (port) &=~(1<< (bit))




const int iRReceivePin = PD2;
IRrecv irrecv(iRReceivePin);
decode_results results;

uint8_t speed = 0;
uint8_t speedVal = 0; // value of speed Read from EEPROM
uint8_t num;


/* Seven Segment Display Function */

void Display(uint8_t num)
{ if (num > 9)
    return;
  switch (num)
  {
    case 0:
      PORTC = 0B00000000;
      PORTB = 0B00000010;
      break;
    case 1:   
      PORTC = 0B00111001;
      PORTB = 0B00000010;
      break;
    case 2:     
      PORTC = 0B00100100;
      PORTB = 0B00000000;
      break;
    case 3:     
      PORTC = 0B00110000;
      PORTB = 0B00000000;
      break;
    case 4:      
      PORTC = 0B00011001;
      PORTB = 0B00000000;
      break;
    case 5:      
      PORTC = 0B00010010;
      PORTB = 0B00000000;
      break;
    case 6:      
      PORTC = 0B00000010;
      PORTB = 0B00000000;
      break;
    case 7:      
      PORTC = 0B00111000;
      PORTB = 0B00000010;
      break;
    case 8:
      PORTC = 0B00000000;
      PORTB = 0B00000000;
      break;
    case 9:
      PORTC = 0B00010000;
      PORTB = 0B00000000;
      break;
  }
}


void setup() {
  // put your setup code here, to run once:

  irrecv.enableIRIn(); // Start the IR receiver


  DDRC =  DDRC | 0B00111111; // Port C pins 0 to 5 as output for seg a b c d e f
  DDRB = DDRB | 0B00000010; // Port B pin 1 as output for segment g
  /* Sets all segments a to g in the display on */
  clearbit (PORTC, PC0);
  clearbit (PORTC, PC1);
  clearbit (PORTC, PC2);
  clearbit (PORTC, PC3);
  clearbit (PORTC, PC4);
  clearbit (PORTC, PC5);
  clearbit (PORTB, PB1);

  EEPROM.get (0, speedVal);
  Display(speedVal);

}

void loop() {
  if (irrecv.decode(&results)) {

    switch (results.value)
    {
      case 0xFF48B7:  // NEC code for UP Key
        {
          if (speed < 9)
            speed++;
          speedVal = speed;
          EEPROM.put(0, speedVal);
          Display (speedVal);
        }
        break;
      case 0XFF609F:  //NEC Code for DOWN Key
        {
          if (speed > 0)
            speed--;
          speedVal = speed;
          EEPROM.put(0, speedVal);
          Display (speedVal);
        }
        break;
    }
   
    irrecv.resume(); // Receive the next value


    delay(10);
  }


}

After a power recycle the segment should increment/decrement to next higher/lower value and not to one or zero.
I am compiling with minicore for Atmega8 and uploading from Arduino IDE using programmer
Seeking help from the forum please.

When you do this:

EEPROM.get (0, speedVal ) ;

it looks like you have also to set the variable speed to the value of speedVal.

uint8_t speed = 0;
uint8_t speedVal = 0; // value of speed Read from EEPROM

I don't know why you are using 2 variables for 1 control value, but since speedval get read from the eeprom and speed is initialized as 0, there is your bug. I would just change all 'speedval' into 'speed' (and remove the 'speedVal = speed;')
i suppose you could also add

speed=speedVal;

just after the EEPROM.get(); (but why ?)

Deva_Rishi:

uint8_t speed = 0;

uint8_t speedVal = 0; // value of speed Read from EEPROM



I don't know why you are using 2 variables for 1 control value, but since speedval get read from the eeprom and speed is initialized as 0, there is your bug. I would just change all 'speedval' into 'speed' (and remove the 'speedVal = speed;') 
i suppose you could also add 


speed=speedVal;



just after the EEPROM.get(); (but why ?)

I changed all 'speedVal to speed' and removed the 'speedVal = speed;'
The display stopped working. Then I replaced the EEPROM.get(, speed); with EEPROM.read(0,speed)
got this error

exit status 1
no matching function for call to 'EEPROMClass::read(int, uint8_t&)'

next as a fluke I changed the data type of speed to char and used the EEPROM.get(0,speed) and the code compiled without error and the display increments/decrements as desired

After uploading the code why does the display digit 8 which on press of up key displays corresponding to case 1 of the Display function ie 0, while the EEPROM had a different value stored. Does flashing/uploading program erase the EEPROM too?

Post your updated code.
An uninitialised eeprom has all bits set to 1.
If you treat such a byte as a char it has the value -1.
If Display() still takes a uint8_t argument, that -1 will look like 255 which will cause it to return immediately without doing anything.

EEPROM.read() takes only an address as an argument and it returns the value read from the eeprom, so it behaves differently to EEPROM.get().

This is my updated code

#include <EEPROM.h>
#include <boarddefs.h>
#include <IRremote.h>
#include <IRremoteInt.h>
#include <ir_Lego_PF_BitStreamEncoder.h>



#define setbit(port, bit) (port) |= (1<< (bit))
#define clearbit(port, bit) (port) &=~(1<< (bit))




const int iRReceivePin = PD2;
IRrecv irrecv(iRReceivePin);
decode_results results;
/* iniialise speed to zero, and also store the set value in EEPROM
on every change to be read from it on power recycle.
*/
char speed = 0;
char num;

/* Seven Segment Display Function */

void Display(char num)
{ if (num > 9)
    return;
  switch (num)
  {
    case 0:
      PORTC = 0B00000000;
      PORTB = 0B00000010;
      break;
    case 1:
      PORTC = 0B00111001;
      PORTB = 0B00000010;
      break;
    case 2:
      PORTC = 0B00100100;
      PORTB = 0B00000000;
      break;
    case 3:
      PORTC = 0B00110000;
      PORTB = 0B00000000;
      break;
    case 4:
      PORTC = 0B00011001;
      PORTB = 0B00000000;
      break;
    case 5:
      PORTC = 0B00010010;
      PORTB = 0B00000000;
      break;
    case 6:
      PORTC = 0B00000010;
      PORTB = 0B00000000;
      break;
    case 7:
      PORTC = 0B00111000;
      PORTB = 0B00000010;
      break;
    case 8:
      PORTC = 0B00000000;
      PORTB = 0B00000000;
      break;
    case 9:
      PORTC = 0B00010000;
      PORTB = 0B00000000;
      break;
  }
}


void setup() {
  // put your setup code here, to run once:

  irrecv.enableIRIn(); // Start the IR receiver


  DDRC =  DDRC | 0B00111111; // Port C pins 0 to 5 as output for seg a b c d e f
  DDRB = DDRB | 0B00000010; // Port B pin 1 as output for segment g
  
  /* Sets all segments a to g in the display on */
  
  setbit (PORTC, PC0);
  setbit (PORTC, PC1);
  setbit (PORTC, PC2);
  setbit (PORTC, PC3);
  setbit (PORTC, PC4);
  setbit (PORTC, PC5);
  setbit (PORTB, PB1);

  EEPROM.get(0, speed);
  Display(speed);

}

void loop() {

  if (irrecv.decode(&results)) {

    switch (results.value)
    {
      case 0xFF48B7:  // NEC code for UP Key
        {
          if (speed < 9)
            speed++;
          //speedVal = speed;
          EEPROM.put(0, speed);
          Display (speed);
        }
        break;
      case 0XFF609F:  //NEC Code for DOWN Key
        {
          if (speed > 0)
            speed--;
          //speedVal = speed;
          EEPROM.put(0, speed);
          Display (speed);
        }
        break;
    }

    irrecv.resume(); // Receive the next value


    delay(10);
  }


}

Thanks for your time, I welcome suggestions towards improvement.