I'm using a ADS1115 (16bit) ADC converter and have the voltage readings displaying correctly,
Which is reading correct at 75amps I get 37.5V
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Adafruit_ADS1015.h>
Adafruit_ADS1115 ads1115;
#define ADS1115_REG_CONFIG_DR_860SPS
#define AVG_NUM 24 //Number of samples to take for ADC reading
#define VOLTS_CHAN0 0 //Batteryv oltage 1
#define VOLTS_CHAN1 1 //Battery voltage 2
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
Adafruit_ADS1115 ads; /* Use this for the 16-bit version */
float Vresults0; // battery voltage
float Vresults1; ///Amps reading
float Vresults2; //only temp will be removed
float Vresults3; //only temp will be removed
float Vresults4; //only temp will be removed
float Vmultiplier = 0.000188; // used to convet readings this is calculated
float R1 = 9960.5; // !! resistance of R1 !!
float R2 = 2700; // !! resistance of R2 !!
void setup() {
ads.setGain(GAIN_TWOTHIRDS); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV (default)
ads.begin(); //start the 16bit A/D converter
Serial.begin(9600); // Initialize Arduino to PC Com Port(debug only to be removed on fianl build)
lcd.begin(20, 4); // Initialize the LCD.
lcd.clear();
delay(100);
lcd.setCursor(0, 1);
lcd.print("Initializing..."); // Print something on the display to show will be removed debug only
lcd.setCursor(0, 2); // Print something on the display to show will be removed debug only
lcd.print("Daves Van Meter"); // Print something on the display to show will be removed debug only
lcd.setCursor(0, 3); // Print something on the display to show will be removed debug only
lcd.print("By Dave"); // Print something on the display to show will be removed debug only
delay(1000); // Print something on the display to show will be removed debug only // it's working.
lcd.clear(); // Print something on the display to show will be removed debug only // Clear display
delay(100);
}
/* ========== Main Loop ============================================================= */
void loop() {
read_data(); // Get current and voltage values.
write_to_lcd();
//This shall be removed only here for debuging and getiing it working.
Vresults3 = Vresults0 / (R2 / (R1 + R2)); /// This will be removed and replaced only for testing
Vresults4 = Vresults1 * 10; //this is wrong 3.75V shows 37.52amps *100 shows 375.2amps
}
/* ========== dsiplay the data ============================================================= */
void write_to_lcd() {
lcd.setCursor(0, 0);
lcd.print(Vresults0, 3); lcd.print("Raw V");
lcd.setCursor(11, 0); //
lcd.print(Vresults1); lcd.print("Raw A ");
lcd.setCursor(0, 2);
lcd.print(Vresults3); lcd.print(" Actual V ");
lcd.setCursor(0, 3);
lcd.print(Vresults4); lcd.print(" Actual A ");
}
/* ========== read easch channel 24 times ======================================================== */
int read_adc(int channel) {
float sum = 0;
int16_t temp;;
int i;
for (i = 0; i < AVG_NUM; i++) { // loop through reading raw adc values AVG_NUM number of times
temp = ads.readADC_SingleEnded(channel); // read the input pin
sum += temp; // store sum for averaging
delayMicroseconds(50); // pauses for 50 microseconds
}
return (sum / AVG_NUM); // divide sum by AVG_NUM to get average and return it
}
/* ========== read chanel ============================================================= */
void read_data(void) {
Vresults0 = read_adc(VOLTS_CHAN0) * Vmultiplier; //(R2/(R1+R2)); //(R2/(R1+R2)This will replace above calcultaionvoltage reading
Vresults1 = read_adc(VOLTS_CHAN1) * Vmultiplier ; // current reading.
}
void read_data(void) {
Vresults0 = read_adc(VOLTS_CHAN0) ;
Vresults1 = read_adc(VOLTS_CHAN1);
}
void loop() {
read_data(); // Get Raw data for current and voltage
write_to_lcd();
//This shall be removed only here for debuging and getiing it working.
Vresults3 = Vresults0 * Vmultiplier; // value in volt (3,75V ?)
Vresults4 = Vresults1 * Vmultiplier * 20.0 ; // value in Amps ( 3.75 *20 =75 amps)
}
How did you come up with 20 ?
The 3.75reading comes from the op-amp which has the gain of 100, the0.000188 is the part that converts it 0-5v so I do understand what adc is. It reads correct in bench like I said. I knew it would be simple in the end guess I give it to much thought. But still don't understand how you plucked 20 to come to the correct figure I was trying that way with different numbers but thought I was just adding a fudge factorif your Vmultiplier can scale the raw value of ADC reading when you enter 37,5mV and show a result of 3,75V
to get 75 instead of 3,75 simply multiply by 20 ! 3,75* 20 => 75
ADC means Analog --> to --> Digital , so Raw data is a digital value (binary result) .. not volts.
When using ADC conversion , the 1rst step is to Know what raw value (16 bits) deliver the ADC for a known voltage input..
After you can convert in Physical Unit (Volt,Amper,°C...) it is only a mathematik calculus..
Thanks that makes it more clearer and understand now, The reason I don't use the PGA because the I'm using A0 for voltage with a resistor divider to scale 20V max to 0-5V and A1 for the current and I would presume that this would effect the voltage reading if I set it to that on setup, I guess I could use a bigger resistor divider and to make the voltage smaller then use the PGA with 16 gain scale. I will have to read up more on the data sheet as this is the first time I've used this ADS1115 board. I use to use PIC'S but thought give Arduino a bash. The code works but could well and more than likely be improved on for better performance.Sorry, there was some misunderstandanding from myself ..
what i understand now:
you use the ADC with a PGA Gain=2/3
so full scale is +-6.144V
and +6,144V -> 32767 points
6.144/32767 => 0.0001875 your Vmultiplier..
and you want to use an external Analog amplifier ( instead of internal PGA) to
amplifie 37,5mV up to 3,75V
so if ADC see 3,75V ADC deliver 20 000 points (= 32 767 * 3.75 / 6.144)
if you want to scale to 750 ( and get 1/10 amp of resolution)
20 000 / 750 =26.66
so scaling value is
shunt 37.5mV -> Analog amplifier *100 -> 3.75V -- ADC reading -> 20 000 points / 26.66 -> 750 (1:10 of Amps)
or divide by 266 if you want Amps, without decimal
Question :
why you don't use PGA gain=16
256mV for 32767 points -> 4800 points for 37,5mV
just scaling with 4800/750 => 64
ADC result / 64 to get 750 dizieme d'Ampere
I don't understand where you get 750 from
Fortunately, offset is a linear error quantity, so that it can be easily adjusted.Your amplifier is not linear because too big offset value when 0mV on shunt..
Yeah the shunt has changed second project because the 100amp shunt is been used in the other project which is on soak test and this is the only shunt I have to handYour amplifier is not linear because too big offset value when 0mV on shunt..
it is better to use a symetrical power supply +5 -5V for the AOP..
this is a simul , but can confirm the problem
with +- 5V OV offset is just 86µV ..
get a good response with your AOP ..before to do scaling with ADC
View attachment 123171
Remember I'm using 16bit and not 10bits . At 70amp current draw full 75mV I calculate 4.39v output. This project will be 50amps max not like the other where that is 80amp max that's why I used 100amp shunt, sorry for the confusion I will soon be able to test it at 50-55amps as where I am at the moment limited to 25-30amps will try this tomorrow if time permitted, In working maths out 4.39*15.43 =67.74 not quite the 70amps as I expected.OK..
if your AOP is linear and with a Gain=58.6 ,
you will get 3.45V at 53.2Amps
and 3.45*1024/5.0=> 706 points read by ADC
so scaling is 706/532=13.28
706 / 13.28 will give the resilt 532 in 1/10em of Amps so place the decimal point to read 53.2 on LCD
Amps*10= Adc_Reading / 13.28
with this gain on AOP, your maxi Amps will be limited at 771 => 77.1 Amps , not 100.0 Amps !
coul you check and confirm this calculus ?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?