Running a DC motor with PWM

Hello. I am really new to this and just trying to figure out some things so that I can have some fun. I have been messing around with the PWM and have been wanting to get a DC motor to ramp up slowly and stay at Full speed until I tell it to Slow down. Kinda like a soft start up. I can get it to ramp up but then when it goes through the loop again it starts at 0 and comes back up to 255 over and over. I want it to stop at 255 until I tell it to slow down.

You can do a digital write from 0 to 255 with some add delay() then repeat.
EX:

loop()
for (int x=1; x<256;x++)
{
// look at the digital write code & place here
// add some delay for the motor to move
}
// maybe some more delay to stop at 255 for a bit

I don't want it do go down on its own. I want it to go up and then stay up

loop()
for (int x=1; x<256;x++)
{
// look at the digital write code & place here
// add some delay for the motor to move
}

Place the above in setup()
In loop() look at a digital i/p switch use an ‘if’ statement, then run a ‘for’ loop to slow down your motor.

Hi Jason2548.

The for.. loop will count until a set value. If you are in a loop (like void loop), you will always start at the initial value (here 1) and end up with the final value (255), and do that over and over again.

So to get rid of that, you can set the initial value for X in void setup. In void loop you will increase X every time, until you reach your end value. In that case you will not increase, because increasing will get to 0 again (an overflow will occur).

By the way: You'll see that your motor will not start running immediatly. It might start at 20 % or later. And it might also reach its maximum speed before it's at 255, but that will be hard to find out. So it would be nice for your experiment to keep track of where you are when the motor starts running. You can do that using a display or using serial and a terminal to see the output. You would also need to slow down the update rate of your PWM, because else you will hardly see the speed ramping up.

Thank you for the input. I am going to try some stuff and see what happens. If your wondering this is for a little HO train. I am going to have a pro mini in the train with a motor driver. Its going to be controlled by infrared lights that tell it when to stop and when to go. getting the motor to ramp up and stay up is my only problem. I will try somethings today. Thank you for your help.

Nice application. For this use, you will for sure need to find out the startspeed. And you'll probably want to slow down the steps (as i mentioned) to get a less steep ramp. Else your train (mass, try different configurations/number of cars) might interfere with the slowing down or speeding up.

Do you also plan on a failsafe, in case your optical communication fails ?

Keep us informed on your progress please.

This sounds like a nice project. What type of driver are you using? A driver IC, or MOSFETs, or a transistor circuit?

Its going to be a little motor driver from sparkfun. Here is my plan. I am going to supply 12vdc to the track and use that to control the trains that have a ProMini inside them with the little 2amp motor driver. On the front of each train is going to be the IR RX. Then is going to let the train stop and start were I want it. All of the track switches are going to be controlled with a servo. Then under the track is going to be some IR sensors that will let me know were the trains are and by the programming would not let them be on the same track at the same time. The failsafe I was thinking that if two trains are on the same track and the sensors see that then it would just shut off power to the whole track so that everything stops. I also am thinking about using just regualar leds to see were the trains are too. I read this the other day and thought it would make it easier and actaully really neat. The only thing that is still throwing a fit is the motor control for the train. I need to rebuild the program and see what I can do.

Also. The Arduino is very new to me and so is programming. There is alot of stuff I do not understand. But for really simple stuff I can make it work. I have made some light controllers. That is all I have done. Also I made a submarine with the uno that worked pretty well except for the design. Thats why with the motor control I really don't understand what I am doing yet. I can get the motor to run but it ramps up and the stops and then ramps up again. just the cycling.

Do you need to change the dirrection of the motor? If not, just use a MOSFET to drive it. Just Google "motor driver circuit"

This is what I am using but still not working. I can’t get it to stop once it reaches the 255

int PWMpin = 13;
void setup()
{
}
void loop()
{
for (int i=0; i <= 255; i++){
analogWrite(PWMpin, i);
delay(10);
}
}

Some time I would like to control the direction. I thought about using the Mosphet but it would simple to buy the chip. It works great just can't get it to do what I want.

This actually does what I would like. Just seems more complicated than it should be

int PWMpin = 13;

void setup() {

}

void loop() { int x = 1; for (int i = 0; i > -1; i = i + x){ analogWrite(PWMpin, i); if (i == 255) x = 0; delay(10); } }

Bro! Dem Mosphets is phat! Braaaaap! Sorry, the temptation was too great! ;)

You should be up and running now...

Have fun!

Jason2548: I don't want it do go down on its own. I want it to go up and then stay up

This means it will slowly increase speed, and when it reaches top speed, it will stay there.

Jason2548: I can't get it to stop once it reaches the 255

This would mean it will slowly increase speed, and once it reaches top speed, it would stop immediatly. Those are 2 different things.

As the code you came up with keeps increasing but will increase by zero once it has reached the preset, i'm assuming you meant stop increasing instead of stop the motor.

I think this should also work and is a bit simpler as you don't need the help of an extra variable. Haven't tested it, but it does compile.

int PWMpin = 13; 
int PWM_val = 0;
void setup()
{
}
void loop()
{
    PWM_val++;
    if (PWM_val == 256) PWM_val --;
      analogWrite(PWMpin, PWM_val);
      delay(10);
}

This way you will stay inside the loop, and also stay counting up (and down again), and you'll keep writing the same value to pin 13.

Last week i discovered the switch...case statement. It is like if...then, but has some advantages which let me like it more. For one it has the break. That break will end the processing of the other cases. The last case (default) defines what has to be done when neither of the cases are true. Doing this will check the value that has been reached, but if you are already have set your maximum, it will not change the output of the pin (or increase the value):

int PWMpin = 13; 
int PWM_val = 0;
void setup()
{
}
void loop()
{
    
   switch (PWM_val)
   {
    case 256:
    break;  //This will skip out of the switch function
    default:
      {
        analogWrite(PWMpin, PWM_val);
      PWM_val++;
      delay(10);
      }
   }
}

Once more, not checked, but it will compile.

Check the language reference every now and then for some functions you haven't heard of before.

(edited: added the comment and {wrapped} the default: actions)

If you don’t need to change dirrection, just get a MOSFET, something like the IRF540N, you will always het it to do what you want it to do.

Thank you everybody for the replies. I have been hard at it for alot of things. I have found the program that will work and once I get it all tested and working I will share it. Then I will start working on the Program for the mega that is going to control all the sensors and lights for the track. Its going to be the best train set a kid could ever ask for. Thank you again to all. Everything has helped me get to this point with alot of learning.

well what i can see is that you want to ramp the speed of the motor slowly rite ok
try something like

int StartSpeed=0; // you have to experiement to find the magic number. 
int StopSpeed=255;//Again experiment ok 
const int MotorPin=3;
int i=StartSpeed;
unsigned long TimeNow;
unsigned long PreviousMillis=0;
long Delay=10; // experiment with the value ok, the lower the value the steeper the gradiend of speed

void setup()
{
  pinMode(MotorPin,OUTPUT);
  digitalWrite(MotorPin,LOW);
}

void loop()
{
  if (i<StopSpeed)
  {
    unsigned long CurrentMillis=millis();
    if (CurrentMillis-PreviousMillis>=Delay)
    {
      PreviousMillis=CurrentMillis;
      i ++;
    }
  }
  analogWrite(MotorPin,i);
}

this code should enable you to ramp up the speed of the motor and keep it there.

That did work with the simulator. The motor Driver for the train is actually working quite well. Now I am on to the sensors and and getting them what I would like to on the track.