Controlling RGB LED using PWM on digital pins

I've a simple program I've started to control RGB LEDs with PWM on an Arduino nano. Its in its early stage of programming. And the Serial output is not what I am expecting. I've attached my code, and the Serial Monitor Capture. Can anyone tell me what is happening here....


unsigned long Counter;
/*  Pin 13:  1 Second Square Wave   Timer1 interrupt)
  Pin 8:  1KHz Square wave oscillator (0 to 5V amplitude)   Timer-0 interrupt
  Pin 9:  4 Khz square wave oscillator  Timer-2 interrupt
  Looking with Oscilloscope.  These are very Square, and accurate.
    998.5 KHz   & 3.99KHz


  //timer interrupts
  //by Amanda Ghassaei
  //June 2012
  //http://www.instructables.com/id/Arduino-Timer-Interrupts/

  /*
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

*/

//timer setup for timer0, timer1, and timer2.
//For arduino uno or any board with ATMEL 328/168.. diecimila, duemilanove, lilypad, nano, mini...

//this code will enable all three arduino timer interrupts.
//timer0 will interrupt at 2kHz
//timer1 will interrupt at 1Hz
//timer2 will interrupt at 8kHz

//Initial LED setting for each of 14 bottle RGB LED's.
//  The next LED's value is off by about 20 from previous
int RED[14] = {255, 236, 216, 196, 176, 156, 136, 116, 96, 76, 56, 36, 16, 0};
int GRN[14] = {0, 16, 36, 56, 76, 96, 116, 136, 156, 176, 196, 216, 236, 255};
int BLU[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int Pointer[14] = {0, 16, 36, 56, 76, 96, 116, 136, 156, 176, 196, 216, 236, 255};
int Cnt = 0;

//storage variables
boolean toggle0 = 0;
boolean toggle1 = 0;
boolean toggle2 = 0;

void setup() {
  Serial.begin(115200);
  Serial.print("Interrupt Setup Example V2.sco  6/30/21 by LJT   Preliminary\n\n");

  //set pins as outputs
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);

  cli();//stop interrupts
  /*
      //set timer0 interrupt at 2kHz
      TCCR0A = 0;// set entire TCCR2A register to 0
      TCCR0B = 0;// same for TCCR2B
      TCNT0  = 0;//initialize counter value to 0
      // set compare match register for 2khz increments
      OCR0A = 124;// = (16*10^6) / (2000*64) - 1 (must be <256)
      // turn on CTC mode
      TCCR0A |= (1 << WGM01);
      // Set CS01 and CS00 bits for 64 prescaler
      TCCR0B |= (1 << CS01) | (1 << CS00);
      // enable timer compare interrupt
      TIMSK0 |= (1 << OCIE0A);

  //set timer1 interrupt at 1Hz
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  // set compare match register for 1hz increments
  OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS12 and CS10 bits for 1024 prescaler
  TCCR1B |= (1 << CS12) | (1 << CS10);
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
  
      //set timer2 interrupt at 8kHz
      TCCR2A = 0;// set entire TCCR2A register to 0
      TCCR2B = 0;// same for TCCR2B
      TCNT2  = 0;//initialize counter value to 0
      // set compare match register for 8khz increments
      OCR2A = 249;// = (16*10^6) / (8000*8) - 1 (must be <256)
      // turn on CTC mode
      TCCR2A |= (1 << WGM21);
      // Set CS21 bit for 8 prescaler
      TCCR2B |= (1 << CS21);
      // enable timer compare interrupt
      TIMSK2 |= (1 << OCIE2A);
  */

  sei();//allow interrupts

}//end setup

/*
ISR(TIMER0_COMPA_vect) { //timer0 interrupt 2kHz toggles pin 8
  //generates pulse wave of frequency 2kHz/2 = 1kHz (takes two cycles for full wave- toggle high then toggle low)

}

ISR(TIMER1_COMPA_vect) { //timer1 interrupt 1Hz toggles pin 13 (LED)
  //generates pulse wave of frequency 1Hz/2 = 0.5kHz (takes two cycles for full wave- toggle high then toggle low)
 //Serial.println("\n\t\t1Hz\n");
}

ISR(TIMER2_COMPA_vect) { //timer1 interrupt 8kHz toggles pin 9
  //generates pulse wave of frequency 8kHz/2 = 4kHz (takes two cycles for full wave- toggle high then toggle low)

}
*/

