Push button DC Motor Control - Ramp up Speed

Hey guys,
New to Arduino but have been looking for the past few months at examples and practicing on my own with the guide of examples. I am an ME major working on a senior design project where we are ramping up the speed on a 12V DC motor from 0 to 100% once a momentary push button is engaged. I have the motor hooked up to the 12V source in parallel with a diode and small capacitor. These 3 input to an NPN transistor with the motor at collector and ground at emitter. I then have the arduino output (pin 10) hooked up to the base of the transistor with a 1k resistor between to protect the Arduino from any current coming from the 12V source. I have a momentary push button receiving power from the Arduino 5V source and providing input to the Arduino at pin 9.

My issue is that when I push the switch, the motor turns on but does not shut off. I have tried adding another while loop (which is commented out at the end) but the motor does not run at all when I do this.

Here is my code so far

//set pin numbers

const int pushbutton = 9;      // seat engaged push button attached to pin 9
const int transistor = 10;     // digital output sent to transistor from pin 10

int buttonstate = 0;           // variable for reading the pushbutton, will be HIGH when pressed
int motorstate = 0;            // value of the state of the motor, HIGH when throttle is engaged

void setup() {
  // initialize transistor as an output
  pinMode(transistor, OUTPUT);
  // initialize pushbutton as an input
  pinMode(pushbutton, INPUT);
}

void loop() {    // put your main code here, to run repeatedly:
  // read the state of pushbutton
  buttonstate = digitalRead(pushbutton);
  
  // while engaged then ramp up power to the transistor
  
    while(buttonstate == HIGH) {
      // ramp up analog voltage signal to transistor
      int i = 0;
      if (i < 255) {
        analogWrite(transistor,i);
        i = i + 1;
        delay(10);
      }
      if (i = 255) {
        analogWrite(transistor,255);
        delay(10);
      }
    }
    //while(buttonstate == LOW) {
    //  analogWrite(transistor,0);
    //}
}

Thanks for the help,
Kyle

Is the push button input floating?

AWOL: Is the push button input floating?

I'm not too sure what you mean by that.. Been a few (~ 4 years) since my last C++ class.

It’s a hardware question. He’s asking if (since your button is active HIGH) you have a pull-down resistor–around 10K ohms from input pin to ground.

–Michael

AWOL: Is the push button input floating?

Sorry - I'm guessing you are getting at asking if I have a resistor in parallel with the output of the pushbutton and ground? I do if that is the case. I'm referring to http://arduino.cc/en/tutorial/button for the button.

Where do you shut the motor off?

That is where I wasn’t sure - I thought that using the second while(LOW) loop would would but the motor wouldn’t run at all. Hence why I commented it out.

You never read buttonState in your first while loop, so once it is high, you can never leave the first loop.

AWOL: Where do you shut the motor off?

That would be the commented-out lines, I suppose. Just a guess since I'm not at the moment in a position to try anything out, but I wonder if the problem isn't getting trapped in "while." Might consider rethinking as "if"s.

--Michael

I just left and will be back by the Arduino soon to try that.. I had not considered that I wouldn't be able to leave the while loop since my thought process was that the void loop() would allow the buttonState to refresh. I will update as soon as I get back.

ok guys I think I got it to work. There will be some fine tuning on the delay in the next few days but we are not sure yet how fast we want to ramp up the speed yet to max power. Below is the final code I used.

Thank you for your help! I really appreciate it.

//set pin numbers

const int pushbutton = 9;      // seat engaged push button attached to pin 9
const int transistor = 10;     // digital output sent to transistor from pin 10

int buttonstate = 0;           // variable for reading the pushbutton, will be HIGH when pressed

void setup() {
  // initialize transistor as an output
  pinMode(transistor, OUTPUT);
  // initialize pushbutton as an input
  pinMode(pushbutton, INPUT);
}

void loop() {    // put your main code here, to run repeatedly:
    // read the state of pushbutton
    buttonstate = digitalRead(pushbutton);
  
    // if both are engaged then ramp up power to the transistor
    // while the button is pressed
    while(buttonstate == HIGH) {
      // ramp up analog voltage signal to transistor
      int i = 0;
      buttonstate = digitalRead(pushbutton);
  
      if (i < 255) {
        analogWrite(transistor,i);
        i = i + 1;
        delay(10);
      }
      if (i = 255) {
        analogWrite(transistor,255);
        delay(10);
      }
    }
    // while the button is NOT pressed
    while(buttonstate == LOW) {
      analogWrite(transistor,0);
      buttonstate = digitalRead(pushbutton);
    }
}

As noted above, because loop() . . . loops itself, you could dispense with the whiles and just put in ifs in their places.