Generates a test signal on an AnalogOut and monitors a signal on an AnalogIn, plotting the test signal or the actual signal depending on a conditional compile. The wait() and wait_ms() library calls for this board are highly inaccurate so a new function is provided to wait for X number of milliseconds -- which is not very accurate.

Dependencies:   LCD_DISCO_F429ZI mbed TS_DISCO_F429ZI mbed-os BSP_DISCO_F429ZI

Files at this revision

API Documentation at this revision

Comitter:
Damotclese
Date:
Mon Jun 17 17:11:07 2019 +0000
Parent:
1:b9d4b9b8884c
Commit message:
Added average TEC history;

Changed in this revision

LaserMon-Main.cpp Show annotated file Show diff for this revision Revisions of this file
LaserMon-Main.h Show annotated file Show diff for this revision Revisions of this file
LaserMon-ScanInput.cpp Show annotated file Show diff for this revision Revisions of this file
LaserMon-ScanInput.h Show annotated file Show diff for this revision Revisions of this file
LaserMon-TEC.cpp Show annotated file Show diff for this revision Revisions of this file
LaserMon-TEC.h Show annotated file Show diff for this revision Revisions of this file
LaserMon-TestOutput.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r b9d4b9b8884c -r cbcf2695a4a1 LaserMon-Main.cpp
--- a/LaserMon-Main.cpp	Fri Jun 14 21:11:31 2019 +0000
+++ b/LaserMon-Main.cpp	Mon Jun 17 17:11:07 2019 +0000
@@ -11,6 +11,7 @@
 #include "TS_DISCO_F429ZI.h"        // For controlling the touch screen
 #include "LaserMon-TestOutput.h"    // For generating test output signal
 #include "LaserMon-ScanInput.h"     // For monitoring laser power pin
+#include "LaserMon-TEC.h"           // For monitoring the TEC output
 #include "LaserMon-Main.h"          // Always include ourself
 
 // ----------------------------------------------------------------------
@@ -19,8 +20,30 @@
 // ----------------------------------------------------------------------
 
     const char * pch_firstMessage  = "Test signal on PA_5";
-    const char * pch_secondMessage = "Laser Scan on PC_1";
+    const char * pch_secondMessage = "Laser Scan on  PC_1";
+    const char * pch_thirdMessage  = "TEC signal on  PC_3";
+
+    // Instantiate a digitial input mapped as our push button
+    static DigitalIn st_pushButton(PA_0);
 
+    // We must see the button down for a period of time, we
+    // do a debounce even though the class may do one already
+    static uint16_t u16_buttonDownCount;
+    
+    // This flag informs the laser scan input module whether
+    // it is permitted to plot the scan input or not
+    static bool b_allowPlotting;
+    
+    // We store the scan length in milliseconds offered to this
+    // module by the laser scanner, and we store the TEC voltage
+    // offered by the TEC scanner
+    static uint16_t u16_scanLength;
+    static uint16_t u16_TECVoltage;
+    static uint16_t u16_scanCount;
+
+    // We talk to Jenkins through an RS232 serial interface
+    static Serial st_Serial1(USE_SERIAL_TX, USE_SERIAL_RX);
+    
 // ----------------------------------------------------------------------
 // Define global data storage which we will export
 //
