Skip to content

Commit b6d896b

Browse files
authored
Merge pull request #33 from sparkfun/release_candidate
v1.3 Release - Improve logging options and stability
2 parents 24beb59 + 58c0338 commit b6d896b

File tree

72 files changed

+247472
-381461
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+247472
-381461
lines changed
Binary file not shown.
1.49 MB
Binary file not shown.

Firmware/RTK_Surveyor/Base.ino

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ bool configureUbloxModuleBase()
55
bool response = true;
66
int maxWait = 2000;
77

8-
digitalWrite(positionAccuracyLED_1cm, LOW);
9-
digitalWrite(positionAccuracyLED_10cm, LOW);
10-
digitalWrite(positionAccuracyLED_100cm, LOW);
8+
if (productVariant == RTK_SURVEYOR)
9+
{
10+
digitalWrite(pin_positionAccuracyLED_1cm, LOW);
11+
digitalWrite(pin_positionAccuracyLED_10cm, LOW);
12+
digitalWrite(pin_positionAccuracyLED_100cm, LOW);
13+
}
1114

1215
i2cGNSS.checkUblox(); //Regularly poll to get latest data and any RTCM
1316

@@ -116,22 +119,23 @@ bool startFixedBase()
116119
{
117120
//Break ECEF into main and high precision parts
118121
//The type casting should not effect rounding of original double cast coordinate
119-
long majorEcefX = settings.fixedEcefX * 100;
120-
long minorEcefX = ((settings.fixedEcefX * 100.0) - majorEcefX) * 100.0;
121-
long majorEcefY = settings.fixedEcefY * 100;
122-
long minorEcefY = ((settings.fixedEcefY * 100.0) - majorEcefY) * 100.0;
123-
long majorEcefZ = settings.fixedEcefZ * 100;
124-
long minorEcefZ = ((settings.fixedEcefZ * 100.0) - majorEcefZ) * 100.0;
122+
long majorEcefX = floor((settings.fixedEcefX * 100.0) + 0.5);
123+
long minorEcefX = floor((((settings.fixedEcefX * 100.0) - majorEcefX) * 100.0) + 0.5);
124+
long majorEcefY = floor((settings.fixedEcefY * 100) + 0.5);
125+
long minorEcefY = floor((((settings.fixedEcefY * 100.0) - majorEcefY) * 100.0) + 0.5);
126+
long majorEcefZ = floor((settings.fixedEcefZ * 100) + 0.5);
127+
long minorEcefZ = floor((((settings.fixedEcefZ * 100.0) - majorEcefZ) * 100.0) + 0.5);
125128

126-
// Serial.printf("fixedEcefY (should be -4716808.5807): %0.04f\n\r", settings.fixedEcefY);
127-
// Serial.printf("major (should be -471680858): %d\n\r", majorEcefY);
128-
// Serial.printf("minor (should be -7): %d\n\r", minorEcefY);
129+
// Serial.printf("fixedEcefY (should be -4716808.5807): %0.04f\n\r", settings.fixedEcefY);
130+
// Serial.printf("major (should be -471680858): %ld\n\r", majorEcefY);
131+
// Serial.printf("minor (should be -7): %ld\n\r", minorEcefY);
129132

130133
//Units are cm with a high precision extension so -1234.5678 should be called: (-123456, -78)
131134
//-1280208.308,-4716803.847,4086665.811 is SparkFun HQ so...
132135
response = i2cGNSS.setStaticPosition(majorEcefX, minorEcefX,
133136
majorEcefY, minorEcefY,
134137
majorEcefZ, minorEcefZ,
138+
false,
135139
maxWait
136140
); //With high precision 0.1mm parts
137141
}

Firmware/RTK_Surveyor/Begin.ino

