Changing RPM at different times

Hello, This is my first post, so please be kind :slight_smile: .

I have successfully connected an Arduino uno, Rugged motor Driver and a 4 wire bipolar stepper motor to run a small pump. I know how to vary the Revolutions Per/Min. but I have a unique need.

I want to change the RPM's between a daytime rate and a nighttime rate.

In simpleton terms..... I am conducting an experiment to water some plants. During the day I want a certain ML/MIN rate. At night I want it less..... but I want it to change between these rpm's on its own. Without me having to upload a changed sketch......

does this sound possible with an Arduino uno? Would I need some sort of "clock shield/timer"?

Any help is appreciated. Keep in mind I'm a Noob at this.

Cash

I presume (based on your Post) that you know how to use two different values to achieve different speeds and that what you need advice with is the code to bring the appropriate value into use at the correct time.

You could use millis() to manage the timing (see Several Things at a Time) but the Arduino clock does not run at exactly 16 MHz so for long time periods it is better to use an external Real Time Clock (RTC) module.

...R
Stepper Motor Basics

One way is to get a light sensor. With this sensor connected to your board, you can program your arduino to use one rate when sensor senses day light and use another rate when the sensor doesn't sens any light.

Another way is to make use of the millis() function, with this function you can define for how long (day time duration where ever you are at) your driver drives the motor with rate A, and for how long (night duration) with rate B. Just google this and see examples on how to use millis() in your code. It's pretty straightforward.

Going with solution one would be more accurate I'd say, as the duration of night and day keeps changing.

Good luck!

To asnwer the question, yes you need an RTC module because the Uno doesn't have a quartz
crystal clock so the basic accuracy of timekeeping is 0.3% or so, not good enough for this
task.

It is possible to replace the ceramic resonator on (some versions of?) the Uno as there are
pads for a quartz crystal and its load capacitors, but its tricky surface-mount rework.

o.k. guys, Thank you for the responses.....

As this experiment is inside, I cant use a light sensor... What I think I will need to do is incorporate a manual switch/button that I can push at a prescribed time to go from one ml/min to the other. This is going to be o.k. for this project..... I can avoid the hassel of needing a clock/timer.

I am truly a NOOB at the C language, I am using a free program that will get the motor to run and I currently go to the sketch and change the rpm and upload it..... but I don't know how to write or modify the sketch to put in a switch..... I'm thinking circuit open..... faster rpm.... when closed.... have sketch switch to the slower rpm.....

here is the sketch__.....I am not using the keyboard I am only changing the RPM and measuring what ml/min it gives me:__

see sketch below... I changed it for cattledog....
Any help would by TOTALLY APPRECIATED......

Any help would by TOTALLY APPRECIATED......

Learn how to post your code using the code tags, and more people will be willing to help you.

Read the sticky post "How to use this forum" at http://forum.arduino.cc/index.php/topic,148850.0.html

I’m terribly sorry. I wasn’t intending to post it incorrectly. As you can see from my earlier post I mentioned I was new to the forums and was not fully versed on your etiquette.

Simply asking me to post it differently would be much more courteous than "Learn how to post… "

I will be reading up on the link you graciously provided. Thank you for your kind attention.

Sincerely,
cashdds

here is the code in the way I think I’m supposed to do it…

#include <Stepper.h>
/* This Rugged Motor Shield application demonstrates keyboard control
* of a stepper motor. Assumptions:
*
*   - stepper motor connected to the 2 phases
*   - 8V-30V supply connected to Vin (optional, else Arduino Vin is used)
*   - Vin jumper is cut (J21) (only required if Vin>15V)
*   - FAULT1 and FAULT2 jumpers (J10/J14) installed (optional)
*   - LED jumpers (J15, J16, J6, J7) installed (optional)
*
* The behavior is as follows:
*
*   - The 'f' key sets forward motion
*   - The 'b' key sets backwards motion
*   - The 'a' key accelerates rotational speed
*   - The 'd' key decelerates rotation speed
*   - The 'o' key increases motor power (PWM higher duty cycle)
*   - The 'm' key decreases motor power (PWM lower duty cycle)
* 
* This software is licensed under the GNU General Public License (GPL) Version
* 3 or later. This license is described at
* http://www.gnu.org/licenses/gpl.html
*
* Application Version 1.0 -- October 2010 Rugged Circuits LLC
* http://www.ruggedcircuits.com
*/

