#include #include #include "driver/ledc.h" #include "EspMQTTClient.h" // https://github.com/plapointe6/EspMQTTClient // Data wire is plugged into port 2 on the Arduino #define ONE_WIRE_BUS 4 #define TEMPERATURE_PRECISION 9 // Lower resolution // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature TemperatureSensors(&oneWire); int numberOfDevices; // Number of temperature devices found DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address // new MQTT definiions //----------------------------------------------- EspMQTTClient MQTTclient( "", // SSID -> Teltroinika RUT230 "", // WiFi Password -> Teltroinika RUT230 "", // MQTT Broker server ip -> Venus.OS "", // Can be omitted if not needed "", // Can be omitted if not needed "Refrigerator", // Client name that uniquely identify your device 1883 // The MQTT port, default to 1883. this line can be omitted ); static int iMQTT_Input = 0; // temperatues from the DALLAS DS18B20 sensors // prepared for up to 5 sensors //----------------------------------------------- static float fTemperature_Ch0 = 0.00; static float fTemperature_Ch1 = 0.00; static float fTemperature_Ch2 = 0.00; static float fTemperature_Ch3 = 0.00; static float fTemperature_Ch4 = 0.00; // sensor addresses //----------------------------------------------- static uint8_t* uint8_DeviceAddress_Ch0 = 0; //Pointer! static uint8_t* uint8_DeviceAddress_Ch1 = 0; //Pointer! static uint8_t* uint8_DeviceAddress_Ch2 = 0; //Pointer! static uint8_t* uint8_DeviceAddress_Ch3 = 0; //Pointer! static uint8_t* uint8_DeviceAddress_Ch4 = 0; //Pointer! // temperatue attached to the PDI //----------------------------------------------- static float fTemperature_for_Amplifier = 0.00; // Outputs to the PWM vents // need 4 wire vents with dedicated PWM input //----------------------------------------------- static int iPWM_Value_Ch0 = 0; static int iPWM_Value_Ch1 = 0; static int iPWM_Value_Ch2 = 0; // PWM setup //----------------------------------------------- static float fNoSpeedAt = 26.00; // no rotation below this temperature static float fFullSpeedAt = 45.00; // full speed temperature static float fOffset_Ch1 = 5.00; // temperature offset in °K for channel 1 based to channel 0 static float fOffset_Ch2 = 7.00; // temperature offset in °K for channel 2 based to channel 0 static float fStartPercentage = 40.00; // start PWM percentage, to avois stalling static int iResolution = 8; // number of bits, e.g. 8 means output between 0~255 static int iWaitTime = 30; // time in seconds to wait before changing ON, e.g. 5 seconds static int iFollowUpTime_Set = 300; // let the vent run longer before switching OFF, e.g. 30 second static int iPWMfrequency = 25000; // frequency of the PWM regulator static int iPIN_PWM_Ch0 = 5; // GPIO PIN attached to PWM Channel 0 static int iPIN_PWM_Ch1 = 18; // GPIO PIN attached to PWM Channel 1 static int iPIN_PWM_Ch2 = 19; // GPIO PIN attached to PWM Channel 2 static int iPIN_LED = 2; // GPIO PIN attached to status LED static int iBlink_Faktor = 4; // speed of the status LED, higher value -> slower blinking static int iPowerMode = 0; // use all vents at once // mmore PWM variables used in program // but calculated automatically //----------------------------------------------- static int iMaxPWM = 0; // is calculated from iResolution static int iMinPWM = 0; // ic calculated from iResolution & fStartPercentage static int iPWMperDegree = 0; // is calculated from all above // Setup tacho serviellence //----------------------------------------------- static int iPIN_Tacho_Ch0 = 13; static int iTacho_Counter_Ch0 = 0; static int iTacho_Value_Ch0 = 0; static int iPIN_Tacho_Ch1 = 12; static int iTacho_Counter_Ch1 = 0; static int iTacho_Value_Ch1 = 0; static int iPIN_Tacho_Ch2 = 14; static int iTacho_Counter_Ch2 = 0; static int iTacho_Value_Ch2 = 0; static int iPIN_Tacho_Ch3 = 27; static int iTacho_Counter_Ch3 = 0; static int iTacho_Value_Ch3 = 0; static int iPIN_Tacho_Ch4 = 26; static int iTacho_Counter_Ch4 = 0; static int iTacho_Value_Ch4 = 0; static int iPIN_Tacho_Ch5 = 25; static int iTacho_Counter_Ch5 = 0; static int iTacho_Value_Ch5 = 0; const bool bSerial_debug = true; // This function is called once everything is connected (Wifi and MQTT) // WARNING : YOU MUST IMPLEMENT IT IF YOU USE EspMQTTClient //--------------------------------------------------------------------------- void onConnectionEstablished() { static float fTemp = 0.0; static int iTemp = 0; // Subscribe to the input signals //--------------------------------------------- MQTTclient.subscribe("refrigerator/input/no_Speed_below", [](const String & payload) { if(bSerial_debug) { Serial.print("received command : "); Serial.println(payload); } fTemp = payload.toFloat(); if((15.00 <= fTemp) && (fTemp <= (fFullSpeedAt-1.00))) { fNoSpeedAt = payload.toFloat(); // define the gradient between temperature and speed // e.g. (255 - 38) / (45.0 - 25.0) = 10,8 points/°K //----------------------------------- iPWMperDegree = ((iMaxPWM - iMinPWM) / (fFullSpeedAt - fNoSpeedAt)); // inform the developer via serial output //----------------------------------- if(bSerial_debug) { Serial.print("PWM per degree is set to: "); Serial.print(iPWMperDegree, DEC); Serial.println(); } // update the setup variables //----------------------------------- MQTTclient.publish("refrigerator/output/no_Speed_below", String(fNoSpeedAt)); MQTTclient.publish("refrigerator/output/PWM_per_Degree", String(iPWMperDegree)); } else { MQTTclient.publish("refrigerator/output/no_Speed_below", String(fNoSpeedAt)); } }); MQTTclient.subscribe("refrigerator/input/Powermode", [](const String & payload) { if(bSerial_debug) { Serial.print("received command : "); Serial.println(payload); } iTemp = payload.toFloat(); if((0 <= iTemp) && (iTemp <= 1)) { iPowerMode = payload.toInt(); if(bSerial_debug) { Serial.print("Powermode is set to: "); Serial.print(iPowerMode, DEC); Serial.println(); } } else { MQTTclient.publish("refrigerator/output/Powermode", String(iPowerMode)); } }); /* // Subscribe to "mytopic/wildcardtest/#" and display received message to Serial MQTTclient.subscribe("mytopic/wildcardtest/#", [](const String & topic, const String & payload) { Serial.println("(From wildcard) topic: " + topic + ", payload: " + payload); }); // Publish a message to "mytopic/test" MQTTclient.publish("mytopic/test", "This is a message"); // You can activate the retain flag by setting the third parameter to true */ MQTTclient.publish("refrigerator/output/no_Speed_below", String(fNoSpeedAt)); // You can activate the retain flag by setting the third parameter to true MQTTclient.publish("refrigerator/output/Powermode", String(iPowerMode)); // You can activate the retain flag by setting the third parameter to true } // end of // // void onConnectionEstablished() //########################################################################### // function to print a device address //--------------------------------------------------------------------------- void printAddress(DeviceAddress deviceAddress) { for (uint8_t i = 0; i < 8; i++) { if (deviceAddress[i] < 16) Serial.print("0"); Serial.print(deviceAddress[i], HEX); } } // end of // // void printAddress() //########################################################################### // function to print the temperature for a device //--------------------------------------------------------------------------- void printTemperature(DeviceAddress deviceAddress) { float tempC = TemperatureSensors.getTempC(deviceAddress); if (tempC == DEVICE_DISCONNECTED_C) { Serial.println("Error: Could not read temperature data"); return; } Serial.print("Temp C: "); Serial.print(tempC); // Serial.print(" Temp F: "); // Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit } // end of // // void printTemperature() //########################################################################### // interrupts //--------------------------------------------------------------------------- // Tacho channel 0 //----------------------------------------------- void Tacho_Counter_Ch0() { iTacho_Counter_Ch0++; } // Tacho channel 1 //----------------------------------------------- void Tacho_Counter_Ch1() { iTacho_Counter_Ch1++; } // Tacho channel 2 //----------------------------------------------- void Tacho_Counter_Ch2() { iTacho_Counter_Ch2++; } // Tacho channel 3 //----------------------------------------------- void Tacho_Counter_Ch3() { iTacho_Counter_Ch3++; } // Tacho channel 4 //----------------------------------------------- void Tacho_Counter_Ch4() { iTacho_Counter_Ch4++; } // Tacho channel 5 //----------------------------------------------- void Tacho_Counter_Ch5() { iTacho_Counter_Ch5++; } // end of // // interrupts //########################################################################### //########################################################################### // // startup // //########################################################################### void setup(void) { // start serial port // slowly, very slowly: 9600baud //----------------------------------- Serial.begin(115200); // introduce myself //----------------------------------- Serial.println("Paulette.die-oswalds.net - Kühlschranküberwachung & Lüfterregelung"); // Establish WiFi connection //----------------------------------- /* WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.println("\nConnecting to WiFi Network .."); while(WiFi.status() != WL_CONNECTED){ Serial.print("."); delay(100); } Serial.println("\nConnected to the WiFi network"); Serial.print("Local ESP32 IP: "); Serial.println(WiFi.localIP()); */ // Optional functionalities of EspMQTTClient // MQTTclient.enableDebuggingMessages(); // Enable debugging messages sent to serial output MQTTclient.enableHTTPWebUpdater(); // Enable the web updater. User and password default to values of MQTTUsername and MQTTPassword. These can be overridded with enableHTTPWebUpdater("user", "password"). // MQTTclient.enableOTA(); // Enable OTA (Over The Air) updates. Password defaults to MQTTPassword. Port is the default OTA port. Can be overridden with enableOTA("password", port). // MQTTclient.enableLastWillMessage("TestClient/lastwill", "I am going offline"); // You can activate the retain flag by setting the third parameter to true // Start up the library //----------------------------------- TemperatureSensors.begin(); // Grab a count of devices on the wire //----------------------------------- numberOfDevices = TemperatureSensors.getDeviceCount(); // locate devices on the bus //----------------------------------- Serial.print("Locating devices..."); Serial.print("Found "); Serial.print(numberOfDevices, DEC); Serial.println(" devices."); // report parasite power requirements Serial.print("Parasite power is: "); if (TemperatureSensors.isParasitePowerMode()) Serial.println("ON"); else Serial.println("OFF"); // Loop through each device, print out address for (int i = 0; i < numberOfDevices; i++) { // Search the wire for address if (TemperatureSensors.getAddress(tempDeviceAddress, i)) { Serial.print("Found device "); Serial.print(i, DEC); Serial.print(" with address: "); printAddress(tempDeviceAddress); Serial.println(); switch (i) { case 0: uint8_DeviceAddress_Ch0 = tempDeviceAddress; break; case 1: uint8_DeviceAddress_Ch1 = tempDeviceAddress; break; case 2: uint8_DeviceAddress_Ch2 = tempDeviceAddress; break; case 3: uint8_DeviceAddress_Ch3 = tempDeviceAddress; break; case 4: uint8_DeviceAddress_Ch4 = tempDeviceAddress; break; } Serial.print("Setting resolution to "); Serial.println(TEMPERATURE_PRECISION, DEC); // set the resolution to TEMPERATURE_PRECISION bit (Each Dallas/Maxim device is capable of several different resolutions) TemperatureSensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION); Serial.print("Resolution actually set to: "); Serial.print(TemperatureSensors.getResolution(tempDeviceAddress), DEC); Serial.println(); } else { Serial.print("Found ghost device at "); Serial.print(i, DEC); Serial.print(" but could not detect address. Check power and cabling"); } } // 2023.07.01 cOswald // added PWM Support //--------------------------------------------- // setup PWM controllers and attach GPIOs //----------------------------------- ledcSetup(0, iPWMfrequency, iResolution); // channel, frequency, resolution ledcAttachPin(iPIN_PWM_Ch0, 0); // GPIO pin, channel ledcSetup(1, iPWMfrequency, iResolution); // channel, frequency, resolution ledcAttachPin(iPIN_PWM_Ch1, 1); // GPIO pin, channel ledcSetup(2, iPWMfrequency, iResolution); // channel, frequency, resolution ledcAttachPin(iPIN_PWM_Ch2, 2); // GPIO pin, channel // calculate maximun PWM output value // e.g. (2^8)-1 = 255 //----------------------------------- iMaxPWM = (pow(2, iResolution))-1; // calculate the minimum PWM output value // e.g. 255 * 15.00/100 = 38 //----------------------------------- iMinPWM = (float)iMaxPWM * (fStartPercentage/100); // define the gradient between temperature and speed // e.g. (255 - 38) / (45.0 - 25.0) = 10,8 points/°K //----------------------------------- iPWMperDegree = ((iMaxPWM - iMinPWM) / (fFullSpeedAt - fNoSpeedAt)); // inform the developer via serial output //----------------------------------- Serial.print("PWM resolution is set to: "); Serial.print(iMaxPWM, DEC); Serial.println(); Serial.print("minimun PWM is set to: "); Serial.print(iMinPWM, DEC); Serial.println(); Serial.print("PWM per degree is set to: "); Serial.print(iPWMperDegree, DEC); Serial.println(); // Set PinMode for Status LED //----------------------------------- // ledcSetup(3, 10000, 8); // channel, frequency, resolution // ledcAttachPin(iPIN_LED, 3); // GPIO pin, channel pinMode( iPIN_LED, OUTPUT); // Setup Tachosignals // attach each input to a interrupt //----------------------------------- pinMode( iPIN_Tacho_Ch0, INPUT); attachInterrupt(digitalPinToInterrupt(iPIN_Tacho_Ch0), Tacho_Counter_Ch0, RISING); pinMode( iPIN_Tacho_Ch1, INPUT); attachInterrupt(digitalPinToInterrupt(iPIN_Tacho_Ch1), Tacho_Counter_Ch1, RISING); pinMode( iPIN_Tacho_Ch2, INPUT); attachInterrupt(digitalPinToInterrupt(iPIN_Tacho_Ch2), Tacho_Counter_Ch2, RISING); pinMode( iPIN_Tacho_Ch3, INPUT); attachInterrupt(digitalPinToInterrupt(iPIN_Tacho_Ch3), Tacho_Counter_Ch3, RISING); pinMode( iPIN_Tacho_Ch4, INPUT); attachInterrupt(digitalPinToInterrupt(iPIN_Tacho_Ch4), Tacho_Counter_Ch4, RISING); pinMode( iPIN_Tacho_Ch5, INPUT); attachInterrupt(digitalPinToInterrupt(iPIN_Tacho_Ch5), Tacho_Counter_Ch5, RISING); Serial.println("---> END OF SETUP <---"); delay(10000); } // end of // // startup() //########################################################################### //########################################################################### // // main loop // //########################################################################### //--------------------------------------------------------------------------- void loop(void) { // instead of using a blocking // delay() // read the actual time and come back // after a while //----------------------------------- static auto next_read = millis(); static auto next_setPWM = millis(); static auto next_send_MQTT = millis(); static auto next_blink_off = millis(); static auto next_blink_on = millis(); static auto next_blur = millis(); static bool bVents_ON = false; static bool bVents_FollowUpTimeRuns = false; static int iFollowUpTime_Ran = 0; static int iStatusLED_bluring = 0; static bool bMQTTInputsBuilt = false; static bool bStatusLED_UP_DOWN = false; // loop for MQTT client MQTTclient.loop(); // wait until WiFi and MQTT connections are // established //--------------------------------------------- if ((bMQTTInputsBuilt == false) && (MQTTclient.isConnected())) { // publish setup //--------------------------------- MQTTclient.publish("refrigerator/output/full_Speed_at", String(fFullSpeedAt)); MQTTclient.publish("refrigerator/output/max_PWM", String(iMaxPWM)); MQTTclient.publish("refrigerator/output/Min_PWM", String(iMinPWM)); MQTTclient.publish("refrigerator/output/PWM_per_Degree", String(iPWMperDegree)); MQTTclient.publish("refrigerator/output/PWM_Waittime", String(iWaitTime)); MQTTclient.publish("refrigerator/output/Vents_FollowUpTimeRuns", String(bVents_FollowUpTimeRuns)); // Publish input variables //--------------------------------- MQTTclient.publish("refrigerator/input/no_Speed_below", String(fNoSpeedAt)); // You can activate the retain flag by setting the third parameter to true MQTTclient.publish("refrigerator/input/Powermode", String(iPowerMode)); // You can activate the retain flag by setting the third parameter to true // Go and never come back again here //--------------------------------- bMQTTInputsBuilt = true; } // switch status LED ON if ( millis() > next_blink_on) { digitalWrite( iPIN_LED, HIGH); // calculate next time for manipulate status LED //--------------------------------- next_blink_off = millis() + (iMaxPWM * iBlink_Faktor) + 50 - (iPWM_Value_Ch0 * iBlink_Faktor); next_blink_on = millis() + (iMaxPWM * iBlink_Faktor * 2) + 50 - (iPWM_Value_Ch0 * iBlink_Faktor * 2); } // schwich status LED ON if ( millis() > next_blink_off) { digitalWrite( iPIN_LED, LOW); // calculate next time for manipulate status LED //--------------------------------- next_blink_off = millis() + (iMaxPWM * iBlink_Faktor * 2) + 50 - (iPWM_Value_Ch0 * iBlink_Faktor * 2); next_blink_on = millis() + (iMaxPWM * iBlink_Faktor) + 50 - (iPWM_Value_Ch0 * iBlink_Faktor); } /* // Blur the status LED if ( millis() > next_blur ) { next_blur = millis() + 1; if ((iStatusLED_bluring < 255) && (bStatusLED_UP_DOWN == false)) { iStatusLED_bluring++; } if ((iStatusLED_bluring > 10) && (bStatusLED_UP_DOWN == true)) { iStatusLED_bluring--; } if (iStatusLED_bluring >= 255 ) { iStatusLED_bluring = 255; bStatusLED_UP_DOWN = true; } if (iStatusLED_bluring <= 10 ) { iStatusLED_bluring = 10; bStatusLED_UP_DOWN = false; } ledcWrite(3, iStatusLED_bluring); } */ // read sensors // time between reads: 1s // // and everything else that should // be done every second // - read the tacho counters // - count the followup time //----------------------------------- if( millis() > next_read) { next_read += 1000; // e.g. 1s // call sensors.requestTemperatures() to issue a global temperature // request to all devices on the bus if (bSerial_debug) { Serial.print("Requesting temperatures..."); } TemperatureSensors.requestTemperatures(); // Send the command to get temperatures if (bSerial_debug) { Serial.println("DONE"); } // Loop through each device, print out temperature data for (int i = 0; i < numberOfDevices; i++) { // Search the wire for address if (TemperatureSensors.getAddress(tempDeviceAddress, i)) { // Output the device ID if (bSerial_debug) { Serial.print("Temperature for device: "); Serial.println(i, DEC); // It responds almost immediately. Let's print out the data printTemperature(tempDeviceAddress); // Use a simple function to print out the data } // set appropiate Temerature per sensor switch(i) { case 0: fTemperature_Ch0 = TemperatureSensors.getTempC(tempDeviceAddress); break; case 1: fTemperature_Ch1 = TemperatureSensors.getTempC(tempDeviceAddress); break; case 2: fTemperature_Ch2 = TemperatureSensors.getTempC(tempDeviceAddress); break; case 3: fTemperature_Ch3 = TemperatureSensors.getTempC(tempDeviceAddress); break; case 4: fTemperature_Ch4 = TemperatureSensors.getTempC(tempDeviceAddress); break; } } //else ghost device! Check your power requirements and cabling } // end FOR // read the tacho signals and reset the counters //--------------------------------- iTacho_Value_Ch0 = iTacho_Counter_Ch0; iTacho_Counter_Ch0 = 0; iTacho_Value_Ch1 = iTacho_Counter_Ch1; iTacho_Counter_Ch1 = 0; iTacho_Value_Ch2 = iTacho_Counter_Ch2; iTacho_Counter_Ch2 = 0; iTacho_Value_Ch3 = iTacho_Counter_Ch3; iTacho_Counter_Ch3 = 0; iTacho_Value_Ch4 = iTacho_Counter_Ch4; iTacho_Counter_Ch4 = 0; iTacho_Value_Ch5 = iTacho_Counter_Ch5; iTacho_Counter_Ch5 = 0; if (bSerial_debug) { Serial.print("Tacho Channel 0: "); Serial.println(iTacho_Value_Ch0, DEC); Serial.print("Tacho Channel 1: "); Serial.println(iTacho_Value_Ch1, DEC); Serial.print("Tacho Channel 2: "); Serial.println(iTacho_Value_Ch2, DEC); Serial.print("Tacho Channel 3: "); Serial.println(iTacho_Value_Ch3, DEC); Serial.print("Tacho Channel 4: "); Serial.println(iTacho_Value_Ch4, DEC); Serial.print("Tacho Channel 5: "); Serial.println(iTacho_Value_Ch5, DEC); } // count the followup time //--------------------------------- if (bVents_FollowUpTimeRuns == true) { iFollowUpTime_Ran++; } else { iFollowUpTime_Ran = 0; } // and switch off vents after // followup timer ran out //--------------------------------- if (iFollowUpTime_Ran >= iFollowUpTime_Set) { bVents_ON = false ; } } // end sensor read, 1 second timer if( millis() > next_setPWM ) { // set the interval for looping //--------------------------------- next_setPWM += (iWaitTime * 1000); // e.g. 3s // for the beginnig fixed Sensor Channel assignment //--------------------------------- fTemperature_for_Amplifier = fTemperature_Ch0; // calulate the PWMs // 0 = no output // 255 = full throttle //--------------------------------- // temperature below starting point //--------------------------------- if (fTemperature_for_Amplifier < fNoSpeedAt) { // wait til the followup time // is ran out // ---------------------------------- if (bVents_ON == false) { iPWM_Value_Ch0 = 0; bVents_FollowUpTimeRuns = false; } else { bVents_FollowUpTimeRuns = true; } } else { // temeprature above maximum point //--------------------------------- if((((fTemperature_for_Amplifier - fNoSpeedAt) * iPWMperDegree) + iMinPWM) >= iMaxPWM) { iPWM_Value_Ch0 = iMaxPWM; bVents_ON = true; bVents_FollowUpTimeRuns = false; iFollowUpTime_Ran = 0; } // temerature within controlled area //--------------------------------- else { iPWM_Value_Ch0 = (((fTemperature_for_Amplifier - fNoSpeedAt) * iPWMperDegree) + iMinPWM); bVents_ON = true; bVents_FollowUpTimeRuns = false; iFollowUpTime_Ran = 0; } } // add second channel if channel 0 cannot get control the temperature // or PowerMode is active //--------------------------------- if ((fTemperature_for_Amplifier < fNoSpeedAt + fOffset_Ch1) && (iPowerMode == 0)) { iPWM_Value_Ch1 = 0; } else { iPWM_Value_Ch1 = iPWM_Value_Ch0; } // add third channel if channel 0 & 1 cannot get control the temperature // or PowerMode is active //--------------------------------- if ((fTemperature_for_Amplifier < fNoSpeedAt + fOffset_Ch2) && (iPowerMode == 0)) { iPWM_Value_Ch2 = 0; } else { iPWM_Value_Ch2 = iPWM_Value_Ch0; } // write the PWM port //----------------------------------- ledcWrite(0, iPWM_Value_Ch0); ledcWrite(1, iPWM_Value_Ch1); ledcWrite(2, iPWM_Value_Ch2); // inform the user //----------------------------------- if (bSerial_debug) { Serial.print("PWM Ch0: "); Serial.println(iPWM_Value_Ch0, DEC); Serial.print("PWM Ch1: "); Serial.println(iPWM_Value_Ch1, DEC); Serial.print("PWM Ch2: "); Serial.println(iPWM_Value_Ch2, DEC); Serial.println("---"); } } // end setting PWM if ((millis() > next_send_MQTT) && (bMQTTInputsBuilt == true)) { next_send_MQTT += 1000; MQTTclient.publish("refrigerator/output/Vents_ON", String(bVents_ON)); MQTTclient.publish("refrigerator/output/FollowUpTime_Ran", String(iFollowUpTime_Ran)); MQTTclient.publish("refrigerator/output/temperature_Ch0", String(fTemperature_Ch0)); MQTTclient.publish("refrigerator/output/temperature_Ch1", String(fTemperature_Ch1)); MQTTclient.publish("refrigerator/output/temperature_Ch2", String(fTemperature_Ch2)); MQTTclient.publish("refrigerator/output/temperature_Ch3", String(fTemperature_Ch3)); MQTTclient.publish("refrigerator/output/temperature_Ch4", String(fTemperature_Ch4)); MQTTclient.publish("refrigerator/output/PWM_Ch0", String(iPWM_Value_Ch0)); MQTTclient.publish("refrigerator/output/PWM_Ch1", String(iPWM_Value_Ch1)); MQTTclient.publish("refrigerator/output/PWM_Ch2", String(iPWM_Value_Ch2)); MQTTclient.publish("refrigerator/output/Tacho_Value_Ch0", String(iTacho_Value_Ch0)); MQTTclient.publish("refrigerator/output/Tacho_Value_Ch1", String(iTacho_Value_Ch1)); MQTTclient.publish("refrigerator/output/Tacho_Value_Ch2", String(iTacho_Value_Ch2)); MQTTclient.publish("refrigerator/output/Tacho_Value_Ch3", String(iTacho_Value_Ch3)); MQTTclient.publish("refrigerator/output/Tacho_Value_Ch4", String(iTacho_Value_Ch4)); MQTTclient.publish("refrigerator/output/Tacho_Value_Ch5", String(iTacho_Value_Ch5)); } } // end of // // loop() //###########################################################################