Adding current monitoring code

This commit is contained in:
-help 2024-02-15 20:21:11 +02:00
parent a630889500
commit 3d8bd4e0cf
8 changed files with 152 additions and 53 deletions

View File

@ -29,6 +29,7 @@ lib_deps =
https://github.com/PowerBroker2/FireTimer.git https://github.com/PowerBroker2/FireTimer.git
https://github.com/adafruit/Adafruit_SSD1306.git https://github.com/adafruit/Adafruit_SSD1306.git
https://github.com/RobTillaart/Stopwatch_RT.git@0.3.5 https://github.com/RobTillaart/Stopwatch_RT.git@0.3.5
https://github.com/RobTillaart/ACS712.git
SPI SPI
Wire Wire

View File

@ -0,0 +1,80 @@
#include "CurrentMonitor.h"
CurrentMonitor::CurrentMonitor()
{
}
CurrentMonitor::~CurrentMonitor()
{
}
int CurrentMonitor::getSystemCurrentMiliVolts()
{
int current = currentSensor.mA_DC();
if (current < 0)
{
current = abs(current);
}
else
{
}
return current;
}
float CurrentMonitor::getSystemCurrentAmps()
{
int current = getSystemCurrentMiliVolts();
float currentAmps = current / 1000.0f;
return trimFloat(currentAmps, 2);
}
/**
* @brief Trims a floating-point value to the specified precision.
*
* This function takes a floating-point value and trims it to the specified precision.
* The precision is defined as the number of decimal places to keep.
*
* @param value The floating-point value to be trimmed.
* @param precision The number of decimal places to keep.
* @return The trimmed floating-point value.
*/
float CurrentMonitor::trimFloat(float value, int precision)
{
float factor = pow(10.0, precision); // Calculate the factor (10^decimals)
return round(value * factor) / factor; // Round the value and return
}
uint8_t CurrentMonitor::calculateMaxPwm()
{
uint8_t maxPwm = 255;
// Start with 255 duty cycle and ramp up slowly to get the max duty cycle
Serial.println("Calculating max PWM");
for (int i = 255; i > 0; i--)
{
analogWrite(17, i);
Serial.println("PWM: " + String(i));
int current = getSystemCurrentMiliVolts();
Serial.println("Current: " + String(current));
float readInputVoltage = analogRef.calculateInputVoltage();
Serial.println("Voltage: " + String(readInputVoltage));
if (current > 6000 || readInputVoltage < 22)
{
Serial.println("Limit reached at PWM: " + String(i)) + " Current: " + String(current) + " Voltage: " + String(readInputVoltage);
maxPwm = i;
break;
}
delay(500);
}
analogWrite(17, 255);
return 255-maxPwm;
}

View File

@ -0,0 +1,23 @@
#ifndef CURRENT_MONITOR_H
#define CURRENT_MONITOR_H
#include "Arduino.h"
#include "globals.h"
class CurrentMonitor {
public:
CurrentMonitor();
~CurrentMonitor();
int getSystemCurrentMiliVolts();
float getSystemCurrentAmps();
float static trimFloat(float value, int precision);
uint8_t calculateMaxPwm();
uint8_t calculatedMaxPwm;
private:
// Add private members and methods here
};
#endif // CURRENT_MONITOR_H

View File

@ -14,7 +14,7 @@ PidController::PidController(PidControllerData *data)
this->data = data; this->data = data;
controller.begin(&(this->data->currentTemp), &(this->data->setPoint), &(this->data->targetTemp), PID_P, PID_I, PID_D); controller.begin(&(this->data->currentTemp), &(this->data->setPoint), &(this->data->targetTemp), PID_P, PID_I, PID_D);
// controller.reverse(); // controller.reverse();
controller.setOutputLimits(PID_OUTPUT_MIN, PID_OUTPUT_MAX); controller.setOutputLimits(PID_OUTPUT_MIN, PID_OUTPUT_MAX);
controller.setSampleTime(PID_SAMPLE_TIME); controller.setSampleTime(PID_SAMPLE_TIME);
controller.setWindUpLimits(PID_WINDUP_MIN, PID_WINDUP_MAX); controller.setWindUpLimits(PID_WINDUP_MIN, PID_WINDUP_MAX);
@ -46,11 +46,13 @@ void PidController::loop()
data->currentTemp = tempController.getPlateTemperature(); data->currentTemp = tempController.getPlateTemperature();
// float sysVoltage = analogRef.calculateSystemVoltage(); // float sysVoltage = analogRef.calculateSystemVoltage();
float inVoltage = analogRef.calculateInputVoltage();
compute(); compute();
//Reverseal of the PWM value is needed because the PID controller is set to work with a normal direction, Creates fopr a better PID control // Reverseal of the PWM value is needed because the PID controller is set to work with a normal direction, Creates for a better PID control
//255= off, 0=full power // 255= off, 0=full power
analogWrite(MOSTFET_PIN, 255- data->setPoint); analogWrite(MOSTFET_PIN, 255 - data->setPoint);
} }
void PidController::stop() void PidController::stop()

