Go Down

Topic: Industrial Modbus Power Meter(Acuvim L) readed in Arduino UNO (Read 4786 times) previous topic - next topic

David_am

May 18, 2014, 07:17 pm Last Edit: May 18, 2014, 10:20 pm by David_am Reason: 1
I was reading over the internet how to create a acceptable power meter during this searching I only found some circuits but those doesn't have all the parameters i have to use to my proyect, and the error of those circuits was unpredictable. The parameters I was looking for are:

Voltage, Current, THD, Individual Harmonic Analisis, Ractive Power and Power Factor. All values for Three Phase system.

The best idea of power metering using simple electronic elements and one arduino used for process the signals was openenergymonitor.org, (EMON). But i was never capable to calibrate it the error in Power Factor was terrible for small currents.
 
My next idea was using an industrial meter but, how to comunicate this to my Arduino?. The used Modbus protocol with a library called Simple-Modbus-Master and Simple-Modbus-Slave and it was very usefull but i only used this for communicate arduinos.  

Looking around the internet I Found An interesting power meter, The Acuvim-L And I bought one the Acuvim-DL vercion, there are many version the diference is the parameters it reads, but all of then has modbus protocol.

In the beginning of the tests of communicate with my arduino, I was having some troubles but the power meter has an icon that indicate that the comminication is ok and it was online. But i didnt have any response in the arduino, The problem was the timing between the byte sending. So I used a low baundrate.
 
Here is the code I used in the Arduino, In This case the Master Modbus point.

Quote
#include <SimpleModbusMaster.h>
#include <SoftwareSerial.h>
#include <SimpleTimer.h>

SoftwareSerial mySerial(10, 11); // RX, TX
SimpleTimer timer;

//////////////////// Port information ///////////////////
#define baud 9600
#define timeout 1000
#define polling 200 // the scan rate

// If the packets internal retry register matches
// the set retry count then communication is stopped
// on that packet. To re-enable the packet you must
// set the "connection" variable to true.
#define retry_count 10

// used to toggle the receive/transmit pin on the driver
#define TxEnablePin 2

#define LED 9

// This is the easiest way to create new packets
// Add as many as you want. TOTAL_NO_OF_PACKETS
// is automatically updated.
enum
{
 PACKET1,
 PACKET2,
 PACKET3,
 PACKET4,
 PACKET5,
 PACKET6,
 PACKET7,
 TOTAL_NO_OF_PACKETS // leave this last entry
};

// Create an array of Packets to be configured
Packet packets[TOTAL_NO_OF_PACKETS];
packetPointer packet1 = &packets[PACKET1];
packetPointer packet2 = &packets[PACKET2];
packetPointer packet3 = &packets[PACKET3];
packetPointer packet4 = &packets[PACKET4];
packetPointer packet5 = &packets[PACKET5];
packetPointer packet6 = &packets[PACKET6];
packetPointer packet7 = &packets[PACKET7];
// Data read from the arduino slave will be stored in this array
// if the array is initialized to the packet.
unsigned int cont=0;
unsigned int control=2050;
unsigned int readRegs[2];
unsigned int readRegs1[1];
unsigned int readRegs2[6];
unsigned int AV1[5];
unsigned int AV2[5];
unsigned int AV3[5];
unsigned int VFloat[2];

void setup()
{
   mySerial.begin(9600);
   
   timer.setInterval(2000, RepeatTask);
 modbus_construct(packet1, 17, READ_HOLDING_REGISTERS, 0x130, 2, readRegs);
 
 modbus_construct(packet2, 17, READ_HOLDING_REGISTERS, 0x400, 1, readRegs1);
 
 modbus_construct(packet3, 17, READ_HOLDING_REGISTERS, 0x184, 6, readRegs2);
 
 modbus_construct(packet4, 17, READ_HOLDING_REGISTERS, 0x406, 5, AV1);
 modbus_construct(packet5, 17, READ_HOLDING_REGISTERS, 0x40B, 5, AV2);
 modbus_construct(packet6, 17, READ_HOLDING_REGISTERS, 0x410, 5, AV3);
 
 modbus_configure(&Serial, baud, SERIAL_8N2, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS);
 
 pinMode(LED, OUTPUT);
}

void loop()
{
 modbus_update();
 timer.run();    
}

