14. MKArduinoLogger

Preface

The MK arduino ( S0 based ) logger is probably one of the most powerful loggers in the arsenal of jSunnyreports. Simply put; This setup will work with every brand/type of inverter. I use this logger too to log all my Steca inverters and my Gridfit inverter. In this (long) page I will explain how to get everything to work properly.

prerequisites

All prerequisites will be explained too, so don’t worry 🙂

  • At least one S0 bus kWh meter
  • 470 ohm resistor 1/4W ( one for every S0 meter )
  • Arduino ( Arduino MEGA is used in this tutorial )
  • A computer ( which is capable of running Java ).

S0 meter

s0

Above picture is an example for a DIN S0 kWhmeter. Its a simple, digital kWh meter which can be placed on a DIN rail in a special utility box. For more pictures visit ( Dutch ) http://www.familie-kleinman.nl/energie/omvormerbord-versie-2-0/

The S0 interface is the little gem in these DIN meters. It will give a short pulse for every unit of electricity that passed the meter. In above picture one pulse is given for every 0.5Wh ( 0.5Wh/imp ). This means that 2000 pulses will be given for every 1kWh electricity produced.

Note: When you buy a DIN S0 meter make sure you have a 0.5Wh/imp or 2000Imp/kWh version as it gives a lot more pulses then a 1000Imp/kWh version.

More about connecting the S0 later on in this chapter.

Arduino

arduino-mega-2560

You will need an Arduino too. The S0 meters will be connected to certain pins on the Arduino board. I used a Arduino MEGA 2580 board as it has 4 pins hardwired to the interrupt handler of the processor. The smaller Arduino’s only have two pins with an interrupt handler.

The Arduino will act as a a first barrier and processor for all pulses received. But the Arduino can’t do all, hence we need a low powered computer to do the rest of the work.

The Arduino receives the pulses, will evaluate them if they are valid and if they are will pass them on to the computer.

Interrupt handler?

Help! This is getting too technical! What is an interrupt handler?

I expected this question :). When a pulse arrives from the S0 meter we want to Arduino to do something with it. Just see this pulse as someone ringing on the doorbell of the Arduino. The Arduino will answer and do something with the pulse.

An interrupt is nothing more of telling the processor it should stop what its doing right now and pay attention to what rang on the doorbell.

The hardware

Now how to connect everything?Lets assume you want to connect 4 inverters. First we need to identify which pins have an interrupt handler. These are:

  • PIN 2 ( IRQ 0 ),
  • PIN 3 ( IRQ 1 ),
  • PIN 20 ( IRQ 2 ),
  • PIN 21 ( IRQ 3 )

arduinomega2560_r2_front

Connecting a S0 meter is easy.

schematics

And you need to do this for the other inverters as well. You can connect all the GND (Ground) wires with each other and connect them to one of the GND pins on the Arduino. Now connect your Arduino with your computer using the USB cable.

Arduino configuration

Now you have to upload the right software ( the Sketch ) to the Arduino to get it up and running. Download the Arduino software from here. Lets discuss a few critical parts of the software sketch here.

The Arduino sketch is fairly simple. What is does is this:

  • Do some kind of setup
  • Tell the Arduino what to do when an interrupt occurs

And that is it! 🙂

Init

// Inverter one
#define INVERTER1_INTERRUPT 0
#define INVERTER1_PIN 2        
unsigned long inverter1FallTime;  //Time of front raising
unsigned long inverter1RiseTime;  //Time of front falling
String inverter1String = "1";

You will find the same piece of code for all 4 inverters in the code. What you see is:

The pin where inverter1 is attached to is PIN 2 with IRQ 0 ( at least it is defined ). Two variables when a pulse occurs,one for the start and one for the end of the pulse. And last but not least a variable which is sent to the computer when a correct pulse occured.

   Serial.begin(9600);
   attachInterrupt( INVERTER1_INTERRUPT, Inverter1InterruptHandler, CHANGE );

This tells the Arduino that the serial output runs at 9600 baud and to run the code in “Inverter1InterruptHandler” when an interrupt on IRQ 0 occurs. And this is done when the pulse starts and when the pulse ends.

   pinMode( INVERTER1_PIN, INPUT );
   digitalWrite( INVERTER1_PIN, HIGH );

This tells the Arduino that the PIN we are using is an INPUT pin and the default is set to HIGH ( 5V ). So when there is no pulse the pin measures 5V. When a PULSE occurs this is dropped to LOW and a specific amount of milliseconds later it will go to HIGH again. That time between LOW and HIGH is the length of the pulse.

// SCHELLCOUNT INFO
unsigned long MIN_PULSE_WIDTH_SCHC = 20;        // minimal pulse width SCHELLCOUNT;
unsigned long MAX_PULSE_WIDTH_SCHC = 55;        // maximal pulse width SCHELLCOUNT;

