Mega PWM Pin "strobing" when it shouldnt

Hello,

I have put together a code which has the main funciton of recording the input from a pot and saving to EEPROM before playing back on a pair of PWM outputs.

The PWM outputs should be optically inverted from one another, ie the effective sum of light from both should remain the same at any level of brightness.

I have used the recording “Servos as Input Devices” by Adafrut Bill Earl as the basis of making the recording and playing back, albeit with adjustment to permit continual playback as well as LED indication of whats happened, latched “play” and “record” buttons.

I Map a the pot input to 0 - 254 and save these values to EEPROM at recording, then i read these values back when playing. These values then lookup Gamma corrected tables, one “normal” and the other inverse.

As a side function, when no playing or recording happens, i have manual dimmer control of both PWM outputs.

Now, all the recording and play back functions work and so too does the gamma correction. The dimmer side function also works.

What i am having trouble with is… During recording, the PWM output for “OutputBPin” which is my inverted function strobes continually though all brightness levels with it being present even when Serial.print indicates im writing a zero to the PWM channel.

Likewise, during playback, adjusting the pot causes a slight flicker in both channels although i am not even reading it during playback.

Not sure if there is some form of code crosstalk going on where some residual values partially update a value elsewhere or some odd thing i dont appreciate.

Any assistance would be appreciated.

Code is here in full:

#include <EEPROM.h>

#define CALIB_MAX 710
#define CALIB_MIN 200
#define SAMPLE_DELAY 25 // in ms.

unsigned int recordButtonPin = 12;
unsigned int playButtonPin = 7;
unsigned int OutputAPin = 8;
unsigned int OutputBPin = 9;
unsigned int inputPin = A0;
unsigned int ledPin = 13;

unsigned int lowWarn = 2;
unsigned int hiWarn = 3;

unsigned int addr = 0;

int recordFlag = 0;
int playFlag = 0;

const uint8_t PROGMEM gamma[] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
  5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13,
  14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24,
  25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 38, 39, 39,
  40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, 51, 52, 54, 55, 56, 57, 58, 59, 60,
  61, 62, 63, 64, 66, 67, 68, 69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86,
  87, 89, 90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 109, 110, 112, 114,
  115, 117, 119, 120, 122, 124, 126, 127, 129, 131, 133, 135, 137, 138, 140, 142,
  144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 167, 169, 171, 173, 175,
  177, 180, 182, 184, 186, 189, 191, 193, 196, 198, 200, 203, 205, 208, 210, 213,
  215, 218, 220, 223, 225, 228, 231, 233, 236, 239, 241, 244, 247, 249, 252, 255
};

const uint8_t PROGMEM gammainverse[] = {
  255, 252, 249, 247, 244, 241, 239, 236, 233, 231, 228, 225, 223, 220, 218, 215,
  213, 210, 208, 205, 203, 200, 198, 196, 193, 191, 189, 186, 184, 182, 180, 177,
  175, 173, 171, 169, 167, 164, 162, 160, 158, 156, 154, 152, 150, 148, 146, 144,
  142, 140, 138, 137, 135, 133, 131, 129, 127, 126, 124, 122, 120, 119, 117, 115,
  114, 112, 110, 109, 107, 105, 104, 102, 101, 99, 98, 96, 95, 93, 92, 90, 89, 87,
  86, 85, 83, 82, 81, 79, 78, 77, 75, 74, 73, 72, 70, 69, 68, 67, 66, 64, 63, 62, 61,
  60, 59, 58, 57, 56, 55, 54, 52, 51, 50, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40,
  39, 39, 38, 37, 36, 35, 35, 34, 33, 32, 32, 31, 30, 29, 29, 28, 27, 27, 26, 25, 25,
  24, 24, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 15, 15, 14, 14,
  13, 13, 13, 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5,
  5, 5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};


void setup() {
  Serial.begin(57600);

  pinMode(recordButtonPin, INPUT);
  digitalWrite(recordButtonPin, HIGH);

  pinMode(playButtonPin, INPUT);
  digitalWrite(playButtonPin, HIGH);

  pinMode(ledPin, OUTPUT);
  pinMode(OutputAPin, OUTPUT);
  pinMode(OutputBPin, OUTPUT);
  pinMode(lowWarn, OUTPUT);
  pinMode(hiWarn, OUTPUT);

  pinMode(inputPin, INPUT);

  Serial.println("Lights Record & Playback with two opposite outputs");
}

