Constant Current Electronic Load Controlled by Arduino Manager

by Fab64 in Circuits > Microcontrollers

34 Views, 0 Favorites, 0 Comments

Constant Current Electronic Load Controlled by Arduino Manager

F1FLDUAMJQ7BLXB.png

This Instructable will guide you through designing a low-cost constant-current electronic load with minimal components controlled using Raspberry Pico W and Arduino Manager.

The system is made of three components:

  1. voltage controlled constant current load: a set of electronic components configured to draw a constant current from the connected load. The current can be adjusted setting the control voltage.
  2. Raspberry Pico W: Receives the user commands, sets the desired current and performs all voltages and current measurements
  3. Arduino Manager: Remote user interface used to set the current and control the entire system.

Arduino Manager, is a powerful general purpose iOS iPadOS / watchOS / macOS App which allows to control any Arduino (or Arduino compatible) board by the means of about 40 different Widgets.

Some of the available Widgets are:

  1. Display Widget
  2. LED Widget
  3. Switch Widget
  4. Push Button Widget
  5. Knob Widget
  6. Slider Widget
  7. Alarm Widget
  8. Sound Alarm Widget
  9. Thermostat Widget
  10. Threshold Widget
  11. Text Widget
  12. and many more

Arduino Manager prioritizes your privacy, with no registration or cloud account required—only your Apple ID. However, you have the option to save your Widget Lists to iCloud, enabling seamless sharing across your devices.

For more information about Arduino Manager:

  1. Arduino Manager for iOS, Arduino Manager for macOS.
  2. Past Instructables:
  3. How to Control Arduino R4 WiFi From Your IPhone / Apple Watch / IPad / Mac
  4. Cheap IOT Device in Minutes and Without Writing Any Code Using Raspberry Pico Pi W
  5. Controlling ESP32 Running Micropython With Arduino Manager
  6. Arduino Manager: Generate Raspberry Pi Pico C/C++ Code for an AC Power Monitor – Step-by-Step Example
  7. How to Measure a Remote Temperature Using Pico W and Arduino Manager

When the complexity of the Arduino code increases, such as when dealing with multiple analog and digital sensors to read, controlling numerous actuators, and implementing complex algorithms, the likelihood of making errors rises. Consequently, debugging the code becomes more challenging and the time and effort required to address these issues could significantly affect the progress of your project. For this reason Arduino Manager also provides (for an additional small fee):

  1. Code Generator: This add-on allows to generate the basic Arduino code for supporting the Widgets you need in your project.
  2. PIN Code Generator: Linking widgets to Arduino PINs, this add-on dramatically speeds up Arduino code development. In many cases you don't need to write a single line of code.

A nice additional feature is Voice Commands which allows to control most of the Arduino Manager Widgets by means of your voice (English only)!. See past Instructables form more.

Apple Watch is supported as well (with some limitations): you can control any Arduino board directly from your wrist, wherever you are in the world!

Arduino Manager for iOS/iPadOS is available here: App Store for $7.99 and includes the watchOS version. The macOS version is available here: App Store for $10.99 (please, note that not all the widgets are available on all the platforms).

More information, documentation, video tutorials, libraries and examples on Arduino Manager are available here:

Arduino Manager for iOS or here: Arduino Manager for macOS.


For this Instructable you need Arduino Manager version 23.2.0 or greater.

Supplies

  1. Power supply 9-12V
  2. Power supply max 30V, 2A
  3. Breadboard
  4. Wires
  5. Schottky Diode 1N5819
  6. LM324 operation amplifier
  7. Resistors:
  8. 1Ω, 1%, at least 2W (better higher)
  9. 10K, 1%, 1/4W
  10. 30K, 1%, 1/4W
  11. 3K, 1%, 1/4W
  12. 1uF Capacitor (25V)
  13. NTC (Vishay NTCALUG02A103FA) (any similar NTC will work as well adapting the code)
  14. MOSFET IRFZ44N (any similar MOSFET that can handle at least 2 A will work as well)
  15. BS170 (any similar MOSFET will work as well)
  16. Heatsink
  17. Fan 5V
  18. Raspberry Pico W (Pico 2W will work as well)

