Commit 08aff03f authored by Tim Soderstrom's avatar Tim Soderstrom

Added a "coast" when changing directions

parent 4fa3d29b
......@@ -9,7 +9,7 @@
/**********
* Defines
**********/
#define VERSION "v0.04"
#define VERSION "v0.10"
#define BANNER_DELAY_MS 1000
#define RED 0x1
......@@ -42,15 +42,21 @@
// Maximum number of dev steps a particular Dev Process can have.
#define MAX_DEV_STEPS 8
// How often to check the temperature probe
#define TEMP_UPDATE_INTERVAL 10
#define TEMP_UPDATE_INTERVAL 60
// Default Preheat Temperature (C)
#define DEFAULT_PREHEAT_TEMP 39
// Manual Temperature Adjustment Steps
#define TEMP_ADJUSTMENT_PRECISION 0.5
#define TEMP_ADJUSTMENT_PRECISION 0.1
// Specified Motor RPM
#define MOTOR_RPM 45
// Slowet Motor Will Turn
#define MOTOR_RPM 76
// Slowest Motor Will Turn
#define MOTOR_MIN_RPM 24
// How long to free spin motor when changing direction
#define COAST_MOTOR_MILLIS 500
// PID Window Size
#define PID_WINDOW_SIZE_MILLIS 5000
#define PID_SAMPLE_TIME 1000
// PID Parameters
//#define KP 2
......@@ -98,10 +104,15 @@ double pidOutput;
double currentTemperature = 0;
double targetTemperature = DEFAULT_PREHEAT_TEMP;
unsigned long pidWindowStartTime;
unsigned int pidWindowSizeMS = 10000;
//unsigned int pidWindowSizeMS = 5000;
bool heaterState = OFF;
unsigned long previousMotorMillis = 0;
unsigned long previousCoastMillis = 0;
bool motorDirection = FORWARD;
// If we need to coast
bool motorCoast = true;
// If we are actively coasting
bool motorCoasting = true;
/**********
* Objects
......@@ -121,48 +132,22 @@ PID pid(&currentTemperature, &pidOutput, &targetTemperature, KP, KI, KD, DIRECT)
******************************/
// Dev Processes (These can eventually be in the EEPROM)
const byte processCount = 3;
const byte processCount = 1;
// Dev Processes
const DevProcess process[] =
{
{
"Test",
255,
10,
24,
5,
{
{"Develop", 30, RED},
{"Blix", 35, VIOLET},
{"Wash 1", 36, BLUE},
{"Wash 2", 37, TEAL},
{"Stabilizer", 40, WHITE}
}
},
{
"C41",
255,
"ECN-2",
75,
10,
38,
41.1,
5,
{
{"Develop", 195, RED},
{"Blix", 195, VIOLET},
{"Wash 1", 360, BLUE},
{"Wash 2", 120, TEAL},
{"Stabilizer", 60, WHITE}
}
},
{
"Dlta100 DDX 1+4",
255,
10,
20,
3,
{
{"Develop", 720, BLUE},
{"Stop", 60, RED},
{"Fix", 300, WHITE}
{"Develop", 180, RED},
{"Stop", 60, YELLOW},
{"Bleach", 180, VIOLET},
{"Fix", 180, WHITE},
{"Rinse", 60, WHITE}
}
}
};
......@@ -202,7 +187,7 @@ void setup()
/* Setup PID */
pidWindowStartTime = millis();
pid.SetOutputLimits(0, pidWindowSizeMS);
pid.SetOutputLimits(0, PID_WINDOW_SIZE_MILLIS);
pid.SetMode(AUTOMATIC);
currentTemperature = collectTemperatures();
......
......@@ -55,26 +55,24 @@ void processStep(DevStep step, byte motorSpeed, byte motorDirectionInterval, int
while(timeRemainingMS >= 0)
{
currentMillis = millis();
controlTemp();
controlMotor(motorSpeed, motorDirectionInterval);
// Update once a second
if(currentMillis - previousMillis >= SECONDS_MS)
{
Serial.print("Time remaining: ");
Serial.println(timeRemainingMS);
// Every 10 seconds, check temperature
// Every TEMP_UPDATE_INTERVAL seconds, check temperature
if(tempUpdateCycle > TEMP_UPDATE_INTERVAL - 1)
{
currentTemperature = collectTemperatures();
tempUpdateCycle = 0;
Serial.print("Temperature: ");
Serial.println(currentTemperature);
//Serial.print("Temperature: ");
//Serial.println(currentTemperature);
}
else
++tempUpdateCycle;
controlMotor(motorSpeed, motorDirectionInterval);
updateDisplay(int(timeRemainingMS / SECONDS_MS), currentTemperature);
timeRemainingMS -= SECONDS_MS;
previousMillis = millis();
......@@ -91,16 +89,16 @@ void developFilm()
controlMotor(0, 0);
// After picking a process, pre-heat then start dev
targetTemperature = currentProcess.targetTemperature;
preheat();
//preheat();
for(byte i = 0 ; i < currentProcess.steps; ++i)
{
processStep(currentProcess.devStep[i],
currentProcess.motorSpeed,
currentProcess.motorDirectionInterval,
currentProcess.targetTemperature);
Serial.println("Motor: Stopping");
//Serial.println("Motor: Stopping");
controlMotor(0, 0);
Serial.println("done");
//Serial.println("done");
wait(currentProcess.devStep[i].name, "Complete");
}
lcd.setBacklight(GREEN);
......@@ -159,14 +157,14 @@ void preheat()
void controlTemp()
{
pid.Compute();
if (millis() - pidWindowStartTime > pidWindowSizeMS)
pidWindowStartTime += pidWindowSizeMS;
if (millis() - pidWindowStartTime > PID_WINDOW_SIZE_MILLIS)
pidWindowStartTime += PID_WINDOW_SIZE_MILLIS;
if (pidOutput > millis() - pidWindowStartTime)
{
if(heaterState != ON)
{
heaterState = ON;
Serial.println("Turned Heater On");
//Serial.println("Turned Heater On");
}
digitalWrite(heater, HIGH);
}
......@@ -175,7 +173,7 @@ void controlTemp()
if(heaterState != OFF)
{
heaterState = OFF;
Serial.println("Turned Heater Off");
//Serial.println("Turned Heater Off");
}
digitalWrite(heater, LOW);
}
......@@ -183,37 +181,69 @@ void controlTemp()
void controlMotor(byte speed, byte directionInterval)
{
analogWrite(motorSpeed, speed);
if(directionInterval > 0)
{
if(millis() - previousMotorMillis >= SECONDS_MS * directionInterval)
// Coast on direction change
if(motorCoast)
{
if(motorDirection == FORWARD)
analogWrite(motorSpeed, 0);
motorCoasting = true;
if (millis() - previousCoastMillis >= COAST_MOTOR_MILLIS && motorCoast)
{
Serial.println("Motor: Reverse");
digitalWrite(motorX, LOW);
digitalWrite(motorY, HIGH);
motorDirection = REVERSE;
//Serial.println("Done Coasting");
motorCoasting = false;
}
else
}
if(millis() - previousMotorMillis >= SECONDS_MS * directionInterval)
{
// Flag we need to coast the motor
// If we are coasting, do nothing
if(motorCoasting)
{
Serial.println("Motor: Forward");
digitalWrite(motorX, HIGH);
digitalWrite(motorY, LOW);
motorDirection = FORWARD;
}
// If we are not currently coasting, but
else if(!motorCoast)
{
//Serial.println("Coast Requested");
previousCoastMillis = millis();
motorCoast = true;
}
// Now Change Direction
else if(!motorCoasting)
{
analogWrite(motorSpeed, toSpeed(speed));
changeDirection();
motorCoast = false;
previousMotorMillis = millis();
}
previousMotorMillis = millis();
}
}
/* If directionInterval is zero, never change speed */
else
{
analogWrite(motorSpeed, toSpeed(speed));
digitalWrite(motorX, HIGH);
digitalWrite(motorY, LOW);
motorDirection = FORWARD;
}
}
void changeDirection()
{
if(motorDirection == FORWARD)
{
//Serial.println("Motor: Reverse");
digitalWrite(motorX, LOW);
digitalWrite(motorY, HIGH);
motorDirection = REVERSE;
}
else
{
//Serial.println("Motor: Forward");
digitalWrite(motorX, HIGH);
digitalWrite(motorY, LOW);
motorDirection = FORWARD;
}
}
void updateDisplay(int totalSeconds, int temperature)
{
char buffer[32];
sprintf(buffer, "%02d:%02d Temp: %02dC", int(totalSeconds / 60), int(totalSeconds % 60), temperature);
sprintf(buffer, "%02d:%02d / %02dC", int(totalSeconds / 60), int(totalSeconds % 60), temperature);
lcd.setCursor(0,1);
lcd.print(buffer);
}
......@@ -13,7 +13,10 @@ byte wait(char line1[16], char line2[16])
byte button=0;
drawDisplay(line1, line2);
while(!button)
{
button = lcd.readButtons();
controlTemp();
}
lcd.clear();
delay(250);
return button;
......@@ -50,7 +53,7 @@ void runMotor()
while(true)
{
if(runMotor)
controlMotor(toSpeed(rpm), directionInterval);
controlMotor(rpm, directionInterval);
else
controlMotor(0, 0);
button = lcd.readButtons();
......
......@@ -17,7 +17,7 @@ struct DevStep
/* Full development process, which consists of the name, an array of dev steps and various setup info.
*
* name: Name of the process, e.g C-41
* motorSpeed: PWM value for the speed of the motor
* motorSpeed: RPM value for the speed of the motor
* motorDirectionInterval: How many seconds between changing direction of rotation
* steps: How many total development steps for the process (e.g. Dev, Stop, Fix would be 3)
* DevStep: An array of DevStep structs. Note uses a const for the array size.
......@@ -27,7 +27,7 @@ struct DevProcess
char* name;
byte motorSpeed;
byte motorDirectionInterval;
byte targetTemperature;
double targetTemperature;
byte steps;
DevStep devStep[MAX_DEV_STEPS];
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment