Thanks to @Grumpy_Mike, I came up with this sketch:
//Thanks to Grumpy_Mike and tuxduino on the Arduino.cc boards
unsigned long keyPrevMillis = 0;
const unsigned long keySampleIntervalMs = 25;
int redPin = 11;
int greenPin = 10;
int bluePin = 9;
int LEDcolor=0; // 0=White, 1=Red, 2=Orange, 3=Yellow, 4=Green, 5-Blue, 6=Purple, 7=Pink
int LEDstatus =0; //0=Off, 1=On
int changed =0; //has the LEDstatus just changed?
byte longKeyPressCountMax = 80; // 80 * 25 = 2000 ms
byte longKeyPressCount = 0;
byte prevKeyState = HIGH; // button is active low
const byte keyPin = 2; // button is connected to pin 2 and GND
// called when button is kept pressed for less than 2 seconds
void shortKeyPress()
{
Serial.println("short");
if (LEDstatus==1)
{
LEDcolor = LEDcolor +1;
if (LEDcolor==8) {LEDcolor=0;}
if (LEDcolor==0) {analogWrite(redPin, 0);analogWrite(greenPin, 0);analogWrite(bluePin, 0);Serial.println("White");}
if (LEDcolor==1) {analogWrite(redPin, 0);analogWrite(greenPin, 255);analogWrite(bluePin, 255);Serial.println("Red");}
if (LEDcolor==2) {analogWrite(redPin, 5);analogWrite(greenPin, 215);analogWrite(bluePin, 255);Serial.println("Orange");}
if (LEDcolor==3) {analogWrite(redPin, 0);analogWrite(greenPin, 0);analogWrite(bluePin, 255);Serial.println("Yellow");}
if (LEDcolor==4) {analogWrite(redPin, 255);analogWrite(greenPin, 0);analogWrite(bluePin, 255);Serial.println("Green");}
if (LEDcolor==5) {analogWrite(redPin, 255);analogWrite(greenPin, 255);analogWrite(bluePin, 0);Serial.println("Blue");}
if (LEDcolor==6) {analogWrite(redPin, 175);analogWrite(greenPin, 255);analogWrite(bluePin, 175);Serial.println("Purple");}
if (LEDcolor==7) {analogWrite(redPin, 0);analogWrite(greenPin, 255);analogWrite(bluePin, 155);Serial.println("Pink");}
}
else
{
Serial.println("NOTHING");
}
}
// called when button is kept pressed for more than 2 seconds
void longKeyPress()
{
Serial.println("long");
if (LEDstatus==0 && changed==0)
{
if (LEDcolor==0) {analogWrite(redPin, 0);analogWrite(greenPin, 0);analogWrite(bluePin, 0);}
if (LEDcolor==1) {analogWrite(redPin, 0);analogWrite(greenPin, 255);analogWrite(bluePin, 255);}
if (LEDcolor==2) {analogWrite(redPin, 5);analogWrite(greenPin, 215);analogWrite(bluePin, 255);}
if (LEDcolor==3) {analogWrite(redPin, 0);analogWrite(greenPin, 0);analogWrite(bluePin, 255);}
if (LEDcolor==4) {analogWrite(redPin, 255);analogWrite(greenPin, 0);analogWrite(bluePin, 255);}
if (LEDcolor==5) {analogWrite(redPin, 255);analogWrite(greenPin, 255);analogWrite(bluePin, 0);}
if (LEDcolor==6) {analogWrite(redPin, 175);analogWrite(greenPin, 255);analogWrite(bluePin, 175);}
if (LEDcolor==7) {analogWrite(redPin, 0);analogWrite(greenPin, 255);analogWrite(bluePin, 155);}
changed=1;
LEDstatus=1;Serial.println("On");
}
if (LEDstatus==1 && changed==0)
{
analogWrite(redPin, 255);
analogWrite(greenPin, 255);
analogWrite(bluePin, 255);
changed=1;
LEDstatus=0;Serial.println("Off");
}
longKeyPressCount = 0;
}
// called when key goes from not pressed to pressed
void keyPress() {
Serial.print("key press / ");
longKeyPressCount = 0;
}
// called when key goes from pressed to not pressed
void keyRelease()
{
Serial.println("key release");
if (longKeyPressCount < longKeyPressCountMax && changed==0) {
shortKeyPress();
}
changed=0;
}
void setup()
{
Serial.begin(9600);
pinMode(keyPin, INPUT);
digitalWrite(keyPin, HIGH);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
analogWrite(redPin, 255);
analogWrite(greenPin, 255);
analogWrite(bluePin, 255);
}
void loop() {
// key management section
if (millis() - keyPrevMillis >= keySampleIntervalMs) {
keyPrevMillis = millis();
byte currKeyState = digitalRead(keyPin);
if ((prevKeyState == HIGH) && (currKeyState == LOW)) {
keyPress();
}
else if ((prevKeyState == LOW) && (currKeyState == HIGH)) {
keyRelease();
}
else if (currKeyState == LOW) {
longKeyPressCount++;
}
prevKeyState = currKeyState;
}
if (longKeyPressCount >= longKeyPressCountMax) {
longKeyPress();
}
}
and it works exactly the way I want it to. I used it as an Arduino/breadboard prototype to show a PCB manufacturer EXACTLY what I want the product to do.
If I want the final product to be an open-source piece of equipment where anyone could hook up and modify the code, is there a chip that I should insist that the manufacturer uses? It looks like the AT Tiny45 would work, but I want to try and go SMALL if I can and just leave pins for hooking up to an Arduino.
Am I stuck with the AT Tiny45, or is there a better choice?
Edit:
I got the idea from this: