Edge detection

This commit is contained in:
Chris Esposito 2019-01-28 13:39:48 +11:00
parent 39524b4d04
commit 6773347739
5 changed files with 109 additions and 16 deletions

View File

@ -17,7 +17,6 @@ extern int TIMER_PERIOD;
extern int ISO_RECOVERY_TIME; extern int ISO_RECOVERY_TIME;
extern int MAX_WINDOW_SIZE; extern int MAX_WINDOW_SIZE;
extern int TICK_SEPARATION; extern int TICK_SEPARATION;
#define TRIGGER_COUNT_THRESH (7 + std::max<int>(0, log10(window))) //Is this the right number?
//Multimeter settings //Multimeter settings
extern int MULTIMETER_PERIOD; extern int MULTIMETER_PERIOD;

View File

@ -23,6 +23,7 @@ namespace
#endif #endif
constexpr auto kTopMultimeter = 2048; constexpr auto kTopMultimeter = 2048;
constexpr double kTriggerSensitivityMultiplier = 4;
} }
isoBuffer::isoBuffer(QWidget* parent, int bufferLen, isoDriver* caller, unsigned char channel_value) isoBuffer::isoBuffer(QWidget* parent, int bufferLen, isoDriver* caller, unsigned char channel_value)
@ -53,12 +54,14 @@ void isoBuffer::insertIntoBuffer(short item)
{ {
m_back = 0; m_back = 0;
} }
checkTriggered();
} }
short isoBuffer::bufferAt(int idx) const short isoBuffer::bufferAt(int idx) const
{ {
// NOTE: this is only correct if idx < m_insertedCount // NOTE: this is only correct if idx < m_insertedCount
return m_buffer[m_back + (m_bufferEnd+1) - idx]; return m_buffer[(m_back-1) + (m_bufferEnd+1) - idx];
} }
void isoBuffer::outputSampleToFile(double averageSample) void isoBuffer::outputSampleToFile(double averageSample)
@ -336,3 +339,35 @@ void isoBuffer::serialManage(double baudRate, UartParity parity)
m_decoder->serialDecode(baudRate); m_decoder->serialDecode(baudRate);
} }
void isoBuffer::setTriggerType(TriggerType newType)
{
qDebug() << "Trigger Type: " << (uint8_t)newType;
m_triggerType = newType;
}
void isoBuffer::setTriggerLevel(double voltageLevel, uint16_t top, bool acCoupled)
{
m_triggerLevel = inverseSampleConvert(voltageLevel, top, acCoupled);
m_triggerSensitivity = static_cast<short>(1 + abs(voltageLevel * kTriggerSensitivityMultiplier * static_cast<double>(top) / 128.));
qDebug() << "Trigger Level: " << m_triggerLevel;
qDebug() << "Trigger sensitivity:" << m_triggerSensitivity;
}
// TODO: Clear trigger
// FIXME: AC changes will not be reflected here
void isoBuffer::checkTriggered()
{
if (m_triggerType == TriggerType::Disabled)
return;
if ((bufferAt(0) >= (m_triggerLevel + m_triggerSensitivity)) && (m_triggerSeekState == TriggerSeekState::BelowTriggerLevel))
{
// Rising Edge
m_triggerSeekState = TriggerSeekState::AboveTriggerLevel;
}
else if ((bufferAt(0) < (m_triggerLevel - m_triggerSensitivity)) && (m_triggerSeekState == TriggerSeekState::AboveTriggerLevel))
{
// Falling Edge
m_triggerSeekState = TriggerSeekState::BelowTriggerLevel;
}
}

View File

@ -21,6 +21,19 @@ class isoDriver;
class uartStyleDecoder; class uartStyleDecoder;
enum class UartParity : uint8_t; enum class UartParity : uint8_t;
enum class TriggerType : uint8_t
{
Disabled,
Rising,
Falling
};
enum class TriggerSeekState : uint8_t
{
BelowTriggerLevel,
AboveTriggerLevel
};
// isoBuffer is a generic class that enables O(1) read times (!!!) on all // isoBuffer is a generic class that enables O(1) read times (!!!) on all
// read/write operations, while maintaining a huge buffer size. // read/write operations, while maintaining a huge buffer size.
// Imagine it as a circular buffer, but with access functions specifically // Imagine it as a circular buffer, but with access functions specifically
@ -64,11 +77,14 @@ public:
private: private:
template<typename Function> template<typename Function>
int capSample(int offset, int target, double seconds, double value, Function comp); int capSample(int offset, int target, double seconds, double value, Function comp);
void checkTriggered();
public: public:
int cap_x0fromLast(double seconds, double vbot); int cap_x0fromLast(double seconds, double vbot);
int cap_x1fromLast(double seconds, int x0, double vbot); int cap_x1fromLast(double seconds, int x0, double vbot);
int cap_x2fromLast(double seconds, int x1, double vtop); int cap_x2fromLast(double seconds, int x1, double vtop);
void serialManage(double baudRate, UartParity parity); void serialManage(double baudRate, UartParity parity);
void setTriggerType(TriggerType newType);
void setTriggerLevel(double voltageLevel, uint16_t top, bool acCoupled);
// ---- MEMBER VARIABLES ---- // ---- MEMBER VARIABLES ----
@ -91,7 +107,11 @@ public:
double m_frontendGain = (R4 / (R3 + R4)); double m_frontendGain = (R4 / (R3 + R4));
int m_samplesPerSecond; int m_samplesPerSecond;
int m_sampleRate_bit; int m_sampleRate_bit;
TriggerType m_triggerType = TriggerType::Disabled;
TriggerSeekState m_triggerSeekState = TriggerSeekState::BelowTriggerLevel;
short m_triggerLevel = 0;
short m_triggerSensitivity = 0;
std::vector<uint32_t> m_triggerPositionList = {};
// UARTS decoding // UARTS decoding
uartStyleDecoder* m_decoder = NULL; uartStyleDecoder* m_decoder = NULL;
bool m_isDecoding = true; bool m_isDecoding = true;

View File

@ -624,20 +624,27 @@ short isoDriver::reverseFrontEnd(double voltage){
void isoDriver::setTriggerEnabled(bool enabled) void isoDriver::setTriggerEnabled(bool enabled)
{ {
triggerEnabled = enabled; triggerEnabled = enabled;
triggerStateChanged();
} }
void isoDriver::setTriggerLevel(double level) void isoDriver::setTriggerLevel(double level)
{ {
internalBuffer375_CH1->setTriggerLevel(level, 128, AC_CH1);
internalBuffer375_CH2->setTriggerLevel(level, 128, AC_CH2);
internalBuffer750->setTriggerLevel(level, 2048, AC_CH1);
triggerStateChanged();
} }
void isoDriver::setSingleShotEnabled(bool enabled) void isoDriver::setSingleShotEnabled(bool enabled)
{ {
singleShotEnabled = enabled; singleShotEnabled = enabled;
triggerStateChanged();
} }
void isoDriver::setTriggerMode(int newMode) void isoDriver::setTriggerMode(int newMode)
{ {
triggerMode = (TriggerType)newMode; triggerMode = newMode;
triggerStateChanged();
} }
void isoDriver::frameActionGeneric(char CH1_mode, char CH2_mode) //0 for off, 1 for ana, 2 for dig, -1 for ana750, -2 for file void isoDriver::frameActionGeneric(char CH1_mode, char CH2_mode) //0 for off, 1 for ana, 2 for dig, -1 for ana750, -2 for file
@ -1403,3 +1410,42 @@ void isoDriver::hideCH2(bool enable)
{ {
axes->graph(1)->setVisible(!enable); axes->graph(1)->setVisible(!enable);
} }
void isoDriver::triggerStateChanged()
{
qDebug() << "triggerStateChanged()";
switch(triggerMode)
{
case 0:
{
internalBuffer375_CH1->setTriggerType(TriggerType::Rising);
internalBuffer375_CH2->setTriggerType(TriggerType::Disabled);
internalBuffer750->setTriggerType(TriggerType::Rising);
break;
}
case 1:
{
internalBuffer375_CH1->setTriggerType(TriggerType::Falling);
internalBuffer375_CH2->setTriggerType(TriggerType::Disabled);
internalBuffer750->setTriggerType(TriggerType::Falling);
break;
}
case 2:
{
internalBuffer375_CH1->setTriggerType(TriggerType::Disabled);
internalBuffer375_CH2->setTriggerType(TriggerType::Rising);
internalBuffer750->setTriggerType(TriggerType::Disabled);
break;
}
case 3:
{
internalBuffer375_CH1->setTriggerType(TriggerType::Disabled);
internalBuffer375_CH2->setTriggerType(TriggerType::Falling);
internalBuffer750->setTriggerType(TriggerType::Disabled);
break;
}
}
}

View File

@ -56,14 +56,6 @@ public:
bool fileModeEnabled = false; bool fileModeEnabled = false;
double daq_maxWindowSize; double daq_maxWindowSize;
private: private:
enum class TriggerType : int
{
rising_ch1 = 0,
falling_ch1 = 1,
rising_ch2 = 2,
falling_ch2 = 3
};
//Those bloody bools that just Enable/Disable a single property //Those bloody bools that just Enable/Disable a single property
bool paused_CH1 = false, paused_CH2 = false, paused_multimeter = false; bool paused_CH1 = false, paused_CH2 = false, paused_multimeter = false;
bool autoGainEnabled = true; bool autoGainEnabled = true;
@ -99,6 +91,7 @@ private:
void multimeterAction(); void multimeterAction();
void broadcastStats(bool CH2); void broadcastStats(bool CH2);
void frameActionGeneric(char CH1_mode, char CH2_mode); void frameActionGeneric(char CH1_mode, char CH2_mode);
void triggerStateChanged();
//Variables that are just pointers to other classes/vars //Variables that are just pointers to other classes/vars
QCustomPlot *axes; QCustomPlot *axes;
std::unique_ptr<short[]> readData375_CH1; std::unique_ptr<short[]> readData375_CH1;
@ -110,11 +103,11 @@ private:
siprint *v0, *v1, *dv, *t0, *t1, *dt, *f; siprint *v0, *v1, *dv, *t0, *t1, *dt, *f;
//Scope/MM++ related variables //Scope/MM++ related variables
double currentVmax, currentVmin, currentVRMS; double currentVmax, currentVmin, currentVRMS;
TriggerType triggerMode;
double multi = 0; double multi = 0;
double xmin = 20, xmax = -20, ymin = 20, ymax = -20; double xmin = 20, xmax = -20, ymin = 20, ymax = -20;
double estimated_resistance = 0; double estimated_resistance = 0;
int multimeterRsource = 0; int multimeterRsource = 0;
int triggerMode = 0;
//Pure MM++ related variables //Pure MM++ related variables
enum multimeterType_enum {V = 0, I = 1, R = 2, C = 3}; enum multimeterType_enum {V = 0, I = 1, R = 2, C = 3};
multimeterType_enum multimeterType = V; multimeterType_enum multimeterType = V;