Hi Shawn,
After further testing I believe my issues are simply running out of processing time in between my interrupts at 128kHz.
I added debugging information to my data stream (going over UDP or Serial) and could see that at the 128kHz rate there are very odd issues occuring such as variables not incrementing and the circular buffer falling over due to this.
At slightly lower interrupt rates (eg 85kHz), everything works completely fine never missing a beat.
I think the only way to improve this is for me to work on methods to reduce processing time in the ISR and on any streaming method.
Just for completeness, here is my ISR: (the encoder counter is being directly incremented for debugging to detect loss of packets, and the last 3 long ints are also for debugging purposes
Code:
void adcDataReadyIsrStream(){
adc.readData(&res);
ultemp = micros() - loggerStatus.logStartTimeMicro;
//mCurPosValue = myEnc1.read(); // taking
mCurPosValue++;
// update digital inputs here as the ISRs for the digital inputs will be disabled
bitWrite(digitalInputs, 0,digitalReadFast(DIN0));
bitWrite(digitalInputs, 1,digitalReadFast(DIN1));
bitWrite(digitalInputs, 2,digitalReadFast(DIN2));
bitWrite(digitalInputs, 3,digitalReadFast(DIN3));
bitWrite(digitalInputs, 4,digitalReadFast(DIN4));
bitWrite(digitalInputs, 5,digitalReadFast(DIN5));
bitWrite(digitalInputs, 6,digitalReadFast(DIN6));
bitWrite(digitalInputs, 7,digitalReadFast(DIN7));
myQueueWrite(0xAA);
myQueueWrite((uint8_t)(0xFF & ultemp)); // elapsed time
myQueueWrite((uint8_t)(ultemp>>8)&0xFF);
myQueueWrite((uint8_t)(ultemp>>16)&0xFF);
myQueueWrite((uint8_t)(ultemp>>24)&0xFF);
myQueueWrite((uint8_t)(res.chan1_16&0xFF)); // analog channel 1
myQueueWrite((uint8_t)(res.chan1_16>>8)&0xFF);
myQueueWrite((uint8_t)(res.chan2_16&0xFF)); // analog channel 1
myQueueWrite((uint8_t)(res.chan2_16>>8)&0xFF);
myQueueWrite((uint8_t)(res.chan3_16&0xFF)); // analog channel 1
myQueueWrite((uint8_t)(res.chan3_16>>8)&0xFF);
myQueueWrite((uint8_t)(res.chan4_16&0xFF)); // analog channel 1
myQueueWrite((uint8_t)(res.chan4_16>>8)&0xFF);
myQueueWrite((uint8_t)(mCurPosValue)&0xFF); // 32 bit encoder counter
myQueueWrite((uint8_t)(mCurPosValue>>8)&0xFF);
myQueueWrite((uint8_t)(mCurPosValue>>16)&0xFF);
myQueueWrite((uint8_t)(mCurPosValue>>24)&0xFF);
myQueueWrite(digitalInputs); // digital inputs, automatically update in own ISRs
// all added for debugging
myQueueWrite((uint8_t)(myCircBuffer.length)&0xFF); // 32 bit buffer length
myQueueWrite((uint8_t)(myCircBuffer.length>>8)&0xFF);
myQueueWrite((uint8_t)(myCircBuffer.length>>16)&0xFF);
myQueueWrite((uint8_t)(myCircBuffer.length>>24)&0xFF);
myQueueWrite((uint8_t)(myCircBuffer.writeIndex)&0xFF); // 32 bit buffer head index
myQueueWrite((uint8_t)(myCircBuffer.writeIndex>>8)&0xFF);
myQueueWrite((uint8_t)(myCircBuffer.writeIndex>>16)&0xFF);
myQueueWrite((uint8_t)(myCircBuffer.writeIndex>>24)&0xFF);
myQueueWrite((uint8_t)(myCircBuffer.readIndex)&0xFF); // 32 bit buffer tail index
myQueueWrite((uint8_t)(myCircBuffer.readIndex>>8)&0xFF);
myQueueWrite((uint8_t)(myCircBuffer.readIndex>>16)&0xFF);
myQueueWrite((uint8_t)(myCircBuffer.readIndex>>24)&0xFF);
}
And here is the section of my state machine responsible for UDP streaming
Code:
case st_stream_udp: {
if ((loggerControl.execute==0)||(timeAnt <= millis())) {
// shut off interrupts
noInterrupts();
detachInterrupt(ADC_DRDY);
interrupts();
if (bytecount>0) Udp.send(clientIP,loggerConfiguration.udpStreamPort, udpStreamBuffer, bytecount);
Serial.println("->st_stream_completed");
state = st_stream_completed;
}
else {
if (myCircBuffer.length>0) {
bytecount=0;
while ((myCircBuffer.length>0)&&(loggerControl.execute==1)&&(timeAnt >= millis())){
udpStreamBuffer[bytecount++]=myQueueDeque();
if ((bytecount >= 20*(SAMPLE_SIZE_ALL+13))){
bytesWritten=0;
attempts=0;
Udp.send(clientIP,loggerConfiguration.udpStreamPort, udpStreamBuffer, bytecount);
bytecount=0;
}
if (myQueueFull()) loggerStatus.queueFull=1;
else loggerStatus.queueFull=0;
if (millis()> timeAnt) {
noInterrupts();
detachInterrupt(ADC_DRDY);
interrupts();
}
}
}
}
}
break;
Here is my super simple circular buffer implementation
Code:
volatile uint8_t uresult;
volatile uint8_t myQueueReset(){
myCircBuffer.writeIndex=0;
myCircBuffer.readIndex=0;
myCircBuffer.length=0;
myCircBuffer.capacity = BIG_BUFFER_SIZE;// CIRC_BUFFER_SIZE;
myCircBuffer.full=0;
myCircBuffer.behind=0;
return 0;
}
void myQueueWrite(volatile uint8_t value){
//circularBuffer[myCircBuffer.writeIndex++] = value;
bigbuffer[myCircBuffer.writeIndex] = value;
myCircBuffer.writeIndex++;
myCircBuffer.length++;
if (myCircBuffer.writeIndex == BIG_BUFFER_SIZE) myCircBuffer.writeIndex=0;
}
volatile uint8_t myQueueDeque(void){
//uresult = circularBuffer[myCircBuffer.readIndex++];
uresult = bigbuffer[myCircBuffer.readIndex];
myCircBuffer.readIndex++;
myCircBuffer.length--;
if (myCircBuffer.readIndex == BIG_BUFFER_SIZE) myCircBuffer.readIndex=0;
return uresult;
}
volatile uint8_t myQueueBehind(void){
if (myCircBuffer.length >0) return 1;
else return 0;
}
volatile uint8_t myQueueFull(void){
if (myCircBuffer.length >= myCircBuffer.capacity) return 1;
else return 0;
}
volatile uint32_t myQueueSpaceRemaining(void){
return BIG_BUFFER_SIZE - myCircBuffer.length;
}