Constant Current Electronic Load - the Basics Explained

CC Electronic Load - Basic.png

The figure shows the schematic of the basic circuit for the constant-current electronic load.

The working principle is easy to understand.

Since the operation amplifier will do everything it can to keep the voltages at inverting and not inverting inputs equal, we can assume that the voltage across the feedback resistor Rf is equal to Control Voltage.

Therefore the current through Rf is:


Control Voltage

IRf = -------------------

Rf


IRf​ is the same current drawn from the external load (connected at J2) and is independent of the voltage across the load.

To set the desired current, we adjust the control voltage according to the previous equation.

This is what makes it a constant-current electronic load.

The Control Voltage - Pwm to DC Conversion

Filter.png
buffer.png

To generate the control voltage there are two options:

  1. A DAC (digital voltage converter): A device that accepts a digital input and converts it into an analog signal. These devices are easy to use and well suited for this purpose, but they are relatively expensive.
  2. PWM-to-DC conversion. The Pi Pico W can easily generate a PWM signal on any GPIO pin. By Filtering the PWM signal with a low-pass filter, we can get a DC voltage proportional to VH (logic high voltage) and to the PWM duty cycle:

Vdc = VH * Duty Cycle

(See this for a deeper explanation Low-Pass Filter a PWM signal into an Analog Voltage).

Using R = 10K and C = 1uF for the filter is sufficient to obtain a smooth signal for our purpose.

To avoid loading the filter and altering its characteristic, it is best to follow it with a buffer that has a very high input impedance and a gain very close to 1.

The Circuit Schematic

Schematic.png

The figure shows the full schematic for the constant-current electronic load. Below are the additional components used in the circuit:

  1. Pico W: manages the communication with Arduino Manager (and the user), measures the required quantities and handle all the system operations
  2. Thermistor: the MOSFET temperature is constantly monitored to avoid that the it overheats and damege. The NTC connected to the Pico W serves this purpose.
  3. Fan: To keep the power MOSFET cool, it is mounted on a heatsink, and a fan provides additional airflow. The fan operates when the MOSFET temperature rises above a user-defined threshold. A BS170 controls the Fan but any other similar MOSFET will do the work
  4. R4 and R5: These resistors form a voltage divider that allows the Pico's ADC (which accepts a maximum of 3.3 V) to measure the main voltage applied to the electronic load. We assume that the maximum voltage is around 30 V. For higher voltages, R4 and R5 must be recalculated.

Powering the Electronic Load

According to the schematic, two voltages are required to power the circuit:

  1. 9/12V to power the op-amp
  2. 5V to power the Pico W via the D1 as recommended in Raspberry Pi Pico W Datasheet (section 3.5).

The 5V can be easily obtained using a DC-DC converter (any inexpensive module should work). Alternatively, the Pico can be powered via a USB wall adapter or even the USB port of a computer.

Building the Electronic Load

Electronic_Load_bb.png

There are many different ways to build the proposed electronic load: custom PCB, perfboard, veroboard, or a breadboard.

The breadboard is the easiest way to experiment with the circuit and adapt it to your requirements.

The picture provides a reference for building the circuit on the breadboard.

Arduino Manager - Firmware Overview

In the next steps, using the Arduino Manager's code generator, we will generate the firmware code for Pico W and adapt it as required.

In this section, we provide an overview of the structure of the generated code to make the following steps easier to understand.

The code for supporting Arduino Manager is mainly based on four functions:

  1. doWork - Replaces the classic Arduino loop() function. Some of your code goes here.
  2. processIncomingMessages - Receives information from the connected iOS/macOS device
  3. processOutgoingMessages - Sends information to the connected iOS/macOS device
  4. doSync - Sends status information to the iOS/macOS devices as soon as it connects

For more information:

  1. Read the previous Instructables starting from Control Arduino From Your IOS Device and Your Apple Watch
  2. Read the Arduino Manager documentation (Arduino Manager Documentation).

Configuring Arduino Manager

FPDGDVHMJQ7AA9L.png

Now we are ready for:

  1. Configure Arduino Manager
  2. Use the Arduino Manager's Code Generator to create the firmware for Raspberry Pico

