Mitchell Levinn / Mbed 2 deprecated RecipeMachine-NXP3823

Dependencies:   mbed

Committer:
levinn
Date:
Mon Feb 28 15:59:49 2011 +0000
Revision:
2:11f93b011c11
Parent:
1:9b55cfc9934b

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
levinn 0:8e708f395bb1 1 /*
levinn 0:8e708f395bb1 2
levinn 2:11f93b011c11 3 This program drives RecipeMachine, project NXP3823.
levinn 0:8e708f395bb1 4
levinn 0:8e708f395bb1 5 Using an mbed NXP LPC1768, here are the pin definitions for I/O interfaces:
levinn 0:8e708f395bb1 6
levinn 0:8e708f395bb1 7 P5 - Continue Switch
levinn 0:8e708f395bb1 8 p6 - Pause Switch
levinn 0:8e708f395bb1 9 p7 - Blue LED
levinn 0:8e708f395bb1 10 p8 - Red LED
levinn 0:8e708f395bb1 11 p9 - Green LED
levinn 0:8e708f395bb1 12 p10 - LCD RS
levinn 0:8e708f395bb1 13 p12 - LCD E
levinn 0:8e708f395bb1 14 p15 - LCD D0
levinn 0:8e708f395bb1 15 p16 - LCD D1
levinn 0:8e708f395bb1 16 P18 - Audio out (analog)
levinn 0:8e708f395bb1 17 p21 - Heater control (PWM)
levinn 0:8e708f395bb1 18 p22 - Mixer control (PWM)
levinn 0:8e708f395bb1 19 p27 - Temp Sensor SDL (I2C)
levinn 0:8e708f395bb1 20 p28 - Temp Sensor SDA (I2C)
levinn 0:8e708f395bb1 21 p29 - LCD D3
levinn 0:8e708f395bb1 22 p30 - LCD D2
levinn 0:8e708f395bb1 23
levinn 0:8e708f395bb1 24 The program is a continuous loop, executing a single recipe repeatedly.
levinn 0:8e708f395bb1 25 The process is:
levinn 0:8e708f395bb1 26 1. Make sure all the appliances are turned off.
levinn 0:8e708f395bb1 27 2. Read the recipe instructions from the recipe.txt file and store it in
levinn 0:8e708f395bb1 28 Steps structure. Memory for up to 20 steps are allocated.
levinn 0:8e708f395bb1 29 3. Wait for "continue" input to start recipe.
levinn 0:8e708f395bb1 30 4. Execute the next step (setting heater level, timer countdown, mixer speed)
levinn 0:8e708f395bb1 31 5. Wait until either time expires, if countdown timer is specified, or
levinn 0:8e708f395bb1 32 Wait until the temperature is above the set temperature, or
levinn 0:8e708f395bb1 33 Check for Pause indicator - (turn off all appliances)
levinn 0:8e708f395bb1 34 if pausing, see if we're aborting (sustained pause request),
levinn 0:8e708f395bb1 35 if aborting, reset step counter
levinn 0:8e708f395bb1 36 6. Go to #3.
levinn 0:8e708f395bb1 37
levinn 0:8e708f395bb1 38 All inputs are polled (no interrupts).
levinn 0:8e708f395bb1 39
levinn 0:8e708f395bb1 40 Modified TextLCD.h library used - modified to include 2x24 display
levinn 0:8e708f395bb1 41 */
levinn 0:8e708f395bb1 42 #include "mbed.h"
levinn 0:8e708f395bb1 43 #include "math.h"
levinn 0:8e708f395bb1 44 #include "TextLCD.h"
levinn 0:8e708f395bb1 45 #define pperiod 0.1
levinn 0:8e708f395bb1 46
levinn 0:8e708f395bb1 47 /*
levinn 0:8e708f395bb1 48 2x24 LCD output
levinn 0:8e708f395bb1 49 */
levinn 0:8e708f395bb1 50 TextLCD lcd(p10, p12, p15, p16, p29, p30); // rs, e, d0-d3
levinn 0:8e708f395bb1 51
levinn 0:8e708f395bb1 52 PwmOut heater(p21); // Heater control triac
levinn 0:8e708f395bb1 53 PwmOut mixer(p22); // Mixer control triac
levinn 0:8e708f395bb1 54 AnalogOut beeptone(p18);
levinn 0:8e708f395bb1 55 DigitalIn Ack(p5); // Momentary acknowledge input, pulldown, by default (Continue switch)
levinn 0:8e708f395bb1 56 DigitalIn Pause(p6); // Momentary pause input, pulldown by default (Pause/Abort switch)
levinn 0:8e708f395bb1 57
levinn 0:8e708f395bb1 58 DigitalOut Blue(p7); // LED to indicate message or pause
levinn 1:9b55cfc9934b 59 DigitalOut Red(p8); // LED to indicate startup or abort
levinn 1:9b55cfc9934b 60 DigitalOut Green(p9); // LED to indicate recipe processing
levinn 0:8e708f395bb1 61
levinn 0:8e708f395bb1 62 struct Steps
levinn 0:8e708f395bb1 63 {
levinn 0:8e708f395bb1 64 char comment[20];
levinn 0:8e708f395bb1 65 float heater, temp, mixer;
levinn 0:8e708f395bb1 66 int clock;
levinn 0:8e708f395bb1 67 };
levinn 0:8e708f395bb1 68
levinn 0:8e708f395bb1 69 const float pi = 3.1415926/20;
levinn 0:8e708f395bb1 70
levinn 0:8e708f395bb1 71 /* IR Temperature Sensor on I2C bus */
levinn 0:8e708f395bb1 72
levinn 0:8e708f395bb1 73 I2C i2c(p28, p27); // sda, scl
levinn 0:8e708f395bb1 74 const int addrwrite = 0xb4; // define the I2C Address - 0x5A is the default, left shift by one for writing
levinn 0:8e708f395bb1 75 const int addrread = 0xb5; // define the I2C address - 0x5A left shifted by one, LSB=1
levinn 0:8e708f395bb1 76 const int Tobj1 = 0x07; // define address of object temperature register in MLX90614
levinn 0:8e708f395bb1 77 // const int Tamb = 0x06; // define address of ambient temperature register in MLX90614 - not used in production
levinn 0:8e708f395bb1 78 Serial pc(USBTX, USBRX); // tx, rx
levinn 0:8e708f395bb1 79
levinn 0:8e708f395bb1 80 const int frequency = 20000;
levinn 0:8e708f395bb1 81 const int AbortTime = 30;
levinn 0:8e708f395bb1 82
levinn 0:8e708f395bb1 83 void beepit(float freq){
levinn 0:8e708f395bb1 84 int i;
levinn 0:8e708f395bb1 85 for (i=0; i<50000; i++) beeptone = 0.5 + freq*sin(pi*i);
levinn 0:8e708f395bb1 86 beeptone = 0.0;
levinn 0:8e708f395bb1 87 }
levinn 0:8e708f395bb1 88
levinn 0:8e708f395bb1 89 void TurnBlue() {Blue = 0; Red = 1; Green = 1;}
levinn 0:8e708f395bb1 90 void TurnRed() {Blue = 1; Red =0; Green = 1;}
levinn 0:8e708f395bb1 91 void TurnGreen() {Blue = 1; Red = 1; Green = 0;}
levinn 0:8e708f395bb1 92
levinn 0:8e708f395bb1 93 LocalFileSystem local("local");
levinn 0:8e708f395bb1 94
levinn 0:8e708f395bb1 95 int main() { // >main
levinn 0:8e708f395bb1 96 char cmd[2];
levinn 0:8e708f395bb1 97 Steps Recipe[20];
levinn 0:8e708f395bb1 98 float temp;
levinn 0:8e708f395bb1 99 int j, c, AbortCntr, countdowntime;
levinn 0:8e708f395bb1 100 bool Abort, Continue;
levinn 0:8e708f395bb1 101
levinn 0:8e708f395bb1 102 TurnRed();
levinn 0:8e708f395bb1 103 heater.period(pperiod);
levinn 0:8e708f395bb1 104 heater.write(0.0); // start with heater off
levinn 0:8e708f395bb1 105 mixer.write(0.0); // and mixer off
levinn 0:8e708f395bb1 106 beepit(4.0);
levinn 0:8e708f395bb1 107 /****************************************************************************
levinn 0:8e708f395bb1 108 Get the recipe from the recipe.txt file and store it in the Steps structure
levinn 0:8e708f395bb1 109 recipe.txt format syntax:
levinn 0:8e708f395bb1 110 one parameter per line
levinn 0:8e708f395bb1 111 first character determines paramater type. Available types:
levinn 0:8e708f395bb1 112 r - the rest of the line is the Recipe name
levinn 0:8e708f395bb1 113 c - is starting value of the countdown timer (seconds) for this step
levinn 0:8e708f395bb1 114 h - is the heater level, between 0.0 and 1.0, the multiplier for the PWM duty cycle
levinn 0:8e708f395bb1 115 t - the target temperature for this step
levinn 0:8e708f395bb1 116 m - the mixer speed, between 0.0 and 1.0, the multiplier for the PWM duty cycle
levinn 0:8e708f395bb1 117 practically, it should be between 0.05 and 0.25 for reasonable speeds
levinn 0:8e708f395bb1 118 p - the pause comment, displayed with each step (add ingredients, for instance)
levinn 0:8e708f395bb1 119 e - indicates the end of a step
levinn 0:8e708f395bb1 120 X - indicates the end of the recipe - this is the last line read (even if there is more in the file)
levinn 0:8e708f395bb1 121 *****************************************************************************/
levinn 0:8e708f395bb1 122
levinn 0:8e708f395bb1 123 FILE *fp = fopen("/local/recipe.txt", "r");
levinn 0:8e708f395bb1 124 if(!fp) { // >>file open
levinn 0:8e708f395bb1 125 lcd.printf("File recipe.txt could not be opened!\n");
levinn 0:8e708f395bb1 126 exit(1);
levinn 0:8e708f395bb1 127 } // <<file open
levinn 0:8e708f395bb1 128
levinn 0:8e708f395bb1 129 wait(2.0); // delay for file operation
levinn 0:8e708f395bb1 130 int totalsteps=0;
levinn 0:8e708f395bb1 131 while ( ((c = fgetc(fp)) != 'X') && (totalsteps < 19)){ //>>readfile
levinn 0:8e708f395bb1 132 switch (c) { //>>>interpret file
levinn 0:8e708f395bb1 133 case 'r': // recipe name - should only be one of these (first)
levinn 0:8e708f395bb1 134 lcd.cls();
levinn 0:8e708f395bb1 135 lcd.printf("Recipe: ");
levinn 0:8e708f395bb1 136 while ( (c = fgetc(fp)) != '\n' ) if(c != '\r')lcd.printf("%c",c);
levinn 0:8e708f395bb1 137 lcd.printf("\n");
levinn 0:8e708f395bb1 138 break;
levinn 0:8e708f395bb1 139 case 'c': fscanf(fp,"%d",&Recipe[totalsteps].clock); // timer (in seconds)
levinn 0:8e708f395bb1 140 break;
levinn 0:8e708f395bb1 141 case 'h': fscanf(fp,"%f",&Recipe[totalsteps].heater); // heater intensity (percentage, between 0 and 1, inclusive)
levinn 0:8e708f395bb1 142 break;
levinn 0:8e708f395bb1 143 case 't': fscanf(fp,"%f",&Recipe[totalsteps].temp); // heater target temp (in degrees fahrenheit)
levinn 0:8e708f395bb1 144 break;
levinn 0:8e708f395bb1 145 case 'm': fscanf(fp,"%f",&Recipe[totalsteps].mixer); // mixer speed (percentage, between 0 and 1, inclusive)
levinn 0:8e708f395bb1 146 break;
levinn 0:8e708f395bb1 147 case 'p':
levinn 0:8e708f395bb1 148 j = 0;
levinn 0:8e708f395bb1 149 while (( (Recipe[totalsteps].comment[j++] = fgetc(fp)) != '\n') && (j < 19)) ; // pause with comment, wait for pushbutton acknowledgement
levinn 0:8e708f395bb1 150 Recipe[totalsteps].comment[j-2] = '\n'; // make sure there is a \n at the end (delete the \r)
levinn 0:8e708f395bb1 151 break;
levinn 0:8e708f395bb1 152 case 'e': // end of this step
levinn 0:8e708f395bb1 153 totalsteps++;
levinn 0:8e708f395bb1 154 break;
levinn 0:8e708f395bb1 155 } //<<<interpret file
levinn 0:8e708f395bb1 156 } //<<read file
levinn 0:8e708f395bb1 157
levinn 0:8e708f395bb1 158 wait(1.0);
levinn 0:8e708f395bb1 159 lcd.printf("Total Steps = %i",totalsteps);
levinn 0:8e708f395bb1 160
levinn 0:8e708f395bb1 161 fclose(fp);
levinn 0:8e708f395bb1 162 wait(1.0); // Drive should be restored. this is the same as just returning from main
levinn 0:8e708f395bb1 163 int stepnumber;
levinn 0:8e708f395bb1 164 while(1) { // >> Main recipe loop
levinn 0:8e708f395bb1 165 Abort = false;
levinn 0:8e708f395bb1 166 TurnBlue();
levinn 0:8e708f395bb1 167 lcd.cls();
levinn 0:8e708f395bb1 168 lcd.printf("\nStarting Recipe");
levinn 0:8e708f395bb1 169 wait(1.0);
levinn 0:8e708f395bb1 170 temp=0.0; // first time through, temp is reset
levinn 0:8e708f395bb1 171 for (stepnumber = 0; ( (stepnumber < totalsteps) && !Abort ) ; stepnumber++) { //>>>Step Loop
levinn 0:8e708f395bb1 172 lcd.cls();
levinn 0:8e708f395bb1 173 j =0; while (Recipe[stepnumber].comment[j] != '\n') lcd.printf("%c",Recipe[stepnumber].comment[j++]);
levinn 0:8e708f395bb1 174 lcd.printf("\nHit Continue to proceed");
levinn 0:8e708f395bb1 175 countdowntime = Recipe[stepnumber].clock;
levinn 0:8e708f395bb1 176 beepit(2.0);
levinn 0:8e708f395bb1 177 TurnBlue();
levinn 0:8e708f395bb1 178 while(Ack == 0) ; // wait for ack
levinn 0:8e708f395bb1 179 while (Ack == 1) ; // debounce
levinn 0:8e708f395bb1 180 TurnGreen(); // we're good to go!
levinn 0:8e708f395bb1 181 Continue = true;
levinn 0:8e708f395bb1 182
levinn 0:8e708f395bb1 183 while(Continue && !Abort) { //>>>>execute step
levinn 0:8e708f395bb1 184 if (Pause == 1) { // check for Pause hit >>>>>Pause/Abort test
levinn 0:8e708f395bb1 185 lcd.cls();
levinn 0:8e708f395bb1 186 lcd.printf("Pausing\n");
levinn 0:8e708f395bb1 187 heater.write(0.0); // turn the heater off for pause
levinn 0:8e708f395bb1 188 mixer.write(0.0); // turn the mixer off for pause
levinn 0:8e708f395bb1 189 beepit(1.0);
levinn 0:8e708f395bb1 190 AbortCntr = 1; // start counter for abort - extended Pause == abort
levinn 0:8e708f395bb1 191 TurnBlue();
levinn 0:8e708f395bb1 192 while (Pause == 1 ) { //>>>>>>delay loop, stay here until Pause released
levinn 0:8e708f395bb1 193 wait(0.1); // 0.1 second samples
levinn 0:8e708f395bb1 194 if (AbortCntr++ > AbortTime) { //>>>>>>>Yes Abort
levinn 0:8e708f395bb1 195 beepit(0.5);
levinn 0:8e708f395bb1 196 lcd.printf("Aborting\n");
levinn 0:8e708f395bb1 197 Abort = true;
levinn 0:8e708f395bb1 198 TurnRed();
levinn 0:8e708f395bb1 199 } //<<<<<<<Yes Abort
levinn 0:8e708f395bb1 200 } //<<<<<<delay loop
levinn 0:8e708f395bb1 201 lcd.printf("Hit Continue to proceed");
levinn 0:8e708f395bb1 202 if (!Abort) while (Ack == 0); // wait for Ack after pause - unless we're aborting
levinn 0:8e708f395bb1 203 } //<<<<<Pause/Abort test
levinn 0:8e708f395bb1 204 if (!Abort) { //>>>>>Not Aborting
levinn 0:8e708f395bb1 205 lcd.cls();
levinn 0:8e708f395bb1 206 j =0; while (Recipe[stepnumber].comment[j] != '\n') lcd.printf("%c",Recipe[stepnumber].comment[j++]);
levinn 0:8e708f395bb1 207 TurnGreen();
levinn 0:8e708f395bb1 208 heater.write(Recipe[stepnumber].heater); // turn the heater on to the setting
levinn 0:8e708f395bb1 209 mixer.write(Recipe[stepnumber].mixer); // turn the mixer on to the setting
levinn 0:8e708f395bb1 210 ///*
levinn 0:8e708f395bb1 211 //Read the ambient temperature
levinn 0:8e708f395bb1 212 //not needed for production version
levinn 0:8e708f395bb1 213 //*/
levinn 0:8e708f395bb1 214 // i2c.frequency(frequency);
levinn 0:8e708f395bb1 215 // i2c.start();
levinn 0:8e708f395bb1 216 // if (i2c.write(addrwrite) != 1) lcd.printf("write 1 error\n");
levinn 0:8e708f395bb1 217 // if (i2c.write(Tamb) !=1) lcd.printf("write 2 error\n");
levinn 0:8e708f395bb1 218 // i2c.start();
levinn 0:8e708f395bb1 219 // if (i2c.write(addrread) != 1) lcd.printf("write 3 error\n");
levinn 0:8e708f395bb1 220 // cmd[0] = i2c.read(1);
levinn 0:8e708f395bb1 221 // cmd[1] = i2c.read(1);
levinn 0:8e708f395bb1 222 // i2c.stop();
levinn 0:8e708f395bb1 223 // temp = ((0.02 * ((cmd[1] << 8) + cmd[0])) - 273.15) * 9/5 + 32;
levinn 0:8e708f395bb1 224 // lcd.printf("amb=%.2f", temp);
levinn 0:8e708f395bb1 225 //
levinn 0:8e708f395bb1 226 /*
levinn 0:8e708f395bb1 227 Read the object temperature
levinn 0:8e708f395bb1 228 */
levinn 0:8e708f395bb1 229
levinn 0:8e708f395bb1 230 i2c.frequency(frequency);
levinn 0:8e708f395bb1 231 i2c.start();
levinn 0:8e708f395bb1 232 if (i2c.write(addrwrite) != 1) lcd.printf("write 1 error\n");
levinn 0:8e708f395bb1 233 if (i2c.write(Tobj1) !=1) lcd.printf("write 2 error\n");
levinn 0:8e708f395bb1 234 i2c.start();
levinn 0:8e708f395bb1 235 if (i2c.write(addrread) != 1) lcd.printf("write 3 error\n");
levinn 0:8e708f395bb1 236 cmd[0] = i2c.read(1);
levinn 0:8e708f395bb1 237 cmd[1] = i2c.read(1);
levinn 0:8e708f395bb1 238 i2c.stop();
levinn 0:8e708f395bb1 239 temp = ((0.02 * ((cmd[1] << 8) + cmd[0])) - 273.15) * 9/5 + 32;
levinn 0:8e708f395bb1 240 lcd.locate(0,1);
levinn 0:8e708f395bb1 241 if (countdowntime == 0) {
levinn 0:8e708f395bb1 242 lcd.printf("Temp:%.2f Target:%.2f", temp, Recipe[stepnumber].temp);
levinn 0:8e708f395bb1 243 if (temp<Recipe[stepnumber].temp) Continue = true;
levinn 0:8e708f395bb1 244 else Continue = false;
levinn 0:8e708f395bb1 245 }
levinn 0:8e708f395bb1 246 else {
levinn 0:8e708f395bb1 247 lcd.printf("Temp:%.2f Time:%4d",temp,countdowntime--);
levinn 0:8e708f395bb1 248 if (countdowntime == 0) Continue = false;
levinn 0:8e708f395bb1 249 else Continue = true;
levinn 0:8e708f395bb1 250 }
levinn 0:8e708f395bb1 251 wait(1.00);
levinn 0:8e708f395bb1 252 } //<<<<<Not Aborting
levinn 0:8e708f395bb1 253
levinn 0:8e708f395bb1 254 } //<<<<execute step loop
levinn 0:8e708f395bb1 255 lcd.cls(); // Done with this step
levinn 0:8e708f395bb1 256 } //<<<step loop
levinn 0:8e708f395bb1 257
levinn 0:8e708f395bb1 258 /* Now we're done. Shut off the heater and mixer. */
levinn 0:8e708f395bb1 259
levinn 0:8e708f395bb1 260 heater.write(0.00);
levinn 0:8e708f395bb1 261 mixer.write(0.00);
levinn 0:8e708f395bb1 262 TurnBlue();
levinn 0:8e708f395bb1 263 lcd.cls();
levinn 0:8e708f395bb1 264 lcd.printf("Recipe done!\nHit Continue to repeat");
levinn 0:8e708f395bb1 265 while (!Ack);
levinn 0:8e708f395bb1 266 }//<<main recipe loop
levinn 0:8e708f395bb1 267 } //<main