summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Layout/LayoutDemoSampling.cpp82
-rw-r--r--Layout/LayoutDemoSampling.h39
-rw-r--r--Mode/ModeDemo.cpp172
-rw-r--r--Mode/ModeDemo.h39
-rw-r--r--main.cpp38
5 files changed, 336 insertions, 34 deletions
diff --git a/Layout/LayoutDemoSampling.cpp b/Layout/LayoutDemoSampling.cpp
new file mode 100644
index 0000000..08d74ff
--- /dev/null
+++ b/Layout/LayoutDemoSampling.cpp
@@ -0,0 +1,82 @@
+#include "LayoutDemoSampling.h"
+
+LayoutDemoSampling::LayoutDemoSampling(DOGS102* lcd)
+ : Layout(lcd),
+ _lAccx(0, 0, "AccX"),
+ _lAccy(6, 0, "AccY"),
+ _lAccz(12, 0, "AccZ"),
+ _lPres(0, 2, "Press="),
+ _lAlt(0, 3, "Alt="),
+ _lTemp(0, 4, "Temp="),
+ _lLight(0, 5, "Light="),
+ _fAccx(0, 1, 5),
+ _fAccy(6, 1, 5),
+ _fAccz(12, 1, 5),
+ _fPres(6, 2, 11),
+ _fAlt(4, 3, 13),
+ _fTemp(5, 4, 12),
+ _fLight(6, 5, 11),
+ _fInfo(0, 6, 17),
+ _fSw1(9, 7, 8),
+ _fSw2(0, 7, 8)
+{}
+
+LayoutDemoSampling::~LayoutDemoSampling() {}
+
+void LayoutDemoSampling::display() {
+ clear();
+ startUpdate();
+
+ writeLabel(_lAccx);
+ writeLabel(_lAccy);
+ writeLabel(_lAccz);
+ writeLabel(_lPres);
+ writeLabel(_lAlt);
+ writeLabel(_lTemp);
+ writeLabel(_lLight);
+
+ endUpdate();
+}
+
+void LayoutDemoSampling::updateInfo(std::string info) {
+ writeField(_fInfo, info, true);
+}
+
+void LayoutDemoSampling::updateSw1(std::string sw1) {
+ writeField(_fSw1, sw1, true);
+}
+
+void LayoutDemoSampling::updateSw2(std::string sw2) {
+ writeField(_fSw2, sw2, true);
+}
+
+void LayoutDemoSampling::updateCountdown(uint32_t seconds) {
+ char buf[32];
+ size_t size;
+
+ memset(buf, 0, sizeof(buf));
+ // for some reason, there's a % character that gets displayed in the last column
+ // add the extra spaces to wipe it out
+ writeField(_fInfo, "No Free Channel ", true);
+ size = snprintf(buf, sizeof(buf), "%lu s", seconds);
+ writeField(_fSw2, buf, size, true);
+}
+
+void LayoutDemoSampling::updateInterval(uint32_t seconds) {
+ char buf[32];
+ size_t size;
+
+ memset(buf, ' ', sizeof(buf));
+ writeField(_fInfo, buf, size, true);
+
+ memset(buf, 0, sizeof(buf));
+ if (seconds < 60)
+ size = snprintf(buf, sizeof(buf), "Interval %lu s", seconds);
+ else if (seconds < 60 * 60)
+ size = snprintf(buf, sizeof(buf), "Interval %lu min", seconds / 60);
+ else
+ size = snprintf(buf, sizeof(buf), "Interval %lu hr", seconds / (60 * 60));
+
+ writeField(_fInfo, buf, size, true);
+}
+
diff --git a/Layout/LayoutDemoSampling.h b/Layout/LayoutDemoSampling.h
new file mode 100644
index 0000000..9d075b2
--- /dev/null
+++ b/Layout/LayoutDemoSampling.h
@@ -0,0 +1,39 @@
+#ifndef __LAYOUTDEMOSAMPLING_H__
+#define __LAYOUTDEMOSAMPLING_H__
+
+#include "Layout.h"
+
+class LayoutDemoSampling : public Layout {
+ public:
+ LayoutDemoSampling(DOGS102* lcd);
+ ~LayoutDemoSampling();
+
+ void display();
+ void updateInfo(std::string info);
+ void updateSw1(std::string sw1);
+ void updateSw2(std::string sw2);
+ void updateCountdown(uint32_t seconds);
+ void updateInterval(uint32_t seconds);
+
+ private:
+ Label _lAccx;
+ Label _lAccy;
+ Label _lAccz;
+ Label _lPres;
+ Label _lAlt;
+ Label _lTemp;
+ Label _lLight;
+
+ Field _fAccx;
+ Field _fAccy;
+ Field _fAccz;
+ Field _fPres;
+ Field _fAlt;
+ Field _fTemp;
+ Field _fLight;
+ Field _fInfo;
+ Field _fSw1;
+ Field _fSw2;
+};
+
+#endif
diff --git a/Mode/ModeDemo.cpp b/Mode/ModeDemo.cpp
new file mode 100644
index 0000000..80d202c
--- /dev/null
+++ b/Mode/ModeDemo.cpp
@@ -0,0 +1,172 @@
+#include "ModeDemo.h"
+#include "MTSLog.h"
+
+// 10 s, 30 s, 1 min, 5 min, 10 min, 15 min, 30 min 1 hour
+const uint32_t ModeDemo::_intervals[] = { 10, 30, 60, 5 * 60, 10 * 60, 15 * 60, 30 * 60, 60 * 60 };
+
+ModeDemo::ModeDemo(DOGS102* lcd, ButtonHandler* buttons, mDot* dot, LoRaHandler* lora, GPSPARSER* gps)
+ : Mode(lcd, buttons, dot, lora, gps),
+ _help(lcd),
+ _sam(lcd),
+ _interval(0)
+{}
+
+ModeDemo::~ModeDemo() {}
+
+bool ModeDemo::start() {
+ bool send = false;
+ bool no_channel = false;
+
+ // clear any stale signals
+ osSignalClear(_main_id, buttonSignal | loraSignal);
+
+ _state = show_help;
+ displayHelp();
+
+ while (true) {
+ osEvent e = Thread::signal_wait(0, 250);
+ if (e.status == osEventSignal) {
+ if (e.value.signals & buttonSignal) {
+ _be = _buttons->getButtonEvent();
+
+ switch (_be) {
+ case ButtonHandler::sw1_press:
+ switch (_state) {
+ case show_help:
+ _state = sampling;
+ _mode = trigger;
+ _sam.display();
+ _sam.updateSw2("Send");
+ break;
+ case sampling:
+ if (_mode == interval) {
+ _interval = (_interval + 1) % (sizeof(_intervals) / sizeof(uint32_t));
+ _sam.updateInterval(_intervals[_interval]);
+ }
+ break;
+ case success:
+ break;
+ case failure:
+ break;
+ }
+ break;
+
+ case ButtonHandler::sw2_press:
+ switch (_state) {
+ case show_help:
+ _state = sampling;
+ _mode = interval;
+ _send_timer.start();
+ _sam.display();
+ _sam.updateSw1("Interval");
+ _sam.updateInterval(_intervals[_interval]);
+ break;
+ case sampling:
+ if (_mode == trigger) {
+ if (_dot->getNextTxMs() > 0)
+ no_channel = true;
+ else
+ send = true;
+ }
+ break;
+ case success:
+ break;
+ case failure:
+ break;
+ }
+ break;
+ case ButtonHandler::sw1_hold:
+ _send_timer.stop();
+ _send_timer.reset();
+ return true;
+ }
+ }
+ if (e.value.signals & loraSignal) {
+ _ls = _lora->getStatus();
+ switch (_ls) {
+ case LoRaHandler::send_success:
+ switch (_state) {
+ case show_help:
+ break;
+ case sampling:
+ if (_mode == trigger) {
+ _sam.updateSw2("Send");
+ } else {
+ _sam.updateSw1("Interval");
+ _sam.updateInterval(_intervals[_interval]);
+ }
+ break;
+ case success:
+ break;
+ case failure:
+ break;
+ }
+ break;
+
+ case LoRaHandler::send_failure:
+ switch (_state) {
+ case show_help:
+ break;
+ case sampling:
+ if (_mode == trigger) {
+ _sam.updateSw2("Send");
+ } else {
+ _sam.updateSw1("Interval");
+ _sam.updateInterval(_intervals[_interval]);
+ }
+ break;
+ case success:
+ break;
+ case failure:
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ if (_send_timer.read_ms() > _intervals[_interval] * 1000) {
+ _send_timer.reset();
+ if (_dot->getNextTxMs() > 0)
+ no_channel = true;
+ else
+ send = true;
+ }
+ if (no_channel) {
+ uint32_t t = _dot->getNextTxMs();
+ if (t > 0) {
+ logInfo("next tx %lu ms", t);
+ _sam.updateCountdown(t / 1000);
+ } else {
+ no_channel = false;
+ send = true;
+ }
+ }
+ if (send) {
+ std::vector<uint8_t> s_data = formatSensorData(_data);
+ logInfo("sending data %s %d", _dot->DataRateStr(_data_rate).c_str(), _power);
+ _sam.updateInfo("Sending...");
+ _sam.updateSw1(" ");
+ _sam.updateSw2(" ");
+ send = false;
+ _dot->setTxDataRate(_data_rate);
+ _dot->setTxPower(_power);
+ // we don't care if the server actually gets this packet or not
+ // we won't retry anyway
+ _dot->setAck(0);
+ _dot->setTxWait(false);
+ _lora->send(s_data);
+ osDelay(500);
+ _sam.updateInfo(" ");
+ }
+ }
+}
+
+void ModeDemo::displayHelp() {
+ _help.display();
+ _help.updateMode("LoRa Demo");
+ _help.updateDescription("Select TX Method");
+ _help.updateSw1(" Trigger");
+ _help.updateSw2("Interval");
+}
+
diff --git a/Mode/ModeDemo.h b/Mode/ModeDemo.h
new file mode 100644
index 0000000..b2aaf21
--- /dev/null
+++ b/Mode/ModeDemo.h
@@ -0,0 +1,39 @@
+#ifndef __MODEDEMO_H__
+#define __MODEDEMO_H__
+
+#include "Mode.h"
+#include "LayoutHelp.h"
+#include "LayoutDemoSampling.h"
+
+class ModeDemo : public Mode {
+ public:
+ ModeDemo(DOGS102* lcd, ButtonHandler* buttons, mDot* dot, LoRaHandler* lora, GPSPARSER* gps);
+ ~ModeDemo();
+
+ bool start();
+
+ private:
+ void displayHelp();
+
+ typedef enum {
+ show_help = 0,
+ sampling,
+ success,
+ failure
+ } state;
+
+ typedef enum {
+ trigger = 0,
+ interval
+ } mode;
+
+ LayoutHelp _help;
+ LayoutDemoSampling _sam;
+ SensorItem _data;
+ mode _mode;
+ Timer _send_timer;
+ uint8_t _interval;
+ static const uint32_t _intervals[];
+};
+
+#endif
diff --git a/main.cpp b/main.cpp
index 9f42df3..5fbf58d 100644
--- a/main.cpp
+++ b/main.cpp
@@ -19,6 +19,7 @@
#include "ModeJoin.h"
#include "ModeSingle.h"
#include "ModeSweep.h"
+#include "ModeDemo.h"
#include "ModeConfig.h"
// misc heders
#include "FileName.h"
@@ -50,6 +51,7 @@ MTSSerial gps_serial(XBEE_DOUT, XBEE_DIN, 256, 2048);
ModeJoin* modeJoin;
ModeSingle* modeSingle;
ModeSweep* modeSweep;
+ModeDemo* modeDemo;
ModeConfig* modeConfig;
// Serial debug port
@@ -88,6 +90,7 @@ int main() {
modeJoin = new ModeJoin(lcd, buttons, dot, lora, gps);
modeSingle = new ModeSingle(lcd, buttons, dot, lora, gps);
modeSweep = new ModeSweep(lcd, buttons, dot, lora, gps);
+ modeDemo = new ModeDemo(lcd, buttons, dot, lora, gps);
modeConfig = new ModeConfig(lcd, buttons, dot, lora, gps);
logInfo("GPS %sdetected", gps->gpsDetected() ? "" : "not ");
@@ -157,7 +160,7 @@ void mainMenu() {
if (selected == menu_strings[demo]) {
if (modeJoin->start())
- loraDemo();
+ modeDemo->start();
} else if (selected == menu_strings[config]) {
modeConfig->start();
} else if (selected == menu_strings[single]) {
@@ -172,36 +175,3 @@ void mainMenu() {
}
}
-void loraDemo() {
- LayoutHelp lh(lcd);
- lh.display();
- lh.updateMode("LoRa Demo");
- lh.updateDescription("Select TX Method");
- lh.updateSw1(" Trigger");
- lh.updateSw2("Interval");
-
- // clear any stale signals
- osSignalClear(main_id, buttonSignal | loraSignal);
-
- logInfo("demo mode");
-
- while (true) {
- osEvent e = Thread::signal_wait(buttonSignal);
- if (e.status == osEventSignal) {
- ButtonHandler::ButtonEvent ev = buttons->getButtonEvent();
- switch (ev) {
- case ButtonHandler::sw1_press:
- logInfo("trigger TX mode");
- break;
- case ButtonHandler::sw2_press:
- logInfo("interval TX mode");
- break;
- case ButtonHandler::sw1_hold:
- return;
- default:
- break;
- }
- }
- }
-}
-