Gisteravond wilde ik mijn soldeerwerkje af maken en dat is gelukt
Dus ik heb geen verdere tests meer gedaan met de ACS - ADS.
Ik zal toch een paar codes plaatsen die ik de afgelopen tijd geprobeert heb.
Alleen ACS
Code van:
https://www.romn.io/2020/...oach-to-measure-acdc.html
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
| #define PIN A0
float resolution = 3.3 / 1024; // Input Voltage Range is 1V to 3.3V
// ESP8266 ADC resolution is 10-bit. 2^10 = 1024
uint32_t period = 1000000 / 50; // One period of a periodic waveform
uint32_t t_start = 0;
// setup
float zero_ADC_Value = 0, zero_voltageValue = 0;
// loop
float ADC = 0, Vrms = 0, Current = 0, Q = 0.0147;
float sensitivity = 0.066; // 185 mV/A, 100 mV/A and 0.66 mV/A for ±5A, ±20A and ±30A current range respectively.
void setup()
{
Serial.begin(115200); // Initialize Serial communication
pinMode(PIN, INPUT); // Set pin A0 as read.
zero_ADC_Value = 835; // The avg analog value when no current pass throught the ACS712 sensor.
zero_voltageValue = zero_ADC_Value * resolution; // The ACS712 output voltage value when no current pass trough the sensor (i = 0)
}
void loop() {
/*----Vrms & Irms Calculation----*/
t_start = micros();
uint32_t ADC_Dif = 0, ADC_SUM = 0, m = 0;
while(micros() - t_start < period) { // Defining one period of the waveform. US frequency(f) is 60Hz. Period = 1/f = 0.016 seg = 16,666 microsec
ADC_Dif = zero_ADC_Value - analogRead(PIN); // To start from 0V we need to subtracting our initial value when no current passes through the current sensor, (i.e. 750 or 2.5V).
ADC_SUM += ADC_Dif * ADC_Dif; // SUM of the square
m++; // counter to be used for avg.
}
ADC = sqrt(ADC_SUM / m); // The root-mean-square ADC value.
Vrms = ADC * resolution ; // The root-mean-square analog voltage value.
Current = (Vrms / sensitivity) - Q; // The root-mean-square analog current value. Note: Q
//------------------------------//
Serial.print("analogRead = ");
Serial.println(analogRead(PIN));
Serial.print("Vrms = ");
Serial.print(Vrms, 6);
Serial.println(" V");
Serial.print("Irms = ");
Serial.print(Current, 6);
Serial.println(" A");
Serial.print("\n");
Serial.print("Zero_ADC = ");
Serial.print(zero_ADC_Value);
Serial.print("\n");
Serial.print("Zero_Voltage = ");
Serial.print(zero_voltageValue);
Serial.print("\n");
delay(1000);
} |
Resultaat:
Ik zag zeker verschil tussen wel en geen load.
Maar ik kon niet goed plaatsen hoe ik verder kon met het resultaat. Zo kreeg ik bv. een Irms van 0,6 A bij een load van ~60W
Dat lijkt me wat hoog... Of ik begrijp het niet goed ?
Code van:
https://github.com/RobTil...e/master/libraries/ACS712
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
| #include "ACS712.h"
// Arduino UNO has 5.0 volt with a max ADC value of 1024 steps
// ACS712 30A uses 66 mV per A
ACS712 ACS(A0, 5.0, 1023, 66);
const float calibration = 1;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
//ACS.setNoisemV(7);
ACS.setMidPoint(835);
//ACS.autoMidPoint();
}
void loop()
{
int mA = ACS.mA_AC();
Serial.println(mA);
if (mA > 0)
{
char c = mA;
float amps = (float) mA / 1000;
float volt = 230;
if (c == '*') ACS.setmVperAmp(ACS.getmVperAmp() + 1);
if (c == '/') ACS.setmVperAmp(ACS.getmVperAmp() - 1);
Serial.print("mVperAmp:\t");
Serial.println(ACS.getmVperAmp());
if (c == '+') ACS.setFormFactor(ACS.getFormFactor() * 1.05);
if (c == '-') ACS.setFormFactor(ACS.getFormFactor() / 1.05);
float formFactor = ACS.getFormFactor();
float calcWatt = formFactor * amps * volt * calibration;
Serial.print("formFactor:\t");
Serial.println(formFactor);
Serial.print("Amps:\t");
Serial.println(amps);
Serial.print("Watts:\t");
Serial.println(calcWatt);
}
//nrDelays++;
delay(1000);
} |
Resultaat:
Deze uitgebreide library heeft veel functies en ik heb die ook getest.
Wat erg van belang is, is de midPoint en FormFactor. Beide beïnvloeden het resultaat in A.
Hierbij kreeg ik wisselende resultaten, maar het kwam nooit goed overeen met de daadwerkelijke load.
Als ik "auto mid point" vaker deed aanroepen (bv. eens per 30sec) dan kon de formfactor soms wel 50% verschil maken. Niet echt stabiel dus. Maar als ik de tekst lees van hem op github is die formfactor wel erg belangrijk... Dat zag ik dus ook in de resultaten. Als die 1 bleef was het resultaat te hoog. Meestal zat ik op 0,3 tot 0,5 voor een beetje vergelijkbaar resultaat.
Code van: verschillende google zoekopdrachten om te testen
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
| unsigned int total; // holds <= 64 analogReads
byte numReadings = 64;
float offset = 833; // calibrate zero current
float span = 0.07393; // calibrate max current | ~0.07315 is for 30A sensor
float current; // holds final current
float totalAverage;
float totalAverageMinOffset;
float watts;
float volt = 230;
void setup() {
Serial.begin(115200);
}
void loop() {
total = 0; // reset
for (int i = 0; i < numReadings; i++) total += analogRead(A0);
totalAverage = (total / numReadings);
Serial.print("Total average is: ");
Serial.print(totalAverage);
Serial.println(" ");
totalAverageMinOffset = totalAverage - offset;
Serial.print("Total average min offset: ");
Serial.print(totalAverageMinOffset);
Serial.println(" ");
current = (total / numReadings - offset) * span;
Serial.print("Current is: ");
Serial.print(current);
//Serial.print(current, 1); // one decimal place
Serial.println(" Amp");
watts = current * volt;
Serial.print("Watts is: ");
Serial.print(watts);
Serial.println(" W");
delay(1000); // human readable
} |
Resultaat:
Deze code is wat simpeler, maar hier kreeg ik eigenlijk vrijwel geen verschil te zien tussen geen load en wel load. De verschillen in "totalAverage" waren te klein en dit komt denk ik door de foutmarge van de ACS.
ACS icm de ADS
Code van:
https://wolles-elektronikkiste.de/en/acs712-current-sensor-2
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
| #include<ADS1115_WE.h>
#include<Wire.h>
#define I2C_ADDRESS 0x48
const float zeroCurrentVoltage_mV = 2538;
ADS1115_WE adc(I2C_ADDRESS);
void setup() {
Wire.begin();
Serial.begin(115200);
if(!adc.init()){
Serial.println("ADS1115 not connected!");
}
/* Set the voltage range of the ADC to adjust the gain
* Please note that you must not apply more than VDD + 0.3V to the input pins!
*
* ADS1115_RANGE_6144 -> +/- 6144 mV
* ADS1115_RANGE_4096 -> +/- 4096 mV
* ADS1115_RANGE_2048 -> +/- 2048 mV (default)
* ADS1115_RANGE_1024 -> +/- 1024 mV
* ADS1115_RANGE_0512 -> +/- 512 mV
* ADS1115_RANGE_0256 -> +/- 256 mV
*/
adc.setVoltageRange_mV(ADS1115_RANGE_6144);
/* Set the inputs to be compared
*
* ADS1115_COMP_0_1 -> compares 0 with 1 (default)
* ADS1115_COMP_0_3 -> compares 0 with 3
* ADS1115_COMP_1_3 -> compares 1 with 3
* ADS1115_COMP_2_3 -> compares 2 with 3
* ADS1115_COMP_0_GND -> compares 0 with GND
* ADS1115_COMP_1_GND -> compares 1 with GND
* ADS1115_COMP_2_GND -> compares 2 with GND
* ADS1115_COMP_3_GND -> compares 3 with GND
*/
adc.setCompareChannels(ADS1115_COMP_0_GND);
Serial.println("ACS712 - Nullstrommessung mit ADS1115");
Serial.println();
}
void loop() {
float voltage = 0.0;
for(int i=0; i<10; i++){
adc.startSingleMeasurement();
while(adc.isBusy()){}
voltage += adc.getResult_mV();
}
voltage /= 10;
voltage -= zeroCurrentVoltage_mV;
float current = voltage/0.100;
Serial.print("ADC712-Spannung [mV]: "); // Voltage
Serial.print(voltage);
Serial.print(" / Strom [mA]: "); // Current
Serial.println(current);
delay(2000);
} |
Resultaat:
Ik compare hier analoog 0 met ground, omdat ik nog niks had aangesloten op 1. Heb ook geprobeert an1 aan te sluiten op ground, maar maakt geen verschil (de code werkt dus wat dat betreft).
Het resultaat in metingen is hierbij wel stabiel bij geen load. Stabieler dan alleen de ACS.
Echter als ik er een load op zet veranderd er te weinig. Het verspringt wel wat, maar totaal niet naar de goede waarde.
Het verschil tussen mijn opstelling en die op deze site staat is dus de voltage divider. Die heb ik nog niet geprobeerd. Heb wel verschillende weerstanden binnen nu om dat te doen.
Een ander voorbeeld met voltage divider vond ik hier:
https://curiousscientist.tech/blog/arduino-acs712-powermeter
Die code is gebaseerd op de adafruit library, het idee is hetzelfde. Die code heb ik ook (met wat aanpassingen) geprobeert maar het resultaat is niet anders.
Code van:
https://github.com/RobTillaart/ADS1X15
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
| #include "ADS1X15.h"
// choose you sensor
// ADS1013 ADS(0x48);
// ADS1014 ADS(0x48);
// ADS1015 ADS(0x48);
// ADS1113 ADS(0x48);
// ADS1114 ADS(0x48);
ADS1115 ADS(0x48);
float zeroPoint = 2.532;
float totalVolts;
float Voltage;
float Current;
float Power;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("ADS1X15_LIB_VERSION: ");
Serial.println(ADS1X15_LIB_VERSION);
ADS.begin();
ADS.setWireClock(400000);
ADS.setGain(0); // 6.144 volt
ADS.setDataRate(7); // fast = 7
ADS.setMode(0); // continuous mode
ADS.readADC(0); // first read to trigger
}
void loop()
{
MeasurePower();
PrintSerial();
//Serial.println(ADS.getValue());
delay(1000);
}
void MeasurePower()
{
totalVolts = ADS.getValue();
float f = ADS.toVoltage(1); // voltage factor
Voltage = totalVolts * f;
Current = (Voltage - zeroPoint) / 0.066;
//Watt = U * I as test
Power = 230 * Current;
}
void PrintSerial()
{
Serial.print(totalVolts);
Serial.print("\t"); //space as delimiter
Serial.print(Voltage,3);
Serial.print("\t");
Serial.print(Current,3);
Serial.print("\t");
Serial.println(Power,3);
} |
Resultaat:
Niet veel anders met de code hiervoor. Dit is een erg uitgebreide library. Heb het op verschillende snelheden (van de ADS) getest en ook zonder die "setWireClock" (I2C interface snelheid).
Maar ook hier dus een goed stabiele meting zonder load, maar weinig tot geen verschil mét load.