Initial commit

This commit is contained in:
2020-08-02 19:14:24 +02:00
commit d7425b8053
12 changed files with 730 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

67
.travis.yml Normal file
View File

@@ -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

7
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
]
}

39
include/README Normal file
View File

@@ -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

85
include/opst.h Normal file
View File

@@ -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
//-----------------------------------------------------------------------------

43
include/sys.h Normal file
View File

@@ -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
//-----------------------------------------------------------------------------

46
lib/README Normal file
View File

@@ -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 <Foo.h>
#include <Bar.h>
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

14
platformio.ini Normal file
View File

@@ -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

87
src/main.cpp Normal file
View File

@@ -0,0 +1,87 @@
/**
* @file main.cpp
* @author Pascal Lais (pascal_lais@gmx.de)
*
* @version 0.1
* @date 2020-08-02
*/
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <Arduino.h>
#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
//-----------------------------------------------------------------------------

223
src/opst.cpp Normal file
View File

@@ -0,0 +1,223 @@
/**
* @file opst.cpp
*
* @author Pascal Lais (pascal_lais@gmx.de)
*
* @version 0.1
* @date 2020-08-02
*/
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <Arduino.h>
#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
//-----------------------------------------------------------------------------

103
src/sys.cpp Normal file
View File

@@ -0,0 +1,103 @@
/**
* @file sys.cpp
* @author Pascal Lais (pascal_lais@gmx.de)
*
* @version 0.1
* @date 2020-08-02
*/
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <Arduino.h>
#include <pins_arduino.h>
#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
//-----------------------------------------------------------------------------

11
test/README Normal file
View File

@@ -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