void loop() {




  /* - - - - - IDLE FUNCTION WHEN NOT RECORDING & PLAYING BACK (JUST A DIMMER) - - - - - */

  int a = analogRead(inputPin);
  delay (SAMPLE_DELAY);
  if (a < CALIB_MIN)
  {
    a = CALIB_MIN;
    digitalWrite(lowWarn, HIGH);
  }
  else
  {
    digitalWrite(lowWarn, LOW);
  }
  if (a > CALIB_MAX)
  {
    a = CALIB_MAX;
    digitalWrite(hiWarn, HIGH);
  }
  else
  {
    digitalWrite(hiWarn, LOW);
  }
  int m = map(a, CALIB_MIN, CALIB_MAX, 0, 254);

  int mforward = pgm_read_byte(&gamma[m]);
  int minverse = pgm_read_byte(&gammainverse[m]);

  analogWrite(OutputAPin, mforward);
  analogWrite(OutputBPin, mforward);  // Run both the same in non play-back or recording mode )i.e. "a dimmer"


  /* - - - - - RECORD ON BUTTON PRESS UNTILL EEPROM FULL OR BUTTON PRESSED AGAIN - - - - - */

  if (! digitalRead(recordButtonPin)) {
    delay(10);
    // wait for released
    while (! digitalRead(recordButtonPin));
    delay(20);
    // OK released!
    Serial.print("Record flag was: "); Serial.print(recordFlag);
    recordFlag = (! recordFlag);
    Serial.print("  // Now Record Button pressed & released, record flag: "); Serial.println(recordFlag);
  }

  if (recordFlag == 1)
  {
    Serial.print("Recording at EEPROM Address: "); Serial.print(addr);
    digitalWrite(ledPin, HIGH);

    unsigned int a = analogRead(inputPin);

    Serial.print(" - - Read analog: "); Serial.print(a);
    if (a < CALIB_MIN)
    {
      a = CALIB_MIN;
      digitalWrite(lowWarn, HIGH);
    }
    else
    {
    digitalWrite(lowWarn, LOW);
    }
    if (a > CALIB_MAX)
    {
      a = CALIB_MAX;
      digitalWrite(hiWarn, HIGH);
    }
    else
    {
      digitalWrite(hiWarn, LOW);
    }
    a = map(a, CALIB_MIN, CALIB_MAX, 0, 254);
    Serial.print(" mapped to -> "); Serial.print(a); Serial.print(" and also to: "); Serial.println(254 - a);

    EEPROM.write(addr, a);   // scaled 0-254 but NOT gamma corrected value (correct Gamma at read)

    delay(5);
    unsigned int m = EEPROM.read(addr);   // read back newly written value and map to outputs for verification
    int mforward = pgm_read_byte(&gamma[m]);
    int minverse = pgm_read_byte(&gammainverse[m]);

    analogWrite(OutputAPin, mforward);
    analogWrite(OutputBPin, minverse);

    addr = addr + 1;
    delay(SAMPLE_DELAY - 5);
    if (addr == 512)
    {
      Serial.print("EEPROM FULL");
      recordFlag = 0;
      EEPROM.write(addr, 255);
      addr = 0;
      digitalWrite(ledPin, LOW);
      Serial.println("Done");
      delay(250);
    }
  }


  /* - - - - - PLAY ON BUTTON PRESS UNTILL BUTTON PRESSED AGAIN.  RESUMES FROM LAST PLACE - - - - - */

  if (! digitalRead(playButtonPin)) {
    delay(10);
    // wait for released
    while (! digitalRead(playButtonPin));
    delay(20);
    // OK released!
    Serial.print("Play flag was: "); Serial.print(playFlag);
    playFlag = (! playFlag);
    Serial.print("  // Now Play Button pressed & released, play flag: "); Serial.println(playFlag);
  }

  if (playFlag == 1)
  {
    Serial.print("Playing at EEPROM Address: "); Serial.print(addr);
    digitalWrite(ledPin, HIGH);

    unsigned int m = EEPROM.read(addr);

    Serial.print("Read EE: "); Serial.print(m);
    m = map(m, 0, 254, 0, 254);  // Output remapping (after Gamma at recording time)

    int mforward = pgm_read_byte(&gamma[m]);
    int minverse = pgm_read_byte(&gammainverse[m]);

    Serial.print(" -> "); Serial.print(mforward); Serial.print(" and also to: "); Serial.println(minverse);

    analogWrite(OutputAPin, mforward);

    analogWrite(OutputBPin, minverse);

    delay(SAMPLE_DELAY);
    addr++;
    if (addr == 512)
    {
      addr = 0;
    }
  }
}

