Non-contact Direct Current Measuring from a Solar System With a HALL-sensor

DC Current measure with Arduino

The solar energy system at my house delivers all the energy back to the electricity grid. In the Netherlands you will receive money back from the energy company for this. On the one hand because this is only a small amount per kW and because it is expected that this return payment will stop, the idea is to use the generated energy yourself.
The problem with using it yourself is that electrical energy is there when it is not so needed, namely during the day. So we have to find something to store electrical energy. You can do this with batteries, but that is very expensive to purchase. It can also be done by heating water in a boiler and using that water at a time of your choice.
I chose this option.

The boiler is a so-called flow boiler. That is to say, when you tap hot water, cold water flows back into the other side.
The boiler is included in a central heating system, which works on natural gas and which has tap water option. The installation is designed in such a way that if there is no or insufficient hot water in the boiler, the water is heated by the central heating installation.
In other words, even if the sun does not provide enough energy, there is enough hot water. In my case, I use the hot water for shower.

My solar energy system is of the type SolarEdge SE4000H. The important data for the project are:
Max DC voltage 480 Vdc
Operating voltage Range 270 – 480Vdc
Max input current 11.5 Ampdc
Max output power 4000VAac
Installed solar energy is 4.5 kW peak

User experience is that of the 4.5kW peak installed power we generate a maximum of 3.5kW.

A warning is in order here !! Direct current is a very dangerous type of current. Although the danger of electrocution is many times lower than with alternating current, it can cause a fire much easier. A slight corrosion on the link or bridging contacts can be sufficient for disintegration and eventual fire. It is very important to have your installation checked regularly by a professional !!

The above was also the reason to measure the direct current generated by the solar cells without contact.

How the system works
My boiler has a consumption of 800 W. This means a current of about 3.5 Amp. At DC level this will be about 4 Amp if you take into account conversion loss. So what we want is to determine a direct current of about 4 Amp or higher and let switch a relay on it. They relay is used to switch the boiler element “on”. This prevents the boiler from being switched “on” when there is too little sun. In the Netherlands, electricity per Kwh is 3.5 times as expensive as the equivalent of gas. Hence this exercise.
And ofcourse that need to be done contactless for the aforementioned reason.

Design
There are four mainparts of design:
+ The Hall-sensor (HSTS16L20A)
+ The Display voor result (WC1602A 2 rows 16 Charachters)
+ The central processing unit (Arduino Nano V3)
+ Relay and control (Arduino module HW-307)

HALL-sensor
One possibility to measuremend contactless is to do this is by using a HALL sensor.
Fortunately, there is also a HALL-effect sensor type with split core transformer that can do the job (as picture on right). It is the Hall-Effect Split-Core Sensor HSTS16L module. With split core current sensor type, not alteration on the existing system is required. In our case, we use the HALL sensor HSTS16L/20A.

The HALL sensor is not a common component for the radio amateur, therefore a short explanation.
It utilizing HALL-effect phenomenon which voltage is produced from the movement of current within the region of magnetic field. The voltage produced by HALL-effect is directly proportional to the applied current making it suitable to estimate the applied current from the voltage sensed.
The HALL-sensor can measure current in 2 direction. Reverse current will not damage the sensor but the voltage produced will be in reduced.
If you want to know more, visit the WIKI page.

The supply voltage of the HALL-sensor  HSTS16L/20A is 5V and the output voltage 2.5 V center and +/- 625 mV deviation.  This means that a current of 20 Amp max, gives a voltage deviation of max + or – 625mV. This means that 1 Amp is 625/20 = 31.25 mV/Amp.!! And that around the center voltage of 2.5 V. This is certainly a challenge to measure that!
The reasult of 31.25mV/Amp is needed for the float ‘mVperAmpValue’ in the software program.

Be Aware!!
The HALL-sensor is magnetic sensitive and has a small deviation of +/- 625 mV. This means that current result measured can affected by magnetic radiation. So the measured current result will be not exact. Even when no measurement is made there can be a result!!
Therefore a “NUL” offset is needed. In the writen software program it will be done automatically. In ‘SetUp’ part of the software, when no current flows true the HALL-sensor, a measure is made. The result (+ or -) will be stored in ‘currentOffset’. In measure current the offset will be substract or count by the measured result and then displayed.

