diff --git a/SatStat_HWLayer/SatStat_HWLayer.ino b/SatStat_HWLayer/SatStat_HWLayer.ino index df889ef..7d90214 100644 --- a/SatStat_HWLayer/SatStat_HWLayer.ino +++ b/SatStat_HWLayer/SatStat_HWLayer.ino @@ -1,96 +1,135 @@ #pragma once -#include "./handlers/Input_handler.h" -#include "./handlers/Output_handler.h" +#include "./handlers/Serial_handler.h" +#include "./other/Sensor_container.h" // Init input and output handler -Input_handler* input_handler; -Output_handler* output_handler; +Serial_handler* serial_handler; +Instruction_handler* instruction_handler; +Sensor_container* sensor_container; // Timing constrains unsigned long start_time = millis(); const int duration = 1000; -void setup() +void handshake() { - // Temp and hum sensor gnd and 5V - pinMode(7, OUTPUT); - digitalWrite(7, LOW); - pinMode(5, OUTPUT); - digitalWrite(5, HIGH); - - // Initialize the serial port - Serial.begin(9600); - - // Instantiate input and output handler - input_handler = new Input_handler(); - output_handler = new Output_handler(); - // Loop until handshake received - bool connection_established = false; - while (!connection_established) - { + while (true) + { // Send ack if approved, nack if not - if (input_handler->handshake_approved()) - { - output_handler->send_handshake_response(); - connection_established = true; - } - else + if (serial_handler->handshake_approved()) { - output_handler->send_nack(); + break; } - } + } +} +bool connection() +{ // Loop until connection request received - connection_established = false; - while (!connection_established) - { + unsigned long start_time = millis(); + unsigned long timeout = 10000; + + while (millis() - start_time < timeout) + { // Send nack if not approved - if (input_handler->connection_request_approved()) - { - connection_established = true; + if (serial_handler->connection_request_approved()) + { + return true; } - else + } + + return false; +} + +bool connection_init() +{ + // Init connection on new config + unsigned long start_time = millis(); + unsigned long timeout = 10000; + + while (millis() - start_time < timeout) + { + if (serial_handler->connection_init_approved()) { - output_handler->send_nack(); + return true; } - } + } - // Apply new config - input_handler->serial_init(); - output_handler->set_newline_format(input_handler->get_newline_format()); + return false; +} - - connection_established = false; - while (!connection_established) - { - output_handler->send_ack(); +bool provide_sensor_data() +{ + // Init connection on new config + unsigned long start_time = millis(); + unsigned long timeout = 10000; - if (input_handler->init_connection()) + while (millis() - start_time < timeout) + { + // Send nack if not approved + if (serial_handler->available_data_request_approved()) { - connection_established = true; + return true; } } + + return false; +} + +void setup() +{ + // Temp and hum sensor gnd and 5V + pinMode(7, OUTPUT); + digitalWrite(7, LOW); + pinMode(5, OUTPUT); + digitalWrite(5, HIGH); + + serial_handler = new Serial_handler(); + instruction_handler = new Instruction_handler(); + sensor_container = new Sensor_container(); + + Serial.begin(9600); + + while (true) + { + handshake(); + + if (connection()) + { + if (connection_init()) + { + if (provide_sensor_data()) + { + break; + } + } + } + serial_handler->send_nack(); + delay(30); + Serial.begin(9600); + } } void loop() { - input_handler->serial_listener(); + serial_handler->serial_listener(); - if (input_handler->instruction_available()) - { - output_handler->interpret_instruction(input_handler->get_instruction()); + if (!instruction_handler->queue_is_empty()) + { + instruction_handler->interpret_instruction(); } - - if (output_handler->get_auto_rotate_en()) + + if (instruction_handler->sadm_auto_rotate_en()) { - output_handler->auto_rotate_sadm(); + instruction_handler->sadm_auto_rotate(); } + // Runs with an interval equal to the duration if (!(millis() - start_time < duration)) { // Prints sensor data - output_handler->print_to_serial(input_handler->read_sensors()); + serial_handler->print_to_serial(sensor_container->read_sensors()); // Update start time to current time start_time = millis(); diff --git a/SatStat_HWLayer/SatStat_HWLayer.vcxproj b/SatStat_HWLayer/SatStat_HWLayer.vcxproj index a116f78..db7e2e6 100644 --- a/SatStat_HWLayer/SatStat_HWLayer.vcxproj +++ b/SatStat_HWLayer/SatStat_HWLayer.vcxproj @@ -112,9 +112,9 @@ - + - + @@ -204,20 +204,24 @@ + + - + - + + + @@ -226,7 +230,7 @@ - + \ No newline at end of file diff --git a/SatStat_HWLayer/SatStat_HWLayer.vcxproj.filters b/SatStat_HWLayer/SatStat_HWLayer.vcxproj.filters index c1e8b69..9026794 100644 --- a/SatStat_HWLayer/SatStat_HWLayer.vcxproj.filters +++ b/SatStat_HWLayer/SatStat_HWLayer.vcxproj.filters @@ -51,9 +51,6 @@ Header Files\handlers - - Header Files\handlers - Header Files\sensors @@ -324,26 +321,29 @@ Header Files\other - - Header Files\handlers - Header Files\other Header Files\other + + Header Files\handlers + + + Header Files\handlers + + + Header Files\other + + + Header Files\other + - - Source Files\handlers - Source Files\handlers - - Source Files\handlers - Source Files\sensors @@ -365,5 +365,17 @@ Source Files\other + + Source Files\handlers + + + Source Files\handlers + + + Source Files\other + + + Source Files\other + \ No newline at end of file diff --git a/SatStat_HWLayer/__vm/Compile.vmps.xml b/SatStat_HWLayer/__vm/Compile.vmps.xml index ef5c6bb..5c49ec6 100644 --- a/SatStat_HWLayer/__vm/Compile.vmps.xml +++ b/SatStat_HWLayer/__vm/Compile.vmps.xml @@ -2,7 +2,7 @@ - + diff --git a/SatStat_HWLayer/__vm/Configuration.Debug.vmps.xml b/SatStat_HWLayer/__vm/Configuration.Debug.vmps.xml index 499945b..a375aa5 100644 --- a/SatStat_HWLayer/__vm/Configuration.Debug.vmps.xml +++ b/SatStat_HWLayer/__vm/Configuration.Debug.vmps.xml @@ -2,7 +2,7 @@ - + diff --git a/SatStat_HWLayer/__vm/Upload.vmps.xml b/SatStat_HWLayer/__vm/Upload.vmps.xml index ef5c6bb..cd07317 100644 --- a/SatStat_HWLayer/__vm/Upload.vmps.xml +++ b/SatStat_HWLayer/__vm/Upload.vmps.xml @@ -2,7 +2,7 @@ - + diff --git a/SatStat_HWLayer/handlers/Input_handler.cpp b/SatStat_HWLayer/handlers/Input_handler.cpp deleted file mode 100644 index 9665108..0000000 --- a/SatStat_HWLayer/handlers/Input_handler.cpp +++ /dev/null @@ -1,247 +0,0 @@ -#pragma once -#include "Input_handler.h" - -// Instantiate sensors -Input_handler::Input_handler() -{ - sensor_collection.append("temp_hum", new Temp_hum_sensor("temp_hum", 6)); - newline_format = "\n"; -} - -// Delete every sensor in the sensor collection -Input_handler::~Input_handler() -{ - for (int i = 0; i < sensor_collection.count(); i++) - { - delete sensor_collection[i]; - } - - //delete handshake_response; -} - -// Reads serial until handshake received -// Returns false if what's received is not a propper handshake. -bool Input_handler::handshake_approved() -{ - Json_container* tmp; - - while (true) - { - serial_listener(); - - if (!json_handler.queue_is_empty()) - { - tmp = json_handler.fetch_instruction(); - - if (tmp->get()->containsKey("serial_handshake")) - { - if (tmp->get()->get("serial_handshake") == "init") - { - delete tmp; - return true; - } - } - - delete tmp; - return false; - } - } -} - -// Reads serial until connection request received -// Returns false if what's received is not a propper request. -bool Input_handler::connection_request_approved() -{ - Json_container* tmp; - JsonObject* nested_obj; - - while (true) - { - serial_listener(); - - if (!json_handler.queue_is_empty()) - { - tmp = json_handler.fetch_instruction(); - - if (tmp->get()->containsKey("connection_request")) - { - nested_obj = &tmp->get()->get("connection_request").asObject(); - - if (config_approved(nested_obj->get("baud_rate"), nested_obj->get("config"))) - { - newline_format = nested_obj->get("newline"); - - delete tmp; - return true; - } - } - - delete tmp; - return false; - } - } -} - -// Listens for serial input -void Input_handler::serial_listener() -{ - if (Serial.available() > 0) - { - String input = Serial.readStringUntil('\n'); - - if (input) - { - json_handler.insert_instruction(input); - } - } -} - -bool Input_handler::config_approved(const unsigned long & baud_rate, const String& config) -{ - int data_bits = config.charAt(0); - char parity = config.charAt(1); - int stop_bits = config.charAt(2); - - if (data_bits >= 53 && data_bits <= 56) - { - if (parity == 'N' || parity == 'O' || parity == 'E') - { - if (stop_bits == 49 || stop_bits == 50) - { - if (baud_rate == 9600 || baud_rate == 14400 || baud_rate == 19200 || baud_rate == 28800 || baud_rate == 38400 || baud_rate == 57600 || baud_rate == 115200) - { - this->config = config; - this->baud_rate = baud_rate; - - return true; - } - } - } - } - - return false; -} - -// Init serial with given config. -void Input_handler::serial_init() -{ - if (config == "5N1") { Serial.begin(baud_rate, SERIAL_5N1); } - else if (config == "6N1") { Serial.begin(baud_rate, SERIAL_6N1); } - else if (config == "7N1") { Serial.begin(baud_rate, SERIAL_7N1); } - else if (config == "8N1") { Serial.begin(baud_rate, SERIAL_8N1); } - else if (config == "5N2") { Serial.begin(baud_rate, SERIAL_5N2); } - else if (config == "6N2") { Serial.begin(baud_rate, SERIAL_6N2); } - else if (config == "7N2") { Serial.begin(baud_rate, SERIAL_7N2); } - else if (config == "8N2") { Serial.begin(baud_rate, SERIAL_8N2); } - else if (config == "5E1") { Serial.begin(baud_rate, SERIAL_5E1); } - else if (config == "6E1") { Serial.begin(baud_rate, SERIAL_6E1); } - else if (config == "7E1") { Serial.begin(baud_rate, SERIAL_7E1); } - else if (config == "8E1") { Serial.begin(baud_rate, SERIAL_8E1); } - else if (config == "5E2") { Serial.begin(baud_rate, SERIAL_5E2); } - else if (config == "6E2") { Serial.begin(baud_rate, SERIAL_6E2); } - else if (config == "7E2") { Serial.begin(baud_rate, SERIAL_7E2); } - else if (config == "8E2") { Serial.begin(baud_rate, SERIAL_8E2); } - else if (config == "5O1") { Serial.begin(baud_rate, SERIAL_5O1); } - else if (config == "6O1") { Serial.begin(baud_rate, SERIAL_6O1); } - else if (config == "7O1") { Serial.begin(baud_rate, SERIAL_7O1); } - else if (config == "8O1") { Serial.begin(baud_rate, SERIAL_8O1); } - else if (config == "5O2") { Serial.begin(baud_rate, SERIAL_5O2); } - else if (config == "6O2") { Serial.begin(baud_rate, SERIAL_6O2); } - else if (config == "7O2") { Serial.begin(baud_rate, SERIAL_7O2); } - else if (config == "8O2") { Serial.begin(baud_rate, SERIAL_8O2); } -} - -bool Input_handler::init_connection() -{ - Json_container* tmp; - unsigned long start_time = millis(); - unsigned long timeout = 10000; - - while (millis() - start_time < timeout) - { - serial_listener(); - - if (!json_handler.queue_is_empty()) - { - tmp = json_handler.fetch_instruction(); - - if (tmp->get()->containsKey("connect")) - { - - if (tmp->get()->get("connect") == "ok") - { - delete tmp; - return true; - } - } - - delete tmp; - return false; - } - } -} - -// Read given sensor -Json_container* Input_handler::read_sensor(const String& name) -{ - Sensor* sensor = sensor_collection.get(name); - const Result* result = sensor->read_sensor(); - const int count = sensor->get_data_count(); - Json_container* obj = json_handler.create_object(); - - for (int i = 0; i < count; i++) - { - json_handler.append_to(obj, result[i].name, result[i].data); - } - - return obj; -} - -// Reads all sensors -Json_container* Input_handler::read_sensors() -{ - Sensor* sensor; - int sensor_count = sensor_collection.count(); - const Result* result; - int result_count; - - Json_container* obj = json_handler.create_object(); - - for (int i = 0; i < sensor_count; i++) - { - sensor = sensor_collection[i]; - result = sensor->read_sensor(); - result_count = sensor->get_data_count(); - - for (int j = 0; j < result_count; j++) - { - json_handler.append_to(obj, result[j].name, result[j].data); - } - } - - return obj; - - return json_handler.create_object("test", 1); -} - -// Fetches instruction form instruction queue -Json_container* Input_handler::get_instruction() -{ - return json_handler.fetch_instruction(); -} - -// Returns a list of available sensors -LinkedList& Input_handler::get_sensor_collection() -{ - return sensor_collection; -} - -const String & Input_handler::get_newline_format() const -{ - return newline_format; -} - -bool Input_handler::instruction_available() const -{ - return !json_handler.queue_is_empty(); -} diff --git a/SatStat_HWLayer/handlers/Input_handler.h b/SatStat_HWLayer/handlers/Input_handler.h deleted file mode 100644 index ed3a559..0000000 --- a/SatStat_HWLayer/handlers/Input_handler.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once -#include "Arduino.h" -#include "Json_handler.h" -#include "../libraries/LinkedList.h" -#include "../sensors/Temp_hum_sensor.h" - -class Input_handler -{ -public: - // Constructor and destructor - Input_handler(); - ~Input_handler(); - - // Serial methods - bool handshake_approved(); - bool connection_request_approved(); - void serial_listener(); - void serial_init(); - bool init_connection(); - - // Sensor methods - Json_container* read_sensor(const String& name); - Json_container* read_sensors(); - - // Getters - Json_container* get_instruction(); - LinkedList& get_sensor_collection(); - const String& get_newline_format() const; - - bool instruction_available() const; - -private: - bool config_approved(const unsigned long& baud_rate, const String& config); - - Json_handler json_handler; - LinkedList sensor_collection; - - unsigned long baud_rate; - String config; - String newline_format; -}; diff --git a/SatStat_HWLayer/handlers/Instruction_handler.cpp b/SatStat_HWLayer/handlers/Instruction_handler.cpp new file mode 100644 index 0000000..207399f --- /dev/null +++ b/SatStat_HWLayer/handlers/Instruction_handler.cpp @@ -0,0 +1,68 @@ +#pragma once +#include "Instruction_handler.h" + +QueueArray*> Instruction_handler::instruction_queue; + +// Constructor +Instruction_handler::Instruction_handler() +{ + sadm_functions.init_stepper(); + instruction_interpreter.append("auto_rotate", SADM_functions::set_auto_rotate); + instruction_interpreter.append("rotate", SADM_functions::rotate); +} + +// Delete every JsonObject in the instruction queue +Instruction_handler::~Instruction_handler() +{ + Json_container* tmp; + while (!instruction_queue.isEmpty()) + { + tmp = instruction_queue.dequeue(); + delete tmp; + } +} + +// Insert instruction into instruction queue +void Instruction_handler::insert_instruction(const String& input_data) +{ + Json_container* obj = new Json_object_container(); + obj->parse(input_data); + instruction_queue.enqueue(obj); +} + +// Fetches an instruction from the instruction queue +Json_container* Instruction_handler::fetch_instruction() +{ + if (!instruction_queue.isEmpty()) + { + return instruction_queue.dequeue(); + } + + return nullptr; +} + +// Returns true if instruction queue is empty +bool Instruction_handler::queue_is_empty() const +{ + return instruction_queue.isEmpty(); +} + +bool Instruction_handler::sadm_auto_rotate_en() +{ + return sadm_functions.get_auto_rotate_en(); +} + +void Instruction_handler::sadm_auto_rotate() +{ + sadm_functions.auto_rotate(); +} + +void Instruction_handler::interpret_instruction() +{ + Json_container* obj = instruction_queue.dequeue(); + String instruction = obj->get()->get("instruction"); + void(*ptr)(Json_container*); + ptr = instruction_interpreter.get(instruction); + ptr(obj); + delete obj; +} \ No newline at end of file diff --git a/SatStat_HWLayer/handlers/Instruction_handler.h b/SatStat_HWLayer/handlers/Instruction_handler.h new file mode 100644 index 0000000..ae638ca --- /dev/null +++ b/SatStat_HWLayer/handlers/Instruction_handler.h @@ -0,0 +1,26 @@ +#pragma once +#include "Arduino.h" +#include "Json_handler.h" +#include "../libraries/QueueArray.h" +#include "../libraries/LinkedList.h" +#include "../other/SADM_functions.h" + +class Instruction_handler +{ +public: + Instruction_handler(); + ~Instruction_handler(); + + void insert_instruction(const String& input_data); + Json_container* fetch_instruction(); + bool queue_is_empty() const; + + bool sadm_auto_rotate_en(); + void sadm_auto_rotate(); + + void interpret_instruction(); +private: + SADM_functions sadm_functions; + static QueueArray*> instruction_queue; + LinkedList*)> instruction_interpreter; +}; \ No newline at end of file diff --git a/SatStat_HWLayer/handlers/Json_handler.cpp b/SatStat_HWLayer/handlers/Json_handler.cpp index cd451c7..162902c 100644 --- a/SatStat_HWLayer/handlers/Json_handler.cpp +++ b/SatStat_HWLayer/handlers/Json_handler.cpp @@ -1,47 +1,6 @@ #pragma once #include "Json_handler.h" -// Delete every JsonObject in the instruction queue -Json_handler::~Json_handler() -{ - Json_container* tmp; - while (!instruction_queue.isEmpty()) - { - tmp = instruction_queue.dequeue(); - delete tmp; - } -} - -// Insert instruction into instruction queue -void Json_handler::insert_instruction(const String& input_data) -{ - Json_container* obj = new Json_object_container(); - obj->parse(input_data); - - // For testing purposes - //obj->get()->printTo(Serial); - //while (!Serial.availableForWrite()); - - instruction_queue.enqueue(obj); -} - -// Fetches an instruction from the instruction queue -Json_container* Json_handler::fetch_instruction() -{ - if (!instruction_queue.isEmpty()) - { - return instruction_queue.dequeue(); - } - - return nullptr; -} - -// Returns true if instruction queue is empty -bool Json_handler::queue_is_empty() const -{ - return instruction_queue.isEmpty(); -} - // Creates a pointer to a Json_object_continer with no initial key-value pair Json_container* Json_handler::create_object() { diff --git a/SatStat_HWLayer/handlers/Json_handler.h b/SatStat_HWLayer/handlers/Json_handler.h index 4958c5e..f99186f 100644 --- a/SatStat_HWLayer/handlers/Json_handler.h +++ b/SatStat_HWLayer/handlers/Json_handler.h @@ -2,20 +2,10 @@ #include "Arduino.h" #include "../other/Json_object_container.h" #include "../other/Json_array_container.h" -#include "../libraries/QueueArray.h" -#include "../sensors/Result.h" class Json_handler { public: - // Destructor - ~Json_handler(); - - // Instruction queue methods - void insert_instruction(const String& input_data); - Json_container* fetch_instruction(); - bool queue_is_empty() const; - // Create object and array methods Json_container* create_object(); Json_container* create_array(); @@ -24,15 +14,12 @@ class Json_handler // Append to object and append to array methods template void append_to(Json_container* obj, const String& key, const T& value); - template void append_to(Json_container* arr, const String& key, const T& value); - -private: - QueueArray*> instruction_queue; + template void append_to(Json_container* arr, const String& key, const T& value); }; // Creates a pointer to a Json_object_container with predefined key and value template -Json_container* Json_handler::create_object(const String& key, const T& value) +inline Json_container* Json_handler::create_object(const String& key, const T& value) { Json_container* obj = new Json_object_container(); obj->get()->set(key, value); @@ -42,7 +29,7 @@ Json_container* Json_handler::create_object(const String& key, const // Creates a pointer to a Json_array_container with predefined key and value template -Json_container* Json_handler::create_array(const T* value, const int& data_count) +inline Json_container* Json_handler::create_array(const T* value, const int& data_count) { Json_container* arr = new Json_array_container(); @@ -56,14 +43,14 @@ Json_container* Json_handler::create_array(const T* value, const int& // Appends a key-value pair to an existing object template -void Json_handler::append_to(Json_container* obj, const String& key, const T& value) +inline void Json_handler::append_to(Json_container* obj, const String& key, const T& value) { obj->get()->set(key, value); } // Appends a key-value pair to an existing array template -void Json_handler::append_to(Json_container* arr, const String& key, const T& value) +inline void Json_handler::append_to(Json_container* arr, const String& key, const T& value) { arr->get()->set(key, value); } \ No newline at end of file diff --git a/SatStat_HWLayer/handlers/Output_handler.cpp b/SatStat_HWLayer/handlers/Output_handler.cpp deleted file mode 100644 index c08726c..0000000 --- a/SatStat_HWLayer/handlers/Output_handler.cpp +++ /dev/null @@ -1,201 +0,0 @@ -#pragma once -#include "Output_handler.h" - -// Constructor -Output_handler::Output_handler() -{ - stepper = new Stepper(stepsPerRev, 8, 10, 9, 11); - steps = 0; - dir = false; - auto_rotate_en = false; - stepper->setSpeed(700); - newline_format = "\r\n"; - instruction_interpreter.append("auto_rotate", &Output_handler::set_auto_rotate); - instruction_interpreter.append("rotate", &Output_handler::rotate_sadm); -} - -void Output_handler::send_handshake_response() -{ - Json_container* handshake_response = json_handler.create_object(); - JsonObject& serial_handshake = handshake_response->get()->createNestedObject("serial_handshake"); - JsonArray& baud_rates = serial_handshake.createNestedArray("baud_rates"); - JsonArray& configs = serial_handshake.createNestedArray("configs"); - JsonArray& newlines = serial_handshake.createNestedArray("newlines"); - - for (unsigned long i = 9600; i <= 38400; i *= 2) - { - baud_rates.add(i); - } - - - for (unsigned long i = 14400; i <= 115200; i *= 2) - { - baud_rates.add(i); - } - - String tmp; - - for (int i = 5; i <= 8; i++) - { - for (int j = 0; j < 3; j++) - { - for (int k = 1; k <= 2; k++) - { - tmp = String(i); - - switch (j) - { - case 0: - tmp += 'N'; - break; - case 1: - tmp += 'O'; - break; - case 2: - tmp += 'E'; - break; - default: - break; - } - - tmp += String(k); - - configs.add(tmp); - } - } - } - - newlines.add("\r\n"); - newlines.add("\n"); - - handshake_response->get()->printTo(Serial); - Serial.print(newline_format); - - delete handshake_response; -} - -//Sends ack to software layer -void Output_handler::send_sensor_collection(LinkedList& sensor_collection) -{ - Json_container* ack = json_handler.create_object("serial_handshake", "ok"); - JsonArray& available_data = ack->get()->createNestedArray("available_data"); - - for (int i = 0; i < sensor_collection.count(); i++) - { - Sensor* sensor = sensor_collection[i]; - for (int i = 0; i < sensor->get_data_count(); i++) - { - available_data.add(*json_handler.create_object(sensor->read_sensor()[i].name, "int")->get()); - } - } - - ack->get()->printTo(Serial); - Serial.print(newline_format); - - delete ack; -} - -void Output_handler::send_ack() -{ - Json_container* ack = json_handler.create_object("connect", "init"); - - ack->get()->printTo(Serial); - Serial.print(newline_format); - - delete ack; -} - -void Output_handler::send_nack() -{ - Json_container* nack = json_handler.create_object("serial_handshake", "failed"); - - nack->get()->printTo(Serial); - Serial.print(newline_format); - - delete nack; -} - -void Output_handler::set_newline_format(const String & newline_format) -{ - this->newline_format = newline_format; -} - -void Output_handler::print_to_serial(Json_container* json) -{ - json->get()->printTo(Serial); - Serial.print(newline_format); - - delete json; -} - -void Output_handler::set_auto_rotate(Json_container* instruction) -{ - auto_rotate_en = instruction->get()->get("enable"); -} - -/* - Automatically rotates the SADM. - Must be continuously called. -*/ -void Output_handler::auto_rotate_sadm() -{ - if (steps < step_limit) - { - steps++; - } - else - { - dir = !dir; - steps = 0; - } - - if (!dir) - { - stepper->step(1); - } - else - { - stepper->step(-1); - } -} - -void Output_handler::rotate_sadm(Json_container* instruction) -{ - if (instruction->get()->containsKey("deg")) - { - float deg = instruction->get()->get("deg"); - rotate_sadm(deg); - } - else if (instruction->get()->containsKey("steps")) - { - int steps = instruction->get()->get("steps"); - rotate_sadm(steps); - } -} - -// Rotates the SADM the passed number of steps -void Output_handler::rotate_sadm(int steps) -{ - stepper->step(steps); -} - -// Converts from degrees to steps, and rotates the SADM -void Output_handler::rotate_sadm(float degrees) -{ - // 1 deg = 2048steps/360deg = 5.69 step/deg - stepper->step((int)(degrees * ((float)2048 / (float)360))); -} - -void Output_handler::interpret_instruction(Json_container* obj) -{ - String instruction = obj->get()->get("instruction"); - void(Output_handler::*ptr)(Json_container*); - ptr = instruction_interpreter.get(instruction); - (*this.*ptr)(obj); - delete obj; -} - -bool Output_handler::get_auto_rotate_en() const -{ - return auto_rotate_en; -} diff --git a/SatStat_HWLayer/handlers/Output_handler.h b/SatStat_HWLayer/handlers/Output_handler.h deleted file mode 100644 index 7873963..0000000 --- a/SatStat_HWLayer/handlers/Output_handler.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once -#include "Arduino.h" -#include "Json_handler.h" -#include "../libraries/Stepper.h" -#include "../libraries/DS1302.h" -#include "../libraries/LinkedList.h" -#include "../sensors/Sensor.h" -#include "../other/Json_object_container.h" -#include "../other/Json_array_container.h" - -class Output_handler -{ -public: - Output_handler(); - - void send_handshake_response(); - void send_sensor_collection(LinkedList& sensor_collection); - void send_ack(); - void send_nack(); - - void set_newline_format(const String& newline_format); - - void print_to_serial(Json_container* json); - - void set_auto_rotate(Json_container* instruction); - void auto_rotate_sadm(); - void rotate_sadm(Json_container* instruction); - void rotate_sadm(int steps); - void rotate_sadm(float degrees); - - void interpret_instruction(Json_container* obj); - - bool get_auto_rotate_en() const; - -private: - Json_handler json_handler; - Stepper* stepper; - int steps; - bool dir; - bool auto_rotate_en; - const int stepsPerRev = 32; - const float factor = 3.25; - const int step_limit = (int)(1024 * factor); - - String newline_format; - - LinkedList*)> instruction_interpreter; -}; - diff --git a/SatStat_HWLayer/handlers/Serial_handler.cpp b/SatStat_HWLayer/handlers/Serial_handler.cpp new file mode 100644 index 0000000..3e46779 --- /dev/null +++ b/SatStat_HWLayer/handlers/Serial_handler.cpp @@ -0,0 +1,324 @@ +#pragma once +#include "Serial_handler.h" + +Serial_handler::Serial_handler() +{ + instruction_handler = new Instruction_handler(); + baud_rate = 9600; + config = "8N1"; + newline_format = "\r\n"; +} + +// Init serial with given config. +void Serial_handler::serial_init() +{ + if (config == "5N1") { Serial.begin(baud_rate, SERIAL_5N1); } + else if (config == "6N1") { Serial.begin(baud_rate, SERIAL_6N1); } + else if (config == "7N1") { Serial.begin(baud_rate, SERIAL_7N1); } + else if (config == "8N1") { Serial.begin(baud_rate, SERIAL_8N1); } + else if (config == "5N2") { Serial.begin(baud_rate, SERIAL_5N2); } + else if (config == "6N2") { Serial.begin(baud_rate, SERIAL_6N2); } + else if (config == "7N2") { Serial.begin(baud_rate, SERIAL_7N2); } + else if (config == "8N2") { Serial.begin(baud_rate, SERIAL_8N2); } + else if (config == "5E1") { Serial.begin(baud_rate, SERIAL_5E1); } + else if (config == "6E1") { Serial.begin(baud_rate, SERIAL_6E1); } + else if (config == "7E1") { Serial.begin(baud_rate, SERIAL_7E1); } + else if (config == "8E1") { Serial.begin(baud_rate, SERIAL_8E1); } + else if (config == "5E2") { Serial.begin(baud_rate, SERIAL_5E2); } + else if (config == "6E2") { Serial.begin(baud_rate, SERIAL_6E2); } + else if (config == "7E2") { Serial.begin(baud_rate, SERIAL_7E2); } + else if (config == "8E2") { Serial.begin(baud_rate, SERIAL_8E2); } + else if (config == "5O1") { Serial.begin(baud_rate, SERIAL_5O1); } + else if (config == "6O1") { Serial.begin(baud_rate, SERIAL_6O1); } + else if (config == "7O1") { Serial.begin(baud_rate, SERIAL_7O1); } + else if (config == "8O1") { Serial.begin(baud_rate, SERIAL_8O1); } + else if (config == "5O2") { Serial.begin(baud_rate, SERIAL_5O2); } + else if (config == "6O2") { Serial.begin(baud_rate, SERIAL_6O2); } + else if (config == "7O2") { Serial.begin(baud_rate, SERIAL_7O2); } + else if (config == "8O2") { Serial.begin(baud_rate, SERIAL_8O2); } +} + +// Listens for serial input +void Serial_handler::serial_listener() +{ + if (Serial.available() > 0) + { + String input = Serial.readStringUntil('\n'); + + if (input) + { + instruction_handler->insert_instruction(input); + } + } +} + +// Reads serial until handshake received +// Returns false if what's received is not a propper handshake. +bool Serial_handler::handshake_approved() +{ + Json_container* tmp; + + unsigned long start_time = millis(); + unsigned long timeout = 2000; + + while (millis() - start_time < timeout) + { + serial_listener(); + + if (!instruction_handler->queue_is_empty()) + { + tmp = instruction_handler->fetch_instruction(); + + if (tmp->get()->containsKey("serial_handshake")) + { + if (tmp->get()->get("serial_handshake") == "init") + { + send_handshake_response(); + delete tmp; + return true; + } + } + send_nack(); + delete tmp; + } + } + + return false; +} + +// Reads serial until connection request received +// Returns false if what's received is not a propper request. +bool Serial_handler::connection_request_approved() +{ + Json_container* tmp; + JsonObject* nested_obj; + + unsigned long start_time = millis(); + unsigned long timeout = 2000; + + while (millis() - start_time < timeout) + { + serial_listener(); + + if (!instruction_handler->queue_is_empty()) + { + tmp = instruction_handler->fetch_instruction(); + + if (tmp->get()->containsKey("connection_request")) + { + nested_obj = &tmp->get()->get("connection_request").asObject(); + + if (config_approved(nested_obj->get("baud_rate"), nested_obj->get("config"))) + { + newline_format = nested_obj->get("newline"); + + serial_init(); + delete tmp; + return true; + } + } + send_nack(); + delete tmp; + } + } + + return false; +} + +bool Serial_handler::connection_init_approved() +{ + Json_container* tmp; + unsigned long start_time = millis(); + unsigned long timeout = 2000; + + send_ack(); + + while (millis() - start_time < timeout) + { + serial_listener(); + + if (!instruction_handler->queue_is_empty()) + { + tmp = instruction_handler->fetch_instruction(); + + if (tmp->get()->containsKey("connect")) + { + + if (tmp->get()->get("connect") == "ok") + { + delete tmp; + return true; + } + } + delete tmp; + } + } + return false; +} + +bool Serial_handler::available_data_request_approved() +{ + Json_container* tmp; + unsigned long start_time = millis(); + unsigned long timeout = 2000; + + while (millis() - start_time < timeout) + { + serial_listener(); + + if (!instruction_handler->queue_is_empty()) + { + tmp = instruction_handler->fetch_instruction(); + + if (tmp->get()->containsKey("request")) + { + + if (tmp->get()->get("request") == "available_data") + { + send_sensor_collection(sensor_container.get_available_sensors()); + delete tmp; + return true; + } + } + send_nack(); + delete tmp; + } + } + + return false; +} + +bool Serial_handler::config_approved(const unsigned long & baud_rate, const String& config) +{ + int data_bits = config.charAt(0); + char parity = config.charAt(1); + int stop_bits = config.charAt(2); + + if (data_bits >= 53 && data_bits <= 56) + { + if (parity == 'N' || parity == 'O' || parity == 'E') + { + if (stop_bits == 49 || stop_bits == 50) + { + if (baud_rate == 9600 || baud_rate == 14400 || baud_rate == 19200 || baud_rate == 28800 || baud_rate == 38400 || baud_rate == 57600 || baud_rate == 115200) + { + this->config = config; + this->baud_rate = baud_rate; + + return true; + } + } + } + } + + return false; +} + +void Serial_handler::send_handshake_response() +{ + Json_container* handshake_response = json_handler.create_object(); + JsonObject& serial_handshake = handshake_response->get()->createNestedObject("serial_handshake"); + JsonArray& baud_rates = serial_handshake.createNestedArray("baud_rates"); + JsonArray& configs = serial_handshake.createNestedArray("configs"); + JsonArray& newlines = serial_handshake.createNestedArray("newlines"); + + for (unsigned long i = 9600; i <= 38400; i *= 2) + { + baud_rates.add(i); + } + + + for (unsigned long i = 14400; i <= 115200; i *= 2) + { + baud_rates.add(i); + } + + String tmp; + + for (int i = 5; i <= 8; i++) + { + for (int j = 0; j < 3; j++) + { + for (int k = 1; k <= 2; k++) + { + tmp = String(i); + + switch (j) + { + case 0: + tmp += 'N'; + break; + case 1: + tmp += 'O'; + break; + case 2: + tmp += 'E'; + break; + default: + break; + } + + tmp += String(k); + + configs.add(tmp); + } + } + } + + newlines.add("\r\n"); + newlines.add("\n"); + + handshake_response->get()->printTo(Serial); + Serial.print(newline_format); + + delete handshake_response; +} + +//Sends ack to software layer +void Serial_handler::send_sensor_collection(LinkedList& sensor_collection) +{ + Json_container* ack = json_handler.create_object("serial_handshake", "ok"); + JsonArray& available_data = ack->get()->createNestedArray("available_data"); + + for (int i = 0; i < sensor_collection.count(); i++) + { + Sensor* sensor = sensor_collection[i]; + for (int i = 0; i < sensor->get_data_count(); i++) + { + available_data.add(*json_handler.create_object(sensor->read_sensor()[i].name, "int")->get()); + } + } + + ack->get()->printTo(Serial); + Serial.print(newline_format); + + delete ack; +} + +void Serial_handler::send_ack() +{ + Json_container* ack = json_handler.create_object("connect", "init"); + + ack->get()->printTo(Serial); + Serial.print(newline_format); + + delete ack; +} + +void Serial_handler::send_nack() +{ + Json_container* nack = json_handler.create_object("serial_handshake", "failed"); + + nack->get()->printTo(Serial); + Serial.print(newline_format); + + delete nack; +} + +void Serial_handler::print_to_serial(Json_container* json) +{ + json->get()->printTo(Serial); + Serial.print(newline_format); + + delete json; +} diff --git a/SatStat_HWLayer/handlers/Serial_handler.h b/SatStat_HWLayer/handlers/Serial_handler.h new file mode 100644 index 0000000..acf681f --- /dev/null +++ b/SatStat_HWLayer/handlers/Serial_handler.h @@ -0,0 +1,37 @@ +#pragma once +#include "Arduino.h" +#include "Instruction_handler.h" +#include "../other/Sensor_container.h" + +class Serial_handler +{ +public: + // Constructor + Serial_handler(); + + // Init methods + void serial_init(); + void serial_listener(); + bool handshake_approved(); + bool connection_request_approved(); + bool connection_init_approved(); + bool available_data_request_approved(); + + void send_handshake_response(); + void send_sensor_collection(LinkedList& sensor_collection); + void send_ack(); + void send_nack(); + + void print_to_serial(Json_container* json); + +private: + bool config_approved(const unsigned long& baud_rate, const String& config); + + unsigned long baud_rate; + String config; + String newline_format; + + Sensor_container sensor_container; + Json_handler json_handler; + Instruction_handler* instruction_handler; +}; \ No newline at end of file diff --git a/SatStat_HWLayer/other/Function_pointer_container.h b/SatStat_HWLayer/other/Function_pointer_container.h deleted file mode 100644 index b17b6ac..0000000 --- a/SatStat_HWLayer/other/Function_pointer_container.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -class Function_pointer_container -{ -public: - template struct Gfp; -}; - -template -struct Function_pointer_container::Gfp -{ - R(*func)(P...); -}; - -template -struct Function_pointer_container::Gfp -{ - R(*func)(void); -}; \ No newline at end of file diff --git a/SatStat_HWLayer/other/Json_array_container.cpp b/SatStat_HWLayer/other/Json_array_container.cpp index 392b4e1..b57ec23 100644 --- a/SatStat_HWLayer/other/Json_array_container.cpp +++ b/SatStat_HWLayer/other/Json_array_container.cpp @@ -8,20 +8,15 @@ Json_array_container::Json_array_container() : Json_container() void Json_array_container::create() { delete Json_container::buffer; - Json_container::buffer = new DynamicJsonBuffer; + Json_container::buffer = new DynamicJsonBuffer(); Json_container::json = &Json_container::buffer->createArray(); } -void Json_array_container::parse(const String & json) +void Json_array_container::parse(const String& json) { delete Json_container::buffer; - Json_container::buffer = new DynamicJsonBuffer; + Json_container::buffer = new DynamicJsonBuffer(); Json_container::json = &Json_container::buffer->parseArray(json); } - -JsonArray* Json_array_container::get() -{ - return Json_container::json; -} diff --git a/SatStat_HWLayer/other/Json_array_container.h b/SatStat_HWLayer/other/Json_array_container.h index 4101927..af38371 100644 --- a/SatStat_HWLayer/other/Json_array_container.h +++ b/SatStat_HWLayer/other/Json_array_container.h @@ -9,5 +9,4 @@ class Json_array_container : public Json_container void create(); void parse(const String &json); - JsonArray* get(); }; \ No newline at end of file diff --git a/SatStat_HWLayer/other/Json_container.h b/SatStat_HWLayer/other/Json_container.h index e6afc93..ad98d3a 100644 --- a/SatStat_HWLayer/other/Json_container.h +++ b/SatStat_HWLayer/other/Json_container.h @@ -11,7 +11,7 @@ class Json_container virtual void create() = 0; virtual void parse(const String &json) = 0; - virtual T* get() = 0; + T* get(); protected: DynamicJsonBuffer* buffer; @@ -19,13 +19,19 @@ class Json_container }; template -Json_container::Json_container() +inline Json_container::Json_container() { buffer = new DynamicJsonBuffer; } template -Json_container::~Json_container() +inline Json_container::~Json_container() { delete buffer; -} \ No newline at end of file +} + +template +inline T* Json_container::get() +{ + return json; +} diff --git a/SatStat_HWLayer/other/Json_object_container.cpp b/SatStat_HWLayer/other/Json_object_container.cpp index ce88928..3be6f1b 100644 --- a/SatStat_HWLayer/other/Json_object_container.cpp +++ b/SatStat_HWLayer/other/Json_object_container.cpp @@ -13,15 +13,10 @@ void Json_object_container::create() Json_container::json = &Json_container::buffer->createObject(); } -void Json_object_container::parse(const String &json) +void Json_object_container::parse(const String& json) { delete Json_container::buffer; Json_container::buffer = new DynamicJsonBuffer(); Json_container::json = &Json_container::buffer->parseObject(json); } - -JsonObject* Json_object_container::get() -{ - return Json_container::json; -} diff --git a/SatStat_HWLayer/other/Json_object_container.h b/SatStat_HWLayer/other/Json_object_container.h index 1c2d3ec..204dc31 100644 --- a/SatStat_HWLayer/other/Json_object_container.h +++ b/SatStat_HWLayer/other/Json_object_container.h @@ -9,5 +9,4 @@ class Json_object_container : public Json_container void create(); void parse(const String &json); - JsonObject* get(); }; \ No newline at end of file diff --git a/SatStat_HWLayer/other/SADM_functions.cpp b/SatStat_HWLayer/other/SADM_functions.cpp new file mode 100644 index 0000000..a53c043 --- /dev/null +++ b/SatStat_HWLayer/other/SADM_functions.cpp @@ -0,0 +1,77 @@ +#include "SADM_functions.h" + +int SADM_functions::steps = 0; +bool SADM_functions::dir = false; +bool SADM_functions::auto_rotate_en = false; +const int SADM_functions::stepsPerRev = 32; +const float SADM_functions::factor = 3.25; +const int SADM_functions::step_limit = (int)(1024 * factor); +Stepper* SADM_functions::stepper = new Stepper(stepsPerRev, 8, 10, 9, 11); + +void SADM_functions::init_stepper() +{ + stepper->setSpeed(700); +} + +void SADM_functions::set_auto_rotate(Json_container* instruction) +{ + auto_rotate_en = instruction->get()->get("enable"); +} + +/* + Automatically rotates the SADM. + Must be continuously called. +*/ +void SADM_functions::auto_rotate() +{ + if (steps < step_limit) + { + steps++; + } + else + { + dir = !dir; + steps = 0; + } + + if (!dir) + { + stepper->step(1); + } + else + { + stepper->step(-1); + } +} + +// Rotates the SADM the passed number of steps +void SADM_functions::rotate(int steps) +{ + stepper->step(steps); +} + +// Converts from degrees to steps, and rotates the SADM +void SADM_functions::rotate(float degrees) +{ + // 1 deg = 2048steps/360deg = 5.69 step/deg + stepper->step((int)(degrees * ((float)2048 / (float)360))); +} + +void SADM_functions::rotate(Json_container* instruction) +{ + if (instruction->get()->containsKey("deg")) + { + float deg = instruction->get()->get("deg"); + rotate(deg); + } + else if (instruction->get()->containsKey("steps")) + { + int steps = instruction->get()->get("steps"); + rotate(steps); + } +} + +bool SADM_functions::get_auto_rotate_en() +{ + return auto_rotate_en; +} diff --git a/SatStat_HWLayer/other/SADM_functions.h b/SatStat_HWLayer/other/SADM_functions.h new file mode 100644 index 0000000..ed7aa8d --- /dev/null +++ b/SatStat_HWLayer/other/SADM_functions.h @@ -0,0 +1,25 @@ +#pragma once +#include "./Json_container.h" +#include "../libraries/Stepper.h" + + +class SADM_functions +{ +public: + static void init_stepper(); + static void set_auto_rotate(Json_container* instruction); + static void auto_rotate(); + static void rotate(int steps); + static void rotate(float degrees); + static void rotate(Json_container* instruction); + static bool get_auto_rotate_en(); + +private: + static int steps; + static bool dir; + static bool auto_rotate_en; + static const int stepsPerRev; + static const float factor; + static const int step_limit; + static Stepper* stepper; +}; diff --git a/SatStat_HWLayer/other/Sensor_container.cpp b/SatStat_HWLayer/other/Sensor_container.cpp new file mode 100644 index 0000000..67d19fb --- /dev/null +++ b/SatStat_HWLayer/other/Sensor_container.cpp @@ -0,0 +1,63 @@ +#pragma once +#include "Sensor_container.h" + +// Instantiate sensors +Sensor_container::Sensor_container() +{ + sensor_collection.append("temp_hum", new Temp_hum_sensor("temp_hum", 6)); +} + +// Delete every sensor in the sensor collection +Sensor_container::~Sensor_container() +{ + for (int i = 0; i < sensor_collection.count(); i++) + { + delete sensor_collection[i]; + } +} + +// Read given sensor +Json_container* Sensor_container::read_sensor(const String& name) +{ + Sensor* sensor = sensor_collection.get(name); + const Result* result = sensor->read_sensor(); + const int count = sensor->get_data_count(); + Json_container* obj = json_handler.create_object(); + + for (int i = 0; i < count; i++) + { + json_handler.append_to(obj, result[i].name, result[i].data); + } + + return obj; +} + +// Reads all sensors +Json_container* Sensor_container::read_sensors() +{ + Sensor* sensor; + int sensor_count = sensor_collection.count(); + const Result* result; + int result_count; + + Json_container* obj = json_handler.create_object(); + + for (int i = 0; i < sensor_count; i++) + { + sensor = sensor_collection[i]; + result = sensor->read_sensor(); + result_count = sensor->get_data_count(); + + for (int j = 0; j < result_count; j++) + { + json_handler.append_to(obj, result[j].name, result[j].data); + } + } + + return obj; +} + +LinkedList& Sensor_container::get_available_sensors() +{ + return sensor_collection; +} diff --git a/SatStat_HWLayer/other/Sensor_container.h b/SatStat_HWLayer/other/Sensor_container.h new file mode 100644 index 0000000..ce92881 --- /dev/null +++ b/SatStat_HWLayer/other/Sensor_container.h @@ -0,0 +1,23 @@ +#pragma once +#include "Arduino.h" +#include "../sensors/Temp_hum_sensor.h" +#include "../libraries/LinkedList.h" +#include "../handlers/Json_handler.h" + +class Sensor_container +{ +public: + // Constructor and destructor + Sensor_container(); + ~Sensor_container(); + + // Read methods + Json_container* read_sensor(const String& name); + Json_container* read_sensors(); + + LinkedList& get_available_sensors(); + +private: + LinkedList sensor_collection; + Json_handler json_handler; +}; \ No newline at end of file diff --git a/SatStat_HWLayer/sensors/Temp_hum_sensor.cpp b/SatStat_HWLayer/sensors/Temp_hum_sensor.cpp index b71a731..28bd07d 100644 --- a/SatStat_HWLayer/sensors/Temp_hum_sensor.cpp +++ b/SatStat_HWLayer/sensors/Temp_hum_sensor.cpp @@ -4,16 +4,15 @@ // Pass parameter inputs to parent constructor arguments Temp_hum_sensor::Temp_hum_sensor(const String& name, const int& pin) : Sensor(name, pin, 2) { + result[0].name = "temperature"; + result[1].name = "humidity"; } // Read and return every reading the sensor support const Result* Temp_hum_sensor::read_sensor() { - DHT.read11(pin); - result[0].name = "temperature"; result[0].data = DHT.temperature; - result[1].name = "humidity"; result[1].data = DHT.humidity; return result;