Skip to content

Commit 51f39a1

Browse files
committed
Updated cell detection and avg of vols/amps
Changed the levels for cell-detection to avoid false detection of to many cells. The wrong number of cells may be detected if the battery is low on powerup. Won't change the cell count in flight if voltage drops. Changed the averaging of volts/amps to report the average volts/amps received through mavlink between each poll. Added a delay to try to eliminate low battery-warnings on model powerup.
1 parent b3caec5 commit 51f39a1

File tree

3 files changed

+146
-18
lines changed

3 files changed

+146
-18
lines changed

MavLink_FrSkySPort/Average.ino

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
12
uint16_t Volt_AverageBuffer[10];
23
uint16_t Current_AverageBuffer[10];
34

5+
// Used to calculate an average vibration level using accelerometers
46
#define accBufferSize 5
57
int32_t accXBuffer[accBufferSize];
68
int32_t accYBuffer[accBufferSize];
@@ -9,6 +11,103 @@ int nrSamplesX = 0;
911
int nrSamplesY = 0;
1012
int nrSamplesZ = 0;
1113

14+
// Used to calculate the average voltage/current between each frksy poll-request.
15+
// A bit overkill since we most of the time only receive one sample from mavlink between each poll.
16+
// voltageMinimum is used to report the lowest value received through mavlink between each poll frsky poll-request.
17+
uint32_t currentSum = 0;
18+
uint16_t currentCount = 0;
19+
uint32_t voltageSum = 0;
20+
uint16_t voltageCount = 0;
21+
uint16_t voltageMinimum = 0;
22+
23+
// Don't respond to FAS/FLVSS request until it looks like the voltage received through mavlink as stabilized.
24+
// This is a try to eliminate most of the low voltage alarms recevied upon model power up.
25+
boolean voltageStabilized = false;
26+
uint16_t voltageLast = 0;
27+
28+
// Store a voltage reading received through mavlink
29+
void storeVoltageReading(uint16_t value)
30+
{
31+
// Try to determine if the voltage has stabilized
32+
if(voltageStabilized == false)
33+
{
34+
// if we have a mavlink voltage, and its less then 0.5V higher then the last sample we got
35+
if(value > 3000 && (value - voltageLast)<500)
36+
{
37+
// The voltage seems to have stabilized
38+
voltageStabilized = true;
39+
}
40+
else
41+
{
42+
// Reported voltage seems to still increase. Save this sample
43+
voltageLast = value;
44+
}
45+
return;
46+
}
47+
48+
// Store this reading so we can return the average if we get multiple readings between the polls
49+
voltageSum += value;
50+
voltageCount++;
51+
// Update the minimu voltage if this is lover
52+
if(voltageMinimum < 1 || value < voltageMinimum)
53+
voltageMinimum = value;
54+
}
55+
56+
// Store a current reading received through mavlink
57+
void storeCurrentReading(uint16_t value)
58+
{
59+
// Only store if the voltage seems to have stabilized
60+
if(!voltageStabilized)
61+
return;
62+
currentSum += value;
63+
currentCount++;
64+
}
65+
66+
// Calculates and returns the average voltage value received through mavlink since the last time this function was called.
67+
// After the function is called the average is cleared.
68+
// Return 0 if we have no voltage reading
69+
uint16_t readAndResetAverageVoltage()
70+
{
71+
if(voltageCount < 1)
72+
return 0;
73+
debugSerial.print(millis());
74+
debugSerial.print("\tNumber of samples for voltage average: ");
75+
debugSerial.print(voltageCount);
76+
debugSerial.println();
77+
78+
uint16_t avg = voltageSum / voltageCount;
79+
80+
voltageSum = 0;
81+
voltageCount = 0;
82+
83+
return avg;
84+
}
85+
86+
// Return the lowest voltage reading received through mavlink since the last time function was called.
87+
// After the function is called the value is cleard.
88+
// Return 0 if we have no new reading
89+
uint16_t readAndResetMinimumVoltage()
90+
{
91+
uint16_t tmp = voltageMinimum;
92+
voltageMinimum = 0;
93+
return tmp;
94+
}
95+
96+
// Calculates and returns the average current value received through mavlink since the last time this function was called.
97+
// After the function is called the average is cleared.
98+
// Return 0 if we have no voltage reading
99+
uint16_t readAndResetAverageCurrent()
100+
{
101+
if(currentCount < 1)
102+
return 0;
103+
uint16_t avg = currentSum / currentCount;
104+
105+
currentSum = 0;
106+
currentCount = 0;
107+
108+
return avg;
109+
}
110+
12111
//returns the average of Voltage for the 10 last values
13112
uint32_t Get_Volt_Average(uint16_t value) {
14113
uint8_t i;
@@ -130,3 +229,6 @@ int32_t fetchAccZ()
130229
}
131230

