target.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. #include <Arduino.h>
  2. #include "target.h"
  3. #include <helpers/ArduinoHelpers.h>
  4. #include <helpers/sensors/MicroNMEALocationProvider.h>
  5. RAK4631Board board;
  6. RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
  7. WRAPPER_CLASS radio_driver(radio, board);
  8. VolatileRTCClock fallback_clock;
  9. AutoDiscoverRTCClock rtc_clock(fallback_clock);
  10. #if ENV_INCLUDE_GPS
  11. MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Wire);
  12. RAK4631SensorManager sensors = RAK4631SensorManager(nmea);
  13. #else
  14. RAK4631SensorManager sensors;
  15. #endif
  16. #ifdef DISPLAY_CLASS
  17. DISPLAY_CLASS display;
  18. #endif
  19. #ifdef MESH_DEBUG
  20. uint32_t deviceOnline = 0x00;
  21. void scanDevices(TwoWire *w)
  22. {
  23. uint8_t err, addr;
  24. int nDevices = 0;
  25. uint32_t start = 0;
  26. Serial.println("Scanning I2C for Devices");
  27. for (addr = 1; addr < 127; addr++) {
  28. start = millis();
  29. w->beginTransmission(addr); delay(2);
  30. err = w->endTransmission();
  31. if (err == 0) {
  32. nDevices++;
  33. switch (addr) {
  34. case 0x42:
  35. Serial.println("\tFound RAK12500 GPS Sensor");
  36. deviceOnline |= RAK12500_ONLINE;
  37. break;
  38. default:
  39. Serial.print("\tI2C device found at address 0x");
  40. if (addr < 16) {
  41. Serial.print("0");
  42. }
  43. Serial.print(addr, HEX);
  44. Serial.println(" !");
  45. break;
  46. }
  47. } else if (err == 4) {
  48. Serial.print("Unknow error at address 0x");
  49. if (addr < 16) {
  50. Serial.print("0");
  51. }
  52. Serial.println(addr, HEX);
  53. }
  54. }
  55. if (nDevices == 0)
  56. Serial.println("No I2C devices found\n");
  57. Serial.println("Scan for devices is complete.");
  58. Serial.println("\n");
  59. }
  60. #endif
  61. bool radio_init() {
  62. rtc_clock.begin(Wire);
  63. return radio.std_init(&SPI);
  64. }
  65. uint32_t radio_get_rng_seed() {
  66. return radio.random(0x7FFFFFFF);
  67. }
  68. void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
  69. radio.setFrequency(freq);
  70. radio.setSpreadingFactor(sf);
  71. radio.setBandwidth(bw);
  72. radio.setCodingRate(cr);
  73. }
  74. void radio_set_tx_power(uint8_t dbm) {
  75. radio.setOutputPower(dbm);
  76. }
  77. #if ENV_INCLUDE_GPS
  78. void RAK4631SensorManager::start_gps()
  79. {
  80. //function currently not used
  81. gps_active = true;
  82. pinMode(disStandbyPin, OUTPUT);
  83. digitalWrite(disStandbyPin, 1);
  84. MESH_DEBUG_PRINTLN("GPS should be on now");
  85. }
  86. void RAK4631SensorManager::stop_gps()
  87. {
  88. //function currently not used
  89. gps_active = false;
  90. pinMode(disStandbyPin, OUTPUT);
  91. digitalWrite(disStandbyPin, 0);
  92. MESH_DEBUG_PRINTLN("GPS should be off now");
  93. }
  94. void RAK4631SensorManager::sleep_gps() {
  95. gps_active = false;
  96. ublox_GNSS.powerSaveMode();
  97. MESH_DEBUG_PRINTLN("GPS should be sleeping now");
  98. }
  99. void RAK4631SensorManager::wake_gps() {
  100. gps_active = true;
  101. ublox_GNSS.powerSaveMode(false);
  102. MESH_DEBUG_PRINTLN("GPS should be waking now");
  103. }
  104. bool RAK4631SensorManager::gpsIsAwake(uint32_t ioPin){
  105. int pinInitialState = 0;
  106. //set initial waking state
  107. pinMode(ioPin,OUTPUT);
  108. digitalWrite(ioPin,0);
  109. delay(1000);
  110. digitalWrite(ioPin,1);
  111. delay(1000);
  112. if (ublox_GNSS.begin(Wire) == true){
  113. MESH_DEBUG_PRINTLN("GPS init correctly and GPS is turned on");
  114. ublox_GNSS.setI2COutput(COM_TYPE_NMEA);
  115. ublox_GNSS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT);
  116. disStandbyPin = ioPin;
  117. gps_active = true;
  118. gps_present = true;
  119. return true;
  120. }
  121. else
  122. MESH_DEBUG_PRINTLN("GPS failed to init on this IO pin... try the next");
  123. //digitalWrite(ioPin,pinInitialState); //reset the IO pin to initial state
  124. return false;
  125. }
  126. #endif
  127. bool RAK4631SensorManager::begin() {
  128. #ifdef MESH_DEBUG
  129. scanDevices(&Wire);
  130. #endif
  131. #if ENV_INCLUDE_GPS
  132. //search for the correct IO standby pin depending on socket used
  133. if(gpsIsAwake(P_GPS_STANDBY_A)){
  134. MESH_DEBUG_PRINTLN("GPS is on socket A");
  135. }
  136. else if(gpsIsAwake(P_GPS_STANDBY_C)){
  137. MESH_DEBUG_PRINTLN("GPS is on socket C");
  138. }
  139. else if(gpsIsAwake(P_GPS_STANDBY_F)){
  140. MESH_DEBUG_PRINTLN("GPS is on socket F");
  141. }
  142. else{
  143. MESH_DEBUG_PRINTLN("Error: No GPS found on sockets A, C or F");
  144. gps_active = false;
  145. gps_present = false;
  146. return false;
  147. }
  148. //Now that GPS is found and set up, set to sleep for initial state
  149. stop_gps();
  150. #endif
  151. }
  152. #if ENV_INCLUDE_GPS
  153. bool RAK4631SensorManager::querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) {
  154. if (requester_permissions & TELEM_PERM_LOCATION && gps_active) { // does requester have permission?
  155. telemetry.addGPS(TELEM_CHANNEL_SELF, node_lat, node_lon, node_altitude);
  156. }
  157. return true;
  158. }
  159. void RAK4631SensorManager::loop() {
  160. static long next_update = 0;
  161. _nmea->loop();
  162. if (millis() > next_update && gps_active) {
  163. node_lat = (double)ublox_GNSS.getLatitude()/10000000.;
  164. node_lon = (double)ublox_GNSS.getLongitude()/10000000.;
  165. node_altitude = (double)ublox_GNSS.getAltitude()/1000.;
  166. MESH_DEBUG_PRINT("lat %f lon %f alt %f\r\n", node_lat, node_lon, node_altitude);
  167. next_update = millis() + 1000;
  168. }
  169. }
  170. int RAK4631SensorManager::getNumSettings() const { return 1; } // just one supported: "gps" (power switch)
  171. const char* RAK4631SensorManager::getSettingName(int i) const {
  172. return i == 0 ? "gps" : NULL;
  173. }
  174. const char* RAK4631SensorManager::getSettingValue(int i) const {
  175. if (i == 0) {
  176. return gps_active ? "1" : "0";
  177. }
  178. return NULL;
  179. }
  180. bool RAK4631SensorManager::setSettingValue(const char* name, const char* value) {
  181. if (strcmp(name, "gps") == 0) {
  182. if (strcmp(value, "0") == 0) {
  183. stop_gps();
  184. } else {
  185. start_gps();
  186. }
  187. return true;
  188. }
  189. return false; // not supported
  190. }
  191. #endif
  192. mesh::LocalIdentity radio_new_identity() {
  193. RadioNoiseListener rng(radio);
  194. return mesh::LocalIdentity(&rng); // create new random identity
  195. }