One button for multi function

I am trying to add a One button multi function to my recently built Aquerium light to control a string of 1W RGB LED’S.Each channel of RGB is controlled by a pot and all works well except i want to use one button click to exit the loop to set a defined PWM value to the LED’S.My problem is that i think the sketch is counting the button clicks as when i get to 4 it turns off the LED’S but the are pulsing ON/OFF at button count 1 - 3.Any guidance would be very much appreciated.Incidentally my code is running on Attiny44.THE code is messy but it works fine except for the switch count function.

[ const int analogInPin_RED = 1;
 const int analogInPin_GREEN = 2;
 const int analogInPin_BLUE = 3;
 const int analogOutPin_RED = 6;
 const int analogOutPin_GREEN = 7;
 const int analogOutPin_BLUE = 8;
 const int Threshold = 120;
 const int SwitchPin = 10;
 int sensorValue_RED = 0;
 int sensorValue_GREEN = 0;
 int sensorValue_BLUE = 0;
 int outputValue_RED = 0;        
 int outputValue_GREEN = 0;
 int outputValue_BLUE = 0;
 int Red_on_LED = 0;
 int Green_on_LED = 4;
 int Blue_on_LED = 5;
 int SwitchState = 0;
 int lastSwitchState = 0;
 int Switchcounter = 0;
 
 
 void setup() {
 
 pinMode(analogInPin_RED, INPUT); 
 pinMode(analogInPin_GREEN, INPUT);
 pinMode(analogInPin_BLUE, INPUT);
 pinMode(analogOutPin_RED, OUTPUT);
 pinMode(analogOutPin_GREEN, OUTPUT);
 pinMode(analogOutPin_BLUE, OUTPUT);
 pinMode(Red_on_LED, OUTPUT);
 pinMode(Green_on_LED, OUTPUT);
 pinMode(Blue_on_LED, OUTPUT);
 pinMode(SwitchPin, INPUT);
 }
 
 void OPTION_1 (){
 analogWrite( analogOutPin_RED, 85 );
 analogWrite( analogOutPin_GREEN, 85 );
 analogWrite( analogOutPin_BLUE, 85 );
 
 }
 void OPTION_2 (){
 analogWrite( analogOutPin_RED, 127 );
 analogWrite( analogOutPin_GREEN, 127 );
 analogWrite( analogOutPin_BLUE, 127 );
 
 }
 void OPTION_3 (){
 analogWrite( analogOutPin_RED, 255 );
 analogWrite( analogOutPin_GREEN, 255 );
 analogWrite( analogOutPin_BLUE, 255 );

 }
 
 void loop() {
   
  SwitchState = digitalRead(SwitchPin);
  if (SwitchState != lastSwitchState) {
    
    if (SwitchState == LOW) {
    Switchcounter++;
    } 
    }
  
  lastSwitchState = SwitchState;
 
  while (Switchcounter == 3  ) {
  OPTION_3 ();
  }
  
  while (Switchcounter == 2  ){
  OPTION_2 ();
  }
  
  
  while (Switchcounter == 1  ){
  OPTION_1 ();
  }
  
  if(Switchcounter >3) Switchcounter ==0;
  
  
  sensorValue_RED = analogRead(analogInPin_RED);
  sensorValue_GREEN = analogRead(analogInPin_GREEN);  
  sensorValue_BLUE = analogRead(analogInPin_BLUE);  
  outputValue_RED = map(sensorValue_RED, 0, 1023, 0, 255);
  outputValue_GREEN = map(sensorValue_GREEN, 0, 1023, 0, 255);
  outputValue_BLUE = map(sensorValue_BLUE, 0, 1023, 0, 255);  
                                                                                                           
  if (sensorValue_RED > 0 && sensorValue_RED <= Threshold ){
  analogWrite( analogOutPin_RED, 0 );  
  digitalWrite(Red_on_LED,HIGH);
  delay(100);
  digitalWrite(Red_on_LED,LOW);
  delay(100);
  }
  else
  {
  analogWrite( analogOutPin_RED,outputValue_RED );  
  digitalWrite(Red_on_LED,LOW);
  }
  
  //************************************************ 
 
  if (sensorValue_GREEN > 0 && sensorValue_GREEN <= Threshold){
  analogWrite( analogOutPin_GREEN, 0 );    
  digitalWrite(Green_on_LED,HIGH);
  delay(100);
  digitalWrite(Green_on_LED,LOW);
  delay(100);
  }
  else
  {
  analogWrite( analogOutPin_GREEN,outputValue_GREEN );  
  digitalWrite(Green_on_LED,LOW);
  }
 //************************************************  
 
  if (sensorValue_BLUE > 0 && sensorValue_BLUE <= Threshold ){
  analogWrite( analogOutPin_BLUE, 0 );  
  digitalWrite(Blue_on_LED,HIGH);
  delay(100);
  digitalWrite(Blue_on_LED,LOW);
  delay(100);
  }
  else
  {
  analogWrite( analogOutPin_BLUE,outputValue_BLUE );  
  digitalWrite(Blue_on_LED,LOW);
  }
  
 }  ]