132231

232+
233+
234+

MavLink_FrSkySPort/FrSkySPort.ino

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ void FrSkySPort_Process(void) {
5050
}
5151

5252
// ***********************************************************************
53+
uint16_t sendValueFlvssVoltage = 0;
54+
uint16_t sendValueFASCurrent = 0;
55+
uint16_t sendValueFASVoltage = 0;
5356
void FrSkySPort_ProcessSensorRequest(uint8_t sensorId)
5457
{
5558
uint32_t temp=0;
@@ -59,29 +62,41 @@ void FrSkySPort_ProcessSensorRequest(uint8_t sensorId)
5962
case SENSOR_ID_FLVSS:
6063
{
6164
printDebugPackageSend("FLVSS", nextFLVSS+1, 3);
65+
// We need cells to continue
66+
if(ap_cell_count < 1)
67+
break;
68+
// Make sure all the cells gets updated from the same voltage average
69+
if(nextFLVSS == 0)
70+
{
71+
sendValueFlvssVoltage = readAndResetMinimumVoltage();
72+
}
73+
// Only respond to request if we have a value
74+
if(sendValueFlvssVoltage < 1)
75+
break;
76+
6277
switch(nextFLVSS)
6378
{
6479
case 0:
6580
if(ap_cell_count > 0)
6681
{
6782
// First 2 cells
6883
offset = 0x00 | ((ap_cell_count & 0xF)<<4);
69-
temp=((ap_voltage_battery/(ap_cell_count * 2)) & 0xFFF);
84+
temp=((sendValueFlvssVoltage/(ap_cell_count * 2)) & 0xFFF);
7085
FrSkySPort_SendPackage(FR_ID_CELLS,(temp << 20) | (temp << 8) | offset); // Battery cell 0,1
7186
}
7287
break;
7388
case 1:
7489
// Optional 3 and 4 Cells
7590
if(ap_cell_count > 2) {
7691
offset = 0x02 | ((ap_cell_count & 0xF)<<4);
77-
temp=((ap_voltage_battery/(ap_cell_count * 2)) & 0xFFF);
92+
temp=((sendValueFlvssVoltage/(ap_cell_count * 2)) & 0xFFF);
7893
FrSkySPort_SendPackage(FR_ID_CELLS,(temp << 20) | (temp << 8) | offset); // Battery cell 2,3
7994
}
8095
break;
8196
case 2: // Optional 5 and 6 Cells
8297
if(ap_cell_count > 4) {
8398
offset = 0x04 | ((ap_cell_count & 0xF)<<4);
84-
temp=((ap_voltage_battery/(ap_cell_count * 2)) & 0xFFF);
99+
temp=((sendValueFlvssVoltage/(ap_cell_count * 2)) & 0xFFF);
85100
FrSkySPort_SendPackage(FR_ID_CELLS,(temp << 20) | (temp << 8) | offset); // Battery cell 2,3
86101
}
87102
break;
@@ -110,13 +125,20 @@ void FrSkySPort_ProcessSensorRequest(uint8_t sensorId)
110125
case SENSOR_ID_FAS:
111126
{
112127
printDebugPackageSend("FAS", nextFAS+1, 2);
128+
if(nextFAS == 0)
129+
{
130+
sendValueFASVoltage = readAndResetAverageVoltage();
131+
sendValueFASCurrent = readAndResetAverageCurrent();
132+
}
133+
if(sendValueFASVoltage < 1)
134+
break;
113135
switch(nextFAS)
114136
{
115137
case 0:
116-
FrSkySPort_SendPackage(FR_ID_CURRENT,ap_current_battery / 10);
138+
FrSkySPort_SendPackage(FR_ID_VFAS,sendValueFASVoltage/10); // Sends voltage as a VFAS value
117139
break;
118140
case 1:
119-
FrSkySPort_SendPackage(FR_ID_VFAS,ap_voltage_battery/10); // Sends voltage as a VFAS value
141+
FrSkySPort_SendPackage(FR_ID_CURRENT, sendValueFASCurrent / 10);
120142
break;
121143
}
122144
if(++nextFAS > 1)
@@ -203,6 +225,7 @@ void FrSkySPort_ProcessSensorRequest(uint8_t sensorId)
203225
debugSerial.print(sensorId, HEX);
204226
debugSerial.println();
205227
#endif
228+
;
206229
}
207230
}
208231

@@ -266,4 +289,3 @@ void FrSkySPort_SendPackage(uint16_t id, uint32_t value) {
266289

267290
digitalWrite(led,LOW);
268291
}
269-

MavLink_FrSkySPort/MavLink_FrSkySPort.ino

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ APM2.5 Mavlink to FrSky X8R SPort interface using Teensy 3.1 http://www.pjrc.co
5252
#define START 1
5353
#define MSG_RATE 10 // Hertz
5454

55-
#define DEBUG_VFR_HUD
56-
#define DEBUG_GPS_RAW
57-
#define DEBUG_ACC
58-
#define DEBUG_BAT
59-
#define DEBUG_FRSKY_SENSOR_REQUEST
55+
//#define DEBUG_VFR_HUD
56+
//#define DEBUG_GPS_RAW
57+
//#define DEBUG_ACC
58+
//#define DEBUG_BAT
59+
//#define DEBUG_FRSKY_SENSOR_REQUEST
6060

6161

6262
// ******************************************
@@ -197,6 +197,8 @@ void _MavLink_receive() {
197197
ap_voltage_battery = Get_Volt_Average(mavlink_msg_sys_status_get_voltage_battery(&msg)); // 1 = 1mV
198198
ap_current_battery = Get_Current_Average(mavlink_msg_sys_status_get_current_battery(&msg)); // 1=10mA
199199

200+
storeVoltageReading(ap_voltage_battery);
201+
storeCurrentReading(ap_current_battery);
200202
#ifdef DEBUG_BAT
201203
debugSerial.print(millis());
202204
debugSerial.print("\tMAVLINK_MSG_ID_SYS_STATUS: voltage_battery: ");
@@ -205,13 +207,15 @@ void _MavLink_receive() {
205207
debugSerial.print(mavlink_msg_sys_status_get_current_battery(&msg));
206208
debugSerial.println();
207209
#endif
208-
209-
if(ap_voltage_battery > 21000) ap_cell_count = 6;
210-
else if (ap_voltage_battery > 16800 && ap_cell_count != 6) ap_cell_count = 5;
211-
else if(ap_voltage_battery > 12600 && ap_cell_count != 5) ap_cell_count = 4;
212-
else if(ap_voltage_battery > 8400 && ap_cell_count != 4) ap_cell_count = 3;
213-
else if(ap_voltage_battery > 4200 && ap_cell_count != 3) ap_cell_count = 2;
214-
else ap_cell_count = 0;
210+
uint8_t temp_cell_count;
211+
if(ap_voltage_battery > 21000) temp_cell_count = 6;
212+
else if (ap_voltage_battery > 17500) temp_cell_count = 5;
213+
else if(ap_voltage_battery > 12750) temp_cell_count = 4;
214+
else if(ap_voltage_battery > 8500) temp_cell_count = 3;
215+
else if(ap_voltage_battery > 4250) temp_cell_count = 2;
216+
else temp_cell_count = 0;
217+
if(temp_cell_count > ap_cell_count)
218+
ap_cell_count = temp_cell_count;
215219
break;
216220
case MAVLINK_MSG_ID_GPS_RAW_INT: // 24
217221
ap_fixtype = mavlink_msg_gps_raw_int_get_fix_type(&msg); // 0 = No GPS, 1 =No Fix, 2 = 2D Fix, 3 = 3D Fix

0 commit comments

Comments
 (0)