Just an update, i had wondered if using the same variable names in the different segments were somehow upsetting things so i have made sure im not recycling variables but that hasn’t fixed it. No effect. Code currently looks like this:

#include <EEPROM.h>

#define CALIB_MAX 710
#define CALIB_MIN 200
#define SAMPLE_DELAY 25 // in ms.

unsigned int recordButtonPin = 12;
unsigned int playButtonPin = 7;
unsigned int OutputAPin = 8;
unsigned int OutputBPin = 9;
unsigned int inputPin = A0;
unsigned int ledPin = 13;

unsigned int lowWarn = 2;
unsigned int hiWarn = 3;

unsigned int addr = 0;

int recordFlag = 0;
int playFlag = 0;

const uint8_t PROGMEM gamma[] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
  5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13,
  14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24,
  25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 38, 39, 39,
  40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, 51, 52, 54, 55, 56, 57, 58, 59, 60,
  61, 62, 63, 64, 66, 67, 68, 69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86,
  87, 89, 90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 109, 110, 112, 114,
  115, 117, 119, 120, 122, 124, 126, 127, 129, 131, 133, 135, 137, 138, 140, 142,
  144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 167, 169, 171, 173, 175,
  177, 180, 182, 184, 186, 189, 191, 193, 196, 198, 200, 203, 205, 208, 210, 213,
  215, 218, 220, 223, 225, 228, 231, 233, 236, 239, 241, 244, 247, 249, 252, 255
};

const uint8_t PROGMEM gammainverse[] = {
  255, 252, 249, 247, 244, 241, 239, 236, 233, 231, 228, 225, 223, 220, 218, 215,
  213, 210, 208, 205, 203, 200, 198, 196, 193, 191, 189, 186, 184, 182, 180, 177,
  175, 173, 171, 169, 167, 164, 162, 160, 158, 156, 154, 152, 150, 148, 146, 144,
  142, 140, 138, 137, 135, 133, 131, 129, 127, 126, 124, 122, 120, 119, 117, 115,
  114, 112, 110, 109, 107, 105, 104, 102, 101, 99, 98, 96, 95, 93, 92, 90, 89, 87,
  86, 85, 83, 82, 81, 79, 78, 77, 75, 74, 73, 72, 70, 69, 68, 67, 66, 64, 63, 62, 61,
  60, 59, 58, 57, 56, 55, 54, 52, 51, 50, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40,
  39, 39, 38, 37, 36, 35, 35, 34, 33, 32, 32, 31, 30, 29, 29, 28, 27, 27, 26, 25, 25,
  24, 24, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 15, 15, 14, 14,
  13, 13, 13, 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5,
  5, 5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};


void setup() {
  Serial.begin(57600);

  pinMode(recordButtonPin, INPUT);
  digitalWrite(recordButtonPin, HIGH);

  pinMode(playButtonPin, INPUT);
  digitalWrite(playButtonPin, HIGH);

  pinMode(ledPin, OUTPUT);
  pinMode(OutputAPin, OUTPUT);
  pinMode(OutputBPin, OUTPUT);
  pinMode(lowWarn, OUTPUT);
  pinMode(hiWarn, OUTPUT);

  pinMode(inputPin, INPUT);

  Serial.println("Lights Record & Playback with two opposite outputs");
}

