Show Posts
|
|
Pages: 1 [2] 3 4
|
|
16
|
Using Arduino / Programming Questions / Re: PWM motor speed question
|
on: April 16, 2013, 06:00:38 pm
|
is the function supposed to do whole cycle of pump during one call (it means ramp-up, run max speed until FILLING_TIME and then ramp-down) and then exit? Yes exactly. Being self-taught I did not have this verbage. The implementation has blocking code to ramp the speed up and down but does not have any blocking code to wait for the elapsed time to pass. This is the problem. It also has a couple of global/static variables that it is incrementing and using to trigger display output. Actually it inhibits repainting the screen and causing a flicker. The only way that makes sense is for HandleFILLING1State() to be called repeatedly, so I assume that's what is happening. Correct. The main loop is just a big switch case tree (correct verbage?) that sends the program to the proper Function continuously until the conditions dictate a state change. the logic to turn the motor on and ramp the speed up should only be called on entry to the state. I would guess that corresponds to (counter == 1). Correct. And the ramp down is the last thing to do other than resetting the variables. You could add an if(counter==1){} statement and move the digital writes and acceleration ramp inside it. This was the best I could come up with but it seemed inelegant. My suggestion, for what it's worth, is that you break this state and this function up into three separates states corresponding to the accelerating, constant speed and decelerating phases. Each state could then be implemented with a trivial non-blocking piece of code and the use of global data would almost disappear. This Would be better but I have 29 states right now so I would have to break up and render 21 of them up to do so. Given that the FILLING1_TIME is defined separately from the pump acceleration characteristics, I wonder whether it's conceivable that the timeout could occur before the acceleration had completed, and what you would want to happen in that case.
If I understand what you are asking- I am ramping up to max speed on the pumps then running for 10 minutes and then ramping down to fill . The stirrer ramps up to a preset speed runs for 10 minutes and then ramps down and then reversing the pump for drain. I want to Start the timer after the motor reaches speed and then decel after counter time-out.
|
|
|
|
|
17
|
Using Arduino / Programming Questions / Re: PWM motor speed question
|
on: April 16, 2013, 01:57:12 pm
|
Here is the stand alone PWM program this works but when I add it to the program I have the above problem. Maybe there is another approach. //////////////////////////////////// int stir_speed = 80; int stir_ramp = 20; int pump_speed = 250; int pump_ramp = 4; ////////////////////////////////////
#define stir_brake 25 #define pump1_brake 27 #define pump2_brake 29 #define pump3_brake 31 #define pump1_direction 33 #define pump2_direction 35 #define pump3_direction 37 void setup() {
digitalWrite(stir_brake, HIGH); digitalWrite(pump1_direction,HIGH); digitalWrite(pump1_brake, HIGH); digitalWrite(pump2_direction,HIGH); digitalWrite(pump2_brake, HIGH); digitalWrite(pump3_direction,HIGH); digitalWrite(pump3_brake, HIGH); pinMode(42, OUTPUT); //Analog pin pinMode(44, OUTPUT); //PWM Output common to all motor drivers pinMode(46, OUTPUT); //Analog pin pinMode(stir_brake, OUTPUT); pinMode(pump1_brake, OUTPUT); pinMode(pump1_direction, OUTPUT); pinMode(pump2_brake, OUTPUT); pinMode(pump2_direction, OUTPUT); pinMode(pump3_brake, OUTPUT); pinMode(pump3_direction, OUTPUT); int motorspeed = 0; }
void loop() { digitalWrite(stir_brake, LOW); digitalWrite(pump1_direction,HIGH); digitalWrite(pump1_brake, HIGH); digitalWrite(pump2_direction,HIGH); digitalWrite(pump2_brake, HIGH); digitalWrite(pump3_direction,HIGH); digitalWrite(pump3_brake, HIGH); for ( int motorspeed ; motorspeed < stir_speed; motorspeed++) { analogWrite(44, motorspeed); delay(stir_ramp); } delay(2000); for (int motorspeed = stir_speed; motorspeed >= 0; motorspeed--) { analogWrite(44, motorspeed); delay(stir_ramp); } delay(20); ///////////////////// digitalWrite(stir_brake, HIGH); digitalWrite(pump1_direction,HIGH); digitalWrite(pump1_brake, LOW); digitalWrite(pump2_direction,HIGH); digitalWrite(pump2_brake, HIGH); digitalWrite(pump3_direction,HIGH); digitalWrite(pump3_brake, HIGH);
for (int motorspeed = 0; motorspeed < pump_speed; motorspeed++) { analogWrite(44, motorspeed); delay(pump_ramp); } delay(2000); for (int motorspeed = pump_speed; motorspeed >= 0; motorspeed--) { analogWrite(44, motorspeed); delay(pump_ramp); } // pause between LEDs: delay(20);
digitalWrite(stir_brake, HIGH); digitalWrite(pump1_direction,HIGH); digitalWrite(pump1_brake, LOW); digitalWrite(pump2_direction,LOW); digitalWrite(pump2_brake, HIGH); digitalWrite(pump3_direction,HIGH); digitalWrite(pump3_brake, HIGH); // iterate over the pins: for (int motorspeed = 0; motorspeed < pump_speed; motorspeed++) { analogWrite(44, motorspeed); delay(pump_ramp); } delay(2000); for (int motorspeed = pump_speed; motorspeed >= 0; motorspeed--) { analogWrite(44, motorspeed); delay(pump_ramp); } delay(20); ///////////////////// digitalWrite(stir_brake, HIGH); digitalWrite(pump1_direction,HIGH); digitalWrite(pump1_brake, HIGH); digitalWrite(pump2_direction,HIGH); digitalWrite(pump2_brake, LOW); digitalWrite(pump3_direction,HIGH); digitalWrite(pump3_brake, HIGH); for (int motorspeed = 0; motorspeed < pump_speed; motorspeed++) { analogWrite(44, motorspeed); delay(pump_ramp); } delay(2000); for (int motorspeed = pump_speed; motorspeed >= 0; motorspeed--) { analogWrite(44, motorspeed); delay(pump_ramp); } delay(20);
///////////////////// digitalWrite(stir_brake, HIGH); digitalWrite(pump1_direction,HIGH); digitalWrite(pump1_brake, HIGH); digitalWrite(pump2_direction,LOW); digitalWrite(pump2_brake, LOW); digitalWrite(pump3_direction,HIGH); digitalWrite(pump3_brake, HIGH); for (int motorspeed = 0; motorspeed < pump_speed; motorspeed++) { analogWrite(44, motorspeed); delay(pump_ramp); } delay(2000); for (int motorspeed = pump_speed; motorspeed >= 0; motorspeed--) { analogWrite(44, motorspeed); delay(pump_ramp); } delay(20); ///////////////////// digitalWrite(stir_brake, HIGH); digitalWrite(pump1_direction,HIGH); digitalWrite(pump1_brake, HIGH); digitalWrite(pump2_direction,HIGH); digitalWrite(pump2_brake, HIGH); digitalWrite(pump3_direction,HIGH); digitalWrite(pump3_brake, LOW); for (int motorspeed = 0; motorspeed < pump_speed; motorspeed++) { analogWrite(44, motorspeed); delay(pump_ramp); } delay(2000); for (int motorspeed = pump_speed; motorspeed >= 0; motorspeed--) { analogWrite(44, motorspeed); delay(pump_ramp); } delay(20); ///////////////////// digitalWrite(stir_brake, HIGH); digitalWrite(pump1_direction,HIGH); digitalWrite(pump1_brake, HIGH); digitalWrite(pump2_direction,HIGH); digitalWrite(pump2_brake, HIGH); digitalWrite(pump3_direction,LOW); digitalWrite(pump3_brake, LOW); for (int motorspeed = 0; motorspeed < pump_speed; motorspeed++) { analogWrite(44, motorspeed); delay(pump_ramp); } delay(2000); for (int motorspeed = pump_speed; motorspeed >= 0; motorspeed--) { analogWrite(44, motorspeed); delay(pump_ramp); } delay(20);
}
|
|
|
|
|
18
|
Using Arduino / Programming Questions / Re: PWM motor speed question
|
on: April 16, 2013, 01:29:00 pm
|
This is the offending code for (int motorspeed = 0; motorspeed < pump_speed; motorspeed++) { analogWrite(44, motorspeed); int motorspeed = 0; Every time thru the loop it initializes motorspeed to 0. I need a for next loop that will let me use a variable that has already been initialized in setup maybe.
|
|
|
|
|
19
|
Using Arduino / Programming Questions / Re: PWM motor speed question
|
on: April 16, 2013, 12:15:31 pm
|
|
The function is one of many states in a state machine. I had relays driving the pumps and the timer stuff worked well. But when I added the pwm routine the ramp up loop runs several times in the function while running.
|
|
|
|
|
20
|
Using Arduino / Programming Questions / Re: PWM motor speed question
|
on: April 16, 2013, 12:11:35 pm
|
by the way, on the closer look i must ask, in what interval you are calling this void from ouside code? because if it is less than one second, you never step inside first "if" and do not print seconds and do not test FILLING_TIME and do not ramp down the pump .... This just keeps the display from flickering. It prints the screen if counter is less than 2 then keeps the counter less tan 5. Without this the counter overflows and the display begins to flicker
|
|
|
|
|
23
|
Using Arduino / Programming Questions / PWM motor speed question
|
on: April 16, 2013, 10:48:16 am
|
Hi, I have 4 LMD 18200 motor driver boards that I am using to control 3 pumps and a stir motor. The inputs are PWM, Direction and Brake. As only one pump is running at any given time all of the pumps share a PWM signal. Individually I am controlling the direction and then releasing the brake. Then the PWM signal will ramp up the speed of the pump to max then the timer counts up to a set point and then the PWM signal ramps down the speed and the moves on to the next state. I have the basic ramp up and down working but I am having trouble integrating it into the existing program. Can you look at this and give me some guidance? ////////////////////////////////////////// void HandleFILLING1State() { TSread(); // Check Touch screen for abort request counter = counter + 1; //Display print counter if (counter <2) // print screen once { /// tft.fillRect(10, 10, 320, 90, BLACK); tft.drawRect(15, 20, 282, 90, GREEN); tft.fillRect(15, 112, 282, 95, BLACK); tft.setCursor(0, 35); tft.setTextColor(GREEN); tft.setTextSize(4); tft.println(" Press to"); tft.println(" Abort Cycle"); tft.setTextColor(RED); tft.setTextSize(4); tft.setCursor(70, 140); tft.println("Filling"); tft.setCursor(71, 170); tft.println("Cleaner"); } /////////////////////// digitalWrite(stir_brake, HIGH); digitalWrite(pump1_direction,HIGH); //Fill so leave direction pin high digitalWrite(pump1_brake, LOW); //Release brake on pump digitalWrite(pump2_direction,HIGH); digitalWrite(pump2_brake, HIGH); digitalWrite(pump3_direction,HIGH); digitalWrite(pump3_brake, HIGH); for (int motorspeed = 0; motorspeed < pump_speed; motorspeed++) { analogWrite(44, motorspeed); // ramp up motor speed PWM pin Serial.println("ramping up "); delay(pump_ramp); // } //motor now running max speed 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++; // add second
Serial.print("Second = "); Serial.println(second);
if (second > FILLING1_TIME){ //time out for (int motorspeed = pump_speed; motorspeed >= 0; motorspeed--) { analogWrite(44, motorspeed); Serial.println("ramping down "); delay(pump_ramp); } //motor is now stopped clearcenter(); counter = 0 ; second = 0 ; state=STIRRING1; } }
if (counter > 5){ counter = 3 ; } }
|
|
|
|
|
25
|
Using Arduino / Programming Questions / Re: Averaging Digital input.
|
on: February 05, 2013, 08:32:01 am
|
This is one of the final hurdles before taking this to Beta test. So time is of the essence. Write the values in an array, sum them all up and divide by the number of measurements. Round the result. This looks like a good avenue and the least to learn. The best thing would be to find out why the false readings happen and eliminate the problem.
I have only seen one false bit of data, and I may have caused it. However I don't want this device kicking out over a bit of noise. No need to average the readings. If you cannot prevent the false readings then you could, perhaps, take 100 readings, adding each to a running total and if the total is not zero or 100 then discard that set, otherwise regard the set as valid and record/display the value as wet or dry as appropriate. The logic is to check if the tank is wet before filling ( not empty ) If wet redirect to manual drain, so the culling process would not need to be so severe. This is mainly a safety to prevent overflow. How often are the readings taken ? Right now in the main loop. I am only using it for filling but I might want it in other states also like draining, abort fill and such. You could also utilize a debounce to ensure that the reading is only valid if it's been that way for X # of milli/microseconds. This is where I started and soon got frustrated. Creative juices running low at this time. Another simple filter for a isolated spikes is to require a data value change to be presented for two or three readings before believing it.
"Tell me once, tell me twice; what you tell me three times I believe is true."
(Edit: You could say this is a way to implement Arrch's proposal.)
This is a viable approach but more like tell me 50 times that you are wet I will act. And I guess it would work pretty much the same if dry
|
|
|
|
|
28
|
Using Arduino / Programming Questions / Averaging Digital input.
|
on: February 04, 2013, 04:36:19 pm
|
|
I have a digital input that is 0 volts when dry and 5 volts when wet. I have it showing in my software. Every now and then I get a false wet or dry. I think what I want to do is average the input after a hundred samples or so. What would be the proper way of doing this?
|
|
|
|
|