View File

@ -348,10 +348,14 @@ void OledDisplay::handleReflowState()
// SysV topright // SysV topright
// #ifdef DEBUG // #ifdef DEBUG
display.setCursor(25, 15); display.setCursor(15, 15);
display.setTextSize(1, 1); display.setTextSize(1, 1);
display.print(analogRef.calculateInputVoltage()); display.print(analogRef.calculateInputVoltage());
// #endif // #endif
int current = currentSensor.mA_DC();
display.setCursor(75, 15);
display.setTextSize(1, 1);
display.print(current);
display.display(); display.display();
} }

View File

@ -4,16 +4,12 @@
#include "thermistors/TemperatureController.h" #include "thermistors/TemperatureController.h"
WrappedState<ReflowProcessState> reflowProcessState = WrappedState<ReflowProcessState>(INITIALIZING); WrappedState<ReflowProcessState> reflowProcessState = WrappedState<ReflowProcessState>(INITIALIZING);
AnalogRef analogRef(5.0); AnalogRef analogRef(5.0);
ThermistorLookup thermistorLookup = ThermistorLookup(); ThermistorLookup thermistorLookup = ThermistorLookup();
// Calibration data for 100K thermistors ->https://datasheet.lcsc.com/lcsc/1810161311_Nanjing-Shiheng-Elec-MF58-104F3950_C123399.pdf ->Glass thermistor NTC 3950 100K // Calibration data for 100K thermistors ->https://datasheet.lcsc.com/lcsc/1810161311_Nanjing-Shiheng-Elec-MF58-104F3950_C123399.pdf ->Glass thermistor NTC 3950 100K
TempCalibration calibration_100K_3950 = {25, 100000, 107, 4957, 167, 1000}; TempCalibration calibration_100K_3950 = {25, 100000, 107, 4957, 167, 1000};
// Initalize the 3950 100K thermistors with ACTUAL reference resistor measurnment(Measured between Left pin and GND when the board is powered off) using the default calibration data for 100K thermistor // Initalize the 3950 100K thermistors with ACTUAL reference resistor measurnment(Measured between Left pin and GND when the board is powered off) using the default calibration data for 100K thermistor
@ -31,28 +27,28 @@ TempCalibration calibration_100K_3950 = {25, 100000, 107, 4957, 167, 1000};
// To measure the resistence turn off the controller completley and measure between GND and the left pin of the connector with the thermistor unplugged // To measure the resistence turn off the controller completley and measure between GND and the left pin of the connector with the thermistor unplugged
// 2.5k reference = Best accuracy around 138C // 2.5k reference = Best accuracy around 138C
Thermistor thermistor2(THERMISTOR2_PIN, 2125, ThermistorZ_Placement::BOTTOM, ThermistorXY_Placement::MIDDLE); //- > 2125Kohm set refrence Thermistor thermistor1(THERMISTOR1_PIN, 2545, ThermistorZ_Placement::ON_PCB, ThermistorXY_Placement::MIDDLE); // -> 2545Kohm set refrence -> This thermistor is set directly touching the PCB to be soldered
Thermistor thermistor3(THERMISTOR3_PIN, 9100, ThermistorZ_Placement::BOTTOM, ThermistorXY_Placement::MIDDLE_LOW_TEMP);// -> 9100Kohm set refrence//// 9k reference = Best accuracy around 90C -> This thermistor is used for the preheat phase if attached Thermistor thermistor2(THERMISTOR2_PIN, 9100, ThermistorZ_Placement::BOTTOM, ThermistorXY_Placement::MIDDLE_LOW_TEMP); //- > 2125Kohm set refrence
Thermistor thermistor4(THERMISTOR4_PIN, 564, ThermistorZ_Placement::BOTTOM, ThermistorXY_Placement::MIDDLE_HIGH_TEMP);//-> 564Kohm set refrence // 564R reference = Best accuracy around 210C Thermistor thermistor3(THERMISTOR3_PIN, 2040, ThermistorZ_Placement::BOTTOM, ThermistorXY_Placement::MIDDLE); // -> 9100Kohm set refrence//// 9k reference = Best accuracy around 90C -> This thermistor is used for the preheat phase if attached
Thermistor thermistor1(THERMISTOR1_PIN, 2545 , ThermistorZ_Placement::ON_PCB, ThermistorXY_Placement::MIDDLE);// -> 2545Kohm set refrence -> This thermistor is set directly touching the PCB to be soldered Thermistor thermistor4(THERMISTOR4_PIN, 564, ThermistorZ_Placement::BOTTOM, ThermistorXY_Placement::MIDDLE_HIGH_TEMP); //-> 564Kohm set refrence // 564R reference = Best accuracy around 210C
// Unused by defualt, keep unplugged
Thermistor thermistor5(THERMISTOR4_PIN, 564, ThermistorZ_Placement::BOTTOM, ThermistorXY_Placement::MIDDLE_HIGH_TEMP);
Thermistor thermistor6(THERMISTOR5_PIN,5727, ThermistorZ_Placement::TOP, ThermistorXY_Placement::MIDDLE_LOW_TEMP);
// Unused by defualt, keep unplugged
Thermistor thermistor5(THERMISTOR5_PIN, 564, ThermistorZ_Placement::BOTTOM, ThermistorXY_Placement::MIDDLE_HIGH_TEMP);
Thermistor thermistor6(THERMISTOR6_PIN, 5727, ThermistorZ_Placement::TOP, ThermistorXY_Placement::MIDDLE_LOW_TEMP);
//--------------------------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------------------------
// This line is here because TAKUMIII IS a bot and he will not let me remove it // This line is here because TAKUMIII IS a bot and he will not let me remove it
Thermistor thermistors[6] = {thermistor1, thermistor2, thermistor3, thermistor4, thermistor5, thermistor6}; Thermistor thermistors[6] = {thermistor1, thermistor2, thermistor3, thermistor4, thermistor5, thermistor6};
//Define the current sensor 20A version
ACS712 currentSensor = ACS712(ACS712_PIN, 5.0, 1023,100);
// Which Color to use for the reflow process markers // Which Color to use for the reflow process markers
uint16_t preheat_COLOR = 0x6800; uint16_t preheat_COLOR = 0x6800;
uint16_t soak_COLOR = 0x6b60; uint16_t soak_COLOR = 0x6b60;
uint16_t reflow_COLOR = 0x0201; uint16_t reflow_COLOR = 0x0201;
uint16_t cool_COLOR = 0x00a8; uint16_t cool_COLOR = 0x00a8;
// These are the reflow profiles that you can choose from, you can add more if you want (up to 5) but you will have to change the nReflowProfiles variable to the number of profiles you have // These are the reflow profiles that you can choose from, you can add more if you want (up to 5) but you will have to change the nReflowProfiles variable to the number of profiles you have
int nReflowProfiles = 4; int nReflowProfiles = 4;
@ -61,38 +57,19 @@ ReflowProfile reflowProfiles[] = {
// 138c profile Sn42Bi58 // 138c profile Sn42Bi58
ReflowProfile(new ReflowStep[5]{ ReflowProfile(new ReflowStep[5]{
ReflowStep(ReflowProcessState::PREHEAT, 100, 100, EASE_OUT), ReflowStep(ReflowProcessState::PREHEAT, 100, 100, EASE_OUT),
ReflowStep(ReflowProcessState::SOAK, 90, 140,EASE_IN_OUT), ReflowStep(ReflowProcessState::SOAK, 90, 140, EASE_IN_OUT),
ReflowStep(ReflowProcessState::REFLOW, 90, 170, HALF_SINE), ReflowStep(ReflowProcessState::REFLOW, 90, 170, HALF_SINE),
ReflowStep(ReflowProcessState::COOL, 50, 85, EASE_IN), ReflowStep(ReflowProcessState::COOL, 50, 85, EASE_IN),
ReflowStep(ReflowProcessState::DONE, 0, 0)}, ReflowStep(ReflowProcessState::DONE, 0, 0)},
"138c Sn42Bi58\0"), "138c Sn42Bi58\0"),
// The profile target says to get to 100c in 30 seconds but our hotplate can not do that so we extended the time to 120 seconds and combine the 150 and 183c steps into one step
// With a 12V PSU it also takes a while to reach these high temps so we increase the times a bit, experemintation is needed for different boards.
ReflowProfile(new ReflowStep[5]{ReflowStep(ReflowProcessState::PREHEAT, 120, 100, EASE_OUT), ReflowStep(ReflowProcessState::SOAK, 160, 183, EASE_IN), ReflowStep(ReflowProcessState::REFLOW, 110, 235, EASE_OUT), ReflowStep(ReflowProcessState::COOL, 30, 80, EASE_OUT), ReflowStep(ReflowProcessState::DONE, 0, 0)}, "183C Sn63 Pb37 \0"),
// The profile target says to get to 100c in 30 seconds but our hotplate can not do that so we extended the time to 120 seconds and combine the 150 and 183c steps into one step ReflowProfile(new ReflowStep[5]{ReflowStep(ReflowProcessState::PREHEAT, 120, 77, LINEAR), ReflowStep(ReflowProcessState::SOAK, 180, 135, LINEAR), ReflowStep(ReflowProcessState::REFLOW, 110, 211, LINEAR), ReflowStep(ReflowProcessState::COOL, 30, 80, EASE_OUT), ReflowStep(ReflowProcessState::DONE, 0, 0)}, "RAMP HOLD 235c\0"),
// With a 12V PSU it also takes a while to reach these high temps so we increase the times a bit, experemintation is needed for different boards.
ReflowProfile(new ReflowStep[5]{ReflowStep(ReflowProcessState::PREHEAT, 120, 100,EASE_OUT),
ReflowStep(ReflowProcessState::SOAK, 160, 183,EASE_IN),
ReflowStep(ReflowProcessState::REFLOW, 110, 235, EASE_OUT),
ReflowStep(ReflowProcessState::COOL, 30, 80,EASE_OUT),
ReflowStep(ReflowProcessState::DONE, 0, 0)},
"183C Sn63 Pb37 \0"),
ReflowProfile(new ReflowStep[5]{ReflowStep(ReflowProcessState::PREHEAT, 200, 100, MID_RAMP_HOLD), ReflowStep(ReflowProcessState::SOAK, 150, 150, FAST_RAMP_HOLD), ReflowStep(ReflowProcessState::REFLOW, 150, 220, SLOW_RAMP_HOLD), ReflowStep(ReflowProcessState::COOL, 200, 0, LINEAR), ReflowStep(ReflowProcessState::DONE, 0, 0)}, "Tuning Profile \0"),
ReflowProfile(new ReflowStep[5]{ReflowStep(ReflowProcessState::PREHEAT, 120, 77,LINEAR),
ReflowStep(ReflowProcessState::SOAK, 180, 135,LINEAR),
ReflowStep(ReflowProcessState::REFLOW, 110, 211, LINEAR),
ReflowStep(ReflowProcessState::COOL, 30, 80,EASE_OUT),
ReflowStep(ReflowProcessState::DONE, 0, 0)},
"RAMP HOLD 235c\0"),
ReflowProfile(new ReflowStep[5]{ReflowStep(
ReflowProcessState::PREHEAT, 200, 100,MID_RAMP_HOLD),
ReflowStep(ReflowProcessState::SOAK, 150, 150,FAST_RAMP_HOLD),
ReflowStep(ReflowProcessState::REFLOW, 150, 220, SLOW_RAMP_HOLD),
ReflowStep(ReflowProcessState::COOL, 200, 0,LINEAR),
ReflowStep(ReflowProcessState::DONE, 0, 0)},
"Tuning Profile \0"),
}; };

