Pages: 1 [2]   Go Down
Author Topic: PWM motor speed question  (Read 1354 times)
0 Members and 1 Guest are viewing this topic.
UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12577
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Suspicious of what?

Redundant states. If you have a lot of states representing similar activities in different contexts, perhaps you would be better to consolidate them into one set of states which has parameters which specify the context.

There are also ways to structure the state machine that reduce the code and data replication between states and make each state more self contained. One that works well is to have the handler function for each state return the new state, and have your state machine framework compare old/new states to detect state transitions. You can use that to trigger exit processing for the old state and entry processing for the new state. For example actions such as initialising sub-state variables such as motor speed and run duration, and starting the motor, could be handled by state entry code. This is a good place to put logging, too. Then the processing for each state would be reduced to 'if the motor speed has reached the target, move to the next state' and so on. It may not apply here, but this approach means that entry/exit processing for each state is always done reliably, without any code replication, regardless of how complex the sequences of state transitions can become. If you need to increase the complexity even further, it gives you a hook which you can use to manage compound finite state machines.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Space Coast Florida
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This sounds good for rev 2. It will take a lot of consideration. And yeah the original plan called for 12 states but it evolved. There are redundant states that could have values passed to a single state, but you know how it is, "Its working move on to the next phase" pressure.Still I am only using 20 % of the mega's program space. Do you have any simple FSM code that you are willing to share. I found the example for the remote car starter and learned a lot from that. Bad habits included. I would be done by now but I had to upgrade the motor controls from relays to an H-Bridge.
Logged

Space Coast Florida
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, I am looking at using a function to spool up and spool down the motors and handle the duration timer. Here is what I have that does not work. Please Help!
Code:
//////////////////////////////

#define STIRRING1_TIME 20  //   1200
#define Srelay    51
int stir_speed = 180;
int time = 0; 
int pump_pwm_del = 1;
int second = 0;
void setup() {
  Serial.begin(57600);
  Serial.println("setup");

  digitalWrite(23,HIGH);
 
  /////////////////////////////
  pinMode(Srelay, OUTPUT); // Provides/Removes Power to motor controllers
  pinMode(44, OUTPUT); //Shared PWM Signal to all 4 motor controllers
  pinMode(23, OUTPUT);   //Stir motor
  digitalWrite(Srelay,LOW);//Turn off power to motor controllers
}

void loop() {
  digitalWrite(Srelay,HIGH);//Turn off power to motor controllers   
  Serial.println("23");
  stir(10);
 
}

/////////////////////////////////////////////////////////
//Stir
int stir(int time){
  digitalWrite(23,LOW); // Release Brake Stir Motor
     Serial.print("Brake On ");
  for (int motorspeed = 0; motorspeed < stir_speed; motorspeed++) {
    analogWrite(44, motorspeed);// Ramp up speed
     Serial.print("motorspeed = ");
    Serial.println(motorspeed);
    delay(4);
  }
  //motor at speed start counting
  Serial.print("motorspeed = MAX ");
  static unsigned long lastTick = 0; // set up a local variable to hold the last time we moved forward one second
  // (static variables are initialized once and keep their values between function calls)
  if (millis() - lastTick >= 1000) {
   
    lastTick = millis();
    second++;
   
   
    Serial.print("Second = ");
    Serial.println(second);

   
    if (second > time){   // Count over decel motor
      Serial.print("Time Out");
       for (int motorspeed = stir_speed; motorspeed >= 0; motorspeed--) {
    analogWrite(44, motorspeed);  //Ramp down
     Serial.print("motorspeed = ");
    Serial.println(motorspeed);
    delay(4);
  }
    Serial.print("motorspeed = MIN ");
  digitalWrite(23, HIGH);// Set Brake stir Motor
   Serial.print("Brake On ");
    }
  }
 
  delay(1000);
}
Logged

East Anglia (UK)
Offline Offline
Faraday Member
**
Karma: 109
Posts: 4082
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Here is what I have that does not work.
Does it do nothing, or not just not what you want ?

Every time the stir() function is called the stir speed will return to zero then ramp up.  Is that what you want ?  Do you want the program to stay in the stir() function for 10 seconds or for it to check each time that it is called whether it should ramp up the speed or whether it is time to ramp down the stir speed if it is running at full speed and has been for 10 seconds ?
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

New Jersey
Offline Offline
Faraday Member
**
Karma: 65
Posts: 3638
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What does it do? What would you like it to do? What serial output do you get?

Since you're calling it in loop, I assume you're expecting it to spool up for a 10 second stir and then wind down and stop and then do it all again repeatedly. If that's the case but it only works once, the likely cause is that you never set you second variable back to zero. After the wind down would be a good place.
Logged

Space Coast Florida
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Quote
What does it do? What would you like it to do? What serial output do you get?

Since you're calling it in loop, I assume you're expecting it to spool up for a 10 second stir and then wind down and stop and then do it all again repeatedly. If that's the case but it only works once, the likely cause is that you never set you second variable back to zero. After the wind down would be a good place.

for this example that is exactly what i want it to do

This is what it is doing.
motorspeed = 176
motorspeed = 177
motorspeed = 178
motorspeed = 179
motorspeed = MAX 25
Brake On motorspeed = 0
motorspeed = 1
motorspeed = 2
motorspeed = 3
motorspeed = 4
motorspeed = 5
motorspeed = 6
 It never reaches the timer or the ramp down.






Quote
Every time the stir() function is called the stir speed will return to zero then ramp up.  Is that what you want ?  Do you want the program to stay in the stir() function for 10 seconds or for it to check each time that it is called whether it should ramp up the speed or whether it is time to ramp down the stir speed if it is running at full speed and has been for 10 seconds ?
I want to call the stir() function passing a duration in seconds ..ramp up count to the variable passed ... then ramp down and then exit the function. I want to stay in the function until the ramp down is complete.
Logged

East Anglia (UK)
Offline Offline
Faraday Member
**
Karma: 109
Posts: 4082
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
void stir(int seconds)
{
  code to ramp up stirring speed
  delay(seconds);
  code to ramp down stirring speed
}

NOTE - this will block execution of any other code including reading button input
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

New Jersey
Offline Offline
Faraday Member
**
Karma: 65
Posts: 3638
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I want to call the stir() function passing a duration in seconds ..ramp up count to the variable passed ... then ramp down and then exit the function. I want to stay in the function until the ramp down is complete

In which case, why are you doing all that stuff with millis and seconds? Isn't that routine just:
Code:
RampUp();
delay(10000);
RampDown();

I initially assumed you were trying to avoid delay so that you could attend to other matters in loop.
Logged

Space Coast Florida
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Is there a way to stay in the loop without using delay I do want to be able to service sensors while counting out the stir time?
Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 65
Posts: 3638
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It looks like the routine you have nearly does that. You just need to add a boolean variable, named stirring perhaps and only do the ramp up if you're not already stirring.

Presumably you'll need something in loop to decide when to stir, rather than doing it unconditionally as you are now.
Logged

Pages: 1 [2]   Go Up
Jump to: