From 674cdb5c13bad3598381b81d843b5aeee5798d1f Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Fri, 20 Nov 2015 08:13:35 -0600 Subject: implement basic single survey mode - still needs sending data packet and data survey file --- Mode/ModeJoin.cpp | 51 ++++++---- Mode/ModeJoin.h | 2 + Mode/ModeSingle.cpp | 282 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Mode/ModeSingle.h | 55 ++++++++++ 4 files changed, 368 insertions(+), 22 deletions(-) create mode 100644 Mode/ModeSingle.cpp create mode 100644 Mode/ModeSingle.h (limited to 'Mode') diff --git a/Mode/ModeJoin.cpp b/Mode/ModeJoin.cpp index 5af4dcd..a39643f 100644 --- a/Mode/ModeJoin.cpp +++ b/Mode/ModeJoin.cpp @@ -17,42 +17,31 @@ ModeJoin::ModeJoin(DOGS102* lcd, ButtonHandler* buttons, mDot* dot, LoRaHandler* ModeJoin::~ModeJoin() {} bool ModeJoin::start() { + bool joining = false; + // clear any stale signals osSignalClear(_main_id, buttonSignal | loraSignal); _joined = false; - _index = 1; - _join.display(); - _join.updateStatus("Joining..."); - if (_dot->getJoinMode() == mDot::MANUAL) { - _join.updateId(mts::Text::bin2hexString(_dot->getNetworkId())); - _join.updateKey(mts::Text::bin2hexString(_dot->getNetworkKey())); - } else { - _join.updateId(_dot->getNetworkName()); - _join.updateKey(_dot->getNetworkPassphrase()); - } - if (_band == mDot::FB_915) { - _sub_band = _dot->getFrequencySubBand(); - _join.updateFsb(_sub_band); - } - // mDot::DataRateStr returns format SF_XX - we only want to display the XX part - _join.updateRate(_dot->DataRateStr(_data_rate).substr(3)); - _join.updatePower(_power); + display(); _lora->setDataRate(_data_rate); _lora->setPower(_power); + _lora->resetJoinAttempts(); while (! _joined) { _next_tx = _lora->getNextTx(); if (_next_tx) { + logInfo("next tx %lu ms", _next_tx); _join.updateCountdown(_next_tx / 1000); - } else { - _join.updateStatus("Joining..."); - if (_lora->join()) - _join.updateAttempt(_index++); + } else if (! joining) { + logInfo("attempting to join"); + joining = true; + display(); + _lora->join(); } - osEvent e = Thread::signal_wait(0, 500); + osEvent e = Thread::signal_wait(0, 250); if (e.status == osEventSignal) { if (e.value.signals & buttonSignal) { _be = _buttons->getButtonEvent(); @@ -78,6 +67,7 @@ bool ModeJoin::start() { case LoRaHandler::join_failure: logInfo("failed to join"); + joining = false; break; } } @@ -86,3 +76,20 @@ bool ModeJoin::start() { return false; } + +void ModeJoin::display() { + _join.display(); + _join.updateStatus("Joining..."); + if (_dot->getJoinMode() == mDot::MANUAL) { + _join.updateId(mts::Text::bin2hexString(_dot->getNetworkId())); + _join.updateKey(mts::Text::bin2hexString(_dot->getNetworkKey())); + } else { + _join.updateId(_dot->getNetworkName()); + _join.updateKey(_dot->getNetworkPassphrase()); + } + // mDot::DataRateStr returns format SF_XX - we only want to display the XX part + _join.updateRate(_dot->DataRateStr(_data_rate).substr(3)); + _join.updatePower(_power); + _join.updateAttempt(_lora->getJoinAttempts()); +} + diff --git a/Mode/ModeJoin.h b/Mode/ModeJoin.h index 6669ad4..6ab6622 100644 --- a/Mode/ModeJoin.h +++ b/Mode/ModeJoin.h @@ -14,6 +14,8 @@ class ModeJoin : public Mode { bool start(); private: + void display(); + LayoutJoin _join; mDot* _dot; LoRaHandler* _lora; diff --git a/Mode/ModeSingle.cpp b/Mode/ModeSingle.cpp new file mode 100644 index 0000000..f49f120 --- /dev/null +++ b/Mode/ModeSingle.cpp @@ -0,0 +1,282 @@ +#include "ModeSingle.h" +#include "MTSLog.h" + +ModeSingle::ModeSingle(DOGS102* lcd, ButtonHandler* buttons, mDot* dot, LoRaHandler* lora) + : Mode(lcd, buttons), + _help(lcd), + _file(lcd), + _confirm(lcd), + _progress(lcd), + _success(lcd), + _failure(lcd), + _dot(dot), + _data_rate(mDot::SF_7), + _power(2), + _lora(lora), + _send_data(false) +{} + +ModeSingle::~ModeSingle() {} + +bool ModeSingle::start() { + bool data_file = false; + bool send_ping = false; + bool send_data = false; + bool no_channel_ping = false; + bool no_channel_data = false; + LoRaHandler::LoRaPing ping_result; + + // clear any stale signals + osSignalClear(_main_id, buttonSignal | loraSignal); + + _band = _dot->getFrequencyBand(); + _sub_band = _dot->getFrequencySubBand(); + + // see if we're supposed to send the data packet after success + // that item is stored in the mDot::StartUpMode config field + _send_data = _dot->getStartUpMode(); + + // see if survey data file exists + std::vector files = _dot->listUserFiles(); + for (std::vector::iterator it = files.begin(); it != files.end(); it++) { + if (it->name == _file_name) { + logInfo("found survey data file"); + data_file = true; + break; + } + } + if (data_file) { + _state = check_file; + _file.display(); + } else { + _state = show_help; + _index = 0; + 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 check_file: + _state = show_help; + _index = 0; // need to get index from NVM + displayHelp(); + break; + case confirm: + _state = check_file; + _file.display(); + break; + case show_help: + incrementRatePower(); + _help.updateMsg(formatNewRatePower()); + break; + case in_progress: + // do nothing + break; + case success: + incrementRatePower(); + _success.updateInfo(formatNewRatePower()); + break; + case data: + break; + case failure: + incrementRatePower(); + _failure.updateInfo(formatNewRatePower()); + break; + } + break; + + case ButtonHandler::sw2_press: + switch (_state) { + case check_file: + _state = confirm; + _confirm.display(); + break; + case confirm: + _state = show_help; + _dot->deleteUserFile(_file_name); + _index = 0; + displayHelp(); + break; + case show_help: + _state = in_progress; + _progress.display(); + if (_lora->getNextTx() > 0) + no_channel_ping = true; + else + send_ping = true; + break; + case in_progress: + // do nothing + break; + case success: + _state = in_progress; + _progress.display(); + if (_lora->getNextTx() > 0) + no_channel_ping = true; + else + send_ping = true; + break; + case data: + break; + case failure: + _state = in_progress; + _progress.display(); + if (_lora->getNextTx() > 0) + no_channel_ping = true; + else + send_ping = true; + break; + } + break; + case ButtonHandler::sw1_hold: + return true; + } + } + if (e.value.signals & loraSignal) { + _ls = _lora->getStatus(); + switch (_ls) { + case LoRaHandler::ping_success: + switch (_state) { + case check_file: + break; + case confirm: + break; + case show_help: + break; + case in_progress: + _state = success; + ping_result = _lora->getPingResults(); + _success.display(); + _success.updateId(_index); + // mDot::DataRateStr returns format SF_XX - we only want to display the XX part + _success.updateRate(_dot->DataRateStr(_data_rate).substr(3)); + _success.updatePower(_power); + _success.updateStats(ping_result); + _success.updateInfo("No GPS Lock"); + _success.updateSw2("Survey"); + break; + case success: + break; + case data: + break; + case failure: + break; + } + break; + + case LoRaHandler::ping_failure: + switch (_state) { + case check_file: + break; + case confirm: + break; + case show_help: + break; + case in_progress: + _state = failure; + _failure.display(); + _failure.updateId(_index); + // mDot::DataRateStr returns format SF_XX - we only want to display the XX part + _success.updateRate(_dot->DataRateStr(_data_rate).substr(3)); + _failure.updatePower(_power); + break; + case success: + break; + case data: + break; + case failure: + break; + } + break; + } + } + } + + if (no_channel_ping) { + uint32_t t = _lora->getNextTx(); + if (t > 0) { + logInfo("next tx %lu ms", t); + _progress.updateCountdown(t / 1000); + } else { + logInfo("ready to transmit"); + _progress.display(); + logInfo("countdown removed"); + no_channel_ping = false; + send_ping = true; + } + } + if (no_channel_data) { + } + if (send_ping) { + logInfo("sending ping"); + send_ping = false; + _lora->setDataRate(_data_rate); + _lora->setPower(_power); + _lora->ping(); + _index++; + } + if (send_data) { + } + } +} + +void ModeSingle::displayHelp() { + _help.display(); + _help.updateMode("Survey Single"); + _help.updateSw1(" DR/PWR"); + _help.updateSw2("Survey"); +} + +std::string ModeSingle::formatNewRatePower() { + std::string msg; + char buf[8]; + size_t size; + + memset(buf, 0, sizeof(buf)); + msg += "New DR="; + msg += _dot->DataRateStr(_data_rate).substr(3); + msg += " P="; + size = snprintf(buf, sizeof(buf), "%u", _power); + msg.append(buf, size); + + return msg; +} + +void ModeSingle::incrementRatePower() { + if (_power == 20) { + _power = 2; + switch (_data_rate) { + case mDot::SF_7: + _data_rate = mDot::SF_8; + break; + case mDot::SF_8: + _data_rate = mDot::SF_9; + break; + case mDot::SF_9: + _data_rate = mDot::SF_10; + break; + case mDot::SF_10: + if (_band == mDot::FB_915) + _data_rate = mDot::SF_7; + else + _data_rate = mDot::SF_11; + break; + case mDot::SF_11: + _data_rate = mDot::SF_12; + break; + case mDot::SF_12: + _data_rate = mDot::SF_7; + break; + } + } else { + _power += 3; + } +} + diff --git a/Mode/ModeSingle.h b/Mode/ModeSingle.h new file mode 100644 index 0000000..976c8eb --- /dev/null +++ b/Mode/ModeSingle.h @@ -0,0 +1,55 @@ +#ifndef __MODESINGLE_H__ +#define __MODESINGLE_H__ + +#include "Mode.h" +#include "mDot.h" +#include "LoRaHandler.h" +#include "LayoutHelp.h" +#include "LayoutFile.h" +#include "LayoutConfirm.h" +#include "LayoutSurveyProgress.h" +#include "LayoutSurveySuccess.h" +#include "LayoutSurveyFailure.h" + +class ModeSingle : public Mode { + public: + ModeSingle(DOGS102* lcd, ButtonHandler* buttons, mDot* dot, LoRaHandler* lora); + ~ModeSingle(); + + bool start(); + + private: + void displayHelp(); + std::string formatNewRatePower(); + void incrementRatePower(); + + typedef enum { + check_file = 0, + confirm, + show_help, + in_progress, + success, + data, + failure + } state; + + LayoutHelp _help; + LayoutFile _file; + LayoutConfirm _confirm; + LayoutSurveyProgress _progress; + LayoutSurveySuccess _success; + LayoutSurveyFailure _failure; + mDot* _dot; + LoRaHandler* _lora; + uint8_t _band; + uint8_t _sub_band; + uint8_t _data_rate; + uint8_t _power; + uint32_t _next_tx; + ButtonHandler::ButtonEvent _be; + LoRaHandler::LoRaStatus _ls; + uint8_t _state; + bool _send_data; +}; + +#endif -- cgit v1.2.3