Mega 2560 RGBW PWM problem



  • This is my first time working with a mega, I have been doing lots of tinkering and cant get a mosfet (have tried several, all produce the same results) to be controled with PWM. (I have seen the fade work though I cant figure out why in that instance it worked, and I haven't been able to duplicate it)

    Im using the circuit on the mysensors page, with the obvious changes that this is a Mega and I have 4 led "channels" instead of one.

    Using my meter and analogWrite I can only get 0v or 5v, which is how my led strip reacts, on or off, no levels. Any value 0-99 produces 0v with 100 giving 5v.

    #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 3560 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() 
    {
      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 );
      }
    }
    

    I have this same code working on a pro mini, with the exception of no white as it doesn't have enough PWM pins, hence going to the Mega.

    Any help is greatly apreciated,
    Sean



  • So, further information, using this code:

    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(7, HIGH);
      delayMicroseconds(100);
      digitalWrite(7, LOW);
      delayMicroseconds(3000);
    }
    

    I can change these numbers up and verify that the hardware works just fine... somebody has to point out some completely noob thing I must be doing.


  • Mod

    @gundark2 this is just a shot in the dark, but maybe you need to set the pwm pins as outputs?
    What happens if you use analogWrite in your minimal sketch? Same problem?



  • Thanks for the response, I forgot to mention that was one of the things i tried. Still only strait on or off.

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

    This code gives me approx 6 seconds of OFF and 3 of ON.

    I have to think something is wrong with the TIMERS, though at least some of them have to be working because the radio works just fine, openhab and all its functions work.... unless I misunderstand I thought the radio uses PWM for some of the pins.


Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.