ACS758 Current measurement on Photon?

I have a question regarding the Offset value for an ACS758.
This module is tuned from the manufacturer on 5v. Due to analogRead on Photon is not 5v tolerant, it is powered via 3V3.

Below is the following code for use with Arduino. The offsets are 2500 and 600 for Bi-directional and Uni-directional.

/*
Henry's Bench
ACS758 Current Measurement Tutorial
*/
const int analogIn = A0;

// Set your scale factor
int mVperAmp = 40; // See Scale Factors Below

/* Scale Factors
50A bi-directional = 40
50A uni-directional = 60
100A bi-directional = 20
100A uni-directional = 40
150A bi-directional = 13.3
150A uni-directioal = 26.7
200A bi-directional = 10
200A uni-directional = 20
*/

// Set you Offset
int ACSoffset = 2500; // See offsets below

/* Offsets
If bi-directional = 2500
If uni- directional = 600
*/

int RawValue= 0;
double Voltage = 0;
double Amps = 0;

void setup(){ 
 Serial.begin(9600);
}

void loop(){
 
 RawValue = analogRead(analogIn);
 Voltage = (RawValue / 1023.0) * 5000; // Gets you mV
 Amps = ((Voltage - ACSoffset) / mVperAmp);

Should these offsets be changed to 1650 and 396 due to using 3.3v instead of 5v?
Below as an example.

/*
Henry's Bench
ACS758 Current Measurement Tutorial
*/
const int analogIn = A0;

// Set your scale factor
int mVperAmp = 40; // See Scale Factors Below

/* Scale Factors
50A bi-directional = 40
50A uni-directional = 60
100A bi-directional = 20
100A uni-directional = 40
150A bi-directional = 13.3
150A uni-directioal = 26.7
200A bi-directional = 10
200A uni-directional = 20
*/

// Set you Offset
int ACSoffset = 1650; // See offsets below

/* Offsets
If bi-directional = 1650
If uni- directional = 396
*/

int RawValue= 0;
double Voltage = 0;
double Amps = 0;

void setup(){ 
 Serial.begin(9600);
}

void loop(){
 
 RawValue = analogRead(analogIn);
 Voltage = (RawValue / 4095.0) * 3300; // Gets you mV
 Amps = ((Voltage - ACSoffset) / mVperAmp);

The other question I have is:
Any way of using 5v instead of 3.3v for the measurement?
This obviously is not safe if using A0.
If using the 50amp sensor and only needing to read up to lets say 30amp should be safe but not ideal.

This is the datasheet.

I use the ACS712. Supply voltage to the IC must be 5v and very very stable otherwise readings (especially of AC current) will be all over the place. A simple resistor bridge is enough to scale the 0-5v signal to 0-3.3v. The output of the IC is never going to exceed 5v and they are tolerant of short over current.

What resistor did you use to lower it to 0-3.3v ?

@eLumaLite This is the schematic - 2 resistors where using ohm’s law output voltage = 5 x 4300/(2200+4300) = 3.3V.
image

Thanks for that @armor
Would I need to make math changes in the above code when using the voltage divider?

analogRead() returns an integer value ranging from 0 to 4095. (ADC is 12 bit whereas Arduino is 10 bit 0 to 1023.

The full range voltage input is 3.3V not 5.0V. Thus:

RawValue = analogRead(analogIn);
Voltage = (RawValue / 4095.0) * 3300; // Gets you mV

Is correct to derive the current sensor signal in mV.

Are you reading an AC or DC load? - Bidirectional or unidirectional in the datasheet.

AC - you need to think peak to peak not RMS.

Also, there are different models with different current ranges. The reference voltage to the ACS758 must be very stable (no noise) and 5V to read accurately. Remember that when the current is zero then output will be 2.5v which equates to 1.67V after the resistor bridge and equates to a reading of 2047/8.

If you are reading AC current then you will need to understand the type of load - sample at sufficient frequency the current over a few cycles and then calculate the RMS (root mean squared). In this calculation it is easier to calculate with the integer value from analogRead() and then apply the factor at the end, IMHO.

1 Like