Hey folks, first post here to please go easy on me. I’ve been working on a current monitoring project using the analog inputs of the Arduino Leonardo. I use an Ethernet Shield 2 to allow me to remotely monitor the current levels of each input. Each current value is nicely displayed on an array of dynamic virtual gauges written in AJAX hosted on a small webpage stored on the microSD card of the Ethernet shield. So far, I’ve successfully displayed the value of each analog input using a 10k potentiometer in place of an actual current sensor.
For simplicity, rather than purchasing current transformers for each analog input and building the necessary circuits to interface them with the Arduino, I’ve instead purchased an “8-Channel 20-Amp AC Current Monitor with I2C Interface” board from NCD. I hope to capture each of the 8 current sensor values via the i2c Arduino interface and display them on these virtual gauges.
I have absolutely no experience with i2c however, I believe I’ve done enough research to correctly connect the 8-Channel Current Monitor board to my Arduino’s Ground, SDA, and ACL pins. The board is powered by its own 12 volt power adapter so I don’t believe I need the +5 volt connection (please tell me if I’m mistaken).
I’m hoping someone might be able to point me to a simple Arduino sketch which will allow me to monitor the numeric value of at least a single channel on the current monitor board. If there is a topic on this forum explaining the use of a i2c current sensor with an Arduino Leonardo, I must have missed it. Any direction you might be able to point me in would be greatly appreciated.
Thank you in advance!
Hi Aaron,
Here you go
i2C is super easy
let me know if you need anything else.
Thanks
@Anil_Bhaskar, thanks for your help! I loaded the sketch found on your GitHub page (PECMAC/Arduino/PECMAC125A.ino) but was not able to see any output on the serial monitor window. I assume even if there was no current being detected, the output would still show the “Channel :” and “Current :” texts but with null values.
I suspect the sketch might not be directly compatible with the Leonardo Arduino board without some minor code changes (only guessing here).
The Leonardo i2c pins are Digital 2 (SDA) and Digital 3 (SCL). Perhaps this needs to be set somewhere in the sketch?
On a positive note, I did confirm that I have the current monitor board correctly connected via the Leonardo’s i2c interface using a i2c scanner sketch I found via a Google search…
https://www.hackster.io/abdularbi17/how-to-scan-i2c-address-in-arduino-eaadda
My Leonardo recognized the device at the expected address of 0x2A!
20:33:06.370 -> Scanning...
20:33:06.370 -> I2C device found at address 0x2A !
20:33:06.370 -> done
If you have any ideas or suggestions for next steps, I’m all ears.
Thank you,
Aaron
the serial terminal baudrate is 9600.
define the i2c as wire.begin(2,3)
Given that the i2c scanner sketch I tried earlier correctly probed the 8 channel current monitor board with an i2c Device Address of 0x2A, I assume that I do not need to define the SCL and SDA pins in the sketch. This must be defined (or assumed) in the sketch already.
The i2c communication seems to be successfully established between my Leonardo Arduino and the 8 channel current monitor board so I suspect that the issue is likely with how I’m trying to call the Internal Register Address or Data values for each current probe on this board.
The serial baud rate is already set to 9600 and the Serial Monitor tool functions correctly in other sketches I’ve used with this same value so I think we’re good here.
Looking at the serial monitor output, I do not see any printed data when I load the PECMAC125A.ino sketch.
To better illustrate what I’ve tried as well as some of the more specific questions I have about this sketch, I’ve added comments within the sketch (see below) for your reference:
// Distributed with a free-will license.
// Use it any way you want, profit or free, provided it fits in the licenses of its associated works.
// PECMAC125A
// This code is designed to work with the PECMAC125A_DLCT03C20 I2C Mini Module available from ControlEverything.com.
// https://www.controleverything.com/content/Current?sku=PECMAC125A_DLCT03C20#tabs-0-product_tabset-2
#include<Wire.h>
// PECMAC125A I2C address is 2A(42)
#define Addr 0x2A
unsigned int data[36];
// Unsure what to set the typeOfSensor value to so I've left it at 0
int typeOfSensor = 0;
// My max current is 20 amps. I've tried maxCurrent values of both 20 and 0 but no success
int maxCurrent = 0;
// The board is 8 channels. I've tried noOfChannel values of both 8 and 0 but no success
int noOfChannel = 0;
void setup()
{
// Initialise I2C communication as MASTER
Wire.begin();
// Initialise Serial Communication, set baud rate = 9600
Serial.begin(9600);
// Read configuration command
// Header byte-1, Header byte-2, command-2, byte 3, 4, 5 and 6 are reserved, checksum
byte readConfigCommand[8] = {0x92, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x00, 0xFE};
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Send read configuration command
Wire.write(readConfigCommand, 8);
// Stop I2C Transmission
Wire.endTransmission();
for(int i = 0; i < 3; i++)
{
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Stop I2C Transmission
Wire.endTransmission();
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
// Read 3 bytes of data
// typeOfSensor, maxCurrent, noOfChannel
if(Wire.available() == 1)
{
data[i] = Wire.read();
}
}
typeOfSensor = data[0];
maxCurrent = data[1];
noOfChannel = data[2];
// Output data to serial monitor
Serial.print(" Type Of Sensor : ");
Serial.println(typeOfSensor);
Serial.print(" Max Current : ");
Serial.println(maxCurrent);
Serial.print(" No Of Channel : ");
Serial.println(noOfChannel);
delay(300);
}
void loop()
{
// Read current command
// Header byte-1, Header byte-2, command-1, start channel-1, stop channel-12,
// There are only 8 channels on this current monitor board. Do I need to change one of the HEX values below since the stop channel should be 8 rather than 12?
// byte 5 and 6 reserved, checksum
byte readCurrentCommand[8] = {0x92, 0x6A, 0x01, 0x01, noOfChannel, 0x00, 0x00, 0x0A};
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Send configuration command
Wire.write(readCurrentCommand, 8);
// Stop I2C Transmission
Wire.endTransmission();
for(int i = 0; i < noOfChannel * 3; i++)
{
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Stop I2C Transmission
Wire.endTransmission();
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
// Read 3 bytes of data
// typeOfSensor, maxCurrent, noOfChannel
if(Wire.available() == 1)
{
data[i] = Wire.read();
}
}
for(int i = 0; i < noOfChannel; i++)
{
// Read current data
// msb1, msb, lsb
int msb1 = data[i * 3] & 0xff;
int msb = data[1 + i * 3] & 0xff ;
int lsb = data[2 + i * 3] & 0xff;
Serial.print(msb1);
Serial.print(msb);
Serial.print(lsb);
float current = (msb1 * 65536) + (msb * 256) + lsb;
// Convert the data to ampere
current = current / 1000;
// Output to the serial monitor
Serial.print("Channel : ");
Serial.println(i + 1);
Serial.print("Current : ");
Serial.println(current);
}
delay(500);
}
There must be something simple I’m missing. I’m sure once we identify it, all the i2c theory will make sense to me.
Thanks again for all your help!
Best,
Aaron
add some debug print message and where its getting stuck.
That is an excellent idea!
I’ve added print commands at nearly all the steps in the loop portion of the sketch.
Here is the modified sketch with the print results below:
// Distributed with a free-will license.
// Use it any way you want, profit or free, provided it fits in the licenses of its associated works.
// PECMAC125A
// This code is designed to work with the PECMAC125A_DLCT03C20 I2C Mini Module available from ControlEverything.com.
// https://www.controleverything.com/content/Current?sku=PECMAC125A_DLCT03C20#tabs-0-product_tabset-2
#include<Wire.h>
// PECMAC125A I2C address is 2A(42)
#define Addr 0x2A
unsigned int data[36];
// Unsure what to set the typeOfSensor value to so I've left it at 0
int typeOfSensor = 0;
// My max current is 20 amps. I've tried maxCurrent values of both 20 and 0 but no success
int maxCurrent = 0;
// The board is 8 channels. I've tried noOfChannel values of both 8 and 0 but no success
int noOfChannel = 0;
void setup()
{
// Initialise I2C communication as MASTER
Wire.begin();
// Initialise Serial Communication, set baud rate = 9600
Serial.begin(9600);
// Read configuration command
// Header byte-1, Header byte-2, command-2, byte 3, 4, 5 and 6 are reserved, checksum
byte readConfigCommand[8] = {0x92, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x00, 0xFE};
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Send read configuration command
Wire.write(readConfigCommand, 8);
// Stop I2C Transmission
Wire.endTransmission();
for(int i = 0; i < 3; i++)
{
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Stop I2C Transmission
Wire.endTransmission();
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
// Read 3 bytes of data
// typeOfSensor, maxCurrent, noOfChannel
if(Wire.available() == 1)
{
data[i] = Wire.read();
}
}
typeOfSensor = data[0];
maxCurrent = data[1];
noOfChannel = data[2];
// Output data to serial monitor
Serial.print(" Type Of Sensor : ");
Serial.println(typeOfSensor);
Serial.print(" Max Current : ");
Serial.println(maxCurrent);
Serial.print(" No Of Channel : ");
Serial.println(noOfChannel);
delay(300);
}
void loop()
{
Serial.print("Message 1/15: Let's get this party started!");
Serial.println();
// Read current command
// Header byte-1, Header byte-2, command-1, start channel-1, stop channel-12,
// There are only 8 channels on this current monitor board. Do I need to change one of the HEX values below since the stop channel should be 8 rather than 12?
// byte 5 and 6 reserved, checksum
Serial.print("Message 2/15: Reading the current command");
Serial.println();
byte readCurrentCommand[8] = {0x92, 0x6A, 0x01, 0x01, noOfChannel, 0x00, 0x00, 0x0A};
Serial.print("Message 3/15: Starting I2C Transmission");
Serial.println();
// Start I2C Transmission
Wire.beginTransmission(Addr);
Serial.print("Message 4/15: Sending configuration command");
Serial.println();
// Send configuration command
Wire.write(readCurrentCommand, 8);
Serial.print("Message 5/15: Stopping I2C Transmission");
Serial.println();
// Stop I2C Transmission
Wire.endTransmission();
Serial.print("Message 6/15: Doing some math here before we transmit again");
Serial.println();
for(int i = 0; i < noOfChannel * 3; i++)
{
Serial.print("Message 7/15: Starting I2C Transmission");
Serial.println();
// Start I2C Transmission
Wire.beginTransmission(Addr);
Serial.print("Message 8/15: Stoping I2C Transmission");
Serial.println();
// Stop I2C Transmission
Wire.endTransmission();
Serial.print("Message 9/15: Requesting 1 byte of data");
Serial.println();
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
Serial.print("Message 10/15: Read 3 bytes of data: typeOfSensor, maxCurrent, noOfChannel");
Serial.println();
// Read 3 bytes of data
// typeOfSensor, maxCurrent, noOfChannel
if(Wire.available() == 1)
{
data[i] = Wire.read();
}
}
Serial.print("Message 11/15: Doing some more math here to average out our data");
Serial.println();
for(int i = 0; i < noOfChannel; i++)
{
// Read current data
// msb1, msb, lsb
int msb1 = data[i * 3] & 0xff;
int msb = data[1 + i * 3] & 0xff ;
int lsb = data[2 + i * 3] & 0xff;
Serial.print("Message 12/15: Printing our msbl, msb, and lsb data");
Serial.println();
Serial.print(msb1);
Serial.print(msb);
Serial.print(lsb);
float current = (msb1 * 65536) + (msb * 256) + lsb;
Serial.print("Message 13/15: Dividing the current value by 1,000");
Serial.println();
// Convert the data to ampere
current = current / 1000;
Serial.print("Message 14/15: Printing the Channel and Current values");
Serial.println();
// Output to the serial monitor
Serial.print("Channel : ");
Serial.println(i + 1);
Serial.print("Current : ");
Serial.println(current);
}
Serial.print("Message 15/15: Waiting 1/2 second before we start this thing all over again");
Serial.println();
Serial.println();
Serial.println();
delay(500);
}
There are 2 gaps in the process, each will multiple missing steps, as shown here:
Message 1/15: Let’s get this party started!
Message 2/15: Reading the current command
Message 3/15: Starting I2C Transmission
Message 4/15: Sending configuration command
Message 5/15: Stopping I2C Transmission
Message 6/15: Doing some math here before we transmit again
-
-
-
-
Message 11/15: Doing some more math here to average out our data
-
-
-
Message 15/15: Waiting 1/2 second before we start this thing all over again
I’ll look into this a bit deeper tomorrow but wanted to post my findings in the meantime.
Thanks,
Aaron