I’ve spent quite some time trying to figure out whether or not I should post the source code for the soldering pen. It’s not like it’s particular secret or anything but I had a internal battle anyway. In the end I was convinced that it should indeed be open. That also means that you out there can spot errors and help on improving the code.
I don’t see myself as the perfect programmer so you will most likely find some typos and logical errors in there. I know for a fact that I need a watchdog and preferably also some feedback on the input voltage. right now I haven’t done that so USE THIS ON YOUR OWN RISK!
you know how it goes – your own stuff, your own safety. I live in europe so getting sued is not that common but anyway..
without further ado:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
#include <EEPROM.h> //Pins: #define REDLED 5 #define GREENLED 6 #define BLUELED 9 #define HEATER_OUT 10 #define STDBY_IN 7 #define BUTTONUP 11 #define BUTTONDOWN 12 #define SENSOR A2 //Opamp definitions #define ADC_TO_TEMP_GAIN 0.39 #define ADC_TO_TEMP_OFFSET 23.9 #define CNTRL_GAIN 10 #define DELAY_MAIN_LOOP 10 int pwm; int storedTemp; //temp stored in EEPROM int wantedTemp; int currentTemp; bool standby=1; //are we in standby? int brightness[3] = {0,0,0}; // how bright each LED (R,G,B) is int fadeAmount[3] = {1,1,1}; // this controls the speed of a fading pulse. Each color channel can have its own speed unsigned long setupTime =0; unsigned long setupLEDTime = 0; unsigned long previousUp = 0; //last UP press unsigned long previousDown = 0; //last DOWN press bool buttonDownPressed=0; bool buttonUpPressed=0; bool setupMode=0; void setup() { //set pin directions: pinMode(HEATER_OUT, OUTPUT); pinMode(REDLED, OUTPUT); pinMode(GREENLED, OUTPUT); pinMode(BLUELED, OUTPUT); pinMode(STDBY_IN, INPUT); pinMode(BUTTONUP, INPUT); pinMode(BUTTONDOWN, INPUT); pinMode(SENSOR, INPUT); pwm=(25*255)/100; digitalWrite(HEATER_OUT, LOW); //enable pullup digitalWrite(STDBY_IN, HIGH); digitalWrite(BUTTONUP, HIGH); digitalWrite(BUTTONDOWN, HIGH); //Get stored temperature from EEPROM. the value is in 10 degrees: 35 = 350degrees storedTemp = EEPROM.read(0); //read value at address 0 if(storedTemp > 45) //should also catch uninitialized memory { storedTemp = 35; //set the temp to a nice default value EEPROM.write(0,storedTemp); //save the value } wantedTemp = storedTemp*10; //load the wanted temperature } void displayTemp() //Show the current temperature { analogWrite(HEATER_OUT,0); // turn off! fadeOut(REDLED,0); fadeOut(GREENLED,1); fadeOut(BLUELED,2); delay(250); for(int i=0;i<storedTemp/10;i++) //for all 100's of degrees, show a red blink (300 degrees = 3 blinks) { analogWrite(REDLED,100); delay(500); analogWrite(REDLED,0); delay(500); } delay(500); //a small pause between the 100's and the 10's for(int i=0;i<storedTemp%10;i++) //show a blue blink for all the 10's of degrees (50 degrees = 5 blinks) { analogWrite(BLUELED,100); delay(500); analogWrite(BLUELED,0); delay(500); } } int getTemperature() //get the current temperature of the tip { analogWrite(HEATER_OUT, 0); //switch off heater delay(10); //wait a bit to let opamp and filter settle int adcValue = analogRead(SENSOR); //Get conversion value analogWrite(HEATER_OUT, pwm); //switch heater back to last value return round(((float) adcValue)*ADC_TO_TEMP_GAIN+ADC_TO_TEMP_OFFSET); //apply linear conversion to actual temperature } void readButtons(int debounceTime) { unsigned long currentMillis = millis(); //get current time if(digitalRead(BUTTONDOWN)==0) { if(previousDown==0) //if the button was not pressed before previousDown = currentMillis; //get the time the button was pressed down else { if(currentMillis-previousDown>=debounceTime) { //button press valid buttonDownPressed=1; previousDown=0; } } } else { previousDown=0; //clear the last time the buttons was pressed buttonDownPressed=0; } if(digitalRead(BUTTONUP)==0) { if(previousUp==0) //if the button was not pressed before previousUp = currentMillis; //get the time the button was pressed down else { if(currentMillis-previousUp>=debounceTime) { //button press valid buttonUpPressed=1; previousUp=0; if(!digitalRead(BUTTONDOWN)==0 && setupMode==0) displayTemp(); } } } else { previousUp=0; //clear the last time the buttons was pressed buttonUpPressed=0; } } void fadeOut(char LED, char index) { if(brightness[index]>0) { while(brightness[index]>2) { fadeAmount[index] = -abs(fadeAmount[index]); brightness[index] += fadeAmount[index]; analogWrite(LED,brightness[index]); delay(2); } analogWrite(LED,0); //turn the LED completely off brightness[index]=0; } } void indicateLED(char LED, int showTime) //indicate a button press. flash the LED for a short period and turn it off again { digitalWrite(LED,HIGH); delay(showTime); digitalWrite(LED,LOW); } void fade(char LED, char index) { if(brightness[index]<1) brightness[index]=1; analogWrite(LED,brightness[index]); // change the brightness for next time through the loop: brightness[index] += fadeAmount[index]; // reverse the direction of the fading at the ends of the fade: if (brightness[index] < 2 || brightness[index] > 100) fadeAmount[index] = -fadeAmount[index] ; } // the loop routine runs over and over again forever: void loop() { if(digitalRead(STDBY_IN)==0) //if the hall sensor is triggered { analogWrite(HEATER_OUT,0); // turn off! standby=1; } else standby=0; if(standby) //if we're in standby { analogWrite(HEATER_OUT,0); // turn off! fadeOut(REDLED,0); fadeOut(GREENLED,1); fade(BLUELED,2); delay(15); } else if(!standby && !setupMode) { fadeOut(BLUELED,2); //do the heating stuff here but only a single loop. //compute difference between target and actual temperature: int diff = wantedTemp-getTemperature(); pwm = diff*CNTRL_GAIN; //apply P controller: pwm = constrain(pwm,0,255); //limit pwm value to 0...255: analogWrite(HEATER_OUT, pwm); //set the PWM duty cycle if(diff>5) //we're not hot enough yet { digitalWrite(GREENLED,LOW); analogWrite(REDLED,pwm); brightness[0] = pwm; } else if(diff<-5) //we're too hot { analogWrite(HEATER_OUT,0); // turn off! digitalWrite(GREENLED,LOW); indicateLED(REDLED,5); delay(90); } else //we're inside the sweet spot { analogWrite(REDLED,0); fade(GREENLED,1); } delay(10); } //handle buttons here readButtons(1000); //read the buttons with a timeout of 1000ms, meaning that a press is not confirmed if it's shorter than 1000ms if(buttonDownPressed && buttonUpPressed) { setupMode=1; setupTime=millis(); } if(setupMode==1) { analogWrite(HEATER_OUT,0); // turn off! fadeOut(REDLED,0); fadeOut(GREENLED,1); fadeOut(BLUELED,2); delay(100); while(buttonDownPressed || buttonUpPressed) //wait for the user to release buttons before unlocking the setup features { readButtons(50); if (millis() - setupLEDTime >= 1000) //blink the green LED to show that we're in setup mode { setupLEDTime = millis(); indicateLED(GREENLED,5); } } while(millis()-setupTime<5000) //trap in this loop while we're setting up. Escape if no button is pressed within timely manner { readButtons(100); //read the buttons with 50ms debounce time if(buttonDownPressed) //turn temp down 10 degrees if button down is pressed { storedTemp--; setupTime = millis(); setupLEDTime=millis(); indicateLED(BLUELED,100); } if(buttonUpPressed) //turn temp up 10 degrees if button up is pressed { storedTemp++; setupTime = millis(); setupLEDTime=millis(); indicateLED(REDLED,100); } while(buttonUpPressed || buttonDownPressed) readButtons(50); if (millis() - setupLEDTime >= 1000) //blink the green LED to show that we're in setup mode { setupLEDTime = millis(); indicateLED(GREENLED,5); } } storedTemp = constrain(storedTemp,4,45); //constrain the temperature - not below 40 degrees and not above 450. don't damage the tip! setupMode=0; //exiting setup mode EEPROM.write(0,storedTemp); //store the temp in EEPROM wantedTemp = storedTemp*10; //set the wanted temperature now displayTemp(); //show the new temperature } } |