Skip to content

Commit d132e48

Browse files
committed
Adding Ticker and xTask demos
1 parent 5688707 commit d132e48

File tree

12 files changed

+1153
-0
lines changed

12 files changed

+1153
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//Ping an I2C device and see if it responds
2+
bool isConnected(uint8_t deviceAddress)
3+
{
4+
Wire.beginTransmission(deviceAddress);
5+
if (Wire.endTransmission() == 0)
6+
return true;
7+
return false;
8+
}
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*
2+
Use Ticker library to periodically check:
3+
Blink BT LED
4+
Check battery
5+
Update display
6+
Check GPS
7+
8+
Update GPS data - We are going to use autoPVT and setAutoHPPOSLLH with Explicit Update. We will checkUblox() every 100ms.
9+
This will cause all dataums (SIV, HPA, etc) to update regularly but when we call getSIV() we will not force wait for the most recent
10+
data. This will also have the added benefit of regularly feeding processRTCM. Every checkUblox() call will pass any waiting RTCM
11+
bytes to a future NTRIP server.
12+
13+
Because tickers can interrupt other tickers, we use a mutex semphore for the I2C hardware.
14+
15+
This implementation still has display errors for unknown reasons. Going to try xTasks next.
16+
*/
17+
18+
19+
const int FIRMWARE_VERSION_MAJOR = 1;
20+
const int FIRMWARE_VERSION_MINOR = 1;
21+
22+
#include "settings.h"
23+
24+
SemaphoreHandle_t xI2CSemaphore;
25+
const int i2cSemaphore_maxWait = 5; //TickType_t
26+
27+
//Hardware connections
28+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
29+
const int positionAccuracyLED_1cm = 2;
30+
const int baseStatusLED = 4;
31+
const int baseSwitch = 5;
32+
const int bluetoothStatusLED = 12;
33+
const int positionAccuracyLED_100cm = 13;
34+
const int positionAccuracyLED_10cm = 15;
35+
const byte PIN_MICROSD_CHIP_SELECT = 25;
36+
const int zed_tx_ready = 26;
37+
const int zed_reset = 27;
38+
const int batteryLevelLED_Red = 32;
39+
const int batteryLevelLED_Green = 33;
40+
const int batteryLevel_alert = 36;
41+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
42+
43+
//Low frequency tasks
44+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
45+
#include <Ticker.h>
46+
47+
Ticker checkUbloxTask;
48+
float checkUbloxTaskPace = 0.1; //Seconds
49+
50+
Ticker btLEDTask;
51+
float btLEDTaskPace = 0.5; //Seconds
52+
53+
Ticker updateDisplayTask;
54+
float updateDisplayTaskPace = 0.5; //Seconds
55+
56+
Ticker battCheckTask;
57+
float battCheckTaskPace = 2.0; //Seconds
58+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
59+
60+
//External Display
61+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
62+
#include <SFE_MicroOLED.h> //Click here to get the library: http://librarymanager/All#SparkFun_Micro_OLED
63+
#include "icons.h"
64+
65+
#define PIN_RESET 9
66+
#define DC_JUMPER 1
67+
MicroOLED oled(PIN_RESET, DC_JUMPER);
68+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
69+
70+
//GNSS configuration
71+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
72+
#define MAX_PAYLOAD_SIZE 384 // Override MAX_PAYLOAD_SIZE for getModuleInfo which can return up to 348 bytes
73+
74+
#include "SparkFun_Ublox_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_Ublox_GPS
75+
//SFE_UBLOX_GPS myGPS;
76+
77+
// Extend the class for getModuleInfo - See Example21_ModuleInfo
78+
class SFE_UBLOX_GPS_ADD : public SFE_UBLOX_GPS
79+
{
80+
public:
81+
boolean getModuleInfo(uint16_t maxWait = 1100); //Queries module, texts
82+
83+
struct minfoStructure // Structure to hold the module info (uses 341 bytes of RAM)
84+
{
85+
char swVersion[30];
86+
char hwVersion[10];
87+
uint8_t extensionNo = 0;
88+
char extension[10][30];
89+
} minfo;
90+
};
91+
92+
SFE_UBLOX_GPS_ADD myGPS;
93+
94+
//This string is used to verify the firmware on the ZED-F9P. This
95+
//firmware relies on various features of the ZED and may require the latest
96+
//u-blox firmware to work correctly. We check the module firmware at startup but
97+
//don't prevent operation if firmware is mismatched.
98+
char latestZEDFirmware[] = "FWVER=HPG 1.13";
99+
100+
//Used for config ZED for things not supported in library: getPortSettings, getSerialRate, getNMEASettings, getRTCMSettings
101+
//This array holds the payload data bytes. Global so that we can use between config functions.
102+
uint8_t settingPayload[MAX_PAYLOAD_SIZE];
103+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
104+
105+
106+
//Battery fuel gauge and PWM LEDs
107+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
108+
#include <SparkFun_MAX1704x_Fuel_Gauge_Arduino_Library.h> // Click here to get the library: http://librarymanager/All#SparkFun_MAX1704x_Fuel_Gauge_Arduino_Library
109+
SFE_MAX1704X lipo(MAX1704X_MAX17048);
110+
111+
// setting PWM properties
112+
const int freq = 5000;
113+
const int ledRedChannel = 0;
114+
const int ledGreenChannel = 1;
115+
const int resolution = 8;
116+
117+
int battLevel = 0; //SOC measured from fuel gauge, in %. Used in multiple places (display, serial debug, log)
118+
float battVoltage = 0.0;
119+
float battChangeRate = 0.0;
120+
121+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
122+
123+
124+
void setup()
125+
{
126+
Serial.begin(115200);
127+
delay(100);
128+
Serial.println("Testing tasks");
129+
130+
pinMode(bluetoothStatusLED, OUTPUT);
131+
132+
Wire.begin();
133+
//Wire.setClock(100000);
134+
135+
beginLEDs(); //LED and PWM setup
136+
137+
beginDisplay(); //Check if an external Qwiic OLED is attached
138+
139+
beginFuelGauge(); //Start I2C device
140+
141+
beginGNSS(); //Connect and configure ZED-F9P
142+
143+
bluetoothState = BT_ON_NOCONNECTION;
144+
145+
//Wire.setClock(400000); //The battery and ublox modules seem to dislike 400kHz
146+
147+
if (xI2CSemaphore == NULL)
148+
{
149+
xI2CSemaphore = xSemaphoreCreateMutex();
150+
if (xI2CSemaphore != NULL)
151+
xSemaphoreGive(xI2CSemaphore); //Make the I2C hardware available for use
152+
}
153+
154+
//Start tasks
155+
btLEDTask.attach(btLEDTaskPace, updateBTled); //Rate in seconds, callback
156+
battCheckTask.attach(battCheckTaskPace, checkBatteryLevels);
157+
checkUbloxTask.attach(checkUbloxTaskPace, checkUblox); //Call the checkUblox function
158+
159+
if (online.display == true)
160+
updateDisplayTask.attach(updateDisplayTaskPace, updateDisplay);
161+
162+
}
163+
164+
void loop() {
165+
166+
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
//Connect to and configure ZED-F9P
2+
void beginGNSS()
3+
{
4+
if (myGPS.begin() == false)
5+
{
6+
//Try again with power on delay
7+
delay(1000); //Wait for ZED-F9P to power up before it can respond to ACK
8+
if (myGPS.begin() == false)
9+
{
10+
Serial.println(F("u-blox GNSS not detected at default I2C address. Hard stop."));
11+
while(1);
12+
}
13+
}
14+
15+
//myGPS.enableDebugging();
16+
17+
bool response = true;
18+
19+
//response &= myGPS.setAutoPVT(true); //Tell the GPS to "send" each solution
20+
response &= myGPS.setAutoPVT(true, false); //Tell the GPS to "send" each solution, but do not update stale data when accessed
21+
response &= myGPS.setAutoHPPOSLLH(true, false); //Tell the GPS to "send" each high res solution, but do not update stale data when accessed
22+
//response &= myGPS.setAutoPVT(false); //Turn off PVT
23+
24+
if(response == false)
25+
{
26+
Serial.println("PVT failed!");
27+
while(1);
28+
}
29+
30+
Serial.println(F("GNSS configuration complete"));
31+
}
32+
33+
//Configure the on board MAX17048 fuel gauge
34+
void beginFuelGauge()
35+
{
36+
// Set up the MAX17048 LiPo fuel gauge
37+
if (lipo.begin() == false)
38+
{
39+
Serial.println(F("MAX17048 not detected. Continuing."));
40+
return;
41+
}
42+
43+
//Always use hibernate mode
44+
if (lipo.getHIBRTActThr() < 0xFF) lipo.setHIBRTActThr((uint8_t)0xFF);
45+
if (lipo.getHIBRTHibThr() < 0xFF) lipo.setHIBRTHibThr((uint8_t)0xFF);
46+
47+
Serial.println(F("MAX17048 configuration complete"));
48+
}
49+
50+
void beginDisplay()
51+
{
52+
//0x3D is default on Qwiic board
53+
if (isConnected(0x3D) == true || isConnected(0x3C) == true)
54+
{
55+
online.display = true;
56+
57+
//Init and display splash
58+
oled.begin(); // Initialize the OLED
59+
oled.clear(PAGE); // Clear the display's internal memory
60+
61+
oled.setCursor(10, 2); //x, y
62+
oled.setFontType(0); //Set font to smallest
63+
oled.print("SparkFun");
64+
65+
oled.setCursor(21, 13);
66+
oled.setFontType(1);
67+
oled.print("RTK");
68+
69+
int surveyorTextY = 25;
70+
int surveyorTextX = 2;
71+
int surveyorTextKerning = 8;
72+
oled.setFontType(1);
73+
74+
oled.setCursor(surveyorTextX, surveyorTextY);
75+
oled.print("S");
76+
77+
surveyorTextX += surveyorTextKerning;
78+
oled.setCursor(surveyorTextX, surveyorTextY);
79+
oled.print("u");
80+
81+
surveyorTextX += surveyorTextKerning;
82+
oled.setCursor(surveyorTextX, surveyorTextY);
83+
oled.print("r");
84+
85+
surveyorTextX += surveyorTextKerning;
86+
oled.setCursor(surveyorTextX, surveyorTextY);
87+
oled.print("v");
88+
89+
surveyorTextX += surveyorTextKerning;
90+
oled.setCursor(surveyorTextX, surveyorTextY);
91+
oled.print("e");
92+
93+
surveyorTextX += surveyorTextKerning;
94+
oled.setCursor(surveyorTextX, surveyorTextY);
95+
oled.print("y");
96+
97+
surveyorTextX += surveyorTextKerning;
98+
oled.setCursor(surveyorTextX, surveyorTextY);
99+
oled.print("o");
100+
101+
surveyorTextX += surveyorTextKerning;
102+
oled.setCursor(surveyorTextX, surveyorTextY);
103+
oled.print("r");
104+
105+
oled.setCursor(20, 41);
106+
oled.setFontType(0); //Set font to smallest
107+
oled.printf("v%d.%d", FIRMWARE_VERSION_MAJOR, FIRMWARE_VERSION_MINOR);
108+
oled.display();
109+
}
110+
}
111+
112+
//Set LEDs for output and configure PWM
113+
void beginLEDs()
114+
{
115+
pinMode(positionAccuracyLED_1cm, OUTPUT);
116+
pinMode(positionAccuracyLED_10cm, OUTPUT);
117+
pinMode(positionAccuracyLED_100cm, OUTPUT);
118+
pinMode(baseStatusLED, OUTPUT);
119+
pinMode(bluetoothStatusLED, OUTPUT);
120+
pinMode(baseSwitch, INPUT_PULLUP); //HIGH = rover, LOW = base
121+
122+
digitalWrite(positionAccuracyLED_1cm, LOW);
123+
digitalWrite(positionAccuracyLED_10cm, LOW);
124+
digitalWrite(positionAccuracyLED_100cm, LOW);
125+
digitalWrite(baseStatusLED, LOW);
126+
digitalWrite(bluetoothStatusLED, LOW);
127+
128+
ledcSetup(ledRedChannel, freq, resolution);
129+
ledcSetup(ledGreenChannel, freq, resolution);
130+
131+
ledcAttachPin(batteryLevelLED_Red, ledRedChannel);
132+
ledcAttachPin(batteryLevelLED_Green, ledGreenChannel);
133+
134+
ledcWrite(ledRedChannel, 0);
135+
ledcWrite(ledGreenChannel, 0);
136+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//Create a bitmap then use http://en.radzio.dxp.pl/bitmap_converter/ to generate output
2+
//Make sure the bitmap is n*8 pixels tall (pad white pixels to lower area as needed)
3+
//Otherwise the bitmap bitmap_converter will compress some of the bytes together
4+
5+
uint8_t BT_Symbol [] = {
6+
0x18, 0x30, 0xE0, 0xFF, 0xE6, 0x3C, 0x18, 0x06, 0x03, 0x01, 0x3F, 0x19, 0x0F, 0x06,
7+
};
8+
int BT_Symbol_Height = 14;
9+
int BT_Symbol_Width = 7;
10+
11+
uint8_t CrossHair [] = {
12+
0x80, 0x80, 0xF0, 0x88, 0x84, 0x84, 0x84, 0x7F, 0x84, 0x84, 0x84, 0x88, 0xF0, 0x80, 0x80, 0x00,
13+
0x00, 0x07, 0x08, 0x10, 0x10, 0x10, 0x7F, 0x10, 0x10, 0x10, 0x08, 0x07, 0x00, 0x00,
14+
};
15+
int CrossHair_Height = 15;
16+
int CrossHair_Width = 15;
17+
18+
uint8_t Antenna [] = {
19+
0x7E, 0xC3, 0x03, 0x06, 0x04, 0x0C, 0x18, 0x38, 0x7C, 0xCE, 0x84, 0x00, 0x00, 0x01, 0x1F, 0x1E,
20+
0x1C, 0x0C, 0x08, 0x08, 0x0C, 0x04, 0x07, 0x07,
21+
};
22+
int Antenna_Height = 13;
23+
int Antenna_Width = 12;
24+
25+
uint8_t Rover [] = {
26+
0x3C, 0x24, 0x64, 0xF4, 0xF7, 0x61, 0x21, 0x21, 0x21, 0x61, 0xF7, 0xF4, 0x64, 0x3C, 0x18,
27+
};
28+
int Rover_Height = 8;
29+
int Rover_Width = 15;
30+
31+
uint8_t Base [] = {
32+
0x00, 0xFF, 0x23, 0x13, 0x08, 0x88, 0x88, 0x88, 0x88, 0x08, 0x10, 0x20, 0xC0, 0x00, 0x0E, 0x09,
33+
0x08, 0x08, 0x08, 0x0F, 0x00, 0x00, 0x0F, 0x08, 0x08, 0x08, 0x09, 0x0E,
34+
};
35+
int Base_Height = 12;
36+
int Base_Width = 14;
37+
38+
uint8_t Battery_3 [] = {
39+
0xFF, 0x01, 0xFD, 0xFD, 0xFD, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0x01,
40+
0x0F, 0x08, 0xF8, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x08, 0x08, 0x0B, 0x0B, 0x0B, 0x08, 0x08, 0x0B,
41+
0x0B, 0x0B, 0x08, 0x0F, 0x01, 0x01,
42+
};
43+
int Battery_3_Height = 12;
44+
int Battery_3_Width = 19;
45+
46+
uint8_t Battery_2 [] = {
47+
0xFF, 0x01, 0xFD, 0xFD, 0xFD, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
48+
0x0F, 0x08, 0xF8, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x08, 0x08, 0x0B, 0x0B, 0x0B, 0x08, 0x08, 0x08,
49+
0x08, 0x08, 0x08, 0x0F, 0x01, 0x01,
50+
};
51+
int Battery_2_Height = 12;
52+
int Battery_2_Width = 19;
53+
54+
uint8_t Battery_1 [] = {
55+
0xFF, 0x01, 0xFD, 0xFD, 0xFD, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
56+
0x0F, 0x08, 0xF8, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
57+
0x08, 0x08, 0x08, 0x0F, 0x01, 0x01,
58+
};
59+
int Battery_1_Height = 12;
60+
int Battery_1_Width = 19;
61+
62+
uint8_t Battery_0 [] = {
63+
0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
64+
0x0F, 0x08, 0xF8, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
65+
0x08, 0x08, 0x08, 0x0F, 0x01, 0x01,
66+
};
67+
int Battery_0_Height = 12;
68+
int Battery_0_Width = 19;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//Bluetooth status LED goes from off (LED off), no connection (blinking), to connected (solid)
2+
enum BluetoothState
3+
{
4+
BT_OFF = 0,
5+
BT_ON_NOCONNECTION,
6+
BT_CONNECTED,
7+
};
8+
volatile byte bluetoothState = BT_OFF;
9+
10+
//These are the devices on board RTK Surveyor that may be on or offline.
11+
struct struct_online {
12+
bool microSD = false;
13+
bool display = false;
14+
bool dataLogging = false;
15+
bool serialOutput = false;
16+
bool eeprom = false;
17+
} online;

0 commit comments

Comments
 (0)