Commit 69bb8e52 authored by Lisandro Damián Nicanor Pérez Meyer's avatar Lisandro Damián Nicanor Pérez Meyer
Browse files

Merge branch 'release/0.0.4'

parents ee9722e2 5a05fa24
......@@ -11,7 +11,7 @@
#include <inttypes.h>
#include <Arduino.h>
#define FIRMWARE_VERSION "0.0.3"
#define FIRMWARE_VERSION "0.0.4"
#define HARDWARE_VERSION "0.0.1"
#define USE_WIFI_SECURE FALSE
......
mosimpa-monitor (0.0.3) mosimpa; urgency=medium
esp32-firmware (0.0.4) mosimpa; urgency=medium
* Rename the changelog entries to esp32-firmware in all entries.
* Be able to send error messages to the topic errors/{DID} (GitLab: #31).
* Avoid endless loops in max32664a.cpp, see
https://gitlab.com/mosimpa/documentation/-/issues/165
* Check that the Arduino ESP32 SDK version is exactly 1.0.5,
otherwise make the build fail.
* Check that the ArdunioJson Library's version is 6.18.0, otherwise make
the build fail.
-- Lisandro Damián Nicanor Pérez Meyer <perezmeyer@gmail.com> Tue, 25 May 2021 10:47:50 -0300
esp32-firmware (0.0.3) mosimpa; urgency=medium
* Decrease the number of MQTT server connection attempts to 5 (GitLab: #24).
- Make the constant private to MqttClient, as there is no need ot have it
......@@ -17,7 +30,7 @@ mosimpa-monitor (0.0.3) mosimpa; urgency=medium
-- Lisandro Damián Nicanor Pérez Meyer <perezmeyer@gmail.com> Thu, 29 Apr 2021 11:51:10 -0300
mosimpa-monitor (0.0.2) mosimpa; urgency=medium
esp32-firmware (0.0.2) mosimpa; urgency=medium
* Use the NTP server provided by our server.
* Use the MAC address as MQTT client name, thus allowing multiple devices to
......@@ -39,7 +52,7 @@ mosimpa-monitor (0.0.2) mosimpa; urgency=medium
-- Lisandro Damián Nicanor Pérez Meyer <perezmeyer@gmail.com> Mon, 28 Dec 2020 20:40:28 -0300
mosimpa-monitor (0.0.1-0) mosimpa; urgency=medium
esp32-firmware (0.0.1-0) mosimpa; urgency=medium
- Initial release.
......
#include <WString.h>
#define ARDUINOJSON_USE_LONG_LONG 1
#include <ArduinoJson.h>
#include "Configuration.h"
#include "errormessage.h"
ErrorMessage::ErrorMessage(const String file, const String func, int line, int retval)
{
_file = file;
_func = func;
_line = line;
_retval = retval;
// Clean up the file path.
int index = _file.lastIndexOf('/');
_file.remove(0, index+1);
}
String ErrorMessage::json() const
{
// The message will be at least 256 bytes long.
StaticJsonDocument<256> jsonDoc;
String msg;
// Create an empty doc.
jsonDoc.to<JsonObject>();
jsonDoc["file"] = _file;
jsonDoc["func"] = _func;
jsonDoc["line"] = _line;
jsonDoc["retval"] = _retval;
jsonDoc["firm_ver"] = FIRMWARE_VERSION;
serializeJson(jsonDoc, msg);
return msg;
}
#ifndef ERRORMESSAGE_H
#define ERRORMESSAGE_H
#include <limits>
#include <WString.h>
class ErrorMessage
{
public:
ErrorMessage(const String file, const String func, const int line, const int retval = std::numeric_limits<int>::min());
String json() const;
inline bool operator==(const ErrorMessage& rhs)
{
if((this->_file == rhs._file) &&
(this->_func == rhs._func) &&
(this->_line == rhs._line) &&
(this->_retval == rhs._retval))
return true;
return false;
}
private:
String _file;
String _func;
int _line;
int _retval;
};
#endif // ERRORMESSAGE_H
#include <string.h>
#include "errormessagequeue.h"
ErrorMessageQueue::ErrorMessageQueue()
{
}
void ErrorMessageQueue::add(const ErrorMessage &msg)
{
// Do not store copies.
for(int i=0; i < _q.size(); i++)
if(_q.at(i) == msg)
return;
// Not a copy, ensure that we have space for it.
while(_q.size() >= MAX_NUM_MSG)
{
_q.pop_front();
}
// Finally add the message at the end of the queue.
_q.push_back(msg);
}
ErrorMessage ErrorMessageQueue::takeFirst()
{
if(_q.empty())
return ErrorMessage(__FILE__, __func__, __LINE__, 0);
ErrorMessage e = _q.front();
_q.pop_front();
return e;
}
#ifndef ERRORMESSAGEQUEUE_H
#define ERRORMESSAGEQUEUE_H
#include <deque>
#include "errormessage.h"
class ErrorMessageQueue
{
public:
ErrorMessageQueue();
void add(const ErrorMessage & msg);
bool isEmpty() { return _q.empty(); }
ErrorMessage takeFirst();
private:
static const int MAX_NUM_MSG = 3;
std::deque<ErrorMessage> _q;
};
#endif // ERRORMESSAGEQUEUE_H
......@@ -9,13 +9,19 @@
/**
* \todo We are sending the password in clear.
*/
#include <string.h>
#define ARDUINOJSON_USE_LONG_LONG 1
#include <ArduinoJson.h>
#include <ArduinoJson/version.hpp>
#include <Wire.h>
#include <Ticker.h>
#include <ESPmDNS.h>
#include <WiFi.h>
#include <core_version.h>
#include "printf.h"
#include "Configuration.h"
#include "ConfigurationWebServer.h"
......@@ -23,7 +29,20 @@
#include "max32664ahub.h"
#include "abstractsensor.h"
#include "temperaturesensor.h"
#include "errormessagequeue.h"
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#ifndef ARDUINO_ESP32_RELEASE_1_0_5
#error This code was tested with version 1.0.5 of the Arduino ESP32 SDK.
#endif
#if (ARDUINOJSON_VERSION_MAJOR != 6) || (ARDUINOJSON_VERSION_MINOR != 18) || (ARDUINOJSON_VERSION_REVISION != 0)
#error This code was tested with version 6.18.0 of the ArduinoJson library.
#endif
/* ------------------------------------------------------------- */
ErrorMessageQueue errorMessageQueue;
/* ------------------------------------------------------------- */
TwoWire temperatureSensorI2C = TwoWire(0);
TwoWire oxygenAndHeartRateSensorI2C = TwoWire(1);
......@@ -128,6 +147,12 @@ void loop()
// Let the MQTT client do it's job.
mqttClient.loop();
// Send error messages if we have them.
while(!errorMessageQueue.isEmpty())
{
publishErrorMessage(errorMessageQueue.takeFirst());
}
// Do not send data if we do not have a valid time reference.
if(mqttClient.lastNtpSync() == 0)
return;
......@@ -227,6 +252,13 @@ void configureSensors()
printfn("Sensor configuration Done!");
}
void publishErrorMessage(const ErrorMessage & msg)
{
String topic("errors/" + mqttClient.getID());
mqttClient.publish(topic.c_str(), msg.json().c_str());
printfn("\r\n- Published error message.");
}
/**
* @brief configureSensorTemperature()
* Configure the sensor temperature driver in order to use it.
......@@ -270,18 +302,20 @@ void configureSensorHub()
break;
case 0x8:
printfn
("Device is in bootloader mode, something went wrong!!!");
printfn("Device is in bootloader mode, something went wrong!!!");
break;
case 0xFF:
printfn("Could not communicate with the sensor hub: %d",
status);
printfn("Could not communicate with the sensor hub: %d", status);
break;
}
if (status != 0)
{
errorMessageQueue.add(ErrorMessage(__FILENAME__, __func__, __LINE__, status));
continue;
}
printfn("Reading default calibration coefficients...");
spo2AndHeartRateHub.readCoefficients(coefficients);
......@@ -295,8 +329,10 @@ void configureSensorHub()
if (status == 0)
printfn("Sensor hub configured.");
else
{
printfn("Error configuring sensor hub: %d", status);
errorMessageQueue.add(ErrorMessage(__FILENAME__, __func__, __LINE__, status));
}
error_count++;
if (error_count >= SENSOR_CONFIG_ERROR_COUNT)
......@@ -470,7 +506,10 @@ void readSensorHub()
retval = spo2AndHeartRateHub.readHrSpO2(bioDataArray, MAX32664AHub::MAX_REPORTS_NUMBER,
numReportsRead, totalNumReports);
if(retval != 0)
{
errorMessageQueue.add(ErrorMessage(__FILENAME__, __func__, __LINE__, retval));
return;
}
printfn("BioHub: retrieved %d out of %d reports in the FIFO.", numReportsRead, totalNumReports);
......
......@@ -286,13 +286,14 @@ uint8_t MAX32664A::writeCmd(const int8_t txLen, const int16_t sleepMs)
delay(sleepMs);
retries = DEFAULT_RETRIES;
do
{
_twoWire->requestFrom(_hubAddress, static_cast<uint8_t>(1));
statusByte = _twoWire->read();
delay(sleepMs);
} while((statusByte == static_cast<uint8_t>(SsStatus::ErrTryAgain)) &&
(statusByte != static_cast<uint8_t>(SsStatus::Success)));
(statusByte != static_cast<uint8_t>(SsStatus::Success)) && (retries-- > 0));
return statusByte;
}
......@@ -338,11 +339,14 @@ uint8_t MAX32664A::readCmd(uint8_t *cmdBytes, const int cmdLen,
// We need a slighter bigger buffer.
uint8_t rx[rxLen+1];
retries = DEFAULT_RETRIES;
do
{
retval = _twoWire->readTransmission(_hubAddress, rx, rxLen+1);
delay(delayMs);
} while((retval != I2C_ERROR_OK) && (rx[0] != static_cast<uint8_t>(SsStatus::ErrTryAgain)));
} while((retval != I2C_ERROR_OK) &&
(rx[0] != static_cast<uint8_t>(SsStatus::ErrTryAgain)) &&
(retries-- > 0));
// Copy back the result.
memcpy(rxBuffer, &rx[1], rxLen);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment