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.
Revision 0:9526e71a200f, committed 2012-01-15
- Comitter:
- jpelletier
- Date:
- Sun Jan 15 06:13:50 2012 +0000
- Commit message:
- This port compiles but I haven\t tested it on hardware yet. There may be some adjustments to the LCD commands to be done.
Changed in this revision
diff -r 000000000000 -r 9526e71a200f TextLCD/TextLCD.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TextLCD/TextLCD.cpp Sun Jan 15 06:13:50 2012 +0000 @@ -0,0 +1,159 @@ +/* mbed TextLCD Library, for a 4-bit LCD based on HD44780 + * Copyright (c) 2007-2010, sford, http://mbed.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "TextLCD.h" +#include "mbed.h" + +TextLCD::TextLCD(PinName rs, PinName e, PinName d4, PinName d5, + PinName d6, PinName d7, LCDType type) : _rs(rs), + _e(e), _d(d4, d5, d6, d7), + _type(type) { + + _e = 1; + _rs = 0; // command mode + + wait(0.015); // Wait 15ms to ensure powered up + + // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus) + for (int i=0; i<3; i++) { + writeByte(0x3); + wait(0.00164); // this command takes 1.64ms, so wait for it + } + writeByte(0x2); // 4-bit mode + wait(0.000040f); // most instructions take 40us + + writeCommand(0x28); // Function set 001 BW N F - - + writeCommand(0x0C); + writeCommand(0x6); // Cursor Direction and Display Shift : 0000 01 CD S (CD 0-left, 1-right S(hift) 0-no, 1-yes + cls(); +} + +void TextLCD::character(int column, int row, int c) { + int a = address(column, row); + writeCommand(a); + writeData(c); +} + +void TextLCD::cls() { + writeCommand(0x01); // cls, and set cursor to 0 + wait(0.00164f); // This command takes 1.64 ms + locate(0, 0); +} + +void TextLCD::locate(int column, int row) { + _column = column; + _row = row; +} + +int TextLCD::_putc(int value) { + if (value == '\n') { + _column = 0; + _row++; + if (_row >= rows()) { + _row = 0; + } + } else { + character(_column, _row, value); + _column++; + if (_column >= columns()) { + _column = 0; + _row++; + if (_row >= rows()) { + _row = 0; + } + } + } + return value; +} + +int TextLCD::_getc() { + return -1; +} + +void TextLCD::writeByte(int value) { + _d = value >> 4; + wait(0.000040f); // most instructions take 40us + _e = 0; + wait(0.000040f); + _e = 1; + _d = value >> 0; + wait(0.000040f); + _e = 0; + wait(0.000040f); // most instructions take 40us + _e = 1; +} + +void TextLCD::writeCommand(int command) { + _rs = 0; + writeByte(command); +} + +void TextLCD::writeData(int data) { + _rs = 1; + writeByte(data); +} + +int TextLCD::address(int column, int row) { + switch (_type) { + case LCD20x4: + switch (row) { + case 0: + return 0x80 + column; + case 1: + return 0xc0 + column; + case 2: + return 0x94 + column; + case 3: + return 0xd4 + column; + } + case LCD16x2B: + return 0x80 + (row * 40) + column; + case LCD16x2: + case LCD20x2: + default: + return 0x80 + (row * 0x40) + column; + } +} + +int TextLCD::columns() { + switch (_type) { + case LCD20x4: + case LCD20x2: + return 20; + case LCD16x2: + case LCD16x2B: + default: + return 16; + } +} + +int TextLCD::rows() { + switch (_type) { + case LCD20x4: + return 4; + case LCD16x2: + case LCD16x2B: + case LCD20x2: + default: + return 2; + } +}
diff -r 000000000000 -r 9526e71a200f TextLCD/TextLCD.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TextLCD/TextLCD.h Sun Jan 15 06:13:50 2012 +0000 @@ -0,0 +1,111 @@ +/* mbed TextLCD Library, for a 4-bit LCD based on HD44780 + * Copyright (c) 2007-2010, sford, http://mbed.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MBED_TEXTLCD_H +#define MBED_TEXTLCD_H + +#include "mbed.h" + +/** A TextLCD interface for driving 4-bit HD44780-based LCDs + * + * Currently supports 16x2, 20x2 and 20x4 panels + * + * @code + * #include "mbed.h" + * #include "TextLCD.h" + * + * TextLCD lcd(p10, p12, p15, p16, p29, p30); // rs, e, d4-d7 + * + * int main() { + * lcd.printf("Hello World!\n"); + * } + * @endcode + */ +class TextLCD : public Stream { +public: + + /** LCD panel format */ + enum LCDType { + LCD16x2 /**< 16x2 LCD panel (default) */ + , LCD16x2B /**< 16x2 LCD panel alternate addressing */ + , LCD20x2 /**< 20x2 LCD panel */ + , LCD20x4 /**< 20x4 LCD panel */ + }; + + /** Create a TextLCD interface + * + * @param rs Instruction/data control line + * @param e Enable line (clock) + * @param d4-d7 Data lines for using as a 4-bit interface + * @param type Sets the panel size/addressing mode (default = LCD16x2) + */ + TextLCD(PinName rs, PinName e, PinName d4, PinName d5, PinName d6, PinName d7, LCDType type = LCD16x2); + +#if DOXYGEN_ONLY + /** Write a character to the LCD + * + * @param c The character to write to the display + */ + int putc(int c); + + /** Write a formated string to the LCD + * + * @param format A printf-style format string, followed by the + * variables to use in formating the string. + */ + int printf(const char* format, ...); +#endif + + /** Locate to a screen column and row + * + * @param column The horizontal position from the left, indexed from 0 + * @param row The vertical position from the top, indexed from 0 + */ + void locate(int column, int row); + + /** Clear the screen and locate to 0,0 */ + void cls(); + + int rows(); + int columns(); + +protected: + + // Stream implementation functions + virtual int _putc(int value); + virtual int _getc(); + + int address(int column, int row); + void character(int column, int row, int c); + void writeByte(int value); + void writeCommand(int command); + void writeData(int data); + + DigitalOut _rs, _e; + BusOut _d; + LCDType _type; + + int _column; + int _row; +}; + +#endif
diff -r 000000000000 -r 9526e71a200f main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Jan 15 06:13:50 2012 +0000 @@ -0,0 +1,409 @@ +//----------------------------------------------------------------------- +// reflow oven controller +// +// Version 1.0 - December 2003 +// +// ATOM-Pro basic for Renesas '3687 +// +// Copyright (name deleted) + +// This project is a port from the original basic code for the Basic Micro EVB87 +// Renesas evaluation board to the mbed in C. +// +// We use the same setup as the original project: +// For the thermocouple, a AD595 cnnected to one of the analog input of the mbed. +// For the buttons, 3 push buttons connected to ground and pullups. +// For the heater, any driver configuration. +// +// http://www.circuitcellar.com/renesas/winners/Abstracts/H3323%20abstract.pdf +//----------------------------------------------------------------------- + +#include "mbed.h" +#include "TextLCD.h" + +//TextLCD lcd(p6, p7, p8, p13, p14, p15, p16); // rs, rw, e, d4, d5, d6, d7 +TextLCD lcd(p6, p8, p13, p14, p15, p16); // rs, e, d4, d5, d6, d7 + +// 0 button pressed, 1 button released +DigitalIn IN8(p30); +DigitalIn IN9(p29); +DigitalIn IN10(p28); + +// 0 off, 1 on +DigitalOut HeaterOutput(p27); + +// Use the USB link as serial port +Serial pc(USBTX, USBRX); // tx, rx + +// The 0.0v to 3.3v range of the AnalogIn is represented in software +// as a normalised floating point number from 0.0 to 1.0. +AnalogIn ain(p15); + +// AD595 10mv/'C at 3.3V -> 330'C + +//======================================================================= +// variables +//======================================================================= + +int PreheatSlope; // 1 to 255, 1/10° per sec +int DryingTemp; // 20 to 250, °C +int Hysteresis; // 1 to 20, °C +int DryingTime; // 1 to 255, seconds +int HeatingSlope; // 1 to 255, 1/10° per sec +int ReflowTemp; // 150 to 255, °C +int ReflowTime; // 1 to 255, seconds +int CoolingSlope; // 1 to 255, 1/10° per sec +int Kd; // kd muliplier for pid, in 1/10 + +char status; // state machine status +int t; // current temperature +int tini; // initial temperature +int tset10; // set temperature times 10 +int tset; // set temperature +int remaining_time; // remaining time in s +char heater; // heater on/off +int tprec; // previous temperature +int testim; // estimated future temperature + +// Used to toggle between 2 display screens +char dispcycle; // display cycle (0/1/0/1...) + +int alow; +int ahigh; + +char *lcd_status[] = { + "UpDry ","WtDry ","Drying ","UpFlow ","WtFlow ","Reflow ","Coolng " +}; + +#define PREHEAT 1 +#define WAIT_DRYING 2 +#define DRYING 3 +#define HEAT 4 +#define WAIT_REFLOW 5 +#define REFLOW 6 +#define COOLING 7 + +void heater_off(void) { + HeaterOutput = 0; +} + +void heater_on(void) { + HeaterOutput = 1; +} + +//======================================================================= +// Subroutines +//======================================================================= + +// Initialisation +void Init(void) { + // Welcome screen + lcd.cls(); + lcd.printf(" REFLOW CONTROL "); + lcd.locate(0,1); + lcd.printf(" V1.0 "); + + wait_ms(10); + + // Initialize variables to default values + PreheatSlope = 10; // 1 to 255, 1/10° per sec + DryingTemp = 100; // 20 to 250, °C + Hysteresis = 5; // 1 to 20, °C + DryingTime = 120; // 1 to 255, seconds + HeatingSlope = 40; // 1 to 255, 1/10° per sec + ReflowTemp = 250; // 150 to 255, °C + ReflowTime = 45; // 1 to 255, seconds + CoolingSlope = 20; // 1 to 255, 1/10° per sec + Kd = 10; // 0 to 100, kd multiplier in 1/10 +} + +void editnum(int *value,int minval,int maxval) { + int v; + + v = *value; + + do { + wait_ms(200); + lcd.locate(10,0); + lcd.printf("%d ",v); + lcd.locate(0,1); + lcd.printf("[2+][1-] [0:end]"); + + if (IN9 == 0) { + v--; + if (v < minval) v = minval; + } + + if (IN10 == 0) { + v++; + if (v > maxval) v = maxval; + } + + } while (IN8 != 0); + + *value = v; +} + +void UpdateStateMachine(void) { + if (status == 0) return; + + switch (status - 1) { + case PREHEAT: + tset10 = tset10 + PreheatSlope; + tset = tset10/10; + + if (tset > DryingTemp) { + tset10 = DryingTemp * 10; + status = WAIT_DRYING; + dispcycle = 1; + } + break; + + case WAIT_DRYING: + if ((t + Hysteresis) > DryingTemp) { + remaining_time = DryingTime; + status = DRYING; + dispcycle = 1; + } + break; + + case DRYING: + if (remaining_time == 0) { + remaining_time = (10 * (ReflowTemp - DryingTemp))/HeatingSlope; + status = HEAT; + dispcycle = 1; + } + break; + + case HEAT: + tset10 = tset10 + HeatingSlope; + tset = tset10/10; + if (tset > ReflowTemp) { + tset10 = 10 * ReflowTemp; + status = WAIT_REFLOW; + dispcycle = 1; + } + break; + + case WAIT_REFLOW: + if ((t + Hysteresis) > ReflowTemp) { + remaining_time = ReflowTime; + status = REFLOW; + dispcycle = 1; + } + break; + + case REFLOW: + if (remaining_time == 0) { + remaining_time = (10 * (ReflowTemp - tini))/CoolingSlope; + status = COOLING; + dispcycle = 1; + } + break; + + case COOLING: + tset10 = tset10 - CoolingSlope; + tset = tset10/10; + if (tset < tini) { + tset10 = 10 * tini; + status = 0; + dispcycle = 1; + } + break; + + default: + status = 0; + } +} + +// Read current temperature +// return temperature in ahigh (degrees) and alow (tens of a degree) +void readtemperature(void) { + long int atemp; + long int a; // temporary + int i; + + a = 0; + + /* 1000 readings */ + for (i=1; i <= 1000; i++) { + atemp = ain * 330; // 3.3V from an AD595 at 10mV/'C -> 330'C + a += atemp; + } + /* a = 1000 * avg temp */ + // ex: 300.2 a = 300200 + + a = a/100; // a = 3002 + + /* ahigh = */ + ahigh = a/10; // ahigh = 300 + alow = a - ahigh*10; // alow = 3002 - 3000 = 2 +} + +void RunMode() { + // initialise run mode + status = 1; + dispcycle = 0; + t = 0; + readtemperature(); + + t = ahigh; + tini = t; + tset10 = 10*t; + remaining_time = (10*(DryingTemp - t))/PreheatSlope; + heater = 0; + + // wait for run button released + while (IN8 == 0); + wait_ms(10); + + do { + tprec = t; + + // read new temperature + readtemperature(); + t = ahigh; + + // estimate future temperature using kd + testim = ((10*t) + (t-tprec) * Kd)/10; + + tset = tset10/10; + + // display screen + lcd.cls(); + lcd.printf("Temp:%dC ", ahigh); + lcd.locate(10,0); + + if (dispcycle == 1) { + lcd.printf("%d/7",status); + } else { + lcd.puts(lcd_status[status-1]); + } + + lcd.locate(0,1); + lcd.printf("Tset:%dC ", tset); + lcd.locate(10,1); + lcd.printf("sec %d", remaining_time); + + // decrement time (in seconds, due to the 1 second pause) + if (remaining_time != 0) remaining_time--; + + // check if abort requested + if (IN8 == 0) { + status = 0; + heater_off(); + + // wait for run button released + while (IN8 == 0); + wait_ms(10); + } + + UpdateStateMachine(); + + tset = tset10/10; + + // control heater + if (heater == 0) { + if (testim < (tset - Hysteresis)) heater = 1; + } + + if (heater == 1) { + if (testim > (tset + Hysteresis)) heater = 0; + } + + if (heater == 0) + heater_off(); + else + heater_on(); + + // send current values to uart + pc.printf("S%d,%d,%d,%d\n",tset, t, status, heater); + + // wait for 1 second + wait(1); + + // next dispcycle + dispcycle = 1 - dispcycle; + } while (status != 0); +} + +void ConfigurationMode(void) { + int i; + + for (i = 1; i <= 9; i++) { + lcd.cls(); + lcd.locate(0,0); + + switch (i) { + case 1: + lcd.printf("DrySlope"); + editnum(&PreheatSlope,1,255); + break; + case 2: + lcd.printf("DryTemp "); + editnum(&DryingTemp,40,150); + break; + case 3: + lcd.printf("Hysteres"); + editnum(&Hysteresis,1,40); + break; + case 4: + lcd.printf("DryTime "); + editnum(&DryingTime,1,255); + break; + case 5: + lcd.printf("HeatSlpe"); + editnum(&HeatingSlope,1,255); + break; + case 6: + lcd.printf("FlowTemp"); + editnum(&ReflowTemp,120,255); + break; + case 7: + lcd.printf("Flowtime"); + editnum(&ReflowTime,1,255); + break; + case 8: + lcd.printf("Coolslop"); + editnum(&CoolingSlope,1,255); + break; + case 9: + lcd.printf("Kd "); + editnum(&Kd,0,200); + break; + } + } +} + +//======================================================================= +// Main program +//======================================================================= + +int main(void) { + // Initialisations + Init(); + + lcd.cls(); + + // Main loop + while (1) { + // heater off + heater_off(); + + // Display current temperature + lcd.locate(0,0); + readtemperature(); + lcd.printf("Temp : %d.%dC ", ahigh, alow); + lcd.locate(0,1); + + // Display menu + lcd.printf("[1:CONF] [0:RUN]"); + + wait_ms(10); + + // Run button ? + if (IN8 == 0) + RunMode(); + else if (IN9 == 0) ConfigurationMode(); + } +}
diff -r 000000000000 -r 9526e71a200f mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sun Jan 15 06:13:50 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/5364839841bd