View File

@ -10,7 +10,7 @@
#include "./PID/PidController.h" #include "./PID/PidController.h"
#include "./thermistors/TemperatureController.h" #include "./thermistors/TemperatureController.h"
#include "ACS712.h"
@ -39,7 +39,7 @@
//PID Controller values //PID Controller values
#define PID_P 3 #define PID_P 3
#define PID_I 5 #define PID_I 5
#define PID_D 100 #define PID_D 10
#define PID_WINDUP_MIN -100 #define PID_WINDUP_MIN -100
#define PID_WINDUP_MAX 200 #define PID_WINDUP_MAX 200
@ -48,11 +48,14 @@
//The actual PWM of the mosfet is 0 for max and 255 for off //The actual PWM of the mosfet is 0 for max and 255 for off
//This gets inverted after the setpoint is grabbed from the PID controller in the main loop //This gets inverted after the setpoint is grabbed from the PID controller in the main loop
#define PID_OUTPUT_MIN 0 #define PID_OUTPUT_MIN 0
#define PID_OUTPUT_MAX 130
//Adjust the MAX PWM value according to your power supply some power supplies can cut off if the current is too high
#define PID_OUTPUT_MAX 140
////////////////////////////////////// //////////////////////////////////////
#define PID_SAMPLE_TIME 200
#define PID_SAMPLE_TIME 20 #define ACS712_PIN 29
@ -83,6 +86,7 @@ extern uint16_t cool_COLOR;
extern ThermistorLookup thermistorLookup; extern ThermistorLookup thermistorLookup;
extern ACS712 currentSensor;

