3 #if defined( ARDUINO_MEASURES_A_CURRENT) && (ARDUINO_MEASURES_A_CURRENT == YES)
9 extern unsigned long micros( void ) ;
10 extern unsigned long millis( void ) ;
11 extern void delay(unsigned long ms
) ;
14 OXS_CURRENT::OXS_CURRENT(uint8_t pinCurrent
, HardwareSerial
&print
)
16 OXS_CURRENT::OXS_CURRENT(uint8_t pinCurrent
)
21 printer
= &print
; //operate on the address of print
23 _pinCurrent
=pinCurrent
;
24 pinMode(pinCurrent
,INPUT
);
27 // **************** Setup the Current sensor *********************
28 void OXS_CURRENT::setupCurrent( ) {
30 float currentDivider
= 1.0 ;
31 #ifdef USE_INTERNAL_REFERENCE
32 analogReference(INTERNAL
) ;
33 #elif defined(USE_EXTERNAL_REFERENCE)
34 analogReference(EXTERNAL
) ;
36 #if defined(USE_INTERNAL_REFERENCE) && defined(REFERENCE_VOLTAGE) && REFERENCE_VOLTAGE < 2000
37 tempRef
= REFERENCE_VOLTAGE
;
38 #elif defined(USE_INTERNAL_REFERENCE) && defined(REFERENCE_VOLTAGE)
39 #error REFERENCE_VOLTAGE must be less than 2000 when USE_INTERNAL_REFERENCE is defined
40 #elif defined(USE_EXTERNAL_REFERENCE)
41 #ifndef REFERENCE_VOLTAGE
42 #error REFERENCE_VOLTAGE must be defined when USE_EXTERNAL_REFERENCE is defined
44 tempRef
= REFERENCE_VOLTAGE
;
46 #elif defined(USE_INTERNAL_REFERENCE)
48 #elif defined(REFERENCE_VOLTAGE) && REFERENCE_VOLTAGE > 2000
49 tempRef
= REFERENCE_VOLTAGE
;
50 #elif defined(REFERENCE_VOLTAGE)
51 #error REFERENCE_VOLTAGE must be greater than 2000 when USE_INTERNAL_REFERENCE is not defined
55 #if defined(RESISTOR_TO_GROUND_FOR_CURRENT) && defined(RESISTOR_TO_CURRENT_SENSOR)
56 if ( RESISTOR_TO_GROUND_FOR_CURRENT
> 0 && RESISTOR_TO_CURRENT_SENSOR
> 0) {
57 currentDivider
= 1.0 * (RESISTOR_TO_GROUND_FOR_CURRENT
+ RESISTOR_TO_CURRENT_SENSOR
) / RESISTOR_TO_GROUND_FOR_CURRENT
;
60 offsetCurrentSteps
= 1023.0 * MVOLT_AT_ZERO_AMP
/ tempRef
/ currentDivider
;
61 mAmpPerStep
= currentDivider
* tempRef
/ MVOLT_PER_AMP
/ 1.023 ;
63 currentData
.milliAmps
.available
= false;
64 currentData
.consumedMilliAmps
.available
= false;
65 // currentData.sumCurrent = 0 ;
68 printer
->print("Current sensor on pin:");
69 printer
->println(_pinCurrent
);
70 printer
->print("Reference voltage:");
71 printer
->println(tempRef
);
72 printer
->print("Offset for current:");
73 printer
->println(offsetCurrentSteps
);
74 printer
->print("mAmp per step:");
75 printer
->println(mAmpPerStep
);
76 printer
->print(" milli=");
77 printer
->println(millis());
83 // **************** Read the Current sensor *********************
84 #if defined(ARDUINO_MEASURES_A_CURRENT) && (ARDUINO_MEASURES_A_CURRENT == YES)
85 void OXS_CURRENT::readSensor() {
87 // static int cntMAmp =0;
88 static unsigned long lastCurrentMillis
= millis() ;
89 // static unsigned long UpdateMs=0;
90 static unsigned long milliTmp
= millis() ;
91 #ifdef USE_INTERNAL_REFERENCE
92 ADMUX
= _BV(REFS1
) | _BV(REFS0
) | _BV(MUX3
) | _BV(MUX2
) | _BV(MUX1
) | _BV(MUX0
); // binary = 11 00 1111 (11 = use internal VRef as max, 1111 = measure ground level)
93 #elif defined(USE_EXTERNAL_REFERENCE)
94 ADMUX
= _BV(MUX3
) | _BV(MUX2
) | _BV(MUX1
) | _BV(MUX0
); // binary = 00 00 1111 (00 = use external VRef as max, 1111 = measure ground level)
96 ADMUX
= _BV(REFS0
) | _BV(MUX3
) | _BV(MUX2
) | _BV(MUX1
) | _BV(MUX0
); // binary = 01 00 1111 (01 = use Vcc as max, 1111 = measure ground level)
98 delayMicroseconds(200); // Wait for Vref to settle
99 ADCSRA
|= _BV(ADSC
); // Start conversion
100 while (bit_is_set(ADCSRA
,ADSC
)); // wait that conversion is done
103 analogRead(_pinCurrent
) ; // make a first read to let ADCMux to set up
104 delayMicroseconds(200) ; // wait to be sure
105 //currentData.sumCurrent += analogRead(_pinCurrent) ;
106 sumCurrent
+= analogRead(_pinCurrent
) ;
108 milliTmp
= millis() ;
109 if( ( milliTmp
- lastCurrentMillis
) > 200 ) { // calculate average once per 200 millisec
110 currentData
.milliAmps
.value
= ((sumCurrent
/ cnt
) - offsetCurrentSteps
) * mAmpPerStep
;
111 // if (currentData.milliAmps.value < 0) currentData.milliAmps.value = 0 ;
112 currentData
.milliAmps
.available
= true ;
113 // if(currentData.minMilliAmps>currentData.milliAmps)currentData.minMilliAmps=currentData.milliAmps;
114 // if(currentData.maxMilliAmps<currentData.milliAmps)currentData.maxMilliAmps=currentData.milliAmps;
116 floatConsumedMilliAmps
+= ((float) currentData
.milliAmps
.value
) * (milliTmp
- lastCurrentMillis
) / 3600.0 /1000.0 ; // Mike , is this ok when millis() overrun????
117 currentData
.consumedMilliAmps
.value
= (int32_t) floatConsumedMilliAmps
;
118 currentData
.consumedMilliAmps
.available
= true ;
119 lastCurrentMillis
= milliTmp
;
121 printer
->print("At time = ");
122 printer
->print(milliTmp
);
123 printer
->print(" Cnt = ");
125 printer
->print(" average current = ");
126 printer
->print(currentData
.milliAmps
.value
);
127 printer
->print(" consumed milliAmph = ");
128 printer
->println(currentData
.consumedMilliAmps
.value
);
133 #endif // end of readSensor
135 void OXS_CURRENT::resetValues(){
136 currentData
.consumedMilliAmps
.value
=0;
137 floatConsumedMilliAmps
=0;
141 #endif // end of #if defined( ARDUINO_MEASURES_A_CURRENT) && (ARDUINO_MEASURES_A_CURRENT == YES)