void loop() {
  //Will Set the value for each set of LEDs for each of 14 bottles
  //the PWM takes place in an intCnt++){
  Serial.println(".");
  
  for (int LED = 0; LED <= 13; LED++) {
    Serial.print("LED="); 
    Serial.print(LED); 
    //Serial.print("\tPointer[]= ");
    /*
        if (Cnt <= 255) {   //Zone 1
          RED[Pointer[LED]] = Cnt;
          GRN[Pointer[LED]] = 255 - Cnt;
          BLU[Pointer[LED]] = 0;
        }
        if (Cnt > 255 && Cnt <= 511) {  //Zone 2
          RED[Pointer[LED]] = 511 - Cnt;
          GRN[Pointer[LED]] = 0;
          BLU[Pointer[LED]] = Cnt - 255;
        }
        if (Cnt > 511 && Cnt <= 767) {  //Zone 3
          RED[Pointer[LED]] = 0;
          GRN[Pointer[LED]] = Cnt - 511;
          BLU[Pointer[LED]] = 767 - Cnt;
        }
    */
    if (RED[Pointer[LED]]>=256) { 
        RED[Pointer[LED]]=0;
    } else if (RED[Pointer[LED]] < 0) {
      RED[Pointer[LED]]=0; 
    } 
    
    if (GRN[Pointer[LED]]>=256) {
      GRN[Pointer[LED]]=0;
    } else if (GRN[Pointer[LED]] < 0) {
      GRN[Pointer[LED]]=0; 
    } 
    
    if (BLU[Pointer[LED]]>=256) {
      BLU[Pointer[LED]]=0; 
    } else if (BLU[Pointer[LED]] < 0) {
      BLU[Pointer[LED]]=0; 
    } 
      
    
    Serial.print("........\t");
    Serial.print(Pointer[LED]); Serial.print("\tR: ");
    Serial.print(RED[Pointer[LED]]); Serial.print("\tG: ");
    Serial.print(GRN[Pointer[LED]]); Serial.print("\tB: ");
    Serial.println(BLU[Pointer[LED]]);
    


    if (Pointer[LED] <= 767) {
      Pointer[LED] = Pointer[LED] + 1;
    } else {
      Pointer[LED] = 0;
    }//endif
    
  } //END FOR


  delay(3000);//temp delay 1 second to look at printout

} //End Sub



/* Arrays RED[], GRN[], BLU[] contain the value of that Bottles RGB-LED between 0 and 255

*/

void SetOutputs() {
  static int PWMvalue;
  PWMvalue++;

  for (int LEDPtr = 0; LEDPtr <= 13; LEDPtr++) {
    if (RED[LEDPtr] < PWMvalue) {
      digitalWrite(RED[LEDPtr], HIGH);
    } else {
      digitalWrite(RED[LEDPtr], LOW);
    }

    if (GRN[LEDPtr] < PWMvalue) {
      digitalWrite(GRN[LEDPtr], HIGH);
    } else {
      digitalWrite(GRN[LEDPtr], LOW);
    }

    if (BLU[LEDPtr] < PWMvalue) {
      digitalWrite(BLU[LEDPtr], HIGH);
    } else {
      digitalWrite(BLU[LEDPtr], LOW);
    }
  }//endfor
}//end sub


This is what the Serial output looks like...

Blockquote

had to send this as an image, cause cutting and pasting was not working...

Blockquote
Issues I am Seeing:

  • List item

Seems to reboot and redo the Setup. I dont think that should be happening.
Also you can see the printout is not aligning (first instance around "LED=5"
After first instance of "LED=13", get some garage numbers... then see the Print from Setup() routing.
Any ideas... I sure this is something simple, and I'm just not seeing it. Any help greatly appreciated.

I'll not download code. Read the forum guidelines to see how to post code.

The resetting behavior is often caused by writing outside the bounds of an array into memory that you do not "own". Examine all array operations.

Thanks for the feedback on the rules. Hopefully i've reposted the code in the appropriate manner.

I believe the following code will fix my problem... testing it out now...


    if ((RED[LED] >= 256) || (RED[LED] < 0)) {
      RED[LED] = 0;
    }
    Serial.print("\tR: "); Serial.print(RED[LED]); 
    
    if ((GRN[LED] >= 256) || (GRN[LED] < 0)) {
      GRN[LED] = 0;
    }
    Serial.print("\tG: "); Serial.print(GRN[LED]);
    
    if ((BLU[LED] >= 256) || (BLU[LED] < 0)) {
      BLU[LED] = 0;
    }
    Serial.print("\tB: "); Serial.println(BLU[LED]);

Thank you groundFungus

Pointer[LED] is a value up to 255. RED[] only has 14 elements. You are mucking with data WAY off the end of the arrays. This causes a crash.

How many leds are there ? do you have resistors with those leds ?

To dim a led, the Arduino has a analogWrite() function that creates a PWM signal for you.
https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/
As you can see on that page, not all pins can be used, only 3, 5, 6, 9, 10, and 11.

There is a library to create a software PWM on any pin. It takes some time to learn how to use it, but it is a well thought-out library.
https://github.com/Palatis/arduino-softpwm

Thank you I have converted to using the sofware PWM, and Im having better results.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.