void loop() {




  /* - - - - - IDLE FUNCTION WHEN NOT RECORDING & PLAYING BACK (JUST A DIMMER) - - - - - */

  int a = analogRead(inputPin);
  delay (SAMPLE_DELAY);
  if (a < CALIB_MIN)
  {
    a = CALIB_MIN;
    digitalWrite(lowWarn, HIGH);
  }
  else
  {
    digitalWrite(lowWarn, LOW);
  }
  if (a > CALIB_MAX)
  {
    a = CALIB_MAX;
    digitalWrite(hiWarn, HIGH);
  }
  else
  {
    digitalWrite(hiWarn, LOW);
  }
  int b = map(a, CALIB_MIN, CALIB_MAX, 0, 254);

  int bforward = pgm_read_byte(&gamma[b]);
  int binverse = pgm_read_byte(&gammainverse[b]);

  analogWrite(OutputAPin, bforward);
  analogWrite(OutputBPin, bforward);  // Run both the same in non play-back or recording mode )i.e. "a dimmer"


  /* - - - - - RECORD ON BUTTON PRESS UNTILL EEPROM FULL OR BUTTON PRESSED AGAIN - - - - - */

  if (! digitalRead(recordButtonPin)) {
    delay(10);
    // wait for released
    while (! digitalRead(recordButtonPin));
    delay(20);
    // OK released!
    Serial.print("Record flag was: "); Serial.print(recordFlag);
    recordFlag = (! recordFlag);
    Serial.print("  // Now Record Button pressed & released, record flag: "); Serial.println(recordFlag);
  }

  if (recordFlag == 1)
  {
    Serial.print("Recording at EEPROM Address: "); Serial.print(addr);
    digitalWrite(ledPin, HIGH);

    unsigned int c = analogRead(inputPin);

    Serial.print(" - - Read analog: "); Serial.print(a);
    if (c < CALIB_MIN)
    {
      c = CALIB_MIN;
      digitalWrite(lowWarn, HIGH);
    }
    else
    {
    digitalWrite(lowWarn, LOW);
    }
    if (c > CALIB_MAX)
    {
      c = CALIB_MAX;
      digitalWrite(hiWarn, HIGH);
    }
    else
    {
      digitalWrite(hiWarn, LOW);
    }
    int d = map(c, CALIB_MIN, CALIB_MAX, 0, 254);
    Serial.print(" mapped to -> "); Serial.println(d);

    EEPROM.write(addr, d);   // scaled 0-254 but NOT gamma corrected value (correct Gamma at read)

    delay(5);
    unsigned int e = EEPROM.read(addr);   // read back newly written value and map to outputs for verification
    int eforward = pgm_read_byte(&gamma[e]);
    int einverse = pgm_read_byte(&gammainverse[e]);

    analogWrite(OutputAPin, eforward);
    analogWrite(OutputBPin, einverse);

    addr = addr + 1;
    delay(SAMPLE_DELAY - 5);
    if (addr == 512)
    {
      Serial.print("EEPROM FULL");
      recordFlag = 0;
      EEPROM.write(addr, 255);
      addr = 0;
      digitalWrite(ledPin, LOW);
      Serial.println("Done");
      delay(250);
    }
  }


  /* - - - - - PLAY ON BUTTON PRESS UNTILL BUTTON PRESSED AGAIN.  RESUMES FROM LAST PLACE - - - - - */

  if (! digitalRead(playButtonPin)) {
    delay(10);
    // wait for released
    while (! digitalRead(playButtonPin));
    delay(20);
    // OK released!
    Serial.print("Play flag was: "); Serial.print(playFlag);
    playFlag = (! playFlag);
    Serial.print("  // Now Play Button pressed & released, play flag: "); Serial.println(playFlag);
  }

  if (playFlag == 1)
  {
    Serial.print("Playing at EEPROM Address: "); Serial.print(addr);
    digitalWrite(ledPin, HIGH);

    unsigned int f = EEPROM.read(addr);

    Serial.print("Read EE: "); Serial.print(f);
    int g = map(f, 0, 254, 0, 254);  // Output remapping (after Gamma at recording time)

    int gforward = pgm_read_byte(&gamma[g]);
    int ginverse = pgm_read_byte(&gammainverse[g]);

    Serial.print(" -> "); Serial.print(gforward); Serial.print(" and also to: "); Serial.println(ginverse);

    analogWrite(OutputAPin, gforward);

    analogWrite(OutputBPin, ginverse);

    delay(SAMPLE_DELAY);
    addr++;
    if (addr == 512)
    {
      addr = 0;
    }
  }
}

Hello,

No takers yet :frowning: Have changed title to possible attract some more attention. (Next title will offer a kitkat finger to whom ever can help).

Ive changed the PWM output pins incase these were faulty in some way with no luck. ive also swapped them and found which ever pin is allocated the inverse gamma table gets the erattic flashing during recording.

I’ve added some serial prints to the record section so i can see whats going into the gamma lookup and whats coming out in both cases.

For example; (where lookupvalue is whats read from the EEPROM and the PWM outputs as written with analogWrite)

lookupvalue,OutputAPin,OutputBPin
0,0,255
0,0,255
0,0,255
0,0,255
0,0,255
0,0,255
0,0,255
0,0,255
0,0,255

