some code snippet - i have redone the programming sequence as I found it a bit rough..
You will need.
#include <avr/pgmspace.h>
and at the moment i have serial debug output, so I define the strings as such..
const PROGMEM char c_ProgrammingMode[] = "Programming Mode = 0 = no, 1 = yes\r\n";
const PROGMEM char c_Programming[] = "Programming Mode = %d %d\r\n";
const PROGMEM char c_ProgramComplete[] = "Program Complete\r\n";
const PROGMEM char c_MagSwitch[] = "Mag Switch? 1 = on, 2 = off\r\n";
const PROGMEM char c_MagSwitchCount[] = "Mag Switch = %d %d\r\n";
const PROGMEM char c_MotorSpeed[] = "Motor Speed? 1 = 100%%, 2 = 90%%, 3 = 80%%,... 10 = 10%%\r\n";
const PROGMEM char c_MotorSpeedCount[] = "Motor Speed = %d %d\r\n";
const PROGMEM char c_SniperDelay[] = "Sniper Delay? 1 = None, 2 = 1 Sec, 3 = 2 Sec,... 11 = 10 Sec\r\n";
const PROGMEM char c_SniperDelayCount[] = "Sniper Delay = %d %d\r\n";
const PROGMEM char c_BrakingOff[] = "Brake? 1 = On, 2 = Off\r\n";
const PROGMEM char c_BrakingOffCount[] = "Brake = %d %d\r\n";
const PROGMEM char c_DebugTriggerCount[] = "Count = %d\r\n";
const PROGMEM char c_DebugTriggerSelect[] = "Trigger Select = %d %d %d\r\n";
enum eIncDec {mINCREMENT,mDECREMENT};
I also did the enum above as I am using C++, it can be changed, if you want to leave out the debug strings, that bit can be removed.
Now, the first bit, is to define the program, using an array of structures, BTW, i use the progmem here to free up ram (and its static)..
struct ProgramItem
{
eIncDec incdec; // increment value or decrement
uint8_t countstart; // start counter vaule
uint8_t maxcount; // max counter value
uint8_t defaultcount; // default value -if no trigger press
const char *serialDebugQ; // debug question, remove if not using serial debug
const char *serialDebugR; // debug answer, remove if not using serial debug.
};
#define ProgramItemsCount 5
const PROGMEM ProgramItem ProgramItems[ProgramItemsCount] =
{
{mINCREMENT,0, 1,0, c_ProgrammingMode,c_Programming},
{mINCREMENT,0, 2,1, c_MagSwitch ,c_MagSwitchCount},
{mINCREMENT,0,11,1, c_MotorSpeed ,c_MotorSpeedCount},
{mINCREMENT,0,11,1, c_SniperDelay ,c_SniperDelayCount},
{mINCREMENT,0, 2,1, c_BrakingOff ,c_BrakingOffCount},
};
you might see that there is no ID or vibrate count, i take that from the index in the array, then the programming function is reduced to..
void Programming::Program()
{
uint8_t Count = 0;
Motor::Vibrate(1000, 30, 50);
for(uint8_t i = 0; i < ProgramItemsCount; i++)
{
Serial::printf_P((char*)pgm_read_word(&ProgramItems[i].serialDebugQ));
VibrateSignal(i+1);
Count = GetTriggerSelect(
pgm_read_byte(&ProgramItems[i].countstart),
pgm_read_byte(&ProgramItems[i].incdec),
pgm_read_byte(&ProgramItems[i].maxcount)
);
if(Count == 0)
Count = pgm_read_byte(&ProgramItems[i].defaultcount);
uint8_t newValue;
bool act = Action(i,Count,newValue);
Serial::printf_P((char*)pgm_read_word(&ProgramItems[i].serialDebugR),Count,newValue);
if(!act)
return;
}
Serial::printf_P(c_ProgramComplete);
}
[code]
To set the menu value, the above calls Action, which has a simple case statement to set the menu values.
bool Programming::Action(uint8_t item, uint8_t value, uint8_t newValue)
{
switch(item)
{
case 0:
if(value == 0)
return false;
break;
case 1:
mMagSwitchEnabled = value == 1;
newValue = value;
break;
case 2:
mMotorSpeed = ((255 * (11 - value)) / 10);
newValue = mMotorSpeed;
break;
case 3:
mSniperDelay = (value - 1) * 1000;
newValue = mSniperDelay;
break;
case 4:
mBrakeEnabled = value == 1;
newValue = value;
break;
}
return true;
}
[/code]
This makes adding new items fairly simple, just add a line into "ProgramItems" and an additional case into "Action".

I am a happy boy when coding things.. or shooting people..
