Informationstechnik Beheizung Keramik 3D Drucker |
Wintersemester 2017/18 Tobias Bruder Lena Jablonsky |
|
|
|||
/* Programname: ESP32_DataLogger_Duesenbeheizung * Author: Lena Jablonsky, Tobias Bruder, Jonas Messerschmid, Florian Proß * Date: 09.11.2017 * * * The circuit: * * 5V - VCC // NOT 3V3 * * SD card attached to SPI bus as follows: ** GPIO 23 - MOSI ** GPIO 19 - MISO ** GPIO 18 - CLK ** GPIO 5 - CS * * I/O attached to ESP32 ** GPIO 16 - DS18B20 analog input ** GPIO 04 - Cerabar PMC21/SKU237545 analog input ** GPIO 17 - Proximity sensor digital input ** GPIO 00 - Poti analog input * * OLED display attached to I2C bus as follow ** GPIO 22 - SCL ** GPIO 21 - SDA */ // ******************** DECLARATIONS **************************************************************** ///////////////////////////////////////////////////////////////// // DECLARATION OLED display ///////////////////////////////////////////////////////////////// #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define OLED_RESET 4 // not used Adafruit_SSD1306 display(OLED_RESET); #define NUMFLAKES 10 #define XPOS 0 #define YPOS 1 #define DELTAY 2 #define LOGO16_GLCD_HEIGHT 16 #define LOGO16_GLCD_WIDTH 16 static const unsigned char PROGMEM logo16_glcd_bmp[] = { B00000000, B11000000, B00000001, B11000000, B00000001, B11000000, B00000011, B11100000, B11110011, B11100000, B11111110, B11111000, B01111110, B11111111, B00110011, B10011111, B00011111, B11111100, B00001101, B01110000, B00011011, B10100000, B00111111, B11100000, B00111111, B11110000, B01111100, B11110000, B01110000, B01110000, B00000000, B00110000 }; #if (SSD1306_LCDHEIGHT != 64) //#error("Height incorrect, please fix Adafruit_SSD1306.h!"); #endif ///////////////////////////////////////////////////////////////// // DECLARATION temperature sensor DS18B20 ///////////////////////////////////////////////////////////////// #include <OneWire.h> // Data wire is plugged into pin OneWire ds(15); byte i; byte present = 0; byte type_s; byte data[12]; byte addr[8]; float celsius; int SolltemperaturGlobal; int Isttemperatur; int Solltemperatur; // Solltemperatur lokal int Temp; ///////////////////////////////////////////////////////////////// // DECLARATIONEN Poti ///////////////////////////////////////////////////////////////// const int S = 0; // analog int Spannung; // für Poti ///////////////////////////////////////////////////////////////// // DECLARATION control relay ///////////////////////////////////////////////////////////////// int Relais = 13; // Low Aktiv ///////////////////////////////////////////////////////////////// // DECLARATIONEN Cerabar PMC21/SKU237545 ///////////////////////////////////////////////////////////////// //here we use analog pin GIO04 of ESP32 to read data #define analogPin 4 // *** Cerabar PMC21 *** //here we need variables to put in and calculate the value int inputVariable0 = 0; int inputVariable1 = 0; // *** SKU237545 *** int SensorVal; // AD converter value float Voltage; // Current voltage float Pressure; // Current pressure ///////////////////////////////////////////////////////////////// // DECLARATION SD card ///////////////////////////////////////////////////////////////// #include "FS.h" #include "SD.h" #include "SPI.h" // SPI bus File dataFile; #define LOGDATEI "/Log" // SLASH WICHTIG für Verzeichnis der SD Karte ///////////////////////////////////////////////////////////////// // DECLARATION Stopwatch ///////////////////////////////////////////////////////////////// unsigned long startzeit; unsigned long vergangeneZeit; int zaehlvariable = 0; ///////////////////////////////////////////////////////////////// // DECLARATION Proximity sensor ///////////////////////////////////////////////////////////////// //here we use digital pin GIO17 of ESP32 to read data #define proximitySensor 17 //// ********************** METHODS ****************************************************************** /////////////////////////////////////////////////////////////////// // // impSD() // implement SD card // /////////////////////////////////////////////////////////////////// void impSD() { if(!SD.begin()){ Serial.println("Card Mount Failed"); return; } uint8_t cardType = SD.cardType(); if(cardType == CARD_NONE){ Serial.println("No SD card attached"); return; } Serial.println("SD card detected"); Serial.print("SD Card Type: "); if(cardType == CARD_MMC){ Serial.println("MMC"); } else if(cardType == CARD_SD){ Serial.println("SDSC"); } else if(cardType == CARD_SDHC){ Serial.println("SDHC"); } else { Serial.println("UNKNOWN"); } uint64_t cardSize = SD.cardSize() / (1024 * 1024); Serial.printf("SD Card Size: %lluMB\n", cardSize); Serial.println("Set-up SD card"); const uint8_t NAMENSLAENGE= sizeof(LOGDATEI) - 1; String dateiName = LOGDATEI "00.csv"; // Z.B. DHT11.csv while (SD.exists(dateiName)) { if (dateiName[NAMENSLAENGE + 1] != '9') { dateiName[NAMENSLAENGE + 1]++; } else if (dateiName[NAMENSLAENGE] != '9') { dateiName[NAMENSLAENGE + 1] = '0'; dateiName[NAMENSLAENGE]++; } else { Serial.println("Kann Datei nicht erzeugen"); } } // Jetzt file öffnen: dataFile = SD.open(dateiName, FILE_WRITE); } ///////////////////////////////////////////////////////////////// // // impHeader() // implement header // ///////////////////////////////////////////////////////////////// void impHeader() { dataFile.println(F("Temperaturmessungen mit DS18B20 und Druckmessung mit Cerabar PMC21/SKU237545 mit Nutzung eines Dataloggers")); dataFile.print(F("Zeit [m]")); dataFile.print(';'); dataFile.print(F("Druck [bar]")); dataFile.print(';'); dataFile.print(F("Temperatur [*C]")); dataFile.print(';'); dataFile.println(); Serial.println("Set-up header"); } ///////////////////////////////////////////////////////////////// // // impDS18B20() // implement DS18B20 temperature sensor // ///////////////////////////////////////////////////////////////// void impDS18B20() { Serial.println("Set-up DS18B20"); } ///////////////////////////////////////////////////////////////// // // impStoppuhr() // implement Stopwatch // ///////////////////////////////////////////////////////////////// void impStoppuhr() { startzeit = millis(); startzeit = startzeit/60000; Serial.print("Set-up stopwatch"); Serial.print(" Starttime of meassurement: "); Serial.print(startzeit); Serial.print(" min"); Serial.println(); } ///////////////////////////////////////////////////////////////// // // impOLED() // implement OLED display // ///////////////////////////////////////////////////////////////// void impOLED() { // by default, we'll generate the high voltage from the 3.3v line internally! (neat!) display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64) // init done // Show image buffer on the display hardware. // Since the buffer is intialized with an Adafruit splashscreen // internally, this will display the splashscreen. display.display(); delay(2000); // Clear the buffer. display.clearDisplay(); // text display tests display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Informationstechnik-"); display.println("Labor:"); display.println(); display.println("3D Keramik Druck"); display.display(); delay(3000); display.clearDisplay(); Serial.println("Set-up OLED display"); } ///////////////////////////////////////////////////////////////// // // impRelay() // implement relay // ///////////////////////////////////////////////////////////////// void impRelay() { pinMode(Relais, OUTPUT); digitalWrite(Relais, HIGH); Serial.println("Set-up relays"); } ///////////////////////////////////////////////////////////////// // // impDrehschalter() // implement Drehschalter/Poti // ///////////////////////////////////////////////////////////////// void impDrehschalter() { // evtl. falls Tausch auf Joystick } ///////////////////////////////////////////////////////////////// // // impProximity() // implement proximity sensor // ///////////////////////////////////////////////////////////////// void impProximity() { pinMode(proximitySensor, INPUT_PULLUP); Serial.println("Set-up proximity sensor"); } ///////////////////////////////////////////////////////////////// // // setup() // initialize SD card reader, header, stopwatch, display, // relay, Drehschalter/Poti and sensors // ///////////////////////////////////////////////////////////////// void setup() { Serial.begin(115200); // serial communication on impSD(); // initialize sd card impHeader(); // initialize header for .csv file impStoppuhr(); // initialize stopwatch impOLED(); // initialize OLED display impRelay(); // initialize relay impDrehschalter(); // initialize poti impProximity(); // initialize proximity sensor impDS18B20(); // initialize temperature sensor Serial.println(); Serial.println("SET-UP DONE."); Serial.println(); } ///////////////////////////////////////////////////////////////// // // Loop: // Reading sensors, print to sd, control relay // ///////////////////////////////////////////////////////////////// void loop() { if(digitalRead(proximitySensor) == LOW) { Serial.println("New print starts -> impSD, impHeader, impStoppuhr"); dataFile.close(); Serial.println(); Serial.println("File closed"); delay(1000); impSD(); // initialize sd card impHeader(); // initialize header for .csv file impStoppuhr(); // initialize stopwatch while(digitalRead(proximitySensor) != LOW) { Serial.print("Loop for new meassurement"); // Delay between every meassurement because of slow sensor delay(2000); // Get time unsigned long zeit = getTime(); // Get pressure value from Cerabar PMC21/SKU237545 int pressure = getPressure(); // Get temperatur value form DS18B20 Isttemperatur = getTemperature(); // Control temperature relay SolltemperaturGlobal = regelung(); // Print to seriell monitor seriellAusgabe(); // Print to OLED display OLED(); // Write data to sd card depends how modulo is set if(zaehlvariable%2) { schreibeMessung(zeit, pressure, Isttemperatur); } // // Anzahl der Durchläufe bis file closed // if(i >= 10) // { // dataFile.close(); // Serial.println(); // Serial.println("File closed"); // while(1); // } // i++; // varible to count every loop -> is needed to write not every messurement to sd card zaehlvariable++; } } else { Serial.println("Waiting for new meassurement"); delay(500); // As short as possible } } ///////////////////////////////////////////////////////////////// // // schreibeMessung() // Write messurement values to SD card // ///////////////////////////////////////////////////////////////// void schreibeMessung(unsigned long vergZeit, float Pressure, int temperature) { dataFile.print(vergZeit); dataFile.print(';'); dataFile.print(Pressure); dataFile.print(';'); dataFile.print(temperature); dataFile.println(); } ///////////////////////////////////////////////////////////////// // // seriellAusgabe() // Print to serial monitor // ///////////////////////////////////////////////////////////////// int seriellAusgabe() { Serial.println(""); Serial.print("Isttemperatur: "); Serial.print(Isttemperatur); // Why "byIndex"? // You can have more than one DS18B20 on the same bus. // 0 refers to the first IC on the wire Serial.println(" Grad C"); Serial.println(""); Serial.print("Solltemperatur: "); Serial.print(SolltemperaturGlobal); // Why "byIndex"? Serial.println(" Grad C"); Serial.println(""); // // print out the values Drehschalter // // /*Serial.print("vertical: "); // Serial.print(vertical,DEC); // //Serial.print(" horizontal: "); // //Serial.print(horizontal,DEC); // //Serial.print(" select: "); // //if(select == HIGH) // // Serial.println("not pressed"); // //else // // Serial.println("PRESSED!");*/ // Serial.print("Analoger Wert: "); // für Poti // Serial.print(Spannung); // Serial.println(""); // Serial.print("Relais aktiv "); // Serial.print(Relais); // Serial.println(""); } ///////////////////////////////////////////////////////////////// // // OLED() // Print to OLED display // ///////////////////////////////////////////////////////////////// int OLED() { display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.print("Isttemperatur: "); display.println(); display.print(Isttemperatur); display.println(" \tC"); display.print("Solltemperatur: "); display.println(); display.print(SolltemperaturGlobal); display.println(" \tC"); display.display(); delay(2000); display.clearDisplay(); } ///////////////////////////////////////////////////////////////// // // Zeit() // get the time // ///////////////////////////////////////////////////////////////// unsigned long getTime() { vergangeneZeit = millis() - startzeit; vergangeneZeit = vergangeneZeit/60000; Serial.println(); Serial.print("Messung nach: "); Serial.print(vergangeneZeit); Serial.print(" min"); Serial.println(); return vergangeneZeit; } ///////////////////////////////////////////////////////////////// // // pressure() // Read pressure from Cerabar PMC21/SKU237545 via analog in // ///////////////////////////////////////////////////////////////// int getPressure() { // *** Cerabar PMC21 *** // inputVariable0 = 0; // This value must be cleared before next reading // // // Lesen // inputVariable1 = analogRead(analogPin); // inputVariable0 = inputVariable0 + inputVariable1; // inputVariable0 = (inputVariable0 - 2048) / 818 ; // // // Ausgabe auf Konsole // Serial.print("Pressure: "); // Serial.print(inputVariable0); // Serial.println(" bar"); // // return inputVariable0; // *** SKU237545 *** // Reading pressure sensor via analog input -> 12 bit AD converter (4096) int SensorVal = analogRead(analogPin); // Calcaulate the value of AD converter to voltage float Voltage = (SensorVal/4096.0)*3.3; // 0 bar = 215 (sensorVal) // 6 bar = 2048 (sensorVal) // 12 bar = 4096 (sensorVal) // Calculate the value of the voltage to bar float Pressure = (Voltage-0.18)*4.65; return Pressure; } ///////////////////////////////////////////////////////////////// // // temperature() // Read temperature from DS18B20 via analog in // ///////////////////////////////////////////////////////////////// int getTemperature() { if ( !ds.search(addr)) { Serial.println("No more addresses."); Serial.println(); ds.reset_search(); delay(250); // return; } // Serial.print("ROM ="); for( i = 0; i < 8; i++) { // Serial.write(' '); // Serial.print(addr[i], HEX); } if (OneWire::crc8(addr, 7) != addr[7]) { // Serial.println("CRC is not valid!"); // return; } // Serial.println(); // the first ROM byte indicates which chip switch (addr[0]) { case 0x10: // Serial.println(" Chip = DS18S20"); // or old DS1820 type_s = 1; break; case 0x28: // Serial.println(" Chip = DS18B20"); type_s = 0; break; case 0x22: // Serial.println(" Chip = DS1822"); type_s = 0; break; default: Serial.println("Device is not a DS18x20 family device."); // return; } ds.reset(); ds.select(addr); ds.write(0x44, 1); // start conversion, with parasite power on at the end delay(1000); // maybe 750ms is enough, maybe not // we might do a ds.depower() here, but the reset will take care of it. present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad // Serial.print(" Data = "); // Serial.print(present, HEX); // Serial.print(" "); for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); // Serial.print(data[i], HEX); // Serial.print(" "); } // Serial.print(" CRC="); // Serial.print(OneWire::crc8(data, 8), HEX); // Serial.println(); // Convert the data to actual temperature // because the result is a 16 bit signed integer, it should // be stored to an "int16_t" type, which is always 16 bits // even when compiled on a 32 bit processor. int16_t raw = (data[1] << 8) | data[0]; if (type_s) { raw = raw << 3; // 9 bit resolution default if (data[7] == 0x10) { // "count remain" gives full 12 bit resolution raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60); // at lower res, the low bits are undefined, so let's zero them if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms //// default is 12 bit resolution, 750 ms conversion time } Temp = (float)raw / 16.0; return Temp; } ///////////////////////////////////////////////////////////////// // // Regelung() // control the temperature // ///////////////////////////////////////////////////////////////// int regelung() { Spannung = analogRead(S); // will be 0-1023 Solltemperatur = Spannung / 58; // in Grad °C if (Solltemperatur > Isttemperatur ) { digitalWrite(Relais, LOW); // Laufen lassen bis Temperatur IST / SOLL gleich } if (Solltemperatur <= Isttemperatur + 2) // heizen erfolgreich { digitalWrite(Relais, HIGH); // Heizung aus } return Solltemperatur; } |
Mit Unterstützung von Prof. J. Walter | Wintersemester 2017/18 |