18.03.2017, 07:51 PM
(Dieser Beitrag wurde zuletzt bearbeitet: 18.03.2017, 08:01 PM von christianw..)
(18.03.2017, 06:24 PM)r0cknrolla schrieb: Doc , weiss bescheid. Wie immer.
Naja, mein Wissen, verglichen mit dem Rest der hier anwesenden Bande, ist eher so "intermediate".
(18.03.2017, 06:24 PM)r0cknrolla schrieb: War 360customs nicht deine Seite mit der Orangenen Xbox mit dem LCD Dran? Da hab ich mir auch den Bauplan für das DIY Komponenten Kabel abgeguckt.
Ist immer noch.
(18.03.2017, 05:56 PM)kahlo schrieb: Das heisst, dass das Hantek-Teil nur die Rohdaten streamt und der PC die Arbeit hat? Dann ist das tatsächlich nix...
Ja, sogar der Trigger ist Software.
(Wobei, der 6022 hat einen rudimentären in HW, wenn ich mich nicht täusche)
Unser SW-Trigger für das DDS120...
Code:
for (int channel = triggerSource; chLoop < BUUDAI_CHANNELS; chLoop++, channel++) {
if (channel >= BUUDAI_CHANNELS)
channel = 0; // wrap-around to next channel
channelDataCount = (dataCount / BUUDAI_CHANNELS) - SKIP; // re-initialize for each channel
// Reallocate memory for samples if the sample count has changed
if (!samples[channel] || samplesSize[channel] != channelDataCount) {
if (samples[channel])
delete samples[channel];
samples[channel] = new double[channelDataCount];
samplesSize[channel] = channelDataCount;
}
// Convert data from the oscilloscope and write it into the sample buffer
unsigned long int bufferPosition = SKIP ;//+ triggerPoint * 2;
unsigned int bufferFraction = (dataCount / BUUDAI_CHANNELS) / 2; // only use a fraction of samplebuffer, scales with timebase via bufferMulti to catch slow signals on longer timebase.
// For buffersizes < 2048 no initial shift is needed, as data fits in fifo without glitch
if (oldTriggerOffset > SKIP && oldTriggerOffset <= dataCount && channel != triggerSource)
bufferPosition = oldTriggerOffset; // Use same trigger position offset found by trigger source
// Trigger Hack for rising edge or falling edge trigger
double dataValueOld = 0;
unsigned long int firstTriggerPos = 0; // first trigger position that will be confirmed by another 3 hits
int hitCounter = 0;
int bad_Case = 1; // Assume bad case where start dataValue above TriggerPositionOffset for rising edge trigger
// and where start dataValue below TriggerPositionOffset for falling edge trigger to avoid false positive
for (unsigned int triggerPositionIndex = 0; triggerPositionIndex < bufferFraction && channel == triggerSource; triggerPositionIndex++){ // Only search for trigger position offset if channel is trigger source
double dataValue = ((double) data[bufferPosition + channel]/sampleRange[channel] - offsetReal[channel])*gainSteps[gain[channel]]*cal[channel];
// Search only when dataValue is NOT above TriggerPositionOffset for rising-edge trigger and
// when dataValue is NOT below TriggerPositionOffset for falling edge trigger to prevent false positive
if (bad_Case == 1 && (bufferPosition + (dataCount >> 7) + channel) < dataCount) {
// Look ahead comparison provide more stable rising edge detection
if (triggerSlope == Dso::SLOPE_POSITIVE) { // Look ahead step size based on time base (aka buffer size)
if (dataValue < (triggerPositionOffset-0.02)) { // so slow signal edge detect is more reliable
if (data[bufferPosition + channel] < data[bufferPosition + (dataCount >> 11) + channel])
hitCounter++;
if (data[bufferPosition + channel] < data[bufferPosition + (dataCount >> 10) + channel])
hitCounter++;
if (data[bufferPosition + channel] < data[bufferPosition + (dataCount >> 9) + channel])
hitCounter++;
if (data[bufferPosition + channel] < data[bufferPosition + (dataCount >> 8) + channel])
hitCounter++;
if (data[bufferPosition + channel] < data[bufferPosition + (dataCount >> 7) + channel])
hitCounter++;
}
}
else if (triggerSlope == Dso::SLOPE_NEGATIVE) { // Look ahead comparison for falling edge detect
if (dataValue > (triggerPositionOffset+0.02)) { // +0.02 (arbitary) forced a better comparison
if (data[bufferPosition + channel] > data[bufferPosition + (dataCount >> 11) + channel])
hitCounter++;
if (data[bufferPosition + channel] > data[bufferPosition + (dataCount >> 10) + channel])
hitCounter++;
if (data[bufferPosition + channel] > data[bufferPosition + (dataCount >> 9) + channel])
hitCounter++;
if (data[bufferPosition + channel] > data[bufferPosition + (dataCount >> 8) + channel])
hitCounter++;
if (data[bufferPosition + channel] > data[bufferPosition + (dataCount >> 7) + channel])
hitCounter++;
}
}
if (hitCounter >= 3) // Enable trigger position search by 3 hits out of 5 in sliding window
bad_Case = 0;
hitCounter = 0; // Reset for next step to confirm trigger position or next attempt to enable search
}
if (bad_Case == 0 &&
((dataValue > dataValueOld && dataValue > triggerPositionOffset && triggerSlope == Dso::SLOPE_POSITIVE) ||
(dataValue < dataValueOld && dataValue < triggerPositionOffset && triggerSlope == Dso::SLOPE_NEGATIVE)))
{ // Normal case search
// Tried sliding window search same as the above edge detection but not as stable for square waves
hitCounter++;
if (hitCounter == 1)
firstTriggerPos = bufferPosition; // First trigger position found
if (hitCounter >= 4) { // Confirm first trigger position by 3 more hits
bufferPositionOffset = firstTriggerPos;
oldTriggerOffset = firstTriggerPos; // Set confirmed trigger position to first hit position to keep
bufferPosition = firstTriggerPos; // the start of displayed waveform close to trigger position cursor
firstTriggerPos = 0; // Reset for next data transfer cycle
hitCounter = 0;
bad_Case = 1; // Reset to bad case assumption for next data transfer and search cycle
break;
}
}
dataValueOld = dataValue;
bufferPosition += 2; // Next position to check
}
if (oldTriggerOffset == SKIP && channel == triggerSource)
bufferPosition = SKIP; // No trigger position found reset buffer position for free running waveforms
// triggerPosition
//bufferPosition = int(bufferPositionOffset + (triggerPosition * 2));
// shorten data due to trigger offset
if (oldTriggerOffset > SKIP) // Check if trigger position is found. Otherwise, allow free running waveform
channelDataCount = channelDataCount - (bufferPosition / 2);
// put data on screen
for (unsigned long int realPosition = 0; realPosition < channelDataCount ; realPosition++) {
if (bufferPosition >= dataCount)
bufferPosition %= dataCount;
samples[channel][realPosition] = ((double) data[bufferPosition + channel]/sampleRange[channel] - offsetReal[channel])*gainSteps[gain[channel]]*cal[channel];
bufferPosition += 2; // Next position to check
}
}
oldTriggerOffset = SKIP; // Clear trigger position for next cycle free running waveforms when no trigger found
samplesMutex.unlock();
// limit framerate and load but be somewhat in sync with samplerate to avoid glitches
if (bufferMulti < 2) {
usleep(32768);
} else {
// usleep(bufferSize);
}
emit samplesAvailable(&(samples), &(samplesSize), (double) samplerateMax / samplerateDivider, &(samplesMutex));
} // if (process)
return 0;
}