void RepeatTask() {
//fecha
  mySerial.print(int(readRegs2[0]));mySerial.print("/"); //año
  mySerial.print(int(readRegs2[1]));mySerial.print("/"); //mes
  mySerial.print(int(readRegs2[2]));mySerial.print("  "); //dia
  mySerial.print(int(readRegs2[3]));mySerial.print(":"); //hora
  mySerial.print(int(readRegs2[4]));mySerial.print(":"); //minuto
  mySerial.println(int(readRegs2[5]));
  //mySerial.println(int(readRegs2[6])); //semana
  mySerial.print("F=");
  mySerial.print(float(readRegs[0])/100);
  mySerial.print("   ");
  mySerial.print("V1=");
  mySerial.println(float(readRegs[1])/10);
  mySerial.print("THD1=");
  mySerial.print(float(readRegs1[0])/100);
  mySerial.println("   ");
  mySerial.println("Contenido Armonico Voltage");  
  mySerial.print("% V2=");mySerial.print(float(AV1[0])/100);
  mySerial.print(" % V3=");mySerial.print(float(AV1[1])/100);
  mySerial.print(" % V4=");mySerial.print(float(AV1[2])/100);
  mySerial.print(" % V5=");mySerial.print(float(AV1[3])/100);
  mySerial.print(" % V6=");mySerial.println(float(AV1[4])/100);
  mySerial.print("% V7=");mySerial.print(float(AV2[0])/100);
  mySerial.print(" % V8=");mySerial.print(float(AV2[1])/100);
  mySerial.print(" % V9=");mySerial.print(float(AV2[2])/100);
  mySerial.print(" % V10=");mySerial.print(float(AV2[3])/100);
  mySerial.print(" % V11=");mySerial.println(float(AV2[4])/100);
  mySerial.print("% V12=");mySerial.print(float(AV3[0])/100);
  mySerial.print(" % V13=");mySerial.print(float(AV3[1])/100);
  mySerial.print(" % V14=");mySerial.print(float(AV3[2])/100);
  mySerial.print(" % V15=");mySerial.print(float(AV3[3])/100);
  mySerial.print(" % V16=");mySerial.println(float(AV3[4])/100);
}


This code is for print some values from the Power meter, I used one softwareSerial port to show the results because the hardware Serial is used to the modbus RS485 adapter just a simple MAX485.

The schematic is this:



The only difference between this schematic and my project is that I used one MAX485 Module http://yourduino.com/sunshop2/index.php?l=product_detail&p=323 the only thing you have to do is to plug it exactly the same pins of the max485. This is the schematic of this module, it only add the 120 resistor in the output and some other resistors and power protection also have one Indicator Led.



The last think you have to do is to plug A and B to the Communication Terminal Strips located in the Acuvim-L Module. There are also one S pin in the power meter, I didn't plug it anywhere. I thing S pin is for noise effects but it works in large Distance.

The  SimpleTimer library is easy to find in the arduino library repository, I used this because the writing a "delay" in the loop() function caused something wrong in the communication seems like it is slow, but this library is great because it doesnt do anything in the loop function it just waits for the pass of the time and it opens the repeat task function.

Thats all I can say, if anyone is interested in more details to do it works I can share some more information, Is a good power meter it has a accuracy table

Here are some results of the comunication.


raschemmel

Quote
the error in Power Factor was terrible for small currents.


You DO realize that POWER FACTOR is IRRELEVANT for small currents. No commercial company or power utilitity company ever talks about POWER FACTOR for feeders with a small current. It is pointless. The ONLY reason to ever talk about POWER FACTOR is when the current is NOT small, because then the transmission cost to the utility company or the power cost to the customer is
significant. If the current is small, nobody cares and they don't talk about POWER FACTOR. If you know what effects power factor
you already know this.
That being said, I think your post will be very useful to people who are interested in power monitors, however , if you don't mind me saying so, if you are posting to contribute to the knowledge base, your post is missing an important document, which is the
schematic. I know how to connect MAX485s but most people don't and I think that while your post definitely constitutes a contribution, is may be problematic for some without the schematic.
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

David_am

Thank you very much for the reply, I forgot about an Schematic I will put it later.

I know what is power factor in the transmission, but my project is for power monitors as you said.

