Update oXs_out_frsky.cpp
[openXsensor.git] / openXsensor / oXs_curr.cpp
blob168f0abee51f91da116e12179ccd8845ff56b224
1 #include "oXs_curr.h"
3 #if defined( ARDUINO_MEASURES_A_CURRENT) && (ARDUINO_MEASURES_A_CURRENT == YES)
5 #ifdef DEBUG
6 //#define DEBUGCURRENT
7 #endif
9 extern unsigned long micros( void ) ;
10 extern unsigned long millis( void ) ;
11 extern void delay(unsigned long ms) ;
13 #ifdef DEBUG
14 OXS_CURRENT::OXS_CURRENT(uint8_t pinCurrent, HardwareSerial &print)
15 #else
16 OXS_CURRENT::OXS_CURRENT(uint8_t pinCurrent)
17 #endif
19 // constructor
20 #ifdef DEBUG
21 printer = &print; //operate on the address of print
22 #endif
23 _pinCurrent=pinCurrent;
24 pinMode(pinCurrent,INPUT);
27 // **************** Setup the Current sensor *********************
28 void OXS_CURRENT::setupCurrent( ) {
29 uint16_t tempRef ;
30 float currentDivider = 1.0 ;
31 #ifdef USE_INTERNAL_REFERENCE
32 analogReference(INTERNAL) ;
33 #elif defined(USE_EXTERNAL_REFERENCE)
34 analogReference(EXTERNAL) ;
35 #endif
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
43 #else
44 tempRef = REFERENCE_VOLTAGE ;
45 #endif
46 #elif defined(USE_INTERNAL_REFERENCE)
47 tempRef = 1100 ;
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
52 #else
53 tempRef = 5000 ;
54 #endif
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 ;
59 #endif
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 ;
66 resetValues();
67 #ifdef DEBUG
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());
78 #endif
83 // **************** Read the Current sensor *********************
84 #if defined(ARDUINO_MEASURES_A_CURRENT) && (ARDUINO_MEASURES_A_CURRENT == YES)
85 void OXS_CURRENT::readSensor() {
86 static int cnt = 0;
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)
95 #else
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)
97 #endif
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) ;
107 cnt++ ;
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;
115 sumCurrent = 0;
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 ;
120 #ifdef DEBUGCURRENT
121 printer->print("At time = ");
122 printer->print(milliTmp);
123 printer->print(" Cnt = ");
124 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);
129 #endif
130 cnt = 0;
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)