Programmeerbare temperatuur Controller + hete plaat (5 / 7 stap)

Stap 5: Code


Kunt u de code in de bijgevoegde bestanden. Ik heb de volgende externe bibliotheken geïmplementeerd:
PID-bibliotheek
Bounce bibliotheek
Roterende Encoder
I2C LC Display
MAX6675

Opmerking: "MAX6675.h" u moet vervangen door lijn 11 (#include "WProgram.h")
#if defined(ARDUINO) & & ARDUINO > = 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
om te laten draaien op Arduino 1.05

Gebruik van de bibliotheek van de "LiquidCrystal" in de sub map 2004-1.0 code, negeren van "LiquidCrystal_I2C".

Wanneer een temperatuur handmatig is ingesteld of een programma van de SD-kaart is geselecteerd, de controller begint met het lezen van de temperatuur ooit 0,1 seconden en berekend de volgende verwarming pulslengte met PID bibliotheek. Als we zijn met behulp van een heleboel verschillende bibliotheken gebruikt ik meer dan 99,5% van al het gratis flash geheugen op de 328 atmega-chip. Erger nog, ik moest verkorten de tekst en menu voor de LCD-display, aangezien ik liep uit SRAM. Volgende keer, ik zou waarschijnlijk met behulp van een atmega 2560 of verwisselen van sommige snaren in de EEPROM.

De verschillende programma's moeten worden opgeslagen als door komma's gescheiden tekstbestanden met bestandsnamen (1.txt,... te verhogen 10.txt) in de root-map van de SD-kaart. De indeling van de bestanden moet er zo uitzien:
1. regel: titel (maximaal 20 tekens)
2. line: eerste temperatuur ingesteld punt, eerste opwarmsnelheid, eerste duur
3. line: tweede temperatuur instelpunt, tweede opwarmsnelheid, tweede duur
4. lijn...

U kunt omhoog tot een maximum van 10 lijnen per bestand. Het moet worden afgesloten met een lege regel.

Ik gebruikte een Arduino UNO te uploaden met de volgende code naar de Atmega:

 //Temperature Controller #include <MAX6675.h> //LCD #include <Wire.h> #include <LCD.h> #include <LiquidCrystal_I2C.h> #include <SD.h> #include <PID_v1.h> //Rotary Encoder #include <Encoder.h> Encoder roundEnc(2, 3); //Pushbutton on rotary encoder #include <Bounce.h> Bounce pushButton = Bounce(4 ,5); #define I2C_ADDR 0x3F // Define I2C Address where the LCD is #define BACKLIGHT_PIN 3 #define En_pin 2 #define Rw_pin 1 #define Rs_pin 0 #define D4_pin 4 #define D5_pin 5 #define D6_pin 6 #define D7_pin 7 LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin); //Temperatursensor int tCS = 7; // CS pin on MAX6675 int tSO = 9; // SO pin of MAX6675 int tSCK = 8; // SCK pin of MAX6675 int units = 1; // Units to readout temp (0 = raw, 1 = ˚C, 2 = ˚F) int TCError = 0; // ErrorFlag - TC Error int tempVal = 0; // Actual-Temperatur //Display unsigned long lastMeas = 0; // Last temperature measurement unsigned long lastDisp = 0; // Last display change unsigned long lastTempDisp = 0; // Last temperature update on display unsigned long lastLog = 0; // Last Logstate unsigned long logTime = 0; int lastDispTemp = -1; int dispOn = 0; // blink int cPosX = -1; // x-position (cursor) on display int cPosY = -1; // y-position on display String emptyString = " "; unsigned long lastDispPrg = 0; //Zeit seit letztem Update des Programm-Displays // Has the button on the rotary encoder been pressed? // 0 = no // 1 = yes // 2 = yes, for more than 2 seconds int buttonPressed = 0; // Rotational Encoder // 0 = not changed // 1 = clockwise // 2 = counterclockwise int rotationState = 0; int rotationNumber = 0; int lastRotationNumber = 0; int rotationBigLeap = 0; //was the rotationl encoder moved more than ~20° int oldRotState = 0; //Program state // 0: No program // 1: Manual Setpoint // 2: Load from SD // 3: not used // 4: Program is running int progState = 0; int subProgState = 0; int lastProgState = -1; int lastSubProgState = -1; // Programs from SD-Card int progCount = 0; byte progLnCount = 0; byte progTSp[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; byte progSprr[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; word progTime[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //Which type of program is running at the moment? //-1 = 0; //0 = Single-Point //>1 = SD-Card int progRun = -1; int runLine = -1; // Actual subprogram of the SDCard unsigned long runTime = 0; // How long is the step running already unsigned long stepTime = 0; // How much time to increase the ramp unsigned long lastPuls = 0; // Last heating puls int minutesPast = 0; boolean SDOpen = false; int aTsp = 0; int Tsp = 120; //Setpoint °C int MaxT = 190; // Maximal T °C byte Sprr = 15; //Rate °C/m byte MaxR = 20; // Maximale Ramp int TAlert = 200; // Shutown Temperature int Tdig1 = Tsp/100; //Digits for Tsp int Tdig2 = (Tsp%100)/10; int Tdig3 = Tsp%10; int Rdig1 = Sprr/10; //Digits for Rp int Rdig2 = Sprr%10; // Initialize the MAX6675 Library for our chip // Setup Serial output and LED Pin // MAX6675 Library already sets pin modes for MAX6675 chip! MAX6675 temp(tCS,tSO,tSCK,units); //PID Parameters double Setpoint, Input, Output; PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT); void setup() { //Serial.begin(9600); lcd.begin (20,4); // Switch on the backlight lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); lcd.setBacklight(HIGH); lcd.noBlink(); lcd.clear (); pinMode(10, OUTPUT); //SC-Pin SD-Card //pinMode(53, OUTPUT); //SC-Pin SD-Karte - Arduino mega //digitalWrite(53, HIGH); pinMode(6, OUTPUT); //heating pin } void loop() { //disable Heating digitalWrite(6, LOW); //get user input getButtonState(); getRotState(); //change display setState(); //Update display displayState(); //Update Temperature //Faster measurement when program is running. In the programming stage the LCD lags if (progState == 4){ getTemp(); updateProgram(); Input = tempVal; Setpoint = aTsp; myPID.Compute(); heatingPuls(); if ((lastLog + 1000) < millis()){ updateLog(); lastLog = millis(); } } else if ((lastMeas + 10000) < millis()){ getTemp(); lastMeas = millis(); } if ((tempVal > TAlert) || ( TCError ==1 )) { stopProgram(); delay(5000); } } void getButtonState(){ unsigned long pushTime = pushButton.duration(); pushButton.update(); //How long was the button pressed - abort? boolean pushed = pushButton.fallingEdge(); if ((pushed == true) && (pushTime < 1500) ){ buttonPressed = 1; } else if ((pushed == true) && (pushTime >= 1500) ){ buttonPressed = 2; } else { buttonPressed = 0; } } void getRotState(){ //int roataionState = 0; //int rotationNumber = 0; - Scale 0-10 long tempState = roundEnc.read(); if (tempState > oldRotState) { rotationState = 1; // rotationNumber = (tempState%100)/10; int tempRotationNumber = (tempState%100)/10; if (tempRotationNumber != rotationNumber) { rotationBigLeap = 1; } rotationNumber = tempRotationNumber; if (rotationNumber < 0) { rotationNumber = 10 + rotationNumber; } oldRotState = (tempState%100); roundEnc.write(oldRotState); } else if (tempState < oldRotState) { rotationState = 2; // rotationNumber = (tempState%100)/10; int tempRotationNumber = (tempState%100)/10; if (tempRotationNumber != rotationNumber) { rotationBigLeap = 1; } rotationNumber = tempRotationNumber; if (rotationNumber < 0) { rotationNumber = 10 + rotationNumber; } oldRotState = (tempState%100); roundEnc.write(oldRotState); } else { rotationState = 0; rotationBigLeap = 0; } } void resetRotState(int digit){ //For entering numbers in the LCD rotationNumber = digit; //Failsave if ((rotationNumber > 10) || (rotationNumber < 0)) { rotationNumber = 0; } oldRotState = digit * 10; roundEnc.write(oldRotState); } //Verarbeite Eingaben am Display void setState(){ //Rotationstate 1 = right //Rotationstate 2 = left //Long pressing: abort if ((progState != 0) && (buttonPressed == 2)) { stopProgram(); buttonPressed = 0; return; } //submenu 0,1 if ((progState == 0) && (rotationState != 0)){ int select = rotationNumber%2 + 1; subProgState = select; displayState(); return; } //choose menu entry //manual setpoint if ((progState == 0) && (buttonPressed == 1)){ if (subProgState == 1) { progState = 1; subProgState = 0; displayState(); buttonPressed = 0; return; } //SD-Card if (subProgState == 2) { progState = 2; subProgState = 0; displayState(); buttonPressed = 0; return; } } //Submenue 0,1 - manual mode if ((progState == 1) && (subProgState < 4) && (rotationState == 1) && (rotationBigLeap == 1)){ subProgState = subProgState + 1; if (subProgState > 3) { subProgState = 0; } displayState(); rotationBigLeap = 0; return; } if ((progState == 1) && (subProgState < 4) && (rotationState == 2) && (rotationBigLeap == 1)){ subProgState = subProgState - 1; if (subProgState < 0) { subProgState = 3; } displayState(); rotationBigLeap = 0; return; } //Back, TSP, Rp, Start in Manual Mode if ((progState == 1) && (subProgState == 0) && (buttonPressed == 1)) { stopProgram(); buttonPressed = 0; return; } if ((progState == 1) && (subProgState == 1) && (buttonPressed == 1)) { subProgState = 11; buttonPressed = 0; return; } if ((progState == 1) && (subProgState == 2) && (buttonPressed == 1)) { subProgState = 21; buttonPressed = 0; return; } if ((progState == 1) && (subProgState == 3) && (buttonPressed == 1)) { startProgram(0); buttonPressed = 0; return; } //1., 2., 3. Digit T-Setpoint if ((progState == 1) && (subProgState == 11) && (buttonPressed == 1)) { subProgState = 12; buttonPressed = 0; return; } if ((progState == 1) && (subProgState == 12) && (buttonPressed == 1)) { subProgState = 13; buttonPressed = 0; return; } if ((progState == 1) && (subProgState == 13) && (buttonPressed == 1)) { //Last digit subProgState = 1; Tsp = Tdig1 * 100 + Tdig2 * 10 + Tdig3; if (Tsp > MaxT) { Tsp = MaxT; } //Maximal Temperature Tdig1 = Tsp/100; //Digits for Tsp Tdig2 = (Tsp%100)/10; Tdig3 = Tsp%10; buttonPressed = 0; return; } //1., 2. Digit ramp if ((progState == 1) && (subProgState == 21) && (buttonPressed == 1)) { subProgState = 22; buttonPressed = 0; return; } if ((progState == 1) && (subProgState == 22) && (buttonPressed == 1)) { //Last digit subProgState = 2; Sprr = Rdig1 * 10 + Rdig2; if (Sprr > MaxR) { Sprr = MaxR; } //Maximal/minimal ramp if (Sprr < 1) { Sprr = 1; } Rdig1 = Sprr/10; //Digits for Rp Rdig2 = Sprr%10; buttonPressed = 0; return; } //Submenu 1,1 - SD-Programm if ((progState == 2) && (subProgState < 11) && (rotationState == 1) && (rotationBigLeap == 1)){ subProgState = subProgState + 1; if (subProgState > progCount) { subProgState = 1; } displayState(); rotationBigLeap = 0; return; } if ((progState == 2) && (subProgState < 11) && (rotationState == 2) && (rotationBigLeap == 1)){ subProgState = subProgState - 1; if (subProgState < 1) { subProgState = progCount; } displayState(); rotationBigLeap = 0; return; } if ((progState == 2) && (subProgState < 11) && (buttonPressed == 1)){ startProgram(subProgState); buttonPressed = 0; return; } } void stopProgram(){ progState = 0; subProgState = 0; progRun = -1; runLine = -1; lastSubProgState = -1; lastProgState = -1; displayState(); myPID.SetMode(MANUAL); } void startProgram(int runType){ progRun = runType; aTsp = tempVal; runTime = millis(); runLine = 0; progState = 4; myPID.SetMode(AUTOMATIC); logTime = millis(); } void updateProgram() { //SD-Card //progLnCount //runline minutesPast = 1.0 * ((millis() - runTime) / 60000.0); if (progRun > 0){ Tsp = progTSp[runLine]; Sprr = progSprr[runLine]; //Load new program? if (minutesPast >= progTime[runLine]) { runLine++; if (runLine > progLnCount) { stopProgram(); return; } runTime = millis(); } } //Ramp long timeStep = (1000.0 * 60.0) / (double)Sprr; if ((stepTime + timeStep < millis()) && (aTsp < Tsp)) { aTsp++; stepTime=millis(); } else if ((stepTime + timeStep < millis()) && (aTsp > Tsp)) { aTsp--; stepTime=millis(); } } void heatingPuls(){ //pulse every 0.1 s if ((lastPuls + 100) < millis()) { digitalWrite(6, HIGH); int dly = Output * 1; //limit Power if (dly > 1000) { dly = 1000; } else if (dly < 0) { dly = 0; } //Serial.println(dly); delay(dly); digitalWrite(6, LOW); lastPuls = millis(); } } void getTemp(){ // Read the temp from the MAX6675 float loop_temperature[2]; for (int ii=0; ii<2; ii++) { loop_temperature[ii] = temp.read_temp(); if (loop_temperature[ii] < 0) { TCError = 1; } delay(50); } tempVal = (int)((loop_temperature[0] + loop_temperature[1] ) / 2 + 0.5); } void updateTemp( boolean force = false, int lastPosX = -1, int lastPosY = -1 ){ if (((millis() > (lastTempDisp + 1000)) && ( tempVal != lastDispTemp)) || (force == true)) { lcd.setCursor(0, 3); lcd.print("T: "); lcd.setCursor(3, 3); lcd.print(tempVal); lcd.print((char)223); lcd.print("C "); lastTempDisp = millis(); lastDispTemp = tempVal; if ((lastPosX != -1) || (lastPosY != -1)) { lcd.setCursor(lastPosX, lastPosY); } } } void fillNumber3(int number, String &dest3){ if (number < -9) { dest3 += String(number); } else if (number < 0) { dest3 = "0"; dest3 += String(number); } else if (number < 10) { dest3 = "00"; dest3 += String(number); } else if (number < 100) { dest3 = "0"; dest3 += String(number); } else { dest3 = String(number); } } void fillNumber2(int number, String &dest2){ if (number < 10) { dest2 = "0"; dest2 += String(number); } else { dest2 = String(number); } } void printProgLine(byte number, String &line){ line = (String)(number); line += ": "; line += (String)(progTSp[number]); line += ", "; line += (String)(progSprr[number]); line += ", "; line += (String)(progTime[number]); line += " "; } void printProcessLine(String &line){ String saSP; fillNumber3( aTsp, saSP); String st; fillNumber3( minutesPast , st); line = "TaSp: "; line += saSP; line += (char)223; line += "C "; line += " t: "; line += st; } void printSingleLine(String &line){ String sTsp; String sSprr; fillNumber3(Tsp, sTsp); fillNumber2(Sprr, sSprr); line = "Tsp: "; line += sTsp; line += (char)223; line += "C "; line += "Rp: "; line += sSprr; line += (char)223; line += "/m"; } //Update display void displayState(){ if (progState==0) { display0(); } if (progState==1) { display1(); } if (progState==2) { display2(); } if (progState==4) { display4(); } } void display0(){ if (lastProgState != 0){ cPosX = -1; cPosY = -1; lcd.noBlink(); lcd.clear (); // go home lcd.print("Program"); // program ended lastProgState = 0; lastSubProgState = -1; //Reset updateTemp(true); //Update Temperature } //Update every second if ((subProgState == 0) && (millis() > (lastDisp + 1000)) && (dispOn == 0)) { lcd.setCursor(0, 1); // go to the 2nd line lcd.print("-"); lastDisp = millis(); dispOn = 1; } else if ((subProgState == 0) && (millis() > (lastDisp + 1000))){ lcd.setCursor ( 0, 1 ); // go to the 2nd line lcd.print(emptyString); lastDisp = millis(); dispOn = 0; } else if ((subProgState == 1) && (lastSubProgState != 1)){ lcd.setCursor(0, 1); lcd.print("Setpoint"); lastSubProgState = 1; updateTemp(true); } else if ((subProgState == 2) && (lastSubProgState != 2)){ lcd.setCursor(0, 1); lcd.print("SDCard "); lastSubProgState = 2; updateTemp(true); } updateTemp(); } //Manual setpoint void display1(){ if (lastProgState != 1){ cPosX = -1; cPosY = -1; lcd.noBlink(); lcd.clear (); // go home lcd.print("Setpoint"); lcd.setCursor(0, 1); String line; printSingleLine(line); lcd.print(line); lastProgState = 1; lastSubProgState = -1; updateTemp(true); } //0. Back if ((subProgState == 0) && (lastSubProgState != 0)) { lcd.noBlink(); lcd.setCursor(0, 2); lcd.print("Back "); } //1. Set Temp if ((subProgState == 1) && (lastSubProgState != 1)) { lcd.noBlink(); lcd.setCursor(0, 1); String line; printSingleLine(line); lcd.print(line); lcd.setCursor(0, 2); lcd.print("TSp "); lastSubProgState = 1; } //2. Set Ramp if ((subProgState == 2) && (lastSubProgState != 2)) { lcd.noBlink(); lcd.setCursor(0, 1); String line; printSingleLine(line); lcd.print(line); lcd.setCursor(0, 2); lcd.print("Rp "); lastSubProgState = 2; } //3. Start if ((subProgState == 3) && (lastSubProgState != 3)) { lcd.noBlink(); lcd.setCursor(0, 2); lcd.print("Start"); lastSubProgState = 3; } //4. Change T 1. Digit if ((subProgState == 11) && (lastSubProgState != 11)) { //1. Digit cPosX = 1, cPosY = 1 cPosX = 5; cPosY = 1; lcd.blink(); resetRotState(Tdig1); lcd.setCursor(cPosX, cPosY); lcd.print(Tdig1); lcd.setCursor(cPosX, cPosY); lastSubProgState = 11; } else if (subProgState == 11) { lcd.setCursor(cPosX, cPosY); Tdig1 = rotationNumber; lcd.print(Tdig1); lcd.setCursor(cPosX, cPosY); } //5. Change T 2. Digit if ((subProgState == 12) && (lastSubProgState != 12)) { //2. Digit cPosX = 6, cPosY = 1 cPosX = 6; cPosY = 1; lcd.blink(); resetRotState(Tdig2); lcd.setCursor(cPosX, cPosY); lcd.print(Tdig2); lcd.setCursor(cPosX, cPosY); lastSubProgState = 12; } else if (subProgState == 12) { lcd.setCursor(cPosX, cPosY); Tdig2 = rotationNumber; lcd.print(Tdig2); lcd.setCursor(cPosX, cPosY); } //6. Change T 3. Digit if ((subProgState == 13) && (lastSubProgState != 13)) { //3. Digit cPosX = 7, cPosY = 1 cPosX = 7; cPosY = 1; lcd.blink(); resetRotState(Tdig3); lcd.setCursor(cPosX, cPosY); lcd.print(Tdig3); lcd.setCursor(cPosX, cPosY); lastSubProgState = 13; } else if (subProgState == 13) { lcd.setCursor(cPosX, cPosY); Tdig3 = rotationNumber; lcd.print(Tdig3); lcd.setCursor(cPosX, cPosY); } //4. Change Ramp 1. Digit if ((subProgState == 21) && (lastSubProgState != 21)) { //1. Digit cPosX = 15, cPosY = 1 cPosX = 15; cPosY = 1; lcd.blink(); resetRotState(Rdig1); lcd.setCursor(cPosX, cPosY); lcd.print(Rdig1); lcd.setCursor(cPosX, cPosY); lastSubProgState = 21; } else if (subProgState == 21) { lcd.setCursor(cPosX, cPosY); Rdig1 = rotationNumber; lcd.print(Rdig1); lcd.setCursor(cPosX, cPosY); } //5. Change Ramp 2. Digit if ((subProgState == 22) && (lastSubProgState != 22)) { //2. Digit cPosX = 16, cPosY = 1 cPosX = 16; cPosY = 1; lcd.blink(); resetRotState(Rdig2); lcd.setCursor(cPosX, cPosY); lcd.print(Rdig2); lcd.setCursor(cPosX, cPosY); lastSubProgState = 22; } else if (subProgState == 22) { lcd.setCursor(cPosX, cPosY); Rdig2 = rotationNumber; lcd.print(Rdig2); lcd.setCursor(cPosX, cPosY); } updateTemp(false, cPosX, cPosY); } void display2(){ if (lastProgState != 2){ lcd.noBlink(); lcd.clear (); // go home lcd.print("SDCard"); lcd.setCursor(0, 1); if (SDOpen != true) { if (! SD.begin(10)) { stopProgram(); return; } } SDOpen = true; progCount = 0; for (int ii = 1; ii < 10; ii++){ String fname = String(ii); fname += ".txt"; char fnamec[6]; fname.toCharArray(fnamec, 6); File myFile = SD.open(fnamec, FILE_READ); if (myFile) { progCount++; } myFile.close(); } if (progCount == 0) { stopProgram(); return; } lastProgState = 2; subProgState = 1; lastSubProgState = -1; updateTemp(true); } if ((subProgState < 10) && (lastSubProgState != subProgState)) { String fname = String(subProgState); fname += ".txt"; char fnamec[6]; fname.toCharArray(fnamec, 6); File myFile = SD.open(fnamec, FILE_READ); if (! myFile) { stopProgram(); } byte line = 0; byte Slength = 0; char tempString[1]; String HeadLine = ""; String ProgLine = ""; for (byte ii=0; ii < 10; ii++) { progTSp[ii] = 0; progSprr[ii] = 0; progTime[ii] = 0; } while (myFile.available()) { tempString[1] = myFile.read(); if (tempString[1] == '\r' ) { } else if (tempString[1] != '\n' ) { ProgLine += tempString[1]; Slength++; } else { if (line == 0) { HeadLine = ProgLine; ProgLine = ""; Slength = 0; line++; } else { if ((line > 10) || (Slength > 20) ) { stopProgram(); return; } char* accum; char buffer[Slength+1]; ProgLine.toCharArray(buffer, Slength+1); const char sep[] = ","; progTSp[line-1] = atoi(strtok_r(buffer, sep, &accum)); if (progTSp[line-1] > MaxT) { progTSp[line-1] = MaxT; } progSprr[line-1] = atoi(strtok_r(NULL, sep, &accum)); if (progSprr[line-1] > MaxR) { progSprr[line-1] = MaxR; }; if (progSprr[line-1] < 1) { progSprr[line-1] = 1; } progTime[line-1] = atoi(strtok_r(NULL, sep, &accum)); progLnCount = line - 1; //0-Anzahl-1 Slength = 0; line++; ProgLine = ""; // } } } myFile.close(); lcd.setCursor(0, 1); lcd.print(emptyString); lcd.setCursor(0, 1); lcd.print(HeadLine); printProgLine(0, ProgLine); lcd.setCursor(0, 2); lcd.print(emptyString); lcd.setCursor(0, 2); lcd.print(ProgLine); resetRotState(0); lastSubProgState = subProgState; } updateTemp(); } void display4(){ if ((lastDispPrg + 1000) > millis()) { return; } if (lastProgState != 4) { lcd.noBlink(); lcd.clear (); updateTemp(true); lastProgState = 4; } if ( progRun == 0 ) { lcd.setCursor(0, 0); String line; printProcessLine(line); lcd.print(line); lcd.setCursor(0, 1); printSingleLine(line); lcd.print(line); } if ( progRun > 0 ) { lcd.setCursor(0, 0); String line; printProcessLine(line); lcd.print(line); lcd.setCursor(0, 1); printProgLine(runLine, line); lcd.print(line); if (runLine != progLnCount) { lcd.setCursor(0, 2); printProgLine(runLine+1, line); lcd.print(line); } else { lcd.setCursor(0, 2); lcd.print(emptyString); } } updateTemp(); } void updateLog(){ if (SDOpen != true) { if (! SD.begin(10)) { return; } } SDOpen = true; File myFile = SD.open("T.log", FILE_WRITE); if (! myFile) { return; } myFile.print(millis() - logTime); // myFile.print(", "); // myFile.print(aTsp); myFile.print(", "); myFile.println(tempVal); myFile.close(); } 

Zoals u in de afbeelding zien kunt, voor een eerste (en niet geoptimaliseerde) proberen zijn dit zeer mooie resultaten. Een echt handige manier om het systeem nog meer zou zijn om een bibliotheek van de autotunig (bv. hier), maar het zou meer ruimte nodig dan wat op de atmega328 beschikbaar is. Een andere optimalisatie zou een meer accurate thermokoppel-controller gebruiken.

Gerelateerde Artikelen

Een .NET-Gadgeteer-gebaseerde gisting temperatuur Controller

Een .NET-Gadgeteer-gebaseerde gisting temperatuur Controller

In dit artikel laat ik zien het ontwerp en de fabricage van een touchscreen gebaseerd geautomatiseerde gisting temperatuurregelaar met behulp van een combinatie van commerciële en aangepaste hardware en software. Ik heb thuis brouwen voor meer dan 20
Plug en Play Arduino temperatuur controller

Plug en Play Arduino temperatuur controller

Ik heb een paar verschillende temperatuur controller projecten hier. Ik wilde te bouwen, met de volgende beperkingen:Gecontroleerde "stom" toestel kan worden aangesloten rechtstreeks op de eenheid. Ik wilde niet inbreken in het toestel, maar nog
Precisie temperatuur Controller

Precisie temperatuur Controller

p.MsoNormal, li. MsoNormal, div. MsoNormal {marge: 0.0 in; font-size: 12.0pt; lettertype-familie: Arial;} p.MsoBodyText, li. MsoBodyText, div. MsoBodyText {marge: 0.0; text-align: rechtvaardigen; tekengrootte: 9.0pt; lettertype-familie: Arial;} div.
Instelbare temperatuur Controller voor verwarmingselementen

Instelbare temperatuur Controller voor verwarmingselementen

Er zijn een heleboel verschillende producten die gebruikmaken van de verwarmingselementen. Helaas, veel van hen zijn niet verstelbaar. Bijvoorbeeld, zijn de meeste soldering strijkijzers ofwel in- of uitschakelen. Het zou veel nuttiger zijn als u zou
Stovetop temperatuur Controller Hack

Stovetop temperatuur Controller Hack

dit is een nul Delta T koken doorbraak. Je hebt gezien andere verhalen van Sous Vide, maar je hebt nooit zoiets gezien. Omdat er zo weinig te zien: bijna alle van de gadgets wordt geëlimineerd.Om dit zelf te doen, moet u een liefde voor lekker eten e
Open bron temperatuur Controller-toestel warmtewisselaar

Open bron temperatuur Controller-toestel warmtewisselaar

Hier is een demo van de warmtewisselaar met behulp van de open bron temperatuur controller.Volledige warmtewisselaar beschikbaar hierIntelligente controller, schema's en code beschikbaar hierDe open bron temperatuur controller kunt u de flexibiliteit
Kleine incubator met temperatuur-controller

Kleine incubator met temperatuur-controller

We hebben een paar kippen thuis maar we wilden wat meer dus kozen we voor degene die we wilden en besloten we wilden sommige eieren. Helaas voor mij betekende dat mijn vader nu wil een incubator dus ik had hem om één te bouwen. all-in-all dit project
Bedrading van een RANCO ETC-111000-000 temperatuur Controller voor uw Kegerator

Bedrading van een RANCO ETC-111000-000 temperatuur Controller voor uw Kegerator

een heleboel thuisbrouwers zet een borstdiepvriezer of koelkast in een kegerator en ze sluit aan de koelkast of diepvriezer op een externe controller voor het beheer van de temperatuur. En als u wilt gaan digitale er is niet een controller die beter
Professionele vak: hete plaat met timer voor morning coffee

Professionele vak: hete plaat met timer voor morning coffee

laten we beginnen met wat uitleg: Ik ben Italiaans, wat betekent dat voor mij van de moka koffie, of de espresso, zijn van vitaal belang in de ochtend, ik weet niet of in ander land moet u zo veel als ik de warme koffie in de ochtend... maar hier is
Raspberry Pi HTS221 relatieve vochtigheid en temperatuur Sensor het leerprogramma van Java

Raspberry Pi HTS221 relatieve vochtigheid en temperatuur Sensor het leerprogramma van Java

HTS221 is een ultra compacte capacitieve digitale sensor voor relatieve vochtigheid en temperatuur. Het omvat een sensing-element en een gemengde signaal toepassing specifieke geïntegreerde circuit(ASIC) de meting informatie via digitale seriële inte
Tweeting, draadloos, Ugly Drum Smoker (UDS) temperatuur controller met Android

Tweeting, draadloos, Ugly Drum Smoker (UDS) temperatuur controller met Android

(Laatst bijgewerkt: oktober 2014. Zie laatste stap voor details over wijzigingen.)Dit is de UDS digitale Supervisor, een Android app en hardware voor het onderhoud op afstand de temperatuur van uw UDS zoals een thermostaat. Uw telefoon monitoren van
DIY roerder/hete plaat

DIY roerder/hete plaat

alle gebieden onderzoek, natuurkunde of scheikunde of biologie, vergt op een bepaald punt in de tijd een roerder en of een warmhoudplaat of een combo van de verwarmingsplaat roerder. Deze dingen zijn vrij duur, zelfs wanneer ze barebones apparaten zi
Meten van de temperatuur op het web met Arduino Ethernet en DS18B20 sensor

Meten van de temperatuur op het web met Arduino Ethernet en DS18B20 sensor

Zoeterd helemaal,Ten eerste wil ik u vertellen dat ik geen programmeur ben. Maar ik ben dol op het doen van nieuwe dingen, vooral als het is gerelateerd aan elektronica. Ik heb hier een webserver aan Arduino Ethernet geïntegreerd met een temperatuurs
Raspberry Pi MCP9803 Temperatuur Sensor het leerprogramma van Java

Raspberry Pi MCP9803 Temperatuur Sensor het leerprogramma van Java

MCP9803 is een hoge nauwkeurigheid van de 2-draads temperatuursensor. Ze zijn vastgelegd met de gebruiker - programmeerbare registers, die de temperatuur sensing toepassingen vergemakkelijken. Deze sensor is geschikt voor zeer geavanceerde multi-zone