Debugging interrupt service routines can be very tricky. It's not like you can print out variabes to the serial port as you might when debugging code outside the interrupt. One way you can can get some idea of what your code is doing in the ISR is to pulse one of the GPIO pins while in the ISR. On the 16Mhz Arduino Uno this takes about 4 microseconds of overhead. Another reason you might want to generate a pusle like this is to synchronize your oscilloscope with another event.
In the case of this experiment I wanted to see the clocking out of data to a 74HC595 shift register.
This all started when I wanted to modify a sample sketch from the Sparkfun inventor kit to allow me to dynamically select and change the pattern being displayed on the 8 leds. The experiment was set up so that the student was expected to un comment only the function to be used then re-upload the sketch to the arduino/redboard.
We had an extra Adafruit RGB LED Matrix that had an I2C interface and 5 menu buttons. This worked very nicely because it only requires 2 pins from the redboard. However, no matter what method you use to interact with the redboard in this example, you have the following problem: The sketch as written uses delays between updating the led patterns. In fact, the majority of what the sketch does is wait in delays. If you try and add code that checks for key presses in the main loop of the program then you will have times that you need to hold the button or press the key for over half a second in order for the sketch to see it. (See sketch that uses polling here)
There are are a few ways this can be solved. 1 - Have the keyboard / buttons generate an external interrupt to the redboard which cases a keyboard read and stores the key pressed in a buffer to be processed soon as the current led pattern function call is finished. (this would require additional hardware to route the physical interrupt signal). 2 - Set up a timer interrupt that polls the key for a keypressed, if one if found, set a flag and store the keypress for the sketch to process soon as the current led pattern function has finished.
Note that both 1 and 2 will involve some delay in the response time but will reduce the need of having the user hold the key or button until the redboard has a chance to check it.
A third way to do this is set up a interrupt that occurs ever millisecond, in the interrupt service routine you will check if the required time has elapsed and if so update the leds with the next pattern. The main program of your loop will be devoted to interacting with the user. Every millisecond the program will take 15 microseconds to decide if it needs to update the led patter on the 74HC595. 99% of the time it has nothing to do and returns. When it does need to update the display it will take about 135 microseconds to shift the pattern out.
This does require rewriting the code. No longer will you have functions you call for each pattern, but will keep a global variable telling the interrupt service routine which pattern is active and will decide how to do that within the interrupt service routine. The advantage to doing this is the updating the display is happening in the background and allowing the main program to be more interactive with the user.
Here is a video of the project along with the code:
No comments:
Post a Comment