@@ -38,6 +61,13 @@
 // ----------------------------------------------------------------------
 static void MainInit(void)
 {
+    // Initialize locally-held data
+    u16_buttonDownCount = 0;
+    b_allowPlotting     = true;
+    u16_scanLength      = 0;
+    u16_TECVoltage      = 0;
+    u16_scanCount       = 0;
+    
     // Bring the LCD up 
     st_lcd.Clear(LCD_COLOR_WHITE);
     
@@ -49,6 +79,168 @@
 
     // Set the default font size
     BSP_LCD_SetFont(&Font16);
+    
+    // Set the push button to not have an internal pull-up or down
+    st_pushButton.mode(PullNone);
+    
+    // We configure the serial interface
+    st_Serial1.baud(115200);
+    st_Serial1.format(8, SerialBase::None, 1);
+}
+
+// ----------------------------------------------------------------------
+//
+//
+// ----------------------------------------------------------------------
+static void MainCheckInbound(void)
+{
+    // See if there is inbound serial data
+    if (st_Serial1.readable())
+    {
+        
+    }  
+}
+
+// ----------------------------------------------------------------------
+//
+//
+// ----------------------------------------------------------------------
+static void MainTransmitOutput(uint8_t * pu8_thisFrame, uint16_t u16_thisCount)
+{
+    st_Serial1.write(pu8_thisFrame, u16_thisCount, NULL);
+}
+
+// ----------------------------------------------------------------------
+// LaserMonMainInformScanInformation()
+//
+//
+// ----------------------------------------------------------------------
+void LaserMonMainInformScanInformation(uint16_t u16_thisScanLength, uint16_t u16_thisScanCount)
+{
+    // If we arte displaying information, the scan gets slowed down
+    // while we print the information to the screen, making the scan
+    // information inaccurate. To avoid displaying inaccurate values
+    // we refrain from storing the scan rate while displaying the
+    // information
+    if (true == b_allowPlotting)
+    {
+        // Allow the scan information to get updated
+        u16_scanLength = u16_thisScanLength;
+    }
+    
+    // Always store the scan counter value
+    u16_scanCount  = u16_thisScanCount;
+}
+
+// ----------------------------------------------------------------------
+// LaserMonMainInformTECVoltage()
+//
+// ----------------------------------------------------------------------
+void LaserMonMainInformTECVoltage(uint16_t u16_thisVoltage)
+{
+    u16_TECVoltage = u16_thisVoltage;    
+}
+
+// ----------------------------------------------------------------------
+// MainReportValues()
+//
+// ----------------------------------------------------------------------
+static void MainReportValues(void)
+{
+    char pch_holdMessage[101] = { 0 };
+    
+    (void)sprintf(pch_holdMessage, "Scan duration %u", u16_scanLength);
+    st_lcd.DisplayStringAt(1, LINE(1), (uint8_t *)pch_holdMessage, LEFT_MODE);
+
+    (void)sprintf(pch_holdMessage, "Scan count %u", u16_scanCount);
+    st_lcd.DisplayStringAt(1, LINE(2), (uint8_t *)pch_holdMessage, LEFT_MODE);
+
+    (void)sprintf(pch_holdMessage, "TEC voltage %1.02f", (float)u16_TECVoltage / 100.0f);
+    st_lcd.DisplayStringAt(1, LINE(3), (uint8_t *)pch_holdMessage, LEFT_MODE);
+
+    (void)sprintf(pch_holdMessage, "TEC average %1.02f", (float)TECGetLastTenAverage() / 100.0f);
+    st_lcd.DisplayStringAt(1, LINE(4), (uint8_t *)pch_holdMessage, LEFT_MODE);
+    
+    // Build a report for Jenkins or anything else to monitor
+    (void)sprintf(pch_holdMessage, "%u,%1.02f,%1.02f,%u%c%c",
+        u16_scanLength,
+        ((float)u16_TECVoltage / 100.0f),
+        ((float)TECGetLastTenAverage() / 100.0f),
+        u16_scanCount,
+        0x0d, 0x0a);
+    
+    // Send that report out the serial interface
+    MainTransmitOutput((uint8_t *)pch_holdMessage, (uint16_t)strlen(pch_holdMessage));
+}
+
+// ----------------------------------------------------------------------
+// MainHandleButtonDown()
+//
+// ----------------------------------------------------------------------
+static void MainHandleButtonDown(void)
+{
+    // Are we currently allowing the laser scan input to be plotted?
+    if (true == b_allowPlotting)
+    {
+        // Flag the fact that we are not allowing the plot
+        b_allowPlotting = false;
+
+        // Make sure that the display is cleared
+        st_lcd.Clear(LCD_COLOR_WHITE);    
+
+        // Report the lasr scan and TEC voltage values
+        MainReportValues();
+    }
+    else
+    {
+        // Clear the display
+        st_lcd.Clear(LCD_COLOR_WHITE);    
+        
+        // Clear the flag so that the plot of the scan may be displayed
+        b_allowPlotting = true;
+    }    
+}
+
+// ----------------------------------------------------------------------
+// MainThread()
+//
+// ----------------------------------------------------------------------
+static bool MainThread(void)
+{
+    bool b_restartOneSecondTimer = false;
+    
+    // Acquire / poll the state of the push button
+    int i_buttonState = st_pushButton.read();
+    
+    // Is the button down?
+    if (1 == i_buttonState)
+    {
+        // The button is not down, was the button down before?
+        // We need to see if the button is down for 10 milliseconds
+        // before we agree that the button is down
+        if (u16_buttonDownCount < 10)
+        {
+            if (10 == ++u16_buttonDownCount)
+            {
+                // The button has been held down long enough
+                MainHandleButtonDown();
+                
+                // We want to have the one second timer restarted
+                b_restartOneSecondTimer = true;
+            }
+        }
+    }
+    else
+    {
+        // The button is not down so clear the down counter
+        u16_buttonDownCount = 0;
+    }
+    
+    // See if there is inbouns serial data to be processed
+    MainCheckInbound();
+    
+    // Indicate whether we are displaying the running information or not
+    return b_restartOneSecondTimer;
 }
 
 // ----------------------------------------------------------------------