With the above i get a dark LED on output A (currently Mega pin 3) however the LED on output B (mega pin 2) flashes on and off at at program loop speed (i know this as ive changed the loop time and this decreases the flash rate).

Likewise, if this is the written values;

lookupvalue,OutputAPin,OutputBPin
254,252,0
254,252,0
254,252,0
254,252,0
254,252,0
254,252,0
254,252,0

I get the expected result where pin a is bright and pin B continues to flash each loop. The only time i dont see a flash is when i am at a median value…

Haven’t made any big changes to code other than limit my serial.prints only to what i need to see this issue and also ive ensured the “idle” (i.e. not recording or playing function doesn’t do anything during recording or playing), but currently here is how it stands:

#include <EEPROM.h>

#define CALIB_MAX 710
#define CALIB_MIN 200
#define SAMPLE_DELAY 25 // in ms.

unsigned int recordButtonPin = 12;
unsigned int playButtonPin = 7;
unsigned int OutputAPin = 3;
unsigned int OutputBPin = 2;
unsigned int inputPin = A0;
unsigned int ledPin = 13;

unsigned int lowWarn = 4;
unsigned int hiWarn = 5;

unsigned int addr = 0;

int recordFlag = 0;
int playFlag = 0;

const uint8_t PROGMEM gamma[] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
  5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13,
  14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24,
  25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 38, 39, 39,
  40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, 51, 52, 54, 55, 56, 57, 58, 59, 60,
  61, 62, 63, 64, 66, 67, 68, 69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86,
  87, 89, 90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 109, 110, 112, 114,
  115, 117, 119, 120, 122, 124, 126, 127, 129, 131, 133, 135, 137, 138, 140, 142,
  144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 167, 169, 171, 173, 175,
  177, 180, 182, 184, 186, 189, 191, 193, 196, 198, 200, 203, 205, 208, 210, 213,
  215, 218, 220, 223, 225, 228, 231, 233, 236, 239, 241, 244, 247, 249, 252, 255
};

const uint8_t PROGMEM gammainverse[] = {
  255, 252, 249, 247, 244, 241, 239, 236, 233, 231, 228, 225, 223, 220, 218, 215,
  213, 210, 208, 205, 203, 200, 198, 196, 193, 191, 189, 186, 184, 182, 180, 177,
  175, 173, 171, 169, 167, 164, 162, 160, 158, 156, 154, 152, 150, 148, 146, 144,
  142, 140, 138, 137, 135, 133, 131, 129, 127, 126, 124, 122, 120, 119, 117, 115,
  114, 112, 110, 109, 107, 105, 104, 102, 101, 99, 98, 96, 95, 93, 92, 90, 89, 87,
  86, 85, 83, 82, 81, 79, 78, 77, 75, 74, 73, 72, 70, 69, 68, 67, 66, 64, 63, 62, 61,
  60, 59, 58, 57, 56, 55, 54, 52, 51, 50, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40,
  39, 39, 38, 37, 36, 35, 35, 34, 33, 32, 32, 31, 30, 29, 29, 28, 27, 27, 26, 25, 25,
  24, 24, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 15, 15, 14, 14,
  13, 13, 13, 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5,
  5, 5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};


void setup() {
  Serial.begin(57600);

  pinMode(recordButtonPin, INPUT);
  digitalWrite(recordButtonPin, HIGH);

  pinMode(playButtonPin, INPUT);
  digitalWrite(playButtonPin, HIGH);

  pinMode(ledPin, OUTPUT);
  pinMode(OutputAPin, OUTPUT);
  pinMode(OutputBPin, OUTPUT);
  pinMode(lowWarn, OUTPUT);
  pinMode(hiWarn, OUTPUT);



  Serial.println("Lights Record & Playback with two opposite outputs");
}