[/code]

  while (Switchcounter == 3  ) {
  OPTION_3 ();
  }

If Switchcounter equals 3 how will it ever change to another value and exit the while loop ?

You could use time duration pushes.
< 500ms

1000 < 2000
3000

http://gammon.com.au/Arduino/SwitchManager.zip
.

As already pointed out, your program will never count more than one key because it gets locked in the first matching while...

The following statemants also do not what you expect them to do

 pinMode(analogInPin_RED, INPUT);
 pinMode(analogInPin_GREEN, INPUT);
 pinMode(analogInPin_BLUE, INPUT);

Passing a 1 to analogRead uses channel 1 aka A1 (pin 19 / 25 / 55 depending on the model) passing a 1 to pinMode uses pin 1.

look at learning - references - switch case

that would work better than using while.

also think about moving the line

if(Switchcounter >3) Switchcounter ==0;

one it has == instead of just =

it also should be before the whiles in your code or it will go to 4 then pass the whiles one time before being changed to 0 (might not really matter in this instance)

gpop1: before the whiles in your code or it will go to 4 then pass the whiles one time before being changed to 0

The while constructs are senseless.

They do nothing or end the program flow (the condition does not change while executing).

I agree, the boundery check has to happen directly after the increment (before the first use at least).

if (++Counter > MAXVAL) {
  Counter = 0;
}

Thanks all i have solved my problem at last.Appreciate your advise,my working code is included for anyone else who may benefit from it.

