diff --git a/ArduinoUtils.cpp b/ArduinoUtils.cpp new file mode 100644 index 0000000..7581a0c --- /dev/null +++ b/ArduinoUtils.cpp @@ -0,0 +1,111 @@ +#include "ArduinoUtils.h" +#if defined(ARDUINO) +#include +#include + +bool StartWifi(const char *wifiSsid, const char *wifiPassword, + bool hotspotFallback) { +#if UNO_R4 || ARDUINO_ARCH_RP2040 + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("WiFi not present, WiFiSync is disabled"); + return false; + } +#endif + +#if ESP32 + printf("Connecting to WiFi %s\n", wifiSsid); +#else + Serial.print("Connecting to WiFi "); + Serial.println(wifiSsid); +#endif + + // Connect to Wifi + WiFi.begin(wifiSsid, wifiPassword); + uint32_t notConnectedCounter = 0; + bool connected = false; + bool hotSpotEnabled = false; + + while (WiFi.status() != WL_CONNECTED && !hotSpotEnabled) { +#if ESP32 + printf("."); +#else + Serial.print("."); +#endif + delay(500); + + notConnectedCounter++; + if (notConnectedCounter > 20 && hotspotFallback) { +#if ESP32 + printf("\nCould not connect to home network.\n"); +#else + Serial.println(); + Serial.println("Could not connect to home network"); +#endif + WiFi.disconnect(); + if (hotspotFallback) { +#if ESP32 + WiFi.mode(WIFI_OFF); + WiFi.mode(WIFI_AP); + IPAddress wifiMyIp(192, 168, 4, 1); + WiFi.softAPConfig(wifiMyIp, wifiMyIp, IPAddress(255, 255, 255, 0)); + + WiFi.softAP(hotspotSSID, hotspotPassword); +#elif UNO_R4 || ARDUINO_ARCH_RP2040 + WiFi.beginAP(hotspotSSID); +#endif + printf("Setup WiFi hotspot...\n"); + // printf("ssid = %s, password = %s\n", hotspotSSID, hotspotPassword); +#if ARDUINO_ARCH_RP2040 + String ipAddress = WiFi.localIP().toString(); +#else + String ipAddress = WiFi.softAPIP().toString(); +#endif + char buf[20]; + ipAddress.toCharArray(buf, 20); + printf("IP address: %s\n", buf); + hotSpotEnabled = true; + } + } + } + connected = notConnectedCounter <= 20; + + if (connected) { + char buf[20]; + String ipAddress = WiFi.localIP().toString(); + ipAddress.toCharArray(buf, 20); +#if ESP32 || ESP8266 + printf("\nWifi connected, IP address: %s\n", buf); +#else + Serial.println(); + Serial.println("Wifi connected"); +#endif +#if ESP32 + printf("Checking credentials in flash\n"); + wifiPreferences.begin(PREFERENCES_NAMESPACE); + wifiPreferences.getBytes(STORAGE_KEY_WIFI, &credentials, + sizeof(credentials)); + if (strcmp(wifiSsid, credentials.ssid) != 0 || + strcmp(wifiPassword, credentials.password) != 0) { + printf("Updating credentials in flash..."); + const int ssidLen = strlen(wifiSsid); + if (ssidLen < 32) { + memcpy(credentials.ssid, wifiSsid, ssidLen); + credentials.ssid[ssidLen] = '\0'; + } + + const int pwdLen = strlen(wifiPassword); + if (pwdLen < 32) { + memcpy(credentials.password, wifiPassword, pwdLen); + credentials.password[pwdLen] = '\0'; + } + wifiPreferences.putBytes(STORAGE_KEY_WIFI, &credentials, + sizeof(credentials)); + printf(" completed.\n"); + } + wifiPreferences.end(); +#endif + } + + return (!hotSpotEnabled); +} +#endif \ No newline at end of file diff --git a/ArduinoUtils.h b/ArduinoUtils.h new file mode 100644 index 0000000..e00514f --- /dev/null +++ b/ArduinoUtils.h @@ -0,0 +1,4 @@ +#pragma once + +bool StartWifi(const char *wifiSsid, const char *wifiPassword, + bool hotspotFallback); \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 3129eac..4e5d151 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,7 @@ else() . LinearAlgebra ) - file(GLOB srcs *.cpp Sensors/*.cpp) + file(GLOB srcs *.cpp Sensors/*.cpp Messages/*.cpp) add_library(ControlCore STATIC ${srcs}) enable_testing() diff --git a/LinearAlgebra/Spherical.cpp b/LinearAlgebra/Spherical.cpp index 10ffd48..b12ea01 100644 --- a/LinearAlgebra/Spherical.cpp +++ b/LinearAlgebra/Spherical.cpp @@ -123,7 +123,7 @@ const SphericalOf SphericalOf::down = template SphericalOf SphericalOf::WithDistance(float distance) { SphericalOf v = SphericalOf(distance, this->direction); - return SphericalOf(); + return v; } template SphericalOf SphericalOf::operator-() const { diff --git a/Messages.cpp b/Messages.cpp index f5abd98..ab0e4c3 100644 --- a/Messages.cpp +++ b/Messages.cpp @@ -1,6 +1,7 @@ #include "Messages.h" #include "LowLevelMessages.h" +// #include "Messages/CustomMsg.h" #include "Participant.h" #include "string.h" @@ -106,43 +107,6 @@ unsigned char PoseMsg::Serialize(char *buffer) { // Pose #pragma endregion -#pragma region CustomMsg - -CustomMsg::CustomMsg(char *buffer) { - unsigned char ix = 1; - this->networkId = buffer[ix++]; - this->thingId = buffer[ix++]; - this->bytes = - buffer + ix; // This is only valid because the code ensures the the msg - // lifetime is shorter than the buffer lifetime... -} - -CustomMsg::CustomMsg(unsigned char networkId, Thing *thing) { - this->networkId = networkId; - this->thingId = thing->id; - this->thing = thing; -} - -unsigned char CustomMsg::Serialize(char *buffer) { - unsigned char ix = this->length; - this->thing->SendBytes(buffer, &ix); - if (ix <= this->length) // in this case, no data is actually sent - return 0; - - buffer[0] = this->id; - buffer[1] = this->networkId; - buffer[2] = this->thingId; - return ix; -} - -CustomMsg CustomMsg::Receive(char *buffer, unsigned char bufferSize) { - CustomMsg msg = CustomMsg(buffer); - return msg; -} - -// CustomMsg -#pragma endregion - #pragma region DestroyMsg DestroyMsg::DestroyMsg(unsigned char networkId, Thing *thing) { diff --git a/Messages.h b/Messages.h index c5d7625..f0d5cd4 100644 --- a/Messages.h +++ b/Messages.h @@ -62,26 +62,6 @@ public: virtual unsigned char Serialize(char *buffer) override; }; -class CustomMsg : public IMessage { -public: - static const unsigned char id = 0xB1; - static const unsigned length = 3; - - unsigned char networkId; - unsigned char thingId; - Thing *thing; - - unsigned char bytesSize; - char *bytes; - - CustomMsg(char *buffer); - CustomMsg(unsigned char networkId, Thing *thing); - - virtual unsigned char Serialize(char *buffer) override; - - static CustomMsg Receive(char *buffer, unsigned char bufferSize); -}; - class DestroyMsg : public IMessage { public: static const unsigned char id = 0x20; diff --git a/Messages/CustomMsg.cpp b/Messages/CustomMsg.cpp new file mode 100644 index 0000000..40e91f1 --- /dev/null +++ b/Messages/CustomMsg.cpp @@ -0,0 +1,41 @@ +#include "CustomMsg.h" + +namespace Passer { +namespace Control { + +CustomMsg::CustomMsg(char *buffer) { + unsigned char ix = 1; + this->networkId = buffer[ix++]; + this->thingId = buffer[ix++]; + this->bytes = + buffer + ix; // This is only valid because the code ensures the the msg + // lifetime is shorter than the buffer lifetime... +} + +CustomMsg::CustomMsg(unsigned char networkId, Thing *thing) { + this->networkId = networkId; + this->thingId = thing->id; + this->thing = thing; +} + +CustomMsg::~CustomMsg() {} + +unsigned char CustomMsg::Serialize(char *buffer) { + unsigned char ix = this->length; + this->thing->SendBytes(buffer, &ix); + if (ix <= this->length) // in this case, no data is actually sent + return 0; + + buffer[0] = this->id; + buffer[1] = this->networkId; + buffer[2] = this->thingId; + return ix; +} + +CustomMsg CustomMsg::Receive(char *buffer, unsigned char bufferSize) { + CustomMsg msg = CustomMsg(buffer); + return msg; +} + +} // namespace Control +} // namespace Passer diff --git a/Messages/CustomMsg.h b/Messages/CustomMsg.h new file mode 100644 index 0000000..ed7c02c --- /dev/null +++ b/Messages/CustomMsg.h @@ -0,0 +1,30 @@ +#pragma once + +#include "Messages.h" + +namespace Passer { +namespace Control { + +class CustomMsg : public IMessage { +public: + static const unsigned char id = 0xB1; + static const unsigned length = 3; + + unsigned char networkId; + unsigned char thingId; + Thing *thing; + + unsigned char bytesSize; + char *bytes = nullptr; + + CustomMsg(char *buffer); + CustomMsg(unsigned char networkId, Thing *thing); + ~CustomMsg(); + + virtual unsigned char Serialize(char *buffer) override; + + static CustomMsg Receive(char *buffer, unsigned char bufferSize); +}; + +} // namespace Control +} // namespace Passer diff --git a/Participant.cpp b/Participant.cpp index 4fb6c72..3e5cd05 100644 --- a/Participant.cpp +++ b/Participant.cpp @@ -18,6 +18,9 @@ #include #endif +namespace Passer { +namespace Control { + Participant::Participant() {} Participant::Participant(int port) { @@ -55,6 +58,10 @@ void Passer::Control::Participant::SetupUDP(int localPort, #endif } +#if defined(ARDUINO) +void Participant::Update() { this->Update(millis()); } +#endif + void Participant::Update(unsigned long currentTimeMs) { if (this->publishInterval > 0 && currentTimeMs > this->nextPublishMe) { ClientMsg *msg = new ClientMsg(this->networkId); @@ -124,6 +131,9 @@ void Passer::Control::Participant::PublishThingInfo(Thing *thing) { ModelUrlMsg *modelMsg = new ModelUrlMsg(this->networkId, thing); this->Publish(modelMsg); delete modelMsg; + CustomMsg *customMsg = new CustomMsg(this->networkId, thing); + this->Publish(customMsg); + delete customMsg; } bool Participant::Send(IMessage *msg) { @@ -242,4 +252,6 @@ void Participant::Process(CustomMsg *msg) { } // Receive -#pragma endregion \ No newline at end of file +#pragma endregion +} // namespace Control +} // namespace Passer diff --git a/Participant.h b/Participant.h index 5e00490..3feaccc 100644 --- a/Participant.h +++ b/Participant.h @@ -2,6 +2,7 @@ #include "ClientMsg.h" #include "Messages.h" +#include "Messages/CustomMsg.h" #include "ModelUrlMsg.h" #include "NameMsg.h" #include "NetworkIdMsg.h" @@ -61,6 +62,9 @@ public: // i.e. // Participant p = Participant("127.0.0.1", 8000); +#if defined(ARDUINO) + virtual void Update(); +#endif virtual void Update(unsigned long currentTimeMs); void SendThingInfo(Thing *thing); diff --git a/Sensors/TemperatureSensor.cpp b/Sensors/TemperatureSensor.cpp index 6cc1644..9fe5c67 100644 --- a/Sensors/TemperatureSensor.cpp +++ b/Sensors/TemperatureSensor.cpp @@ -7,6 +7,8 @@ namespace Control { // TemperatureSensor::TemperatureSensor() : Thing(Type::TemperatureSensor) {} +TemperatureSensor::TemperatureSensor() : Thing(Type::TemperatureSensor) {} + TemperatureSensor::TemperatureSensor(unsigned char networkId, unsigned char thingId) : Thing(nullptr, networkId, thingId, Type::TemperatureSensor) {} diff --git a/Sensors/TemperatureSensor.h b/Sensors/TemperatureSensor.h index 22f8083..d4f5142 100644 --- a/Sensors/TemperatureSensor.h +++ b/Sensors/TemperatureSensor.h @@ -7,6 +7,7 @@ namespace Control { class TemperatureSensor : public Thing { public: + TemperatureSensor(); TemperatureSensor(unsigned char networkId, unsigned char thingId); virtual void SetTemperature(float temp); diff --git a/SiteServer.cpp b/SiteServer.cpp index 83149d0..87ea5d6 100644 --- a/SiteServer.cpp +++ b/SiteServer.cpp @@ -2,6 +2,9 @@ #include "Sensors/TemperatureSensor.h" +#include +#include + namespace Passer { namespace Control { diff --git a/float16.cpp b/float16.cpp index a084f22..041b3d3 100644 --- a/float16.cpp +++ b/float16.cpp @@ -188,6 +188,13 @@ float float16::f16tof32(uint16_t _value) const { } uint16_t float16::f32tof16(float f) const { + // untested code, but will avoid strict aliasing warning + // union { + // float f; + // uint32_t t; + // } u; + // u.f = f; + // uint32_t t = u.t; uint32_t t = *(uint32_t *)&f; // man bits = 10; but we keep 11 for rounding uint16_t man = (t & 0x007FFFFF) >> 12;