I have finished implementing the state machine and the rest of the interrupts that it will take in. I also tested it with the shift register fret-detection but ran into issues with the fret detection not working. I spent several hours with Owen trying to debug it, and I tried a variety of things to try to rule out software as an issue. One attempt at this was adding delays (using delayMicroseconds() and delay() calls) in between the digitalWrite() calls that controlled the digital clock and data-in signals for the shift register in case they were changing too fast for the DFFs to register the signal. This did not help, and after viewing the signals on a scope and reviewing the code logic carefully, Owen and I decided the software was not the issue.
So, we were pretty sure it was a hardware issue, with the flip flops not propagating the data correctly through the shift register. We had several theories for why this could be:
- The hot-plate method of soldering SMD components on the fret PCBs killed the D-Flip-Flop chips.
- We were damaging the chips with ESD
- We were running into setup/hold time issues
- The clock was ringing so much that the digital assumption broke down.
More details are documented in Owen’s status report, but the gist is that we don’t think the issue is 1 or 2. To have less ringing on the clock, I suggested adding an RC delay between the stages to allow for a smoother clock signal, and after Owen tested that out, the results seemed to improve. This may have helped 3 and/or 4.
As for the state machine, I implemented the final 2 interrupts (pause and restart) and the done signal. The “done” signal is asserted when the song finishes – when all notes in the MIDI file are read.
To start integrating the fret detection, I implemented sampling of the fretboard, but as described, I ran into issues with the shift register malfunctioning. The following images show the code for sampling the fretboard:
The clearShiftRegister() function ensures no voltage stimulus on the fretboard before we start reading. This is done by propagating a 0 through the fretboard twice for good measure. loadShiftRegister() loads a single 1 into the shift register, which is later propagated through the DFFs. The sampleFrets() method calls the previous 2 and does the “shifting” of the shift register by pulsing the clock and reading the GPIO pins connected to the strings (this is another task that I implemented this week). sampleFrets() is called periodically, and when the “sample” contains an interesting value (a string is pressed down on a fret), the state machine prints a message for debugging.
This progress is on track. Despite the hardware side of the fret detection keeps slipping, the software part is back on track after slipping last week. Going forward, we must build confidence in the RC delay solution or pivot away from a shift register and use 14 individual GPIOs to provide electrical stimuli to the frets.
Next week, I will need to work on the 2 different user modes – “training” mode, where the system waits for the user to play a note before moving onto the next note, and “continuous” mode, where the system keeps flashing LEDs according to the timing set in the MIDI file even if the user can’t keep up. I have also realized that the time specified in the MIDI file for holding a note is meaningless for a guitar because there isn’t a concept of “holding” a note for a duration on a guitar. Thus, the timing I care about is the duration from starting a note to starting the following note, as opposed to knowing both the duration from starting a note to ending it and the duration between ending a note and starting the next note. This gives more clarify on how I will implement the 2 different playing modes.