The HALL-sensor has 5 wires. To connect I used a DIN-connector 5 pole with pins spaced over 240 degrees.
pin 1 = Black = 0 V
pin 2 = White = Vref
pin 3 = Cable shield = Gnd
pin 4 = Yellow = Vout
pin 5 = Red = +5 V

The Display
I chose a standard display that has 16 characters and two rows. It is known under type number WC1602A. For this project I chose for a separate Display-PCB. You can find the drawing here.

The display module has 16 contacts. Ten contacts of these are used in this project, which are connected to the main board via a 10-pin connector. The display is equipped with LED background lighting. A 100 Ω resistor is included in the anode line to damp it slightly. The contrast is adjusted with a 10-turn trim pot of 10KΩ.
The display inputs DB0 – DB3 are fed out through a connector that is not used in this project. With these display inputs, special actions can be performed with the display, including dimming the display, allowing a character to run in, for example.

How the program works
Standard for the arduino is a program flow that starts with initialization, followed by the setup routine and then the main loop.
In the initialization phase, the fixed values are assigned, such as those for the display, the Hall sensor and so on. Then comes the setup phase. The one-time variable settings are programmed here, such as the start screen and the the force to start with the ‘offset’ routine. Then in the mainloop [void loop()] the first thing done is testing of the “Offset Buton” is pressed. When the button is pressed or set in SetUp part of the program, the ‘offsetRead’ selector is set. This means that main routine is continued with the -DC current Measurement- (sub)routine. The result in ‘currentResult’ is then used in the -Offset calculate- (sub)routine. The loop wil be now -Calculate DC-current –> Offset calculate –> for at least 2.5 sec. After 2.5 sec, the measured result is placed in “currentOffset” and the program go back to central part where it displayed the result.

Current sensor is a sensitive sensor. The output reading of the sensor produces electrical noises or fake current values even when there is no current detected. It is more obvious if the measurement is in a smaller time frame. In order to greatly reduce this phenomenon, multiple samples must be taken for averaging and initial offset sometimes must be done. Our code is designed to display a value which is derived from averaging 1000 samples in every second. Each sample is recorded every 1 milli second (0.001 second). The single averaged value is then to be displayed at LCD Display. With this, the fluctuation of value is way lesser compare to taking 1 sample reading every second.

The second problem could be the false signal and accuracy problem. Each sensor has its own deviation error. When there is no current sensed, the sensor might not be 100% at middle point of voltage value. Some might be remaining at few milli voltages above / below the middle point even though after averaging. This might be due to voltage supplied not in exact 5V or due to the sensor itself.

The central processing unit
As earlier mentioned the Arduino Nano has been used. Arduino has the ability to measure current by voltahe swing in the ADC analog input pin. Arduino NANO has 8 input pins. The analog input pins will map input voltages between 0 and 5V into integer values between 0 and 1023 with resolution of 4.9mV per unit (5.00V / 1024 units).
All sensors that connected to analog input must be measured by voltage value. In order to provide the current value, the sensor actually providing voltage value that related to measured current value.

The drawing from the central processing unit you find here.
In the schematic you will find 4 connectors namely:
J1 = for the push button
J2 = for the HALL sensor
J3 = for the Display
J4 = for the relay connection

If you short the contacts 3 – 4 of connector J1, the software program will forcibly go into the “Offset” level (sub) routine. The rest of the connectors are clear.

The built-in ADC is sensitive to supply voltage variation. If the supply voltage varies due to load, the ADC will also vary accordingly (bias offset). With a voltage variation due to load 4.95 V – 5.05 V, which is 100mV, the ADC output also fluctuates in the same order. If you try to measure a very small voltage of 625 mV a deviation of 100 mV is about 16% !!!! That is far too much for an accurate measurement. The only solution is either to connect an extremely stable power supply or split up the power supply in one for the NANO and one for the load, so I have done.

Relay and control
Used is the Arduino HW-307 Relais module with optocoupler for voltage separation. Type 5V and one changeover contact. Trigger current 5mA. Max load AC 250V/10A or DC 30v/10A. When trigger voltage is HIGH the relay is in rest.

