Ok, I thought copying my complete code just into here will not be nice readable, but ok.
I do have a pull-up resistor, but 1k (as I have read somewhere one person almost solved the issues with reducing it from 4k7 to 1k).
Ok, here my code:
I know, normally I only put parts of the code, but for me it does not make sense because its all connected together and I maybe, as a beginner, leave out an essential part of the code, where you say: "Ah, but if you also doing display stuff, that consumes too much time" or similar, so therefore all my code:
/****************** Include Files ******************************************************/
// "" => Looks in the same directory as the 'C' file I compile
// <> => Looks in the library paths
// Arduino
#include <Arduino.h>
// OLED-Display
#include <U8x8lib.h>
// 1-wire
#include <OneWire.h>
#include <DallasTemperature.h>
// MCP3221
#include "MCP3221.h"
/****************** Constants **********************************************************/
// VCC voltage reference: Used for MCP3221 and internal Arduino ADC
const float VCC_VREF_V = 5.02; // Voltage reference ( = VCC) for in units [V]
// 1-wire
#define ENABLE_SEARCH_ADDRESS // Use the ENABLE_SEARCH_ADDRESS to gather all the unique addresses of the sensors. Comment it out if you don't want to use it.
#define ENABLE_READ_BACK_RESOLUTION // Use the ENABLE_READ_BACK_RESOLUTION to confirm that the right resolution has been set.
#define ONE_WIRE_BUS 2 // Data wire is plugged into port 2 on the Arduino; Make sure a pull-up resistor (e.g. 1k) is connected (so from Data to VCC)
#define TEMPERATURE_PRECISION 12 // 12 is maximum but slower.
#define NUM_OW_SENSORS 8 // the number of DS18B20 sensors on the 1-Wire bus.
// Array to hold device addresses. The address is a group of 8 bytes, and there are 'NUM_OW_SENSORS' of those groups of 8 bytes. The "DeviceAddress" type already defined as a group of 8 bytes.
/*
// Sensor data for small cooling box
const DeviceAddress sensor_address[NUM_OW_SENSORS] =
{
{ 0x28, 0x41, 0x6B, 0x07, 0xD6, 0x01, 0x3C, 0xAA }, // S01_ColdIntoPWT = TempSensors_Temps[0]
{ 0x28, 0x4F, 0xEA, 0x07, 0xD6, 0x01, 0x3C, 0xBF }, // S02_ColdFromPWT = TempSensors_Temps[1]
{ 0x28, 0xCF, 0xC2, 0x07, 0xD6, 0x01, 0x3C, 0x93 }, // S03_HotFromCompr = TempSensors_Temps[2]
{ 0x28, 0xD4, 0x45, 0x07, 0xD6, 0x01, 0x3C, 0xAA }, // S04_HotFromPWT = TempSensors_Temps[3]
{ 0x28, 0xC9, 0x05, 0x07, 0xD6, 0x01, 0x3C, 0x52 }, // S05_AmbientOfUnit = TempSensors_Temps[4]
{ 0x28, 0xAA, 0xD5, 0xAC, 0x1D, 0x13, 0x02, 0xE5 }, // S06_InsideFluid = TempSensors_Temps[5]
{ 0x28, 0xAA, 0xC1, 0xDD, 0x1D, 0x13, 0x02, 0xA1 }, // S07_CoolBoxS01 = TempSensors_Temps[6]
{ 0x28, 0xAA, 0xFA, 0xE0, 0x1D, 0x13, 0x02, 0x80 }, // S08_CoolBoxS02 = TempSensors_Temps[7]
};
*/
// Sensor data for big cooling box
const DeviceAddress sensor_address[NUM_OW_SENSORS] =
{
{ 0x28, 0x41, 0x6B, 0x07, 0xD6, 0x01, 0x3C, 0xAA }, // S01_ColdIntoPWT = TempSensors_Temps[0]
{ 0x28, 0x4F, 0xEA, 0x07, 0xD6, 0x01, 0x3C, 0xBF }, // S02_ColdFromPWT = TempSensors_Temps[1]
{ 0x28, 0xCF, 0xC2, 0x07, 0xD6, 0x01, 0x3C, 0x93 }, // S03_HotFromCompr = TempSensors_Temps[2]
{ 0x28, 0xD4, 0x45, 0x07, 0xD6, 0x01, 0x3C, 0xAA }, // S04_HotFromPWT = TempSensors_Temps[3]
{ 0x28, 0xC9, 0x05, 0x07, 0xD6, 0x01, 0x3C, 0x52 }, // S05_AmbientOfUnit = TempSensors_Temps[4]
{ 0x28, 0xAA, 0xD5, 0xAC, 0x1D, 0x13, 0x02, 0xE5 }, // S06_InsideFluid = TempSensors_Temps[5]
{ 0x28, 0xD4, 0xD1, 0xEA, 0x32, 0x14, 0x01, 0xDF }, // S07_CoolBoxS01 = TempSensors_Temps[6]
{ 0x28, 0xAA, 0xC3, 0xDB, 0x1D, 0x13, 0x02, 0x2B }, // S08_CoolBoxS02 = TempSensors_Temps[7]
};
// Create labels in PROGMEM, see : https://www.arduino.cc/en/Reference/PROGMEM ; The order of the labels must match the order of the addresses in 'sensor_address[]'.
const char string0[] PROGMEM = "S01_ColdIntoPWT";
const char string1[] PROGMEM = "S02_ColdFromPWT";
const char string2[] PROGMEM = "S03_HotFromCompr";
const char string3[] PROGMEM = "S04_HotFromPWT";
const char string4[] PROGMEM = "S05_AmbientOfUnit";
const char string5[] PROGMEM = "S06_InsideFluid";
const char string6[] PROGMEM = "S07_CoolBoxS01";
const char string7[] PROGMEM = "S08_CoolBoxS02";
const char * const string_table[] PROGMEM =
{
string0, string1, string2, string3, string4, string5, string6, string7,
};
// MCP3221
// Each MCP3221 has 1 of 8 possible I2C addresses (factory hardwired & recognized by its specific part number & top marking on the package itself):
// PART DEVICE I2C ADDRESS PART
// NUMBER (BIN) (HEX) (DEC) MARKING
// MCP3221A0T-E/OT 01001000 0x48 72 GE
// MCP3221A1T-E/OT 01001001 0x49 73 GH
// MCP3221A2T-E/OT 01001010 0x4A 74 GB
// MCP3221A3T-E/OT 01001011 0x4B 75 GC
// MCP3221A4T-E/OT 01001100 0x4C 76 GD
// MCP3221A5T-E/OT 01001101 0x4D 77 GA
// MCP3221A6T-E/OT 01001110 0x4E 78 GF
// MCP3221A7T-E/OT 01001111 0x4F 79 GG
const byte SLAVE1 = 0x4E; // I2C address of the MCP3221 for measuring the compressor current
const byte SLAVE2 = 0x4F; // I2C address of the MCP3221 for measuring the pump current
const float MPC3221_VREF_V = VCC_VREF_V; // Voltage reference ( = VCC) for the MCP3221 in units [V]
// ACS723 over MCP3221
// Sensitivity
const float SENS_ACS723_05__V_PER_A = 0.4; // SENSitivity of the "ACS723LLCTR-05AB-T" in units [V/A]
const float SENS_ACS723_10__V_PER_A = 0.2; // SENSitivity of the "ACS723LLCTR-10AB-T" in units [V/A]
// Internal ADC for 12V VBB (VBAT) voltage reading
const int VBB_MEAS_ANALOG_IN_PIN = A6; // Pin used for voltage VBB (VBAT) measurement reading through internal Arduino ADC
const float VBB_MEAS_RES_DIV_GAIN = 4; // Gain setting of the RESistor DIVider (potentiometer) between the VBB (VBAT) voltage (max. 20V foreseen) to VCC related (approx. 5V nom).
// Alive / Error LED
const int AliveErrorLED = 4; // Pin "D4"
// Switches ( = Pushbuttons)
#define ERROR_WINDOW_SW 50 // +/- this value
#define DEBUG_ON
int AnalogSwPin = 7; // switch circuit input connected to analog pin 7
// Temperature control
// Inside cooling box, set the initial value to which the system shall control the temperatures of the water e.g.
float Temp_CoolBoxS02_Lo = -0.3;
float Temp_CoolBoxS02_Hi = +0.5;
bool Change_S01_Lo_or_Hi = false; // If the switches / keys shall change the "Lo" or the "Hi" value of the "S01" temperature sensor.
// Compressor switch on / off
#define ComprOnOffPin A3 // An analog hardware is connected to pin A3 which switches the relay off immediately as soon as this pin is going low. If this pin is going high, approx. 7 min has to be waited due to an RC time constant until the relay switches on.
bool ComprOnOff = false; // If the compressor shall be turned on or off
// Miscellaneous
// TBD.
// ??????????????????????? ****************** WAS IST DAS ????? **********************************************************`?????????????????????????????/
// 1-wire
// Orig. from: "https://forum.arduino.cc/index.php?topic=393653.0", and adapted to my sensor addresses etc. :
// "Changed the names of variable: sensor_bus is the bus (was called 'sensors'). // sensor_address[] is the array with the deviceaddresses of the sensors.
// Note that the index by the DallasTemperature is not our own index. I don't even print that index. The index used in the sketch is our own index, it matches the labels with the addresses.
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
DallasTemperature sensor_bus( &oneWire); // Pass our oneWire reference to Dallas Temperature.
/****************** Constructors ******************************************************/
// OLED-Display
U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); // Please update the pin numbers according to your setup. Use U8X8_PIN_NONE if the reset pin is not connected
/****************** Enumberations ******************************************************/
/****************** Structures *********************************************************/
/****************** Variables **********************************************************/
// 1-wire
static int CurNrOWdevsBus; // Current number of 1-wire devices on the bus
static float TempSensors_Temps[NUM_OW_SENSORS]; // Array which holds the current temperatures of all 1-wire temperature sensors
// Flow-sensor
volatile int flow_frequency; // Measures flow sensor pulses
float l_minute = 0.0; // Calculated litres/hour
unsigned char flowsensor = 3; // Sensor Input
unsigned long currentTime;
unsigned long cloopTime;
// MCP3221
//static unsigned int Compr_Cur_DigCode; // COMPRessor digital code read through MCP3221 ( 0 .. 4095 )
static float Compr_Cur_DigCode; // COMPRessor digital code read through MCP3221 ( 0 .. 4095 )
static float Compr_Cur_A; // COMPRessor CURrent read through MCP3221 stored in this variable in units "[A]"
static float Pump_Cur_DigCode; // PUMP digital code read through MCP3221 ( 0 .. 4095 )
static float Pump_Cur_A; // PUMP CURrent read through MCP3221 stored in this variable in units "[A]"
// Internal ADC for 12V VBB (VBAT) voltage reading
static int VBBmeas_ADC_val_DigCode = 0;
static float VBBmeas_ADC_val_V = 0; // ADC value for VBB (VBAT) measurement in units [V] but still from 0 .. 5V (not converted)
static float VBBmeas_VBB_V = 0; // VBB (VBAT) measurement: VBB measured / converted in(to) units [V]
// Misc
static unsigned short SysErr = 0; // If there is an error in the system, e.g. overtemperature of the compressor etc.
static unsigned short uCalive = 1; // Change value every e.g. 1s and display some character on OLED display
// Debug
unsigned char DEBUG_PIN = 4;
/****************** Subprograms / Functions ********************************************/
/***************************************************************************************/
/* Interrupt Subprogram / Function */
/***************************************************************************************/
void flow () // Interrupt function
{
flow_frequency++;
}
///***************************************************************************************/
///* Subprogram / Function */
///***************************************************************************************/
//// Print the temperature for a device
//void func_OW_PrintTemperature(DeviceAddress deviceAddress)
//{
// float tempC = sensors.getTempC(deviceAddress);
// if(tempC == DEVICE_DISCONNECTED_C)
// {
// Serial.println("Error: Could not read temperature data");
// return;
// }
// Serial.print("Temp C: ");
// Serial.print(tempC);
//}
//
///***************************************************************************************/
///* Subprogram */
///***************************************************************************************/
//// Print a device address
//void func_OW_PrintAddress(DeviceAddress deviceAddress)
//{
// for (uint8_t i = 0; i < 8; i++)
// {
// if (deviceAddress[i] < 16) Serial.print("0");
// Serial.print(deviceAddress[i], HEX);
// }
//}
/***************************************************************************************/
/* Subprogram */
/***************************************************************************************/
void func_OW_GetDevicesOnBusAndAssignAddr()
{
// locate devices on the bus
Serial.print("Locating One-Wire devices...");
sensor_bus.begin(); // Start up the library
#ifdef ENABLE_SEARCH_ADDRESS
// Get the number of devices on the 1-Wire bus.
CurNrOWdevsBus = sensor_bus.getDeviceCount();
Serial.print(F( "Number of devices found: "));
Serial.println( CurNrOWdevsBus );
// Get the unique address: Use the actual number of found sensors, to make it possible to connect the sensors one by one (and press reset every time) and see the unique address. Once all the addresses are set in 'sensor_address[]', then the index of that is used, and not the index of the DallasTemperature.
Serial.println(F( "Copy the 8 bytes of the sensor address into the sketch."));
DeviceAddress sens; // temporary sensor address.
for( int i=0; i<CurNrOWdevsBus; i++) // this is the index for the DallasTemperature library
{
sensor_bus.getAddress( sens, i);
Serial.print(F( "Device found, address: "));
for( int j=0; j<8; j++)
{
Serial.print(F( "0x"));
if( sens[j] < 16)
Serial.print(F( "0"));
Serial.print( sens[j], HEX);
if( j!=7)
Serial.print(F( ", "));
}
Serial.println();
}
#endif
}
/***************************************************************************************/
/* Subprogram */
/***************************************************************************************/
// Set the resolution of the 1-wire temperature sensors: Set to x bit (Each Dallas/Maxim device is capable of several different resolutions)
void func_OW_SetGetTempDevicesProperties()
{
// Resolution: The next part is only valid if the sensor address had been written in the sketch.
#ifdef ENABLE_READ_BACK_RESOLUTION
Serial.println(F( "Resolution:"));
#endif
for( int i=0; i<NUM_OW_SENSORS; i++)
{
sensor_bus.setResolution( sensor_address[i], TEMPERATURE_PRECISION);
#ifdef ENABLE_READ_BACK_RESOLUTION
char buffer[40];
strcpy_P( buffer, (char *) pgm_read_word( &(string_table[i])));
Serial.print(F( " "));
Serial.print( buffer);
Serial.print(F( " resolution: "));
Serial.print( sensor_bus.getResolution( sensor_address[i]), DEC);
Serial.println();
#endif
}
// Parasite power: Report parasite power requirements
Serial.print("Parasite power is: ");
if (sensor_bus.isParasitePowerMode()) Serial.println("ON");
else Serial.println("OFF");
}
/***************************************************************************************/
/* Subprogram */
/***************************************************************************************/
// Get current temperatures of all 1-wire temperature sensors and store them into an array
void func_OW_GetTempsensorTemps()
{
sensor_bus.requestTemperatures(); // Global request to get the temperatures // Gather all the temperatures // The temperatures are requested by using the unique address of the sensor. The connected sensors with its address in this sketch will return a valid temperature, regardless of other sensors that might be missing or extra sensors that might have been added.
for( int i=0; i<NUM_OW_SENSORS; i++)
{
TempSensors_Temps[i] = sensor_bus.getTempC( sensor_address[i]); // Get temperature with its own unique address. // This matches the labels to the specific sensor.
}
// Print all the temperatures
for( int i=0; i<NUM_OW_SENSORS; i++)
{
char buffer[40];
strcpy_P( buffer, (char *) pgm_read_word( &(string_table[i])));
Serial.print( buffer);
Serial.print(F( ": "));
if( TempSensors_Temps[i] == -127.0)
{
Serial.print(F( "Error, not found "));
}
else
{
Serial.print( TempSensors_Temps[i]);
Serial.print(F( " "));
}
}
Serial.println();
}
/***************************************************************************************/
/* Subprogram */
/***************************************************************************************/
// I2C Scanner from: "https://forum.arduino.cc/index.php?topic=632881.0" ; This sketch tests the standard 7-bit addresses, Devices with higher bit address might not be seen properly.
// If called stand-alone, it needs "#include <Wire.h>".
void func_I2C_Scanner()
{
byte error, address;
int nDevices;
Serial.print(F("\n----------------------\n"));
Serial.println("Scanning for I2C devices ...");
nDevices = 0;
for(address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices++;
}
else if (error==4)
{
Serial.print("Unknown error at address 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
}
/***************************************************************************************/
/* Subprogram */
/***************************************************************************************/
// Read 3 Switches = Pushbuttons over an analog input pin.
// (c) Bernd Cettl, 07/2021, based on script from "Doug LaRue" from "Nov. 2008".
/*
* analogPin VCC (+5 V)
* | |
* | |
* o -------------- |
* | | |
* | \ |
* ----- 120R / |
* ----- 100nF \ |
* | / |
* | \ |
* _____ |____ \____|
* ___ ground | SW1 |
* _ \ \
* / /
* 1k5 \ \ 1k5
* / /
* \ \
* |____ \____|
* | SW2 |
* \ \
* / /
* 1k5 \ \ 1k5
* / /
* \ \
* |____ \____|
* | SW3
* \
* 1k5 /
* \
* /
* \
* |
* _____
* ___ ground
* _
*
*/
int buttonPushed(int pinNum) {
int val; // variable to store the read value
val = analogRead(pinNum); // read the input pin
#ifdef DEBUG_ON
Serial.println(val);
#endif
if ( val >= (1023-ERROR_WINDOW_SW) and val <= (1023) ) { // 1022 .. 1023
#ifdef DEBUG_ON
Serial.println("switch 1 pressed/triggered");
#endif
return 1;
}
else if ( val >= (681-ERROR_WINDOW_SW) and val <= (681+ERROR_WINDOW_SW) ) { // 681
#ifdef DEBUG_ON
Serial.println("switch 2 pressed/triggered");
#endif
return 2;
}
else if ( val >= (340-ERROR_WINDOW_SW) and val <= (340+ERROR_WINDOW_SW) ) { // 340
#ifdef DEBUG_ON
Serial.println("switch 3 pressed/triggered");
#endif
return 3;
}
else
return 0; // no button found to have been pushed
}
/***************************************************************************************/
/* Main: Setup // put your setup code here, to run once: */
/***************************************************************************************/
void setup()
{
// System LED
pinMode( LED_BUILTIN , OUTPUT );
// AliveErrorLED
pinMode( AliveErrorLED , OUTPUT );
// Compressor switch on / off
pinMode( ComprOnOffPin , OUTPUT );
// Switches
pinMode( AnalogSwPin , INPUT );
// start serial port
Serial.begin(9600);
while(!Serial); // Acc. to Arduino Forum, basically: Wait for serial port to connect, necessary for some boards. // In more detail: "On boards with an FT232 chip or other USB->Serial bridge chip (Uno, Mega, etc) it does absolutely nothing. On boards with a direct USB connection, such as the Leonardo or the Yùn it waits for an active serial connection to be established by the PC (i.e., for the serial port to be opened by a piece of software)."
Serial.print(F("INITIATING SERIAL COMMUNICATION\n"));
Serial.print(F("Serial Port "));
Serial.print(Serial ? "is open\n" : "Could not be opened\n");
Serial.print(F("----------------------\n"));
// 1-wire
// Get 1-wire device addresses and assign increasing integer number to them
func_OW_GetDevicesOnBusAndAssignAddr();
// Set the resolution of the 1-wire temperature sensors
func_OW_SetGetTempDevicesProperties();
// Get current temperatures of all 1-wire temperature sensors and store them into an array
func_OW_GetTempsensorTemps();
// Flow-sensor
pinMode(flowsensor, INPUT);
digitalWrite(flowsensor, HIGH); // Optional Internal Pull-Up
attachInterrupt(digitalPinToInterrupt(flowsensor), flow, RISING); // Setup Interrupt
currentTime = millis();
cloopTime = currentTime;
// Start communication with I2C: Needed for MCP3221
Wire.begin();
// I2C devices
// I2C Scanner
func_I2C_Scanner();
// MCP3221: Hint from "https://forum.arduino.cc/index.php?topic=550117.0": Summary: It works, if we move the constructors ( = "MCP3221 mcp3221A(SLAVE1);" ; "MCP3221 mcp3221B(SLAVE2);") __INTO_ "loop()", thereby constructing 2 new slave devices at each cycle like so:
MCP3221 mcp3221A(SLAVE1);
// Ping
Serial.print(F("Slave A reading:\t"));
Serial.print(mcp3221A.ping() ? (F("Not Found\n")) : (F("Found!\n")));
// Set different things
mcp3221A.setSmoothing(NO_SMOOTHING);
// Get raw data
Compr_Cur_DigCode = mcp3221A.getData();
Serial.print(F("Compressor current still in digital code (0..4095): "));
Serial.print(Compr_Cur_DigCode);
Serial.print(F("[]\n"));
MCP3221 mcp3221B(SLAVE2);
// Ping
Serial.print(F("Slave B reading:\t"));
Serial.print(mcp3221B.ping() ? (F("Not Found\n")) : (F("Found!\n")));
// Set different things
mcp3221B.setSmoothing(NO_SMOOTHING);
// Get raw data
Pump_Cur_DigCode = mcp3221B.getData();
Serial.print(F("Pump current still in digital code (0..4095): "));
Serial.print(Pump_Cur_DigCode);
Serial.print(F("[]\n"));
// OLED-Display
u8x8.begin();
u8x8.setPowerSave(0);
// Write OW devices with addresses to OLED-Display
u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8.drawString(0,0,"Nr Devs OW bus:");
u8x8.setCursor(0,1);
u8x8.print(CurNrOWdevsBus);
//u8x8.drawString(0,1,CurNrOWdevsBus_char);
u8x8.refreshDisplay(); // only required for SSD1606/7
// Show setup display 2 seconds long
delay(2000);
// Clear display in order that some remaining characters are not displayed during the loop. E.g. If here in setup it says "Temperatures:" and later in the loop just say "Temps:" in the same line, that it doesn't write: "Temps:atures:"
u8x8.clear();
// Debug
// pinMode(LED_BUILTIN, OUTPUT);
}
/***************************************************************************************/
/* Main: Loop // put your main code here, to run repeatedly: */
/***************************************************************************************/
void loop()
{
// Scheduler: Especially for flow-sensor
currentTime = millis();
// Every second, calculate and print litres/hour
if(currentTime >= (cloopTime + 2000))
{
// ==============================================
// !! THERE ARE JUST 150ms LEFT FOR PROCESSING !!
// ==============================================
// Debug
// TBD.
// Flow-sensor: Shall be the 1st entry in the loop (except Debug) because it shall be best exactly 1000ms and the difference how much it is more than 1000ms is calibrated away "(currentTime - cloopTime)", but if there are other time-consuming variable tasks in-between, this calibration is not good anymore. the
if(flow_frequency != 0){
// Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
//l_minute = (flow_frequency / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour
l_minute = 1000.0 / (currentTime - cloopTime) * (flow_frequency / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour // "1000.0 / (currentTime - cloopTime)" = Correction if loop takes longer than "1000" ms.
flow_frequency = 0; // Reset Counter
//Serial.print(l_minute, DEC); // Print litres/min
//Serial.println(" l/min");
l_minute = l_minute * 0.9; // Correction: 3.0 l/min from Wasseruhr, YF-S201 displayed 3.33 l/min. => After this correction measured approx. correct at least with flow rates checked with 1 (one) l/min, and 3 l/min (on 21.02.2021).
// Durchfluss-Sensor brauch erneute Kalibration nachdem die LoopTime ohne Delay umgestellt worden ist!!
}
else {
l_minute = 0; // To not keep the last value forever if there is no more flow.
}
// Reset the time count right after (in order that not even more time passes than 1000ms) the Flow-Sensor but also not before it (otherwise calibration of flow sensor will fail, see there).
cloopTime = currentTime; // Updates cloopTime
// 1-wire
// Get current temperatures of all 1-wire temperature sensors and store them into an array
func_OW_GetTempsensorTemps();
// Still just for fun:
int countAbove70 = 0;
for( int i=0; i<NUM_OW_SENSORS; i++)
{
if( TempSensors_Temps[i] > 86.0)
{
countAbove70++;
}
}
Serial.print(F( "There are "));
Serial.print( countAbove70);
Serial.println(F( " sensors above 70.0"));
if( countAbove70 > 0) // at least one sensor above 70 degrees ?
{
SysErr = 1;
}
else
{
SysErr = 0;
}
// MCP3221: Hint from "https://forum.arduino.cc/index.php?topic=550117.0": Summary: It works, if we move the constructors ( = "MCP3221 mcp3221A(SLAVE1);" ; "MCP3221 mcp3221B(SLAVE2);") __INTO_ "loop()", thereby constructing 2 new slave devices at each cycle like so:
// Set different things and get raw data
MCP3221 mcp3221A(SLAVE1);
mcp3221A.setSmoothing(NO_SMOOTHING); // Obviously has to be repeated here in the loop. Is not enough to once define it in the setup.
Compr_Cur_DigCode = mcp3221A.getData();
MCP3221 mcp3221B(SLAVE2);
mcp3221B.setSmoothing(NO_SMOOTHING); // Obviously has to be repeated here in the loop. Is not enough to once define it in the setup.
Pump_Cur_DigCode = mcp3221B.getData();
// Print raw data to serial
Serial.print(F("Compressor current still in digital code (0..4095): "));
Serial.print(Compr_Cur_DigCode);
Serial.print(F("[]\n"));
Serial.print(F("Pump current still in digital code (0..4095): "));
Serial.print(Pump_Cur_DigCode);
Serial.print(F("[]\n"));
// Convert raw data to current
Compr_Cur_A = MPC3221_VREF_V * ( 2 * Compr_Cur_DigCode - 4096 ) / ( 4096 * 2 * SENS_ACS723_10__V_PER_A );
Pump_Cur_A = MPC3221_VREF_V * ( 2 * Pump_Cur_DigCode - 4096 ) / ( 4096 * 2 * SENS_ACS723_05__V_PER_A );
// Print converted currents to Amperes to serial
Serial.print(F("Compressor current in units [A]: "));
Serial.print(Compr_Cur_A);
Serial.print(F("[]\n"));
Serial.print(F("Pump current in units [A]: "));
Serial.print(Pump_Cur_A);
Serial.print(F("[]\n"));
//# ToDo: In the setup: First set MCP3221 A and B voltage reference and smoothing "NO" and then check, if it has been set and only then proceed. Also Values are not in mV but in "dig.code" !!!
//# Schauen, wieviel Zeit float multiplikation braucht, ich habe lt. oben (siehe weiter oben!) nur mehr 150ms verfügbar und es kommen noch 2 Tempsenses und schalter und leds etc dazu!
// 12V VBB (VBAT) voltage reading (internal ADC)
VBBmeas_ADC_val_DigCode = analogRead( VBB_MEAS_ANALOG_IN_PIN );
VBBmeas_ADC_val_V = VBBmeas_ADC_val_DigCode * ( VCC_VREF_V / 1024 );
VBBmeas_VBB_V = VBBmeas_ADC_val_V * VBB_MEAS_RES_DIV_GAIN;
// Switches
int buttNum = buttonPushed(AnalogSwPin);
#ifdef DEBUG_ON
Serial.print("Button "); Serial.print(buttNum); Serial.println(" was pushed.");
#endif
if ( Change_S01_Lo_or_Hi == false ) { // If "Change_S01_Lo_or_Hi" = e.g. Lo ( = e.g. "false") ==> Allow to modify the "Lo" value with the switches / keys.
if ( buttNum == 1 ) {
Temp_CoolBoxS02_Lo = Temp_CoolBoxS02_Lo + 0.1;
}
else if ( buttNum == 2 ) {
Temp_CoolBoxS02_Lo = Temp_CoolBoxS02_Lo - 0.1;
}
}
else { // If "Change_S01_Lo_or_Hi" = e.g. Hi ( = e.g. "true") ==> Allow to modify the "Hi" value with the switches / keys.
if ( buttNum == 1 ) {
Temp_CoolBoxS02_Hi = Temp_CoolBoxS02_Hi + 0.1;
}
else if ( buttNum == 2 ) {
Temp_CoolBoxS02_Hi = Temp_CoolBoxS02_Hi - 0.1;
}
}
if ( buttNum == 3 ) { // Button nr. 3 changes the modification of either the "Lo" or "Hi" value of the "S01".
Change_S01_Lo_or_Hi = !Change_S01_Lo_or_Hi;
}
// Higher limit must be higher than the lower limit, because it does only cooling
if ( Temp_CoolBoxS02_Lo >= Temp_CoolBoxS02_Hi ) {
Temp_CoolBoxS02_Hi = Temp_CoolBoxS02_Lo + 1;
}
#ifdef DEBUG_ON
Serial.print("Temp_CoolBoxS02_Lo = "); Serial.println(Temp_CoolBoxS02_Lo);
Serial.print("Temp_CoolBoxS02_Hi = "); Serial.println(Temp_CoolBoxS02_Hi);
#endif
// Compressor switch on / off control
if ( SysErr == 1 ) { // If a system error ( = e.g. critical temperature is reached anywhere) occurred ...
ComprOnOff = false; // ... turn off the compressor
}
else {
if ( TempSensors_Temps[7] < Temp_CoolBoxS02_Lo ) { // If the temperature of sensor "S02" is <= as the minimum set temperature ...
ComprOnOff = false; // ... turn off the compressor
}
if ( TempSensors_Temps[7] > Temp_CoolBoxS02_Hi ) { // If the temperature of sensor "S02" is <= as the minimum set temperature ...
ComprOnOff = true; // ... turn on the compressor
}
}
if ( ComprOnOff == false ) {
digitalWrite( ComprOnOffPin , LOW );
}
if ( ComprOnOff == true ) {
digitalWrite( ComprOnOffPin , HIGH );
}
// OLED-Display
// Write temperatures to OLED-Display
//u8x8.drawString(0, 0, "Temps:");
u8x8.drawString(0, 0, "CI"); // Cold Into the plate heat exchanger
u8x8.drawString(0, 1, "CO"); // Cold Out of the plate heat exchanger
u8x8.drawString(0, 2, "HC"); // Hot out of the Compressor
u8x8.drawString(0, 3, "HO"); // Hot Out of the plate heat exchanger
u8x8.drawString(0, 4, "AT"); // Ambient Temperature
u8x8.drawString(0, 5, "IF"); // Inside Fluid
u8x8.drawString(0, 6, "S1"); // CoolBox inside Sensor 01
u8x8.drawString(0, 7, "S2"); // CoolBox inside Sensor 01
for (uint8_t i = 0; i < CurNrOWdevsBus; i++) { // If "NrOWdevs = 10", runs from 0 .. 9
//u8x8.setCursor(0,i+1); // Set cursor to column 0 of display
// u8x8.print(i+1); // Print the current number of device (e.g. "1" .."7") // Obviously for an integer variable, the number of decimal places do not need to be defined explicitely with the command "print". So e.g. enough is "print(i)", "print(i,1)" is not needed.
// u8x8.setCursor(3,i+1); // Set cursor to column 2 of display
u8x8.setCursor(3,i); // Set cursor to column 3 of display (starting with column "0")
u8x8.print(TempSensors_Temps[i],2);
}
// Blank one character if displayed temp returns from below -10 degrees
// At least do for inside S01 and S02; ToDo: Quick fix, gehört nochmal überarbeitet: => Was ist mit den anderen Temperatursensoren?
u8x8.drawString(7, 6, " ");
u8x8.drawString(7, 7, " ");
//u8x8.drawString(13, 6, "-");
// Write flow rate to OLED-Display
u8x8.drawString(9, 1, " "); // Obviously additionally needed to clear this part of the display, otherwise could happen, that if number falls below 4 digits (e.g. "1000"), then the last "0" remains, so e.g. if first was "1234mV" displayed, then only "980mV" that the display showed "9804mV".
u8x8.setCursor(9,1);
u8x8.print(l_minute,2);
u8x8.drawString(9, 0, "CAL!"); // Durchfluss-Sensor brauch erneute Kalibration nachdem die LoopTime ohne Delay umgestellt worden ist!!
u8x8.drawString(14, 1, "FR");
// Write compressor and pump current to OLED-Display
u8x8.drawString(9, 2, " "); // Obviously additionally needed to clear this part of the display, otherwise could happen, that if number falls below 4 digits (e.g. "1000"), then the last "0" remains, so e.g. if first was "1234mV" displayed, then only "980mV" that the display showed "9804mV".
u8x8.setCursor(9,2);
u8x8.print(Compr_Cur_A , 1); // Although "unsigned int", "1" decimal place necessary; with "0", it doesn't display the voltage
u8x8.drawString(14, 2, "CC"); // CC = Compressor Current
u8x8.drawString(9, 3, " "); // Obviously additionally needed to clear this part of the display, otherwise could happen, that if number falls below 4 digits (e.g. "1000"), then the last "0" remains, so e.g. if first was "1234mV" displayed, then only "980mV" that the display showed "9804mV".
u8x8.setCursor(9,3);
u8x8.print(Pump_Cur_A , 1); // Although "unsigned int", "1" decimal place necessary; with "0", it doesn't display the voltage
u8x8.drawString(14, 3, "PC"); // PC = Pump Current
// Write VBB voltage to OLED-Display
u8x8.drawString(9, 4, " "); // Obviously additionally needed to clear this part of the display, otherwise could happen, that if number falls below 4 digits (e.g. "1000"), then the last "0" remains, so e.g. if first was "1234mV" displayed, then only "980mV" that the display showed "9804mV".
u8x8.setCursor(9,4);
u8x8.print(VBBmeas_VBB_V , 1); // Although "unsigned int", "1" decimal place necessary; with "0", it doesn't display the voltage
u8x8.drawString(14, 4, "VB"); // VB = VBB (VBAT) = nom. 12V
// Switches
// u8x8.setCursor(15,5);
// u8x8.print(buttNum , 1); // Although "unsigned int", "1" decimal place necessary; with "0", it doesn't display the voltage
// Compressor state
if ( ComprOnOff == false ) {
u8x8.drawString(13, 5, "OFF");
}
if ( ComprOnOff == true ) {
u8x8.drawString(13, 5, " ON");
}
// Display the set temperatures
// Lower value
u8x8.drawString(8, 7, " ");
if ( Temp_CoolBoxS02_Lo < 0 ) {
u8x8.drawString(8, 7, "-");
}
else {
u8x8.drawString(8, 7, "+");
}
u8x8.setCursor(9,7);
u8x8.print( abs(Temp_CoolBoxS02_Lo) , 1); // Although "unsigned int", "1" decimal place necessary; with "0", it doesn't display the voltage
// Higher value
u8x8.drawString(12, 7, " "); // One blank " " less thank above ( = with "Temp_CoolBoxS02_Lo") because end column of display.
if ( Temp_CoolBoxS02_Hi < 0 ) {
u8x8.drawString(12, 7, "-");
}
else {
u8x8.drawString(12, 7, "+");
}
u8x8.setCursor(13,7);
u8x8.print( abs(Temp_CoolBoxS02_Hi) , 1); // Although "unsigned int", "1" decimal place necessary; with "0", it doesn't display the voltage
// Show that uC and display is alive and switch "Alive/Error LED": // If everything ok, then AliveErrorLED = "HI,LO,LO,LO", else "HI,LO,HI,HI" PWM.
switch (uCalive) {
case 1:
u8x8.drawString(15, 0, "-");
uCalive = 2;
digitalWrite( LED_BUILTIN , HIGH );
digitalWrite( AliveErrorLED , HIGH );
break;
case 2:
u8x8.drawString(15, 0, "\\");
uCalive = 3;
digitalWrite( LED_BUILTIN , LOW );
digitalWrite( AliveErrorLED , LOW );
break;
case 3:
u8x8.drawString(15, 0, "|");
uCalive = 4;
if ( SysErr >= 1 )
digitalWrite( AliveErrorLED , HIGH );
break;
case 4:
u8x8.drawString(15, 0, "/");
uCalive = 1;
break;
default:
u8x8.drawString(15, 0, "E"); // Error !
break; // Wird nicht benötigt, wenn Statement(s) vorhanden sind
}
// u8x8.drawString(15, 7, "T"); // Test
// Other things
// Debug
//u8x8.setCursor(8,5);
//u8x8.print((currentTime - cloopTime),1);
//cloopTime = currentTime; // Updates cloopTime
//u8x8.setCursor(8,4);
//u8x8.userInterfaceMessage("Title1", "Title2", "Title3", " Ok \n Cancel ");
// Update OLED-Display
u8x8.refreshDisplay(); // only required for SSD1606/7
// Debug
// TBD.
}
}
>