@@ -58,26 +250,65 @@
 // ----------------------------------------------------------------------
 int main(void)
 {
+    uint16_t u16_oneSecondCounter    = 0;
+    bool     b_restartOneSecondTimer = false;
+    
     // Perform local module initialization, if any
     MainInit();
     
-    // Start generating the putput test signal
+    // Initialize the generating of the output test signal module
     TestOutputInit();
     
-    // Start scanning the laser drive power
+    // Initialize the scanning of the the laser drive power module
     ScanInputInit();
     
+    // Initialize the scanning of the TEC input and launch thread
+    TECInit();
+    
     // Display information about what signal pigs have what
-    st_lcd.DisplayStringAt(1, LINE(1), (uint8_t *)pch_firstMessage, LEFT_MODE);
-    st_lcd.DisplayStringAt(1, LINE(2), (uint8_t *)pch_secondMessage, LEFT_MODE);
+    st_lcd.DisplayStringAt(1, LINE(0), (uint8_t *)pch_firstMessage,  LEFT_MODE);
+    st_lcd.DisplayStringAt(1, LINE(1), (uint8_t *)pch_secondMessage, LEFT_MODE);
+    st_lcd.DisplayStringAt(1, LINE(2), (uint8_t *)pch_thirdMessage,  LEFT_MODE);
     
     // Go in to a forever loop for the main thread which does nothing
     while(true)
     {
         // Wait for 1 millisecond
         wait_us(899);
+        
+        // Instead of launching threads whose timing is a problem,
+        // we merely call the once-a-millisecond "thread" functions
+        // to drive the test signal out and the laser scan signal in
         TestOutputThread();
-        ScanInputThread();
+        ScanInputThread(b_allowPlotting);
+        b_restartOneSecondTimer = MainThread();
+        TECThread();
+        
+        // Have we just started displaying collected information?
+        if (true == b_restartOneSecondTimer)
+        {
+            // Yes, so we will count down the timer
+            u16_oneSecondCounter = 1000;
+        }
+        else
+        {
+            // In case the one second timer is running, stop it
+            b_restartOneSecondTimer = 0;
+        }
+        
+        // Is the one second counter running?
+        if (u16_oneSecondCounter > 0 && false == b_allowPlotting)
+        {
+            // Count down the one second timer and see if it's expired
+            if (0 == --u16_oneSecondCounter)
+            {
+                // Report the current values again
+                MainReportValues();
+                
+                // Restart the one second timer
+                u16_oneSecondCounter = 1000;
+            }
+        }
     }
 }
 
diff -r b9d4b9b8884c -r cbcf2695a4a1 LaserMon-Main.h
--- a/LaserMon-Main.h	Fri Jun 14 21:11:31 2019 +0000
+++ b/LaserMon-Main.h	Mon Jun 17 17:11:07 2019 +0000
@@ -8,6 +8,9 @@
 
 #define TEST_SIGNAL_OUT     PA_5
 #define LASER_SCAN_IN       PC_1
+#define TEC_VOLTAGE_IN      PC_3
+#define USE_SERIAL_TX       PA_9
+#define USE_SERIAL_RX       PA_10
 
 // ----------------------------------------------------------------------
 // Defined constants and MACROs
@@ -37,6 +40,8 @@
 //
 // ----------------------------------------------------------------------
 
+extern void LaserMonMainInformScanInformation(uint16_t u16_scanLength, uint16_t u16_scanCount);
+extern void LaserMonMainInformTECVoltage(uint16_t u16_thisVoltage);
 
 // End of file
 
diff -r b9d4b9b8884c -r cbcf2695a4a1 LaserMon-ScanInput.cpp
--- a/LaserMon-ScanInput.cpp	Fri Jun 14 21:11:31 2019 +0000
+++ b/LaserMon-ScanInput.cpp	Mon Jun 17 17:11:07 2019 +0000
@@ -17,7 +17,7 @@
 //
 // ----------------------------------------------------------------------
 
