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

Committer:
Damotclese
Date:
Fri Jun 14 21:11:31 2019 +0000
Revision:
1:b9d4b9b8884c
Parent:
0:1ebe7d222470
Child:
2:cbcf2695a4a1
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.;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Damotclese 0:1ebe7d222470 1
Damotclese 0:1ebe7d222470 2 // ----------------------------------------------------------------------
Damotclese 0:1ebe7d222470 3 // LaserMon-ScanInput.cpp
Damotclese 0:1ebe7d222470 4 //
Damotclese 0:1ebe7d222470 5 // Fredric L. Rice, June 2019
Damotclese 0:1ebe7d222470 6 //
Damotclese 0:1ebe7d222470 7 // ----------------------------------------------------------------------
Damotclese 0:1ebe7d222470 8
Damotclese 0:1ebe7d222470 9 #include "mbed.h" // The mbed operating system
Damotclese 0:1ebe7d222470 10 #include "LCD_DISCO_F429ZI.h" // For controlling the LCD
Damotclese 0:1ebe7d222470 11 #include "TS_DISCO_F429ZI.h" // For controlling the touch screen
Damotclese 0:1ebe7d222470 12 #include "LaserMon-Main.h" // For data exported to us
Damotclese 0:1ebe7d222470 13 #include "LaserMon-TestOutput.h" // For test signal
Damotclese 0:1ebe7d222470 14
Damotclese 0:1ebe7d222470 15 // ----------------------------------------------------------------------
Damotclese 0:1ebe7d222470 16 // Options, defined constants, and MACROs
Damotclese 0:1ebe7d222470 17 //
Damotclese 0:1ebe7d222470 18 // ----------------------------------------------------------------------
Damotclese 0:1ebe7d222470 19
Damotclese 0:1ebe7d222470 20 #define WANT_TEST_SIGNAL 1
Damotclese 0:1ebe7d222470 21
Damotclese 0:1ebe7d222470 22 // ----------------------------------------------------------------------
Damotclese 0:1ebe7d222470 23 // Local data storage
Damotclese 0:1ebe7d222470 24 //
Damotclese 0:1ebe7d222470 25 // ----------------------------------------------------------------------
Damotclese 0:1ebe7d222470 26
Damotclese 0:1ebe7d222470 27 // We create an analog input
Damotclese 0:1ebe7d222470 28 static AnalogIn st_scanInput(LASER_SCAN_IN);
Damotclese 1:b9d4b9b8884c 29
Damotclese 0:1ebe7d222470 30 // For diagnostic purposes to show that the Laser Scan is operating
Damotclese 0:1ebe7d222470 31 static DigitalOut st_scanInputLED(LED2);
Damotclese 0:1ebe7d222470 32
Damotclese 0:1ebe7d222470 33 // There are LCD_HEIGHT possible scan lines with a height of
Damotclese 0:1ebe7d222470 34 // LCD_WIDTH -- yes, the defined constant names are swapped
Damotclese 0:1ebe7d222470 35 // because we plot sideways.
Damotclese 0:1ebe7d222470 36 //
Damotclese 0:1ebe7d222470 37 // This value contains the next scan line number to plot
Damotclese 0:1ebe7d222470 38 static uint16_t u16_nextScanLine;
Damotclese 0:1ebe7d222470 39
Damotclese 1:b9d4b9b8884c 40 // We store the last pixel's height so we may plot
Damotclese 0:1ebe7d222470 41 static uint16_t u16_lastHeight = 0;
Damotclese 0:1ebe7d222470 42
Damotclese 1:b9d4b9b8884c 43 // Flag indicates whether we believe we are receiving porch or not
Damotclese 1:b9d4b9b8884c 44 static bool b_inPorch;
Damotclese 0:1ebe7d222470 45
Damotclese 1:b9d4b9b8884c 46 static uint16_t u16_resyncCount;
Damotclese 1:b9d4b9b8884c 47 static uint32_t u32_scanCount;
Damotclese 1:b9d4b9b8884c 48
Damotclese 1:b9d4b9b8884c 49 static bool b_waitingForPorch;
Damotclese 1:b9d4b9b8884c 50
Damotclese 0:1ebe7d222470 51 // ----------------------------------------------------------------------
Damotclese 0:1ebe7d222470 52 // ScanInputPlotThisValue()
Damotclese 0:1ebe7d222470 53 //
Damotclese 0:1ebe7d222470 54 // What percentage of LCD_HEIGHT is the voltage? We need to scale 0 to
Damotclese 0:1ebe7d222470 55 // 3.3 volts across LCD_HEIGHT, with 0 being zero, and 3.3 volts being
Damotclese 0:1ebe7d222470 56 // LCD_HEIGHT.
Damotclese 0:1ebe7d222470 57 //
Damotclese 0:1ebe7d222470 58 // We compute the percentage of 3.3 volts that the input signal is
Damotclese 0:1ebe7d222470 59 // currently showing, then we compute that percentage of LCD_HEIGHT to
Damotclese 0:1ebe7d222470 60 // determine how many pixels on a scan line that percentage is. That
Damotclese 0:1ebe7d222470 61 // gives us the height of the plot line while u16_nextScanLine gives
Damotclese 0:1ebe7d222470 62 // us the line to plot it on.
Damotclese 0:1ebe7d222470 63 //
Damotclese 0:1ebe7d222470 64 // This is easy because the value passed to this function is a value
Damotclese 0:1ebe7d222470 65 // from 0.0 to 1.0 which is a percentage of 3.3 volts, so we use the
Damotclese 0:1ebe7d222470 66 // value against LCD_HEIGHT to yield the percentage of height.
Damotclese 0:1ebe7d222470 67 //
Damotclese 0:1ebe7d222470 68 // ----------------------------------------------------------------------
Damotclese 0:1ebe7d222470 69 static void ScanInputPlotThisValue(float f_analogValue)
Damotclese 0:1ebe7d222470 70 {
Damotclese 0:1ebe7d222470 71 // Compute the percentage of LCD height
Damotclese 1:b9d4b9b8884c 72 uint16_t u16_pixelHeight = ((f_analogValue / 3.3f) * ((float)LCD_HEIGHT - 10.0f));
Damotclese 0:1ebe7d222470 73
Damotclese 0:1ebe7d222470 74 u16_pixelHeight /= 2;
Damotclese 0:1ebe7d222470 75 u16_pixelHeight += 10;
Damotclese 0:1ebe7d222470 76
Damotclese 1:b9d4b9b8884c 77 // Clear the entire current scan line to plot
Damotclese 1:b9d4b9b8884c 78 st_lcd.SetTextColor(LCD_COLOR_WHITE);
Damotclese 1:b9d4b9b8884c 79 st_lcd.DrawLine(1, u16_nextScanLine, LCD_WIDTH, u16_nextScanLine);
Damotclese 1:b9d4b9b8884c 80
Damotclese 1:b9d4b9b8884c 81 // Plot from the previous pixel to the new one
Damotclese 1:b9d4b9b8884c 82 st_lcd.SetTextColor(LCD_COLOR_BLUE);
Damotclese 1:b9d4b9b8884c 83
Damotclese 1:b9d4b9b8884c 84 // Are we currently in porch? We plot differently if so
Damotclese 1:b9d4b9b8884c 85 if (false == b_inPorch)
Damotclese 0:1ebe7d222470 86 {
Damotclese 1:b9d4b9b8884c 87 // We plot ramp from the previous scan line's height to the current scan line and height
Damotclese 1:b9d4b9b8884c 88 st_lcd.DrawLine(u16_lastHeight, u16_nextScanLine - 1, u16_pixelHeight, u16_nextScanLine);
Damotclese 0:1ebe7d222470 89 }
Damotclese 0:1ebe7d222470 90 else
Damotclese 0:1ebe7d222470 91 {
Damotclese 1:b9d4b9b8884c 92 // We plot the porch at a height of 10 pixels
Damotclese 1:b9d4b9b8884c 93 st_lcd.DrawLine(10, u16_nextScanLine - 1, 10, u16_nextScanLine);
Damotclese 0:1ebe7d222470 94 }
Damotclese 1:b9d4b9b8884c 95
Damotclese 1:b9d4b9b8884c 96 // Keep track of the last height so we may plot
Damotclese 0:1ebe7d222470 97 u16_lastHeight = u16_pixelHeight;
Damotclese 1:b9d4b9b8884c 98 }
Damotclese 1:b9d4b9b8884c 99
Damotclese 1:b9d4b9b8884c 100 // ----------------------------------------------------------------------
Damotclese 1:b9d4b9b8884c 101 //
Damotclese 1:b9d4b9b8884c 102 //
Damotclese 1:b9d4b9b8884c 103 // ----------------------------------------------------------------------
Damotclese 1:b9d4b9b8884c 104 static float ScanInputGetInputVoltage(void)
Damotclese 1:b9d4b9b8884c 105 {
Damotclese 1:b9d4b9b8884c 106 // Get the current analog input value and convert to volts
Damotclese 1:b9d4b9b8884c 107 float f_analogValue = st_scanInput.read() * 3.3f;
Damotclese 0:1ebe7d222470 108
Damotclese 1:b9d4b9b8884c 109 #if WANT_TEST_SIGNAL
Damotclese 1:b9d4b9b8884c 110 // Use the test output signal voltage instead
Damotclese 1:b9d4b9b8884c 111 f_analogValue = f_rampVoltage;
Damotclese 1:b9d4b9b8884c 112 #endif
Damotclese 1:b9d4b9b8884c 113
Damotclese 1:b9d4b9b8884c 114 // Return either the actual analog in or test voltage
Damotclese 1:b9d4b9b8884c 115 return f_analogValue;
Damotclese 1:b9d4b9b8884c 116 }
Damotclese 1:b9d4b9b8884c 117
Damotclese 1:b9d4b9b8884c 118 // ----------------------------------------------------------------------
Damotclese 1:b9d4b9b8884c 119 // ScanInputWaitForPorch()
Damotclese 1:b9d4b9b8884c 120 //
Damotclese 1:b9d4b9b8884c 121 // ----------------------------------------------------------------------
Damotclese 1:b9d4b9b8884c 122 static void ScanInputWaitForPorch(void)
Damotclese 1:b9d4b9b8884c 123 {
Damotclese 1:b9d4b9b8884c 124 float f_analogValue = 5.0f;
Damotclese 1:b9d4b9b8884c 125
Damotclese 1:b9d4b9b8884c 126 // While we're not seeing porch, loop
Damotclese 1:b9d4b9b8884c 127 if (f_analogValue > 0.5f)
Damotclese 0:1ebe7d222470 128 {
Damotclese 1:b9d4b9b8884c 129 return;
Damotclese 1:b9d4b9b8884c 130 }
Damotclese 0:1ebe7d222470 131
Damotclese 1:b9d4b9b8884c 132 // Flag the fact that we're in porch
Damotclese 1:b9d4b9b8884c 133 b_inPorch = true;
Damotclese 1:b9d4b9b8884c 134
Damotclese 1:b9d4b9b8884c 135 b_waitingForPorch = false;
Damotclese 1:b9d4b9b8884c 136
Damotclese 1:b9d4b9b8884c 137 // Since we detected porch, start the plot over from the beginning
Damotclese 1:b9d4b9b8884c 138 u16_nextScanLine = 50;
Damotclese 1:b9d4b9b8884c 139
Damotclese 1:b9d4b9b8884c 140 // The last height we consider to be 1 pixel on porch
Damotclese 1:b9d4b9b8884c 141 u16_lastHeight = 1;
Damotclese 1:b9d4b9b8884c 142
Damotclese 1:b9d4b9b8884c 143 ++u16_resyncCount;
Damotclese 0:1ebe7d222470 144 }
Damotclese 0:1ebe7d222470 145
Damotclese 0:1ebe7d222470 146 // ----------------------------------------------------------------------
Damotclese 0:1ebe7d222470 147 // ScanInputGetNextValue()
Damotclese 0:1ebe7d222470 148 //
Damotclese 0:1ebe7d222470 149 //
Damotclese 0:1ebe7d222470 150 // ----------------------------------------------------------------------
Damotclese 0:1ebe7d222470 151 static void ScanInputGetNextValue(void)
Damotclese 0:1ebe7d222470 152 {
Damotclese 1:b9d4b9b8884c 153 float f_analogValue = ScanInputGetInputVoltage();
Damotclese 0:1ebe7d222470 154
Damotclese 1:b9d4b9b8884c 155 // Dows the input indicate that we are in porch?
Damotclese 1:b9d4b9b8884c 156 if (f_analogValue < 1.0f)
Damotclese 1:b9d4b9b8884c 157 {
Damotclese 1:b9d4b9b8884c 158 // Did we previously know that we were in porch?
Damotclese 1:b9d4b9b8884c 159 if (false == b_inPorch)
Damotclese 1:b9d4b9b8884c 160 {
Damotclese 1:b9d4b9b8884c 161 char pch_testMessage[21] = { 0 };
Damotclese 1:b9d4b9b8884c 162
Damotclese 1:b9d4b9b8884c 163 // Flag the fact that we're in porch now
Damotclese 1:b9d4b9b8884c 164 b_inPorch = true;
Damotclese 1:b9d4b9b8884c 165
Damotclese 1:b9d4b9b8884c 166 // Since we detected a new porch, start the plot over
Damotclese 1:b9d4b9b8884c 167 u16_nextScanLine = 49;
Damotclese 1:b9d4b9b8884c 168
Damotclese 1:b9d4b9b8884c 169 // The last height we consider to be 1 pixel on porch
Damotclese 1:b9d4b9b8884c 170 u16_lastHeight = 1;
Damotclese 1:b9d4b9b8884c 171
Damotclese 1:b9d4b9b8884c 172 (void)sprintf(pch_testMessage, "Resync %u, Scans %u", u16_resyncCount, ++u32_scanCount);
Damotclese 1:b9d4b9b8884c 173 st_lcd.DisplayStringAt(1, LINE(0), (uint8_t *)pch_testMessage, LEFT_MODE);
Damotclese 1:b9d4b9b8884c 174 }
Damotclese 1:b9d4b9b8884c 175 }
Damotclese 1:b9d4b9b8884c 176 else
Damotclese 1:b9d4b9b8884c 177 {
Damotclese 1:b9d4b9b8884c 178 // We are in the ramp so flag the fact even if we already know
Damotclese 1:b9d4b9b8884c 179 b_inPorch = false;
Damotclese 1:b9d4b9b8884c 180 }
Damotclese 0:1ebe7d222470 181
Damotclese 1:b9d4b9b8884c 182 // Indicate the next line to plot this reading on to
Damotclese 1:b9d4b9b8884c 183 u16_nextScanLine++;
Damotclese 1:b9d4b9b8884c 184
Damotclese 0:1ebe7d222470 185 // Call the function which plots this value
Damotclese 1:b9d4b9b8884c 186 (void)ScanInputPlotThisValue(f_analogValue);
Damotclese 1:b9d4b9b8884c 187
Damotclese 1:b9d4b9b8884c 188 // Are we about to exceed the display?
Damotclese 1:b9d4b9b8884c 189 if (u16_nextScanLine >= (LCD_HEIGHT - 10))
Damotclese 1:b9d4b9b8884c 190 {
Damotclese 1:b9d4b9b8884c 191 // We have lost track of porch so we must search for it again
Damotclese 1:b9d4b9b8884c 192 b_waitingForPorch = true;
Damotclese 1:b9d4b9b8884c 193 }
Damotclese 1:b9d4b9b8884c 194
Damotclese 1:b9d4b9b8884c 195 // Set the LED with whether we are at porch or not
Damotclese 1:b9d4b9b8884c 196 st_scanInputLED = b_inPorch;
Damotclese 0:1ebe7d222470 197 }
Damotclese 0:1ebe7d222470 198
Damotclese 0:1ebe7d222470 199 // ----------------------------------------------------------------------
Damotclese 0:1ebe7d222470 200 // ScanInputThread()
Damotclese 0:1ebe7d222470 201 //
Damotclese 0:1ebe7d222470 202 // This thread wakes up every 1 millisecond to drive the input of the
Damotclese 0:1ebe7d222470 203 // signal coming in on the analog input -- or if it's enabled, to drive
Damotclese 0:1ebe7d222470 204 // the input based on the test signal for diagnostic and software
Damotclese 0:1ebe7d222470 205 // development use.
Damotclese 0:1ebe7d222470 206 //
Damotclese 0:1ebe7d222470 207 // ----------------------------------------------------------------------
Damotclese 1:b9d4b9b8884c 208 void ScanInputThread(void)
Damotclese 0:1ebe7d222470 209 {
Damotclese 1:b9d4b9b8884c 210 if (true == b_waitingForPorch)
Damotclese 0:1ebe7d222470 211 {
Damotclese 1:b9d4b9b8884c 212 // Start out searching for porch
Damotclese 1:b9d4b9b8884c 213 ScanInputWaitForPorch();
Damotclese 0:1ebe7d222470 214 }
Damotclese 1:b9d4b9b8884c 215
Damotclese 1:b9d4b9b8884c 216 ScanInputGetNextValue();
Damotclese 0:1ebe7d222470 217 }
Damotclese 0:1ebe7d222470 218
Damotclese 0:1ebe7d222470 219 // ----------------------------------------------------------------------
Damotclese 0:1ebe7d222470 220 // ScanInputInit()
Damotclese 0:1ebe7d222470 221 //
Damotclese 0:1ebe7d222470 222 // ----------------------------------------------------------------------
Damotclese 0:1ebe7d222470 223 void ScanInputInit(void)
Damotclese 0:1ebe7d222470 224 {
Damotclese 0:1ebe7d222470 225 // Start out with the LED turned ON
Damotclese 0:1ebe7d222470 226 st_scanInputLED = 1;
Damotclese 0:1ebe7d222470 227
Damotclese 0:1ebe7d222470 228 // Initialize locally-held variables
Damotclese 1:b9d4b9b8884c 229 u16_nextScanLine = 50;
Damotclese 0:1ebe7d222470 230
Damotclese 1:b9d4b9b8884c 231 // Flag the fact that we don't believe that we are seeing porch
Damotclese 1:b9d4b9b8884c 232 b_inPorch = false;
Damotclese 1:b9d4b9b8884c 233 b_waitingForPorch = true;
Damotclese 1:b9d4b9b8884c 234
Damotclese 1:b9d4b9b8884c 235 u16_resyncCount = 0;
Damotclese 1:b9d4b9b8884c 236 u32_scanCount = 0;
Damotclese 0:1ebe7d222470 237 }
Damotclese 0:1ebe7d222470 238
Damotclese 0:1ebe7d222470 239 // End of file
Damotclese 0:1ebe7d222470 240