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
Revision 1:b9d4b9b8884c, committed 2019-06-14
- Comitter:
- Damotclese
- Date:
- Fri Jun 14 21:11:31 2019 +0000
- Parent:
- 0:1ebe7d222470
- Child:
- 2:cbcf2695a4a1
- Commit message:
- Threat timing is very bad, a thread will average waking up once a millisecond when asked but there is a lot of slop. Instead of launching threads I instead call the "threads" from main() now.;
Changed in this revision
--- a/LaserMon-Main.cpp Mon Jun 10 17:10:01 2019 +0000
+++ b/LaserMon-Main.cpp Fri Jun 14 21:11:31 2019 +0000
@@ -74,37 +74,12 @@
// Go in to a forever loop for the main thread which does nothing
while(true)
{
- // Wait for 1 second and then wait again
- wait(1.0);
+ // Wait for 1 millisecond
+ wait_us(899);
+ TestOutputThread();
+ ScanInputThread();
}
}
-// ----------------------------------------------------------------------
-// accurate_wait_ms()
-//
-// Because the wait() and wait_ms() library calls for the board we are
-// using is not accurate, this function is provided which uses
-// microseconds to scale the requested wait offered in milliseconds.
-//
-// ----------------------------------------------------------------------
-void accurate_wait_ms(uint16_t u16_thisManyMilliseconds)
-{
- // There are one million microseconds in a second
- // There are one thousand milliseconds in a second
- // Compute how many microseconds would normally be needed to
- // perform the reqested number of milliseconds to wait if the
- // system clock / crystal were accurate
- uint64_t u64_thisManyMicroseconds = (u16_thisManyMilliseconds * 100000);
-
- // Since the clock appears to run much faster than expected by
- // the mbed library, divide the number of microseconds by a
- // hard-coded scaling factor to attempt to yield a number that
- // is closer to what we actually get
- u64_thisManyMicroseconds /= 300ul;
-
- // Now wait that many microseconds asking the library to do it
- wait_us((int)u64_thisManyMicroseconds);
-}
-
// End of file
--- a/LaserMon-Main.h Mon Jun 10 17:10:01 2019 +0000 +++ b/LaserMon-Main.h Fri Jun 14 21:11:31 2019 +0000 @@ -18,6 +18,9 @@ #define LCD_WIDTH 240 #define LCD_HEIGHT 320 +// This describes how many pixels to the right we start plotting porch +#define INITIAL_PORCH_HEIGHT 50 + // ---------------------------------------------------------------------- // Describe data which we export to all other modules // @@ -34,7 +37,6 @@ // // ---------------------------------------------------------------------- -extern void accurate_wait_ms(uint16_t u16_thisManyMilliseconds); // End of file
--- a/LaserMon-ScanInput.cpp Mon Jun 10 17:10:01 2019 +0000
+++ b/LaserMon-ScanInput.cpp Fri Jun 14 21:11:31 2019 +0000
@@ -26,10 +26,7 @@
// We create an analog input
static AnalogIn st_scanInput(LASER_SCAN_IN);
-
- // We will be creating a thread
- static Thread st_scanInputThread;
-
+
// For diagnostic purposes to show that the Laser Scan is operating
static DigitalOut st_scanInputLED(LED2);
@@ -40,10 +37,17 @@
// This value contains the next scan line number to plot
static uint16_t u16_nextScanLine;
+ // We store the last pixel's height so we may plot
static uint16_t u16_lastHeight = 0;
- bool b_done = false;
+ // Flag indicates whether we believe we are receiving porch or not
+ static bool b_inPorch;
+ static uint16_t u16_resyncCount;
+ static uint32_t u32_scanCount;
+
+ static bool b_waitingForPorch;
+
// ----------------------------------------------------------------------
// ScanInputPlotThisValue()
//
@@ -65,30 +69,78 @@
static void ScanInputPlotThisValue(float f_analogValue)
{
// Compute the percentage of LCD height
- uint16_t u16_pixelHeight = ((f_analogValue / 3.8f) * LCD_HEIGHT);
+ uint16_t u16_pixelHeight = ((f_analogValue / 3.3f) * ((float)LCD_HEIGHT - 10.0f));
u16_pixelHeight /= 2;
u16_pixelHeight += 10;
- // Plot the pixel
- if (u16_nextScanLine > 0)
+ // Clear the entire current scan line to plot
+ st_lcd.SetTextColor(LCD_COLOR_WHITE);
+ st_lcd.DrawLine(1, u16_nextScanLine, LCD_WIDTH, u16_nextScanLine);
+
+ // Plot from the previous pixel to the new one
+ st_lcd.SetTextColor(LCD_COLOR_BLUE);
+
+ // Are we currently in porch? We plot differently if so
+ if (false == b_inPorch)
{
- st_lcd.DrawLine(u16_pixelHeight, u16_nextScanLine, u16_lastHeight, u16_nextScanLine - 1);
+ // We plot ramp from the previous scan line's height to the current scan line and height
+ st_lcd.DrawLine(u16_lastHeight, u16_nextScanLine - 1, u16_pixelHeight, u16_nextScanLine);
}
else
{
- st_lcd.DrawPixel(u16_pixelHeight, u16_nextScanLine, LCD_COLOR_BLACK);
+ // We plot the porch at a height of 10 pixels
+ st_lcd.DrawLine(10, u16_nextScanLine - 1, 10, u16_nextScanLine);
}
-
+
+ // Keep track of the last height so we may plot
u16_lastHeight = u16_pixelHeight;
+}
+
+// ----------------------------------------------------------------------
+//
+//
+// ----------------------------------------------------------------------
+static float ScanInputGetInputVoltage(void)
+{
+ // Get the current analog input value and convert to volts
+ float f_analogValue = st_scanInput.read() * 3.3f;
- // Increment the scan line and see if it wrapped
- if (++u16_nextScanLine >= LCD_WIDTH)
+#if WANT_TEST_SIGNAL
+ // Use the test output signal voltage instead
+ f_analogValue = f_rampVoltage;
+#endif
+
+ // Return either the actual analog in or test voltage
+ return f_analogValue;
+}
+
+// ----------------------------------------------------------------------
+// ScanInputWaitForPorch()
+//
+// ----------------------------------------------------------------------
+static void ScanInputWaitForPorch(void)
+{
+ float f_analogValue = 5.0f;
+
+ // While we're not seeing porch, loop
+ if (f_analogValue > 0.5f)
{
- u16_nextScanLine = 40;
+ return;
+ }
- b_done = true;
- }
+ // Flag the fact that we're in porch
+ b_inPorch = true;
+
+ b_waitingForPorch = false;
+
+ // 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;
+
+ ++u16_resyncCount;
}
// ----------------------------------------------------------------------
@@ -98,16 +150,50 @@
// ----------------------------------------------------------------------
static void ScanInputGetNextValue(void)
{
- // Get the current analog input value and convert to volts
- float f_analogValue = st_scanInput.read() * 3.3f;
+ float f_analogValue = ScanInputGetInputVoltage();
-#if WANT_TEST_SIGNAL
- // Use the test output signal voltage instead
- f_analogValue = f_rampVoltage;
-#endif
+ // Dows the input indicate that we are in porch?
+ if (f_analogValue < 1.0f)
+ {
+ // Did we previously know that we were in porch?
+ if (false == b_inPorch)
+ {
+ char pch_testMessage[21] = { 0 };
+
+ // Flag the fact that we're in porch now
+ b_inPorch = true;
+
+ // Since we detected a new porch, start the plot over
+ u16_nextScanLine = 49;
+
+ // 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);
+ }
+ }
+ else
+ {
+ // We are in the ramp so flag the fact even if we already know
+ b_inPorch = false;
+ }
+ // Indicate the next line to plot this reading on to
+ u16_nextScanLine++;
+
// Call the function which plots this value
- ScanInputPlotThisValue(f_analogValue);
+ (void)ScanInputPlotThisValue(f_analogValue);
+
+ // Are we about to exceed the display?
+ if (u16_nextScanLine >= (LCD_HEIGHT - 10))
+ {
+ // We have lost track of porch so we must search for it again
+ b_waitingForPorch = true;
+ }
+
+ // Set the LED with whether we are at porch or not
+ st_scanInputLED = b_inPorch;
}
// ----------------------------------------------------------------------
@@ -119,20 +205,15 @@
// development use.
//
// ----------------------------------------------------------------------
-static void ScanInputThread(void)
+void ScanInputThread(void)
{
- // This thread goes in to a forever loop waking up once a millisecond
- while(true)
+ if (true == b_waitingForPorch)
{
- if (false == b_done)
- {
- // Drive the input scanner
- ScanInputGetNextValue();
- }
-
- // Wait for 1 millisecond
- accurate_wait_ms(1);
+ // Start out searching for porch
+ ScanInputWaitForPorch();
}
+
+ ScanInputGetNextValue();
}
// ----------------------------------------------------------------------
@@ -145,10 +226,14 @@
st_scanInputLED = 1;
// Initialize locally-held variables
- u16_nextScanLine = 40;
+ u16_nextScanLine = 50;
- // Launch the thread
- st_scanInputThread.start(ScanInputThread);
+ // 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;
}
// End of file
--- a/LaserMon-ScanInput.h Mon Jun 10 17:10:01 2019 +0000 +++ b/LaserMon-ScanInput.h Fri Jun 14 21:11:31 2019 +0000 @@ -12,6 +12,7 @@ // ---------------------------------------------------------------------- extern void ScanInputInit(void); +extern void ScanInputThread(void); // End of file
--- a/LaserMon-TestOutput.cpp Mon Jun 10 17:10:01 2019 +0000
+++ b/LaserMon-TestOutput.cpp Fri Jun 14 21:11:31 2019 +0000
@@ -24,10 +24,10 @@
//
// ----------------------------------------------------------------------
-#define PORCH_WIDTH 40 // In milliseconds
-#define RAMP_WIDTH 216 // In milliseconds
+#define PORCH_WIDTH 10 // In milliseconds
+#define RAMP_WIDTH 250 // In milliseconds
#define SCAN_LENGTH (PORCH_WIDTH + RAMP_WIDTH) // In milliseconds
-#define STEP_HEIGHT 2.5f // In volts
+#define STEP_HEIGHT 1.8f // In volts
// ----------------------------------------------------------------------
// Local data storage
@@ -36,10 +36,7 @@
// We create an analog output
static AnalogOut st_testSignalOut(TEST_SIGNAL_OUT);
-
- // We will be creating a thread
- static Thread st_testSignalOutThread;
-
+
// For diagnostic purposes to show that the test output is working
static DigitalOut st_testSignalLED(LED1);
@@ -52,7 +49,7 @@
// incremental voltage should be so that when the ramp has
// been completed, we end up at 3.3 volts, starting from the
// initial step.
- static const float f_stepIncrement = ((3.3f - STEP_HEIGHT) / (float)RAMP_WIDTH);
+ static const float f_stepIncrement = ((3.3f - STEP_HEIGHT) / ((float)RAMP_WIDTH - 10.0f));
// ----------------------------------------------------------------------
// Data that we will export globally
@@ -65,10 +62,10 @@
float f_rampVoltage = 0.0f;
// ----------------------------------------------------------------------
-// TestOutputDriveWaveformAT1Millisecond()
+// TestOutputThread()
//
// ----------------------------------------------------------------------
-static void TestOutputDriveWaveformAT1Millisecond(void)
+void TestOutputThread(void)
{
static uint8_t u8_ledTimeoutTimer = 0;
@@ -86,13 +83,9 @@
// Are we stepping out the porch?
if (true == b_onPorch)
{
- // Yes, are we just now starting on the porch?
- if (PORCH_WIDTH == u16_countRemaining)
- {
- // Yes, so drive the voltage down to zero for porch
- st_testSignalOut.write(0.0);
- }
-
+ // Drive the voltage down to zero for porch
+ st_testSignalOut.write(f_rampVoltage = 0.0f);
+
// Is the porch time remaining still have some time?
if (u16_countRemaining > 0)
{
@@ -105,11 +98,8 @@
// Set the ramp duration
u16_countRemaining = RAMP_WIDTH;
- // Set the output voltage to the step height
- f_rampVoltage = STEP_HEIGHT;
-
- // Set the initial step height
- st_testSignalOut.write(f_rampVoltage / 3.3f);
+ // Set the next output voltage to the step height
+ f_rampVoltage = (STEP_HEIGHT - f_stepIncrement);
}
}
}
@@ -151,27 +141,6 @@
}
// ----------------------------------------------------------------------
-// TestOutputThread()
-//
-// This thread sleeps for 1 millisecond and then calls the function
-// that sends the wavefor out the analog output pin.
-//
-// ----------------------------------------------------------------------
-static void TestOutputThread(void)
-{
-
- while(true)
- {
- // Wait for 1 millisecond
- accurate_wait_ms(1);
-
- // Call the routine which drives the wave form output
- // one millisecond at a time.
- TestOutputDriveWaveformAT1Millisecond();
- }
-}
-
-// ----------------------------------------------------------------------
// TestOutputInit()
//
// This function initializes this module and then launches the thread
@@ -182,9 +151,6 @@
// Initialize this module
b_onPorch = true;
u16_countRemaining = PORCH_WIDTH;
-
- // Start the test output thread
- st_testSignalOutThread.start(TestOutputThread);
}
// End of file
--- a/LaserMon-TestOutput.h Mon Jun 10 17:10:01 2019 +0000 +++ b/LaserMon-TestOutput.h Fri Jun 14 21:11:31 2019 +0000 @@ -19,6 +19,7 @@ // ---------------------------------------------------------------------- extern void TestOutputInit(void); +extern void TestOutputThread(void); // End of file