-#define WANT_TEST_SIGNAL        1
+#define WANT_TEST_SIGNAL        0
 
 // ----------------------------------------------------------------------
 // Local data storage
@@ -43,10 +43,23 @@
     // Flag indicates whether we believe we are receiving porch or not
     static bool b_inPorch;
     
+    // We keep track of how many times we have had to search for porch.
+    // Typically we could expect not to have to search for it when the
+    // plot goes beyond the end of the screen, however we may need to
+    // search on power-up and when the scan frequency changes
     static uint16_t u16_resyncCount;
+    
+    // For no reason at all we keep track of how many scans we detect
     static uint32_t u32_scanCount;
     
+    // When we are searching for porch, we use this flag to indicate that
     static bool b_waitingForPorch;
+    
+    // We keep track of how many milliseconds there are between porch
+    // detections. This indicates a fairly close timing of the scan
+    // frequency.
+    static uint16_t u16_scanFrequency;
+    static uint16_t u16_msFromPorchToPorch;
    
 // ----------------------------------------------------------------------
 // ScanInputPlotThisValue()
@@ -115,6 +128,15 @@
     return f_analogValue;
 }
 
+static void ScanInputUpdateScanFrequency(void)
+{
+    // Store the last porch to porch counter
+    u16_scanFrequency = u16_msFromPorchToPorch;
+    
+    // Restart the porch to porch counter
+    u16_msFromPorchToPorch = 0;
+}
+
 // ----------------------------------------------------------------------
 // ScanInputWaitForPorch()
 //
@@ -134,12 +156,19 @@
     
     b_waitingForPorch = false;
     
+    // Keep track of our scan frequency
+    ScanInputUpdateScanFrequency();
+    
     // Since we detected porch, start the plot over from the beginning
     u16_nextScanLine = 50;
     
     // The last height we consider to be 1 pixel on porch
     u16_lastHeight = 1;
     
+    // Keep track of how many times we had to wait for locating porch
+    // again after loosing it. Note that on power-up, if we are using
+    // the test signal output, it is driven to porch co-incident with
+    // the input test, so we start up with porch as the first sample
     ++u16_resyncCount;
 }
 
@@ -148,7 +177,7 @@
 //
 //
 // ----------------------------------------------------------------------
-static void ScanInputGetNextValue(void)
+static void ScanInputGetNextValue(bool b_allowPlotting)
 {
     float f_analogValue = ScanInputGetInputVoltage();
 
@@ -158,7 +187,7 @@
         // Did we previously know that we were in porch?
         if (false == b_inPorch)
         {
-            char pch_testMessage[21] = { 0 };
+            float f_plusFourPercent = 0.0f;
             
             // Flag the fact that we're in porch now
             b_inPorch = true;
@@ -169,21 +198,36 @@
             // The last height we consider to be 1 pixel on porch
             u16_lastHeight = 1;
             
-            (void)sprintf(pch_testMessage, "Resync %u, Scans %u", u16_resyncCount, ++u32_scanCount);
-            st_lcd.DisplayStringAt(1, LINE(0), (uint8_t *)pch_testMessage, LEFT_MODE);
+            // Update our scan frequency
+            ScanInputUpdateScanFrequency();
+            
+            // Since our timing in this device is off, we add a correction
+            f_plusFourPercent = (((float)u16_scanFrequency / 100.0f) * 4.3f);
+            
+            // Let the main module know what the scan rate is for display
+            // and for testing and evaluating
+            LaserMonMainInformScanInformation((uint16_t)((float)u16_scanFrequency + f_plusFourPercent), ++u32_scanCount);
         }
     }
     else
     {
         // We are in the ramp so flag the fact even if we already know
         b_inPorch = false;
+        
+        // Keep track of the scan frequency
+        u16_msFromPorchToPorch++;
     }
 
     // Indicate the next line to plot this reading on to
     u16_nextScanLine++;
     
-    // Call the function which plots this value
-    (void)ScanInputPlotThisValue(f_analogValue);
+    // The display may be in use for other functionality so we
+    // check to ensure that we are permitted to plot the input
+    if (true == b_allowPlotting)
+    {
+        // Call the function which plots this value
+        (void)ScanInputPlotThisValue(f_analogValue);
+    }
     
     // Are we about to exceed the display?
     if (u16_nextScanLine >= (LCD_HEIGHT - 10))
