I'm using a T4.1 (600MHz clock) in a fairly complex program that regulates the current in a sensor using PWM to control the voltage in a resonant circuit(No problems here). I am interleaving two A/Ds to achieve 1MHz 12 bit sampling of an analog signal the average value of which R_AVG is used as feedback for the regulation routine. In addition, the samples( placed in a 2000 value buffer) are converted to cr terminated strings and sent as UDP Ethernet messages to a Windows 11 PC using a pair of Ethernet to wifi bridges ( no problems here either). I have verified the integrity of received sample data using the Wireshark network analysis program. The regulation routine relies on the current value of R_AVG ( global variable) equal to the arithmetic average of the 2000 samples in the buffer. The Regulate() function is called from the Loop() after the average is computed and interrupts are re-enabled just prior to leaving the loop.
In loop(), I disable interrupts on entry to prevent any A/D conversions from being triggered by the A/D service interrupt routine while I process the 2000 samples in the buffer array. A semaphore( bufferdone) indicates that 2000 samples have been acquired and ready to process. The samples are accessed using a pointer p1 to the buffer. All of this is no problem and works perfectly if the arithmetic R_AVG of the buffer is computed following the completion of the for loop that performs the summation of the samples. I have verified that the summation of the 2000 samples is being executed properly.
The PROBLEM is that unless there is Serial.print() statement in the for loop, the AVG is not computed properly afterwards and is set to =0. This terminates sensor regulation because an AVG value less than 400 typically indicates an open sensor or a power switch failure.
I'm attaching only the code for Loop() as the rest of the program is of no consequence as to why the presence of a print statement is required for computation of the average.
In loop(), I disable interrupts on entry to prevent any A/D conversions from being triggered by the A/D service interrupt routine while I process the 2000 samples in the buffer array. A semaphore( bufferdone) indicates that 2000 samples have been acquired and ready to process. The samples are accessed using a pointer p1 to the buffer. All of this is no problem and works perfectly if the arithmetic R_AVG of the buffer is computed following the completion of the for loop that performs the summation of the samples. I have verified that the summation of the 2000 samples is being executed properly.
The PROBLEM is that unless there is Serial.print() statement in the for loop, the AVG is not computed properly afterwards and is set to =0. This terminates sensor regulation because an AVG value less than 400 typically indicates an open sensor or a power switch failure.
I'm attaching only the code for Loop() as the rest of the program is of no consequence as to why the presence of a print statement is required for computation of the average.
Code:
```cpp
void loop() {
volatile uint32_t dwt_L = 0;
uint32_t deltacount_L = 0;
volatile uint32_t dwtlast_L = 0;
unsigned int j = 0;
noInterrupts(); //disable interrupts to stop a/d sampling
dwt_L = ARM_DWT_CYCCNT;
if (error) Serial.println("99999"); // if tried to start A/D conversion while busy
p1 = value1; // reset pointer to a/d buffer1
L_AVGSUM = 0.0; // clear sum
if (bufferdone) {
for (j = 0; j < 1999; j++) {
p1++;
L_AVGSUM += *p1;
Serial.println(); // REQUIRE A Serial.print STATEMENT HERE or R_AVG will not
// be computed after the for loop and will = 0. This will stop the regulation
// as a result of detecting an AVG value < OpenProbeValue=400
// DONT KNOW WHY ??????
sprintf(string1, "%u", *(p1)); // convert buffer value to string
strcat(string1, string2); //add a comma delimiter
// dwt = ARM_DWT_CYCCNT;
// dwtlast = ARM_DWT_CYCCNT;
string1_len = strlen(string1);
// send string1, to the IP address and port of PC
Udp.beginPacket(ipremote, localPort);
Udp.write(string1, string1_len); // send ASCII cr delimited string of A/D sample from buffer
Udp.endPacket();
}
dwtlast_L = ARM_DWT_CYCCNT;
R_AVG = (unsigned int)(L_AVGSUM / 2000); // compute avg here
Serial.print(" AVG= ");
Serial.println(R_AVG);
//dwtlast_L = ARM_DWT_CYCCNT;
deltacount_L = (dwtlast_L - dwt_L);
//Serial.println(deltacount_L);
}
p1 = value1; //reset pointer to a/d buffer
bufferdone = false; //clear bufferdone flag
interrupts(); //reenable interrupts for A/D service
Regulate();
}
```
Last edited: