Go Down

Topic: Current Sensor ACS714 Wandering Values (Read 1 time) previous topic - next topic


Hello everyone,

My first post & and I'm a newbie to Arduino so forgive me if I'm being a bit stupid.
I've hooked up a ACS714 (-30A to +30A), a RTC and SD card onto my MEGA (also fitted with Ethernet Shield but removing it makes no difference) but am a bit perplexed as to why, with nothing connected, the sensorValue wanders around from about 506 to 511. I was expected a little fluctuation but around 0.4A seems a lot. I have my ACS board connected to my MEGA as follows:

Vcc:  5v

Should I be using a resistor anywhere?
Is there a reference GND I should be using?
and finally do I have my maths right for calculating the mA readings - as hunting around the internet there seems to be several ways of doing this.

Any advice gratefully received...

Here's my code:

#include <LiquidCrystal.h> //For the LCD
#include <RTClib.h>// For the RTC
#include <Wire.h> //For I2C comms
#include <SdFat.h> // Include the standard SD card library

SdFat sd; //alias for the SD library
SdFile DataFile; //alias for the datalog file
const int chipSelect = 53; //Initialise the SD card outputs on the Arduino. Mega = 53

// initialize the LCD library with the numbers of the interface pins. You can use any (but wire to those specified obviously!)
LiquidCrystal lcd(22, 23, 24, 25, 26, 27); //LCD pins RS(4), DB4(11), DB5(12), DB6(13), DB7(14)

RTC_DS1307 RTC; //Initialise the RTC

int analogInPin = A0;    // Analog input pin that the carrier board OUT is connected to
int sensorValue = 0;     // value read from the carrier board
int outputValue = 0;   // output in milliamps
String TimeString=""; //Used to concatenate the time & date string
int lastTime = -1; //Used to set a time interval
int led = 13;//LED to show logging

void setup() {

  Serial.begin(9600);  // initialize serial communications at 9600 bps:
  lcd.begin(20, 4);// LCD set up. Set the LCD's number of columns and rows: 
  Wire.begin();//set off the I2C comand
  RTC.begin(); //Start the RTC
  //RTC.adjust(DateTime(__DATE__, __TIME__)); //Running this sets the RTC Clock via the controller PC
  pinMode(chipSelect, OUTPUT); //Set SD Chip Select pin on the Arduino as output (even if not using this function)
  pinMode(led, OUTPUT);

void loop() {

{digitalWrite(led, LOW);}    // turn the LED off by making the voltage LOW
  DateTime now = RTC.now();   //Get the Time
  int time = now.minute();

   // read the analog in value:
  sensorValue = analogRead(analogInPin);           
  // convert to milli amps
  outputValue = ((long)sensorValue  - 512 ) * 73.982L;
  //outputValue = ((long)sensorValue  - 512 ) * 234375 / 4000000;
  //outputValue = ( ((long)sensorValue * 5000 / 1024) - 2500 ) * 1000 / 66;
Analog read produces a value of 0-1023, equating to 0v to 5v.
With a sensitivity of 66 mV per A the optimized -30 to 30 range
would be (Vcc/2)-1.98V to (Vcc/2)+1.98V (0.52V to 4.48V).
That's something like .073982 A per step.  73,982 microamps per step.           

//  lcd.clear();

if (abs(time - lastTime) >= 1)
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level) 

   //create the time string
TimeString=String(now.day(),DEC) + "/" + String(now.month(),DEC) + "/" + String(now.year(),DEC) + " "
+ String(now.hour(),DEC) + ":" + String(now.minute(),DEC) + ":" + String(now.second(),DEC);
  // print the results to the serial monitor:
  Serial.print("Sensor Count (0-1023)= " );                       
  Serial.print("\t Current (ma) = ");     

  // Initialize SdFat or print a detailed error message and halt
  // Use half speed like the native library.
  // change to SPI_FULL_SPEED for more performance.
  if (!sd.begin(chipSelect, SPI_QUARTER_SPEED)) sd.initErrorHalt();

  // open the file for write at end like the Native SD library
  if (!DataFile.open("ampleak.txt", O_RDWR | O_CREAT | O_AT_END))
    sd.errorHalt("ERROR opening ampleak.txt for write!");

  // if the file opened okay, write to it:
  Serial.println("Writing " + TimeString + "," + String(sensorValue) + + "," + String(outputValue) + " to ampleak.txt...");
  lastTime = time;
  DataFile.println(TimeString + "," + String(sensorValue) + "," + String(outputValue));

  DataFile.close();// close the file to complete the write process:



I see some problems with points and commas and floating point and long and int.

Your calculation seems good.
Could you try a floating point calculation ? That is easier.

Code: [Select]

int sensorValue;
float milliAmps;

sensorValue = analogRead(analogInPin);           

Serial.print("raw sensorValue = ");

// Convert to milli amps
// The offset of 512 has to be determined, perhaps during startup.
milliAmps = ((float) (sensorValue  - 512) * 5.0 / 1023.0 ) * 1000.0 / 66.0;

Serial.print("milliAmps = ");



Many thanks, that did the trick. I still have a lot to learn about data types in this language, I'm more used to Visual Studio where things seems a little more straightforward...!

I would have replied earlier but we seem to have lost the forum for a day?



To increase speed and precission you could replace

milliAmps = ((float) (sensorValue  - 512) * 5.0 / 1023.0 ) * 1000.0 / 66.0;


milliAmps = (sensorValue  - 512) * 0.074054326;

BUt yes you should document where that magic number comes from ;)
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)


These hall-effect current sensors are quite noisy - and sensitive to external magnetic fields too.

Their good points are isolation and low shunt resistance and thus low dropout voltage (basically
its a copper link in the high current circuit).
[ I won't respond to messages, use the forum please ]

Go Up