PWM on Mega 2560 Pins 44-46 not working

Is there any trick to getting the PWM outputs working on pins 44-46 of the Mega 2560 board?
I can set the pins high and low with digitalWrite() but analogWrite() to the same pins does nothing.
Help!

Thanks,

  • al

This worked for me:

void setup ()
  {
  analogWrite (44, 50);
  }  // end of setup

void loop () { }

Perhaps if you posted your code.

int RedPin = 44;

void setup() { pinMode(RedPin, OUTPUT); // probably not necessary }

void red(int value)

{

if (value > 255) value = 255; // sanity check analogWrite(RedPin, value); // write analog value }

Please modify your post and put the code inside [ code] [ /code] tags.

That can't be your whole code. Please paste everything, not just the bits you think are relevant. As it is in the code you posted, your red() function never gets called. You should put the call to this inside a loop() function, probably followed by a delay().

loop()
{
    red(0);
    delay(1000);
    red(64);
    delay(1000);
    red(128);
    delay(1000);
    red(255);
    delay(5000);
}

Arduino expects a loop() function, and automatically calls it.

Yep, post code that compiles, not snippets.

http://snippets-r-us.com/

#include <Servo.h>
// include the library code:
#include <LiquidCrystal.h>
#include <pitches.h>
int volt_service(void);

Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created

int pos = 0; // variable to store the servo position
int inputPin = 10; //choose the input pin (for a pushbutton)
int val = 0; //variable for reading the pin status
int dest = 127;
int ledpin = 12;
int trigger_pin=23;
int fire_pin=22;
int inverter_pin = 13;
int start = 0;
int analogPin = 0;
int Voltage, Full_Bars, Part_Bars, Our_Cursor;
int Last_Val = 100;
int Last_Volt = 2000;
int RedPin = 44;
int BluePin = 45;
int GreenPin = 46;
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
byte Bar0[8] =
{
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B00000
};
byte Bar1[8] =
{
B10000,
B10000,
B10000,
B10000,
B10000,
B10000,
B10000,
B10000
};
byte Bar2[8] =
{
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
B11000
};
byte Bar3[8] =
{
B11100,
B11100,
B11100,
B11100,
B11100,
B11100,
B11100,
B11100
};
byte Bar4[8] =
{
B11110,
B11110,
B11110,
B11110,
B11110,
B11110,
B11110,
B11110
};
byte Bar5[8] =
{
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111
};
void setup()
{
int I;
pinMode(inverter_pin, OUTPUT);
digitalWrite(inverter_pin, HIGH);
myservo.attach(11); // attaches the servo on pin 11 to the servo object
//myservo.write(start); // set the servo to 0
for(pos = dest; pos > start; pos -= 1)
{
myservo.write(pos); //load projectile
delay(20); // wait 500ms

}
pinMode(RedPin, OUTPUT);
pinMode(BluePin, OUTPUT);
pinMode(GreenPin, OUTPUT);
pinMode(inputPin, INPUT); //declare pushbutton as input
pinMode(ledpin, OUTPUT);
pinMode(trigger_pin, INPUT);
pinMode(fire_pin, OUTPUT);
digitalWrite(fire_pin, HIGH);
digitalWrite(trigger_pin, HIGH);
// set up the LCD’s number of columns and rows:
lcd.begin(16, 2);
lcd.createChar(0, Bar0);
lcd.createChar(1, Bar1);
lcd.createChar(2, Bar2);
lcd.createChar(3, Bar3);
lcd.createChar(4, Bar4);
lcd.createChar(5, Bar5);
// Print a message to the LCD.
lcd.print(“hello, world!”);
Serial3.begin(19200);
Serial3.println(“Hello Serial”);
}
//Write a brightness value to the red LED 0-255
void red(int value)
{
if(value>0) digitalWrite(RedPin, HIGH); // non-zero is on
else digitalWrite(RedPin, LOW); // else off
}
void green(int value)
{
if(value>0) digitalWrite(GreenPin, HIGH); // non-zero is on
else digitalWrite(GreenPin, LOW); // else off
}
void blue(int value)
{
if(value>0) digitalWrite(BluePin, HIGH); // non-zero is on
else digitalWrite(BluePin, LOW); // else off
}
int volt_service(void)
{
int I;
float V;
val = analogRead(analogPin);
V=val;
V*=1.6;
Voltage=(V+0.5);
val = Voltage;

val /= 14;
if (val > 71) val = 71;
if (val != Last_Val)
{
Last_Val = val;
Full_Bars = val / 6;
Part_Bars = val % 6;
Our_Cursor = 0;
lcd.setCursor (0,2);
lcd.print(" “);
if (Full_Bars > 0)
{
for (I = 0; I < Full_Bars; ++I)
{
lcd.setCursor (Our_Cursor, 1);
lcd.write (byte(5));
Our_Cursor++;
}
}
lcd.setCursor (Our_Cursor, 1);
lcd.write(byte (Part_Bars));
}
if (Voltage != Last_Volt)
{
Last_Volt = Voltage;
lcd.setCursor (12,1);
lcd.print(” ");
lcd.setCursor (12,1);
lcd.print (Voltage);
}
return Voltage;
}

//beeper service
void beep(void)
{
tone(8, 1057, 250); //turn on the beeper
delay(120); //wait 1/8th second
noTone(8); //turn off beeper
}
//servo services
void servo_in(void)
{
for(pos = start; pos < dest; pos += 1)
{
myservo.write(pos); //load projectile
delay(20); // wait 500ms
}

}
void servo_out(void)
{
for(pos = dest; pos > start; pos -= 1)
{
myservo.write(pos); //load projectile
delay(20); // wait 500ms
}

}
void charge_on(void)
{
digitalWrite(inverter_pin, LOW); //turn charger on

}
void charge_off(void)
{
digitalWrite(inverter_pin, HIGH); //turn charger off

}
void fire(void) //activate coil
{
digitalWrite(fire_pin, LOW);
delay(100);
digitalWrite(fire_pin, HIGH);

}
unsigned char trigger(void) //sense trigger state
{
if(digitalRead(trigger_pin)==HIGH) return false;
else return true;
}
unsigned char start_button(void) //sense start button
{
if(digitalRead(inputPin)==HIGH) return false; // read input value
else return true;
}

// Get an integer from the console
int get_int(void)
{
byte c;
int retval = 0; // clear our register
while(1)
{
if(Serial3.available()) // if we have a character
{
c=Serial3.read(); // fetch it
if((c>=‘0’)&(c<=‘9’)) // if numeric
{
Serial3.write(c); // echo it
retval*=10; // multiply our output register by 10
retval+=(c-‘0’); // add in new one’s
}
if(c==0x0d) // if enter key
{
return retval; // return what we have
}
}
}
}
// Ask for an integer value from the console
int ask_int(char*s)
{
int retval;
Serial3.print(s); // print the prompt
retval=get_int(); // get the value
Serial3.println(""); // new line
return retval; // return the value
}
//menu service, called from main work loop
void menu(void)
{
int c;
if (Serial3.available() == 0) return;
switch(Serial3.read())
{
case ‘r’:
c=ask_int("Value for Red (0-255)? ");
Serial3.print(“red is “);
Serial3.print(c);
Serial3.println(””);
red(c);

break;
case ‘g’:
c=ask_int("Value for Green (0-255)? ");
Serial3.print(“green is “);
Serial3.print(c);
Serial3.println(””);
green(c);

break;
case ‘l’:
c=ask_int("Value for Blue (0-255)? ");
Serial3.print(“blue is “);
Serial3.print(c);
Serial3.println(””);
blue(c);

break;
case ‘b’:
Serial3.println(“beeper engaged”);
beep(); //beep the beeper
break;
case ‘i’: //move servo in
Serial3.println(“Moving Servo in”);
servo_in();
break;
case ‘o’: //move servo out
Serial3.println(“Moving Servo out”);
servo_out();
break;
case ‘c’: //start charge
Serial3.println(“Starting Charge”);
charge_on();
break;
case ‘k’: //kill charge
Serial3.println(“Killing Charge”);
charge_off();
break;
case ‘f’: //fire
Serial3.println(“Firing”);
fire();
break;
case ‘t’: //sense trigger state
if (trigger()) Serial3.println(“Trigger Pressed”);
else Serial3.println(“Trigger Released”);
break;
case ‘s’: //sense start button
if (start_button()) Serial3.println(“Start Button Pressed”);
else Serial3.println(“Start Button Released”);
break;
case ‘v’: //sense voltage
Serial3.print("Voltage is ");
Serial3.println(volt_service(), DEC);
break;
default:
Serial3.println(“Railgun Menu”);
Serial3.println(“B - Beeper Test”);
Serial3.println(“i - Move Servo in”);
Serial3.println(“o - Move Servo out”);
Serial3.println(“c - Start Charge”);
Serial3.println(“k - Kill Charge”);
Serial3.println(“f - Fire”);
Serial3.println(“t - Trigger Sense”);
Serial3.println(“s - Start Button”);
Serial3.println(“v - Print Voltage”);
Serial3.println(“r - set red LED”);
Serial3.println(“g - set green LED”);
Serial3.println(“l - set blue LED”);
break;

}
}

void loop()
{
lcd.setCursor (0,0);
lcd.print ("Ready ");

while(1) //main work loop
{
menu(); // only debug menu for now
}
}

See this?

noTone(8); //turn off beeper

That's why we ask you to use code tags.

Read this before posting a programming question

//Write a brightness value to the red LED 0-255
void red(int value)
 {
   if(value>0) digitalWrite(RedPin, HIGH);        // non-zero is on
   else digitalWrite(RedPin, LOW);        // else off
 }

Ah, there is no analogWrite anywhere in your code.

And it looks nothing like the snippet you posted:

void red(int value)
 {
   if (value > 255) value = 255;   // sanity check
   analogWrite(RedPin, value);     // write analog value
}

arduinodlb: Please modify your post and put the code inside [ code] [ /code] tags.

Without doing what you have already been asked to do, I doubt that many members will take the time to look at your last post.

You first posted this

int RedPin = 44;


void setup()
{
  pinMode(RedPin, OUTPUT);
        // probably not necessary
}


void red(int value)
  
{
    
    if (value > 255) value = 255;   // sanity check
    analogWrite(RedPin, value);     // write analog value
}

Now you new post includes this

void red(int value)
  {
    if(value>0) digitalWrite(RedPin, HIGH);        // non-zero is on
    else digitalWrite(RedPin, LOW);        // else off
  }

This latter code is only writing the pin HIGH or LOW without any hint of PWM ??

Please post your code, using code tags, which shows the problem you are apparently having.

Cheers

Edit - Nick got in before me :)

laughingcat: Is there any trick to getting the PWM outputs working on pins 44-46 of the Mega 2560 board?

To answer your original question, no there is no trick. There is a trick to using the forum though:

How to use this forum

Whoops, sorry guys, I posted the code that we are using since having problems.
I will clean it up and re-post in the proper way.

Thanks,

  • al

OK, I found the root of the problem, but not a solution (yet). If I take out the servo.attach(11) call, the PWM works fine. If I include it, the PWM does not work on pin 44 (probably not 45 or 46 either, since they are the same counter/timer). Is there an interaction involving resources for the servo object?

Thanks,

  • al

Yes, servos use PWM. :P

OK guys, snarky comments aside (for the newbie),

I found the root of the problem. It turns out that the servo attach function for the Mega2560 board uses the timer 5 resource and disables PWM for pins 44-46. I will try to modify and recompile the MegaServo.cpp file to use a different resource (i.e. Timer 1) so that PWM is still available for pins 44-46.

  • al

Wouldn't it be easier to use alternative pins for your LED's ??