void loop() {


  /* - - - - - IDLE FUNCTION WHEN NOT RECORDING & PLAYING BACK (JUST A DIMMER) - - - - - */
  if ( (recordFlag == 0) && (playFlag == 0) );
  {
    pinMode(inputPin, INPUT);
    int a = analogRead(inputPin);
    delay (SAMPLE_DELAY);
    if (a < CALIB_MIN)
    {
      a = CALIB_MIN;
      digitalWrite(lowWarn, HIGH);
    }
    else
    {
      digitalWrite(lowWarn, LOW);
    }
    if (a > CALIB_MAX)
    {
      a = CALIB_MAX;
      digitalWrite(hiWarn, HIGH);
    }
    else
    {
      digitalWrite(hiWarn, LOW);
    }
    int b = map(a, CALIB_MIN, CALIB_MAX, 0, 254);

    int bforward = pgm_read_byte(&gamma[b]);
    int binverse = pgm_read_byte(&gammainverse[b]);

    analogWrite(OutputAPin, bforward);
    analogWrite(OutputBPin, bforward);  // Run both the same in non play-back or recording mode )i.e. "a dimmer"
    pinMode(inputPin, OUTPUT);
  }

  /* - - - - - RECORD ON BUTTON PRESS UNTILL EEPROM FULL OR BUTTON PRESSED AGAIN - - - - - */

  if (! digitalRead(recordButtonPin)) {
    delay(10);
    // wait for released
    while (! digitalRead(recordButtonPin));
    delay(20);
    // OK released!
 //   Serial.print("Record flag was: "); Serial.print(recordFlag);
    recordFlag = (! recordFlag);
 //   Serial.print("  // Now Record Button pressed & released, record flag: "); Serial.println(recordFlag);
  }

  if (recordFlag == 1)
  {
 //   Serial.print("Recording at EEPROM Address: "); Serial.print(addr);
    digitalWrite(ledPin, HIGH);
    pinMode(inputPin, INPUT);
    unsigned int c = analogRead(inputPin);
    pinMode(inputPin, OUTPUT);
    
 //   Serial.print(" - - Read analog: "); Serial.print(c);
    if (c < CALIB_MIN)
    {
      c = CALIB_MIN;
      digitalWrite(lowWarn, HIGH);
    }
    else
    {
      digitalWrite(lowWarn, LOW);
    }
    if (c > CALIB_MAX)
    {
      c = CALIB_MAX;
      digitalWrite(hiWarn, HIGH);
    }
    else
    {
      digitalWrite(hiWarn, LOW);
    }
    int d = map(c, CALIB_MIN, CALIB_MAX, 0, 254);
//    Serial.print(" mapped to -> "); Serial.println(d);

    EEPROM.write(addr, d);   // scaled 0-254 but NOT gamma corrected value (correct Gamma at read)

    delay(10);
    unsigned int e = EEPROM.read(addr);   // read back newly written value and map to outputs for verification
    int eforward = pgm_read_byte(&gamma[e]);
    int einverse = pgm_read_byte(&gammainverse[e]);

Serial.print(e); Serial.print(","); Serial.print(eforward); Serial.print(","); Serial.println(einverse);

    analogWrite(OutputAPin, eforward);
    analogWrite(OutputBPin, einverse);

    addr = addr + 1;
    delay(SAMPLE_DELAY - 10);
    if (addr == 512)
    {
      Serial.print("EEPROM FULL");
      recordFlag = 0;
      EEPROM.write(addr, 255);
      addr = 0;
      digitalWrite(ledPin, LOW);
      Serial.println("Done");
      delay(250);
    }
  }


  /* - - - - - PLAY ON BUTTON PRESS UNTILL BUTTON PRESSED AGAIN.  RESUMES FROM LAST PLACE - - - - - */

  if (! digitalRead(playButtonPin)) {
    delay(10);
    // wait for released
    while (! digitalRead(playButtonPin));
    delay(20);
    // OK released!
//    Serial.print("Play flag was: "); Serial.print(playFlag);
    playFlag = (! playFlag);
//    Serial.print("  // Now Play Button pressed & released, play flag: "); Serial.println(playFlag);
  }

  if (playFlag == 1)
  {
 //   Serial.print("Playing at EEPROM Address: "); Serial.print(addr);
    digitalWrite(ledPin, HIGH);

    unsigned int f = EEPROM.read(addr);

 //   Serial.print("Read EE: "); Serial.print(f);
    int g = map(f, 0, 254, 0, 254);  // Output remapping (after Gamma at recording time)

    int gforward = pgm_read_byte(&gamma[g]);
    int ginverse = pgm_read_byte(&gammainverse[g]);

 //   Serial.print(" -> "); Serial.print(gforward); Serial.print(" and also to: "); Serial.println(ginverse);

    analogWrite(OutputAPin, gforward);

    analogWrite(OutputBPin, ginverse);

    delay(SAMPLE_DELAY);
    addr++;
    if (addr == 512)
    {
      addr = 0;
    }
  }
}

Thanks,
Stuart