Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: SoftSerial MAX14690 Buffer
Fork of rtos_threading_with_callback by
Revision 3:d7ec6dc025b0, committed 2018-03-30
- Comitter:
- lwehmeier
- Date:
- Fri Mar 30 10:32:10 2018 +0000
- Parent:
- 2:bf699e054b34
- Commit message:
- implemented basic GPS read support, freed serial connection for uart jpg camera module
Changed in this revision
diff -r bf699e054b34 -r d7ec6dc025b0 BufferedSerial/Buffer.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BufferedSerial/Buffer.lib Fri Mar 30 10:32:10 2018 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/sam_grove/code/Buffer/#89564915f2a7
diff -r bf699e054b34 -r d7ec6dc025b0 BufferedSerial/BufferedSerial.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferedSerial/BufferedSerial.cpp Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,161 @@
+/**
+ * @file BufferedSerial.cpp
+ * @brief Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
+ * @author sam grove
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BufferedSerial.h"
+#include <stdarg.h>
+
+BufferedSerial::BufferedSerial(PinName tx, PinName rx, uint32_t buf_size, uint32_t tx_multiple, const char* name)
+ : RawSerial(tx, rx) , _rxbuf(buf_size), _txbuf((uint32_t)(tx_multiple*buf_size))
+{
+ //attach(this, &BufferedSerial::rxIrq, Serial::RxIrq);
+ this->_buf_size = buf_size;
+ this->_tx_multiple = tx_multiple;
+ return;
+}
+
+BufferedSerial::~BufferedSerial(void)
+{
+ //printf("destructor buffered serial\r\n");
+ RawSerial::attach(NULL, RawSerial::RxIrq);
+ RawSerial::attach(NULL, RawSerial::TxIrq);
+
+ return;
+}
+
+int BufferedSerial::readable(void)
+{
+ return _rxbuf.available(); // note: look if things are in the buffer
+}
+
+int BufferedSerial::writeable(void)
+{
+ return 1; // buffer allows overwriting by design, always true
+}
+
+int BufferedSerial::getc(void)
+{
+ return _rxbuf;
+}
+
+int BufferedSerial::putc(int c)
+{
+ _txbuf = (char)c;
+ BufferedSerial::prime();
+
+ return c;
+}
+
+int BufferedSerial::puts(const char *s)
+{
+ if (s != NULL) {
+ const char* ptr = s;
+
+ while(*(ptr) != 0) {
+ _txbuf = *(ptr++);
+ }
+ _txbuf = '\n'; // done per puts definition
+ BufferedSerial::prime();
+
+ return (ptr - s) + 1;
+ }
+ return 0;
+}
+
+int BufferedSerial::printf(const char* format, ...)
+{
+ char buffer[this->_buf_size];
+ memset(buffer,0,this->_buf_size);
+ int r = 0;
+
+ va_list arg;
+ va_start(arg, format);
+ r = vsprintf(buffer, format, arg);
+ // this may not hit the heap but should alert the user anyways
+ if(r > this->_buf_size) {
+ error("%s %d buffer overwrite (max_buf_size: %d exceeded: %d)!\r\n", __FILE__, __LINE__,this->_buf_size,r);
+ va_end(arg);
+ return 0;
+ }
+ va_end(arg);
+ r = BufferedSerial::write(buffer, r);
+
+ return r;
+}
+
+ssize_t BufferedSerial::write(const void *s, size_t length)
+{
+ if (s != NULL && length > 0) {
+ const char* ptr = (const char*)s;
+ const char* end = ptr + length;
+
+ while (ptr != end) {
+ _txbuf = *(ptr++);
+ }
+ BufferedSerial::prime();
+
+ return ptr - (const char*)s;
+ }
+ return 0;
+}
+
+
+void BufferedSerial::rxIrq(void)
+{
+ //printf("rx\r\n");
+ // read from the peripheral and make sure something is available
+ if(serial_readable(&_serial)) {
+ _rxbuf = serial_getc(&_serial); // if so load them into a buffer
+ }
+
+ return;
+}
+
+void BufferedSerial::txIrq(void)
+{
+ // see if there is room in the hardware fifo and if something is in the software fifo
+ while(serial_writable(&_serial)) {
+ if(_txbuf.available()) {
+ serial_putc(&_serial, (int)_txbuf.get());
+ } else {
+ // disable the TX interrupt when there is nothing left to send
+ RawSerial::attach(NULL, RawSerial::TxIrq);
+ break;
+ }
+ }
+
+ return;
+}
+
+void BufferedSerial::prime(void)
+{
+ //printf("prime\r\n");
+ // if already busy then the irq will pick this up
+ if(serial_writable(&_serial)) {
+ RawSerial::attach(NULL, RawSerial::TxIrq); // make sure not to cause contention in the irq
+ BufferedSerial::txIrq(); // only write to hardware in one place
+ RawSerial::attach(this, &BufferedSerial::txIrq, RawSerial::TxIrq);
+ }
+
+ return;
+}
+
+
diff -r bf699e054b34 -r d7ec6dc025b0 BufferedSerial/BufferedSerial.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferedSerial/BufferedSerial.h Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,140 @@
+
+/**
+ * @file BufferedSerial.h
+ * @brief Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
+ * @author sam grove
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BUFFEREDSERIAL_H
+#define BUFFEREDSERIAL_H
+
+#include "mbed.h"
+#include "MyBuffer.h"
+
+/** A serial port (UART) for communication with other serial devices
+ *
+ * Can be used for Full Duplex communication, or Simplex by specifying
+ * one pin as NC (Not Connected)
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ * #include "BufferedSerial.h"
+ *
+ * BufferedSerial pc(USBTX, USBRX);
+ *
+ * int main()
+ * {
+ * while(1)
+ * {
+ * Timer s;
+ *
+ * s.start();
+ * pc.printf("Hello World - buffered\n");
+ * int buffered_time = s.read_us();
+ * wait(0.1f); // give time for the buffer to empty
+ *
+ * s.reset();
+ * printf("Hello World - blocking\n");
+ * int polled_time = s.read_us();
+ * s.stop();
+ * wait(0.1f); // give time for the buffer to empty
+ *
+ * pc.printf("printf buffered took %d us\n", buffered_time);
+ * pc.printf("printf blocking took %d us\n", polled_time);
+ * wait(0.5f);
+ * }
+ * }
+ * @endcode
+ */
+
+/**
+ * @class BufferedSerial
+ * @brief Software buffers and interrupt driven tx and rx for Serial
+ */
+class BufferedSerial : public RawSerial
+{
+private:
+ MyBuffer <char> _rxbuf;
+ MyBuffer <char> _txbuf;
+ uint32_t _buf_size;
+ uint32_t _tx_multiple;
+
+public:
+
+ void rxIrq(void);
+ void txIrq(void);
+ void prime(void);
+ /** Create a BufferedSerial port, connected to the specified transmit and receive pins
+ * @param tx Transmit pin
+ * @param rx Receive pin
+ * @param buf_size printf() buffer size
+ * @param tx_multiple amount of max printf() present in the internal ring buffer at one time
+ * @param name optional name
+ * @note Either tx or rx may be specified as NC if unused
+ */
+ BufferedSerial(PinName tx, PinName rx, uint32_t buf_size = 256, uint32_t tx_multiple = 4,const char* name=NULL);
+
+ /** Destroy a BufferedSerial port
+ */
+ virtual ~BufferedSerial(void);
+
+ /** Check on how many bytes are in the rx buffer
+ * @return 1 if something exists, 0 otherwise
+ */
+ virtual int readable(void);
+
+ /** Check to see if the tx buffer has room
+ * @return 1 always has room and can overwrite previous content if too small / slow
+ */
+ virtual int writeable(void);
+
+ /** Get a single byte from the BufferedSerial Port.
+ * Should check readable() before calling this.
+ * @return A byte that came in on the Serial Port
+ */
+ virtual int getc(void);
+
+ /** Write a single byte to the BufferedSerial Port.
+ * @param c The byte to write to the Serial Port
+ * @return The byte that was written to the Serial Port Buffer
+ */
+ virtual int putc(int c);
+
+ /** Write a string to the BufferedSerial Port. Must be NULL terminated
+ * @param s The string to write to the Serial Port
+ * @return The number of bytes written to the Serial Port Buffer
+ */
+ virtual int puts(const char *s);
+
+ /** Write a formatted string to the BufferedSerial Port.
+ * @param format The string + format specifiers to write to the Serial Port
+ * @return The number of bytes written to the Serial Port Buffer
+ */
+ virtual int printf(const char* format, ...);
+
+ /** Write data to the Buffered Serial Port
+ * @param s A pointer to data to send
+ * @param length The amount of data being pointed to
+ * @return The number of bytes written to the Serial Port Buffer
+ */
+ virtual ssize_t write(const void *s, std::size_t length);
+};
+
+#endif
diff -r bf699e054b34 -r d7ec6dc025b0 GPS/GPS.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/GPS/GPS.cpp Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,292 @@
+#include "GPS.h"
+
+GPS::GPS(PinName tx, PinName rx) : _gps(tx, rx) {
+ _gps.baud(9600);
+ _gps.attach(&_gps, &BufferedSerial::rxIrq);
+ nmea_longitude = 0.0;
+ nmea_latitude = 0.0;
+ utc_time = 0;
+ ns = ' ';
+ ew = ' ';
+ lock = 0;
+ satelites = 0;
+ hdop = 0.0;
+ msl_altitude = 0.0;
+ msl_units = ' ';
+
+ rmc_status = ' ';
+ speed_k = 0.0;
+ course_d = 0.0;
+ date = 0;
+
+ dec_longitude = 0.0;
+ dec_latitude = 0.0;
+
+ gll_status = ' ';
+
+ course_t = 0.0; // ground speed true
+ course_t_unit = ' ';
+ course_m = 0.0; // magnetic
+ course_m_unit = ' ';
+ speed_k_unit = ' ';
+ speed_km = 0.0; // speek km/hr
+ speed_km_unit = ' ';
+
+ altitude_ft = 0.0;
+#ifdef OPEN_LOG
+ is_logging = false;
+#endif
+}
+
+#ifdef OPEN_LOG
+void GPS::start_log() {
+ is_logging = true;
+}
+
+void GPS::new_file(void) {
+ _openLog.newFile();
+}
+
+void GPS::stop_log(void) {
+ is_logging = false;
+}
+#endif
+
+float GPS::nmea_to_dec(float deg_coord, char nsew) {
+ int degree = (int)(deg_coord/100);
+ float minutes = deg_coord - degree*100;
+ float dec_deg = minutes / 60;
+ float decimal = degree + dec_deg;
+ if (nsew == 'S' || nsew == 'W') { // return negative
+ decimal *= -1;
+ }
+ return decimal;
+}
+unsigned printMsg = 0;
+int GPS::sample() {
+ int line_parsed = 0;
+
+
+ if (_gps.readable()) {
+ getline();
+
+#ifdef OPEN_LOG
+ if (is_logging && lock) {
+ format_for_log();
+ _openLog.write(bfr);
+ }
+#endif
+ char dummy1,dummy2,dummy3, dummy4;
+ float dummyf;
+ // Check if it is a GPGGA msg (matches both locked and non-locked msg)
+ //GNGGA,165051.00,5620.69688,N,00248.59763,W,0,00,99.99,63.5,M,49.5,M,,*57
+ //$GNGGA,165649.00,5620.44393,N,00248.54510,W,1,05,5.63,-9.3,M,49.5,M,,*70
+ if (sscanf(msg, "GNGGA,%f,%f,%c,%f,%c,%d,%d,%f,%f,%c,%f,%c,,%c%c%c", &utc_time, &nmea_latitude, &ns, &nmea_longitude, &ew, &lock, &satelites, &hdop, &msl_altitude, &msl_units, &dummyf,&dummy1,&dummy2,&dummy3,&dummy4) >= 1) {
+ line_parsed = GGA;
+ //printf("GNGGA\r\n");
+ }
+ // Check if it is a GPRMC msg
+ //else if (sscanf(msg, "GNRMC,%f,%c,%f,%c,%f,%f,%d", &utc_time, &ns, &nmea_longitude, &ew, &speed_k, &course_d, &date) >= 1) {
+ // line_parsed = RMC;
+ //}
+ // GLL - Geographic Position-Lat/Lon
+ // $GNGLL,5139.30741,N,04007.46879,E,162559.00,V,N*6B
+ if (sscanf(msg, "GNGLL,%f,%c,%f,%c,%f,%c,N%c%c%c", &nmea_latitude, &ns, &nmea_longitude, &ew, &utc_time, &gll_status, &dummy1, &dummy2, &dummy3) >= 1) {
+ line_parsed = GLL;
+ //printf("GNGLL\r\n");
+ }
+ // VTG-Course Over Ground and Ground Speed
+ //else if (sscanf(msg, "GNVTG,%f,%c,%f,%c,%f,%c,%f,%c", &course_t, &course_t_unit, &course_m, &course_m_unit, &speed_k, &speed_k_unit, &speed_km, &speed_km_unit) >= 1) {
+ // line_parsed = VTG;
+ //}
+
+ if(satelites == 0) {
+ lock = 0;
+ }
+ }
+ if (!lock) {
+ return NO_LOCK;
+ } else if (line_parsed) {
+ return line_parsed;
+ } else {
+ return NOT_PARSED;
+ }
+}
+
+
+// INTERNAL FUNCTINS ////////////////////////////////////////////////////////////
+float GPS::trunc(float v) {
+ if (v < 0.0) {
+ v*= -1.0;
+ v = floor(v);
+ v*=-1.0;
+ } else {
+ v = floor(v);
+ }
+ return v;
+}
+
+void GPS::getline() {
+ while (_gps.getc() != '$'); // wait for the start of a line
+ for (int i=0; i<1022; i++) {
+ msg[i] = _gps.getc();
+ if (msg[i] == '\r') {
+ msg[i] = 0;
+ return;
+ }
+ }
+ error("Overflow in getline");
+}
+
+void GPS::format_for_log() {
+ bfr[0] = '$';
+ for (int i = 0; i < 1022; i++) {
+ bfr[i+1] = msg[i];
+ if (msg[i] == 0 || msg[i] =='$') {
+ bfr[i+1] = '\r';
+ bfr[i+2] = '\n';
+ bfr[i+3] = 0;
+ return;
+ }
+ }
+ error("Overflow in format");
+}
+
+// GET FUNCTIONS /////////////////////////////////////////////////////////////////
+float GPS::get_msl_altitude() {
+ if (!lock)
+ return 0.0;
+ else
+ return msl_altitude;
+}
+
+int GPS::get_satelites() {
+ return satelites;
+}
+
+float GPS::get_nmea_longitude() {
+ if (!lock)
+ return 0.0;
+ else
+ return nmea_longitude;
+}
+
+float GPS::get_dec_longitude() {
+ dec_longitude = nmea_to_dec(nmea_longitude, ew);
+ if (!lock)
+ return 0.0;
+ else
+ return dec_longitude;
+}
+
+float GPS::get_nmea_latitude() {
+ if (!lock)
+ return 0.0;
+ else
+ return nmea_latitude;
+}
+
+float GPS::get_dec_latitude() {
+ dec_latitude = nmea_to_dec(nmea_latitude, ns);
+ if (!lock)
+ return 0.0;
+ else
+ return dec_latitude;
+}
+
+float GPS::get_course_t() {
+ if (!lock)
+ return 0.0;
+ else
+ return course_t;
+}
+
+float GPS::get_course_m() {
+ if (!lock)
+ return 0.0;
+ else
+ return course_m;
+}
+
+float GPS::get_speed_k() {
+ if (!lock)
+ return 0.0;
+ else
+ return speed_k;
+}
+
+float GPS::get_speed_km() {
+ if (!lock)
+ return 0.0;
+ else
+ return speed_km;
+}
+
+float GPS::get_altitude_ft() {
+ if (!lock)
+ return 0.0;
+ else
+ return 3.280839895*msl_altitude;
+}
+
+// NAVIGATION FUNCTIONS ////////////////////////////////////////////////////////////
+float GPS::calc_course_to(float pointLat, float pontLong) {
+ const double d2r = PI / 180.0;
+ const double r2d = 180.0 / PI;
+ double dlat = abs(pointLat - get_dec_latitude()) * d2r;
+ double dlong = abs(pontLong - get_dec_longitude()) * d2r;
+ double y = sin(dlong) * cos(pointLat * d2r);
+ double x = cos(get_dec_latitude()*d2r)*sin(pointLat*d2r) - sin(get_dec_latitude()*d2r)*cos(pointLat*d2r)*cos(dlong);
+ return atan2(y,x)*r2d;
+}
+
+/*
+var y = Math.sin(dLon) * Math.cos(lat2);
+var x = Math.cos(lat1)*Math.sin(lat2) -
+ Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
+var brng = Math.atan2(y, x).toDeg();
+*/
+
+/*
+ The Haversine formula according to Dr. Math.
+ http://mathforum.org/library/drmath/view/51879.html
+
+ dlon = lon2 - lon1
+ dlat = lat2 - lat1
+ a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2
+ c = 2 * atan2(sqrt(a), sqrt(1-a))
+ d = R * c
+
+ Where
+ * dlon is the change in longitude
+ * dlat is the change in latitude
+ * c is the great circle distance in Radians.
+ * R is the radius of a spherical Earth.
+ * The locations of the two points in
+ spherical coordinates (longitude and
+ latitude) are lon1,lat1 and lon2, lat2.
+*/
+double GPS::calc_dist_to_mi(float pointLat, float pontLong) {
+ const double d2r = PI / 180.0;
+ double dlat = pointLat - get_dec_latitude();
+ double dlong = pontLong - get_dec_longitude();
+ double a = pow(sin(dlat/2.0),2.0) + cos(get_dec_latitude()*d2r) * cos(pointLat*d2r) * pow(sin(dlong/2.0),2.0);
+ double c = 2.0 * asin(sqrt(abs(a)));
+ double d = 63.765 * c;
+
+ return d;
+}
+
+double GPS::calc_dist_to_ft(float pointLat, float pontLong) {
+ return calc_dist_to_mi(pointLat, pontLong)*5280.0;
+}
+
+double GPS::calc_dist_to_km(float pointLat, float pontLong) {
+ return calc_dist_to_mi(pointLat, pontLong)*1.609344;
+}
+
+double GPS::calc_dist_to_m(float pointLat, float pontLong) {
+ return calc_dist_to_mi(pointLat, pontLong)*1609.344;
+}
+
+
\ No newline at end of file
diff -r bf699e054b34 -r d7ec6dc025b0 GPS/GPS.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/GPS/GPS.h Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,104 @@
+#include "mbed.h"
+#include "BufferedSerial.h"
+#ifndef MBED_GPS_H
+#define MBED_GPS_H
+
+#define NO_LOCK 1
+#define NOT_PARSED 2
+#define GGA 3
+#define GLL 4
+#define RMC 5
+#define VTG 6
+
+#define PI (3.141592653589793)
+
+/** A GPS interface for reading from a Globalsat EM-406 GPS Module */
+class GPS {
+public:
+
+ /** Create the GPS interface, connected to the specified serial port
+ */
+ GPS(PinName tx, PinName rx);
+
+ /** Sample the incoming GPS data, returning whether there is a lock
+ *
+ * @return 1 if there was a lock when the sample was taken (and therefore .longitude and .latitude are valid), else 0
+ */
+ int sample();
+ float get_nmea_longitude();
+ float get_nmea_latitude();
+ float get_dec_longitude();
+ float get_dec_latitude();
+ float get_msl_altitude();
+ float get_course_t();
+ float get_course_m();
+ float get_speed_k();
+ float get_speed_km();
+ int get_satelites();
+ float get_altitude_ft();
+
+ // navigational functions
+ float calc_course_to(float, float);
+ double calc_dist_to_mi(float, float);
+ double calc_dist_to_ft(float, float);
+ double calc_dist_to_km(float, float);
+ double calc_dist_to_m(float, float);
+
+ void onInterrupt(){
+ printf("%d\r\n", _gps.readable());
+ }
+#ifdef OPEN_LOG
+ void start_log(void);
+ void new_file(void);
+ void stop_log(void);
+#endif
+
+private:
+ float nmea_to_dec(float, char);
+ float trunc(float v);
+ void getline();
+ void format_for_log(void);
+
+ BufferedSerial _gps;
+ char msg[1024];
+ char bfr[1030];
+ bool is_logging;
+#ifdef OPEN_LOG
+ Logger _openLog;
+#endif
+ // calculated values
+ float dec_longitude;
+ float dec_latitude;
+ float altitude_ft;
+
+ // GGA - Global Positioning System Fixed Data
+ float nmea_longitude;
+ float nmea_latitude;
+ float utc_time;
+ char ns, ew;
+ int lock;
+ int satelites;
+ float hdop;
+ float msl_altitude;
+ char msl_units;
+
+ // RMC - Recommended Minimmum Specific GNS Data
+ char rmc_status;
+ float speed_k;
+ float course_d;
+ int date;
+
+ // GLL
+ char gll_status;
+
+ // VTG - Course over ground, ground speed
+ float course_t; // ground speed true
+ char course_t_unit;
+ float course_m; // magnetic
+ char course_m_unit;
+ char speed_k_unit;
+ float speed_km; // speek km/hr
+ char speed_km_unit;
+};
+
+#endif
diff -r bf699e054b34 -r d7ec6dc025b0 SoftSerial.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SoftSerial.lib Fri Mar 30 10:32:10 2018 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/Sissors/code/SoftSerial/#a0029614de72
diff -r bf699e054b34 -r d7ec6dc025b0 acquireDHT/getDHT.cpp
--- a/acquireDHT/getDHT.cpp Sun Feb 25 16:40:28 2018 +0000
+++ b/acquireDHT/getDHT.cpp Fri Mar 30 10:32:10 2018 +0000
@@ -2,6 +2,7 @@
#include "DHT.h"
#include "rtos.h"
#include "global.h"
+#include "logger.h"
class DHTData
{
@@ -16,6 +17,10 @@
float h = dht.ReadHumidity();
humidity = h;
float dpf = dht.CalcdewPointFast(c, h);
+ char *buffer = new char[50];
+ sprintf(buffer, "Temperature: %3.2f, Humidity: %3.2f\r\n", c,h);
+ Logger::log(buffer);
+
printf("DHT: Temperature in Celcius: %4.2f\r\n", c);
printf("DHT: Humidity is %4.2f, Dewpoint: %4.2f\r\n", h, dpf);
diff -r bf699e054b34 -r d7ec6dc025b0 gpsTask.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gpsTask.cpp Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,35 @@
+#include "mbed.h"
+#include "GPS.h"
+#include "rtos.h"
+#include "global.h"
+
+class GpsTask
+{
+public:
+ static void run()
+ {
+ for (;;) {
+ //printf("GPS task\r\n");
+ if(gps.sample()>2)
+ {
+ float lon = gps.get_dec_longitude();
+ printf("Sat: %u\r\n", gps.get_satelites());
+ printf("%3.2f\r\n", lon);
+ }
+ //float lon = gps.get_dec_longitude();
+ //printf("Sat: %u\r\n", gps.get_satelites());
+ //printf("%3.2f\r\n", lon);
+ rtos::Thread::wait(250);
+ }
+ }
+ GpsTask()
+ {
+ registerThread(GpsTask::run);
+ //run();
+ }
+ static GPS gps;
+};
+GPS GpsTask::gps(P5_4, P5_3);
+
+// some witchcraft to register run function without touching anything outside our library
+static GpsTask _dummy;
\ No newline at end of file
diff -r bf699e054b34 -r d7ec6dc025b0 logger/logger.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/logger/logger.cpp Fri Mar 30 10:32:10 2018 +0000 @@ -0,0 +1,3 @@ +#include "logger.h" + +rtos::Queue<char, 24> Logger::q = rtos::Queue<char, 24>(); \ No newline at end of file
diff -r bf699e054b34 -r d7ec6dc025b0 logger/logger.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/logger/logger.h Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "rtos.h"
+class SDLogger;
+class Logger
+{
+ friend SDLogger;
+public:
+ static bool log(char* msg){
+ q.put(msg, osWaitForever);
+ return true;
+ }
+protected:
+ static rtos::Queue<char, 24> q; //max sz == 24
+ static const unsigned maxQueueSize = 24;
+};
\ No newline at end of file
diff -r bf699e054b34 -r d7ec6dc025b0 main.cpp
--- a/main.cpp Sun Feb 25 16:40:28 2018 +0000
+++ b/main.cpp Fri Mar 30 10:32:10 2018 +0000
@@ -8,6 +8,15 @@
MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
+#include "platform/mbed_assert.h"
+#include "platform/mbed_debug.h"
+#include "platform/mbed_error.h"
+#include "platform/mbed_stats.h"
+#define MAX_THREAD_INFO 10
+mbed_stats_heap_t heap_info;
+mbed_stats_stack_t stack_info[ MAX_THREAD_INFO ];
+
+
SPI spi(P5_1, P5_2, P5_0);
I2C i2c(P5_7, P6_0); //sda, scl
I2C i2c2(P3_4, P3_5); //sda, scl
@@ -52,11 +61,12 @@
{
txBuf[i]|=(linkEnc.getNext()<<j);
}
- printf("0x%02x%02x%02x%02x%02x%02x%02x%02x\r\n", txBuf[0], txBuf[1], txBuf[2], txBuf[3], txBuf[4], txBuf[5], txBuf[6], txBuf[7]);
+ //printf("0x%02x%02x%02x%02x%02x%02x%02x%02x\r\n", txBuf[0], txBuf[1], txBuf[2], txBuf[3], txBuf[4], txBuf[5], txBuf[6], txBuf[7]);
spi.write((char*)txBuf, 8, (char*)0, 0);
}
}
int main() {
+ set_time(0);
setupTx();
thread_txRF.start(txData);
@@ -68,6 +78,38 @@
printf("MAIN: started %u registered application threads\r\n", numRegisteredThreads);
while(1)
- wait(1024);
+ {/*
+ printf("\r\nRuntimeStats:");
+ printf("\r\n\tSystem uptime in s: %d", time(NULL));
+ printf("\r\nMemoryStats:");
+ mbed_stats_heap_get( &heap_info );
+ printf("\r\n\tBytes allocated currently: %d", heap_info.current_size);
+ printf("\r\n\tMax bytes allocated at a given time: %d", heap_info.max_size);
+ printf("\r\n\tCumulative sum of bytes ever allocated: %d", heap_info.total_size);
+ printf("\r\n\tCurrent number of bytes allocated for the heap: %d", heap_info.reserved_size);
+ printf("\r\n\tCurrent number of allocations: %d", heap_info.alloc_cnt);
+ printf("\r\n\tNumber of failed allocations: %d", heap_info.alloc_fail_cnt);
+
+ mbed_stats_stack_get( &stack_info[0] );
+ printf("\r\nCumulative Stack Info:");
+ printf("\r\n\tMaximum number of bytes used on the stack: %d", stack_info[0].max_size);
+ printf("\r\n\tCurrent number of bytes allocated for the stack: %d", stack_info[0].reserved_size);
+ printf("\r\n\tNumber of stacks stats accumulated in the structure: %d", stack_info[0].stack_cnt);
+
+ mbed_stats_stack_get_each( stack_info, MAX_THREAD_INFO );
+ printf("\r\nThread Stack Info:");
+ for(int i=0;i < MAX_THREAD_INFO; i++)
+ {
+ if(stack_info[i].thread_id != 0)
+ {
+ printf("\r\n\tThread: %d", i);
+ printf("\r\n\t\tMaximum number of bytes used on the stack: %d", stack_info[i].max_size);
+ printf("\r\n\t\tCurrent number of bytes allocated for the stack: %d", stack_info[i].reserved_size);
+ printf("\r\n\t\tNumber of stacks stats accumulated in the structure: %d", stack_info[i].stack_cnt);
+ }
+ }
+ */
+ rtos::Thread::wait(60000);
+ }
}
\ No newline at end of file
diff -r bf699e054b34 -r d7ec6dc025b0 mbed_app.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_app.json Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,3 @@
+{
+ "macros": ["DEBUG_ISR_STACK_USAGE=1", "MBED_HEAP_STATS_ENABLED=1", "MBED_STACK_STATS_ENABLED=1"]
+}
\ No newline at end of file
diff -r bf699e054b34 -r d7ec6dc025b0 sdLogger/sdLogger.cpp
--- a/sdLogger/sdLogger.cpp Sun Feb 25 16:40:28 2018 +0000
+++ b/sdLogger/sdLogger.cpp Fri Mar 30 10:32:10 2018 +0000
@@ -6,19 +6,20 @@
#include "SDBlockDevice.h"
#include "LittleFileSystem.h"
#include "FATFileSystem.h"
+#include "logger.h"
static void return_error(int ret_val){
if (ret_val)
printf("SD: Failure. %d\r\n", ret_val);
- else
- printf("SD: done.\r\n");
+ //else
+ //printf("SD: done.\r\n");
}
static void errno_error(void* ret_val){
if (ret_val == NULL)
printf("SD: Failure. %d \r\n", errno);
- else
- printf("SD: done.\r\n");
+ //else
+ //printf("SD: done.\r\n");
}
class SDLogger
{
@@ -26,9 +27,11 @@
static void run()
{
for (;;) {
- char buffer[200];
- sprintf(buffer, "Pressure: %4.1f \t Temperature: %3.2f\t Altitude: %4.1f\r\nACC1:%2.1f;%2.1f;%2.1f\r\nACC2:%2.1f;%2.1f;%2.1f\r\n", pressure, temperature, altitude, (acc1[0]), (acc1[1]), (acc1[2]),(acc2[0]), (acc2[1]), (acc2[2]));
- SD_appendData(buffer);
+ //char buffer[200];
+ //sprintf(buffer, "Pressure: %4.1f \t Temperature: %3.2f\t Altitude: %4.1f\r\nACC1:%2.1f;%2.1f;%2.1f\r\nACC2:%2.1f;%2.1f;%2.1f\r\n", pressure, temperature, altitude, (acc1[0]), (acc1[1]), (acc1[2]),(acc2[0]), (acc2[1]), (acc2[2]));
+ char* msg = (char*) Logger::q.get(osWaitForever).value.p;
+ SD_appendData(msg);
+ delete[] msg;
rtos::Thread::wait(6000);//10 datasets per minute. TODO: log current system time
}
}
@@ -57,19 +60,19 @@
fclose(fd);
printf("SD: done.\r\n");
}
-static void SD_appendData(char* data)
+static void SD_appendData(const char* data)
{
- printf("SD: Opening file data.txt.\r\n");
+ //printf("SD: Opening file data.txt.\r\n");
FILE* fd = fopen("/fs/data.txt", "w+");
errno_error(fd);
fprintf(fd, "%s", data);
- printf("SD: Writing done.\r\n");
+ //printf("SD: Writing done.\r\n");
- printf("SD: Closing file.\r\n");
+ //printf("SD: Closing file.\r\n");
fclose(fd);
- printf("SD: done.\r\n");
+ //printf("SD: done.\r\n");
}
static SDBlockDevice bd;//PinName mosi, PinName miso, PinName sclk, PinName cs
static FATFileSystem fs;