Software Codes
The final step would be adding source code onto Arduino board. I assume you have installed the Arduino IDE Software. Once you have downloaded and install the IDE software, you may download the code file ‘Measure DC-current Solar system” (.ino). The source code are fully explaind in the code itselfs.

Files
Drawing sheet Display Unit
Gerber file Display_Unit 
  Pay attention!! The PCB-layout is for the display HY1602E and not for the described display WC1602A. The effect of both is the same.
Drawing sheet Processor unit
Gerber file Central processor unit
– Software for the Measure DCcurrent Solar system.

/********************** Measure DC-current Solar system V 0.6 ******************************
* DC Solar Current measure from PA3BYB in according to Solarduino HTTPS://solarduino.com
* ***************************************************************************************** 
* 
* The aim of the program is to switch on a water boiler if the generated solar energy is
* sufficient for this.
* In order to measure the DC-current coming from the solar panels, non-contact mesuring is
* necessary. A HALL-sensor of the HSTS16L/20A type is used for this.
* 
* ******************* How the program works **********************************************
* After initialization and setup routine, the program start with selecting the buttons.
* When button is pressed, the offsetRead selector is set (1). This means that loop routine
* is continued with the -DC curren Measurement- routine. The result in "currentResult" is 
* then used in the -Offset calculate- routine. 
* The loop wil be now -Calculate DC-current --> Offset calculate --> for at least 2.5 sec.
* After 2.5 sec, the measured result is placed in "currentOffset" and the program go back
* to central part where it displayed the result.
* 
* ******************* HALL-sensor HSTS16L/20A ********************************************
* HALL Sensor center voltage is 2,5V The deviation voltage arround the center voltage is 
* max +/- 0,625 V for 20 Amp full scale. This means that 1 Amp is 625/20 = 31.25 mV/Amp.
* This reasult is needed for the float mVperAmpValue.
* 
* The HALL-sensor has 5 wires. To connect I used a DIN-connector 5 pole met pennen verdeeld
* over 240 degrees.
* pin 1 = Black = 0 V
* pin 2 = White = Vref
* pin 3 = Cable shield = Gnd
* pin 4 = Yellow = Vout
* pin 5 = Red = +5 V
* 
* The HALL-sensor is magnetic sensitive and has a small deviation of +/- 625 mV. This means 
* that current result measured can affected by magnetic radiation. So the measured current 
* result will be not exact. Even when no measurement is made there can be a result!!
* Therefore a "NUL" offset is needed. In this program it will be done automatically. 
* In situation no current flows true the HALL-sensor a measure is made. The result (+ or -) 
* will be stored in currentOffset. In measure current the offset will be substract or count 
* by the measured result and then displayed. 
* 
* ******************* Board type used ****************************************************
* The board type I used is a Nano compatible type with the ATmega328. 
* It is a older type (<2018) therefore the IDE must be set to it. This is done as follows,
* select:<<tools>> <<Processor>> <<ATmega328P>> with old <<Old Boot Loader>>
* 
* The Nano can operate on three different voltage sources: 
* - 6 - 20 V unregulated pin 30; 
* - 5V regulated pin 27;
* - USB
* 
* The built-in ADC is sensitive to supply voltage variation. If the supply voltage varies 
* due to load, the ADC will also vary accordingly.
* With a voltage variation due to load 4.95 V - 5.05 V, which is 100mV, the ADC output also 
* fluctuates in the same order. If you try to measure a very small voltage of 625 mV then a 
* deviation of 100 mV is about 16% !!!! That is far too much for an accurate measurement.
* The only solution is either to connect an extremely stable power supply or split up the 
* powersupplay in one for the NANO and one for the load.
* 
* A1 = Analog pin in
* The program code read the voltage on pin A1 of the Hall-sensor
* 
* D2 = Digital out pin
* The program write to this pin to switch the relay
* 
****************************** Relais *****************************************************
* Relais module with optocoupler for voltage separation. Type 5V and one changeover contact.
* Trigger current 5mA. Max load AC 250V/10A, DC 30v/10A
* When trigger voltage is HIGH the relay is in rest.
* 
***************************** Some Functions **********************************************
* "float"
* float is a datatype for floating-point numbers. Floating-point numbers are often used to 
* approximate analog and continuous values because they have greater resolution than integers. 
* Floating-point numbers can be as large as 3.4028235E+38 and as low as -3.4028235E+38. 
* They are stored as 32 bits (4 bytes) of information.
* 
* "millis()"
* millis() Returns the number of milliseconds passed since the Arduino board began running 
* the current program. This number will overflow (go back to zero), after approximately 
* 50 days.
* 
* "analogRead()"
* analogRead() Reads the value from the specified analog pin. Arduino boards contain a 
* multichannel, 10-bit analog to digital converter. This means that it will map input 
* voltages between 0 and the operating voltage 5V into integer values between 0 and 1023. 
* On an Arduino UNO this yields a resolution between readings of: 5 volts / 1024 units 
* or, 0.0049 volts (4.9 mV) per unit.
* 
* "void()"
* The "void()" keyword is used only in functions declaration. It indicates the the function 
* is expected to return NO information to the function from wich it was called.
* Use in program it works like a subroutine.
* Insite a subroutine is is NOT possible to run a second (or more) sub-sub routines. Only 
* one subroutine is possible.
* Another problem with subroutines is that they take a lot of time. Sub-routines are slow 
* down the main program very much.
*/

//////////////////////////// Initialization Fix constants //////////////////////////////////
//******** Initialization LCD Display 1602A 16x2 charachters ***********
// The Display use data pin 4, 5, 6, 7, and 8 = RS; 9 = E; RW is connect to GND

#include<LiquidCrystal.h> // Load LCD Library
LiquidCrystal lcd(8,9,4,5,6,7); // LCD-dislay 1602
unsigned long startMillisLCD;
unsigned long currentMillisLCD;
const unsigned long periodLCD = 1000;
int numRows = 2; // Init number of rows Display
int numCols = 16; // Init number of character Display

//******** Initialization HALL-sensor HSTS16L20A **********************
// The HSTS16L/20A Hall-Effect Current Transformer rated at 20A, 2.5V +/- 0.625V, 
// This means that the mVperAmp will be 625 mV / 20A = 31.25 mV/A 
float mVperAmpValue = 31.25 ; // Denominator can't be "nul"!!!

//******* Initialization Reading pin Arduino is A1 **********************
// The A-series pin's Arduino Uno are analog reading pin with a ADC function. This means the
// voltage will be convert in byte words; 2 for integer and 4 for floating point numbers
int analogPin = A1; // ArduinoUno pin A1 is analog "in"
int decimalPrecision = 2; // max two digids behind the floating point

//******* Initialization Relais on Digital Pin 12 ***********************
int digitalPin = 2 ; // Digital Pin 2 is used for switching relay

///////////////////////////// Initialization Variabele ////////////////////////////////////
//
//***** Initialization DC Current Offset variables **********************
int offsetRead = 0; // To switch functions autocalibrate/normal
float middleVoltage = 2500; // Center voltage from the HALL-sensor
float supplyVoltage = 5060; // This voltage depends on the supply voltage 
float currentOffset = 0.00; // The (auto) offset deviation from autocalibrate
float offsetLastSample = 0; // to count time for each sample (1 sample // is 1 milli
float offsetSampleCount = 0; // Count number of sample

//******** Initialization DC current measurement ************************
float sampleRead = 0; // to read the value of a sample
float sampleLast = 0; // Count the time for each sample (1 milli 1 sample)
float sampleSum = 0; // Accumulation of sample readings
float sampleCount = 0; // To count the number of samples
float currentMean = 0; // result of calculate the average value
float roughResult = 0; // result without offset value
float currentResult = 0; // final result of the measure