const int analogInPin_RED = 1;
 const int analogInPin_GREEN = 2;
 const int analogInPin_BLUE = 3;
 const int analogOutPin_RED = 6;
 const int analogOutPin_GREEN = 7;
 const int analogOutPin_BLUE = 8;
 const int Threshold = 120;
 const int SwitchPin = 10;
 int sensorValue_RED = 0;
 int sensorValue_GREEN = 0;
 int sensorValue_BLUE = 0;
 int outputValue_RED = 0;        
 int outputValue_GREEN = 0;
 int outputValue_BLUE = 0;
 int Red_on_LED = 0;
 int Green_on_LED = 4;
 int Blue_on_LED = 5;
 int Switchcounter = 0;
 
 
 void setup() {
 
 pinMode(analogInPin_RED, INPUT); 
 pinMode(analogInPin_GREEN, INPUT);
 pinMode(analogInPin_BLUE, INPUT);
 pinMode(analogOutPin_RED, OUTPUT);
 pinMode(analogOutPin_GREEN, OUTPUT);
 pinMode(analogOutPin_BLUE, OUTPUT);
 pinMode(Red_on_LED, OUTPUT);
 pinMode(Green_on_LED, OUTPUT);
 pinMode(Blue_on_LED, OUTPUT);
 pinMode(SwitchPin, INPUT);
 }
 
 void OPTION_1 (){
 analogWrite( analogOutPin_RED, 85 );
 analogWrite( analogOutPin_GREEN, 85 );
 analogWrite( analogOutPin_BLUE, 85 );
 
 }
 void OPTION_2 (){
 analogWrite( analogOutPin_RED, 127 );
 analogWrite( analogOutPin_GREEN, 127 );
 analogWrite( analogOutPin_BLUE, 127 );
 
 }
 void OPTION_3 (){
 analogWrite( analogOutPin_RED, 255 );
 analogWrite( analogOutPin_GREEN, 255 );
 analogWrite( analogOutPin_BLUE, 255 );
 
 }
 
 void loop() {
   
 int SwitchState = digitalRead(SwitchPin);
 if (SwitchState == LOW){ 
 delay(500);  
 Switchcounter ++;
 if(Switchcounter == 4)
   {
     Switchcounter = 0;
   }
   }
  if (Switchcounter == 1 ) {
  OPTION_1 ();
  }
  else if (Switchcounter == 2 ){
  OPTION_2 ();
  }
  else if (Switchcounter == 3 ){
  OPTION_3 ();
  }
  else{
  sensorValue_RED = analogRead(analogInPin_RED);
  sensorValue_GREEN = analogRead(analogInPin_GREEN);  
  sensorValue_BLUE = analogRead(analogInPin_BLUE);  
  outputValue_RED = map(sensorValue_RED, 0, 1023, 0, 255);
  outputValue_GREEN = map(sensorValue_GREEN, 0, 1023, 0, 255);
  outputValue_BLUE = map(sensorValue_BLUE, 0, 1023, 0, 255);  
                                                                                                           
  if (sensorValue_RED > 0 && sensorValue_RED <= Threshold ){
  analogWrite( analogOutPin_RED, 0 );  
  digitalWrite(Red_on_LED,HIGH);
  delay(100);
  digitalWrite(Red_on_LED,LOW);
  delay(100);
  }
  else
  {
  analogWrite( analogOutPin_RED,outputValue_RED );  
  digitalWrite(Red_on_LED,LOW);
  }
  if (sensorValue_GREEN > 0 && sensorValue_GREEN <= Threshold){
  analogWrite( analogOutPin_GREEN, 0 );    
  digitalWrite(Green_on_LED,HIGH);
  delay(100);
  digitalWrite(Green_on_LED,LOW);
  delay(100);
  }
  else
  {
  analogWrite( analogOutPin_GREEN,outputValue_GREEN );  
  digitalWrite(Green_on_LED,LOW);
  }
  if (sensorValue_BLUE > 0 && sensorValue_BLUE <= Threshold ){
  analogWrite( analogOutPin_BLUE, 0 );  
  digitalWrite(Blue_on_LED,HIGH);
  delay(100);
  digitalWrite(Blue_on_LED,LOW);
  delay(100);
  }
  else
  {
  analogWrite( analogOutPin_BLUE,outputValue_BLUE );  
  digitalWrite(Blue_on_LED,LOW);
  }
  }
  }
  int SwitchState = digitalRead(SwitchPin);
  if (SwitchState == LOW) 
  {
    delay(500);
    Switchcounter ++;
    if (Switchcounter == 4)
    {
      Switchcounter = 0;
    }

This looks clumsy. Consider detecting when the button [u]becomes[/u] pressed rather than when it [u]is[/u] pressed. The StateChangeDetection example in the IDE should help.

Another thing to consider. Why are many of the variables in your code declared as ints when their value will never exceed 255 ? You could save memory by declaring them as byte.

Yes i know my code is very messy,but it's a start and it work's.I appreciate what you are saying and i am very happy to take your advise.Small steps at a time i guess.But thank's again for your help

Guy’s i’m back need more help please.

I have added (well have tried to) option 4 to my project.This option is to cycle through a series of LED fades using For Loops.Problem is i just cannot exit this option on button count 5.I’ve had all different types of results while trying the While Loop and Switch functions except the one that i need and i just can’t get my head round it.Again i know my code is very clumsy,but i am trying and am willing to learn.Please bear with me on this and any advise or pointers are always welcome.

Thank You

const int analogInPin_RED = 1;
  const int analogInPin_GREEN = 2;
  const int analogInPin_BLUE = 3;
  const int analogOutPin_RED = 6;
  const int analogOutPin_GREEN = 7;
  const int analogOutPin_BLUE = 8;
  const int Threshold = 120;
  const int SwitchPin = 10;
  int sensorValue_RED = 0;
  int sensorValue_GREEN = 0;
  int sensorValue_BLUE = 0;
  int outputValue_RED = 0;        
  int outputValue_GREEN = 0;
  int outputValue_BLUE = 0;
  int Red_on_LED = 0;
  int Green_on_LED = 4;
  int Blue_on_LED = 5;
  int Switchcounter = 0;
  int fadeValue = 0;
 
  void setup() {
 
  pinMode(analogInPin_RED, INPUT); 
  pinMode(analogInPin_GREEN, INPUT);
  pinMode(analogInPin_BLUE, INPUT);
  pinMode(analogOutPin_RED, OUTPUT);
  pinMode(analogOutPin_GREEN, OUTPUT);
  pinMode(analogOutPin_BLUE, OUTPUT);
  pinMode(Red_on_LED, OUTPUT);
  pinMode(Green_on_LED, OUTPUT);
  pinMode(Blue_on_LED, OUTPUT);
  pinMode(SwitchPin, INPUT);
  }
  void OPTION_1 (){
  analogWrite( analogOutPin_RED, 50 );//255
  analogWrite( analogOutPin_GREEN, 0 ); //YELLOW //215
  analogWrite( analogOutPin_BLUE, 0 );//0
  }
  void OPTION_2 (){
  analogWrite( analogOutPin_RED, 100 ); //238
  analogWrite( analogOutPin_GREEN, 100 );  //PURPLE //0
  analogWrite( analogOutPin_BLUE, 0 ); //238
  }
  void OPTION_3 (){
  analogWrite( analogOutPin_RED, 255 ); //255
  analogWrite( analogOutPin_GREEN, 255 );  //ORANGE //69
  analogWrite( analogOutPin_BLUE, 255 );  //0
  }
  void OPTION_4 (){
    
  analogWrite( analogOutPin_RED, 0 );
  analogWrite( analogOutPin_GREEN, 0 ); 
  analogWrite( analogOutPin_BLUE, 0 );
  delay(20);
  
  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
  analogWrite(analogOutPin_RED, fadeValue);         
  delay(200);                            
  }
  for( fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
  analogWrite(analogOutPin_RED, fadeValue);         
  delay(200);                            
  } 
  for( fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
  analogWrite(analogOutPin_GREEN, fadeValue);         
  delay(200);                            
  }
  for( fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
  analogWrite(analogOutPin_GREEN, fadeValue);         
  delay(200);                            
  }
  for( fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
  analogWrite(analogOutPin_BLUE, fadeValue);         
  delay(200);                            
  }
  for( fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
  analogWrite(analogOutPin_BLUE, fadeValue);         
  delay(200);
  }
  }
 
 void loop() {
 
 int switchVal = digitalRead(SwitchPin);
 if(switchVal == LOW)
  {
 delay(500);  
 Switchcounter ++;
   
 if(Switchcounter == 5)
  {
    Switchcounter = 0;
  }
  }

 else
 
   switch (Switchcounter) {
   case 1:
     OPTION_1 ();
     break;
   case 2:
     OPTION_2 ();
     break;
   case 3:
     OPTION_3 ();
     break;
   case 4:
     OPTION_4 ();
     break;
   
   }
   }

