Greg Voronin
/
gammaCanary02
This version is the one to be submitted as a part the Hackster.io contest, Unleash Invisible Intelligence
main.cpp@0:a761fba7f8a8, 2018-07-31 (annotated)
- Committer:
- gov1
- Date:
- Tue Jul 31 16:30:32 2018 +0000
- Revision:
- 0:a761fba7f8a8
complete version with emer. batt low check
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gov1 | 0:a761fba7f8a8 | 1 | #include "mbed.h" |
gov1 | 0:a761fba7f8a8 | 2 | #include "LoRa.h" |
gov1 | 0:a761fba7f8a8 | 3 | #include "MBed_Adafruit_GPS.h" |
gov1 | 0:a761fba7f8a8 | 4 | #include "MAX17055.h" |
gov1 | 0:a761fba7f8a8 | 5 | |
gov1 | 0:a761fba7f8a8 | 6 | Serial pc (USBTX, USBRX); // debug serial port |
gov1 | 0:a761fba7f8a8 | 7 | DigitalOut led1(LED1); // debug blinker |
gov1 | 0:a761fba7f8a8 | 8 | |
gov1 | 0:a761fba7f8a8 | 9 | /******************************************************************************/ |
gov1 | 0:a761fba7f8a8 | 10 | /*************************** Power & Fuel Gauge *******************************/ |
gov1 | 0:a761fba7f8a8 | 11 | /******************************************************************************/ |
gov1 | 0:a761fba7f8a8 | 12 | DigitalOut powerHLD(P2_2, 1); //keep power on when connected to battery |
gov1 | 0:a761fba7f8a8 | 13 | I2C i2c(I2C2_SDA, I2C2_SCL); |
gov1 | 0:a761fba7f8a8 | 14 | MAX17055 max17055(i2c); |
gov1 | 0:a761fba7f8a8 | 15 | int gaugeStatus; |
gov1 | 0:a761fba7f8a8 | 16 | int stateOfCharge, timeToEmpty; |
gov1 | 0:a761fba7f8a8 | 17 | float batteryVoltage, batteryCurrent, boardTemperature, tteReport; |
gov1 | 0:a761fba7f8a8 | 18 | #define FUEL_REFRESH 30 // 120 secs, 2 minutes for now, testing . . . |
gov1 | 0:a761fba7f8a8 | 19 | |
gov1 | 0:a761fba7f8a8 | 20 | Timer fuelTimer; |
gov1 | 0:a761fba7f8a8 | 21 | Timer batteryEmergencyPause; // avoid sending alert right after starting unit up! |
gov1 | 0:a761fba7f8a8 | 22 | bool startBatteryEmergency; |
gov1 | 0:a761fba7f8a8 | 23 | bool inBatteryEmergencyState; |
gov1 | 0:a761fba7f8a8 | 24 | #define EMERBEGIN 180000 // 3 minutes in millissecond after setup runs |
gov1 | 0:a761fba7f8a8 | 25 | void readFuelGauge(void); |
gov1 | 0:a761fba7f8a8 | 26 | /************************* End Power & Fuel Guage *****************************/ |
gov1 | 0:a761fba7f8a8 | 27 | |
gov1 | 0:a761fba7f8a8 | 28 | /******************************************************************************/ |
gov1 | 0:a761fba7f8a8 | 29 | /***************************** LoRa TxRx **************************************/ |
gov1 | 0:a761fba7f8a8 | 30 | /******************************************************************************/ |
gov1 | 0:a761fba7f8a8 | 31 | #define GATEWAYID 0x30 // LoRa Gateway ID |
gov1 | 0:a761fba7f8a8 | 32 | #define LOCALADDRESSID 0x31 // this gamma canary ID |
gov1 | 0:a761fba7f8a8 | 33 | #define GPSDATA 0x40 |
gov1 | 0:a761fba7f8a8 | 34 | #define CPMDATA 0x41 |
gov1 | 0:a761fba7f8a8 | 35 | #define FUELDATA 0x42 |
gov1 | 0:a761fba7f8a8 | 36 | #define LOWBATTERY 0x43 |
gov1 | 0:a761fba7f8a8 | 37 | // #define CPMALERT 0x44 |
gov1 | 0:a761fba7f8a8 | 38 | |
gov1 | 0:a761fba7f8a8 | 39 | // data transmission/report intervals |
gov1 | 0:a761fba7f8a8 | 40 | // #define LOCATION_INTERVAL 15.0 // GPS location every 120 secs |
gov1 | 0:a761fba7f8a8 | 41 | // #define CPM_INTERVAL 60.0 // CPM every 60 secs |
gov1 | 0:a761fba7f8a8 | 42 | // #define FUEL_INTERVAL 90.0 // Fuel Gauge every 90 secs |
gov1 | 0:a761fba7f8a8 | 43 | |
gov1 | 0:a761fba7f8a8 | 44 | // data transmission/report intervals |
gov1 | 0:a761fba7f8a8 | 45 | float LOCATION_INTERVAL = 15.0; // GPS location every 120 secs |
gov1 | 0:a761fba7f8a8 | 46 | float CPM_INTERVAL = 60.0; // CPM every 60 secs |
gov1 | 0:a761fba7f8a8 | 47 | float FUEL_INTERVAL = 90.0; // Fuel Gauge every 90 secs |
gov1 | 0:a761fba7f8a8 | 48 | |
gov1 | 0:a761fba7f8a8 | 49 | volatile int locationCountDown, cpmCountDown, fuelCountDown; |
gov1 | 0:a761fba7f8a8 | 50 | |
gov1 | 0:a761fba7f8a8 | 51 | Ticker transmissionTicker; |
gov1 | 0:a761fba7f8a8 | 52 | void transmitLoRaTicker(void) |
gov1 | 0:a761fba7f8a8 | 53 | { |
gov1 | 0:a761fba7f8a8 | 54 | if (locationCountDown > 0) locationCountDown--; |
gov1 | 0:a761fba7f8a8 | 55 | if (cpmCountDown > 0) cpmCountDown--; |
gov1 | 0:a761fba7f8a8 | 56 | if (fuelCountDown >0) fuelCountDown--; |
gov1 | 0:a761fba7f8a8 | 57 | } |
gov1 | 0:a761fba7f8a8 | 58 | |
gov1 | 0:a761fba7f8a8 | 59 | void transmitLocation(void); |
gov1 | 0:a761fba7f8a8 | 60 | void transmitCPM(void); |
gov1 | 0:a761fba7f8a8 | 61 | void transmitFuel(void); |
gov1 | 0:a761fba7f8a8 | 62 | void batteryLowTransmit(); |
gov1 | 0:a761fba7f8a8 | 63 | void onReceive(int packetSize); |
gov1 | 0:a761fba7f8a8 | 64 | /*************************** End LoRa *****************************************/ |
gov1 | 0:a761fba7f8a8 | 65 | |
gov1 | 0:a761fba7f8a8 | 66 | /******************************************************************************/ |
gov1 | 0:a761fba7f8a8 | 67 | /******************************** GPS *****************************************/ |
gov1 | 0:a761fba7f8a8 | 68 | /******************************************************************************/ |
gov1 | 0:a761fba7f8a8 | 69 | double currentLatitude, currentLongitude, previousLatitude, previousLongitude; |
gov1 | 0:a761fba7f8a8 | 70 | Serial * _gpsSerial; |
gov1 | 0:a761fba7f8a8 | 71 | |
gov1 | 0:a761fba7f8a8 | 72 | #define GPS_REFRESH 5000 // 2000 millisecs??? |
gov1 | 0:a761fba7f8a8 | 73 | Timer gpsTimer; // GPS data collection/refresh timer |
gov1 | 0:a761fba7f8a8 | 74 | |
gov1 | 0:a761fba7f8a8 | 75 | void transformGPSData(double lat, char p, double lon, char m); |
gov1 | 0:a761fba7f8a8 | 76 | // GPS command list at http://www.adafruit.com/datasheets/PMTK_A08.pdf |
gov1 | 0:a761fba7f8a8 | 77 | /**************************** End GPS *****************************************/ |
gov1 | 0:a761fba7f8a8 | 78 | |
gov1 | 0:a761fba7f8a8 | 79 | /******************************************************************************/ |
gov1 | 0:a761fba7f8a8 | 80 | /*********************** Begin Radiation Monitoring ***************************/ |
gov1 | 0:a761fba7f8a8 | 81 | /******************************************************************************/ |
gov1 | 0:a761fba7f8a8 | 82 | // PMOD Port 1 pins for radiation sensor |
gov1 | 0:a761fba7f8a8 | 83 | volatile int signalCounter, noiseCounter; |
gov1 | 0:a761fba7f8a8 | 84 | InterruptIn signalPin(P1_0); |
gov1 | 0:a761fba7f8a8 | 85 | InterruptIn noisePin(P1_1); |
gov1 | 0:a761fba7f8a8 | 86 | // interrupt service routines(ISR) which count are called whenever signal or noise pins are triggered |
gov1 | 0:a761fba7f8a8 | 87 | void signalISR(){ signalCounter++; led1 = !led1;} |
gov1 | 0:a761fba7f8a8 | 88 | void noiseISR(){ noiseCounter++; } |
gov1 | 0:a761fba7f8a8 | 89 | |
gov1 | 0:a761fba7f8a8 | 90 | // #define CPMALERTLEVEL 50 // set very low or testing purposes. |
gov1 | 0:a761fba7f8a8 | 91 | // #DEFINE CPMMAXALERTS 3 // only three at a time to not bomb SMS network! |
gov1 | 0:a761fba7f8a8 | 92 | #define CPM_REFRESH 60 // 60 seconds in a minute |
gov1 | 0:a761fba7f8a8 | 93 | Timer cpmTimer; // CPM data collection, determine total current counts per minute |
gov1 | 0:a761fba7f8a8 | 94 | |
gov1 | 0:a761fba7f8a8 | 95 | int currentSignalCount, currentNoiseCount, previousCPM, currentCPM; |
gov1 | 0:a761fba7f8a8 | 96 | int previousTotalSignalCount, previousTotalNoiseCount; |
gov1 | 0:a761fba7f8a8 | 97 | |
gov1 | 0:a761fba7f8a8 | 98 | void calculateCPM(); |
gov1 | 0:a761fba7f8a8 | 99 | /*********************** End Radiation Monitoring *****************************/ |
gov1 | 0:a761fba7f8a8 | 100 | |
gov1 | 0:a761fba7f8a8 | 101 | |
gov1 | 0:a761fba7f8a8 | 102 | int main() |
gov1 | 0:a761fba7f8a8 | 103 | { |
gov1 | 0:a761fba7f8a8 | 104 | /****************************** Setup *************************************/ |
gov1 | 0:a761fba7f8a8 | 105 | pc.printf(" ********* gamma canary v001 ********* \n"); |
gov1 | 0:a761fba7f8a8 | 106 | |
gov1 | 0:a761fba7f8a8 | 107 | /** 0. Confirm running on battery power **/ |
gov1 | 0:a761fba7f8a8 | 108 | if (powerHLD.is_connected()) {pc.printf("Battery power connected...\n");} |
gov1 | 0:a761fba7f8a8 | 109 | |
gov1 | 0:a761fba7f8a8 | 110 | /** 1. LoRa TxRx initialization **/ |
gov1 | 0:a761fba7f8a8 | 111 | if (!LoRa.begin(915E6)) {pc.printf("LoRa not found!");} |
gov1 | 0:a761fba7f8a8 | 112 | else { pc.printf("LoRa started...\n");} |
gov1 | 0:a761fba7f8a8 | 113 | // LoRa.onReceive(onReceive); |
gov1 | 0:a761fba7f8a8 | 114 | // LoRa.receive(); |
gov1 | 0:a761fba7f8a8 | 115 | transmissionTicker.attach(&transmitLoRaTicker,1.0); |
gov1 | 0:a761fba7f8a8 | 116 | |
gov1 | 0:a761fba7f8a8 | 117 | /** 2. GPS/NMEA Initialization **/ |
gov1 | 0:a761fba7f8a8 | 118 | currentLongitude = 0.00; |
gov1 | 0:a761fba7f8a8 | 119 | previousLongitude = currentLongitude; |
gov1 | 0:a761fba7f8a8 | 120 | currentLatitude = 0.00; |
gov1 | 0:a761fba7f8a8 | 121 | previousLatitude = currentLatitude; |
gov1 | 0:a761fba7f8a8 | 122 | |
gov1 | 0:a761fba7f8a8 | 123 | _gpsSerial = new Serial(P3_1,P3_0); //serial object for use w/ GPS |
gov1 | 0:a761fba7f8a8 | 124 | Adafruit_GPS myGPS(_gpsSerial); |
gov1 | 0:a761fba7f8a8 | 125 | myGPS.begin(9600); |
gov1 | 0:a761fba7f8a8 | 126 | char c; |
gov1 | 0:a761fba7f8a8 | 127 | myGPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //these commands are defined in MBed_Adafruit_GPS.h; a link is provided there for command creation |
gov1 | 0:a761fba7f8a8 | 128 | myGPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); |
gov1 | 0:a761fba7f8a8 | 129 | myGPS.sendCommand(PGCMD_ANTENNA); |
gov1 | 0:a761fba7f8a8 | 130 | gpsTimer.start(); |
gov1 | 0:a761fba7f8a8 | 131 | pc.printf("GPS setup done...\n"); |
gov1 | 0:a761fba7f8a8 | 132 | |
gov1 | 0:a761fba7f8a8 | 133 | //** 3. Radiation Detecton - CPM(Counts Per Minute) |
gov1 | 0:a761fba7f8a8 | 134 | currentSignalCount = 0; |
gov1 | 0:a761fba7f8a8 | 135 | previousTotalSignalCount = 0; |
gov1 | 0:a761fba7f8a8 | 136 | currentNoiseCount = 0; |
gov1 | 0:a761fba7f8a8 | 137 | previousTotalNoiseCount = 0; |
gov1 | 0:a761fba7f8a8 | 138 | currentCPM = 0; |
gov1 | 0:a761fba7f8a8 | 139 | previousCPM = 0; |
gov1 | 0:a761fba7f8a8 | 140 | signalPin.rise(&signalISR); // attach ISR function to the rising edge |
gov1 | 0:a761fba7f8a8 | 141 | noisePin.rise(&noiseISR); // attach ISR function to the rising edge |
gov1 | 0:a761fba7f8a8 | 142 | cpmTimer.start(); |
gov1 | 0:a761fba7f8a8 | 143 | pc.printf("Starting radiation monitoring...\n"); |
gov1 | 0:a761fba7f8a8 | 144 | |
gov1 | 0:a761fba7f8a8 | 145 | /** 4. Fuel Gauge/Battery Monitoring **/ |
gov1 | 0:a761fba7f8a8 | 146 | max17055.init(0.05f); |
gov1 | 0:a761fba7f8a8 | 147 | max17055.status(&gaugeStatus); |
gov1 | 0:a761fba7f8a8 | 148 | fuelTimer.start(); |
gov1 | 0:a761fba7f8a8 | 149 | startBatteryEmergency = false; |
gov1 | 0:a761fba7f8a8 | 150 | inBatteryEmergencyState = false; |
gov1 | 0:a761fba7f8a8 | 151 | batteryEmergencyPause.start(); |
gov1 | 0:a761fba7f8a8 | 152 | pc.printf("MAX17055 status: %04X\r\n", (uint16_t)gaugeStatus); |
gov1 | 0:a761fba7f8a8 | 153 | wait(3.0); |
gov1 | 0:a761fba7f8a8 | 154 | pc.printf("Setup complete...\n"); |
gov1 | 0:a761fba7f8a8 | 155 | |
gov1 | 0:a761fba7f8a8 | 156 | /***************************** End Setup **********************************/ |
gov1 | 0:a761fba7f8a8 | 157 | // loop() |
gov1 | 0:a761fba7f8a8 | 158 | while(1) |
gov1 | 0:a761fba7f8a8 | 159 | { |
gov1 | 0:a761fba7f8a8 | 160 | |
gov1 | 0:a761fba7f8a8 | 161 | /** GPS/Location Data Collection"loop" here **/ |
gov1 | 0:a761fba7f8a8 | 162 | c = myGPS.read(); //queries the GPS |
gov1 | 0:a761fba7f8a8 | 163 | if ( myGPS.newNMEAreceived() ) |
gov1 | 0:a761fba7f8a8 | 164 | { |
gov1 | 0:a761fba7f8a8 | 165 | if ( !myGPS.parse(myGPS.lastNMEA()) ) { |
gov1 | 0:a761fba7f8a8 | 166 | continue; |
gov1 | 0:a761fba7f8a8 | 167 | } |
gov1 | 0:a761fba7f8a8 | 168 | } |
gov1 | 0:a761fba7f8a8 | 169 | |
gov1 | 0:a761fba7f8a8 | 170 | //check if enough time has passed to warrant printing GPS info to screen |
gov1 | 0:a761fba7f8a8 | 171 | //note if refresh_Time is too low or pc.baud is too low, GPS data may be lost during printing |
gov1 | 0:a761fba7f8a8 | 172 | if (gpsTimer.read_ms() >= GPS_REFRESH) |
gov1 | 0:a761fba7f8a8 | 173 | { |
gov1 | 0:a761fba7f8a8 | 174 | gpsTimer.reset(); |
gov1 | 0:a761fba7f8a8 | 175 | if (myGPS.fix) { |
gov1 | 0:a761fba7f8a8 | 176 | // pc.printf("Location: %5.2f%c, %5.2f%c\n", myGPS.latitude, myGPS.lat, myGPS.longitude, myGPS.lon); |
gov1 | 0:a761fba7f8a8 | 177 | // previousLatitude = currentLatitude; |
gov1 | 0:a761fba7f8a8 | 178 | // previousLongitude = currentLongitude; |
gov1 | 0:a761fba7f8a8 | 179 | // currentLatitude = myGPS.latitude; |
gov1 | 0:a761fba7f8a8 | 180 | // currentLongitude = myGPS.longitude; |
gov1 | 0:a761fba7f8a8 | 181 | transformGPSData(myGPS.latitude, myGPS.lat, myGPS.longitude, myGPS.lon); |
gov1 | 0:a761fba7f8a8 | 182 | } |
gov1 | 0:a761fba7f8a8 | 183 | } |
gov1 | 0:a761fba7f8a8 | 184 | |
gov1 | 0:a761fba7f8a8 | 185 | if (cpmTimer.read() >= CPM_REFRESH) |
gov1 | 0:a761fba7f8a8 | 186 | { |
gov1 | 0:a761fba7f8a8 | 187 | cpmTimer.reset(); |
gov1 | 0:a761fba7f8a8 | 188 | calculateCPM(); |
gov1 | 0:a761fba7f8a8 | 189 | } |
gov1 | 0:a761fba7f8a8 | 190 | |
gov1 | 0:a761fba7f8a8 | 191 | if (fuelTimer.read() >= FUEL_REFRESH) |
gov1 | 0:a761fba7f8a8 | 192 | { |
gov1 | 0:a761fba7f8a8 | 193 | fuelTimer.reset(); |
gov1 | 0:a761fba7f8a8 | 194 | readFuelGauge(); |
gov1 | 0:a761fba7f8a8 | 195 | } |
gov1 | 0:a761fba7f8a8 | 196 | |
gov1 | 0:a761fba7f8a8 | 197 | // special 1 time timer to begin battery monitoring for emergency lo battery warning |
gov1 | 0:a761fba7f8a8 | 198 | |
gov1 | 0:a761fba7f8a8 | 199 | if( batteryEmergencyPause.read_ms() >= EMERBEGIN ) |
gov1 | 0:a761fba7f8a8 | 200 | { |
gov1 | 0:a761fba7f8a8 | 201 | batteryEmergencyPause.stop(); |
gov1 | 0:a761fba7f8a8 | 202 | startBatteryEmergency = true; |
gov1 | 0:a761fba7f8a8 | 203 | } |
gov1 | 0:a761fba7f8a8 | 204 | |
gov1 | 0:a761fba7f8a8 | 205 | /** LoRa Data Transmision **/ |
gov1 | 0:a761fba7f8a8 | 206 | if (locationCountDown == 0) |
gov1 | 0:a761fba7f8a8 | 207 | { |
gov1 | 0:a761fba7f8a8 | 208 | locationCountDown = LOCATION_INTERVAL; |
gov1 | 0:a761fba7f8a8 | 209 | transmitLocation(); |
gov1 | 0:a761fba7f8a8 | 210 | } |
gov1 | 0:a761fba7f8a8 | 211 | if (cpmCountDown == 0) |
gov1 | 0:a761fba7f8a8 | 212 | { |
gov1 | 0:a761fba7f8a8 | 213 | cpmCountDown = CPM_INTERVAL; |
gov1 | 0:a761fba7f8a8 | 214 | transmitCPM(); |
gov1 | 0:a761fba7f8a8 | 215 | } |
gov1 | 0:a761fba7f8a8 | 216 | if (fuelCountDown == 0) |
gov1 | 0:a761fba7f8a8 | 217 | { |
gov1 | 0:a761fba7f8a8 | 218 | fuelCountDown = FUEL_INTERVAL; |
gov1 | 0:a761fba7f8a8 | 219 | transmitFuel(); |
gov1 | 0:a761fba7f8a8 | 220 | } |
gov1 | 0:a761fba7f8a8 | 221 | |
gov1 | 0:a761fba7f8a8 | 222 | } // end loop |
gov1 | 0:a761fba7f8a8 | 223 | |
gov1 | 0:a761fba7f8a8 | 224 | } |
gov1 | 0:a761fba7f8a8 | 225 | |
gov1 | 0:a761fba7f8a8 | 226 | /** GPS Functions **/ |
gov1 | 0:a761fba7f8a8 | 227 | void transformGPSData(double lat, char parallel, double lon, char meridian) |
gov1 | 0:a761fba7f8a8 | 228 | { |
gov1 | 0:a761fba7f8a8 | 229 | float degrees = floor(lat/100.00); |
gov1 | 0:a761fba7f8a8 | 230 | double minutes = lat - (100.00*degrees); |
gov1 | 0:a761fba7f8a8 | 231 | minutes /= 60.00; |
gov1 | 0:a761fba7f8a8 | 232 | degrees += minutes; |
gov1 | 0:a761fba7f8a8 | 233 | if (parallel=='S') { degrees *= -1.00; } |
gov1 | 0:a761fba7f8a8 | 234 | |
gov1 | 0:a761fba7f8a8 | 235 | double dLatitude = degrees; |
gov1 | 0:a761fba7f8a8 | 236 | |
gov1 | 0:a761fba7f8a8 | 237 | degrees = floor(lon/100.00); |
gov1 | 0:a761fba7f8a8 | 238 | minutes = lon - (100.00*degrees); |
gov1 | 0:a761fba7f8a8 | 239 | minutes /= 60.00; |
gov1 | 0:a761fba7f8a8 | 240 | degrees += minutes; |
gov1 | 0:a761fba7f8a8 | 241 | if (meridian == 'W') { degrees *= -1.00; } |
gov1 | 0:a761fba7f8a8 | 242 | |
gov1 | 0:a761fba7f8a8 | 243 | double dLongitude = degrees; |
gov1 | 0:a761fba7f8a8 | 244 | currentLatitude = dLatitude; |
gov1 | 0:a761fba7f8a8 | 245 | currentLongitude = dLongitude; |
gov1 | 0:a761fba7f8a8 | 246 | pc.printf("LAT: %f ", dLatitude); |
gov1 | 0:a761fba7f8a8 | 247 | pc.printf("LON: %f\n", dLongitude); |
gov1 | 0:a761fba7f8a8 | 248 | } |
gov1 | 0:a761fba7f8a8 | 249 | |
gov1 | 0:a761fba7f8a8 | 250 | /** CPM functions **/ |
gov1 | 0:a761fba7f8a8 | 251 | void calculateCPM() |
gov1 | 0:a761fba7f8a8 | 252 | { |
gov1 | 0:a761fba7f8a8 | 253 | |
gov1 | 0:a761fba7f8a8 | 254 | currentSignalCount = signalCounter - previousTotalSignalCount; |
gov1 | 0:a761fba7f8a8 | 255 | previousTotalSignalCount = signalCounter; |
gov1 | 0:a761fba7f8a8 | 256 | |
gov1 | 0:a761fba7f8a8 | 257 | currentNoiseCount = noiseCounter - previousTotalNoiseCount; |
gov1 | 0:a761fba7f8a8 | 258 | previousTotalNoiseCount = noiseCounter; |
gov1 | 0:a761fba7f8a8 | 259 | |
gov1 | 0:a761fba7f8a8 | 260 | previousCPM = currentCPM; |
gov1 | 0:a761fba7f8a8 | 261 | currentCPM = currentSignalCount - currentNoiseCount; |
gov1 | 0:a761fba7f8a8 | 262 | |
gov1 | 0:a761fba7f8a8 | 263 | pc.printf("signal: %d, noise: %d, ", currentSignalCount, currentNoiseCount); |
gov1 | 0:a761fba7f8a8 | 264 | pc.printf("Current CPM: %d\n", currentCPM); |
gov1 | 0:a761fba7f8a8 | 265 | |
gov1 | 0:a761fba7f8a8 | 266 | } |
gov1 | 0:a761fba7f8a8 | 267 | |
gov1 | 0:a761fba7f8a8 | 268 | /** Fuel Guage Functions **/ |
gov1 | 0:a761fba7f8a8 | 269 | void readFuelGauge() |
gov1 | 0:a761fba7f8a8 | 270 | { |
gov1 | 0:a761fba7f8a8 | 271 | max17055.v_cell(&batteryVoltage); |
gov1 | 0:a761fba7f8a8 | 272 | printf("%6.3fV ", batteryVoltage); |
gov1 | 0:a761fba7f8a8 | 273 | |
gov1 | 0:a761fba7f8a8 | 274 | max17055.current(&batteryCurrent); |
gov1 | 0:a761fba7f8a8 | 275 | printf("%6.3fI ", batteryCurrent); |
gov1 | 0:a761fba7f8a8 | 276 | |
gov1 | 0:a761fba7f8a8 | 277 | max17055.temp(&boardTemperature); |
gov1 | 0:a761fba7f8a8 | 278 | printf("%6.3fC ", boardTemperature); |
gov1 | 0:a761fba7f8a8 | 279 | |
gov1 | 0:a761fba7f8a8 | 280 | max17055.reportSOC(&stateOfCharge); |
gov1 | 0:a761fba7f8a8 | 281 | if (startBatteryEmergency and !inBatteryEmergencyState) |
gov1 | 0:a761fba7f8a8 | 282 | { |
gov1 | 0:a761fba7f8a8 | 283 | pc.printf("emergency battery monitoring set\n"); |
gov1 | 0:a761fba7f8a8 | 284 | if (stateOfCharge < 51.0) |
gov1 | 0:a761fba7f8a8 | 285 | { |
gov1 | 0:a761fba7f8a8 | 286 | inBatteryEmergencyState = true; // prevents sending messages over and over again, future versions to reset this when bat > 50 again; |
gov1 | 0:a761fba7f8a8 | 287 | batteryLowTransmit(); |
gov1 | 0:a761fba7f8a8 | 288 | } |
gov1 | 0:a761fba7f8a8 | 289 | } |
gov1 | 0:a761fba7f8a8 | 290 | printf(" SOC:%d\\% ",stateOfCharge); |
gov1 | 0:a761fba7f8a8 | 291 | |
gov1 | 0:a761fba7f8a8 | 292 | // max17055.tte1(&timeToEmpty); |
gov1 | 0:a761fba7f8a8 | 293 | // tteReport = ((5.625)*timeToEmpty)/120.0; |
gov1 | 0:a761fba7f8a8 | 294 | // printf(" TTE:%6.2fhours \n", tteReport); |
gov1 | 0:a761fba7f8a8 | 295 | |
gov1 | 0:a761fba7f8a8 | 296 | } |
gov1 | 0:a761fba7f8a8 | 297 | |
gov1 | 0:a761fba7f8a8 | 298 | /** LoRa TxRx Functions **/ |
gov1 | 0:a761fba7f8a8 | 299 | void transmitLocation() |
gov1 | 0:a761fba7f8a8 | 300 | { |
gov1 | 0:a761fba7f8a8 | 301 | // transmite GPS/Location data, lat/lon |
gov1 | 0:a761fba7f8a8 | 302 | LoRa.beginPacket(); |
gov1 | 0:a761fba7f8a8 | 303 | |
gov1 | 0:a761fba7f8a8 | 304 | // Packet Header |
gov1 | 0:a761fba7f8a8 | 305 | LoRa.printf("%c",LOCALADDRESSID); LoRa.printf("**"); |
gov1 | 0:a761fba7f8a8 | 306 | LoRa.printf("%c",GPSDATA); LoRa.printf("**"); |
gov1 | 0:a761fba7f8a8 | 307 | |
gov1 | 0:a761fba7f8a8 | 308 | // Packet Contents |
gov1 | 0:a761fba7f8a8 | 309 | LoRa.printf("%f",currentLatitude);LoRa.printf("**"); |
gov1 | 0:a761fba7f8a8 | 310 | LoRa.printf("%f",currentLongitude);LoRa.printf("**"); |
gov1 | 0:a761fba7f8a8 | 311 | |
gov1 | 0:a761fba7f8a8 | 312 | LoRa.endPacket(); |
gov1 | 0:a761fba7f8a8 | 313 | pc.printf("LoRa GPS Packet Sent\n"); |
gov1 | 0:a761fba7f8a8 | 314 | } |
gov1 | 0:a761fba7f8a8 | 315 | |
gov1 | 0:a761fba7f8a8 | 316 | void transmitCPM() |
gov1 | 0:a761fba7f8a8 | 317 | { |
gov1 | 0:a761fba7f8a8 | 318 | // Transmit Radiation data: CPM = Counts Per Minute, current reading |
gov1 | 0:a761fba7f8a8 | 319 | LoRa.beginPacket(); |
gov1 | 0:a761fba7f8a8 | 320 | |
gov1 | 0:a761fba7f8a8 | 321 | // Packet Header |
gov1 | 0:a761fba7f8a8 | 322 | LoRa.printf("%c",LOCALADDRESSID); LoRa.printf("**"); |
gov1 | 0:a761fba7f8a8 | 323 | LoRa.printf("%c",CPMDATA); LoRa.printf("**"); |
gov1 | 0:a761fba7f8a8 | 324 | |
gov1 | 0:a761fba7f8a8 | 325 | // Packet Contents |
gov1 | 0:a761fba7f8a8 | 326 | LoRa.printf("%d",currentCPM);LoRa.printf("**"); |
gov1 | 0:a761fba7f8a8 | 327 | LoRa.printf("%d", "-1");LoRa.printf("**"); |
gov1 | 0:a761fba7f8a8 | 328 | |
gov1 | 0:a761fba7f8a8 | 329 | LoRa.endPacket(); |
gov1 | 0:a761fba7f8a8 | 330 | pc.printf("LoRa CPM Packet Sent\n"); |
gov1 | 0:a761fba7f8a8 | 331 | } |
gov1 | 0:a761fba7f8a8 | 332 | void transmitFuel() |
gov1 | 0:a761fba7f8a8 | 333 | { |
gov1 | 0:a761fba7f8a8 | 334 | // Transimet Battery/Fuel Gauge data: voltage, current, temp |
gov1 | 0:a761fba7f8a8 | 335 | LoRa.beginPacket(); |
gov1 | 0:a761fba7f8a8 | 336 | |
gov1 | 0:a761fba7f8a8 | 337 | // Packet Header |
gov1 | 0:a761fba7f8a8 | 338 | LoRa.printf("%c",LOCALADDRESSID); LoRa.printf("**"); |
gov1 | 0:a761fba7f8a8 | 339 | LoRa.printf("%c",FUELDATA); LoRa.printf("**"); |
gov1 | 0:a761fba7f8a8 | 340 | |
gov1 | 0:a761fba7f8a8 | 341 | LoRa.printf("%d",stateOfCharge);LoRa.printf("**"); |
gov1 | 0:a761fba7f8a8 | 342 | LoRa.printf("%f",tteReport);LoRa.printf("**"); // time to empty in hours |
gov1 | 0:a761fba7f8a8 | 343 | LoRa.printf("%f",boardTemperature);LoRa.printf("**"); |
gov1 | 0:a761fba7f8a8 | 344 | |
gov1 | 0:a761fba7f8a8 | 345 | // Packet Contents |
gov1 | 0:a761fba7f8a8 | 346 | |
gov1 | 0:a761fba7f8a8 | 347 | LoRa.endPacket(); |
gov1 | 0:a761fba7f8a8 | 348 | pc.printf("LoRa Fuel Gauge Packet Sent\n"); |
gov1 | 0:a761fba7f8a8 | 349 | } |
gov1 | 0:a761fba7f8a8 | 350 | |
gov1 | 0:a761fba7f8a8 | 351 | void batteryLowTransmit() |
gov1 | 0:a761fba7f8a8 | 352 | { |
gov1 | 0:a761fba7f8a8 | 353 | /** broadcast warning low battery/increased transmisson intervals **/ |
gov1 | 0:a761fba7f8a8 | 354 | |
gov1 | 0:a761fba7f8a8 | 355 | // extend transmission intervals to conserve power |
gov1 | 0:a761fba7f8a8 | 356 | LOCATION_INTERVAL = 150.0; |
gov1 | 0:a761fba7f8a8 | 357 | CPM_INTERVAL = 600.0; |
gov1 | 0:a761fba7f8a8 | 358 | FUEL_INTERVAL = 900.0; |
gov1 | 0:a761fba7f8a8 | 359 | |
gov1 | 0:a761fba7f8a8 | 360 | // Transimet Battery/Fuel Gauge data: voltage, current, temp |
gov1 | 0:a761fba7f8a8 | 361 | LoRa.beginPacket(); |
gov1 | 0:a761fba7f8a8 | 362 | |
gov1 | 0:a761fba7f8a8 | 363 | // Packet Header |
gov1 | 0:a761fba7f8a8 | 364 | LoRa.printf("%c",LOCALADDRESSID); LoRa.printf("**"); |
gov1 | 0:a761fba7f8a8 | 365 | LoRa.printf("%c",LOWBATTERY); LoRa.printf("**"); |
gov1 | 0:a761fba7f8a8 | 366 | |
gov1 | 0:a761fba7f8a8 | 367 | LoRa.printf("%d",stateOfCharge);LoRa.printf("**"); |
gov1 | 0:a761fba7f8a8 | 368 | |
gov1 | 0:a761fba7f8a8 | 369 | LoRa.endPacket(); |
gov1 | 0:a761fba7f8a8 | 370 | pc.printf("LoRa Low Battery Packet Sent\n"); |
gov1 | 0:a761fba7f8a8 | 371 | |
gov1 | 0:a761fba7f8a8 | 372 | } |
gov1 | 0:a761fba7f8a8 | 373 | |
gov1 | 0:a761fba7f8a8 | 374 | void onReceive(int packetSize) |
gov1 | 0:a761fba7f8a8 | 375 | { |
gov1 | 0:a761fba7f8a8 | 376 | char msg[45]; |
gov1 | 0:a761fba7f8a8 | 377 | pc.printf("PACKET RECEIVED, SIZE:%d \n", packetSize); |
gov1 | 0:a761fba7f8a8 | 378 | for (int i = 0; i<packetSize; i++) |
gov1 | 0:a761fba7f8a8 | 379 | { if ( i < 45) |
gov1 | 0:a761fba7f8a8 | 380 | { |
gov1 | 0:a761fba7f8a8 | 381 | msg[i] = (char)LoRa._getc(); |
gov1 | 0:a761fba7f8a8 | 382 | } |
gov1 | 0:a761fba7f8a8 | 383 | } |
gov1 | 0:a761fba7f8a8 | 384 | pc.printf("RSSI: %d, ", LoRa.packetRssi()); pc.printf("MSG:%s \n",msg); |
gov1 | 0:a761fba7f8a8 | 385 | if (msg[0] == LOCALADDRESSID) |
gov1 | 0:a761fba7f8a8 | 386 | { |
gov1 | 0:a761fba7f8a8 | 387 | pc.printf("received from %x\n", msg[0]); |
gov1 | 0:a761fba7f8a8 | 388 | } |
gov1 | 0:a761fba7f8a8 | 389 | else { |
gov1 | 0:a761fba7f8a8 | 390 | pc.printf("dont know who, %x is, ignore msg\n", msg[0]); |
gov1 | 0:a761fba7f8a8 | 391 | } |
gov1 | 0:a761fba7f8a8 | 392 | } |