View File

@ -15,7 +15,7 @@
#include "tools/ExecutionTimer.h" #include "tools/ExecutionTimer.h"
#include "StopWatch.h" #include "StopWatch.h"
#include "thermistors/Thermistor.h" #include "thermistors/Thermistor.h"
#include "Current/CurrentMonitor.h"
#define MOSTFET_PIN 17 #define MOSTFET_PIN 17
@ -25,8 +25,9 @@ double pwmValue = 255;
ExecutionTimer executionTimer; ExecutionTimer executionTimer;
TemperatureController tempController ; CurrentMonitor currentMonitor = CurrentMonitor();
TemperatureController tempController;
Buttons buttons = Buttons(); Buttons buttons = Buttons();
LEDS leds = LEDS(); LEDS leds = LEDS();
@ -47,7 +48,7 @@ void setup()
Serial.begin(38400); Serial.begin(38400);
//Serial.println("Starting OLED"); // Serial.println("Starting OLED");
// Set PWM frequency to 64 kHz // Set PWM frequency to 64 kHz
analogWriteFrequency(64); analogWriteFrequency(64);
@ -68,6 +69,8 @@ void setup()
thermMilisTimer.setResolution(StopWatch::Resolution::MILLIS); thermMilisTimer.setResolution(StopWatch::Resolution::MILLIS);
Serial.println("Setup done"); Serial.println("Setup done");
// currentMonitor.calculateMaxPwm();
} }
void loop() void loop()
{ {
@ -116,7 +119,7 @@ void loop()
pidController.start(); pidController.start();
thermMilisTimer.start(); thermMilisTimer.start();
thermTimer.start(); thermTimer.start();
//Serial.println("Time,Therm1,Therm2,Therm3,Therm4,Therm5,Therm6,,Scaling1,Scaling2,Scaling3,Scaling4,Scaling5,Scaling6,Averaged1,Weighting1,Weighting2,Weighting3"); // Serial.println("Time,Therm1,Therm2,Therm3,Therm4,Therm5,Therm6,,Scaling1,Scaling2,Scaling3,Scaling4,Scaling5,Scaling6,Averaged1,Weighting1,Weighting2,Weighting3");
} }
} }
state = newState; state = newState;
@ -128,8 +131,13 @@ void loop()
{ {
pidController.loop(); pidController.loop();
// #ifdef DEBUG
pidController.debug(); pidController.debug();
float amps = currentMonitor.getSystemCurrentAmps();
Serial.println("Current: " + String(amps));
float inVoltage = analogRef.calculateInputVoltage();
Serial.println("Voltage: " + String(inVoltage));
// #ifdef DEBUG
// #endif // #endif
tftDisplay.drawRealTemp(pidController.getInput(), chosenReflowProfile.getPercentage()); tftDisplay.drawRealTemp(pidController.getInput(), chosenReflowProfile.getPercentage());