For this Instructable you need Arduino Manager version 23.2.0 or greater.

We start opening Arduino Manager and creating a new Widget List:

  1. Widget Lists from the left menu
  2. Click New
  3. Choose to store it in the cloud in order to share it between all your devices
  4. Enter the widget list's name: Constant Current Electronic Load
  5. Select the newly created Widget List

Then we have to create a connection to allow the Pico to connect to the Wi-Fi network.

  1. From the left menu, select Connections
  2. Click New Wi-Fi
  3. Enter the connection details:
  4. Name: Electronic Load Connection
  5. IP: 192.168.1.98 (use a value compatible with your Wi-Fi network configuration)
  6. Port: 100

Return to the Widget List:

  1. Select Widgets from the left menu
  2. Put the Widget List into edit mode using the Edit switch located at the bottom of the screen
  3. Click on the Wrench at the top right of the screen
  4. Select the Constant Current Electronic Load connection

We are now ready to add the widgets we need. Let’s start with the first one:

  1. Click on the plus button in one of the free spaces
  2. Select the Slider widget to set the desired current drawn by the Electronic Load
  3. Replace the ? with the name of the widget: Current
  4. Click to configure the widget
  5. Enter the maximum value for the current: 2
  6. Choose a color for the slider and click Ok
  7. Switch back from the edit mode.

Generate the Code for the First Widget

Screenshot 2026-01-10 at 8.12.55 AM.png

From the left menu, open the Code Generator to create a new project:

  1. Click New
  2. Enter the name of the new project: Constant Current Electronic Load
  3. Enter the project details:
  4. Board: Raspberry Pico W (in case you have the Pico 2 W, select it instead. Arduino Manager will automatically handle the project configuration.)
  5. Communication Device: Built in WiFi (in case you prefer to use Bluetooth, select it instead. Arduino Manager will automatically handle the project configuration.)
  6. Connection: Electronic Load Connection. (Some of the connection details are copied from the connection, others will be entered.)
  7. Netmask: 255.255.255.0 (use a value compatible with your network configuration.)
  8. Gateway: 192.168.1.1 (use a value compatible with your network configuration.)
  9. SSID: Enter the name of your WiFi network.
  10. Password: Enter the password used to authenticate to the WiFi network.
  11. Connection Callback: off
  12. Disconnection Callback: on
  13. Click Widget Pins to configure the pins used by each Gpio pin
  14. Select the Slider widget and enter the required details:
  15. Pin: 17 (according to the schematics the Pin used to set the current is Gpio 17)
  16. Value at Power On: 0
  17. Click Generate

Now the new project is created and available in your iCloud drive.

Some additional steps are now required to open the project in Visual Studio Code (we assume that you have already configured the development environment. If not, use the official documentation: Getting started with Raspberry Pi Pico-series Microcontrollers).

For the remaining part of this Instructable we assume that you are using the Debug Probe).

  1. Start Visual Studio Code
  2. Open the Raspberry Pi extension from the left side menu
  3. Select Import Project
  4. Select the project: iCloud Driver -> Arduino Manager -> Constant_Current_Electronic_Load
  5. Click Import
  6. Create a lib folder
  7. Right click on the lib folder and select Open in Integrated Terminal
  8. Enter the following commands:
git clone --recurse-submodules https://github.com/ArduinoManager/AM_SDK_PicoWiFi.git
git clone --single-branch --recurse-submodules https://github.com/carlk3/no-OS-FatFS-SD-SDIO-SPI-RPi-Pico.git
cd no-OS-FatFS-SD-SDIO-SPI-RPi-Pico
git switch --detach tags/v3.6.2
  1. Click on Raspberry Pi Pico Extension on the left bar and select Configure CMake
  2. Ctrl + F5 to start the program.

Custom Code for the Current Widget

The generated code already set the value of the PWM pin automatically.

void slider_Current_callback(float value)
{
current = value;
/* Start your code (sliderCurrentCallback) */
/* End your code */
pwm_set_gpio_level(PIN_CURRENT, current);
}