I think i may have sorted my code problem out but i would like some clarification.According to the link below Attiny44 does not support the While function.Again i'm not sure of this but it makes sense as i was sure that my code was OK if not clumsy.

http://tronixstuff.com/2011/11/23/using-an-attiny-as-an-arduino/

The list given is of supported [u]Arduino[/u] functions. while is not an Arduino function it is a C function.

whats the else doing In loop of the code you posted ?

I think that's a problem

Sorry the else shouldn't be there forgot to delete it.So are you saying that the Attiny does or does not support the while function.I have uploaded the code to an UNO and just connected a momentary switch via a pullup resistor and added some serial statements to check switchcounter values and all works OK.This is what is making me believe that there is a problem with the while function and the Attiny.I cannot test this with the Attiny as serial is not supported.

It should be trivial to test whether it supports the while function, although I would be surprised if it didn’t as it is such a basic construct in C. Perhaps read an input and while it is HIGH repeatedly take an output HIGH for a period then LOW for a period otherwise do the HIGH/LOW output for a different period so that you can distinguish between them.

Thank You for your reply,i do appreciate it.Can i ask you how you would modify my code for OPTION_4 (); so that it will exit the for loop's when switch is pressed for the fifth time and reset to zero.As i've said i have tried everything with varying results except what i need.

