Skip to content

Commit eb57d4a

Browse files
authored
Early at power up warning, if battery voltage is low (#210)
Fixes #209
1 parent c07a5a7 commit eb57d4a

File tree

7 files changed

+100
-62
lines changed

7 files changed

+100
-62
lines changed

.idea/OpenBikeSensorFirmware.iml

Lines changed: 1 addition & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/OpenBikeSensorFirmware.cpp

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -138,24 +138,36 @@ void setup() {
138138
switch_wire_speed_to_SSD1306();
139139

140140
displayTest->showLogo(true);
141-
displayTest->showTextOnGrid(2, 0, OBSVersion,DEFAULT_FONT);
141+
displayTest->showTextOnGrid(2, displayTest->startLine(), OBSVersion);
142+
143+
voltageMeter = new VoltageMeter; // takes a moment, so do it here
144+
if (voltageMeter->hasReadings()) {
145+
displayTest->showTextOnGrid(2, displayTest->newLine(),
146+
"Battery: " + String(voltageMeter->read(), 1) + "V");
147+
delay(333); // Added for user experience
148+
}
149+
if (voltageMeter->isWarningLevel()) {
150+
displayTest->showTextOnGrid(2, displayTest->newLine(), "LOW BAT");
151+
displayTest->showTextOnGrid(2, displayTest->newLine(), "WARNING!");
152+
delay(5000);
153+
}
142154

143155
//##############################################################
144156
// Load, print and save config
145157
//##############################################################
146158

147-
displayTest->showTextOnGrid(2, 1, "Config... ",DEFAULT_FONT);
159+
displayTest->showTextOnGrid(2, displayTest->newLine(), "Config... ");
148160

149161
if (!SPIFFS.begin(true)) {
150162
Serial.println("An Error has occurred while mounting SPIFFS");
151-
displayTest->showTextOnGrid(2, 1, "Config... error ",DEFAULT_FONT);
163+
displayTest->showTextOnGrid(2, displayTest->currentLine(), "Config... error ");
152164
return;
153165
}
154166

155167
Serial.println(F("Load config"));
156168
ObsConfig cfg; // this one is valid in setup!
157169
if (!cfg.loadConfig()) {
158-
displayTest->showTextOnGrid(2, 1, "Config...RESET",DEFAULT_FONT);
170+
displayTest->showTextOnGrid(2, displayTest->currentLine(), "Config...RESET");
159171
delay(1000); // resetting config once, wait a moment
160172
}
161173

@@ -182,37 +194,32 @@ void setup() {
182194

183195
delay(333); // Added for user experience
184196
char buffer[32];
185-
snprintf(buffer, sizeof(buffer), "<%02d| |%02d>",
197+
snprintf(buffer, sizeof(buffer), "<%02d| - |%02d>",
186198
config.sensorOffsets[LEFT_SENSOR_ID],
187199
config.sensorOffsets[RIGHT_SENSOR_ID]);
188-
displayTest->showTextOnGrid(2, 1, buffer,DEFAULT_FONT);
200+
displayTest->showTextOnGrid(2, displayTest->currentLine(), buffer);
189201

190202
gps.begin();
191203

192204
//##############################################################
193205
// Handle SD
194206
//##############################################################
195-
// Counter, how often the SD card will be read before writing an error on the display
196-
int8_t sdCount = 5;
197-
198-
displayTest->showTextOnGrid(2, 2, "SD...",DEFAULT_FONT);
207+
int8_t sdCount = 0;
208+
displayTest->showTextOnGrid(2, displayTest->newLine(), "SD...");
199209
while (!SD.begin()) {
200-
if(sdCount > 0) {
201-
sdCount--;
202-
} else {
203-
displayTest->showTextOnGrid(2, 2, "SD... error",DEFAULT_FONT);
204-
if (config.simRaMode || digitalRead(PushButton_PIN) == HIGH) {
205-
break;
206-
} // FIXME: Stop trying!!?
210+
sdCount++;
211+
displayTest->showTextOnGrid(2,
212+
displayTest->currentLine(), "SD... error " + String(sdCount));
213+
if (config.simRaMode || digitalRead(PushButton_PIN) == HIGH || sdCount > 10) {
214+
break;
207215
}
208-
Serial.println("Card Mount Failed");
209-
//delay(100);
216+
delay(200);
210217
}
211-
delay(333); // Added for user experience
218+
212219
if (SD.begin()) {
213-
Serial.println("Card Mount Succeeded");
214-
displayTest->showTextOnGrid(2, 2, "SD... ok",DEFAULT_FONT);
220+
displayTest->showTextOnGrid(2, displayTest->currentLine(), "SD... ok");
215221
}
222+
delay(333); // Added for user experience
216223

217224
//##############################################################
218225
// Init HCSR04
@@ -243,7 +250,7 @@ void setup() {
243250

244251
buttonState = digitalRead(PushButton_PIN);
245252
if (buttonState == HIGH || (!config.simRaMode && displayError != 0)) {
246-
displayTest->showTextOnGrid(2, 2, "Start Server",DEFAULT_FONT);
253+
displayTest->showTextOnGrid(2, displayTest->newLine(), "Start Server");
247254
ESP_ERROR_CHECK_WITHOUT_ABORT(
248255
esp_bt_mem_release(ESP_BT_MODE_BTDM)); // no bluetooth at all here.
249256

@@ -264,29 +271,19 @@ void setup() {
264271
// Prepare CSV file
265272
//##############################################################
266273

267-
displayTest->showTextOnGrid(2, 3, "CSV file...",DEFAULT_FONT);
274+
displayTest->showTextOnGrid(2, displayTest->newLine(), "CSV file...");
268275

269276
const String trackUniqueIdentifier = ObsUtils::createTrackUuid();
270277

271278
if (SD.begin()) {
272279
writer = new CSVFileWriter;
273280
writer->setFileName();
274281
writer->writeHeader(trackUniqueIdentifier);
275-
displayTest->showTextOnGrid(2, 3, "CSV file... ok",DEFAULT_FONT);
276-
Serial.println("File initialised");
282+
displayTest->showTextOnGrid(2, displayTest->currentLine(), "CSV file... ok");
277283
} else {
278-
displayTest->showTextOnGrid(2, 3, "CSV. skipped",DEFAULT_FONT);
284+
displayTest->showTextOnGrid(2, displayTest->currentLine(), "CSV. skipped");
279285
}
280286

281-
//##############################################################
282-
// GPS
283-
//##############################################################
284-
285-
displayTest->showTextOnGrid(2, 4, "Wait for GPS",DEFAULT_FONT);
286-
gps.handle();
287-
voltageMeter = new VoltageMeter; // takes a moment, so do it here
288-
gps.handle();
289-
290287
//##############################################################
291288
// Temperatur Sensor BMP280
292289
//##############################################################
@@ -299,6 +296,7 @@ void setup() {
299296
// Bluetooth
300297
//##############################################################
301298
if (cfg.getProperty<bool>(ObsConfig::PROPERTY_BLUETOOTH)) {
299+
displayTest->showTextOnGrid(2, displayTest->newLine(), "Bluetooth ..");
302300
bluetoothManager = new BluetoothManager;
303301
bluetoothManager->init(
304302
cfg.getProperty<String>(ObsConfig::PROPERTY_OBS_NAME),
@@ -307,13 +305,15 @@ void setup() {
307305
batteryPercentage,
308306
trackUniqueIdentifier);
309307
bluetoothManager->activateBluetooth();
308+
displayTest->showTextOnGrid(2, displayTest->currentLine(), "Bluetooth up");
310309
} else {
311310
bluetoothManager = nullptr;
312311
ESP_ERROR_CHECK_WITHOUT_ABORT(
313312
esp_bt_mem_release(ESP_BT_MODE_BTDM)); // no bluetooth at all here.
314313
}
315314

316-
Serial.println("Waiting for GPS fix...");
315+
displayTest->showTextOnGrid(2, displayTest->newLine(), "Wait for GPS");
316+
displayTest->newLine();
317317
gps.handle();
318318
int gpsWaitFor = cfg.getProperty<int>(ObsConfig::PROPERTY_GPS_FIX);
319319
while (!gps.hasState(gpsWaitFor, displayTest)) {
@@ -329,10 +329,10 @@ void setup() {
329329

330330
buttonState = digitalRead(PushButton_PIN);
331331
if (buttonState == HIGH
332-
|| (config.simRaMode && !gps.moduleIsAlive()) // no module && simRaMode
333-
) {
332+
|| (config.simRaMode && !gps.moduleIsAlive()) // no module && simRaMode
333+
) {
334334
log_d("Skipped get GPS...");
335-
displayTest->showTextOnGrid(2, 5, "...skipped",DEFAULT_FONT);
335+
displayTest->showTextOnGrid(2, displayTest->currentLine(), "...skipped");
336336
break;
337337
}
338338
}
@@ -516,6 +516,14 @@ void loop() {
516516
memcpy(&(currentSet->startOffsetMilliseconds),
517517
&(sensorManager->startOffsetMilliseconds), currentSet->measurements * sizeof(uint16_t));
518518

519+
#ifdef DEVELOP
520+
Serial.write("min. distance: ");
521+
Serial.print(currentSet->sensorValues[confirmationSensorID]) ;
522+
Serial.write(" cm,");
523+
Serial.print(measurements);
524+
Serial.write(" measurements \n");
525+
#endif
526+
519527
// if nothing was detected, write the dataset to file, otherwise write it to the buffer for confirmation
520528
if (!transmitConfirmedData
521529
&& currentSet->sensorValues[confirmationSensorID] == MAX_SENSOR_VALUE
@@ -529,13 +537,6 @@ void loop() {
529537
dataBuffer.push(currentSet);
530538
}
531539

532-
#ifdef DEVELOP
533-
Serial.write("min. distance: ");
534-
Serial.print(currentSet->sensorValues[confirmationSensorID]) ;
535-
Serial.write(" cm,");
536-
Serial.print(measurements);
537-
Serial.write(" measurements \n");
538-
#endif
539540

540541
lastMeasurements = measurements;
541542

src/VoltageMeter.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ VoltageMeter::VoltageMeter() {
5757
#endif
5858
}
5959

60+
bool VoltageMeter::isWarningLevel() {
61+
return hasReadings() && (read() < VoltageMeter::BATTERY_WARNING_LEVEL);
62+
}
63+
64+
bool VoltageMeter::hasReadings() {
65+
return read() > VoltageMeter::BATTERY_NO_READ_LEVEL;
66+
}
67+
6068
double VoltageMeter::read() {
6169
return esp_adc_cal_raw_to_voltage(readSmoothed(), &adc_chars)
6270
* 3.0 / 2000.0; // voltage divider @ OSB PCB

src/VoltageMeter.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ class VoltageMeter {
1010
/* Returns the (smoothed) value in Volts. */
1111
double read();
1212
uint8_t readPercentage();
13+
bool hasReadings();
14+
bool isWarningLevel();
1315

1416
private:
1517
/* This one is typically NOT used, our ESP32 dos have
@@ -20,6 +22,12 @@ class VoltageMeter {
2022
// const uint8_t REFERENCE_PIN = 35;
2123
const int16_t MINIMUM_SAMPLES = 64;
2224
const int16_t SAMPLES_DIVIDE = 128;
25+
26+
/* Below this value a warning will be printed during startup. */
27+
const double BATTERY_WARNING_LEVEL = 3.47;
28+
/* Below this value it is assumed there is no voltage reading at all. */
29+
const double BATTERY_NO_READ_LEVEL = 3.00;
30+
2331
esp_adc_cal_characteristics_t adc_chars;
2432
int16_t lastSmoothedReading;
2533
int readSmoothed();

src/displays.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,26 @@ void SSD1306DisplayDevice::showSpeed(double velocity) {
211211
this->prepareTextOnGrid(0, 4, buffer, Dialog_plain_20);
212212
this->prepareTextOnGrid(1, 5, "km/h",DEFAULT_FONT);
213213
}
214+
215+
uint8_t SSD1306DisplayDevice::currentLine() const {
216+
return mCurrentLine;
217+
}
218+
219+
uint8_t SSD1306DisplayDevice::newLine() {
220+
if (mCurrentLine >= 5) {
221+
scrollUp();
222+
}
223+
return ++mCurrentLine;
224+
}
225+
226+
uint8_t SSD1306DisplayDevice::scrollUp() {
227+
for (uint8_t i = 0; i < 5; i++) {
228+
prepareTextOnGrid(2, i, displayTest->get_gridTextofCell(2, i + 1));
229+
}
230+
m_display->display();
231+
return mCurrentLine--;
232+
}
233+
234+
uint8_t SSD1306DisplayDevice::startLine() {
235+
return mCurrentLine = 0;
236+
}

src/displays.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class SSD1306DisplayDevice : public DisplayDevice {
5959
SSD1306* m_display;
6060
String gridText[ 4 ][ 6 ];
6161
uint8_t mLastProgress = 255;
62+
uint8_t mCurrentLine = 0;
6263

6364
public:
6465
SSD1306DisplayDevice() : DisplayDevice() {
@@ -73,6 +74,11 @@ class SSD1306DisplayDevice : public DisplayDevice {
7374
delete m_display;
7475
}
7576

77+
uint8_t currentLine() const;
78+
uint8_t newLine();
79+
uint8_t scrollUp();
80+
uint8_t startLine();
81+
7682
//##############################################################
7783
// Basic display configuration
7884
//##############################################################

src/gps.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -291,17 +291,14 @@ void Gps::showWaitStatus(SSD1306DisplayDevice *display) {
291291
if (gps.passedChecksum() != 0 //only do this if a communication is there and a valid time is there
292292
&& gps.time.isValid()
293293
&& !(gps.time.second() == 00 && gps.time.minute() == 00 && gps.time.hour() == 00)) {
294-
// This is a hack :) if still the version is displayed in the 1st line we scroll up
295-
if (displayTest->get_gridTextofCell(2, 0).startsWith("v")) {
296-
//This should implement scrolling and only scroll up on the first time, should be a display feature
297-
for (uint8_t i = 0; i < 4; i++) {
298-
displayTest->showTextOnGrid(2, i, displayTest->get_gridTextofCell(2, i + 1), DEFAULT_FONT);
299-
}
294+
// This is a hack :) if still the "Wait for GPS" version is displayed original line
295+
if (displayTest->get_gridTextofCell(2, 4).startsWith("Wait")) {
296+
display->newLine();
300297
}
301-
displayTest->showTextOnGrid(2, 4, satellitesString[0], DEFAULT_FONT);
302-
displayTest->showTextOnGrid(2, 5, satellitesString[1], DEFAULT_FONT);
298+
displayTest->showTextOnGrid(2, display->currentLine() - 1, satellitesString[0]);
299+
displayTest->showTextOnGrid(2, display->currentLine(), satellitesString[1]);
303300
} else { //if no gps comm or no time is there, just write in the last row
304-
displayTest->showTextOnGrid(2, 5, satellitesString[0]);
301+
displayTest->showTextOnGrid(2, display->currentLine(), satellitesString[0]);
305302
}
306303
}
307304

0 commit comments

Comments
 (0)