Files
@ 48235b240e56
Branch filter:
Location: seniordesign-firmware/master/master/lib/sensordata.c
48235b240e56
6.9 KiB
text/plain
Fixed issue where master battery voltage was not included in APRS transmission. Switched vBatt identifier from 'l' to 'b'
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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | /*
* Master Firmware: Sensor Data
*
* This file is part of OpenTrack.
*
* OpenTrack is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenTrack is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with OpenTrack. If not, see <http://www.gnu.org/licenses/>.
*
* Ethan Zonca
* Matthew Kanning
* Kyle Ripperger
* Matthew Kroening
*
*/
#include "../config.h"
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "sensordata.h"
#include "slavesensors.h"
#include "sensors.h"
#include "looptime.h"
#include "gps.h"
#include "logger.h"
// Slave sensor reading storage
int32_t slaves[MAX_NUM_SLAVES][MAX_NUM_SENSORS];
void sensordata_setup()
{
for(int i=0; i<MAX_NUM_SLAVES; i++)
{
for(int j=0; j<MAX_NUM_SENSORS; j++)
{
slaves[i][j] = -2111111111; // minimum value of 16 bit integer
}
}
}
// Store a sensor value in memory
void sensordata_set(uint8_t nodeID, uint8_t type, int32_t value)
{
if(nodeID < MAX_NUM_SLAVES)
{
slaves[nodeID][type] = value;
}
}
// Retrieve a sensor value from memory
int32_t sensordata_get(uint8_t nodeID, uint8_t type)
{
// Avoid reading out of bad places!
if(nodeID < MAX_NUM_SLAVES)
{
return slaves[nodeID][type];
}
else
{
return 0;
}
}
bool isEven = true;
// Generate APRS comment
// TODO: Can we move this buffer to a local scope of this function?
char* slavesensors_getAPRScomment(char* commentBuffer, uint16_t bufferSize)
{
snprintf(commentBuffer,bufferSize, "~v%s~_%s~|%s", get_speedKnots(), get_latitudeLSBs(), get_longitudeLSBs());
if(isEven)
{
// Master details
uint16_t len = strlen(commentBuffer);
snprintf(commentBuffer + len, bufferSize-len, "~t9%d~b9%d~s%s~h%s", sensors_getBoardTemp(), sensors_getBatt(), get_sv(), get_hdop());
// Find slave sensors to include in this log
for(int i=0; i<MAX_NUM_SLAVES; i++)
{
// Board temperature sensors (all slaves)
uint32_t val = sensordata_get(i, SENSOR_BOARDTEMP);
if(val != -2111111111) {
uint16_t len = strlen(commentBuffer);
snprintf(commentBuffer + len, bufferSize-len, "~t%u%li",i,val);
}
// Battery voltages (all slaves)
val = sensordata_get(i, SENSOR_BATTERYLEVEL);
if(val != -2111111111) {
uint16_t len = strlen(commentBuffer);
snprintf(commentBuffer + len, bufferSize-len, "~b%u%li",i,val);
}
// Pressure
val = sensordata_get(i, SENSOR_PRESSURE);
if(val != -2111111111) {
uint16_t len = strlen(commentBuffer);
snprintf(commentBuffer + len, bufferSize-len, "~P%li",val);
}
// Air Temperature
val = sensordata_get(i, SENSOR_AIRTEMP);
if(val != -2111111111) {
uint16_t len = strlen(commentBuffer);
snprintf(commentBuffer + len, bufferSize-len, "~C%li",val);
}
// Humidity
val = sensordata_get(i, SENSOR_HUMIDITY);
if(val != -2111111111) {
uint16_t len = strlen(commentBuffer);
snprintf(commentBuffer + len, bufferSize-len, "~H%li",val);
}
// Altitude
val = sensordata_get(i, SENSOR_ALTITUDE);
if(val != -2111111111) {
uint16_t len = strlen(commentBuffer);
snprintf(commentBuffer + len, bufferSize-len, "~A%li",val);
}
// Radiation
val = sensordata_get(i, SENSOR_CPM_RADIATION);
if(val != -2111111111) {
uint16_t len = strlen(commentBuffer);
snprintf(commentBuffer + len, bufferSize-len, "~R%li",val);
}
}
if(logger_aprsInfoTextAvailable())
{
uint16_t len = strlen(commentBuffer);
snprintf(commentBuffer + len, bufferSize-len, "~%s",logger_getAprsInfoText());
logger_aprsInfoTextConsumed();
}
isEven = false;
}
else {
// odd does nothing
isEven = true;
}
return commentBuffer;
}
// Generates CSV headers on first run and logs values to the SD card (if data available)
bool dataWasReady = false;
void sensordata_logvalues()
{
// Generate CSV header after we have queried all slaves once
if(slavesensors_dataReady())
{
// Only generate/write header the first time data is ready
if(!dataWasReady)
{
#define CSV_BUFFER_SIZE 64
char csvHeader[CSV_BUFFER_SIZE];
csvHeader[0] = 0x00;
// Add master data headers
logger_log("Time,BoardTemp,VBatt,GPSTime,GPSLat,GPSLon,GPSAlt,GPSSpeed,GPSHDOP,GPSCourse,GPSSV,");
// Add slave data headers
for(uint8_t i=0; i<MAX_NUM_SLAVES; i++)
{
for(uint8_t j=0; j<MAX_NUM_SENSORS; j++)
{
int32_t tmp = sensordata_get(i, j);
// If a sensor value exists, write a header for it
if(tmp != -2111111111)
{
snprintf(csvHeader, CSV_BUFFER_SIZE,"%s-%s,", slavesensors_slavename(i), slavesensors_getLabel(j));
logger_log(csvHeader);
}
}
}
// End line and write to SD card
snprintf(csvHeader, CSV_BUFFER_SIZE,"\r\n");
logger_log(csvHeader);
dataWasReady = true;
}
// Write CSV sensor values to SD card
#define CSV_LOGLINE_SIZE 512
char logbuf[CSV_LOGLINE_SIZE];
logbuf[0] = 0x00;
// Write master sensor values
snprintf(logbuf, CSV_LOGLINE_SIZE, "%lu,%d,%u,%s,%s%s,%s%s,%s,%s,%s,%s,%s,", time_millis(), sensors_getBoardTemp(), sensors_getBatt(), get_timestamp(), get_latitudeTrimmed(), get_latitudeLSBs(), get_longitudeTrimmed(), get_longitudeLSBs(),get_gpsaltitude(), get_speedKnots(), get_hdop(), get_course(), get_sv());
// Write slave sensor values
for(int i=0; i<MAX_NUM_SLAVES; i++)
{
for(int j=0; j<MAX_NUM_SENSORS; j++)
{
int32_t tmp = sensordata_get(i, j);
// If a sensor value exists, log the data
if(tmp != -2111111111)
{
snprintf(logbuf + strlen(logbuf),CSV_LOGLINE_SIZE-strlen(logbuf)," %ld,", tmp);
}
}
}
// End line and write to log
snprintf(logbuf + strlen(logbuf),CSV_LOGLINE_SIZE-strlen(logbuf),"\r\n");
logger_log(logbuf);
}
}
bool isTouchdown = false;
bool sensordata_isTouchdown()
{
return isTouchdown;
}
int32_t sensordata_getSensorValue(uint8_t sensorID)
{
// Loop through all slaves
for(int i=0; i<MAX_NUM_SLAVES; i++)
{
uint32_t val = sensordata_get(i, sensorID);
if(val != -2111111111) {
return val;
}
}
return -2111111111;
}
void sensordata_checkTouchdown()
{
// If we have reached touchdown, never get out of this state
if(isTouchdown)
{
return;
}
if(time_millis() > sysconfig->buzzer_failsafe_duration)
{
isTouchdown = true;
}
else
{
int32_t altitude = sensordata_getSensorValue(SENSOR_ALTITUDE);
if(altitude != -2111111111 && altitude < sysconfig->buzzer_trigger_maxaltitude && time_millis() > sysconfig->buzzer_trigger_minduration)
{
isTouchdown = true;
}
}
}
|