have you tested since you removed the "else" ?

Hi sorry havn't tested it yet without the else as i'm not home at the moment.However i have taken you advise on board and plan to try it when i'm home.Thank's for your help

This is my latest attempt it works fine as long as switch is low when for loop for blue is at the end. if i press switch LOW during this cycle it does not recognie it. my head is wrecked.

 const int analogInPin_RED = 1;
  const int analogInPin_GREEN = 2;
  const int analogInPin_BLUE = 3;
  const int analogOutPin_RED = 6;
  const int analogOutPin_GREEN = 7;
  const int analogOutPin_BLUE = 8;
  const int Threshold = 120;
  const int SwitchPin = 10;
  int sensorValue_RED = 0;
  int sensorValue_GREEN = 0;
  int sensorValue_BLUE = 0;
  int outputValue_RED = 0;        
  int outputValue_GREEN = 0;
  int outputValue_BLUE = 0;
  int Red_on_LED = 0;
  int Green_on_LED = 4;
  int Blue_on_LED = 5;
  int Switchcounter = 0;
  int green_led = 9;
 
  void setup() {
 
  pinMode(analogInPin_RED, INPUT); 
  pinMode(analogInPin_GREEN, INPUT);
  pinMode(analogInPin_BLUE, INPUT);
  pinMode(analogOutPin_RED, OUTPUT);
  pinMode(analogOutPin_GREEN, OUTPUT);
  pinMode(analogOutPin_BLUE, OUTPUT);
  pinMode(Red_on_LED, OUTPUT);
  pinMode(Green_on_LED, OUTPUT);
  pinMode(Blue_on_LED, OUTPUT);
  pinMode(green_led, OUTPUT);
  pinMode(SwitchPin, INPUT);
  }
  void OPTION_0 (){
  
  sensorValue_RED = analogRead(analogInPin_RED);
  sensorValue_GREEN = analogRead(analogInPin_GREEN);  
  sensorValue_BLUE = analogRead(analogInPin_BLUE);  
  outputValue_RED = map(sensorValue_RED, 0, 1023, 0, 255);
  outputValue_GREEN = map(sensorValue_GREEN, 0, 1023, 0, 255);
  outputValue_BLUE = map(sensorValue_BLUE, 0, 1023, 0, 255);  
                                                                                                           
  if (sensorValue_RED > 0 && sensorValue_RED <= Threshold ){
  analogWrite( analogOutPin_RED, 0 );  
  digitalWrite(Red_on_LED,HIGH);
  delay(100);
  digitalWrite(Red_on_LED,LOW);
  delay(100);
  }
  else
  {
  analogWrite( analogOutPin_RED,outputValue_RED );  
  digitalWrite(Red_on_LED,LOW);
  }
  if (sensorValue_GREEN > 0 && sensorValue_GREEN <= Threshold){
  analogWrite( analogOutPin_GREEN, 0 );    
  digitalWrite(Green_on_LED,HIGH);
  delay(100);
  digitalWrite(Green_on_LED,LOW);
  delay(100);
  }
  else
  {
  analogWrite( analogOutPin_GREEN,outputValue_GREEN );  
  digitalWrite(Green_on_LED,LOW);
  }
  if (sensorValue_BLUE > 0 && sensorValue_BLUE <= Threshold ){
  analogWrite( analogOutPin_BLUE, 0 );  
  digitalWrite(Blue_on_LED,HIGH);
  delay(100);
  digitalWrite(Blue_on_LED,LOW);
  delay(100);
  }
  else
  {
  analogWrite( analogOutPin_BLUE,outputValue_BLUE );  
  digitalWrite(Blue_on_LED,LOW);
  }
  
  }

  
 
  void OPTION_1 (){
  analogWrite( analogOutPin_RED, 255 ); 
  analogWrite( analogOutPin_GREEN, 255 );  //WHITE
  analogWrite( analogOutPin_BLUE, 255 ); 
  }
  void OPTION_2 (){
   analogWrite( analogOutPin_RED, 255 ); 
  analogWrite( analogOutPin_GREEN, 0 );  //RED
  analogWrite( analogOutPin_BLUE, 0 );
  }
  void OPTION_3 (){
   analogWrite( analogOutPin_RED, 0 ); 
  analogWrite( analogOutPin_GREEN, 255 );  //GREEN
  analogWrite( analogOutPin_BLUE, 0 ); 
  }
  void OPTION_4 (){
   analogWrite( analogOutPin_RED, 0 ); 
  analogWrite( analogOutPin_GREEN, 0 );  //BLUE
  analogWrite( analogOutPin_BLUE, 255 );
  }
  void OPTION_5 (){
  analogWrite( analogOutPin_RED, 255 );
  analogWrite( analogOutPin_GREEN, 215 ); //YELLOW 
  analogWrite( analogOutPin_BLUE, 0 );
  }
  void OPTION_6 (){
  analogWrite( analogOutPin_RED, 238 ); 
  analogWrite( analogOutPin_GREEN, 0 );  //PURPLE
  analogWrite( analogOutPin_BLUE, 238 ); 
  }
  void OPTION_7 (){
  analogWrite( analogOutPin_RED, 255 ); 
  analogWrite( analogOutPin_GREEN, 69 );  //ORANGE 
  analogWrite( analogOutPin_BLUE, 0 );  
  }
   void OPTION_8 (){
   
  analogWrite( analogOutPin_RED, 0 );
  analogWrite( analogOutPin_GREEN, 0 );
  analogWrite( analogOutPin_BLUE, 0 );
  delay(20);
 
  int x = 1;
   for (int i = 0; i > -1; i = i + x){
      analogWrite(analogOutPin_RED, i);
      if (i == 255) x = -1;             // FADE RED
      delay(10);
   }
   
  int y = 1;
   for (int i = 0; i > -1; i = i + y){
      analogWrite(analogOutPin_GREEN, i);
      if (i == 255) y = -1;             // FADE GREEN
      delay(10);
   }
   
   
  int z = 1;
   for (int i = 0; i > -1; i = i + z){
      analogWrite(analogOutPin_BLUE, i);
      if (i == 255) z = -1;             // FADE BLUE
      delay(10);
   }
   
  }
 
  
  void loop() {
   
  int SwitchState = digitalRead(SwitchPin);
  if (SwitchState == LOW){
  digitalWrite( green_led,HIGH );
  delay(50);
  digitalWrite( green_led,LOW );  
  delay(500);  
  Switchcounter ++;
  
  if(Switchcounter == 9)
  Switchcounter = 0;
  
  }
   if (Switchcounter == 0 ) {
  OPTION_0 ();
  }
  else if (Switchcounter == 1 ) {
  OPTION_1 ();
  }
  else if (Switchcounter == 2 ){
  OPTION_2 ();
  }
  else if (Switchcounter == 3 ){
  OPTION_3 ();
  }
  else if (Switchcounter == 4 ){
  OPTION_4 ();
  }
  else if (Switchcounter == 5 ){
  OPTION_5 ();
  }
  else if (Switchcounter == 6 ){
  OPTION_6 ();
  }
  else if (Switchcounter == 7 ){
  OPTION_7 ();
  }
  else if (Switchcounter == 8 ){
  OPTION_8 ();
  }
  }

You only read the color sensors once, here at the start of this function

  void OPTION_0 (){
  
  sensorValue_RED = analogRead(analogInPin_RED);
  sensorValue_GREEN = analogRead(analogInPin_GREEN);  
  sensorValue_BLUE = analogRead(analogInPin_BLUE);

You could try reading each one twice (RED twice, Green twice, Blue twice), gives the analog value some time to stabilize before the ADC does the conversion.

You only read the switch pin once,

void loop() {
   
  int SwitchState = digitalRead(SwitchPin);
  if (SwitchState == LOW){

I would enable the internal pullup for that pin, change this line in setup() pinMode(SwitchPin, INPUT); to pinMode(SwitchPin, INPUT_PULLUP); so the pin is not just floating around, and eventually drifting up to a high level.

You also have that 1/2 second delay & other delays that would make the button seem unresponsive.