Lines changed: 344 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
//Initial startup functions for GNSS, SD, display, radio, etc
2+
3+
//Based on hardware features, determine if this is RTK Surveyor or RTK Express hardware
4+
//Must be called after Wire.begin so that we can do I2C tests
5+
void beginBoard()
6+
{
7+
productVariant = RTK_SURVEYOR;
8+
if (isConnected(0x19) == true) //Check for accelerometer
9+
{
10+
productVariant = RTK_EXPRESS;
11+
}
12+
else if (analogRead(35) > 400 && analogRead(35) < 600)
13+
{
14+
productVariant = RTK_FACET;
15+
}
16+
17+
//Setup hardware pins
18+
if (productVariant == RTK_SURVEYOR)
19+
{
20+
pin_batteryLevelLED_Red = 32;
21+
pin_batteryLevelLED_Green = 33;
22+
pin_positionAccuracyLED_1cm = 2;
23+
pin_positionAccuracyLED_10cm = 15;
24+
pin_positionAccuracyLED_100cm = 13;
25+
pin_baseStatusLED = 4;
26+
pin_bluetoothStatusLED = 12;
27+
pin_baseSwitch = 5;
28+
pin_microSD_CS = 25;
29+
pin_zed_tx_ready = 26;
30+
pin_zed_reset = 27;
31+
pin_batteryLevel_alert = 36;
32+
33+
strcpy(platformFilePrefix, "SFE_Surveyor");
34+
strcpy(platformPrefix, "Surveyor");
35+
}
36+
else if (productVariant == RTK_EXPRESS)
37+
{
38+
pin_muxA = 2;
39+
pin_muxB = 4;
40+
pin_powerSenseAndControl = 13;
41+
pin_setupButton = 14;
42+
pin_microSD_CS = 25;
43+
pin_dac26 = 26;
44+
pin_powerFastOff = 27;
45+
pin_adc39 = 39;
46+
47+
pinMode(pin_powerSenseAndControl, INPUT_PULLUP);
48+
pinMode(pin_powerFastOff, INPUT);
49+
50+
if (esp_reset_reason() == ESP_RST_POWERON)
51+
{
52+
powerOnCheck(); //Only do check if we POR start
53+
}
54+
55+
pinMode(pin_setupButton, INPUT_PULLUP);
56+
57+
setMuxport(settings.dataPortChannel); //Set mux to user's choice: NMEA, I2C, PPS, or DAC
58+
59+
strcpy(platformFilePrefix, "SFE_Express");
60+
strcpy(platformPrefix, "Express");
61+
}
62+
else if (productVariant == RTK_FACET)
63+
{
64+
//v10
65+
pin_muxA = 2;
66+
pin_muxB = 0;
67+
pin_powerSenseAndControl = 13;
68+
pin_peripheralPowerControl = 14;
69+
pin_microSD_CS = 25;
70+
pin_dac26 = 26;
71+
pin_powerFastOff = 27;
72+
pin_adc39 = 39;
73+
74+
pinMode(pin_powerSenseAndControl, INPUT_PULLUP);
75+
pinMode(pin_powerFastOff, INPUT);
76+
77+
if (esp_reset_reason() == ESP_RST_POWERON)
78+
{
79+
powerOnCheck(); //Only do check if we POR start
80+
}
81+
82+
digitalWrite(pin_peripheralPowerControl, HIGH); //Turn on SD, ZED, etc
83+
84+
setMuxport(settings.dataPortChannel); //Set mux to user's choice: NMEA, I2C, PPS, or DAC
85+
86+
strcpy(platformFilePrefix, "SFE_Facet");
87+
strcpy(platformPrefix, "Facet");
88+
}
89+
90+
Serial.printf("SparkFun RTK %s v%d.%d-%s\r\n", platformPrefix, FIRMWARE_VERSION_MAJOR, FIRMWARE_VERSION_MINOR, __DATE__);
91+
92+
//For all boards, check reset reason. If reset was do to wdt or panic, append last log
93+
if (esp_reset_reason() == ESP_RST_POWERON)
94+
{
95+
reuseLastLog = false; //Start new log
96+
}
97+
else
98+
{
99+
reuseLastLog = true; //Attempt to reuse previous log
100+
101+
Serial.print("Reset reason: ");
102+
switch (esp_reset_reason())
103+
{
104+
case ESP_RST_UNKNOWN: Serial.println(F("ESP_RST_UNKNOWN")); break;
105+
case ESP_RST_POWERON : Serial.println(F("ESP_RST_POWERON")); break;
106+
case ESP_RST_SW : Serial.println(F("ESP_RST_SW")); break;
107+
case ESP_RST_PANIC : Serial.println(F("ESP_RST_PANIC")); break;
108+
case ESP_RST_INT_WDT : Serial.println(F("ESP_RST_INT_WDT")); break;
109+
case ESP_RST_TASK_WDT : Serial.println(F("ESP_RST_TASK_WDT")); break;
110+
case ESP_RST_WDT : Serial.println(F("ESP_RST_WDT")); break;
111+
case ESP_RST_DEEPSLEEP : Serial.println(F("ESP_RST_DEEPSLEEP")); break;
112+
case ESP_RST_BROWNOUT : Serial.println(F("ESP_RST_BROWNOUT")); break;
113+
case ESP_RST_SDIO : Serial.println(F("ESP_RST_SDIO")); break;
114+
default : Serial.println(F("Unknown"));
115+
}
116+
}
117+
}
118+
119+
void beginSD()
120+
{
121+
pinMode(pin_microSD_CS, OUTPUT);
122+
digitalWrite(pin_microSD_CS, HIGH); //Be sure SD is deselected
123+
124+
if (settings.enableSD == true)
125+
{
126+
//Max power up time is 250ms: https://www.kingston.com/datasheets/SDCIT-specsheet-64gb_en.pdf
127+
//Max current is 200mA average across 1s, peak 300mA
128+
delay(10);
129+
130+
if (sd.begin(SdSpiConfig(pin_microSD_CS, DEDICATED_SPI, SD_SCK_MHZ(settings.spiFrequency), &spi)) == false)
131+
{
132+
int tries = 0;
133+
int maxTries = 2;
134+
for ( ; tries < maxTries ; tries++)
135+
{
136+
Serial.printf("SD init failed. Trying again %d out of %d\n\r", tries + 1, maxTries);
137+
138+
delay(250); //Give SD more time to power up, then try again
139+
if (sd.begin(SdSpiConfig(pin_microSD_CS, DEDICATED_SPI, SD_SCK_MHZ(settings.spiFrequency), &spi)) == true) break;
140+
}
141+
142+
if (tries == maxTries)
143+
{
144+
Serial.println(F("SD init failed. Is card present? Formatted?"));
145+
digitalWrite(pin_microSD_CS, HIGH); //Be sure SD is deselected
146+
online.microSD = false;
147+
return;
148+
}
149+
}
150+
151+
//Change to root directory. All new file creation will be in root.
152+
if (sd.chdir() == false)
153+
{
154+
Serial.println(F("SD change directory failed"));
155+
online.microSD = false;
156+
return;
157+
}
158+
159+
//Setup FAT file access semaphore
160+
if (xFATSemaphore == NULL)
161+
{
162+
xFATSemaphore = xSemaphoreCreateMutex();
163+
if (xFATSemaphore != NULL)
164+
xSemaphoreGive(xFATSemaphore); //Make the file system available for use
165+
}
166+
167+
if (createTestFile() == false)
168+
{
169+
Serial.println(F("Failed to create test file. Format SD card with 'SD Card Formatter'."));
170+
displaySDFail(5000);
171+
online.microSD = false;
172+
return;
173+
}
174+
175+
online.microSD = true;
176+
}
177+
else
178+
{
179+
online.microSD = false;
180+
}
181+
}
182+
183+
//We do not start the UART2 for GNSS->BT reception here because the interrupts would be pinned to core 1
184+
//competing with I2C interrupts
185+
//See issue: https://github.com/espressif/arduino-esp32/issues/3386
186+
//We instead start a task that runs on core 0, that then begins serial
187+
void beginUART2()
188+
{
189+
if (startUART2TaskHandle == NULL) xTaskCreatePinnedToCore(
190+
startUART2Task,
191+
"UARTStart", //Just for humans
192+
2000, //Stack Size
193+
NULL, //Task input parameter
194+
0, // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
195+
&startUART2TaskHandle, //Task handle
196+
0); //Core where task should run, 0=core, 1=Arduino
197+
198+
while (uart2Started == false) //Wait for task to run once
199+
delay(1);
200+
}
201+
202+
//ESP32 requires the creation of an EEPROM space
203+
void beginEEPROM()
204+
{
205+
if (EEPROM.begin(EEPROM_SIZE) == false)
206+
Serial.println(F("beginEEPROM: Failed to initialize EEPROM"));
207+
else
208+
online.eeprom = true;
209+
}
210+
211+
void beginDisplay()
212+
{
213+
//0x3D is default on Qwiic board
214+
if (isConnected(0x3D) == true || isConnected(0x3C) == true)
215+
{
216+
online.display = true;
217+
218+
oled.setI2CTransactionSize(64); //Increase to page size of 64. Slight speed improvement over 32 bytes.
219+
220+
displaySplash();
221+
}
222+
}
223+
224+
//Connect to and configure ZED-F9P
225+
void beginGNSS()
226+
{
227+
if (i2cGNSS.begin() == false)
228+
{
229+
//Try again with power on delay
230+
delay(1000); //Wait for ZED-F9P to power up before it can respond to ACK
231+
if (i2cGNSS.begin() == false)
232+
{
233+
Serial.println(F("u-blox GNSS not detected at default I2C address. Hard stop."));
234+
displayGNSSFail(0);
235+
blinkError(ERROR_NO_I2C);
236+
}
237+
}
238+
239+
//Increase transactions to reduce transfer time
240+
i2cGNSS.i2cTransactionSize = 128;
241+
242+
//Check the firmware version of the ZED-F9P. Based on Example21_ModuleInfo.
243+
// if (i2cGNSS.getModuleInfo(1100) == true) // Try to get the module info
244+
// {
245+
// if (strcmp(i2cGNSS.minfo.extension[1], latestZEDFirmware) != 0)
246+
// {
247+
// Serial.print(F("The ZED-F9P appears to have outdated firmware. Found: "));
248+
// Serial.println(i2cGNSS.minfo.extension[1]);
249+
// Serial.print(F("The Surveyor works best with "));
250+
// Serial.println(latestZEDFirmware);
251+
// Serial.print(F("Please upgrade using u-center."));
252+
// Serial.println();
253+
// }
254+
// else
255+
// {
256+
// Serial.println(F("ZED-F9P firmware is current"));
257+
// }
258+
// }
259+
260+
bool response = configureUbloxModule();
261+
if (response == false)
262+
{
263+
//Try once more
264+
Serial.println(F("Failed to configure module. Trying again."));
265+
delay(1000);
266+
response = configureUbloxModule();
267+
268+
if (response == false)
269+
{
270+
Serial.println(F("Failed to configure module. Hard stop."));
271+
blinkError(ERROR_GPS_CONFIG_FAIL);
272+
}
273+
}
274+
275+
Serial.println(F("GNSS configuration complete"));
276+
277+
online.gnss = true;
278+
}
279+
280+
//Set LEDs for output and configure PWM
281+
void beginLEDs()
282+
{
283+
if (productVariant == RTK_SURVEYOR)
284+
{
285+
pinMode(pin_positionAccuracyLED_1cm, OUTPUT);
286+
pinMode(pin_positionAccuracyLED_10cm, OUTPUT);
287+
pinMode(pin_positionAccuracyLED_100cm, OUTPUT);
288+
pinMode(pin_baseStatusLED, OUTPUT);
289+
pinMode(pin_bluetoothStatusLED, OUTPUT);
290+
pinMode(pin_baseSwitch, INPUT_PULLUP); //HIGH = rover, LOW = base
291+
292+
digitalWrite(pin_positionAccuracyLED_1cm, LOW);
293+
digitalWrite(pin_positionAccuracyLED_10cm, LOW);
294+
digitalWrite(pin_positionAccuracyLED_100cm, LOW);
295+
digitalWrite(pin_baseStatusLED, LOW);
296+
digitalWrite(pin_bluetoothStatusLED, LOW);
297+
298+
ledcSetup(ledRedChannel, freq, resolution);
299+
ledcSetup(ledGreenChannel, freq, resolution);
300+
301+
ledcAttachPin(pin_batteryLevelLED_Red, ledRedChannel);
302+
ledcAttachPin(pin_batteryLevelLED_Green, ledGreenChannel);
303+
304+
ledcWrite(ledRedChannel, 0);
305+
ledcWrite(ledGreenChannel, 0);
306+
}
307+
}
308+
309+
//Configure the on board MAX17048 fuel gauge
310+
void beginFuelGauge()
311+
{
312+
// Set up the MAX17048 LiPo fuel gauge
313+
if (lipo.begin() == false)
314+
{
315+
Serial.println(F("MAX17048 not detected. Continuing."));
316+
return;
317+
}
318+
319+
//Always use hibernate mode
320+
if (lipo.getHIBRTActThr() < 0xFF) lipo.setHIBRTActThr((uint8_t)0xFF);
321+
if (lipo.getHIBRTHibThr() < 0xFF) lipo.setHIBRTHibThr((uint8_t)0xFF);
322+
323+
Serial.println(F("MAX17048 configuration complete"));
324+
325+
online.battery = true;
326+
}
327+
328+
//Begin accelerometer if available
329+
void beginAccelerometer()
330+
{
331+
if (accel.begin() == false)
332+
{
333+
online.accelerometer = false;
334+
return;
335+
}
336+
337+
//The larger the avgAmount the faster we should read the sensor
338+
//accel.setDataRate(LIS2DH12_ODR_100Hz); //6 measurements a second
339+
accel.setDataRate(LIS2DH12_ODR_400Hz); //25 measurements a second
340+
341+
Serial.println(F("Accelerometer configuration complete"));
342+
343+
online.accelerometer = true;
344+
}

0 commit comments

Comments
 (0)