When I said " the error in Power Factor was terrible for small currents". The real problem in this was the consequences in other values, The EMON meter shows Real Power, Apparent Power and Reactive Power and all of this depends of the Power Factor Value,  all this values was OK including in the low currents, the problem was when the Harmonic Content was high, And if you are metering small currents and non-lineal loads this meter does not works. I know this because I was using a fluke power meter and comparing the results.

The Acuvim-L not only shows Power Factor, It also has a large table of Values, Depending of the Model, In my case Acuvim-DL
and remember all is in three phase. Also it reads energy parameters, In my case i don't use it, maybe somebody is trying to read this somewhere and this is very useful.

But Why to do this?? The simple answer is to make one low cost power control. I am doing a project for control some non-lineal loads and that was the reason for making it works.

All the table is showed in this pdf, also there is the addresses of Modbus parameters.:

http://www.powermeterstore.com/pdfs/cache/www.powermeterstore.com/accuenergy/power_meter/acuvim_cl/manual/accuenergy_acuvim_cl_power_meter_manual.pdf


Simone72

This project is very interesting!
I'm trying to communicate with an energy meter (ULYS MD80 + ULYSCOM) that speaks Modbus and your code will be of tremendous help to me!
At the same time I am trying to implement the function of datalogger with writing data on SD card ...
For the time stamping'm thinking to use a RTC (DS3231 AT24C32) because in the counter does not have this option.
Good luck to all!
2 X Arduino MEGA 2560

priyankachougule

I am doing similar project. My meter is sycon 9900-P. Sir I request you to tell which software you have used to communicate meter and arduino .  Will you please provide me the connection details of your project. I am doing this project in final year. I am using arduino first time. I saw your project details but I didn't get connections. Please reply as early possible.

David_am

I am doing similar project. My meter is sycon 9900-P. Sir I request you to tell which software you have used to communicate meter and arduino .  Will you please provide me the connection details of your project. I am doing this project in final year. I am using arduino first time. I saw your project details but I didn't get connections. Please reply as early possible.
Hello I hope you read this, I'm not sure about the "software" because you only have to put the codes in the package of the modbus message. In the arduino code. You have to read the details of your meter. Maybe you need to read first more information about libraries.

THe connection is simple you only need one RS485 module, and plug in directly to your meter, as I showed in the post.

David_am

This project is very interesting!
I'm trying to communicate with an energy meter (ULYS MD80 + ULYSCOM) that speaks Modbus and your code will be of tremendous help to me!
At the same time I am trying to implement the function of datalogger with writing data on SD card ...
For the time stamping'm thinking to use a RTC (DS3231 AT24C32) because in the counter does not have this option.
Good luck to all!
Hello I hope you made it.

Thanks I make this for helping people like you, All the things that you need is completly posible.

emmanuelbabu

Hello

The post was really useful, could you please share the location of these header files which you have used:

#include <SimpleModbusMaster.h>
#include <SoftwareSerial.h>
#include <SimpleTimer.h>

Emmanuel

ricardo_76_scp

Hello

I am try make the same for Power metet PM3250 from shnider. but i cant make the conection, i am using the same MAX485 and conections, but i dont have any information from PM.


I've used several libraries , and I did not have any results.

the connections have had the RO TO RX , TX TO DI ... all of it.

I'm trying so get information that is in the address 3028 and has the size of 2 bytes.

getting this information , try another.

someone can help me?


David_am

maybe in your power meter show examples to how to plug the modbus comunication. i remember my power mater only had 3 point tx rx and (ground I dont remember this clearly)

neerav

I was reading over the internet how to create a acceptable power meter during this searching I only found some circuits but those doesn't have all the parameters i have to use to my proyect, and the error of those circuits was unpredictable. The parameters I was looking for are:

Voltage, Current, THD, Individual Harmonic Analisis, Ractive Power and Power Factor. All values for Three Phase system.



/tmp/arduino_modified_sketch_985471/sketch_may10a.ino: In function 'void setup()':
sketch_may10a:86: error: invalid conversion from 'unsigned int*' to 'unsigned int' [-fpermissive]
 modbus_construct(packet1, 17, READ_HOLDING_REGISTERS, 130, 2, readRegs);
                                                                       ^
