The issue is that I've got a pair of "page up / page down" buttons on the breadboard to allow me to scroll thru the log and whenever you push one of the buttons (doesn't matter which one), the interrupt for that button will fire 2 or more times. It only happens about half the time, usually with 1 extra interrupt, but other times several in a row.
I read about someone else on these forums last June having a similar issue and he'd reported it as a bug in the .NetMF. His issue was marked resolved about a month later so I figured I'd try upgrading the firmware. I did that yesterday with the latest from tese forums and the problem still exists.
I've also read from people who have experienced this with noisy switches or sensors, so I whipped out the oscilloscope and had it do single shot traces until the issue reared it's ugly head (which didn't take long). I've attached the results. It looks like a rather clean square waveform to me.
Here is the code for my logging class:
using System; using System.Collections; using MicroLiquidCrystal; using Microsoft.SPOT.Hardware; namespace Hs.LcdLogger { public class LcdLogger { private readonly Lcd _lcd; public Lcd LoggerLcd { get { return _lcd; } } private readonly ArrayList _logList; private Int32 _logIndex; private readonly Int32 _logSize; private static InterruptPort _btnPreviousPage; private static InterruptPort _btnNextPage; public LcdLogger(SPI.SPI_module spiBus, Cpu.Pin latchPin, Int32 logSize, Cpu.Pin previousPin, Cpu.Pin nextPin) { // Create the transfer provider. Shifter74Hc595LcdTransferProvider lcdProvider = new Shifter74Hc595LcdTransferProvider(spiBus, latchPin, Shifter74Hc595LcdTransferProvider.BitOrder.MSBFirst); // Create the LCD interface. _lcd = new Lcd(lcdProvider); // Set up the LCD's number of columns and rows. _lcd.Begin(16, 2); _lcd.Backlight = false; // The plug-in module will have it's own switch for the backlight. // Initialize log array. _logSize = logSize; _logList = new ArrayList { Capacity = logSize }; // Set up navigation pins. _btnPreviousPage = new InterruptPort(previousPin, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeLow); _btnPreviousPage.OnInterrupt += BtnPreviousPage_OnInterrupt; _btnNextPage = new InterruptPort(nextPin, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeLow); _btnNextPage.OnInterrupt += BtnNextPage_OnInterrupt; } public void BtnPreviousPage_OnInterrupt(uint port, uint state, DateTime time) { PreviousPage(); } public void BtnNextPage_OnInterrupt(uint port, uint state, DateTime time) { NextPage(); } public void LastPage() { if (_logList.Count == 0) return; if (_logList.Count > 1) _logIndex = _logList.Count - 2; else _logIndex = _logList.Count - 1; UpdateDisplay(); } public void NextPage() { if (_logList.Count == 0) return; if (_logList.Count > 2) { _logIndex += 2; // If we went past the last page, set to the last page. if (_logIndex > _logList.Count - 2) _logIndex = _logList.Count - 2; } else _logIndex = 0; UpdateDisplay(); } public void PreviousPage() { if (_logList.Count == 0) return; if (_logList.Count > 2) { _logIndex -= 2; // If we went past the first page, set to the first page. if (_logIndex < 0) _logIndex = 0; } else _logIndex = 0; UpdateDisplay(); } private void UpdateDisplay() { _lcd.Clear(); // First line if (_logList.Count > 0) { _lcd.SetCursorPosition(0, 0); _lcd.Write(_logList[_logIndex].ToString()); } // Second line if (_logList.Count > 1) { _lcd.SetCursorPosition(0, 1); _lcd.Write(_logList[_logIndex + 1].ToString()); } } public void AddLogLine(String logLine) { // If adding a line will exceed our max log size, remove the first entry (first in, first out). if (_logList.Count > _logSize) _logList.RemoveAt(0); // Add the first 16 chars _logList.Add(logLine.Length > 16 ? logLine.Substring(0, 16) : logLine); // If it's longer than 16 chars, dump the remaining chars (up to 16) to another line. if (logLine.Length > 16) { // If adding a line will exceed our max log size, remove the first entry (first in, first out). if (_logList.Count > _logSize) _logList.RemoveAt(0); // Add a ">" char to indicate word-wrapped line. logLine = String.Concat(">", logLine.Substring(16, 15)); _logList.Add(logLine); } } } }
And here's the sample program I'm using to test it:
using System.Threading; using Hs.LcdLogger; using Microsoft.SPOT.Hardware; using SecretLabs.NETMF.Hardware.Netduino; namespace NetduinoApplication1 { public class Program { static private InputPort _pinEndButton = new InputPort(Pins.ONBOARD_SW1, false, Port.ResistorMode.Disabled); public static void Main() { LcdLogger logger = new LcdLogger(SPI_Devices.SPI1, Pins.GPIO_PIN_D10, 20, Pins.GPIO_PIN_D2, Pins.GPIO_PIN_D3); logger.AddLogLine("Page 1, Line 1"); logger.AddLogLine("Page 1, Line 2"); logger.AddLogLine("Page 2, Line 1"); logger.AddLogLine("Page 2, Line 2"); logger.AddLogLine("Page 3, Line 1"); logger.AddLogLine("Page 3, Line 2"); logger.AddLogLine("Page 4, Line 1"); logger.AddLogLine("Page 4, Line 2"); logger.AddLogLine("Page 5, Line 1"); logger.AddLogLine("Page 5, Line 2"); while (!_pinEndButton.Read()) { } logger.LoggerLcd.Clear(); } } }
Any help with this issue would be greatly appreciated!
Thanks in advance!
Frank