Today was the last day of the Applied Circuits class, and the students were turning in their 10th lab report. It’s all over but the grading (though I expect a few more redone assignments to be turned in on Monday).
Today’s class started with my explaining a bug that was just found in the PteroDAQ code.
Symptoms: On the EKG assignment a number of students ran into trouble in the lab with the PteroDAQ software suddenly switching from normal recording to a sawtooth waveform, then spontaneously switching back after a while. When plotting the saved data with gnuplot, the timestamps were all messed up in the part of the recording where the sparkline had displayed a sawtooth waveform, but returned to normal when the sparkline did. We had never seen this behavior on the Macs, nor had we seen it previously on the Windows machines. The one new thing in this lab is that we were using a higher sampling rate on the Windows machines than we had previously used.
Diagnosis 1: The sawtooth waveform suggested to me that the low-order part of the timestamp was being taken as the signal, and the disordered timestamps as intrusion of the data into the timestamp. I suspected that the old, slow Windows machines were not able to keep up with the USB serial traffic, and that they were losing a byte and getting a framing error.
I suggested this diagnosis to my son, but he showed me the framing character and checksum used to detect malformed packets, and pointed out that even if a malformed packed passed the checksum, synchronization would be re-established within a packet or two. Although the behavior certainly looks like a framing error, the packets should not go out of frame consistently.
Today, after watching the Shakespeare To Go 50-minute production of Hamlet with me, my son accompanied me to the lab to observe the behavior for himself. We got the behavior very quickly with a 300Hz sampling rate, and the error message for a checksum failure was not printed. He added a print statement in the code where the data packets were getting their checksums checked, so that we could see what data was coming in. We looked at the transition from good behavior to bad, and noted that the packets were still the right length, but the information in the packet seemed to have been shifted. So there seemed to be a framing error, but not in the USB communication.
Diagnosis 2: This shift indicated that the problem was in the software running on the KL25Z board, rather than in the software running on the Windows host. The packets to be sent out the USB serial port are stored in a queue in the KL25Z, and I conjectured that the queue was overflowing. Since a circular buffer is used for the queue, writing when the queue is full would overwrite data for a different packet. Because the queue length in bytes was not a multiple of the size of the items on the queue, this overwriting would be out of phase, and we would observe periodic switching between in-frame and out-of-frame packets, which is what we were observing.
We checked the code, and found that the test for sufficient room in the buffer for another packet had not been included in the routine for adding a new event to the queue. The code to check the remaining space had been written, but not not used yet. A fifteen-minute bug fix, while I went to my office to get my materials for my class, confirmed that this had indeed been the problem. He will be pushing the fix to https://bitbucket.org/abe_k/pterodaq this evening. The fix consists of discarding any event for which there is insufficient room in the queue. Some loss of data is unavoidable when the queue fills up, and this delays the loss as much as possible, as well as minimizing how many events are discarded. Since the events are timestamped, losing an event will often have little or no consequence for downstream analysis or plotting.
The first part of the class was explaining the bug to the students, which I had to do in a rather handwavy fashion, since most of the class has not had programming, much less queues and circular buffers.
We then talked about a variety of different things: deadlines for redos, when the t-shirts would be available, instructor feedback forms to fill out online, differences between bioengineering programs at the various UCs, what the job market was like for bioengineers, and other general advising sorts of things. I also reviewed some of the goals of the course in terms of engineering thinking, tinkering vs. engineering by design, the usefulness of models that aren’t perfectly accurate, trying to switch them from answer-getting to keeping in mind the meaning of what they were doing, sanity checks, methodical work and lab notebooks records, and that the real world trumps any models (“try it and see!”).
Incidentally, this year’s t-shirts have that motto on the shirts:
When the students finally ran out of questions, I had about 10 minutes left, so I introduced them to the Wien-bridge oscillator, first by reminding them of the bridge-null condition (which them almost remembered from the quiz it had been on), then deriving that and . I even had time to tell them about how the amplitude of the original oscillators was regulated by having a light bulb as a non-linear resistor in place of R1.
After class I attempted to help one of the students get PteroDAQ working with his laptop, but we got as far as determining that the drivers were missing for the USB serial device on the KL25Z board, and that the Windows 7 driver installation did not fix the problem before he had to go to another class. My son and I will have to look for Windows 8 driver initialization that will set things up properly for the KL25Z board—this might be tricky as we have no access to a Windows 8 machine to test putative solutions on.