From dd9f508339fdeb7a8161c965486d3ce07d948a2e Mon Sep 17 00:00:00 2001 From: psychogenic Date: Fri, 8 Jan 2016 13:01:52 -0500 Subject: [PATCH] SerialUI version 1.4.0 Changes: * 0-delay checkForUser() -- call can now be made with "0" timeout, and will return immediately with answer. * Library re-organization, for automated imports using Arduino IDE Library Manager. * Supported platforms now include SUI_PLATFORM_ARDUINOSTANDARD (most Arduino/Arduino-compatible) SUI_PLATFORM_ARDUINO_DUE (Due) SUI_PLATFORM_RBLNRF51822 (nRF51822-centered Arduino SDK, by RedBearLab, for things like the BLE Nano http://redbearlab.com/blenano/) Coming soon: v2, with new organization to allow some nifty new stuff, and support for an updated Druid4Arduino. --- INSTALL.txt | 51 ------ extras/INSTALL.txt | 36 ++++ LICENSE.txt => extras/LICENSE.txt | 0 includes/SUIPlat_DigiUSB.h | 157 ------------------ library.properties | 11 ++ SUIMenu.cpp => src/SUIMenu.cpp | 7 +- src/SUIPlat_ArduinoSerial.cpp | 21 +++ .../SUIPlat_DigiUSB.cpp | 2 +- .../SUIStateTracking.cpp | 0 src/SUIStreamDigi.cpp | 41 +++++ .../SUIStreamStandard.cpp | 57 +++++-- SerialUI.cpp => src/SerialUI.cpp | 28 ++-- SerialUI.h => src/SerialUI.h | 11 +- {includes => src/includes}/README.txt | 0 {includes => src/includes}/SUIConfig.h | 102 +++++++++--- {includes => src/includes}/SUIMenu.h | 0 {includes => src/includes}/SUIPlatform.h | 18 +- {includes => src/includes}/SUIStateTracking.h | 0 src/includes/SUIStream.h | 50 ++++++ {includes => src/includes}/SUIStrings.h | 0 {includes => src/includes}/SUIStrings_en.h | 0 {includes => src/includes}/SUIStrings_fr.h | 0 .../includes/platform/ArduinoSerial.h | 69 ++++---- src/includes/platform/Desktop.h | 80 +++++++++ src/includes/platform/DigiUSB.h | 97 +++++++++++ src/includes/platform/RBL_nRF51822.h | 87 ++++++++++ 26 files changed, 624 insertions(+), 301 deletions(-) delete mode 100644 INSTALL.txt create mode 100644 extras/INSTALL.txt rename LICENSE.txt => extras/LICENSE.txt (100%) delete mode 100644 includes/SUIPlat_DigiUSB.h create mode 100644 library.properties rename SUIMenu.cpp => src/SUIMenu.cpp (99%) create mode 100644 src/SUIPlat_ArduinoSerial.cpp rename SUIPlat_DigiUSB.cpp => src/SUIPlat_DigiUSB.cpp (97%) rename SUIStateTracking.cpp => src/SUIStateTracking.cpp (100%) create mode 100644 src/SUIStreamDigi.cpp rename SUIPlat_ArduinoSerial.cpp => src/SUIStreamStandard.cpp (76%) rename SerialUI.cpp => src/SerialUI.cpp (95%) rename SerialUI.h => src/SerialUI.h (97%) rename {includes => src/includes}/README.txt (100%) rename {includes => src/includes}/SUIConfig.h (84%) rename {includes => src/includes}/SUIMenu.h (100%) rename {includes => src/includes}/SUIPlatform.h (80%) rename {includes => src/includes}/SUIStateTracking.h (100%) create mode 100644 src/includes/SUIStream.h rename {includes => src/includes}/SUIStrings.h (100%) rename {includes => src/includes}/SUIStrings_en.h (100%) rename {includes => src/includes}/SUIStrings_fr.h (100%) rename includes/SUIPlat_ArduinoSerial.h => src/includes/platform/ArduinoSerial.h (75%) create mode 100644 src/includes/platform/Desktop.h create mode 100644 src/includes/platform/DigiUSB.h create mode 100644 src/includes/platform/RBL_nRF51822.h diff --git a/INSTALL.txt b/INSTALL.txt deleted file mode 100644 index e5ca3c1..0000000 --- a/INSTALL.txt +++ /dev/null @@ -1,51 +0,0 @@ -SerialUI Installation - - SerialUI: Serial User Interface. - Copyright (C) 2013,2014 Pat Deegan. All rights reserved. - http://www.flyingcarsandstuff.com/projects/SerialUI - - -If you're using the Arduino IDE and building for -Arduino, the installation procedure is the same -as for any library and is described fully at: - -http://arduino.cc/en/Guide/Libraries - -The short version is: plop the SerialUI directory -(folder) found within the zip file into your -Arduino libraries directory. - -The libraries directory location is system-dependent, -but will be something like: - - ~/sketchbook/libraries (Linux), - Documents/Arduino/libraries/ (mac), -or - My Documents\Arduino\libraries\ (windows) - - -Apparently, with newer version of the Arduino IDE, -you can import libraries from the IDE itself. I've -yet to try this version--see the link above for -details and let me know if it works. - -You'll need to restart the Arduino IDE before you -see SerialUI in the - File -> Examples -and - Sketch -> Import Library -listings. - -Do have a look at the - - File -> Examples -> SerialUI -> SuperBlinker - -example, the README.txt and/or the SerialUI.h header -file. - -For other platforms/dev environments, just include -the contents of the SerialUI directory wherever -appropriate ;-) - -Pat Deegan, psychogenic.com - diff --git a/extras/INSTALL.txt b/extras/INSTALL.txt new file mode 100644 index 0000000..7783366 --- /dev/null +++ b/extras/INSTALL.txt @@ -0,0 +1,36 @@ +SerialUI Installation + + SerialUI: Serial User Interface. + Copyright (C) 2013-2016 Pat Deegan. All rights reserved. + http://flyingcarsandstuff.com/projects/SerialUI/ + + +If you're using the Arduino IDE and building for +Arduino, the installation procedure is the same +as for any library and is described fully at: + +http://arduino.cc/en/Guide/Libraries + +The short version is: SerialUI now supports imports into +the set of libraries directly as a zip file. Simply +download the SerialUI-x.x.x.zip file and then, from +within the Arduino IDE, select + + Sketch -> Include Library -> Add .ZIP library + +and select the SerialUI file. + + +Do have a look at the + + File -> Examples -> SerialUI -> SuperBlinker + +example, the README.txt and/or the SerialUI.h header +file. + +For other platforms/dev environments, just include +the contents of the SerialUI directory wherever +appropriate ;-) + +Pat Deegan, psychogenic.com + diff --git a/LICENSE.txt b/extras/LICENSE.txt similarity index 100% rename from LICENSE.txt rename to extras/LICENSE.txt diff --git a/includes/SUIPlat_DigiUSB.h b/includes/SUIPlat_DigiUSB.h deleted file mode 100644 index 62397f5..0000000 --- a/includes/SUIPlat_DigiUSB.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * - * SUIPlat_DigiUSB.h -- SerialUI system platform-specifics. - * Copyright (C) 2013 Pat Deegan. All rights reserved. - * - * - * http://www.flyingcarsandstuff.com/projects/SerialUI - * - * - * This program library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See file LICENSE.txt for further informations on licensing - * terms. - * - * - * ************************* OVERVIEW ************************* - * - * Here we'll store all the platform-specific includes and structures. - * This is a version to be used with the Digistump Digispark and its - * DigiUSB serial line. - * - * NOTE: It is currently non-functional. A trivial examples compiles - * to just a few bytes too large, even with all the - * compile-time flags set using SUI_BUILD_FOR_DIGISPARK (in SUIConfig.h) - * and we don't have enough room for - * - */ - - -#ifndef SUIPlat_DigiUSB_h -#define SUIPlat_DigiUSB_h - - -// system/avr includes -#include -#include -#include -#include "Arduino.h" -#include - - - - -// SUI is the namespace in which we keep all our goodies. -namespace SUI { - -/* - * StreamImplementation -- wraps all the uses of Serial in a single place, - * to ease implementation of different types of comm. - * All you need are the following 7 methods to behave like Serial (HardwareSerial.h) - * methods and the rest should just work. - */ - -class StreamImplementation { - -public: - - static int peeked; - - static inline int available() { return DigiUSB.available();} - static int read() ; - static int peek(); - static void flush() ; - static inline size_t write(uint8_t i) { return DigiUSB.write(i); } - static inline void begin(unsigned long speed) { DigiUSB.begin(); } - - -}; - - -/* - * class SUIStream -- a streaming class based on Arduino Stream. - * - * In this case, we need to augment the default stream with some - * additional methods. - * - * For the moment, these are left as non-functional stubs. - */ - -#undef SUI_SUISTREAM_NEEDSVIRTUAL -class SUIStream : public Print -{ -public: - - // virtual ~SUIStream() {} - - // Non-working, required methods... (stubs) - // size_t readBytesUntil( char terminator, char *buffer, size_t length) { return 0;} - long parseInt(char skipChar=1) { return -1; } - - - unsigned long timeout() { return _timeout; } - void setTimeout(unsigned long timeout) { _timeout = timeout ; } - - /* - int timedRead() { - // straight from Arduino Stream, LGPLed - // Copyright (c) 2010 David A. Mellis. - int c; - _startMillis = millis(); - do { - c = StreamImplementation::read(); - if (c >= 0) - return c; - } while (millis() - _startMillis < _timeout); - return -1; // -1 indicates timeout - } - */ - - - - - virtual size_t write(uint8_t i) { return DigiUSB.write(i); } - -private: - unsigned long _startMillis; - unsigned long _timeout; - - /* DEADBEEF (tried to save space by avoiding deriving from Print - * and implementing these manually... even avoiding the String versions, - * WString and a bunch of other stuff gets included by DigiUSB so we don't - * save any space even by doing this: - - void printNumber(unsigned long a, uint8_t n){ DigiUSB.println(a, n); } - void printFloat(double a, uint8_t n){ DigiUSB.println(a, n); } - void print(const char str[]){ DigiUSB.print(str); } - void print(char a, int i = BYTE){ DigiUSB.print(a, i); } - void print(unsigned char a, int i= BYTE){ DigiUSB.print(a, i); } - void print(int a, int i= DEC){ DigiUSB.print(a, i); } - void print(unsigned int a, int i= DEC){ DigiUSB.print(a, i); } - void print(long a, int i= DEC){ DigiUSB.print(a, i); } - void print(unsigned long a, int i= DEC){ DigiUSB.print(a, i); } - void print(double a, int i = 2){ DigiUSB.print(a, i); } - void println(const char str[]){ DigiUSB.println(str); } - void println(char a, int i= BYTE){ DigiUSB.println(a, i); } - void println(unsigned char a, int i= BYTE){ DigiUSB.println(a, i); } - void println(int a, int i= DEC){ DigiUSB.println(a, i); } - void println(unsigned int a, int i= DEC){ DigiUSB.println(a, i); } - void println(long a, int i= DEC){ DigiUSB.println(a, i); } - void println(unsigned long a, int i= DEC){ DigiUSB.println(a, i); } - void println(double a, int i= 2){ DigiUSB.println(a, i); } - - */ -}; - -} /* end namespace SUI */ - - -#endif /* SUIPlat_DigiUSB_h */ diff --git a/library.properties b/library.properties new file mode 100644 index 0000000..b48d297 --- /dev/null +++ b/library.properties @@ -0,0 +1,11 @@ +name=SerialUI +version=1.14.0 +author=Pat Deegan +maintainer=Pat Deegan +sentence=A user interface through the serial channel (menus, sub-menus and command execution), with support for navigation through the menu hierarchy and online help. +paragraph=With SerialUI, you can create a hierarchy of menus and submenus of arbitrary depth (limited only by ROM/RAM space). Each menu contains a list of menu items, which are either sub-menus (lead you to another level of menu items) or commands (actually perform some type of action). Exactly what happens when a user issues a command is determined by your callbacks. +category=Communication +url=http://flyingcarsandstuff.com/projects/SerialUI/ +architectures=* + + diff --git a/SUIMenu.cpp b/src/SUIMenu.cpp similarity index 99% rename from SUIMenu.cpp rename to src/SUIMenu.cpp index 42f3198..ce466ad 100644 --- a/SUIMenu.cpp +++ b/src/SUIMenu.cpp @@ -946,9 +946,14 @@ void Menu::showName() { sui_driver->print_P(menu_name); } void Menu::pingRespond() { #ifdef SUI_ENABLE_STATE_TRACKER - sui_driver->showTrackedState(); + if (sui_driver->showTrackedState()) + { + return; + } #endif + sui_driver->println(' '); + diff --git a/src/SUIPlat_ArduinoSerial.cpp b/src/SUIPlat_ArduinoSerial.cpp new file mode 100644 index 0000000..0929f46 --- /dev/null +++ b/src/SUIPlat_ArduinoSerial.cpp @@ -0,0 +1,21 @@ +/* + * SUIPlat_Arduino.cpp + * + * Created on: 2013-12-13 + * Author: malcalypse + */ + + +#include "includes/SUIPlatform.h" + +#ifdef SUI_PLATFORM_ARDUINOSTANDARD +#include "includes/platform/ArduinoSerial.h" + +// SUI is the namespace in which we keep all our goodies. +namespace SUI { + + + + +} /* namespace SUI */ +#endif /* SUI_PLATFORM_ARDUINOSTANDARD */ diff --git a/SUIPlat_DigiUSB.cpp b/src/SUIPlat_DigiUSB.cpp similarity index 97% rename from SUIPlat_DigiUSB.cpp rename to src/SUIPlat_DigiUSB.cpp index 16740c7..665efab 100644 --- a/SUIPlat_DigiUSB.cpp +++ b/src/SUIPlat_DigiUSB.cpp @@ -32,7 +32,7 @@ #ifdef SUI_PLATFORM_DIGISPARKUSB // only include this stuff if we're actually using this platform... -#include "includes/SUIPlat_DigiUSB.h" +#include "includes/platform/DigiUSB.h" namespace SUI { int StreamImplementation::peeked = -1; diff --git a/SUIStateTracking.cpp b/src/SUIStateTracking.cpp similarity index 100% rename from SUIStateTracking.cpp rename to src/SUIStateTracking.cpp diff --git a/src/SUIStreamDigi.cpp b/src/SUIStreamDigi.cpp new file mode 100644 index 0000000..fd487c7 --- /dev/null +++ b/src/SUIStreamDigi.cpp @@ -0,0 +1,41 @@ +/* + * SUIStreamDigi.cpp + * + * Created on: Jan 7, 2016 + * Author: Pat Deegan + * Part of the SerialUI Project + * Copyright (C) 2015 Pat Deegan, http://psychogenic.com + */ + +#include "includes/SUIStream.h" + +#ifdef SUI_PLATFORM_DIGISPARKUSB + +namespace SUI { + + + +/* + * class SUIStream -- a streaming class based on Arduino Stream. + * + * In this case, we need to augment the default stream with some + * additional methods. + * + * For the moment, these are left as non-functional stubs. + */ + +// size_t readBytesUntil( char terminator, char *buffer, size_t length) { return 0;} +long SUIStream::parseInt(char skipChar=1) { return -1; } + + +unsigned long SUIStream::timeout() { return timeout_ms; } +void SUIStream::setTimeout(unsigned long timeout) { timeout_ms = timeout ; } + +size_t SUIStream::write(uint8_t i) { return DigiUSB.write(i); } + + + +} /* namespace SUI */ + +#endif /* SUI_PLATFORM_DIGISPARKUSB */ + diff --git a/SUIPlat_ArduinoSerial.cpp b/src/SUIStreamStandard.cpp similarity index 76% rename from SUIPlat_ArduinoSerial.cpp rename to src/SUIStreamStandard.cpp index a492bf3..4ed6ffa 100644 --- a/SUIPlat_ArduinoSerial.cpp +++ b/src/SUIStreamStandard.cpp @@ -1,23 +1,21 @@ /* - * SUIPlat_Arduino.cpp + * SUIStream.cpp * - * Created on: 2013-12-13 - * Author: malcalypse + * Created on: Jan 7, 2016 + * Author: Pat Deegan + * Part of the SerialUI Project + * Copyright (C) 2015 Pat Deegan, http://psychogenic.com */ -#include "includes/SUIConfig.h" +#include "includes/SUIStream.h" -#ifdef SUI_PLATFORM_ARDUINOSERIAL -#include "includes/SUIPlat_ArduinoSerial.h" - - - -// SUI is the namespace in which we keep all our goodies. +#ifdef SUI_BASEIMPLEMENTATION_STANDARD namespace SUI { + // default to using standard HardwareSerial as implementation stream to use. -StreamInstanceType * StreamImplementation::stream_to_use = &Serial; +StreamInstanceType * StreamImplementation::stream_to_use = &(SUI_PLATFORM_HARDWARESERIAL_DEFAULT); bool StreamImplementation::stream_to_use_override = false; void StreamImplementation::setStream(StreamInstanceType * strm) { @@ -30,16 +28,43 @@ void StreamImplementation::begin(unsigned long speed) { if (!stream_to_use_override) { - Serial.begin(speed); + // when overridden, it's your responsibility to + // begin()... here, there's no override used, + // so we make the call ourselves. + SUI_PLATFORM_HARDWARESERIAL_DEFAULT.begin(speed); } // we also set a sane timeout for reads, as this was causing issues // assuming code will call begin() prior to setTimeout() (if used) stream_to_use->setTimeout(SUI_SERIALUI_READBYTES_TIMEOUT_DEFAULT_MS); } -unsigned long SUIStream::timeout() { return timeout_ms; } -void SUIStream::setTimeout(unsigned long timeout) { timeout_ms = timeout ; Stream::setTimeout(timeout); } + + + + + + + + + + + + + + + #define NO_SKIP_CHAR 1 +size_t SUIStream::write(uint8_t i) +{ + return StreamImplementation::write(i); +} + +long SUIStream::parseInt(char skipChar) +{ + return SerialUIStreamBaseType::parseInt(skipChar); +} +unsigned long SUIStream::timeout() { return timeout_ms; } +void SUIStream::setTimeout(unsigned long timeout) { timeout_ms = timeout ; StreamInstanceType::setTimeout(timeout); } unsigned long SUIStream::parseULong() { @@ -132,6 +157,6 @@ int SUIStream::peekNextDigit(bool includeHex) return -1; } +} -} /* namespace SUI */ -#endif +#endif /* SUI_BASEIMPLEMENTATION_STANDARD */ diff --git a/SerialUI.cpp b/src/SerialUI.cpp similarity index 95% rename from SerialUI.cpp rename to src/SerialUI.cpp index a75430d..b354014 100644 --- a/SerialUI.cpp +++ b/src/SerialUI.cpp @@ -25,8 +25,7 @@ #include "SerialUI.h" -#define SUI_SERIALUI_USERCHECK_DELAY_MS 3 -#define SUI_SERIALUI_HANDLEREQ_DELAY_MS 5 +#define SUI_SERIALUI_HANDLEREQ_DELAY_MS 3 #ifdef SUI_INCLUDE_DEBUG // debug is ON, call the debug() method: @@ -213,14 +212,19 @@ bool SerialUI::checkForUserOnce(uint16_t timeout_ms) { bool SerialUI::checkForUser(uint16_t timeout_ms) { uint16_t ms_count = 0; - while (ms_count < timeout_ms) { + while (ms_count <= timeout_ms) { if (this->available() > 0) { user_present = true; return true; } - delay(SUI_SERIALUI_USERCHECK_DELAY_MS); - ms_count += SUI_SERIALUI_USERCHECK_DELAY_MS; + // nothing on serial line, as of yet + // if this was a "non-blocking" check, return immediately + if (! timeout_ms) + return false; + + delay(SUI_SERIALUI_USERCHECK_BLOCKFORINPUTDELAY_MS); + ms_count += SUI_SERIALUI_USERCHECK_BLOCKFORINPUTDELAY_MS; } return false; @@ -505,7 +509,7 @@ int8_t SerialUI::addStateTracking(PGM_P name, TrackedType type, void* var) } -void SerialUI::showTrackedState() +bool SerialUI::showTrackedState() { char outBuf[SUI_SERIALUI_PROGMEM_STRING_ABS_MAXLEN]; @@ -513,7 +517,7 @@ void SerialUI::showTrackedState() if (stateTrackedVarsNextAvailableSlot() == 0) { // nothing to show... - return; + return false; } @@ -541,7 +545,8 @@ void SerialUI::showTrackedState() outBuf[totlen++] = SUI_SERIALUI_PROG_STR_SEP_CHAR; outBuf[totlen] = '\0'; - double dval = 0; // Assumes 8-bit chars plus zero byte. + //double dval = 0; // Assumes 8-bit chars plus zero byte. + float dval = 0; // Assumes 8-bit chars plus zero byte. char *str = &numBuf[sizeof(numBuf) - 1]; switch (stateTrackedVars[idx]->type) @@ -573,7 +578,9 @@ void SerialUI::showTrackedState() totlen += sprintf(&(outBuf[totlen]), "%.2f", *(stateTrackedVars[idx]->ptr_float)); #else dval = *(stateTrackedVars[idx]->ptr_float); - totlen += strlen(dtostrf(dval, 5, 2, &(outBuf[totlen]))); + totlen += SUI_CONVERT_FLOAT_TO_STRING_AND_RETLEN(dval, &(outBuf[totlen])); + + // strlen(dtostrf(dval, 5, 2, &(outBuf[totlen]))); #endif break; @@ -592,11 +599,12 @@ void SerialUI::showTrackedState() println(outBuf); - return; + return (totlen > 0); } #endif + return false; } #endif diff --git a/SerialUI.h b/src/SerialUI.h similarity index 97% rename from SerialUI.h rename to src/SerialUI.h index a976c2a..e66848d 100644 --- a/SerialUI.h +++ b/src/SerialUI.h @@ -259,6 +259,7 @@ // SerialUI includes #include "includes/SUIConfig.h" +#include "includes/SUIStream.h" #include "includes/SUIStrings.h" #include "includes/SUIMenu.h" #include "includes/SUIPlatform.h" @@ -427,8 +428,12 @@ class SerialUI : public SUI::SUIStream * true, there is a user sending requests that need to be * handled (see handleRequests()) * - * TIMOUTMS is a timeout in ms. This call is blocking, for - * a maximum of TIMOUTMS ms. + * TIMOUTMS is a timeout in ms. If TIMEOUTMS is 0, the check + * will be performed and return immediately with an answer as to + * whether a user is present or not. + * + * With any positive value > 0, the call is blocking, for + * a maximum of TIMOUTMS ms (and a minimum of SUI_SERIALUI_USERCHECK_BLOCKFORINPUTDELAY_MS) * * Return boolean true if a user is present, false otherwise. * @@ -602,7 +607,7 @@ class SerialUI : public SUI::SUIStream int8_t trackState(PGM_P name, unsigned long * var) { return addStateTracking(name, SUITracked_UInt, (void*)var);} int8_t trackState(PGM_P name, float * var) { return addStateTracking(name, SUITracked_Float, (void*)var);} - void showTrackedState(); + bool showTrackedState(); #endif diff --git a/includes/README.txt b/src/includes/README.txt similarity index 100% rename from includes/README.txt rename to src/includes/README.txt diff --git a/includes/SUIConfig.h b/src/includes/SUIConfig.h similarity index 84% rename from includes/SUIConfig.h rename to src/includes/SUIConfig.h index aa5ff0d..76f5504 100644 --- a/includes/SUIConfig.h +++ b/src/includes/SUIConfig.h @@ -1,9 +1,9 @@ /* * * SUIConfig.h -- SerialUI compile time configuration. - * Copyright (C) 2013 Pat Deegan. All rights reserved. + * Copyright (C) 2013-2016 Pat Deegan. All rights reserved. * - * http://www.flyingcarsandstuff.com/projects/SerialUI + * http://www.flyingcarsandstuff.com/projects/SerialUI/ * * Please let me know if you use SerialUI in your projects, and * provide a URL if you'd like me to link to it from the SerialUI @@ -30,12 +30,51 @@ * * See below for available flags. */ -#ifndef SUIConfig_h -#define SUIConfig_h +#ifndef SERIAL_UI_CONFIGURATION_H_ +#define SERIAL_UI_CONFIGURATION_H_ + + +/* + * SUI_PLATFORM_X + * + * Define ONE OF the available SUI_PLATFORM_X values to select the serial + * implementation platform. + * + * SUI_PLATFORM_ARDUINOSTANDARD: regular Arduino/Arduino-compatible. + * Is the default and will usually just work(tm) + * + * SUI_PLATFORM_ARDUINO_DUE: What it says, Arduino Due. + * + * + * SUI_PLATFORM_RBLNRF51822: nRF51822-centered Arduino SDK, by + * RedBearLab, for things like the BLE Nano http://redbearlab.com/blenano/ + * + * + * SUI_PLATFORM_DIGISPARKUSB: DigiSpark, needs testing/work. + * + * NOTE: for SUI_PLATFORM_DIGISPARKUSB, I've had to add a + * #include + * at the top of my sketch to get it to compile at all... + */ +#define SUI_PLATFORM_ARDUINOSTANDARD +// #define SUI_PLATFORM_ARDUINO_DUE +// #define SUI_PLATFORM_RBLNRF51822 +// #define SUI_PLATFORM_DIGISPARKUSB + + + + + + #define SERIAL_UI_VERSION 1 -#define SERIAL_UI_SUBVERSION 13 +#define SERIAL_UI_SUBVERSION 14 +#define SERIAL_UI_PATCHLEVEL 0 + + + + /* *********************** DEFAULT VALUES *********************** */ @@ -297,28 +336,47 @@ #define SUI_STATE_TRACKER_MAX_VARIABLES 8 + /* - * SUI_PLATFORM_X - * - * Define ONE OF the available SUI_PLATFORM_X values to select the serial - * implementation platform. + * SUI_SERIALUI_USERCHECK_BLOCKFORINPUTDELAY_MS * - * Only SUI_PLATFORM_ARDUINOSERIAL working for now, SUI_PLATFORM_DIGISPARKUSB is - * a work in-progress for digistump Digispark USB serial comm... not sure - * I'll be able to get it usable in such a tight space (a whole - * 6k of flash available!!1!). + * Used when a call to checkForUser(TIMEOUTMS) is made with some + * positive TIMEOUTMS value. * - * NOTE: for SUI_PLATFORM_DIGISPARKUSB, I've had to add a - * #include - * at the top of my sketch to get it to compile at all... + * When TIMEOUTMS == 0, the call returns immediately with a boolean + * indicating presence of user. With TIMEOUTMS > 0, the check will + * simply: + * * either return true, if a user is around + * * wait for SUI_SERIALUI_USERCHECK_BLOCKFORINPUTDELAY_MS and check + * again, until we hit the TIMOUTMS total. */ -//#define SUI_PLATFORM_DIGISPARKUSB -#define SUI_PLATFORM_ARDUINOSERIAL +#define SUI_SERIALUI_USERCHECK_BLOCKFORINPUTDELAY_MS 1 + + + + + + + +// default "Serial" implementation to use +#define SUI_PLATFORM_HARDWARESERIAL_DEFAULT Serial + + + + + +// a bit of flag management, here, nothing to configure + +#ifdef SUI_PLATFORM_ARDUINO_DUE +// is actually just standard Arduino + +// the SUI_BUILD_FOR_DUE flag +#define SUI_PLATFORM_ARDUINOSTANDARD /* SUI_BUILD_FOR_DUE -* If you're building for a DUE, please uncomment this line: */ -//#define SUI_BUILD_FOR_DUE +#define SUI_BUILD_FOR_DUE + +#endif @@ -337,7 +395,7 @@ #undef SUI_MENU_ENABLE_SUBMENUS #undef SUI_ENABLE_MODES -#undef SUI_PLATFORM_ARDUINOSERIAL +#undef SUI_PLATFORM_ARDUINOSTANDARD #define SUI_PLATFORM_DIGISPARKUSB #endif @@ -359,4 +417,4 @@ (SERIAL_UI_VERSION > v)) -#endif /* SUIConfig_h */ +#endif /* SERIAL_UI_CONFIGURATION_H_ */ diff --git a/includes/SUIMenu.h b/src/includes/SUIMenu.h similarity index 100% rename from includes/SUIMenu.h rename to src/includes/SUIMenu.h diff --git a/includes/SUIPlatform.h b/src/includes/SUIPlatform.h similarity index 80% rename from includes/SUIPlatform.h rename to src/includes/SUIPlatform.h index 8580654..a3b8fc0 100644 --- a/includes/SUIPlatform.h +++ b/src/includes/SUIPlatform.h @@ -32,12 +32,24 @@ #include "SUIConfig.h" -#ifdef SUI_PLATFORM_ARDUINOSERIAL -#include "SUIPlat_ArduinoSerial.h" +#ifdef SUI_PLATFORM_ARDUINOSTANDARD +#include "platform/ArduinoSerial.h" #endif #ifdef SUI_PLATFORM_DIGISPARKUSB -#include "SUIPlat_DigiUSB.h" +#include "platform/DigiUSB.h" #endif + +#ifdef SUI_PLATFORM_RBLNRF51822 +#include "platform/RBL_nRF51822.h" +#endif + +#ifdef PLATFORM_DESKTOP + +#include "platform/Desktop.h" + +#endif + + #endif /* SUIPlatform_H */ diff --git a/includes/SUIStateTracking.h b/src/includes/SUIStateTracking.h similarity index 100% rename from includes/SUIStateTracking.h rename to src/includes/SUIStateTracking.h diff --git a/src/includes/SUIStream.h b/src/includes/SUIStream.h new file mode 100644 index 0000000..ab95c25 --- /dev/null +++ b/src/includes/SUIStream.h @@ -0,0 +1,50 @@ +/* + * SUIStream.h + * + * Created on: Jan 7, 2016 + * Author: Pat Deegan + * Part of the SerialUI Project + * Copyright (C) 2015 Pat Deegan, http://psychogenic.com + */ + +#ifndef SERIALUI_SRC_INCLUDES_SUISTREAM_H_ +#define SERIALUI_SRC_INCLUDES_SUISTREAM_H_ + +#include "SUIPlatform.h" + + +namespace SUI { + +class SUIStream : public SerialUIStreamBaseType +{ +public: +#ifdef SUI_SUISTREAM_NEEDSVIRTUAL + virtual ~SUIStream() {} +#endif + + unsigned long timeout(); + void setTimeout(unsigned long timeout); + + // parseULong -- gives us access to large valued ints (unsigned) + unsigned long parseULong(char skipChar); + unsigned long parseULong(); + + // parseInHex -- allows us to parse hex ints like 3e and F3D9 + unsigned long parseIntHex(); + unsigned long parseIntHex(char skipChar); + + virtual size_t write(uint8_t i); + virtual long parseInt(char skipChar=1); +private: + int timedPeek(); + + int peekNextDigit(bool includeHex=false); + unsigned long timeout_ms; +}; + + +} + + + +#endif /* SERIALUI_SRC_INCLUDES_SUISTREAM_H_ */ diff --git a/includes/SUIStrings.h b/src/includes/SUIStrings.h similarity index 100% rename from includes/SUIStrings.h rename to src/includes/SUIStrings.h diff --git a/includes/SUIStrings_en.h b/src/includes/SUIStrings_en.h similarity index 100% rename from includes/SUIStrings_en.h rename to src/includes/SUIStrings_en.h diff --git a/includes/SUIStrings_fr.h b/src/includes/SUIStrings_fr.h similarity index 100% rename from includes/SUIStrings_fr.h rename to src/includes/SUIStrings_fr.h diff --git a/includes/SUIPlat_ArduinoSerial.h b/src/includes/platform/ArduinoSerial.h similarity index 75% rename from includes/SUIPlat_ArduinoSerial.h rename to src/includes/platform/ArduinoSerial.h index 7359153..a685588 100644 --- a/includes/SUIPlat_ArduinoSerial.h +++ b/src/includes/platform/ArduinoSerial.h @@ -27,8 +27,13 @@ * */ -#ifndef SUIPlat_ArduinoSerial_h -#define SUIPlat_ArduinoSerial_h +#ifndef SERIALUI_SRC_INCLUDES_SUIPLAT_ARDUINOSERIAL_H_ +#define SERIALUI_SRC_INCLUDES_SUIPLAT_ARDUINOSERIAL_H_ + +#include "../SUIConfig.h" + + +#ifdef SUI_PLATFORM_ARDUINOSTANDARD // system/avr includes @@ -39,14 +44,13 @@ #else -#include -#include "Arduino.h" +#ifdef SUI_BUILD_FOR_DUE + // For Due, it seems all the *_P() functions // are simply defined as their regular equivalents, but // there's no strncpy_P and strncmp_P defined, so we // create aliases in that case: -#ifdef SUI_BUILD_FOR_DUE #ifndef strncpy_P #define strncpy_P(to, from, s) strncpy(to, from, s) #endif @@ -54,14 +58,35 @@ #ifndef strncmp_P #define strncmp_P(a, b, s) strncmp(a,b,s) #endif + +#define SUI_CONVERT_FLOAT_TO_STRING_AND_RETLEN(fl, intoptr) sprintf(intoptr, "%.2f", fl); + +#else +#define SUI_CONVERT_FLOAT_TO_STRING_AND_RETLEN(fl, intoptr) SUI::_ard_float2str_and_len(fl, intoptr) #endif +#include +#include "Arduino.h" + + #endif // SUI is the namespace in which we keep all our goodies. namespace SUI { +#ifndef SUI_PLATFORM_ARDUINO_DUE +inline size_t _ard_float2str_and_len(double fl, char * intoptr) { + return strlen(dtostrf(fl, 5, 2, intoptr)); + } +#endif + +typedef Stream SerialUIStreamBaseType; + +// used the standard base implementation of the SUIStream +#define SUI_BASEIMPLEMENTATION_STANDARD +#define SUI_SUISTREAM_NEEDSVIRTUAL + typedef Stream StreamInstanceType; @@ -89,40 +114,10 @@ class StreamImplementation { }; -/* - * class SUIStream -- a streaming class based on Arduino Stream. - * - * In this case, there's nothing to do--we can use Stream as-is so - * we just derive a class from Stream and leave it empty. - */ - - -#define SUI_SUISTREAM_NEEDSVIRTUAL -class SUIStream : public Stream -{ -public: - // nothing to do - virtual ~SUIStream() {} - - unsigned long timeout(); - void setTimeout(unsigned long timeout); - - // parseULong -- gives us access to large valued ints (unsigned) - unsigned long parseULong(char skipChar); - unsigned long parseULong(); - // parseInHex -- allows us to parse hex ints like 3e and F3D9 - unsigned long parseIntHex(); - unsigned long parseIntHex(char skipChar); - -private: - int timedPeek(); - - int peekNextDigit(bool includeHex=false); - unsigned long timeout_ms; -}; } /* end namespace SUI */ +#endif /* SUI_PLATFORM_ARDUINOSTANDARD */ -#endif /* SUIPlat_ArduinoSerial_h */ +#endif /* SERIALUI_SRC_INCLUDES_SUIPLAT_ARDUINOSERIAL_H_ */ diff --git a/src/includes/platform/Desktop.h b/src/includes/platform/Desktop.h new file mode 100644 index 0000000..0ab3390 --- /dev/null +++ b/src/includes/platform/Desktop.h @@ -0,0 +1,80 @@ +/* + * Desktop.h + * + * Created on: Jan 7, 2016 + * Author: Pat Deegan + * Part of the SerialUI Project + * Copyright (C) 2015 Pat Deegan, http://psychogenic.com + */ + +#ifndef SERIALUI_SRC_INCLUDES_PLATFORM_DESKTOP_H_ +#define SERIALUI_SRC_INCLUDES_PLATFORM_DESKTOP_H_ + +#include "../SUIConfig.h" + +#ifdef PLATFORM_DESKTOP + +#define PGM_P const char * + +#define SUI_CONVERT_FLOAT_TO_STRING_AND_RETLEN(fl, intoptr) 0 + + + + + +// SUI is the namespace in which we keep all our goodies. +namespace SUI { + + +class DummyStream { +public: + DummyStream() {} + virtual ~DummyStream() {} + virtual int available() { return 0;} + virtual int read() { return 0; } + virtual int peek() { return 0; } + virtual void flush() { } + virtual size_t write(uint8_t i) { return 1;} + virtual void begin(unsigned long speed) {} +}; +typedef DummyStream SerialUIStreamBaseType; + +// used the standard base implementation of the SUIStream +#define SUI_BASEIMPLEMENTATION_STANDARD +#define SUI_SUISTREAM_NEEDSVIRTUAL + +typedef DummyStream StreamInstanceType; + + +/* + * StreamImplementation -- wraps all the uses of Serial in a single place, + * to ease implementation of different types of comm. + * All you need are the following 7 methods to behave like Serial (HardwareSerial.h) + * methods and the rest should just work. + */ +class StreamImplementation { + +public: + static void setStream(StreamInstanceType * strm); + static inline int available() { return stream_to_use->available();} + static inline int read() { return stream_to_use->read(); } + static inline int peek() { return stream_to_use->peek(); } + static inline void flush() { stream_to_use->flush(); } + static inline size_t write(uint8_t i) { return stream_to_use->write(i); } + static void begin(unsigned long speed) ; + +private: + static StreamInstanceType * stream_to_use; + static bool stream_to_use_override; + + +}; + + + +} /* end namespace SUI */ + +#endif + + +#endif /* SERIALUI_SRC_INCLUDES_PLATFORM_DESKTOP_H_ */ diff --git a/src/includes/platform/DigiUSB.h b/src/includes/platform/DigiUSB.h new file mode 100644 index 0000000..61a33b3 --- /dev/null +++ b/src/includes/platform/DigiUSB.h @@ -0,0 +1,97 @@ +/* + * + * SUIPlat_DigiUSB.h -- SerialUI system platform-specifics. + * Copyright (C) 2013 Pat Deegan. All rights reserved. + * + * + * http://www.flyingcarsandstuff.com/projects/SerialUI + * + * + * This program library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See file LICENSE.txt for further informations on licensing + * terms. + * + * + * ************************* OVERVIEW ************************* + * + * Here we'll store all the platform-specific includes and structures. + * This is a version to be used with the Digistump Digispark and its + * DigiUSB serial line. + * + * NOTE: It is currently non-functional. A trivial examples compiles + * to just a few bytes too large, even with all the + * compile-time flags set using SUI_BUILD_FOR_DIGISPARK (in SUIConfig.h) + * and we don't have enough room for + * + */ + + +#ifndef SUIPlat_DigiUSB_h +#define SUIPlat_DigiUSB_h + +#include "SUIConfig.h" + +#ifdef SUI_PLATFORM_DIGISPARKUSB + + +// system/avr includes +#include +#include +#include +#include "Arduino.h" +#include + + + + +// SUI is the namespace in which we keep all our goodies. +namespace SUI { + + +// need a custom base implementation of the SUIStream +#define SUI_BASEIMPLEMENTATION_CUSTOM_DIGI +typedef Print SerialUIStreamBaseType; + +inline size_t _ard_float2str_and_len(double fl, char * intoptr) { + return strlen(dtostrf(fl, 5, 2, intoptr)); + } + +/* + * StreamImplementation -- wraps all the uses of Serial in a single place, + * to ease implementation of different types of comm. + * All you need are the following 7 methods to behave like Serial (HardwareSerial.h) + * methods and the rest should just work. + */ + +class StreamImplementation { + +public: + + static int peeked; + + static inline int available() { return DigiUSB.available();} + static int read() ; + static int peek(); + static void flush() ; + static inline size_t write(uint8_t i) { return DigiUSB.write(i); } + static inline void begin(unsigned long speed) { DigiUSB.begin(); } + + +}; + + + +} /* end namespace SUI */ + + +#endif /* SUI_PLATFORM_DIGISPARKUSB */ +#endif /* SUIPlat_DigiUSB_h */ diff --git a/src/includes/platform/RBL_nRF51822.h b/src/includes/platform/RBL_nRF51822.h new file mode 100644 index 0000000..3e17bc0 --- /dev/null +++ b/src/includes/platform/RBL_nRF51822.h @@ -0,0 +1,87 @@ +/* + * SUIPlat_nRF51822.h + * + * Created on: Jan 7, 2016 + * Author: Pat Deegan + * Part of the SerialUI Project + * Copyright (C) 2015 Pat Deegan, http://psychogenic.com + */ + +#ifndef SERIALUI_SRC_INCLUDES_SUIPLAT_NRF51822_H_ +#define SERIALUI_SRC_INCLUDES_SUIPLAT_NRF51822_H_ + +#include "../SUIConfig.h" + +#ifdef SUI_PLATFORM_RBLNRF51822 + +// system/avr includes +#include + + +#define SUI_CONVERT_FLOAT_TO_STRING_AND_RETLEN(fl, intoptr) sprintf(intoptr, "%.2f", fl) + + +#ifndef PLATFORM_DESKTOP +#include +#include "Arduino.h" + + + +// Seems all the *_P() functions +// are simply defined as their regular equivalents, but +// there's no strncpy_P and strncmp_P defined, so we +// create aliases in that case: +#ifndef strncpy_P +#define strncpy_P(to, from, s) strncpy(to, from, s) +#endif + +#ifndef strncmp_P +#define strncmp_P(a, b, s) strncmp(a,b,s) +#endif + + +#endif + + +// SUI is the namespace in which we keep all our goodies. +namespace SUI { + +// used the standard base implementation of the SUIStream +#define SUI_BASEIMPLEMENTATION_STANDARD +#define SUI_SUISTREAM_NEEDSVIRTUAL +typedef WStream SerialUIStreamBaseType; +typedef WStream StreamInstanceType; + + +/* + * StreamImplementation -- wraps all the uses of Serial in a single place, + * to ease implementation of different types of comm. + * All you need are the following 7 methods to behave like Serial (HardwareSerial.h) + * methods and the rest should just work. + */ +class StreamImplementation { + +public: + static void setStream(StreamInstanceType * strm); + static inline int available() { return stream_to_use->available();} + static inline int read() { return stream_to_use->read(); } + static inline int peek() { return stream_to_use->peek(); } + static inline void flush() { stream_to_use->flush(); } + static inline size_t write(uint8_t i) { return stream_to_use->write(i); } + static void begin(unsigned long speed) ; + +private: + static StreamInstanceType * stream_to_use; + static bool stream_to_use_override; + + +}; + + + +} /* end namespace SUI */ + + +#endif /* SUI_PLATFORM_RBLNRF51822 */ + +#endif /* SERIALUI_SRC_INCLUDES_SUIPLAT_NRF51822_H_ */