Mega 2560 RGBWW dimmer

Hi all, been googling my butt off and tinkering with my code a bunch but I have run into some problems. This devices is based off a project on MySensors and I have posted in that forum. However the more digging I do the more I think the problem is related to something I must not understand about the Mega, so I’m posting here.

My problem is that I can’t get the anologWrite method of PWM working on my project.

#define MY_DEBUG
#define MY_RADIO_NRF24
#define MY_NODE_ID 22

#define SN   "Dimmable RGBW Led strip"
#define SV   "v1.0"

#define MY_RF24_CE_PIN 49 //atmega 2560 code
#define MY_RF24_CS_PIN 53 //atmega 2560 code

#include <MySensors.h>
#include <SPI.h>

// Arduino pin attached to MOSFET Gate pin
#define LED_RED_PIN 6
#define LED_GREEN_PIN 5
#define LED_BLUE_PIN 7
#define LED_WHITE_PIN 8
// CHILD ID's
#define CHILD_ID_RED 1
#define CHILD_ID_GREEN 2
#define CHILD_ID_BLUE 3
#define CHILD_ID_WHITE 4
// Bunch of dimmer values
#define FADE_DELAY 10 // MS delay, IE how long in between each dim step.
int RequestedColor = 0; // Variable for incoming message color
static int16_t currentLevelWhite = 0;  // Current dim level...
static int16_t currentLevelRed = 0;
static int16_t currentLevelGreen = 0;
static int16_t currentLevelBlue = 0;

// Define message name and type to send sensor info
MyMessage RedStatus(CHILD_ID_RED, V_DIMMER);		
MyMessage GreenStatus(CHILD_ID_GREEN, V_DIMMER);
MyMessage BlueStatus(CHILD_ID_BLUE, V_DIMMER);
MyMessage WhiteStatus(CHILD_ID_WHITE, V_DIMMER);
     
void setup() 
{
  pinMode( LED_RED_PIN, OUTPUT );
  pinMode( LED_GREEN_PIN, OUTPUT );
  pinMode( LED_BLUE_PIN, OUTPUT );
  pinMode( LED_WHITE_PIN, OUTPUT );
  request( CHILD_ID_RED, V_DIMMER );
  request( CHILD_ID_GREEN, V_DIMMER );
  request( CHILD_ID_BLUE, V_DIMMER );
  request( CHILD_ID_WHITE, V_DIMMER );
}

void presentation()
{
  present( CHILD_ID_RED, V_DIMMER );
  present( CHILD_ID_GREEN, V_DIMMER );
  present( CHILD_ID_BLUE, V_DIMMER );
  present( CHILD_ID_WHITE, V_DIMMER );
  sendSketchInfo(SN, SV);
}

void loop()
{
  
}


void receive(const MyMessage &message)
{
	if (message.type == V_LIGHT || message.type == V_DIMMER) {

                Serial.print("Which sensor did we get a message for? : ");
                Serial.println(message.sensor);
                RequestedColor = (message.sensor);
                
		//  Retrieve the power or dim level from the incoming request message
		int requestedLevel = atoi( message.data );

		// Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on]
		requestedLevel *= ( message.type == V_LIGHT ? 100 : 1 );

		// Clip incoming level to valid range of 0 to 100
		requestedLevel = requestedLevel > 100 ? 100 : requestedLevel;
		requestedLevel = requestedLevel < 0   ? 0   : requestedLevel;

                if(RequestedColor == CHILD_ID_WHITE) {
                  Serial.print( "Changing White level to " );
		  Serial.print( requestedLevel );
		  Serial.print( ", from " );
		  Serial.println( currentLevelWhite );
		  fadeToLevelWhite( requestedLevel );
                }else if(RequestedColor == CHILD_ID_RED) {
		  Serial.print( "Changing Red level to " );
		  Serial.print( requestedLevel );
		  Serial.print( ", from " );
		  Serial.println( currentLevelRed );
		  fadeToLevelRed( requestedLevel );
                }else if(RequestedColor == CHILD_ID_GREEN) {
		  Serial.print( "Changing Green level to " );
		  Serial.print( requestedLevel );
		  Serial.print( ", from " );
		  Serial.println( currentLevelGreen );
		  fadeToLevelGreen( requestedLevel );
                }else if(RequestedColor == CHILD_ID_BLUE) {
		  Serial.print( "Changing Blue level to " );
		  Serial.print( requestedLevel );
		  Serial.print( ", from " );
		  Serial.println( currentLevelBlue );
		  fadeToLevelBlue( requestedLevel );
                }
                
		// Inform the gateway of the current DimmableLED's SwitchPower1 and LoadLevelStatus value...
//		send(lightMsg.set(currentLevel > 0));

		// hek comment: Is this really nessesary?
//		send( dimmerMsg.set(currentLevel) );
	}
}

/***
 *  This method provides a graceful fade up/down effect
 */
void fadeToLevelRed( int toLevel ) {

  int delta = ( toLevel - currentLevelRed ) < 0 ? -1 : 1;
  
  while ( currentLevelRed != toLevel ) {
    currentLevelRed += delta;
    analogWrite( LED_RED_PIN, (int)(currentLevelRed / 100. * 255) );
    Serial.println(currentLevelRed);
    delay( FADE_DELAY );
  }
}

void fadeToLevelGreen( int toLevel ) {

  int delta = ( toLevel - currentLevelGreen ) < 0 ? -1 : 1;
  
  while ( currentLevelGreen != toLevel ) {
    currentLevelGreen += delta;
    analogWrite( LED_GREEN_PIN, (int)(currentLevelGreen / 100. * 255) );
    delay( FADE_DELAY );
  }
}

void fadeToLevelBlue( int toLevel ) {

  int delta = ( toLevel - currentLevelBlue ) < 0 ? -1 : 1;
  
  while ( currentLevelBlue != toLevel ) {
    currentLevelBlue += delta;
    analogWrite( LED_BLUE_PIN, (int)(currentLevelBlue / 100. * 255) );
    delay( FADE_DELAY );
  }
}

void fadeToLevelWhite( int toLevel ) {

  int delta = ( toLevel - currentLevelWhite ) < 0 ? -1 : 1;
  
  while ( currentLevelWhite != toLevel ) {
    currentLevelWhite += delta;
    analogWrite( LED_WHITE_PIN, (int)(currentLevelWhite / 100. * 255) );
    delay( FADE_DELAY );
  }
}

In the code above everything works as expected (by that I mean that the radio communicates, which I think uses a PWM pin) with the exception that with a meter, and with the led strip attaced, I only get 0v or 5v on the pin and the LEDs are only in an on or off state.

void setup() {
  pinMode (8, OUTPUT);
  pinMode (7, OUTPUT);
  pinMode (6, OUTPUT);
  pinMode (5, OUTPUT);
  digitalWrite(8, LOW);
  digitalWrite(7, LOW);
  digitalWrite(6, LOW);
  digitalWrite(5, LOW);
}

void loop() {
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
  digitalWrite(8, HIGH);
  delayMicroseconds(1);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  delayMicroseconds(5000);
}

When I use the code above I can change all 4 LED color dim levels by manipulating the length of the delays.

void loop () {
analogWrite(8, 0);
delay(3000);
analogWrite(8, 127);
delay(3000);
analogWrite(8, 255);
delay(3000);
}

This code gives me 6 seconds of OFF and 3 seconds of ON, I know I am doing something silly, any help out there?

Thanks,
Sean

I found this today, still struggling, is this how I would manipulate the pin itself using registers?

void setup() {
  pinMode(8,OUTPUT);
  analogWrite(2,1);
  OCR4C = 128;
}

void loop() {
  delay(3000);
  OCR4C = 4;
  delay(3000);
  OCR4C = 255;
  delay(3000);
}

What are the values of the variables printed to the serial monitor? They shown correctly?

birddog:
What are the values of the variables printed to the serial monitor? They shown correctly?

Not sure which variables you are talking about?

Im my original sketch everything reports correct. Dimmer values, when it goes to fade, they all show up correctly, it acts just like it does on a pro mini with the exception that it does not function.

Sorry, I should have been more specific.

In the first code.

if(RequestedColor == CHILD_ID_WHITE) {
                  Serial.print( "Changing White level to " );
  Serial.print( requestedLevel );
  Serial.print( ", from " );
  Serial.println( currentLevelWhite );
  fadeToLevelWhite( requestedLevel );
                }else if(RequestedColor == CHILD_ID_RED) {
  Serial.print( "Changing Red level to " );
  Serial.print( requestedLevel );
  Serial.print( ", from " );
  Serial.println( currentLevelRed );
  fadeToLevelRed( requestedLevel );
                }else if(RequestedColor == CHILD_ID_GREEN) {
  Serial.print( "Changing Green level to " );
  Serial.print( requestedLevel );
  Serial.print( ", from " );
  Serial.println( currentLevelGreen );
  fadeToLevelGreen( requestedLevel );
                }else if(RequestedColor == CHILD_ID_BLUE) {
  Serial.print( "Changing Blue level to " );
  Serial.print( requestedLevel );
  Serial.print( ", from " );
  Serial.println( currentLevelBlue );
  fadeToLevelBlue( requestedLevel );
                }

and the printouts in the functions

analogWrite( LED_RED_PIN, (int)(currentLevelRed / 100. * 255) );
    Serial.println(currentLevelRed);

Also maybe add the following print just to check the value you are writing to the LED.

Serial.println((int)(currentLevelRed / 100. * 255) );

You are printing what you want your led to do, and what it should have done. Are these values as you would expect when the code is running?

Additionally, there is a lot of strange looking syntax to me. Is this written in C? I still have quite a bit to learn, so it may be techniques I have yet to learn or the way a library expects it.

Sorry again, head not screwed on right today.

Here are a couple examples of what I meant by strange looking syntax.

 // Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on]
 requestedLevel *= ( message.type == V_LIGHT ? 100 : 1 );

 // Clip incoming level to valid range of 0 to 100
 requestedLevel = requestedLevel > 100 ? 100 : requestedLevel;
 requestedLevel = requestedLevel < 0   ? 0   : requestedLevel;

and…

 *  This method provides a graceful fade up/down effect
 */
void fadeToLevelRed( int toLevel ) {

  int delta = ( toLevel - currentLevelRed ) < 0 ? -1 : 1;
 
  while ( currentLevelRed != toLevel ) {
    currentLevelRed += delta;
    analogWrite( LED_RED_PIN, (int)(currentLevelRed / 100. * 255) );
    Serial.println(currentLevelRed);
    delay( FADE_DELAY );

Also I have had an issue before with pin 53 on a Mega. You might try temporarily moving that pin elsewhere and see if that helps.

birddog:
Sorry again, head not screwed on right today.

Here are a couple examples of what I meant by strange looking syntax.

 // Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on]

requestedLevel *= ( message.type == V_LIGHT ? 100 : 1 );

// Clip incoming level to valid range of 0 to 100
requestedLevel = requestedLevel > 100 ? 100 : requestedLevel;
requestedLevel = requestedLevel < 0  ? 0  : requestedLevel;




and... 


*  This method provides a graceful fade up/down effect
*/
void fadeToLevelRed( int toLevel ) {

int delta = ( toLevel - currentLevelRed ) < 0 ? -1 : 1;

while ( currentLevelRed != toLevel ) {
    currentLevelRed += delta;
    analogWrite( LED_RED_PIN, (int)(currentLevelRed / 100. * 255) );
    Serial.println(currentLevelRed);
    delay( FADE_DELAY );




Also I have had an issue before with pin 53 on a Mega. You might try temporarily moving that pin elsewhere and see if that helps.

Here is the output of changing a red value which has the most output.

18385 TSF:MSG:READ,0-0-22,s=1,c=1,t=3,pt=0,l=2,sg=0:65
Which sensor did we get a message for? : 1
Changing Red level to 65, from 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

Also on the issue of pin 53, that is decided by the mysensors radio libraries, I don’t think I have any control over that, or at least the knowledge to add messing with that to the equation.