but the value is in the range: 0 - 2. We need to transform that range in the proper duty cycle.

  1. Update the slider callback as follows:


void slider_Current_callback(float value)
{
current = value;
/* Start your code (sliderCurrentCallback) */

set_control_voltage(current);
return;

/* End your code */
pwm_set_gpio_level(PIN_CURRENT, current);
}


  1. Go to the top of the code and change the following section:


/* Start your code (defines) */
/* End your code */


as follows:


const uint16_t WRAP_VALUE = 255; // 16-bit PWM resolution
const float Vpwm = 3.29; // Maximum votage at output of the Pwm to DC filter
const float Rf = 1.12; // Feedback resistor for setting the desided current

void set_control_voltage(float current);


  1. Then go to the bottom of the code and add a new function:


/* Start your code (User Functions) */

void set_control_voltage(float current)
{
float control_voltage = current * Rf;

if (control_voltage > Vpwm)
{
control_voltage = Vpwm;
}

float duty_cycle = control_voltage / Vpwm;
uint16_t level = (uint16_t)((duty_cycle) * WRAP_VALUE);
pwm_set_gpio_level(PIN_CURRENT, level);
}

/* End your code */


As already mentioned, this function calculates the duty cycle required to obtain a proper DC voltage and then set it on the GPIO PIN.

Finally, we turn off the current when Arduino Manager disconnects from the Pico with this simple change:


void deviceDisconnected()
{
/* Start your code (deviceDisconnected) */
current = 0;
pwm_set_gpio_level(PIN_CURRENT, 0);
/* End your code */
}


  1. Press Ctrl + F5 to compile and run the code.

First Test

Screenshot 2025-12-30 at 6.06.52 PM.png
  1. In Arduino Manager, select Widgets from the side menu to open the Constant Current Electronic Load.
  2. Connect Arduino Manager to the Pico by clicking the Connect button and wait until the LED at the bottom left of the screen turns on.
  3. Move the slider to a small current value, for example, 0.5 A.
  4. Using a multimeter, measure the control voltage (the voltage across Rf​).
  5. If everything is working correctly, you should measure a voltage of approximately 0.5 V.

Reading the Control Voltage

Screenshot 2026-01-10 at 8.22.01 AM.png

Now we will measure the control voltage using one of the Pico’s Analog-to-Digital Converters (ADCs) and display this information in Arduino Manager.

Put the widget list in edit mode and and then follow the steps below:

  1. Add a Display widget
  2. Configure it as follows:
  3. Name: Current
  4. Variable: ctrl_voltage
  5. Unit of measure: [V]
  6. Number of Digits: 3
  7. Exit from the edit mode
  8. Go to Code Generator and select Widget Pins
  9. Select the Display widget and ente the following details:
  10. Pin: 26 (as per schematic)
  11. Read Value Every: 500ms
  12. Input Preprocess Function: yes
  13. Switch back from the edit mode.
  14. Click Generate to generate the code
  15. We need to convert the integer value read by the ADC to the voltage value with the formula:


value = adc_read();
voltage += value * Vref / 4095.0;


where Vref is the reference voltage used by the ADC that in this case is the power voltage (3.3V).

  1. To make better measurements we need to perform more ADC readings and average them. This is the purpose of this function to add at the really bottom of the file:
/* Start your code (User Functions) */

float read_mean_voltage()
{
int num_samples = 5; // Number of samples to average
float voltage = 0;
uint16_t value;

for (int i = 0; i < num_samples; i++)
{
value = adc_read();
voltage += value * Vref / 4095.0;
}
voltage = voltage / num_samples;
return voltage;
}


  1. Go at the top of the code in the section Start your code (defines) and add these lines:


const float Vcc = 3.3; // Pico Power Voltage
const float Vref = Vcc; // Reference voltage for the ADC

float read_mean_voltage();


  1. Finally, change the preprocess_display_ControlVoltage function as follows


float preprocess_display_ControlVoltage(uint16_t value)
{
float ret = value;
/* Start your code (preprocessDisplayControlVoltage) */

adc_select_input(0);
sleep_ms(10);
ret = read_mean_voltage();

/* End your code */
return ret;
}


  1. Go to the widget list (menu widgets) and connect to the board
  2. Set a current (e.g. 0.5A)
  3. The Display widget should display a value very close to the set current

