All checks were successful
continuous-integration/drone/push Build is passing
215 lines
7.3 KiB
C++
215 lines
7.3 KiB
C++
/**
|
|
* @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++;
|
|
mOpstFiFo.mIn %= OPST_FIFO_SIZE;
|
|
|
|
if(mOpstFiFo.mOut == mOpstFiFo.mIn)
|
|
{
|
|
mOpstFiFo.mOverrun = true;
|
|
}
|
|
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
|
|
|
|
nextOut = mOpstFiFo.mOut + 1;
|
|
nextOut %= OPST_FIFO_SIZE;
|
|
|
|
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
|
|
//-----------------------------------------------------------------------------
|