I am working on a project which will involve controlling the speed of a motor in various patterns. I'm currently using pwm (on pin 3) and a whack of delay()'s (ick, i know...) to create these patterns which is working just fine. The problem comes in when I try to control which pattern is active via serial. There's a few long patterns (that can run from minutes to hours) which causes problems trying to read the serial. Essentially, when the pattern is running, I cannot issue a 'stop' command to halt the pattern.
I know the first obvious solution would be something along the lines of the 'blink without delay' tutorial (not sure of the name of the method used). I've done the same thing many times in simpler projects, but I just can't wrap my head around how to go about doing it in this case. There's many different patterns, with varying timing ranging from seconds to over an hour. (relevant code below)
My second idea is to use a second atmega to handle the serial (it will be a cellular chip in the final version) and ping the motor 'node' via a hardware interrupt. However I think that I'd still have the same problem due to the delay()'s.
On a side (but forum related) topic. How feasible is it to use bluetooth to pair the arduino to a cell phone? Would it be specific to the phone or is there some sort of standards in place? The project will be controlled via text messages, so I don't really need much from the phone; only a notice of a new message, number and content.
Thanks as always for any help!
Code:
#define motor_PIN 3
#define NUM_motor_SPEEDS 4
#define motor_HIGH 255
#define motor_MEDHIGH 200
#define motor_MED 150
#define motor_LOW 100
#define MILLIS_IN_MINUTE 60000
int speeds[NUM_motor_SPEEDS] = {motor_LOW, motor_MED, motor_MEDHIGH, motor_HIGH};
void motorOff() {digitalWrite(motor_PIN, 0);}
void motorOn(byte spd) {analogWrite(motor_PIN, spd);}
void motorRampUp(byte maxSpeed, int dly) {
for (int i=0;i<=maxSpeed;i+=5) {
analogWrite(motor_PIN, i);
delay(dly);
}
}
void motorRampDown(byte maxSpeed, int dly) {
for (int i=maxSpeed;i>0;i-=5) {
analogWrite(motor_PIN, i);
delay(dly);
}
motorOff();
}
void motorGrowingPulse(byte spd, byte pulseSpd, int onDly, int offDly) {
motorRampUp(spd, pulseSpd);
delay(onDly);
motorRampDown(spd, pulseSpd);
delay(offDly);
}
void motorQuickPulse() {
motorOn(motor_HIGH);
delay(150);
motorOff();
delay(50);
}
void motorQuickPulse(byte cnt) {
for (byte i=0;i<cnt;i++) {
motorQuickPulse();
}
}
void motorIncreasingQuickPulses(byte cnt, long dly) {
for (byte i=1;i<=cnt;i++) {
for (byte x=0;x<i;x++) {
motorQuickPulse();
}
delay(dly);
}
}
void motorModeGrowingPulsesShort(byte cnt, byte spd) {
for (byte i=0;i<cnt;i++) {
motorGrowingPulse(spd, 25, 2000, 2000);
}
}
void motorModeGrowingPulsesLong(byte cnt, byte spd) {
for (byte i=0;i<cnt;i++) {
motorGrowingPulse(spd, 100, 5000, 1000);
}
}
void motorPatternA(byte spd, int totMinutes) {
motorOn(motor_HIGH);
delay(2000);
motorOff();
delay(150);
motorQuickPulse(3);
long totalMillis = totMinutes * MILLIS_IN_MINUTE;
long current = 0;
randomSeed(analogRead(0));
delay(random(5000,30000));
unsigned long startTime = millis();
while (current <= totalMillis) {
current = millis() - startTime;
motorQuickPulse(random(1, 6));
delay(random(100, ((totalMillis - current) * 0.1)));
}
}
void motorPatternB(byte maxSpeed, int totMinutes) {
unsigned long startTime = millis();
long totalMillis = totMinutes * MILLIS_IN_MINUTE;
long current = 0;
long remaining = totalMillis - current;
int minDly = 5000;
byte cycle = 1;
randomSeed(analogRead(0));
while (current <= totalMillis) {
current = millis() - startTime;
remaining = totalMillis - current;
if (remaining < 10000) minDly = 500;
motorRampCycle(cycle++, motor_HIGH, 2, 5, 0);
delay(random(minDly, remaining * 0.1));
}
}
void motorModePatternC(byte cycles) {
int bigPulseDly = 500;
int miniPulseDly = 0;
for (byte i=0;i<=cycles;i++) {
Serial.print("Cyc: ");Serial.print(i, DEC);Serial.print(" big: ");Serial.print(bigPulseDly, DEC);Serial.print (", mini: ");Serial.println(miniPulseDly, DEC);
motorRampCycle(1, motor_HIGH, 5, bigPulseDly, 100);
motorRampCycle(i, motor_HIGH, 2, miniPulseDly, 0);
if ((bigPulseDly+=100) > 3500) bigPulseDly = 3500;
if ((miniPulseDly+=5) > 125) miniPulseDly = 125;
delay(1000);
}
}
void motorRampCycle(byte numCycles, byte spd, byte dly, int upDly, int downDly) {
for (byte i=0;i<numCycles;i++) {
motorRampUp(spd, dly);
delay(upDly);
motorRampDown(spd, dly);
delay(downDly);
}
motorOff();
}