// Define how many steps there are in 1 revolution of your motor
#define STEPS_PER_REVOLUTION 200

/**********************************************************/
/* YOU SHOULDN'T HAVE TO CHANGE ANYTHING BELOW THIS POINT */
/**********************************************************/

// Enable (PWM) outputs
#define EN1_PIN 3
#define EN2_PIN 11

// Direction outputs
#define DIR1_PIN 12
#define DIR2_PIN 13

// Fault inputs, active low
#define FAULT1_PIN 5
#define FAULT2_PIN 8

// General-purpose LED's, active high
#define LED0_PIN 9    // For motor A
#define LED1_PIN 10   // For motor A
#define LED2_PIN 16   // For motor B
#define LED3_PIN 17   // For motor B

Stepper stepper(STEPS_PER_REVOLUTION, DIR1_PIN, DIR2_PIN);

// Set initial default values
unsigned RPM = 10;
unsigned PWM = 25;
unsigned DIR = 1;

void setup()
{
 // Configure all outputs off for now
 pinMode(EN1_PIN, OUTPUT); digitalWrite(EN1_PIN, LOW);
 pinMode(EN2_PIN, OUTPUT); digitalWrite(EN2_PIN, LOW);
 pinMode(DIR1_PIN, OUTPUT); digitalWrite(DIR1_PIN, LOW);
 pinMode(DIR2_PIN, OUTPUT); digitalWrite(DIR2_PIN, LOW);

 pinMode(LED0_PIN, OUTPUT); digitalWrite(LED0_PIN, LOW);
 pinMode(LED1_PIN, OUTPUT); digitalWrite(LED1_PIN, LOW);
 pinMode(LED2_PIN, OUTPUT); digitalWrite(LED2_PIN, LOW);
 pinMode(LED3_PIN, OUTPUT); digitalWrite(LED3_PIN, LOW);

 // Configure fault inputs with pullups
 pinMode(FAULT1_PIN, INPUT); digitalWrite(FAULT1_PIN, HIGH);
 pinMode(FAULT2_PIN, INPUT); digitalWrite(FAULT2_PIN, HIGH);

 Serial.begin(9600);

 // Change from divide-by-64 prescale on Timer 2 to divide by 8 to get
 // 8-times faster PWM frequency (976 Hz --> 7.8 kHz). This should prevent
 // overcurrent conditions for steppers with high voltages and low inductance.
 TCCR2B = _BV(CS21);

 // Now enable PWM and start motion
 analogWrite(EN1_PIN, PWM);
 analogWrite(EN2_PIN, PWM);
 stepper.setSpeed(RPM);

}

void printHelp()
{
 Serial.println(
"f - forward motion\n"
"b - backwards motion\n"
"a - faster\n"
"d - slower\n"
"o - more power\n"
"m - less power\n"
);
}

