Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
- Committer:
- levinn
- Date:
- 2011-02-28
- Revision:
- 1:9b55cfc9934b
- Parent:
- 0:8e708f395bb1
- Child:
- 2:11f93b011c11
File content as of revision 1:9b55cfc9934b:
/*
This program drive RecipeMachine, project NXP3823.
Using an mbed NXP LPC1768, here are the pin definitions for I/O interfaces:
P5 - Continue Switch
p6 - Pause Switch
p7 - Blue LED
p8 - Red LED
p9 - Green LED
p10 - LCD RS
p12 - LCD E
p15 - LCD D0
p16 - LCD D1
P18 - Audio out (analog)
p21 - Heater control (PWM)
p22 - Mixer control (PWM)
p27 - Temp Sensor SDL (I2C)
p28 - Temp Sensor SDA (I2C)
p29 - LCD D3
p30 - LCD D2
The program is a continuous loop, executing a single recipe repeatedly.
The process is:
1. Make sure all the appliances are turned off.
2. Read the recipe instructions from the recipe.txt file and store it in
Steps structure. Memory for up to 20 steps are allocated.
3. Wait for "continue" input to start recipe.
4. Execute the next step (setting heater level, timer countdown, mixer speed)
5. Wait until either time expires, if countdown timer is specified, or
Wait until the temperature is above the set temperature, or
Check for Pause indicator - (turn off all appliances)
if pausing, see if we're aborting (sustained pause request),
if aborting, reset step counter
6. Go to #3.
All inputs are polled (no interrupts).
Modified TextLCD.h library used - modified to include 2x24 display
*/
#include "mbed.h"
#include "math.h"
#include "TextLCD.h"
#define pperiod 0.1
/*
2x24 LCD output
*/
TextLCD lcd(p10, p12, p15, p16, p29, p30); // rs, e, d0-d3
PwmOut heater(p21); // Heater control triac
PwmOut mixer(p22); // Mixer control triac
AnalogOut beeptone(p18);
DigitalIn Ack(p5); // Momentary acknowledge input, pulldown, by default (Continue switch)
DigitalIn Pause(p6); // Momentary pause input, pulldown by default (Pause/Abort switch)
DigitalOut Blue(p7); // LED to indicate message or pause
DigitalOut Red(p8); // LED to indicate startup or abort
DigitalOut Green(p9); // LED to indicate recipe processing
struct Steps
{
char comment[20];
float heater, temp, mixer;
int clock;
};
const float pi = 3.1415926/20;
/* IR Temperature Sensor on I2C bus */
I2C i2c(p28, p27); // sda, scl
const int addrwrite = 0xb4; // define the I2C Address - 0x5A is the default, left shift by one for writing
const int addrread = 0xb5; // define the I2C address - 0x5A left shifted by one, LSB=1
const int Tobj1 = 0x07; // define address of object temperature register in MLX90614
// const int Tamb = 0x06; // define address of ambient temperature register in MLX90614 - not used in production
Serial pc(USBTX, USBRX); // tx, rx
const int frequency = 20000;
const int AbortTime = 30;
void beepit(float freq){
int i;
for (i=0; i<50000; i++) beeptone = 0.5 + freq*sin(pi*i);
beeptone = 0.0;
}
void TurnBlue() {Blue = 0; Red = 1; Green = 1;}
void TurnRed() {Blue = 1; Red =0; Green = 1;}
void TurnGreen() {Blue = 1; Red = 1; Green = 0;}
LocalFileSystem local("local");
int main() { // >main
char cmd[2];
Steps Recipe[20];
float temp;
int j, c, AbortCntr, countdowntime;
bool Abort, Continue;
TurnRed();
heater.period(pperiod);
heater.write(0.0); // start with heater off
mixer.write(0.0); // and mixer off
beepit(4.0);
/****************************************************************************
Get the recipe from the recipe.txt file and store it in the Steps structure
recipe.txt format syntax:
one parameter per line
first character determines paramater type. Available types:
r - the rest of the line is the Recipe name
c - is starting value of the countdown timer (seconds) for this step
h - is the heater level, between 0.0 and 1.0, the multiplier for the PWM duty cycle
t - the target temperature for this step
m - the mixer speed, between 0.0 and 1.0, the multiplier for the PWM duty cycle
practically, it should be between 0.05 and 0.25 for reasonable speeds
p - the pause comment, displayed with each step (add ingredients, for instance)
e - indicates the end of a step
X - indicates the end of the recipe - this is the last line read (even if there is more in the file)
*****************************************************************************/
FILE *fp = fopen("/local/recipe.txt", "r");
if(!fp) { // >>file open
lcd.printf("File recipe.txt could not be opened!\n");
exit(1);
} // <<file open
wait(2.0); // delay for file operation
int totalsteps=0;
while ( ((c = fgetc(fp)) != 'X') && (totalsteps < 19)){ //>>readfile
switch (c) { //>>>interpret file
case 'r': // recipe name - should only be one of these (first)
lcd.cls();
lcd.printf("Recipe: ");
while ( (c = fgetc(fp)) != '\n' ) if(c != '\r')lcd.printf("%c",c);
lcd.printf("\n");
break;
case 'c': fscanf(fp,"%d",&Recipe[totalsteps].clock); // timer (in seconds)
break;
case 'h': fscanf(fp,"%f",&Recipe[totalsteps].heater); // heater intensity (percentage, between 0 and 1, inclusive)
break;
case 't': fscanf(fp,"%f",&Recipe[totalsteps].temp); // heater target temp (in degrees fahrenheit)
break;
case 'm': fscanf(fp,"%f",&Recipe[totalsteps].mixer); // mixer speed (percentage, between 0 and 1, inclusive)
break;
case 'p':
j = 0;
while (( (Recipe[totalsteps].comment[j++] = fgetc(fp)) != '\n') && (j < 19)) ; // pause with comment, wait for pushbutton acknowledgement
Recipe[totalsteps].comment[j-2] = '\n'; // make sure there is a \n at the end (delete the \r)
break;
case 'e': // end of this step
totalsteps++;
break;
} //<<<interpret file
} //<<read file
wait(1.0);
lcd.printf("Total Steps = %i",totalsteps);
fclose(fp);
wait(1.0); // Drive should be restored. this is the same as just returning from main
int stepnumber;
while(1) { // >> Main recipe loop
Abort = false;
TurnBlue();
lcd.cls();
lcd.printf("\nStarting Recipe");
wait(1.0);
temp=0.0; // first time through, temp is reset
for (stepnumber = 0; ( (stepnumber < totalsteps) && !Abort ) ; stepnumber++) { //>>>Step Loop
lcd.cls();
j =0; while (Recipe[stepnumber].comment[j] != '\n') lcd.printf("%c",Recipe[stepnumber].comment[j++]);
lcd.printf("\nHit Continue to proceed");
countdowntime = Recipe[stepnumber].clock;
beepit(2.0);
TurnBlue();
while(Ack == 0) ; // wait for ack
while (Ack == 1) ; // debounce
TurnGreen(); // we're good to go!
Continue = true;
while(Continue && !Abort) { //>>>>execute step
if (Pause == 1) { // check for Pause hit >>>>>Pause/Abort test
lcd.cls();
lcd.printf("Pausing\n");
heater.write(0.0); // turn the heater off for pause
mixer.write(0.0); // turn the mixer off for pause
beepit(1.0);
AbortCntr = 1; // start counter for abort - extended Pause == abort
TurnBlue();
while (Pause == 1 ) { //>>>>>>delay loop, stay here until Pause released
wait(0.1); // 0.1 second samples
if (AbortCntr++ > AbortTime) { //>>>>>>>Yes Abort
beepit(0.5);
lcd.printf("Aborting\n");
Abort = true;
TurnRed();
} //<<<<<<<Yes Abort
} //<<<<<<delay loop
lcd.printf("Hit Continue to proceed");
if (!Abort) while (Ack == 0); // wait for Ack after pause - unless we're aborting
} //<<<<<Pause/Abort test
if (!Abort) { //>>>>>Not Aborting
lcd.cls();
j =0; while (Recipe[stepnumber].comment[j] != '\n') lcd.printf("%c",Recipe[stepnumber].comment[j++]);
TurnGreen();
heater.write(Recipe[stepnumber].heater); // turn the heater on to the setting
mixer.write(Recipe[stepnumber].mixer); // turn the mixer on to the setting
///*
//Read the ambient temperature
//not needed for production version
//*/
// i2c.frequency(frequency);
// i2c.start();
// if (i2c.write(addrwrite) != 1) lcd.printf("write 1 error\n");
// if (i2c.write(Tamb) !=1) lcd.printf("write 2 error\n");
// i2c.start();
// if (i2c.write(addrread) != 1) lcd.printf("write 3 error\n");
// cmd[0] = i2c.read(1);
// cmd[1] = i2c.read(1);
// i2c.stop();
// temp = ((0.02 * ((cmd[1] << 8) + cmd[0])) - 273.15) * 9/5 + 32;
// lcd.printf("amb=%.2f", temp);
//
/*
Read the object temperature
*/
i2c.frequency(frequency);
i2c.start();
if (i2c.write(addrwrite) != 1) lcd.printf("write 1 error\n");
if (i2c.write(Tobj1) !=1) lcd.printf("write 2 error\n");
i2c.start();
if (i2c.write(addrread) != 1) lcd.printf("write 3 error\n");
cmd[0] = i2c.read(1);
cmd[1] = i2c.read(1);
i2c.stop();
temp = ((0.02 * ((cmd[1] << 8) + cmd[0])) - 273.15) * 9/5 + 32;
lcd.locate(0,1);
if (countdowntime == 0) {
lcd.printf("Temp:%.2f Target:%.2f", temp, Recipe[stepnumber].temp);
if (temp<Recipe[stepnumber].temp) Continue = true;
else Continue = false;
}
else {
lcd.printf("Temp:%.2f Time:%4d",temp,countdowntime--);
if (countdowntime == 0) Continue = false;
else Continue = true;
}
wait(1.00);
} //<<<<<Not Aborting
} //<<<<execute step loop
lcd.cls(); // Done with this step
} //<<<step loop
/* Now we're done. Shut off the heater and mixer. */
heater.write(0.00);
mixer.write(0.00);
TurnBlue();
lcd.cls();
lcd.printf("Recipe done!\nHit Continue to repeat");
while (!Ack);
}//<<main recipe loop
} //<main