commit d7425b8053bfcf0b6336afdd47e90111b9f58dbd Author: Pascal Lais Date: Sun Aug 2 19:14:24 2020 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..7c486f1 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,67 @@ +# Continuous Integration (CI) is the practice, in software +# engineering, of merging all developer working copies with a shared mainline +# several times a day < https://docs.platformio.org/page/ci/index.html > +# +# Documentation: +# +# * Travis CI Embedded Builds with PlatformIO +# < https://docs.travis-ci.com/user/integration/platformio/ > +# +# * PlatformIO integration with Travis CI +# < https://docs.platformio.org/page/ci/travis.html > +# +# * User Guide for `platformio ci` command +# < https://docs.platformio.org/page/userguide/cmd_ci.html > +# +# +# Please choose one of the following templates (proposed below) and uncomment +# it (remove "# " before each line) or use own configuration according to the +# Travis CI documentation (see above). +# + + +# +# Template #1: General project. Test it using existing `platformio.ini`. +# + +# language: python +# python: +# - "2.7" +# +# sudo: false +# cache: +# directories: +# - "~/.platformio" +# +# install: +# - pip install -U platformio +# - platformio update +# +# script: +# - platformio run + + +# +# Template #2: The project is intended to be used as a library with examples. +# + +# language: python +# python: +# - "2.7" +# +# sudo: false +# cache: +# directories: +# - "~/.platformio" +# +# env: +# - PLATFORMIO_CI_SRC=path/to/test/file.c +# - PLATFORMIO_CI_SRC=examples/file.ino +# - PLATFORMIO_CI_SRC=path/to/test/directory +# +# install: +# - pip install -U platformio +# - platformio update +# +# script: +# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..0f0d740 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ] +} diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/include/opst.h b/include/opst.h new file mode 100644 index 0000000..44a60b5 --- /dev/null +++ b/include/opst.h @@ -0,0 +1,85 @@ +/** + * @file opst.h + * @author Pascal Lais (pascal_lais@gmx.de) + * + * @version 0.1 + * @date 2020-08-02 + */ + +#ifndef OPST_H_INCLUDED +#define OPST_H_INCLUDED + +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Datatypes +//----------------------------------------------------------------------------- + +typedef enum eagOpstState +{ + OPST_STATE_NONE, + OPST_STATE_REPORT_TEMP, + OPST_STATE_REPORT_PRESSURE, + OPST_STATE_TEMP_FAULT, + OPST_STATE_PRESSURE_FAULT, + OPST_STATE_HARDWARE_FAULT, +}eOpstState; + +//----------------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Function prototypes +//----------------------------------------------------------------------------- + +/** + * Init opst handling + * + * @param pin The pin that connects to the output pin of the sensor. Only pin 2 or 3 can be used here. + */ +void opstInit(uint8_t pin); + +/** + * OPS+T sensor pwm data handling. Call this in the loop function. + */ +void opstUpdate(); + +/** + * Get the current state of the sensor. + * + * @return One of eOpstState + */ +uint32_t opstGetState(); + +/** + * Get the temperature value. + * + * @return Temperature vale in 0.1 °C steps (ie 274 for 27.4 °C) + */ +int32_t opstGetTemp(); + +/** + * Get the pressure value + * + * @return Pressure in millibar + */ +int32_t opstGetPressure(); + +/** + * Check fifo for overruns. If overrun was detected increase fifo size. + * + * @return True if fifo overrun was detected at any time. + */ +bool opstFiFoOverrunDetected(); + +#endif //OPST_H_INCLUDED +//----------------------------------------------------------------------------- +// EOF +//----------------------------------------------------------------------------- diff --git a/include/sys.h b/include/sys.h new file mode 100644 index 0000000..2c2de1e --- /dev/null +++ b/include/sys.h @@ -0,0 +1,43 @@ +/** + * @file sys.h + * @author Pascal Lais (pascal_lais@gmx.de) + * + * @version 0.1 + * @date 2020-08-02 + */ + +#ifndef SYS_H_INCLUDED +#define SYS_H_INCLUDED + +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Datatypes +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Function prototypes +//----------------------------------------------------------------------------- + +void sysInit(); +void sysLoop(uint32_t ts); +void sysLoop10ms(uint32_t ts); +void sysLoop50ms(uint32_t ts); +void sysLoop100ms(uint32_t ts); +void sysLoop500ms(uint32_t ts); +void sysLoop1000ms(uint32_t ts); + +#endif //SYS_H_INCLUDED +//----------------------------------------------------------------------------- +// EOF +//----------------------------------------------------------------------------- diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..96febe7 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,14 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nanoatmega328] +platform = atmelavr +board = nanoatmega328 +framework = arduino diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..2b794bd --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,87 @@ +/** + * @file main.cpp + * @author Pascal Lais (pascal_lais@gmx.de) + * + * @version 0.1 + * @date 2020-08-02 + */ + +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- + +#include + +#include "sys.h" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Datatypes +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Function prototypes +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Function implementation +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +void setup() +//----------------------------------------------------------------------------- +{ + sysInit(); +} + +//----------------------------------------------------------------------------- +void loop() +//----------------------------------------------------------------------------- +{ + static uint32_t ts10ms = 0; + static uint32_t ts50ms = 0; + static uint32_t ts100ms = 0; + static uint32_t ts500ms = 0; + static uint32_t ts1000ms = 0; + + uint32_t ts = millis(); + + sysLoop(ts); + + if(10 < (ts - ts10ms)) + { + ts10ms = ts; + sysLoop10ms(ts); + } + if(50 < (ts - ts50ms)) + { + ts50ms = ts; + sysLoop50ms(ts); + } + if(100 < (ts - ts100ms)) + { + ts100ms = ts; + sysLoop100ms(ts); + } + if(500 < (ts - ts500ms)) + { + ts500ms = ts; + sysLoop500ms(ts); + } + if(1000 < (ts - ts1000ms)) + { + ts1000ms = ts; + sysLoop1000ms(ts); + } +} + +//----------------------------------------------------------------------------- +// EOF +//----------------------------------------------------------------------------- diff --git a/src/opst.cpp b/src/opst.cpp new file mode 100644 index 0000000..c3ec669 --- /dev/null +++ b/src/opst.cpp @@ -0,0 +1,223 @@ +/** + * @file opst.cpp + * + * @author Pascal Lais (pascal_lais@gmx.de) + * + * @version 0.1 + * @date 2020-08-02 + */ + +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- + +#include + +#include "opst.h" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +#define OPST_FIFO_SIZE 32 + +//----------------------------------------------------------------------------- +// Datatypes +//----------------------------------------------------------------------------- +typedef struct tagPwmInPulse +{ + uint32_t mRising; + uint32_t mFalling; +}tPwmInPulse; + +typedef struct tagOpstInFiFo +{ + uint32_t mIn; + uint32_t mOut; + tPwmInPulse mData[OPST_FIFO_SIZE]; + bool mOverrun; +}tOpstFiFo; + +//----------------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------------- + +static uint8_t mOpstPin; +static volatile tOpstFiFo mOpstFiFo; + +static uint32_t mOpstState = OPST_STATE_NONE; +static int32_t mOpstTemp = 0; +static int32_t mOpstPressure = 0; + +//----------------------------------------------------------------------------- +// Function prototypes +//----------------------------------------------------------------------------- + +/** + * Interrupt service routine to handle a rising edge on pwm input + * + */ +void pwmInRisingEdgeISR(); + +/** + * Interrupt service routine to handle a falling edge on pwm input + * + */ +void pwmInFallingEdgeISR(); + +//----------------------------------------------------------------------------- +// Function implementation +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +void pwmInRisingEdgeISR() +//----------------------------------------------------------------------------- +{ + mOpstFiFo.mData[mOpstFiFo.mIn].mRising = micros(); + mOpstFiFo.mData[mOpstFiFo.mIn].mFalling = 0; + attachInterrupt(digitalPinToInterrupt(mOpstPin), pwmInFallingEdgeISR, FALLING); +} + +//----------------------------------------------------------------------------- +void pwmInFallingEdgeISR() +//----------------------------------------------------------------------------- +{ + mOpstFiFo.mData[mOpstFiFo.mIn].mFalling = micros(); + mOpstFiFo.mIn++; + + if(mOpstFiFo.mOut == mOpstFiFo.mIn) + { + mOpstFiFo.mOverrun = true; + } + if(OPST_FIFO_SIZE <= mOpstFiFo.mIn) + { + mOpstFiFo.mIn = 0; + } + attachInterrupt(digitalPinToInterrupt(mOpstPin), pwmInRisingEdgeISR, RISING); +} + +//----------------------------------------------------------------------------- +void opstInit(uint8_t pin) +//----------------------------------------------------------------------------- +{ + mOpstFiFo.mIn = 0; + mOpstFiFo.mOut = 0; + mOpstPin = pin; + pinMode(pin, INPUT_PULLUP); + attachInterrupt(digitalPinToInterrupt(mOpstPin), pwmInRisingEdgeISR, RISING); +} + +//----------------------------------------------------------------------------- +void opstUpdate() +//----------------------------------------------------------------------------- +{ + if(mOpstFiFo.mIn != mOpstFiFo.mOut) + { + uint32_t behind; // the number reported values that have not been processed + uint32_t in = mOpstFiFo.mIn; // We need to store the in counter in case interrupts occur during update and it gets changed inside the struct + + if(in > mOpstFiFo.mOut) + { + behind = in - mOpstFiFo.mOut; + } + else + { + behind = (OPST_FIFO_SIZE - mOpstFiFo.mOut) + in; + } + + while(behind > 1) // cannot process last pulse because we need the time between current and next rising edge + { + uint32_t nextOut; // index of following fifo entry + uint32_t pulseInterval = 0; // time between rising edge of current pulse and rising edge of following pulse + uint32_t pulseLen = 0; // time between rising edge of current pulse and falling edge of current pulse + + if(OPST_FIFO_SIZE > (mOpstFiFo.mOut + 1)) + { + nextOut = mOpstFiFo.mOut + 1; + } + else + { + nextOut = 0; + } + + pulseInterval = mOpstFiFo.mData[nextOut].mRising - mOpstFiFo.mData[mOpstFiFo.mOut].mRising; + pulseLen = mOpstFiFo.mData[mOpstFiFo.mOut].mFalling - mOpstFiFo.mData[mOpstFiFo.mOut].mRising; + + if(((1024 - 103) < pulseInterval) && + ((1024 + 103) > pulseInterval)) // +-10% Tolerance + { + // S1 + pulseLen = pulseLen * 1024 / pulseInterval; // pulse length is relative to interval length + if(((256 - 25) < pulseLen) && ((256 + 25) > pulseLen)) + { + mOpstState = OPST_STATE_REPORT_TEMP; + } + else if(((384 - 25) < pulseLen) && ((384 + 25) > pulseLen)) + { + mOpstState = OPST_STATE_TEMP_FAULT; + } + else if(((512 - 25) < pulseLen) && ((512 + 25) > pulseLen)) + { + mOpstState = OPST_STATE_PRESSURE_FAULT; + } + else if(((640 - 25) < pulseLen) && ((640 + 25) > pulseLen)) + { + mOpstState = OPST_STATE_HARDWARE_FAULT; + } + } + else if(((4096 - 410) < pulseInterval) && + ((4096 + 410) > pulseInterval)) // +-10% Tolerance + { + if(OPST_STATE_REPORT_TEMP == mOpstState) + { + // T1 + pulseLen = pulseLen * 4096 / pulseInterval; // pulse length is relative to interval length + mOpstTemp = (((pulseLen) - 128) * 10 / 19.2) - 400; + mOpstState = OPST_STATE_REPORT_PRESSURE; //Next pulse is pressure + } + else if(OPST_STATE_REPORT_PRESSURE == mOpstState) + { + // T2 + pulseLen = pulseLen * 4096 / pulseInterval; //pulse length is relative to interval length + mOpstPressure = ((pulseLen - 128) * 1000 / 384) + 500; + mOpstState = OPST_STATE_NONE; + } + } + + mOpstFiFo.mOut = nextOut; + behind--; + } + } +} + +//----------------------------------------------------------------------------- +uint32_t opstGetState() +//----------------------------------------------------------------------------- +{ + return mOpstState; +} + +//----------------------------------------------------------------------------- +int32_t opstGetTemp() +//----------------------------------------------------------------------------- +{ + return mOpstTemp; +} + +//----------------------------------------------------------------------------- +int32_t opstGetPressure() +//----------------------------------------------------------------------------- +{ + return mOpstPressure; +} + +//----------------------------------------------------------------------------- +bool opstFiFoOverrunDetected() +//----------------------------------------------------------------------------- +{ + return mOpstFiFo.mOverrun; +} + +//----------------------------------------------------------------------------- +// EOF +//----------------------------------------------------------------------------- diff --git a/src/sys.cpp b/src/sys.cpp new file mode 100644 index 0000000..e515857 --- /dev/null +++ b/src/sys.cpp @@ -0,0 +1,103 @@ +/** + * @file sys.cpp + * @author Pascal Lais (pascal_lais@gmx.de) + * + * @version 0.1 + * @date 2020-08-02 + */ + +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- + +#include +#include + +#include "opst.h" +#include "sys.h" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +#define OPST_PIN 2 //Either Pin 2 or Pin 3 can be used + +//----------------------------------------------------------------------------- +// Datatypes +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Function prototypes +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Function implementation +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +void sysInit() +//----------------------------------------------------------------------------- +{ + Serial.begin(9600); + pinMode(LED_BUILTIN, OUTPUT); + opstInit(OPST_PIN); +} + +//----------------------------------------------------------------------------- +void sysLoop(uint32_t ts) +//----------------------------------------------------------------------------- +{ + opstUpdate(); +} + +//----------------------------------------------------------------------------- +void sysLoop10ms(uint32_t ts) +//----------------------------------------------------------------------------- +{ + +} + +//----------------------------------------------------------------------------- +void sysLoop50ms(uint32_t ts) +//----------------------------------------------------------------------------- +{ + digitalWrite(LED_BUILTIN, 1); +} + +//----------------------------------------------------------------------------- +void sysLoop100ms(uint32_t ts) +//----------------------------------------------------------------------------- +{ + +} + +//----------------------------------------------------------------------------- +void sysLoop500ms(uint32_t ts) +//----------------------------------------------------------------------------- +{ + +} + +//----------------------------------------------------------------------------- +void sysLoop1000ms(uint32_t ts) +//----------------------------------------------------------------------------- +{ + digitalWrite(LED_BUILTIN, 0); + if(opstFiFoOverrunDetected()) + { + Serial.print("Overrun detected!\n"); + } + Serial.print("Temp: "); + Serial.print(opstGetTemp()); + Serial.print(", Pressure: "); + Serial.print(opstGetPressure()); + Serial.print("\n"); +} + +//----------------------------------------------------------------------------- +// EOF +//----------------------------------------------------------------------------- diff --git a/test/README b/test/README new file mode 100644 index 0000000..df5066e --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html