@@ -199,41 +243,43 @@
 // ----------------------------------------------------------------------
 // ScanInputThread()
 //
-// This thread wakes up every 1 millisecond to drive the input of the
-// signal coming in on the analog input -- or if it's enabled, to drive
-// the input based on the test signal for diagnostic and software
-// development use.
+// This is called once a millisecond however it is not a thread, the
+// thread class on this board ended up with timing that could not be
+// controlled so the main() loop calls us once a millisecond.
 //
 // ----------------------------------------------------------------------
-void ScanInputThread(void)
+void ScanInputThread(bool b_allowPlotting)
 {
+    // Are we waiting for porch synchronization?
     if (true == b_waitingForPorch)
     {
         // Start out searching for porch
         ScanInputWaitForPorch();
     }
 
-    ScanInputGetNextValue();
+    // Scan the signal coming in and optionally plot it
+    ScanInputGetNextValue(b_allowPlotting);
 }
 
 // ----------------------------------------------------------------------
 // ScanInputInit()
 //
+// Initialize this module's locally-held data
+//
 // ----------------------------------------------------------------------
 void ScanInputInit(void)
 {
     // Start out with the LED turned ON
     st_scanInputLED = 1;
     
-    // Initialize locally-held variables
-    u16_nextScanLine = 50;
-    
-    // Flag the fact that we don't believe that we are seeing porch
-    b_inPorch         = false;
-    b_waitingForPorch = true;
-    
-    u16_resyncCount = 0;
-    u32_scanCount   = 0;
+    // Initialize loc ally-held variables
+    u16_nextScanLine       = 50;
+    b_inPorch              = false;
+    b_waitingForPorch      = true;
+    u16_scanFrequency      = 0;    
+    u16_resyncCount        = 0;
+    u32_scanCount          = 0;
+    u16_msFromPorchToPorch = 0;
 }
 
 // End of file
diff -r b9d4b9b8884c -r cbcf2695a4a1 LaserMon-ScanInput.h
--- a/LaserMon-ScanInput.h	Fri Jun 14 21:11:31 2019 +0000
+++ b/LaserMon-ScanInput.h	Mon Jun 17 17:11:07 2019 +0000
@@ -12,7 +12,7 @@
 // ----------------------------------------------------------------------
 
 extern void ScanInputInit(void);
-extern void ScanInputThread(void);
+extern void ScanInputThread(bool b_allowPlotting);
 
 // End of file
 