void loop()
{
 if (Serial.available()) {
   switch (Serial.read()) {
     case 'f': case 'F': DIR = 1; break;
     case 'b': case 'B': DIR = -1; break;
     case 'o': case 'O':
                         if (PWM <= 250) PWM += 5;
                         Serial.print("PWM="); Serial.println(PWM);
                         analogWrite(EN1_PIN, PWM); analogWrite(EN2_PIN, PWM);
                         break;
     case 'm': case 'M':
                         if (PWM >= 5) PWM -= 5;
                         Serial.print("PWM="); Serial.println(PWM);
                         analogWrite(EN1_PIN, PWM); analogWrite(EN2_PIN, PWM);
                         break;
     case 'a': case 'A':
                         RPM++;
                         Serial.print("RPM="); Serial.println(RPM);
                         stepper.setSpeed(RPM);
                         break;
     case 'd': case 'D':
                         if (RPM > 1) RPM--;
                         Serial.print("RPM="); Serial.println(RPM);
                         stepper.setSpeed(RPM);
                         break;
     case 'h': case 'H':
                         printHelp();
                         break;
     default:
                         Serial.println("Unknown command");
                         break;
   }
 }

 // This is a busy-wait loop until the inter-step time passes
 stepper.step(DIR);

 // Mirror phase outputs in LED's
 digitalWrite(LED1_PIN, digitalRead(DIR1_PIN));
 digitalWrite(LED3_PIN, digitalRead(DIR2_PIN));

 // Drive fault output LED's as mirror of fault inputs
 digitalWrite(LED0_PIN, !digitalRead(FAULT1_PIN));
 digitalWrite(LED2_PIN, !digitalRead(FAULT2_PIN));

As far as I can see the speed depends on the value in the RPM variable.

I think, from what you said earlier, you want to change that value for day and for night. Something like

if (daytime == true) {
    RPM = daytimeRPM;
}
else {
    RPM = nighttimeRPM;
}

You would use data from the RTC to decide whether it is daytime.

The use of PWM to prevent the smoke escaping is an interesting idea.

...R

If you are going to use a two position switch like a toggle switch or rocker switch you could use

if (digitalRead(switchpin#here) == 1) {
    RPM = daytimeRPM;
}
else {
    RPM = nighttimeRPM;
}

This switch from SparkFun with a built in indicator looks interesting

If you are going to use a momentary push button switch to change states day/night then you will need to follow the examples given in the IDE under File>Examples>02.Digital>StateChangeDetection.

Adding an RTC is really the best way to go, if you want to make the system automatic. Once you get into it, you will find that the programming is relatively simple. A DS3231 would be a good choice as they are more accurate than a ds1307 you can possibly use the alarm functions to switch your system.

Thanks cattledog… and I apologize again for inappropriately posting my sketch

Hey cattledog,

I have been pouring over the suggestion you posted... I think I am going to just use a manual rocker switch like you said, but without a clock component. I will be able to manually switch it when I want so it doesn't have to be automatic....

does that mean I would have to change:

{RPM = daytimeRPM;}

to a different C code term? like {RPM = inputSwitchRPM}?

I don't have a C code dictionary.... if you could recommend one I would gladly buy it....

Thank you,
Cash

daytimeRPM is a constant that you create. You can declare this up the top of the sketch (above the line that says "Don't change anything below this line". It's not a special C code. It's just a name. You could call it "X" but it's best to use descriptive names.

It's called a constant because you don't expect to change this without uploading a new program. RPM on the other hand, is a variable because you do expect its value to change. Once again, this is not a special C keyword, it's just a name that the previous programmer invented.

does that mean I would have to change:

{RPM = daytimeRPM;}

to a different C code term? like {RPM = inputSwitchRPM}?

No. RPM is the name of the variable used in the code you posted, and there is no need to change its name.

The value you assign to RPM can be a number like RPM = 50, or a number represented by a another variable or constant.

daytimeRPM = 50;
RPM = daytimeRPM;

The name you give to a variable is up to you, but it should be descriptive and help communicate the purpose of your code. I think that daytimeRPM and nighttimeRPM are fine names for the variables and I think it is better that they reflect the condition, rather than their origin from a switch state.

A good way to develop your programming skill is to make constant use of the reference dictionary at the arduino.cc site Arduino Reference - Arduino Reference
That reference will help you with pin assignment and digitalRead() which you will need to implement the switch.

You will also need do some searching for information on how to wire switches to a digital input which will lead you to the term INPUT_PULLUP or a discussion of external pullups or pulldowns to avoid "floating" inputs. A good document on switches and their wiring is here
http://www.thebox.myzen.co.uk/Tutorial/Inputs.html

Thank you all.... Its nice to have the support to guide me.... Im old school... like I grew up on programs like:

10 print "hello, how are you?"
20 goto 10

or

10 if (input) = high then goto 30
20 if (input) = low then goto 40
30 RPM=50
35 home
40 RPM=10
45 home

LOL :o .... Apple IIe and Atari 800xl man I'm old

C language is so much more adaptive and easy...so far