// VOLTCRAFT PULSE
unsigned long MIN_PULSE_WIDTH_VOLT = 20;        // minimal pulse width VOLTCRAFT;
unsigned long MAX_PULSE_WIDTH_VOLT = 55;        // maximal pulse width VOLTCRAFT;

Two variables used to determine the minimum and maximum time how long a pulse can take. This can differ from your S0 meter so check the documentation that came with it.

The interrupt handler

irqhandelr

This is de code that is executed when a CHANGE occurs in the pins level ( HIGH to LOW and LOW to HIGH ). The code has two pieces.

if ( digitalRead( INVERTER1_PIN ) == LOW ) 
   {
      inverter1FallTime = millis(); //get time of pulse going down
   }

When the state of the pin went to LOW we know that a pulse has started. We put the time it started into the FallTime variable. Nothing more is done.

  else
   {
      inverter1RiseTime = millis();                              //get time of pulse going up
      interruptTime = inverter1RiseTime - inverter1FallTime;      //measure time between down and up

      if ( interruptTime >= MIN_PULSE_WIDTH_SCHC && interruptTime <= MAX_PULSE_WIDTH_SCHC ) 
      {
         Serial.print(inverter1String);  
         ChangeLedStatus();
      } else {
        if ( DEBUG ) { 
           // pulse was too short or too long.
           Serial.println( interruptTime );
        }  
        
      }
   }

When the pulse ends and goes from LOW to HIGH again. The rest of the work is done. The time is saved in RiseTime. And the difference between the two is stored in the variable “interruptTime” Now a simple check is done if the time of the pulse is between the minimum and maximum spec of the s0 meter. If that is the case a character is yelled over the Serial line. This character will be picked up by the other part of the software discussed later in this chapter.

Summary

So what happens is:

Electricity is produced by your PV set. When a certain amount is generated a pulse is given by the S0 meter. This pulse is registered by the Arduino, it checks if the pulse is correct and it will yell a unique character for this inverter over the Serial/USB line to the computer it is attached to.

Upload

Now upload the sketch to your Arduino using the Arduino software. See https://www.arduino.cc/en/main/howto for more information how to do this

Logger software

Now lets take a look at the logger software which runs on your computer.

Directory content

dircontents

  • Classes, contains the compiled java classes
  • Conf, contains the configuration file needed
  • Lib, contains libraries that are needed
  • Src, contains the source files if you want to do some manual hacking yourself
  • Arduinologger.jpr, Project file when you want to open the project in jDeveloper
  • runlogger.cmd. command line file to run the logger.

For a normal operation you do not need to go into the source files you just need to copy some files, edit the config file and edit runlogger.cmd

rxtx

The first step is to get RXTX up and running. This differs for every operating system. If you are on Windows you need to copy rxtxserial.dll to c:/windows/system32 directory. If you are on linux unzip the zip file and read the installation file.

Runlogger.cmd

The file consists of one single line that needs to be editted.

java.exe -client -classpath c:\loggers\arduino\classes;c:\loggers\arduino\lib\RXTXcomm.jar rxtxtest.SerialTest COM5

Two parts need to be modified:

c:\loggers\arduino\classes;c:\loggers\arduino\lib\RXTXcomm.jar

Both paths must exist!

COM5

This has to be the COM port attached to your Arduino.

Settings.ini

You will find 4 blocks in it. One for every inverter.

#logger ( listens to '1' from the arduino )
logger1.listento = 1
logger1.maxwatt = 500
logger1.pulses = 2000
logger1.outputlocation = c:/outputlocation/logger1/

First of all to which character does the logeger listen to. Leave this untouched.

logger1.maxwatt = 500

Determines the maximum watt that can be produced by this inverter. This will prevent rogue pulses from messing up your charts.

logger1.pulses = 2000

Determines the amount of pulses counted for every kWh.

logger1.outputlocation = c:/outputlocation/logger1/

The outputlocation where you want to save the logfiles. Note: end this path with a slash. Else saving the logfiles will fail. And always use forward slashes!

Run

After editting both files just start the cmd file.

My slightly editted version has this as output on the screen:

output

Inverters.conf

inverter.1.mandatory.invertername=Somename
inverter.1.mandatory.wattpeak=1000
inverter.1.mandatory.kwhkwp=900
inverter.1.mandatory.invertertype=14
inverter.1.mandatory.inputdirectory=C:/temp_mk/development_input/gridfit
inverter.1.mandatory.barcolor=255,128,64
inverter.1.mandatory.linecolor=255,128,64
inverter.1.mandatory.fromdate=23-03-2011
inverter.1.optional.comparelinecolor=255,40,0
inverter.1.optional.correctionfactor=1.00
inverter.1.optional.inclination=45
inverter.1.optional.orientation=180
inverter.1.optional.tilldate=