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;
}
}
}