Nadat het uitlezen en weergeven van de temperaturen was gelukt, was de volgende stap het maken van de vertaling naar de pomp snelheid.
De motor en controller moeten volgende de specificaties gekoeld worden met 13 tot 16 liter per minuut. Over de motor wordt gezegd “It withstands great abuse to the degree you cool it.” dus afhankelijk van de omstandigheden is wat extra inzetbare capaciteit niet erg.
Over de Pierburg CWA50 pomp las ik dat de pomp van minimale naar maximale flow gaat tussen een duty cycle van 13% tot 85%. Onder de 13% doet hij het niet. In de documentatie van Tecomotive (een kant en klare controller voor deze pomp) las ik dat de opbrengst bij 50% iets van 13 tot 15 liter per minuut is. Daarmee kwam ik op de volgende dynamische curves.
Deze kan ik eenmaal in de auto nog verder fine-tunen ook afhankelijk van daadwerkelijke flow als gevolg van drukval. Bij temperaturen onder nul zet ik ze vast op de ondergrens en eenmaal op 100% zal dat hij nog hogere temperaturen zo blijven. Daarmee m’n software verder opgezet.
En een test gedaan. Als er een meetfout optreedt gaat de pomp snelheid naar 100%.
En een filmpje:
Volgende stap was om ook daadwerkelijk een pomp aan te sturen. Dus een meetopstelling gemaakt. De BWM connector voor de pomp.
En een geïmproviseerd overflow vat omdat de pomp niet zelf aanzuigend is.
De proefopstelling klaar, tijd voor de proef op de som.
Na nog wat fine-tunen aan de schakeling werkte het!
Hierbij de schakeling in actie.
De hamvraag was natuurlijk: Hoeveel stroom trekt de pomp bij lagere flow. Het goede nieuws is dat verlagen van de pompsnelheid en dus flow significant helpt. Bij 19 liter per minuut trekt de pomp 2 ampère.
En bij 25 liter per minuut maar liefst 6 ampère.
Hierbij nog een filmpje van het vertragen van de pomp als de sensor afkoelt.
Volgende stap is het toevoegen van de andere twee pompen, wellicht een groter scherm en het aansturen van de kleppen maar de basis voor het koelsysteem is bij deze gelegd.
Hieronder staat de Arduino code van deze test (of een net iets andere of latere versie):
#include <DallasTemperature.h> // Source https://www.milesburton.com/Dallas_Temperature_Control_Library
#include <OneWire.h> // includes the OneWire Library for DS18B20 temp. sensors
#include <Wire.h> // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>
/*-----( Declare Constants and Pin Numbers )-----*/
// Data wire is plugged into port 12 on the Arduino for battery, controller, motor
#define ONE_WIRE_BUS 12 // NOTE: No ";" on #define
/*-----( Declare objects )-----*/
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass address of our oneWire instance to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// set the LCD address to 0x27 for a 20 chars 4 line display
// Set the pins on the I2C chip used for LCD connections:
// addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
// Assigns PWM pump pins
int BatteryPumpPin = 6;
int ControllerPumpPin = 7;
int MotorPumpPin = 8;
/*-----( Declare Variables )-----*/
// Assign the addresses of your 1-Wire temp sensors.
DeviceAddress Battery = { 0x28, 0xD3, 0x9B, 0x68, 0x08, 0x00, 0x00, 0xED };
DeviceAddress Controller = { 0x28, 0x6B, 0xE0, 0x68, 0x08, 0x00, 0x00, 0x56 };
DeviceAddress Motor = { 0x28, 0xF0, 0x7D, 0x69, 0x08, 0x00, 0x00, 0xCB };
// Temp sensors
int intTempC;
int mesTempC;
// Flow sensor stuff define
// Battery
volatile int flow_frequency_b; // Measures flow meter pulses
unsigned int l_min_b; // Litres/min
int flowmeter_b = 2; // Battery Flow Meter Pin number
unsigned long currentTime_b;
unsigned long cloopTime_b;
void flow_b () // Interrupt function
{
flow_frequency_b++;
}
// Controller
volatile int flow_frequency_c; // Measures flow meter pulses
unsigned int l_min_c; // Litres/min
int flowmeter_c = 3; // Controller Flow Meter Pin number
unsigned long currentTime_c;
unsigned long cloopTime_c;
void flow_c () // Interrupt function
{
flow_frequency_c++;
}
// Motor
volatile int flow_frequency_m; // Measures flow meter pulses
unsigned int l_min_m; // Litres/min
int flowmeter_m = 18; // Controller Flow Meter Pin number
unsigned long currentTime_m;
unsigned long cloopTime_m;
void flow_m () // Interrupt function
{
flow_frequency_m++;
}
// end flow stuff
void setup() /****** SETUP: RUNS ONCE ******/
{
Serial.begin(9600); // Set communication speed (Baud rate)
lcd.begin(20,4); // Initializes the interface to the LCD screen, and specifies the dimensions (width and height) of the display }
//------- Initialize the Temperature measurement library--------------
sensors.begin();
// set the resolution to 10 bit (Can be 9 to 12 bits .. lower is faster)
sensors.setResolution(Battery, 10);
sensors.setResolution(Controller, 10);
sensors.setResolution(Motor, 10);
// Initialize the pump pins
pinMode(BatteryPumpPin, OUTPUT);
pinMode(ControllerPumpPin, OUTPUT);
pinMode(MotorPumpPin, OUTPUT);
// Initialize the flowmeters
// Battery
pinMode(flowmeter_b, INPUT);
attachInterrupt(0, flow_b, RISING); // Setup Interrupt
// see http://arduino.cc/en/Reference/attachInterrupt
sei(); // Enable interrupts
currentTime_b = millis();
cloopTime_b = currentTime_b;
// Controller
pinMode(flowmeter_c, INPUT);
attachInterrupt(1, flow_c, RISING); // Setup Interrupt
// see http://arduino.cc/en/Reference/attachInterrupt
sei(); // Enable interrupts
currentTime_c = millis();
cloopTime_c = currentTime_c;
// Motor
pinMode(flowmeter_m, INPUT);
attachInterrupt(5, flow_m, RISING); // Setup Interrupt
// see http://arduino.cc/en/Reference/attachInterrupt
sei(); // Enable interrupts
currentTime_m = millis();
cloopTime_m = currentTime_m;
}
//
void loop() /****** LOOP: RUNS CONSTANTLY ******/
{
// Temperature sensing
sensors.requestTemperatures(); // Send the command to get temperatures
//Calculate pump speed
//Battery
int batteryTemp;
int batteryWrite;
int batteryPWM;
batteryTemp = currentTemperature(Battery);
Serial.print(batteryTemp);
Serial.println(" battery temp in calc. loop");
if (batteryTemp < 0)
{
batteryPWM = 50;
analogWrite(BatteryPumpPin, 127); //battery pump speed 50%
}
else if (batteryTemp > 40)
{
analogWrite(BatteryPumpPin, 255); //battery pump speed 100%
batteryPWM = 100;
}
else
{
batteryWrite = ((((1.25 * batteryTemp) + 50)) * 2.55);
batteryPWM = (((1.25 * batteryTemp) + 50));
Serial.print(batteryWrite);
analogWrite(BatteryPumpPin, batteryWrite);
}
//--end battery
//Controller
int controllerTemp;
int controllerWrite;
int controllerPWM;
controllerTemp = currentTemperature(Controller);
Serial.print(controllerTemp);
Serial.println(" controller temp in calc. loop");
if (controllerTemp < 0)
{
controllerPWM = 50;
analogWrite(ControllerPumpPin, 127); //controller pump speed 50%
}
else if (controllerTemp > 50)
{
analogWrite(ControllerPumpPin, 255); //controller pump speed 100%
controllerPWM = 100;
}
else
{
controllerWrite = ((controllerTemp + 50) * 2.55);
controllerPWM = (controllerTemp + 50);
Serial.print(controllerWrite);
analogWrite(ControllerPumpPin, controllerWrite);
}
//--end controller
//Motor
int motorTemp;
int motorWrite;
int motorPWM;
motorTemp = currentTemperature(Motor);
Serial.print(motorTemp);
Serial.println(" motor temp in calc. loop");
if (motorTemp < 0)
{
motorPWM = 50;
analogWrite(MotorPumpPin, 127); //motor pump speed 50%
}
//else if (motorTemp > 60)
else
{
analogWrite(MotorPumpPin, 255); //controller pump speed 100%
motorPWM = 100;
}
//else
//{
// motorWrite = ((((0.83 * motorTemp) + 50)) * 2.55);
// motorPWM = (((0.83 * motorTemp) + 50));
// Serial.print(motorWrite);
// analogWrite(MotorPumpPin, motorWrite);
//}
//--end motor control calculations
// Flowmeter calculate section
// Battery
currentTime_b = millis();
// Every second, calculate and print litres/hour
if(currentTime_b >= (cloopTime_b + 1000))
{
cloopTime_b = currentTime_b; // Updates cloopTime
// Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min. (Results in +/- 3% range)
l_min_b = (flow_frequency_b / 7.5); // Pulse frequency / 7.5Q = flow rate in L/min
flow_frequency_b = 0; // Reset Counter
}
// Controller
currentTime_c = millis();
// Every second, calculate and print litres/hour
if(currentTime_c >= (cloopTime_c + 1000))
{
cloopTime_c = currentTime_c; // Updates cloopTime
// Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min. (Results in +/- 3% range)
l_min_c = (flow_frequency_c / 7.5); // Pulse frequency / 7.5Q = flow rate in L/min
flow_frequency_c = 0; // Reset Counter
}
// Motor
currentTime_m = millis();
// Every second, calculate and print litres/hour
if(currentTime_m >= (cloopTime_m + 1000))
{
cloopTime_m = currentTime_m; // Updates cloopTime
// Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min. (Results in +/- 3% range)
l_min_m = (flow_frequency_m / 7.55); // Pulse frequency / 7.5Q = flow rate in L/min
flow_frequency_m = 0; // Reset Counter
}
// Print temperatures, flow and duty cycle on the LCD
// NOTE: Line number and character number start at 0 not 1
lcd.setCursor(0,0); //Start at character 0 on line 0
lcd.print("T=");
if(currentTemperature(Battery) < 100)
{
lcd.setCursor(3,0);
displayTemperature(Battery);
}
else
{
lcd.setCursor(2,0);
displayTemperature(Battery);
}
//Column 2 controller
lcd.setCursor(7,0);
lcd.print("T=");
if(currentTemperature(Controller) < 100)
{
lcd.setCursor(10,0);
displayTemperature(Controller);
}
else
{
lcd.setCursor(9,0);
displayTemperature(Controller);
}
//Column 3 motor
lcd.setCursor(15,0);
lcd.print("T=");
if(currentTemperature(Motor) < 100)
{
lcd.setCursor(18,0);
displayTemperature(Motor);
}
else
{
lcd.setCursor(17,0);
displayTemperature(Motor);
}
//Row 2: PWM%
//Column 1 battery
if (batteryPWM < 100)
{
lcd.setCursor(2,2);
lcd.print(batteryPWM); // Prints battery pump duty cycle
lcd.print("%");
}
else
{
lcd.setCursor(1,2);
lcd.print(batteryPWM); // Prints battery pump duty cycle
lcd.print("%");
}
//Column 2 controller
if (controllerPWM < 100)
{
lcd.setCursor(9,2);
lcd.print(controllerPWM); // Prints controller pump duty cycle
lcd.print("%");
}
else
{
lcd.setCursor(8,2);
lcd.print(controllerPWM); // Prints controller pump duty cycle
lcd.print("%");
}
//Column 3 motor
if (motorPWM < 100)
{
lcd.setCursor(17,2);
lcd.print(motorPWM); // Prints motor pump duty cycle
lcd.print("%");
}
else
{
lcd.setCursor(16,2);
lcd.print(motorPWM); // Prints motor pump duty cycle
lcd.print("%");
}
//Row 3: Flow
//Column 1 battery
lcd.setCursor(0,3);
lcd.print("F=");
lcd.setCursor(3,3);
lcd.print(l_min_b, DEC);
//Column 2 controller
lcd.setCursor(7,3);
lcd.print("F=");
lcd.setCursor(10,3);
lcd.print(l_min_c, DEC);
//Column 3 motor
lcd.setCursor(12,3);
//lcd.print("F=");
//lcd.setCursor(18,3);
lcd.print(l_min_m, DEC);
lcd.print(" l/min");
Serial.print(l_min_m, DEC); // Print litres/min
Serial.println(" L/min");
delay(500);
}//--(end main loop )---
/*-----( Declare User-written Functions )-----*/
void displayTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
if (tempC == -127.00) // Measurement failed or no device found
{
lcd.print("Err");
}
else
{
intTempC = 0.5 + tempC * 10;
lcd.print(intTempC / 10);
}
}
int currentTemperature(DeviceAddress deviceAddress)
{
float mesTempC = sensors.getTempC(deviceAddress);
if (mesTempC == -127) // Measurement failed or no device found
{
return mesTempC= 100;
}
else
return mesTempC;
}
//*********( THE END )***********
Hallo Lars,
Voor in de auto is dit wellicht een mooie arduino kloon https://www.conrad.nl/nl/controllino-mini-100-000-00-plc-aansturingsmodule-12-vdc-24-vdc-1325474.html
Dank Henk!
Die kende ik nog niet. Wat een mooi en robuust apparaat. Ik ga zeker even kijken of ik die kan inzetten in plaats van mijn Arduino Mega. Hun Controllino Maxi Automate lijkt dezelfde ATmega2560 chipset te hebben. Hopelijk heeft hij voldoende I/O’s (aansluitingen).
Hoi Lars,
Allereerst wat een supergaaf project! Erg netjes gedaan allemaal! Vraagje ik zie dat je de Pierburg CWA50 in BMW trim hebt gebruikt, deze is in tegenstelling tot andere fabrikaten uitgerust met 4 contacten ipv 3 als ik met niet vergis. Hoe ben je omgegaan met 4 de contact (lin-bus als ik het goed heb)? En heb je nog enig idee wat je betaald hebt voor de connector bij BMW?
Dank! Pin 2 is inderdaad de LIN-bus pin. Die heb ik gewoon niet aangesloten en dat ging prima.
Connectoren weet ik niet meer precies.