Control Voltage ADC Readings Calibration

You may have noticed that the ADC readings at 0V are not exactly 0. For that reason we need to calibrate each ADC channel.

We are going to use a two points calibration (see Calibrating Sensors).

First we need to make some changes to the code.

  1. Download the class Calibrator and copy it into your project folder.
  2. Change the Start your code (defines) as follows


/* Start your code (defines) */

#include "calibrator.h"

...

Calibrator ctlr_voltage_calibrator = Calibrator(0, Vcc, 0, Vcc);

...

/* End your code */


  1. Modify the function preprocess_display_ControlVoltage as follows


/* Start your code (preprocessDisplayControlVoltage) */

adc_select_input(0);
sleep_ms(10);
ret = read_mean_voltage();

ret = ctlr_voltage_calibrator.calibratedValue(ret);

/* End your code */


  1. Upload and run the code

Now we have to identify the readings returned by the ADC to use for the calibration:


  1. Using a digital multimeter, read the 3.3V voltage at Pin 36 of the Pico.
  2. Modify the value of Vcc accordingly
  3. Connect the ADC pin to ground
  4. From Arduino Manager connect to the board
  5. Read the value measured by the ADC (let's suppose it is 0.014)
  6. Connect the ADC pin to 3.3V
  7. Read the value measured by the ADC (let's suppose it is 3.321)
  8. Modify the ctlr_voltage_calibrator definition using the value just read:


/* Start your code (defines) */
...
Calibrator ctlr_voltage_calibrator = Calibrator(0, Vcc, 0.014, 3.321);
...
/* End your code */

Downloads

Reading the MOSFET Temperature

Screenshot 2025-12-31 at 3.43.15 PM.png

As already mentioned, to avoid damaging the MOSFET, we continuously measure its temperature and display it in Arduino Manager. Later in the Instructable, we will automatically turn on the fan to keep the MOSFET as cool as possible.

To read the MOSFET temperature (via a thermistor) we initially configure Arduino Manager and calibrate the ADC.

Put the widget list in edit mode and and then follow the steps below:

  1. Add a Display widget
  2. Configure it as follows:
  3. Name: Temperature
  4. Variable: Temperature
  5. Unit of measure: ˚C
  6. Number of Digits: 2
  7. Exit from the edit mode
  8. Go to Code Generator and select Widget Pins
  9. Select the Display widget and ente the following details:
  10. Pin: 28 (as per schematic)
  11. Read Value Every: 500ms
  12. Input Preprocess Function: yes
  13. Switch back from the edit mode.
  14. Click Generate to generate the code
  15. Create a new calibrator


/* Start your code (defines) */
...
Calibrator ctlr_voltage_calibrator = Calibrator(0, Vcc, 0.014, 3.321);
Calibrator temperature_voltage_calibrator = Calibrator(0, Vcc, 0, Vcc);
...
/* End your code */


  1. Modify the function preprocess_display_Temperature:


/* Start your code (preprocessDisplayTemperature) */
adc_select_input(2);
ret = read_mean_voltage();
ret = temperature_voltage_calibrator.calibratedValue(ret);
/* End your code */


  1. Run the code and using Arduino Manager identify the values for the ADC calibration like we in step 11. Use the read values for the calibrator (we assume they are the same of the other ADC channel)


/* Start your code (defines) */
...
Calibrator ctlr_voltage_calibrator = Calibrator(0, Vcc, 0.014, 3.321);
Calibrator temperature_voltage_calibrator = Calibrator(0, Vcc, 0.014, 3.321);
...
/* End your code */


Now that the voltage reading is correct, we have to convert it into temperature. This is done in two steps:

  1. From the voltage measurement, we calculate the resistance of the thermistor
  2. using the thermistor resistor, we use the Steinhart–Hart equation to calculate the temperature

You will find all the details in a past Instructable: How to Measure a Remote Temperature Using Pico W and Arduino Manager.


  1. In the Start your code (defines) section add:
  2. the include for the mathematical functions
  3. the coefficients for the Steinhart–Hart equation (provided in the thermistor datasheet). Enter the values specified for the thermistor you are using
  4. thermistor resistor value @ 25˚C
  5. the value of the shunt resistor
  6. two heather for the conversion functions.


#include <math.h>

...

// Steinhart–Hart equation coefficients

float A1 = 0.003354016434680530000;
float B1 = 0.000256523550896126000;
float C1 = 0.000002605970120720520;
float D1 = 0.000000063292612648746;

float R25 = 10E3; // NTC Resistance @ 25 ˚C
float R = 10E3; // Value of the resistor used together with the thermistor (NTC) for the voltage divider

...

float calculate_rt(float voltage);
float calculate_temperature_celsius(float RT);


  1. At the very bottom of the file add the following functions:


float calculate_rt(float voltage)
{
// This formula is the inverse of the usual voltage divider formula, which,
// given the values of the two resistors, provides the output voltage.

return R * voltage / (Vcc - voltage);
}

float calculate_temperature_celsius(float RT)
{
// This is the Steinhart–Hart equation

return 1 / (A1 + B1 * log(RT / R25) + C1 * pow(log(RT / R25), 2.0) + D1 * pow(log(RT / R25), 3.0)) - 273.15;
}


Finally, complete the function preprocess_display_Temperature:


/* Start your code (preprocessDisplayTemperature) */

adc_select_input(2);
ret = read_mean_voltage();
ret = temperature_voltage_calibrator.calibratedValue(ret);

float RT = calculate_rt(ret);
float temperature = calculate_temperature_celsius(RT);
ret = temperature;

/* End your code */


Run the code, connect from Arduino Manager and the Temperature Display should display the temperature of the MOSFET.

Controlling the Fan

We could easily control the fan manually using a Switch widget in Arduino Manager, but we want to make everything automatic.

We can use the Code Generator to configure a digital GPIO to control the fan. The Code Generator will provide a variable that allows us to do this easily.

  1. Select Code Generator from the left menu
  2. Select Other Pins
  3. Click New Digital Pin
  4. Configure the new Pin as follows:
  5. Pin: 16 (as per schematic)
  6. Variable: fan
  7. Direction: Output
  8. Value at Power On: Low (fan is off when the Electronic Load starts)
  9. Switch back from the edit mode.
  10. Click Generate

The fan should operate when the MOSFET temperature rises above a threshold and should stop when the temperature falls below a threshold. The Thermostat widget helps us manage this behavior.

  1. Open the Widget list and switch to edit
  2. Add a Thermostat Widget
  3. Configure it as follows:
  4. Name: Temperature
  5. Variable: Temperature
  6. Low: 25
  7. High: 45
  8. Step: 5
  9. Select Code Generator from the left menu
  10. Switch back from the edit mode.
  11. Click Generate

Now we have available two variables:

  1. temperature_low
  2. temperature_high

that are automatically updated with the values set in Arduino Manager and a function thermostat_Temperature_check that can be used to react to the temperature getting either below or above the threshold changing the function as follows:


void thermostat_Temperature_check()
{
/* Start your code (thermostatTemperatureCheck) */
if (temperature < temperature_low) {
fan = false;
}
if (temperature > temperature_high) {
fan = true;
}
/* End your code */
}


  1. Upload and run the code.
  2. From Arduino Manager connect to the Pico.
  3. On the Thermostat widget select L to configure the lower threshold and set it to 20.
  4. Select H to configure the higher threshold and set it to 40.
  5. Set the current to an high value such as 1.5A to make the MOSFET temperature rise quickly.
  6. As soon as the temperature rises above 40 ˚C the fan should switch on.
  7. Set the current to 0A.
  8. The MOSFET temperature start to fall and as soon as it drops below 20 ˚C the fan should switch off.

Now turn off the Pico and then turn it back on or upload the code again. Then without changing anything on the Threshold widget set the current to 1.5A and wait for the temperature to rise above 40 ˚C.

The fan doesn't start. This because the previously set threshold have been lost at the Pico power off.

We need to store the thresholds in flash memory so they are preserved across power cycles.

  1. Download the flash_storage.h and flash_storage.cpp and copy them to your project folder
  2. Open the file CMakeLists.txt and add the flash_storage.ccp file


add_executable(Constant_Current_Electronic_Load
Constant_Current_Electronic_Load.cpp
flash_storage.cpp
)


  1. Update the Start your code (defines) section as follows:


#include "flash_storage.h"
....

flash_data_t cfg;


  1. Locate the /* Start your code (setup) */ section and add the following lines


/* Start your code (setup) */

if (!flash_load(&cfg))
{
cfg.fan_on_temp = 40.0f; // Default value at which the fan starts
cfg.fan_off_temp = 25.0f; // Default value at which the fan stops
cfg.shutoff_temp = 60.0f; // Default value at which the system shut off
}

temperature_low = cfg.fan_off_temp;
temperature_high = cfg.fan_on_temp;

/* End your code */


At startup the structure cfg is restored from the flash. If this is not possible because it was never saved before, each field is properly initialized.

Ignore shutoff_temp for now. It will be used later.

  1. The function thermostat_Temperature_callback is called each time Arduino Manager sets the Thermostat widget's low or high threshold. We have to update it in order to save the threshold values in the flash memory.


void thermostat_Temperature_callback(float value, bool low)
{
if (low)
temperature_low = value;
else
temperature_high = value;

/* Start your code (thermostatTemperatureCallback) */

cfg.fan_off_temp = temperature_low;
cfg.fan_on_temp = temperature_high;
flash_save(&cfg);

/* End your code */
}

The Threshold Widget

Screenshot 2025-12-31 at 6.30.12 PM.png

Now that we measure the temperature, we can prevent the MOSFET from overheating by setting a threshold above which the electronic load automatically turns off the drawn current.

  1. Open Arduino Manager, using the side menu open the Widget list and switch to edit
  2. Add a Threshold Widget
  3. Configure it as follows:
  4. Name: Max Temperature
  5. Variable: Max_temp
  6. Min: 60
  7. Max: 110
  8. Step: 2
  9. Value: 60
  10. Exit from the edit mode
  11. Go to Code Generator and click Generate
  12. This threshold has to be saved in the Flash memory as well


/* Start your code (setup) */

...

temperature_low = cfg.fan_off_temp;
temperature_high = cfg.fan_on_temp;
max_temp = cfg.shutoff_temp;

/* End your code */


  1. The function threshold_MaxTemperature_callback is called each time Arduino Manager sets the Threshold widget's value. We have to update it in order to save the threshold value in the flash memory.


void threshold_MaxTemperature_callback(float value)
{
max_temp = value;
/* Start your code (thresholdMaxTemperatureCallback) */

cfg.shutoff_temp = max_temp;
flash_save(&cfg);

/* End your code */
}


  1. Update the thermostat_Temperature_check adding the following lines:


if (temperature > max_temp)
{
// Emergency Stop
ctrl_voltage = 0;
set_control_voltage(ctrl_voltage);
amController.write_message("Current", 0);
}


  1. To test that it works as expected, proceed with the following steps:
  2. From Arduino Manager set the current to the maximum level: 2A
  3. The MOSFET temperature should rise very quickly until the fan starts
  4. If the fan and the heatsink are not effective enough to stabilize the MOSFET temperature, it will continue to rise
  5. As soon as the temperature reaches the threshold set by the Max Temperature widget, the current is automatically reset to 0. The fan keeps running to help cool the MOSFET.


Led Widget & Sound Alarm Widget

We can now add two useful widgets:

  1. LED widget: to see when the fan is operating
  2. Sound Alarm widget: to receive an audible alert when the temperature is close to the maximum allowed value

Follow these steps:

  1. Open the Widget list from the side menu and switch to edit mode
  2. Add a LED widget and configure it as follows:
  3. Name: Fan
  4. Variable: Fan
  5. Color: whatever you like
  6. Add a Sound Alarm widget and configure as follows:
  7. Name: Temperature Alert
  8. Variable: Temperature
  9. Sound: whatever you like
  10. Operator: >
  11. Threshold: 55
  12. Switch back from the edit mode.
  13. Open the Code Generator and click Generate
  14. Upload and run the code

Now the LED will turn on when the fan is operating, and as soon as the temperature reaches 55 °C, a sound will be played.

Power Calculation

Screenshot 2026-01-01 at 9.31.54 AM.png
Screenshot 2026-01-01 at 10.11.36 AM.png

May be useful to know what is the power drawn by the electronic load. The power is calculated using this formula:

Power = Vin * Irf

We know that:

Control Voltage

IRf = -------------------

Rf

Arduino Manager already receives the value of the (measured) Control Voltage, we just need to calculate the current. Since in our case Rf is 1Ω this calculation is unnecessary but but it serves as a good demonstration of Arduino Manager's capabilities.

  1. Open the widget list and switch to edit.
  2. Add a Display Widget and configure as follows
  3. Name: Current
  4. Variable: Ir
  5. Unit of Measure: [A]
  6. Number of Digits: 2
  7. Calculated Widget: Yes

This widget does not receive any information from the board; therefore, the Code Generator will not generate any code for it. However, Arduino Manager (more precisely, the Calculator widget) will keep it updated by calculating its value.

  1. Add a Calculator Widget and add a new formula
  2. Variable: Ir
  3. Formula: ctrl_voltage / 1
  4. Switch back from the edit mode.

We now have to measure Vin. We proceed as we did for measuring the control voltage:

  1. Open the widget list and switch to edit.
  2. Add a Display Widget and configure it as follows:
  3. Name: Vin
  4. Variable: Vin
  5. Unit of Measure: [V]
  6. Number of Digits: 2
  7. Calculated Widget: No
  8. Switch back from the edit mode.
  9. Select Code Generator
  10. Select Widget Pins
  11. Select Display widget for Vin
  12. Configure the Pin as follows:
  13. Pin: 27
  14. Read Value Every: 500ms
  15. Input Preprocess function: Yes
  16. Click Generate


The generated code has to be customized as follows:

  1. In the section Start your code (defines) add


float R5 = 30e3;
float R4 = 3e3;

...

Calibrator vin_calibrator = Calibrator(0, Vcc, 0.014, 3.321);


The calibrator for this ADC channel has been configured like the other channels, its better define the specific values for the channel using the procedure previously described.

  1. Finally, update the preprocess_display_Vin:


float preprocess_display_Vin(uint16_t value)
{
float ret = value;
/* Start your code (preprocessDisplayVin) */
adc_select_input(1);
ret = read_mean_voltage();
ret = vin_calibrator.calibratedValue(ret);

float k = R4 / (R5+R4);
ret = ret / k;

/* End your code */
return ret;
}


  1. We now need a (calculated) Display widget to display the Power.
  2. Name: Power
  3. Variable: Power
  4. Unit of Measure: [W]
  5. Number of Digits: 2
  6. Calculated Widget: Yes
  7. The last configuration is to add a new calculation formula to the Calculator widget:
  8. Variable: Power
  9. Formula: Vin * Ir

Current Values Sequence

Screenshot 2026-01-01 at 12.20.37 PM.png

For testing your device, you may need to apply a pre-defined sequence of currents to the load. This can be easily done in Arduino Manager by adding a Value Scheduler widget.

  1. Open the widget list and switch to edit.
  2. Add a Value Scheduler widget and configure it as follows:
  3. Name: Values
  4. Variable: Current
  5. Start on Connection: No
  6. Repeat Sequence: No
  7. Time Slot 1: 2000ms / 0.5
  8. Time Slot 2: 1500ms / 1
  9. Time Slot 3: 1000ms / 2
  10. Time Slot 4: 100ms / 0
  11. Now click on Start. The sequence will begin, and the electronic load will draw the pre-defined currents from the load

Conclusion

It has been a long journey, but in the end we created an inexpensive yet powerful tool—the Electronic Load—that can be effortlessly controlled from an iOS or macOS device.

Arduino Manager proves to be a compelling alternative to traditional device GUIs, eliminating the need for physical displays, endless lines of code, and hours of development just to achieve a polished interface.

With Arduino Manager, you can design, control, and monitor even complex systems in a matter of minutes.