In file included from /tmp/arduino_modified_sketch_985471/sketch_may10a.ino:1:0:
/root/Arduino/libraries/SimpleModbusMasterV2rev2/SimpleModbusMaster.h:127:6: error:   initializing argument 6 of 'void modbus_construct(Packet*, unsigned char, unsigned char, unsigned int, unsigned int, unsigned int)' [-fpermissive]
 void modbus_construct(Packet *_packet,

      ^
sketch_may10a:89: error: invalid conversion from 'unsigned int*' to 'unsigned int' [-fpermissive]
  modbus_construct(packet2, 17, READ_HOLDING_REGISTERS, 400, 1, readRegs1);
                                                                         ^
In file included from /tmp/arduino_modified_sketch_985471/sketch_may10a.ino:1:0:
/root/Arduino/libraries/SimpleModbusMasterV2rev2/SimpleModbusMaster.h:127:6: error:   initializing argument 6 of 'void modbus_construct(Packet*, unsigned char, unsigned char, unsigned int, unsigned int, unsigned int)' [-fpermissive]
 void modbus_construct(Packet *_packet,

      ^
sketch_may10a:92: error: invalid conversion from 'unsigned int*' to 'unsigned int' [-fpermissive]
 modbus_construct(packet3, 17, READ_HOLDING_REGISTERS, 184, 6, readRegs2);
                                                                        ^
In file included from /tmp/arduino_modified_sketch_985471/sketch_may10a.ino:1:0:
/root/Arduino/libraries/SimpleModbusMasterV2rev2/SimpleModbusMaster.h:127:6: error:   initializing argument 6 of 'void modbus_construct(Packet*, unsigned char, unsigned char, unsigned int, unsigned int, unsigned int)' [-fpermissive]
 void modbus_construct(Packet *_packet,

      ^
sketch_may10a:95: error: invalid conversion from 'unsigned int*' to 'unsigned int' [-fpermissive]
 modbus_construct(packet4, 17, READ_HOLDING_REGISTERS, 406, 5, AV1);
                                                                  ^
In file included from /tmp/arduino_modified_sketch_985471/sketch_may10a.ino:1:0:
/root/Arduino/libraries/SimpleModbusMasterV2rev2/SimpleModbusMaster.h:127:6: error:   initializing argument 6 of 'void modbus_construct(Packet*, unsigned char, unsigned char, unsigned int, unsigned int, unsigned int)' [-fpermissive]
 void modbus_construct(Packet *_packet,

      ^
sketch_may10a:98: error: unable to find numeric literal operator 'operator"" B'
 modbus_construct(packet5, 17, READ_HOLDING_REGISTERS, 40B, 5, AV2);
                                                       ^
sketch_may10a:101: error: invalid conversion from 'unsigned int*' to 'unsigned int' [-fpermissive]
 modbus_construct(packet6, 17, READ_HOLDING_REGISTERS, 410, 5, AV3);
                                                                  ^
In file included from /tmp/arduino_modified_sketch_985471/sketch_may10a.ino:1:0:
/root/Arduino/libraries/SimpleModbusMasterV2rev2/SimpleModbusMaster.h:127:6: error:   initializing argument 6 of 'void modbus_construct(Packet*, unsigned char, unsigned char, unsigned int, unsigned int, unsigned int)' [-fpermissive]
 void modbus_construct(Packet *_packet,

      ^
exit status 1
invalid conversion from 'unsigned int*' to 'unsigned int' [-fpermissive]

This is the error msg i am getting when i am running your code on my UNO board .

neerav

#include <SimpleModbusMaster.h>
#include <SoftwareSerial.h>
#include <SimpleTimer.h>

SoftwareSerial mySerial(10, 11); // RX, TX
SimpleTimer timer;

//////////////////// Port information ///////////////////
#define baud 9600
#define timeout 1000
#define polling 200 // the scan rate

// If the packets internal retry register matches
// the set retry count then communication is stopped
// on that packet. To re-enable the packet you must
// set the "connection" variable to true.
#define retry_count 10

// used to toggle the receive/transmit pin on the driver
#define TxEnablePin 2

#define LED 9

// This is the easiest way to create new packets
// Add as many as you want. TOTAL_NO_OF_PACKETS
// is automatically updated.
enum
{
 PACKET1,
 PACKET2,
 PACKET3,
 PACKET4,
 PACKET5,
 PACKET6,
 PACKET7,
 TOTAL_NO_OF_PACKETS // leave this last entry
};

// Create an array of Packets to be configured
Packet packets[TOTAL_NO_OF_PACKETS];
packetPointer packet1 = &packets[PACKET1];
packetPointer packet2 = &packets[PACKET2];
packetPointer packet3 = &packets[PACKET3];
packetPointer packet4 = &packets[PACKET4];
packetPointer packet5 = &packets[PACKET5];
packetPointer packet6 = &packets[PACKET6];
packetPointer packet7 = &packets[PACKET7];
// Data read from the arduino slave will be stored in this array
// if the array is initialized to the packet.
unsigned int cont=0;
unsigned int control=2050;
unsigned int readRegs[2];
unsigned int readRegs1[1];
unsigned int readRegs2[6];
unsigned int AV1[5];
unsigned int AV2[5];
unsigned int AV3[5];
unsigned int VFloat[2];

void setup()
{
   mySerial.begin(9600);
   
   timer.setInterval(2000, RepeatTask);
 modbus_construct(packet1, 17, READ_HOLDING_REGISTERS, 0x130, 2, readRegs);
 
 modbus_construct(packet2, 17, READ_HOLDING_REGISTERS, 0x400, 1, readRegs1);
 
 modbus_construct(packet3, 17, READ_HOLDING_REGISTERS, 0x184, 6, readRegs2);
 
 modbus_construct(packet4, 17, READ_HOLDING_REGISTERS, 0x406, 5, AV1);
 modbus_construct(packet5, 17, READ_HOLDING_REGISTERS, 0x40B, 5, AV2);
 modbus_construct(packet6, 17, READ_HOLDING_REGISTERS, 0x410, 5, AV3);
 
 modbus_configure(&Serial, baud, SERIAL_8N2, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS);
 
 pinMode(LED, OUTPUT);
}

void loop()
{
 modbus_update();
 timer.run();     
}

void RepeatTask() {
//fecha
  mySerial.print(int(readRegs2[0]));mySerial.print("/"); //año
  mySerial.print(int(readRegs2[1]));mySerial.print("/"); //mes
  mySerial.print(int(readRegs2[2]));mySerial.print("  "); //dia
  mySerial.print(int(readRegs2[3]));mySerial.print(":"); //hora
  mySerial.print(int(readRegs2[4]));mySerial.print(":"); //minuto
  mySerial.println(int(readRegs2[5]));
  //mySerial.println(int(readRegs2[6])); //semana
  mySerial.print("F=");
  mySerial.print(float(readRegs[0])/100);
  mySerial.print("   ");
  mySerial.print("V1=");
  mySerial.println(float(readRegs[1])/10);
  mySerial.print("THD1=");
  mySerial.print(float(readRegs1[0])/100);
  mySerial.println("   ");
  mySerial.println("Contenido Armonico Voltage");   
  mySerial.print("% V2=");mySerial.print(float(AV1[0])/100);
  mySerial.print(" % V3=");mySerial.print(float(AV1[1])/100);
  mySerial.print(" % V4=");mySerial.print(float(AV1[2])/100);
  mySerial.print(" % V5=");mySerial.print(float(AV1[3])/100);
  mySerial.print(" % V6=");mySerial.println(float(AV1[4])/100);
  mySerial.print("% V7=");mySerial.print(float(AV2[0])/100);
  mySerial.print(" % V8=");mySerial.print(float(AV2[1])/100);
  mySerial.print(" % V9=");mySerial.print(float(AV2[2])/100);
  mySerial.print(" % V10=");mySerial.print(float(AV2[3])/100);
  mySerial.print(" % V11=");mySerial.println(float(AV2[4])/100);
  mySerial.print("% V12=");mySerial.print(float(AV3[0])/100);
  mySerial.print(" % V13=");mySerial.print(float(AV3[1])/100);
  mySerial.print(" % V14=");mySerial.print(float(AV3[2])/100);
  mySerial.print(" % V15=");mySerial.print(float(AV3[3])/100);
  mySerial.print(" % V16=");mySerial.println(float(AV3[4])/100);
}




this code is not working with arduino uno please can you share the working code .
it is showing the error "invalid conversion from "unsigned int* " to  "unsigned int* " [-fparmissive]

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy