Mitchell Levinn / Mbed 2 deprecated RecipeMachine-NXP3823

Dependencies:   mbed

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