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.
Dependencies: Menu PID_v2 PinDetect QEI TextLCD Thermistor mbed
main.cpp@1:219e882c32eb, 2015-11-27 (annotated)
- Committer:
- albertobianco
- Date:
- Fri Nov 27 10:50:06 2015 +0000
- Revision:
- 1:219e882c32eb
- Parent:
- 0:b6fd8ca8bfbf
- Child:
- 3:884bfa90a09d
Ciau, neh!
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| walter76 | 0:b6fd8ca8bfbf | 1 | #include "mbed.h" |
| walter76 | 0:b6fd8ca8bfbf | 2 | #include "TextLCD.h" |
| walter76 | 0:b6fd8ca8bfbf | 3 | #include "PID.h" |
| walter76 | 0:b6fd8ca8bfbf | 4 | #include "QEI.h" |
| albertobianco | 1:219e882c32eb | 5 | #include "Menu.h" |
| albertobianco | 1:219e882c32eb | 6 | #include "PinDetect.h" |
| albertobianco | 1:219e882c32eb | 7 | #include "Thermistor.h" |
| walter76 | 0:b6fd8ca8bfbf | 8 | |
| albertobianco | 1:219e882c32eb | 9 | #define TPIT_MIN 0.0 |
| albertobianco | 1:219e882c32eb | 10 | #define TPIT_MAX 250.0 |
| albertobianco | 1:219e882c32eb | 11 | #define TCOAL_MIN 0.0 |
| albertobianco | 1:219e882c32eb | 12 | #define TCOAL_MAX 1000.0 |
| walter76 | 0:b6fd8ca8bfbf | 13 | #define TMEAT_MIN 50 |
| walter76 | 0:b6fd8ca8bfbf | 14 | #define TMEAT_MAX 120 |
| walter76 | 0:b6fd8ca8bfbf | 15 | #define MAX_HOURS 24 |
| albertobianco | 1:219e882c32eb | 16 | |
| albertobianco | 1:219e882c32eb | 17 | #define PULLUP_MEAT 10000.0 |
| albertobianco | 1:219e882c32eb | 18 | |
| walter76 | 0:b6fd8ca8bfbf | 19 | /* |
| walter76 | 0:b6fd8ca8bfbf | 20 | |
| walter76 | 0:b6fd8ca8bfbf | 21 | This FW implements a PID temperature controller specifically designed for Ugly Drum Smokers (UDS) |
| walter76 | 0:b6fd8ca8bfbf | 22 | and uses a K-type termocouple as pit temperature sensors and a PWM-controlled fan to regulate the |
| walter76 | 0:b6fd8ca8bfbf | 23 | airflow at the intake. |
| walter76 | 0:b6fd8ca8bfbf | 24 | A second K-type termocouple is used to monitor the meat temperature, while a countdown timer takes care |
| walter76 | 0:b6fd8ca8bfbf | 25 | of the cooking time. |
| walter76 | 0:b6fd8ca8bfbf | 26 | The required HW consists of: |
| walter76 | 0:b6fd8ca8bfbf | 27 | - 1x STM32 F411RE Nucleo board |
| walter76 | 0:b6fd8ca8bfbf | 28 | - 1x 20x4 Text LCD |
| walter76 | 0:b6fd8ca8bfbf | 29 | - 1x Quadrature rotary encoder |
| walter76 | 0:b6fd8ca8bfbf | 30 | - 1x Pushbutton (if not embedded in the encoder) |
| walter76 | 0:b6fd8ca8bfbf | 31 | - 2x MAX6675 modules |
| walter76 | 0:b6fd8ca8bfbf | 32 | - 2x K-type termocouples (pit & meat) |
| walter76 | 0:b6fd8ca8bfbf | 33 | - 1x Buzzer |
| walter76 | 0:b6fd8ca8bfbf | 34 | - 1x 12V fan |
| walter76 | 0:b6fd8ca8bfbf | 35 | - 1x N-MOS capable of driving the fan |
| walter76 | 0:b6fd8ca8bfbf | 36 | - 1x fly-wheeling diode |
| walter76 | 0:b6fd8ca8bfbf | 37 | |
| walter76 | 0:b6fd8ca8bfbf | 38 | */ |
| walter76 | 0:b6fd8ca8bfbf | 39 | |
| albertobianco | 1:219e882c32eb | 40 | int Hrs=0, Min=0, Sec=0, warning=0, timeout=0; |
| albertobianco | 1:219e882c32eb | 41 | int TimerRunning = 0; |
| albertobianco | 1:219e882c32eb | 42 | float FanSpeed, TcoalPID, Tcoal, Tpit, Tmeat, Tset; |
| albertobianco | 1:219e882c32eb | 43 | float Talm = 200.0; |
| albertobianco | 1:219e882c32eb | 44 | float TcoalSet, DfanSet; |
| walter76 | 0:b6fd8ca8bfbf | 45 | float Vpot; |
| albertobianco | 1:219e882c32eb | 46 | uint8_t req_LCD_update; |
| albertobianco | 1:219e882c32eb | 47 | |
| albertobianco | 1:219e882c32eb | 48 | uint8_t displayLine; |
| albertobianco | 1:219e882c32eb | 49 | |
| albertobianco | 1:219e882c32eb | 50 | int pitPidMode = 0; |
| albertobianco | 1:219e882c32eb | 51 | int coalPidMode = 0; |
| albertobianco | 1:219e882c32eb | 52 | |
| albertobianco | 1:219e882c32eb | 53 | char stringa[20]; |
| albertobianco | 1:219e882c32eb | 54 | |
| albertobianco | 1:219e882c32eb | 55 | void UpdatePidMode(void); |
| albertobianco | 1:219e882c32eb | 56 | void SetCoalTemp(void); |
| albertobianco | 1:219e882c32eb | 57 | void SetFanDuty(void); |
| albertobianco | 1:219e882c32eb | 58 | void SetPIDK(void); |
| albertobianco | 1:219e882c32eb | 59 | void ResetSeconds(void); |
| albertobianco | 1:219e882c32eb | 60 | |
| albertobianco | 1:219e882c32eb | 61 | float coalKc = 0.1, coalTauI = 6.0; |
| albertobianco | 1:219e882c32eb | 62 | float pitKc = 0.1, pitTauI = 60.0; |
| albertobianco | 1:219e882c32eb | 63 | |
| albertobianco | 1:219e882c32eb | 64 | MenuNode MNhead(NULL,"Exit"); |
| albertobianco | 1:219e882c32eb | 65 | MenuNode MNpid(&MNhead,"PID settings"); |
| albertobianco | 1:219e882c32eb | 66 | //MenuNode MNpitap(&MNpid,"Pit Auto PID"); |
| albertobianco | 1:219e882c32eb | 67 | MenuNode MNpitPidTarget(&MNhead,"Pit Target temp",(void *) &Tset,'f',NULL,1.0,TPIT_MIN,TPIT_MAX); |
| walter76 | 0:b6fd8ca8bfbf | 68 | |
| albertobianco | 1:219e882c32eb | 69 | MenuNode MNpitPidMode(&MNpid,"Pit PID mode",(void *) &pitPidMode,'i',&UpdatePidMode,1.0,0.0,1.0,(char *[]){"Manual","Auto"}); |
| albertobianco | 1:219e882c32eb | 70 | MenuNode MNcoalPidMode(&MNpid,"Coal PID mode",(void *) &coalPidMode,'i',&UpdatePidMode,1.0,0.0,1.0,(char *[]){"Manual","Auto"}); |
| albertobianco | 1:219e882c32eb | 71 | |
| albertobianco | 1:219e882c32eb | 72 | MenuNode MNpitPidOutput(&MNpid,"Coal Temp (man)",(void *) &TcoalSet,'f',&SetCoalTemp,5.0,TCOAL_MIN,TCOAL_MAX); |
| albertobianco | 1:219e882c32eb | 73 | MenuNode MNcoalPidOutput(&MNpid,"Fan Speed (man)",(void *) &DfanSet,'f',&SetFanDuty,0.05,0.0,1.0); |
| albertobianco | 1:219e882c32eb | 74 | MenuNode MNcoalKc(&MNpid,"Coal Kc",(void *) &coalKc,'e',&SetPIDK,1.25,0.0001,100.0); |
| albertobianco | 1:219e882c32eb | 75 | MenuNode MNcoalTauI(&MNpid,"Coal TauI",(void *) &coalTauI,'e',&SetPIDK,1.25,1.0,1000.0); |
| albertobianco | 1:219e882c32eb | 76 | MenuNode MNpitKc(&MNpid,"Pit Kc",(void *) &pitKc,'e',&SetPIDK,1.25,0.0001,100.0); |
| albertobianco | 1:219e882c32eb | 77 | MenuNode MNpitTauI(&MNpid,"Pit TauI",(void *) &pitTauI,'e',&SetPIDK,1.25,1.0,10000.0); |
| albertobianco | 1:219e882c32eb | 78 | |
| albertobianco | 1:219e882c32eb | 79 | MenuNode MNtmr(&MNhead,"Timer settings"); |
| albertobianco | 1:219e882c32eb | 80 | MenuNode MNtmrRun(&MNtmr,"Timer mode",(void *) &TimerRunning,'i',NULL,1.0,0.0,2.0,(char *[]){"Stop","Countdown", "Timer"}); |
| albertobianco | 1:219e882c32eb | 81 | MenuNode MNtmrHrs(&MNtmr,"Hours",(void *) &Hrs,'i',&ResetSeconds,1.0,0.0,24.0); |
| albertobianco | 1:219e882c32eb | 82 | MenuNode MNtmrMin(&MNtmr,"Minutes",(void *) &Min,'i',&ResetSeconds,5.0,0.0,55.0); |
| walter76 | 0:b6fd8ca8bfbf | 83 | |
| albertobianco | 1:219e882c32eb | 84 | MenuNode MNtalm(&MNhead,"Meat Target temperature", &Talm,'f', NULL, 1.0, 30.0, 150.0); |
| albertobianco | 1:219e882c32eb | 85 | |
| albertobianco | 1:219e882c32eb | 86 | Menu MN(&MNhead); |
| albertobianco | 1:219e882c32eb | 87 | |
| albertobianco | 1:219e882c32eb | 88 | Thermistor MeatThermistor(25.0, 100000.0, 3950.0); |
| albertobianco | 1:219e882c32eb | 89 | |
| walter76 | 0:b6fd8ca8bfbf | 90 | |
| albertobianco | 1:219e882c32eb | 91 | //DigitalOut RLED (PC_5); // Pin 2 of CN10 (MORPHO connector, debug only) |
| albertobianco | 1:219e882c32eb | 92 | //DigitalOut YLED (PC_6); // Pin 4 of CN10 (MORPHO connector, debug only) |
| albertobianco | 1:219e882c32eb | 93 | //DigitalOut GLED (PC_8); // Pin 6 of CN10 (MORPHO connector, debug only) |
| albertobianco | 1:219e882c32eb | 94 | |
| albertobianco | 1:219e882c32eb | 95 | PwmOut FAN (D5); // D3=PB3 --> PMW output (FAN control) |
| albertobianco | 1:219e882c32eb | 96 | |
| albertobianco | 1:219e882c32eb | 97 | DigitalOut TC_CLK (D4); // D4=PB5 --> MAX6675 CLK (to both chips) |
| albertobianco | 1:219e882c32eb | 98 | |
| walter76 | 0:b6fd8ca8bfbf | 99 | DigitalOut TC_CS1 (A5); // A0=PC0 --> MAX6675 CS (chip 1) |
| walter76 | 0:b6fd8ca8bfbf | 100 | DigitalOut TC_CS2 (D2); // D2=PA10 --> MAX6675 CS (chip 2) |
| albertobianco | 1:219e882c32eb | 101 | DigitalIn TC_SDO (D8); // D8=PA9 <-- MAX6675 SDO (from both chips) |
| walter76 | 0:b6fd8ca8bfbf | 102 | |
| albertobianco | 1:219e882c32eb | 103 | //DigitalOut BUZZER (A2); // A2=PA4 --> self-oscillating buzzer |
| walter76 | 0:b6fd8ca8bfbf | 104 | PwmOut ALM (D9); |
| albertobianco | 1:219e882c32eb | 105 | |
| albertobianco | 1:219e882c32eb | 106 | PinDetect Button (D7); // D7=PA8 <-- Hold/Set pushbutton |
| albertobianco | 1:219e882c32eb | 107 | |
| albertobianco | 1:219e882c32eb | 108 | AnalogIn MeatIn (A0); |
| walter76 | 0:b6fd8ca8bfbf | 109 | |
| albertobianco | 1:219e882c32eb | 110 | PID pitPID(0.1, 60.0, 0.0, 1.0); // Specify Kc, Ti, Td & refresh rate |
| albertobianco | 1:219e882c32eb | 111 | PID coalPID(0.1, 6.0, 0.0, 1.0); // Specify Kc, Ti, Td & refresh rate |
| albertobianco | 1:219e882c32eb | 112 | QEI Wheel(D3, D6, NC, 16, QEI::X4_ENCODING); // quadrature encoder |
| albertobianco | 1:219e882c32eb | 113 | TextLCD MyLCD(D15, D14, D13, D12, D11, D10, TextLCD::LCD16x2); //20x4 LCD connection |
| walter76 | 0:b6fd8ca8bfbf | 114 | |
| walter76 | 0:b6fd8ca8bfbf | 115 | Ticker Sec_Beat; // timer ticker |
| albertobianco | 1:219e882c32eb | 116 | //Ticker decSecBeat; // 1/10th sec beat |
| walter76 | 0:b6fd8ca8bfbf | 117 | |
| walter76 | 0:b6fd8ca8bfbf | 118 | |
| walter76 | 0:b6fd8ca8bfbf | 119 | // ------------------- Prototypes ----------------------- |
| walter76 | 0:b6fd8ca8bfbf | 120 | |
| walter76 | 0:b6fd8ca8bfbf | 121 | void Button_Pressed(void); |
| walter76 | 0:b6fd8ca8bfbf | 122 | void Timer_tick(void); |
| walter76 | 0:b6fd8ca8bfbf | 123 | void Update_LCD(void); |
| walter76 | 0:b6fd8ca8bfbf | 124 | int MAX6675_GetTemp(int); |
| walter76 | 0:b6fd8ca8bfbf | 125 | |
| albertobianco | 1:219e882c32eb | 126 | void ResetSeconds(void) |
| albertobianco | 1:219e882c32eb | 127 | { |
| albertobianco | 1:219e882c32eb | 128 | Sec = 0; |
| albertobianco | 1:219e882c32eb | 129 | } |
| walter76 | 0:b6fd8ca8bfbf | 130 | |
| walter76 | 0:b6fd8ca8bfbf | 131 | // -------------------- Routines ------------------------ |
| albertobianco | 1:219e882c32eb | 132 | void SetPIDK(void) |
| albertobianco | 1:219e882c32eb | 133 | { |
| albertobianco | 1:219e882c32eb | 134 | pitPID.setTunings(pitKc, pitTauI, 0.0); |
| albertobianco | 1:219e882c32eb | 135 | coalPID.setTunings(coalKc, coalTauI, 0.0); |
| albertobianco | 1:219e882c32eb | 136 | } |
| walter76 | 0:b6fd8ca8bfbf | 137 | |
| albertobianco | 1:219e882c32eb | 138 | void SetCoalTemp(void) |
| albertobianco | 1:219e882c32eb | 139 | { |
| albertobianco | 1:219e882c32eb | 140 | if(!pitPID.isAuto()) |
| albertobianco | 1:219e882c32eb | 141 | pitPID.setOutput(TcoalSet); |
| albertobianco | 1:219e882c32eb | 142 | } |
| albertobianco | 1:219e882c32eb | 143 | |
| albertobianco | 1:219e882c32eb | 144 | void SetFanDuty(void) |
| albertobianco | 1:219e882c32eb | 145 | { |
| albertobianco | 1:219e882c32eb | 146 | if(!coalPID.isAuto()) |
| albertobianco | 1:219e882c32eb | 147 | coalPID.setOutput(DfanSet); |
| walter76 | 0:b6fd8ca8bfbf | 148 | } |
| walter76 | 0:b6fd8ca8bfbf | 149 | |
| walter76 | 0:b6fd8ca8bfbf | 150 | |
| walter76 | 0:b6fd8ca8bfbf | 151 | |
| albertobianco | 1:219e882c32eb | 152 | void Button_Pressed() |
| walter76 | 0:b6fd8ca8bfbf | 153 | { |
| albertobianco | 1:219e882c32eb | 154 | |
| albertobianco | 1:219e882c32eb | 155 | if(!MN.isLeaf()) |
| albertobianco | 1:219e882c32eb | 156 | MN.descend(); |
| albertobianco | 1:219e882c32eb | 157 | else |
| albertobianco | 1:219e882c32eb | 158 | { |
| albertobianco | 1:219e882c32eb | 159 | if(MN.isSelect()) |
| albertobianco | 1:219e882c32eb | 160 | MN.setEdit(); |
| albertobianco | 1:219e882c32eb | 161 | else if(MN.isEdit()) |
| albertobianco | 1:219e882c32eb | 162 | { |
| albertobianco | 1:219e882c32eb | 163 | MN.resetEdit(); |
| albertobianco | 1:219e882c32eb | 164 | MN.execFun(); |
| albertobianco | 1:219e882c32eb | 165 | } |
| walter76 | 0:b6fd8ca8bfbf | 166 | } |
| albertobianco | 1:219e882c32eb | 167 | |
| albertobianco | 1:219e882c32eb | 168 | req_LCD_update = 1; |
| albertobianco | 1:219e882c32eb | 169 | Wheel.reset(); |
| walter76 | 0:b6fd8ca8bfbf | 170 | |
| albertobianco | 1:219e882c32eb | 171 | } |
| albertobianco | 1:219e882c32eb | 172 | |
| albertobianco | 1:219e882c32eb | 173 | |
| albertobianco | 1:219e882c32eb | 174 | void UpdatePidMode(void) |
| albertobianco | 1:219e882c32eb | 175 | { |
| albertobianco | 1:219e882c32eb | 176 | coalPID.setMode(coalPidMode); |
| albertobianco | 1:219e882c32eb | 177 | pitPID.setMode(pitPidMode); |
| walter76 | 0:b6fd8ca8bfbf | 178 | } |
| walter76 | 0:b6fd8ca8bfbf | 179 | |
| walter76 | 0:b6fd8ca8bfbf | 180 | // ------------------------------------------------------------- |
| walter76 | 0:b6fd8ca8bfbf | 181 | |
| albertobianco | 1:219e882c32eb | 182 | void Timer_tick() |
| albertobianco | 1:219e882c32eb | 183 | { |
| albertobianco | 1:219e882c32eb | 184 | float Rmeat; |
| walter76 | 0:b6fd8ca8bfbf | 185 | |
| albertobianco | 1:219e882c32eb | 186 | if((Hrs==0)&&(Min==0)&&(Sec==0) && (TimerRunning == 1)) |
| albertobianco | 1:219e882c32eb | 187 | timeout = 1; |
| albertobianco | 1:219e882c32eb | 188 | else |
| albertobianco | 1:219e882c32eb | 189 | { |
| albertobianco | 1:219e882c32eb | 190 | timeout = 0; |
| walter76 | 0:b6fd8ca8bfbf | 191 | |
| albertobianco | 1:219e882c32eb | 192 | if (TimerRunning == 1) |
| albertobianco | 1:219e882c32eb | 193 | { |
| albertobianco | 1:219e882c32eb | 194 | Sec--; |
| albertobianco | 1:219e882c32eb | 195 | if((Hrs==0)&&(Min==0)&&(Sec==0)) |
| albertobianco | 1:219e882c32eb | 196 | timeout = 1; |
| albertobianco | 1:219e882c32eb | 197 | else if((Sec<=0)||(Sec>60)) |
| albertobianco | 1:219e882c32eb | 198 | { |
| albertobianco | 1:219e882c32eb | 199 | Sec=59; |
| albertobianco | 1:219e882c32eb | 200 | if(Min>0) |
| albertobianco | 1:219e882c32eb | 201 | Min--; |
| albertobianco | 1:219e882c32eb | 202 | else if (Hrs>0) |
| albertobianco | 1:219e882c32eb | 203 | { |
| albertobianco | 1:219e882c32eb | 204 | Min=59; |
| albertobianco | 1:219e882c32eb | 205 | Hrs--; |
| albertobianco | 1:219e882c32eb | 206 | } |
| albertobianco | 1:219e882c32eb | 207 | } |
| albertobianco | 1:219e882c32eb | 208 | } |
| albertobianco | 1:219e882c32eb | 209 | else if ((TimerRunning == 2) ) |
| albertobianco | 1:219e882c32eb | 210 | { |
| albertobianco | 1:219e882c32eb | 211 | Sec++; |
| albertobianco | 1:219e882c32eb | 212 | if((Sec>=60)) |
| albertobianco | 1:219e882c32eb | 213 | { |
| albertobianco | 1:219e882c32eb | 214 | Sec=0; |
| albertobianco | 1:219e882c32eb | 215 | Min++; |
| albertobianco | 1:219e882c32eb | 216 | if(Min>=60) |
| albertobianco | 1:219e882c32eb | 217 | { |
| albertobianco | 1:219e882c32eb | 218 | Min = 0; |
| albertobianco | 1:219e882c32eb | 219 | Hrs++; |
| albertobianco | 1:219e882c32eb | 220 | } |
| albertobianco | 1:219e882c32eb | 221 | } |
| albertobianco | 1:219e882c32eb | 222 | } |
| walter76 | 0:b6fd8ca8bfbf | 223 | } |
| albertobianco | 1:219e882c32eb | 224 | |
| albertobianco | 1:219e882c32eb | 225 | Tcoal = (float)(MAX6675_GetTemp(0)/2); // read meat & pit temperature |
| albertobianco | 1:219e882c32eb | 226 | Tpit = (float)(MAX6675_GetTemp(1)/2); |
| albertobianco | 1:219e882c32eb | 227 | |
| albertobianco | 1:219e882c32eb | 228 | pitPID.setProcessValue(Tpit); |
| albertobianco | 1:219e882c32eb | 229 | TcoalPID = pitPID.compute(); |
| albertobianco | 1:219e882c32eb | 230 | coalPID.setSetPoint( TcoalPID ); |
| albertobianco | 1:219e882c32eb | 231 | |
| albertobianco | 1:219e882c32eb | 232 | coalPID.setProcessValue(Tcoal); |
| albertobianco | 1:219e882c32eb | 233 | FanSpeed = coalPID.compute(); |
| albertobianco | 1:219e882c32eb | 234 | |
| albertobianco | 1:219e882c32eb | 235 | FAN.write(FanSpeed); |
| albertobianco | 1:219e882c32eb | 236 | |
| albertobianco | 1:219e882c32eb | 237 | if(MN.isHead()) |
| albertobianco | 1:219e882c32eb | 238 | req_LCD_update = 1; |
| albertobianco | 1:219e882c32eb | 239 | |
| albertobianco | 1:219e882c32eb | 240 | |
| albertobianco | 1:219e882c32eb | 241 | Rmeat = MeatIn.read(); |
| albertobianco | 1:219e882c32eb | 242 | Rmeat = (Rmeat * PULLUP_MEAT) / (1 - Rmeat); |
| albertobianco | 1:219e882c32eb | 243 | |
| albertobianco | 1:219e882c32eb | 244 | Tmeat = MeatThermistor.trans_R2T(Rmeat); |
| albertobianco | 1:219e882c32eb | 245 | |
| albertobianco | 1:219e882c32eb | 246 | |
| albertobianco | 1:219e882c32eb | 247 | if(Tmeat>Talm || timeout) // Meat is ready! |
| albertobianco | 1:219e882c32eb | 248 | warning = 1; |
| albertobianco | 1:219e882c32eb | 249 | else |
| albertobianco | 1:219e882c32eb | 250 | warning = 0; |
| albertobianco | 1:219e882c32eb | 251 | |
| albertobianco | 1:219e882c32eb | 252 | |
| albertobianco | 1:219e882c32eb | 253 | return; |
| walter76 | 0:b6fd8ca8bfbf | 254 | } |
| walter76 | 0:b6fd8ca8bfbf | 255 | |
| walter76 | 0:b6fd8ca8bfbf | 256 | |
| walter76 | 0:b6fd8ca8bfbf | 257 | // ------------------------------------------------------------- |
| albertobianco | 1:219e882c32eb | 258 | int saturate(int data, int min, int max) |
| albertobianco | 1:219e882c32eb | 259 | { |
| albertobianco | 1:219e882c32eb | 260 | if(data > max) |
| albertobianco | 1:219e882c32eb | 261 | return max; |
| albertobianco | 1:219e882c32eb | 262 | else if (data < min) |
| albertobianco | 1:219e882c32eb | 263 | return min; |
| albertobianco | 1:219e882c32eb | 264 | else return data; |
| albertobianco | 1:219e882c32eb | 265 | } |
| walter76 | 0:b6fd8ca8bfbf | 266 | |
| albertobianco | 1:219e882c32eb | 267 | |
| albertobianco | 1:219e882c32eb | 268 | char * idleString(int n, char *dst) |
| albertobianco | 1:219e882c32eb | 269 | { |
| albertobianco | 1:219e882c32eb | 270 | int tcoal_l, tpit_l, tmeat_l; |
| albertobianco | 1:219e882c32eb | 271 | |
| albertobianco | 1:219e882c32eb | 272 | switch(n) |
| albertobianco | 1:219e882c32eb | 273 | { |
| albertobianco | 1:219e882c32eb | 274 | |
| albertobianco | 1:219e882c32eb | 275 | case 0: |
| albertobianco | 1:219e882c32eb | 276 | sprintf(dst,"%02d:%02d:%02d Tgt %02dC",Hrs,Min,Sec,int(Talm)); |
| albertobianco | 1:219e882c32eb | 277 | break; |
| albertobianco | 1:219e882c32eb | 278 | case 1: |
| albertobianco | 1:219e882c32eb | 279 | tcoal_l = saturate(int(Tcoal),0,999); |
| albertobianco | 1:219e882c32eb | 280 | tpit_l = saturate(int(Tpit),0,999); |
| albertobianco | 1:219e882c32eb | 281 | tmeat_l = saturate(int(Tmeat),0,999); |
| albertobianco | 1:219e882c32eb | 282 | sprintf(dst,"C%3dC P%3dC M%2dC",tcoal_l,tpit_l,tmeat_l); |
| albertobianco | 1:219e882c32eb | 283 | break; |
| albertobianco | 1:219e882c32eb | 284 | case 2: |
| albertobianco | 1:219e882c32eb | 285 | sprintf(dst,"d%3d CP%4dC ",int(FanSpeed * 100), int(TcoalPID)); |
| albertobianco | 1:219e882c32eb | 286 | break; |
| albertobianco | 1:219e882c32eb | 287 | case 3: |
| albertobianco | 1:219e882c32eb | 288 | sprintf(dst,"Ciao Mamma"); |
| albertobianco | 1:219e882c32eb | 289 | break; |
| albertobianco | 1:219e882c32eb | 290 | } |
| albertobianco | 1:219e882c32eb | 291 | |
| albertobianco | 1:219e882c32eb | 292 | return dst; |
| albertobianco | 1:219e882c32eb | 293 | } |
| albertobianco | 1:219e882c32eb | 294 | |
| albertobianco | 1:219e882c32eb | 295 | |
| albertobianco | 1:219e882c32eb | 296 | void Update_LCD(void) |
| albertobianco | 1:219e882c32eb | 297 | { |
| albertobianco | 1:219e882c32eb | 298 | |
| albertobianco | 1:219e882c32eb | 299 | |
| albertobianco | 1:219e882c32eb | 300 | if(MN.isHead()) |
| albertobianco | 1:219e882c32eb | 301 | { |
| albertobianco | 1:219e882c32eb | 302 | |
| albertobianco | 1:219e882c32eb | 303 | MyLCD.locate(0,0); |
| albertobianco | 1:219e882c32eb | 304 | MyLCD.printf(idleString(displayLine,stringa)); |
| albertobianco | 1:219e882c32eb | 305 | MyLCD.locate(0,1); |
| albertobianco | 1:219e882c32eb | 306 | MyLCD.printf(idleString((displayLine+1)&0x03,stringa)); |
| albertobianco | 1:219e882c32eb | 307 | |
| albertobianco | 1:219e882c32eb | 308 | } |
| albertobianco | 1:219e882c32eb | 309 | else |
| albertobianco | 1:219e882c32eb | 310 | { |
| albertobianco | 1:219e882c32eb | 311 | MyLCD.locate(0,0); |
| albertobianco | 1:219e882c32eb | 312 | MyLCD.printf("%-16s",MN.getText()); |
| albertobianco | 1:219e882c32eb | 313 | if(MN.isSelect()) |
| albertobianco | 1:219e882c32eb | 314 | { |
| albertobianco | 1:219e882c32eb | 315 | MyLCD.locate(0,1); |
| albertobianco | 1:219e882c32eb | 316 | MyLCD.printf("%-16s",MN.getNextText()); |
| albertobianco | 1:219e882c32eb | 317 | } |
| albertobianco | 1:219e882c32eb | 318 | else |
| albertobianco | 1:219e882c32eb | 319 | { |
| albertobianco | 1:219e882c32eb | 320 | MyLCD.locate(0,1); |
| albertobianco | 1:219e882c32eb | 321 | MyLCD.printf("%-16s",MN.getDataText(stringa)); |
| albertobianco | 1:219e882c32eb | 322 | } |
| albertobianco | 1:219e882c32eb | 323 | } |
| albertobianco | 1:219e882c32eb | 324 | |
| albertobianco | 1:219e882c32eb | 325 | |
| albertobianco | 1:219e882c32eb | 326 | //Button.fall(&Button_Pressed); |
| albertobianco | 1:219e882c32eb | 327 | |
| albertobianco | 1:219e882c32eb | 328 | #if 0 |
| albertobianco | 1:219e882c32eb | 329 | |
| albertobianco | 1:219e882c32eb | 330 | |
| albertobianco | 1:219e882c32eb | 331 | if(warning||timeout) // in case of a warning or timeout |
| albertobianco | 1:219e882c32eb | 332 | { |
| albertobianco | 1:219e882c32eb | 333 | MyLCD.locate(0,3); |
| albertobianco | 1:219e882c32eb | 334 | MyLCD.printf(" ---- WARNING! ---- "); |
| albertobianco | 1:219e882c32eb | 335 | |
| albertobianco | 1:219e882c32eb | 336 | //FAN.write(0); // stop the fan (optional) |
| albertobianco | 1:219e882c32eb | 337 | } else // otherwise |
| albertobianco | 1:219e882c32eb | 338 | { |
| albertobianco | 1:219e882c32eb | 339 | BUZZER = 0; // buzzer off |
| albertobianco | 1:219e882c32eb | 340 | } |
| albertobianco | 1:219e882c32eb | 341 | |
| albertobianco | 1:219e882c32eb | 342 | #endif |
| albertobianco | 1:219e882c32eb | 343 | } |
| albertobianco | 1:219e882c32eb | 344 | |
| albertobianco | 1:219e882c32eb | 345 | // ------------------------------------------------------------- |
| walter76 | 0:b6fd8ca8bfbf | 346 | int MAX6675_GetTemp(int chip) |
| walter76 | 0:b6fd8ca8bfbf | 347 | { |
| albertobianco | 1:219e882c32eb | 348 | int Temp=0, mask=32768; |
| albertobianco | 1:219e882c32eb | 349 | int i; |
| albertobianco | 1:219e882c32eb | 350 | |
| albertobianco | 1:219e882c32eb | 351 | if(chip==0) |
| albertobianco | 1:219e882c32eb | 352 | TC_CS1 = 0; // select chip #1 |
| albertobianco | 1:219e882c32eb | 353 | else |
| albertobianco | 1:219e882c32eb | 354 | TC_CS2 = 0; // select chip #2 |
| albertobianco | 1:219e882c32eb | 355 | wait_ms(1); |
| albertobianco | 1:219e882c32eb | 356 | for(i=0; i<16; i++) { |
| walter76 | 0:b6fd8ca8bfbf | 357 | |
| albertobianco | 1:219e882c32eb | 358 | TC_CLK = 1; // CLK high |
| albertobianco | 1:219e882c32eb | 359 | if(TC_SDO == 1 ) Temp = Temp | mask; |
| albertobianco | 1:219e882c32eb | 360 | wait_ms(1); |
| albertobianco | 1:219e882c32eb | 361 | TC_CLK = 0; // CLK low |
| albertobianco | 1:219e882c32eb | 362 | wait_ms(1); |
| albertobianco | 1:219e882c32eb | 363 | mask = mask/2; |
| albertobianco | 1:219e882c32eb | 364 | } |
| albertobianco | 1:219e882c32eb | 365 | wait_ms(1); |
| albertobianco | 1:219e882c32eb | 366 | TC_CS1 = 1; // Both CS high |
| albertobianco | 1:219e882c32eb | 367 | TC_CS2 = 1; |
| albertobianco | 1:219e882c32eb | 368 | |
| albertobianco | 1:219e882c32eb | 369 | Temp=((Temp>>3)&0x0FFF); |
| albertobianco | 1:219e882c32eb | 370 | |
| albertobianco | 1:219e882c32eb | 371 | return(Temp); |
| albertobianco | 1:219e882c32eb | 372 | |
| walter76 | 0:b6fd8ca8bfbf | 373 | } |
| walter76 | 0:b6fd8ca8bfbf | 374 | |
| walter76 | 0:b6fd8ca8bfbf | 375 | // ------------------------------------------------------------- |
| walter76 | 0:b6fd8ca8bfbf | 376 | // ------------------------------------------------------------- |
| walter76 | 0:b6fd8ca8bfbf | 377 | // ------------------------------------------------------------- |
| walter76 | 0:b6fd8ca8bfbf | 378 | |
| albertobianco | 1:219e882c32eb | 379 | int main() |
| albertobianco | 1:219e882c32eb | 380 | { |
| albertobianco | 1:219e882c32eb | 381 | |
| albertobianco | 1:219e882c32eb | 382 | FAN.period_us(500); // set initial fan PWM period and duty-cycle |
| albertobianco | 1:219e882c32eb | 383 | FAN.write(0.1); |
| albertobianco | 1:219e882c32eb | 384 | |
| albertobianco | 1:219e882c32eb | 385 | pitPID.setInputLimits(TPIT_MIN, TPIT_MAX); |
| albertobianco | 1:219e882c32eb | 386 | pitPID.setOutputLimits(TCOAL_MIN, TCOAL_MAX); |
| albertobianco | 1:219e882c32eb | 387 | |
| albertobianco | 1:219e882c32eb | 388 | coalPID.setInputLimits(TCOAL_MIN, TCOAL_MAX); |
| albertobianco | 1:219e882c32eb | 389 | coalPID.setOutputLimits(0.0, 1.0); |
| albertobianco | 1:219e882c32eb | 390 | |
| albertobianco | 1:219e882c32eb | 391 | ALM.period_us(500); // set initial ALM period and duty-cycle |
| albertobianco | 1:219e882c32eb | 392 | ALM.write(0.01); |
| walter76 | 0:b6fd8ca8bfbf | 393 | |
| albertobianco | 1:219e882c32eb | 394 | TC_SDO.mode(PullDown); // enable pull-down on TC_SDO |
| albertobianco | 1:219e882c32eb | 395 | |
| albertobianco | 1:219e882c32eb | 396 | Button.mode(PullUp); // enable pushbutton pull-up |
| albertobianco | 1:219e882c32eb | 397 | |
| albertobianco | 1:219e882c32eb | 398 | Button.setSampleFrequency( 20000 ); |
| albertobianco | 1:219e882c32eb | 399 | |
| albertobianco | 1:219e882c32eb | 400 | //Wheel.reset(); // reset quadrature encoder |
| albertobianco | 1:219e882c32eb | 401 | Hrs = 2; |
| albertobianco | 1:219e882c32eb | 402 | timeout = 0; |
| walter76 | 0:b6fd8ca8bfbf | 403 | |
| albertobianco | 1:219e882c32eb | 404 | MyLCD.cls(); // clear LCD |
| albertobianco | 1:219e882c32eb | 405 | |
| albertobianco | 1:219e882c32eb | 406 | MyLCD.locate(0,0); |
| albertobianco | 1:219e882c32eb | 407 | MyLCD.printf(__TIME__, Hrs, Min, Sec); |
| albertobianco | 1:219e882c32eb | 408 | MyLCD.locate(1,1); |
| albertobianco | 1:219e882c32eb | 409 | MyLCD.printf(__DATE__, Hrs, Min, Sec); |
| albertobianco | 1:219e882c32eb | 410 | |
| albertobianco | 1:219e882c32eb | 411 | |
| albertobianco | 1:219e882c32eb | 412 | Sec_Beat.attach(&Timer_tick, 1); // configure tickers |
| albertobianco | 1:219e882c32eb | 413 | //decSecBeat.attach(&Fast_tick, 1); // configure tickers |
| albertobianco | 1:219e882c32eb | 414 | FanSpeed = 0; |
| walter76 | 0:b6fd8ca8bfbf | 415 | |
| albertobianco | 1:219e882c32eb | 416 | //Button.fall(&Button_Pressed); // enable button interrupt |
| albertobianco | 1:219e882c32eb | 417 | Button.attach_deasserted( &Button_Pressed ); |
| walter76 | 0:b6fd8ca8bfbf | 418 | |
| albertobianco | 1:219e882c32eb | 419 | while(1) |
| albertobianco | 1:219e882c32eb | 420 | { |
| albertobianco | 1:219e882c32eb | 421 | if(req_LCD_update) { |
| albertobianco | 1:219e882c32eb | 422 | Update_LCD(); |
| albertobianco | 1:219e882c32eb | 423 | req_LCD_update = 0; |
| albertobianco | 1:219e882c32eb | 424 | } |
| albertobianco | 1:219e882c32eb | 425 | |
| albertobianco | 1:219e882c32eb | 426 | if(warning) |
| albertobianco | 1:219e882c32eb | 427 | ALM.write(0.01); |
| albertobianco | 1:219e882c32eb | 428 | else |
| albertobianco | 1:219e882c32eb | 429 | ALM.write(0.0); |
| albertobianco | 1:219e882c32eb | 430 | |
| albertobianco | 1:219e882c32eb | 431 | if(MN.isSelect()) |
| albertobianco | 1:219e882c32eb | 432 | { |
| albertobianco | 1:219e882c32eb | 433 | if(Wheel.getPulses() > 0) |
| albertobianco | 1:219e882c32eb | 434 | { |
| albertobianco | 1:219e882c32eb | 435 | MN.next(); |
| albertobianco | 1:219e882c32eb | 436 | Wheel.reset(); |
| albertobianco | 1:219e882c32eb | 437 | req_LCD_update = 1; |
| albertobianco | 1:219e882c32eb | 438 | } |
| albertobianco | 1:219e882c32eb | 439 | else if(Wheel.getPulses() < 0) |
| albertobianco | 1:219e882c32eb | 440 | { |
| albertobianco | 1:219e882c32eb | 441 | MN.prev(); |
| albertobianco | 1:219e882c32eb | 442 | Wheel.reset(); |
| albertobianco | 1:219e882c32eb | 443 | req_LCD_update = 1; |
| albertobianco | 1:219e882c32eb | 444 | } |
| albertobianco | 1:219e882c32eb | 445 | } |
| albertobianco | 1:219e882c32eb | 446 | else if(MN.isEdit()) |
| albertobianco | 1:219e882c32eb | 447 | { |
| albertobianco | 1:219e882c32eb | 448 | if(Wheel.getPulses()) |
| albertobianco | 1:219e882c32eb | 449 | { |
| albertobianco | 1:219e882c32eb | 450 | MN.edit(Wheel.getPulses()); |
| albertobianco | 1:219e882c32eb | 451 | Wheel.reset(); |
| albertobianco | 1:219e882c32eb | 452 | req_LCD_update = 1; |
| albertobianco | 1:219e882c32eb | 453 | } |
| albertobianco | 1:219e882c32eb | 454 | } |
| albertobianco | 1:219e882c32eb | 455 | else if(MN.isIdle()) |
| albertobianco | 1:219e882c32eb | 456 | { |
| albertobianco | 1:219e882c32eb | 457 | if(Wheel.getPulses() > 0) |
| albertobianco | 1:219e882c32eb | 458 | { |
| albertobianco | 1:219e882c32eb | 459 | displayLine++; |
| albertobianco | 1:219e882c32eb | 460 | displayLine &= 0x3; |
| albertobianco | 1:219e882c32eb | 461 | Wheel.reset(); |
| albertobianco | 1:219e882c32eb | 462 | req_LCD_update = 1; |
| albertobianco | 1:219e882c32eb | 463 | } |
| albertobianco | 1:219e882c32eb | 464 | else if(Wheel.getPulses() < 0) |
| albertobianco | 1:219e882c32eb | 465 | { |
| albertobianco | 1:219e882c32eb | 466 | displayLine--; |
| albertobianco | 1:219e882c32eb | 467 | displayLine &= 0x3; |
| albertobianco | 1:219e882c32eb | 468 | Wheel.reset(); |
| albertobianco | 1:219e882c32eb | 469 | req_LCD_update = 1; |
| albertobianco | 1:219e882c32eb | 470 | } |
| albertobianco | 1:219e882c32eb | 471 | |
| albertobianco | 1:219e882c32eb | 472 | } |
| albertobianco | 1:219e882c32eb | 473 | } |
| albertobianco | 1:219e882c32eb | 474 | |
| walter76 | 0:b6fd8ca8bfbf | 475 | |
| albertobianco | 1:219e882c32eb | 476 | |
| albertobianco | 1:219e882c32eb | 477 | |
| walter76 | 0:b6fd8ca8bfbf | 478 | } //main |