Test program for SPS30
Revision 4:91fa1c5ebbe1, committed 2019-03-27
- Comitter:
- ziqiyap
- Date:
- Wed Mar 27 06:08:17 2019 +0000
- Parent:
- 3:572adaa86366
- Commit message:
- working copy with sps30 lib integrated with sensordriver;
Changed in this revision
--- a/main.cpp Tue Mar 05 03:06:13 2019 +0000
+++ b/main.cpp Wed Mar 27 06:08:17 2019 +0000
@@ -11,7 +11,7 @@
Serial pc(SERIAL_TX, SERIAL_RX);
-sps30 sps(SDA0, SCL0, 100000); //Microchip real time clock (set as 400kHz)
+//sps30 sps(SDA1, SCL1, 100000); //Microchip real time clock (set as 400kHz)
DigitalOut myled(LED1);
//-----------------------------------------------------------------------------
@@ -24,30 +24,36 @@
//-----------------------------------------------------------------------------
// initial the scd30
-
+/*
void initSPS30() {
pc.printf("Initializing SPS30...\r\n");
- uint8_t dbg = sps.softReset();
+ uint8_t dbg = sps.SoftReset();
if (dbg != sps30::SPSnoERROR) pc.printf("No ack \r\n");
wait_ms(2000);
- sps.getSerialNumber();
+ sps.GetSerialNumber();
pc.printf(" - SPS30 s/n ascii: ");
for(int i = 0; i < sizeof(sps.sn); i++)
{
pc.printf("%c", sps.sn[i]);
}
pc.printf("\r\n");
- sps.getArticleCode();
+ sps.GetArticleCode();
pc.printf(" - SPS30 article code ascii: ");
for(int i = 0; i < sizeof(sps.acode); i++)
{
- pc.printf("%c", sps.acode[i]);
+ pc.printf("%d", sps.acode[i]);
}
-
+ pc.printf("\r\n");
+ sps.SetAutoCleanInterval();
+ pc.printf(" - SPS30 auto clean interval: %d", sps.clean_interval_i);
pc.printf("\r\n");
- sps.startMeasurement();
+
+ sps.StartMeasurement();
+ // sps.startFanClean();
+// pc.printf(" - SPS30 start manual clean \r\n");
+
}
-
+*/
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
@@ -59,11 +65,13 @@
pc.baud(9600);
wait_ms(200);
initSplash();
-
- initSPS30();
+
+ Sps30 sps(SDA2, SCL2, 100000);
+ sps.InitSensor();
+ wait(1);
+ pc.printf("Serial Number: %s \r\n", sps.sensor_serial);
int count = 0;
-// string mass_1p0, mass_2p5, mass_4p0, mass_10p0, num_0p5, num_1p0, num_2p5, num_4p0, num_10p0, typ_pm_size;
pc.printf("Ready...\r\n");
pc.printf(" count | MASS CONCENTRATION (ug/m3) | NUMBER CONCENTRATION (#/cm3) | Typical Particle Size \r\n");
pc.printf(" | PM1.0 | PM2.5 | PM4.0 | PM10.0 | PM0.5 | PM1.0 | PM2.5 | PM4.0 | PM10.0 | (um) \r\n");
@@ -72,16 +80,32 @@
{
myled = !myled;
wait_ms(250);
- sps.getReadyStatus();
+ int ret = sps.PollSensor();
+ if (ret == SensorDriver::SENSOR_DATAOK)
+ {
+ pc.printf(" %5d |", count);
+ for (int i = 0; i < sps.sensor_data.size(); i++)
+ {
+ pc.printf(" %s |", sps.sensor_data[i].second);
+ }
+ pc.printf("\r\n");
+ count++;
+ }
+
+ /*
+ sps.GetReadyStatus();
uint16_t redy = sps.ready;
if(redy == sps30::SPSisReady) {
- uint8_t crcc = sps.readMeasurement();
+ uint8_t crcc = sps.ReadMeasurement();
count++;
if(crcc != sps30::SPSnoERROR) pc.printf("ERROR: %d\r\n", crcc);
else pc.printf(" %5d | %7.3f | %7.3f | %7.3f | %7.3f | %7.3f | %7.3f | %7.3f | %7.3f | %7.3f | %7.3f \r\n", \
count, sps.mass_1p0_f, sps.mass_2p5_f, sps.mass_4p0_f, sps.mass_10p0_f, sps.num_0p5_f, \
sps.num_1p0_f, sps.num_2p5_f, sps.num_4p0_f, sps.num_10p0_f, sps.typ_pm_size_f);
}
+ */
+// pc.printf("breakpoint 2");
+// sps.sensor_data.clear();
wait(5);
}
}
--- a/sps30.lib Tue Mar 05 03:06:13 2019 +0000 +++ b/sps30.lib Wed Mar 27 06:08:17 2019 +0000 @@ -1,1 +1,1 @@ -https://os.mbed.com/users/ziqiyap/code/SPS30/#0078efb8903a +https://os.mbed.com/users/ziqiyap/code/SPS30-sensor/#a5fe43e183e2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/DatastructConversion/conversions.cpp Wed Mar 27 06:08:17 2019 +0000
@@ -0,0 +1,140 @@
+/**
+ * @defgroup conversions Data Structure Conversions
+ * @{
+ */
+
+#include <sstream>
+#include <iomanip>
+#include <vector>
+#include "conversions.h"
+
+/**
+ * @brief Converts a C++ string to C-string; Use free() to release mem after copying the content.
+ * @author Lau Lee Hong
+ * @param str C++ string
+ * @return Pointer to a null-terminated array of character
+ */
+char* StringToChar(const std::string& str)
+{
+ char* buffer = (char*)std::malloc(std::strlen(str.c_str()) + 1);
+ if(buffer != NULL)
+ {
+ std::strcpy(buffer, str.c_str());
+ }
+
+ return buffer;
+}
+
+/**
+ * @brief Converts an int-type to string-type hex.
+ * @author Lau Lee Hong
+ * @param i Integer to be converted to hex string
+ * @return Hexadecimal of string format
+ */
+std::string IntToHex(uint32_t i)
+{
+ std::stringstream stream;
+ stream << std::hex << i;
+ return stream.str();
+}
+
+/**
+ * @brief Converts an int-type to string.
+ * @author Lau Lee Hong
+ * @param i (int)integer to be converted (std::string)integer
+ * @return Integer of string format
+ */
+std::string IntToString(int v)
+{
+ std::ostringstream oss;
+ oss << v;
+ return oss.str();
+}
+
+/**
+ * @brief Converts an double-type to a C-string with variable number of decimal places.
+ * @author Lau Lee Hong
+ * @param str buffer to store result
+ * @param v value
+ * @param decimal_digits number of decimal places
+ * @return Null-terminated charcter array of double value with user-defined number of decimal places
+ */
+char* DoubleToChar(char* str, double v, int decimal_digits)
+{
+ int i = 1;
+ int int_part, fract_part;
+ int len;
+ char *ptr;
+
+ /* Prepare decimal digits multiplicator */
+ for (; decimal_digits != 0; i *= 10, decimal_digits--);
+
+ /* Calculate integer & fractional parts */
+ int_part = (int)v;
+ fract_part = (int)((v - (double)(int)v) * i);
+
+ /* Fill in integer part */
+ std::sprintf(str, "%i.", int_part);
+
+ /* Prepare fill in of fractional part */
+ len = std::strlen(str);
+ ptr = &str[len];
+
+ /* Fill in leading fractional zeros */
+ for (i /= 10; i > 1; i /= 10, ptr++)
+ {
+ if (fract_part >= i)
+ {
+ break;
+ }
+ *ptr = '0';
+ }
+
+ /* Fill in (rest of) fractional part */
+ std::sprintf(ptr, "%i", fract_part);
+
+ return str;
+}
+
+/**
+ * @brief Converts a C++ string to an integer
+ * @author Lee Tze Han
+ * @param str C++ string
+ * @return Integer from string representation
+ */
+int StringToInt(const std::string& str)
+{
+ std::istringstream iss(str);
+ int v;
+ iss >> v;
+ return v;
+}
+
+/**
+ * @brief Converts a time_t object (from NTPClient) to a C++ string
+ * @author Lee Tze Han
+ * @param time time_t representing current time
+ * @return String representation of the underlying typedef'd uint32_t
+ */
+//std::string TimeToString(const std::time_t time)
+//{
+// std::ostringstream oss;
+// oss << time;
+// return oss.str();
+//}
+//
+///**
+// * @brief Converts a C++ string to time_t object
+// * @author Lee Tze Han
+// * @param str C++ string
+// * @return time_t from string representation
+// */
+//std::time_t StringToTime(const std::string& str)
+//{
+// std::istringstream iss(str);
+// std::time_t time;
+// iss >> time;
+// return time;
+//}
+
+/** @}*/
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/DatastructConversion/conversions.h Wed Mar 27 06:08:17 2019 +0000 @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2018-2019, Sensors and IoT Capability Centre (SIOT) at GovTech. + * + * Contributor(s): + * Lau Lee Hong lau_lee_hong@tech.gov.sg + * Lee Tze Han + *******************************************************************************/ +#ifndef CONVERSIONS_H +#define CONVERSIONS_H + +#include <string> +#include <stdint.h> + +char* StringToChar(const std::string& str); +std::string IntToHex(uint32_t i); +std::string IntToString(int v); +char* DoubleToChar(char* str, double v, int decimalDigits); +int StringToInt(const std::string& str); +//std::string TimeToString(const std::time_t time); +//std::time_t StringToTime(const std::string& str); + +#endif // CONVERSIONS_H \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/SensorDriver/sensor_driver.cpp Wed Mar 27 06:08:17 2019 +0000
@@ -0,0 +1,77 @@
+/**
+ * @defgroup sensor_control Sensor Control API
+ * @{
+ */
+
+#include "sensor_driver.h"
+//#include "mbed-trace/mbed_trace.h"
+//#include "src/SensorProfile/sensor_profile.h"
+#include "src/DatastructConversion/conversions.h"
+//#include "src/TimeEngine/time_engine.h"
+//#include "src/TraceManager/trace_manager.h"
+//#include "src/TraceManager/trace_macro.h"
+
+//#define TRACE_GROUP "SensorDriver"
+
+/* General Functions for type conversions */
+
+std::string SensorDriver::ConvertSerialNumber(uint8_t sn_arr[])
+{
+ std::string sn_str = "";
+ for (int i = 0; i < sizeof(sn_arr); i++)
+ {
+ std::string str = IntToHex(sn_arr[i]);
+ sn_str.append(str);
+ }
+ return sn_str;
+}
+
+
+std::string SensorDriver::ConvertDataToString(float data)
+{
+ char buf[32];
+ std::string data_str = DoubleToChar(buf, data, 2);
+ return data_str;
+}
+
+
+int SensorDriver::ValidateData(float data, float data_min, float data_max)
+{
+ if (data > data_max | data < data_min)
+ {
+ return SENSOR_DATAOOR;
+ }
+ else return SENSOR_DATAOK;
+}
+
+
+void SensorDriver::SendSensorEmTrace(int err, std::string trace_string)
+{
+ if (err == SENSOR_DCN)
+ {
+// EmTrace(trace_level[WARN], trace_name[P1_DISCONN], RtcTimeNow()); // trace macro too specific to port
+ pc.printf("Warning: Sensor Disconnect\r\n");
+ }
+
+ if (err == SENSOR_CN)
+ {
+// EmTrace(trace_level[INFO], trace_name[P1_CONN], RtcTimeNow()); // trace macro too specific to port
+ pc.printf("Info: Sensor Connect\r\n");
+ }
+
+ if (err == SENSOR_DATAERR)
+ {
+// EmTrace(trace_level[WARN], trace_name[SEN_DATA_NOT_RDY], RtcTimeNow()); // trace macro not specific to port
+ pc.printf("Warning: Sensor Data Error\r\n");
+ }
+
+ if (err == SENSOR_DATAOOR)
+ {
+// EmTrace(trace_level[WARN], trace_string, RtcTimeNow());
+ pc.printf("Warning: Sensor Data Out of Range\r\n");
+ }
+
+ return;
+}
+
+/** @}*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/SensorDriver/sensor_driver.h Wed Mar 27 06:08:17 2019 +0000
@@ -0,0 +1,64 @@
+
+#ifndef SENSOR_DRIVER_H
+#define SENSOR_DRIVER_H
+
+#include <string>
+#include <vector>
+#include "mbed.h"
+
+/* Serial Communication Pins */
+#define SDA1 PB_9
+#define SCL1 PB_6
+#define SDA2 PF_0
+#define SCL2 PF_1
+#define SDA3 PF_15
+#define SCL3 PF_14
+
+/** SensorDriver Abstract class.
+ * @brief Contains common methods and members of the various sensors
+ *
+ * Example:
+ * @code{.cpp}
+ * #include "mbed.h"
+ * #include "sensor_driver.h"
+ *
+ * int main()
+ * {
+ *
+ * }
+ * @endcode
+ */
+
+extern Serial pc; /// for testing
+
+typedef vector< pair <string, string> > datalist_t;
+
+class SensorDriver
+{
+ public:
+ /// Public exposed methods
+ virtual void InitSensor() = 0; /// Initialise Sensor
+ virtual int PollSensor() = 0; /// Poll Sensor
+
+ std::string sensor_serial; /// Sensor ID string
+ datalist_t sensor_data; /// Sensor Data Vector
+
+ enum SensorStatus
+ {
+ SENSOR_DCN,
+ SENSOR_CN,
+ SENSOR_DATAERR,
+ SENSOR_DATAOOR,
+ SENSOR_DATAOK,
+ };
+
+ protected:
+ /// For use within the specific sensor class
+ std::string ConvertSerialNumber(uint8_t sn_arr[]); /// Convert uint8_t array of Serial ASCII to string
+ std::string ConvertDataToString(float data); /// Convert float data to string
+
+ int ValidateData(float data, float data_min, float data_max); /// Validate data with defined limits
+ void SendSensorEmTrace(int err, std::string trace_string = ""); /// Send Warning Trace to Event Manager
+
+};
+#endif // SENSOR_DRIVER_H