Files
arduino-nano-opst/src/opst.cpp
Pascal Lais ecfbb6af04
All checks were successful
continuous-integration/drone/push Build is passing
Update 'src/opst.cpp'
2020-08-03 14:13:37 +02:00

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