diff -r b9d4b9b8884c -r cbcf2695a4a1 LaserMon-TEC.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LaserMon-TEC.cpp	Mon Jun 17 17:11:07 2019 +0000
@@ -0,0 +1,104 @@
+
+// ----------------------------------------------------------------------
+// LaserMon-TEC.cpp
+//
+// Fredric L. Rice, June 2019
+//
+// ----------------------------------------------------------------------
+
+#include "mbed.h"                   // The mbed operating system
+#include "LCD_DISCO_F429ZI.h"       // For controlling the LCD
+#include "TS_DISCO_F429ZI.h"        // For controlling the touch screen
+#include "LaserMon-Main.h"          // For data exported to us
+#include "LaserMon-TEC.h"           // Always include ourself
+
+// ----------------------------------------------------------------------
+// Local data storage
+//
+// ----------------------------------------------------------------------
+
+    // We bring in the TEC voltage to scan what it is
+    static AnalogIn st_TECInput(TEC_VOLTAGE_IN);
+    
+    // We store the last ten TEC readings and keep a running average
+    // of the last ten so that the main module may find out what the
+    // average is and display it
+    static uint16_t u16_TECHistory[TEC_HISTORY_COUNT_MAX];
+    static uint8_t  u8_TECHistoryCount;
+    static uint16_t u16_TECHistoryRunningAverage;
+    
+// ----------------------------------------------------------------------
+// TECGetLastTenAverage()
+//
+// ----------------------------------------------------------------------
+uint16_t TECGetLastTenAverage(void)
+{
+    return u16_TECHistoryRunningAverage;
+}
+
+// ----------------------------------------------------------------------
+//
+//
+// ----------------------------------------------------------------------
+void TECThread(void)
+{
+    uint16_t u16_TECVoltage  = 0;
+    float    f_rawTECVoltage = 0.0f;
+    
+    // Get the current voltage
+    f_rawTECVoltage = st_TECInput.read() * 3.3f;
+    
+    // The TEC voltage is converted from a floating point in to
+    // 16 bit value with the value after the decimal moved to
+    // the right by two decimal place
+    u16_TECVoltage = (uint16_t)(f_rawTECVoltage * 100.0f);
+    
+    // Inform the main module what the TEC voltage is
+    LaserMonMainInformTECVoltage(u16_TECVoltage);
+    
+    // Do we have lessd than our TEC history values stored so far?
+    if (u8_TECHistoryCount < TEC_HISTORY_COUNT_MAX)
+    {
+        // Since we have fewer than our maximum history, store it
+        u16_TECHistory[u8_TECHistoryCount++] = u16_TECVoltage;
+    }
+    else
+    {
+#if 1
+        // Discard the oldest history value that we have
+        for (uint8_t u8_thisValue = 1; u8_thisValue < TEC_HISTORY_COUNT_MAX; u8_thisValue++)
+        {
+            // Move the history value over to the left once
+            u16_TECHistory[u8_thisValue] = u16_TECHistory[u8_thisValue - 1];
+        }
+        
+        // Now store the latest value in to the history array
+        u16_TECHistory[TEC_HISTORY_COUNT_MAX - 1] = u16_TECVoltage;
+#endif
+    }
+    
+    // Compute the average TEC value
+    u16_TECHistoryRunningAverage = 0;
+    
+    for (uint8_t u8_thisValue = 0; u8_thisValue < u8_TECHistoryCount; u8_thisValue++)
+    {
+        u16_TECHistoryRunningAverage += u16_TECHistory[u8_thisValue];
+    }
+    
+    // Compute the average
+    u16_TECHistoryRunningAverage /= u8_TECHistoryCount;
+}
+
+// ----------------------------------------------------------------------
+//
+//
+// ----------------------------------------------------------------------
+void TECInit(void)
+{
+    // Initialize locally-held data
+    u8_TECHistoryCount            = 0;
+    u16_TECHistoryRunningAverage  = 0;
+}
+
+// End of file
+
diff -r b9d4b9b8884c -r cbcf2695a4a1 LaserMon-TEC.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LaserMon-TEC.h	Mon Jun 17 17:11:07 2019 +0000
@@ -0,0 +1,26 @@
+
+// ----------------------------------------------------------------------
+// LaserMon-TEC.h
+//
+// Fredric L. Rice, June 2019
+//
+// ----------------------------------------------------------------------
+
+// ----------------------------------------------------------------------
+// Defined constants and MACROs we may use
+//
+// ----------------------------------------------------------------------
+
+#define TEC_HISTORY_COUNT_MAX       10
+
+// ----------------------------------------------------------------------
+// External function prototype that we will export
+// 
+// ----------------------------------------------------------------------
+
+extern void     TECInit(void);
+extern void     TECThread(void);
+extern uint16_t TECGetLastTenAverage(void);
+
+// End of file
+
diff -r b9d4b9b8884c -r cbcf2695a4a1 LaserMon-TestOutput.cpp
--- a/LaserMon-TestOutput.cpp	Fri Jun 14 21:11:31 2019 +0000
+++ b/LaserMon-TestOutput.cpp	Mon Jun 17 17:11:07 2019 +0000
@@ -36,7 +36,7 @@
 
     // We create an analog output
     static AnalogOut st_testSignalOut(TEST_SIGNAL_OUT);
-
+    
     // For diagnostic purposes to show that the test output is working
     static DigitalOut st_testSignalLED(LED1);
     
@@ -64,11 +64,15 @@
 // ----------------------------------------------------------------------
 // TestOutputThread()
 //
+// This is called once a millisecond however it is not a thread, the
+// thread class on this board ended up with timing that could not be
+// controlled so the main() loop calls us once a millisecond.
+//
 // ----------------------------------------------------------------------
 void TestOutputThread(void)
 {
     static uint8_t u8_ledTimeoutTimer = 0;
-    
+
     // Do we need to turn the scan-completed LED off?
     if (u8_ledTimeoutTimer > 0)
     {
@@ -143,7 +147,7 @@
 // ----------------------------------------------------------------------
 // TestOutputInit()
 //
-// This function initializes this module and then launches the thread
+// This function initializes this module's locally-held data
 //
 // ----------------------------------------------------------------------
 void TestOutputInit(void)