/**************************************************************************************
* START PROGRAM
***************************************************************************************/
void setup() {
pinMode(digitalPin, OUTPUT); // Digital pin 12 is now output
digitalWrite(digitalPin, HIGH); // Relay is switch off

Serial.begin(9600); // SetUp serial display
lcd.setCursor(0,0); // Cursor placed on first character
lcd.begin(numCols,numRows); // LCD has 16 characters in 2 rows

startMillisLCD = millis(); // start counting time for Display

lcd.print(" PA3BYB ");
lcd.setCursor(0,1);
lcd.print("Solar Amp meter");
delay(4000);
lcd.clear();

offsetRead = 1; // Start witch offset routine
}

//********************************** Main Loop ****************************************
void loop() { 

//************** Button Select ****************
int buttonRead; // Read pressed button
buttonRead = analogRead(0); // Read analog pin A0
if (buttonRead < 60) // 250 mV / 4.9 mV = 127 units
  { lcd.clear(); lcd.setCursor(0,0); lcd.print ("Press Offset"); delay(1000);}
  else if (buttonRead <200) // 980 mV / 4.9 mV = 706 units
    { lcd.clear(); lcd.setCursor(0,0); lcd.print ("Offset routine"); delay(1000);
      offsetRead = 1; // Start Offset sub-routine
    }
dcCurrent();
displayCurrent();
}

//********* Subroutine DC Current Measurement **************
void dcCurrent()
{
  if(millis() >= sampleLast + 1); // Every one milli sec. taken one reading
{
sampleRead = analogRead(analogPin) - ((middleVoltage/supplyVoltage)*1024); // Read sample
sampleSum = sampleSum + sampleRead;
sampleCount = sampleCount + 1 ; // next count
sampleLast = millis(); // reset time for next sample read
}
  if (sampleCount == 1000) // after 1 sec.) do calculation and display result
{
currentMean = sampleSum/sampleCount; // calculate average current value
roughResult = (((currentMean/1024)*supplyVoltage)/mVperAmpValue); // calculate rough result in amp
currentResult = roughResult + currentOffset; // Final result is result + offset

sampleSum = 0; // reset accumulate sample for next cycle
sampleCount = 0; // reset nummber of sample for next cycle
}


//**************** Offset calculate *****************
// when offsetRead = 1 the "Offset calculate" program part will be run
if (offsetRead == 1) // calulate the offset current
  { 
  currentOffset = 0;
  if (millis() > offsetLastSample) // Every one milli sec. taken one reading
  {
offsetSampleCount = offsetSampleCount + 1;
offsetLastSample = millis();
}
if (offsetSampleCount == 2500) // If offsetSampleCount # 2500 (2.5 sec) go back to DC current measure
{ // 
currentOffset = - currentResult; // currentOffeset == currentResult

offsetSampleCount = 0; // Reset for next offest calculate
offsetRead = 0; // Calculate offset is ready, go back to DC current measurement
}
}
}

//********* Display Momentane Current **********
void displayCurrent()
{
currentMillisLCD = millis();
if (currentMillisLCD - startMillisLCD >= periodLCD)
{
lcd.clear();
lcd.setCursor(0,1);
lcd.print(currentResult,decimalPrecision);
lcd.print(" Amp");
(startMillisLCD = currentMillisLCD); 
}

if (currentResult >= 2)
{ digitalWrite(digitalPin, LOW); lcd.setCursor(0,0); lcd.print ("Relay switch on");}
if (currentResult <= 2)
{ digitalWrite(digitalPin, HIGH); lcd.setCursor(0,0); lcd.print ("Relay switch off");}
}

/******************************************************************************************
*

//************************* Switch Relais ************************************
if (offsetRead == 0) { // if no offset button go further

if (currentResult > 2) // if current is > 2 Amp
{
callSubRelay(); // Switch relay
}
}


//****************************** Relay handling **********************************
void callSubRelay()
{
digitalWrite(digitalPin, LOW);
lcd.setCursor(0,0);
lcd.print ("Relay switch on");
delay (4000);
digitalWrite(digitalPin, HIGH);
lcd.setCursor(0,0);
lcd.print ("Relay switch off");
delay (4000);
}
*/

The developed software is sufficient for the first experiments, but adjustments still need to be made for definitive use. These will follow as soon as possible.

Henny, PA3BYB

DC Solar Current measure system Developt by PA3BYB in according to the idea of Solarduino HTTPS://solarduino.com