Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: LCD_DISCO_F429ZI mbed TS_DISCO_F429ZI mbed-os BSP_DISCO_F429ZI
LaserMon-ScanInput.cpp
00001 00002 // ---------------------------------------------------------------------- 00003 // LaserMon-ScanInput.cpp 00004 // 00005 // Fredric L. Rice, June 2019 00006 // 00007 // ---------------------------------------------------------------------- 00008 00009 #include "mbed.h" // The mbed operating system 00010 #include "LCD_DISCO_F429ZI.h" // For controlling the LCD 00011 #include "TS_DISCO_F429ZI.h" // For controlling the touch screen 00012 #include "LaserMon-Main.h" // For data exported to us 00013 #include "LaserMon-TestOutput.h" // For test signal 00014 00015 // ---------------------------------------------------------------------- 00016 // Options, defined constants, and MACROs 00017 // 00018 // ---------------------------------------------------------------------- 00019 00020 #define WANT_TEST_SIGNAL 0 00021 00022 // ---------------------------------------------------------------------- 00023 // Local data storage 00024 // 00025 // ---------------------------------------------------------------------- 00026 00027 // We create an analog input 00028 static AnalogIn st_scanInput(LASER_SCAN_IN); 00029 00030 // For diagnostic purposes to show that the Laser Scan is operating 00031 static DigitalOut st_scanInputLED(LED2); 00032 00033 // There are LCD_HEIGHT possible scan lines with a height of 00034 // LCD_WIDTH -- yes, the defined constant names are swapped 00035 // because we plot sideways. 00036 // 00037 // This value contains the next scan line number to plot 00038 static uint16_t u16_nextScanLine; 00039 00040 // We store the last pixel's height so we may plot 00041 static uint16_t u16_lastHeight = 0; 00042 00043 // Flag indicates whether we believe we are receiving porch or not 00044 static bool b_inPorch; 00045 00046 // We keep track of how many times we have had to search for porch. 00047 // Typically we could expect not to have to search for it when the 00048 // plot goes beyond the end of the screen, however we may need to 00049 // search on power-up and when the scan frequency changes 00050 static uint16_t u16_resyncCount; 00051 00052 // For no reason at all we keep track of how many scans we detect 00053 static uint32_t u32_scanCount; 00054 00055 // When we are searching for porch, we use this flag to indicate that 00056 static bool b_waitingForPorch; 00057 00058 // We keep track of how many milliseconds there are between porch 00059 // detections. This indicates a fairly close timing of the scan 00060 // frequency. 00061 static uint16_t u16_scanFrequency; 00062 static uint16_t u16_msFromPorchToPorch; 00063 00064 // ---------------------------------------------------------------------- 00065 // ScanInputPlotThisValue() 00066 // 00067 // What percentage of LCD_HEIGHT is the voltage? We need to scale 0 to 00068 // 3.3 volts across LCD_HEIGHT, with 0 being zero, and 3.3 volts being 00069 // LCD_HEIGHT. 00070 // 00071 // We compute the percentage of 3.3 volts that the input signal is 00072 // currently showing, then we compute that percentage of LCD_HEIGHT to 00073 // determine how many pixels on a scan line that percentage is. That 00074 // gives us the height of the plot line while u16_nextScanLine gives 00075 // us the line to plot it on. 00076 // 00077 // This is easy because the value passed to this function is a value 00078 // from 0.0 to 1.0 which is a percentage of 3.3 volts, so we use the 00079 // value against LCD_HEIGHT to yield the percentage of height. 00080 // 00081 // ---------------------------------------------------------------------- 00082 static void ScanInputPlotThisValue(float f_analogValue) 00083 { 00084 // Compute the percentage of LCD height 00085 uint16_t u16_pixelHeight = ((f_analogValue / 3.3f) * ((float)LCD_HEIGHT - 10.0f)); 00086 00087 u16_pixelHeight /= 2; 00088 u16_pixelHeight += 10; 00089 00090 // Clear the entire current scan line to plot 00091 st_lcd.SetTextColor(LCD_COLOR_WHITE); 00092 st_lcd.DrawLine(1, u16_nextScanLine, LCD_WIDTH, u16_nextScanLine); 00093 00094 // Plot from the previous pixel to the new one 00095 st_lcd.SetTextColor(LCD_COLOR_BLUE); 00096 00097 // Are we currently in porch? We plot differently if so 00098 if (false == b_inPorch) 00099 { 00100 // We plot ramp from the previous scan line's height to the current scan line and height 00101 st_lcd.DrawLine(u16_lastHeight, u16_nextScanLine - 1, u16_pixelHeight, u16_nextScanLine); 00102 } 00103 else 00104 { 00105 // We plot the porch at a height of 10 pixels 00106 st_lcd.DrawLine(10, u16_nextScanLine - 1, 10, u16_nextScanLine); 00107 } 00108 00109 // Keep track of the last height so we may plot 00110 u16_lastHeight = u16_pixelHeight; 00111 } 00112 00113 // ---------------------------------------------------------------------- 00114 // 00115 // 00116 // ---------------------------------------------------------------------- 00117 static float ScanInputGetInputVoltage(void) 00118 { 00119 // Get the current analog input value and convert to volts 00120 float f_analogValue = st_scanInput.read() * 3.3f; 00121 00122 #if WANT_TEST_SIGNAL 00123 // Use the test output signal voltage instead 00124 f_analogValue = f_rampVoltage; 00125 #endif 00126 00127 // Return either the actual analog in or test voltage 00128 return f_analogValue; 00129 } 00130 00131 static void ScanInputUpdateScanFrequency(void) 00132 { 00133 // Store the last porch to porch counter 00134 u16_scanFrequency = u16_msFromPorchToPorch; 00135 00136 // Restart the porch to porch counter 00137 u16_msFromPorchToPorch = 0; 00138 } 00139 00140 // ---------------------------------------------------------------------- 00141 // ScanInputWaitForPorch() 00142 // 00143 // ---------------------------------------------------------------------- 00144 static void ScanInputWaitForPorch(void) 00145 { 00146 float f_analogValue = 5.0f; 00147 00148 // While we're not seeing porch, loop 00149 if (f_analogValue > 0.5f) 00150 { 00151 return; 00152 } 00153 00154 // Flag the fact that we're in porch 00155 b_inPorch = true; 00156 00157 b_waitingForPorch = false; 00158 00159 // Keep track of our scan frequency 00160 ScanInputUpdateScanFrequency(); 00161 00162 // Since we detected porch, start the plot over from the beginning 00163 u16_nextScanLine = 50; 00164 00165 // The last height we consider to be 1 pixel on porch 00166 u16_lastHeight = 1; 00167 00168 // Keep track of how many times we had to wait for locating porch 00169 // again after loosing it. Note that on power-up, if we are using 00170 // the test signal output, it is driven to porch co-incident with 00171 // the input test, so we start up with porch as the first sample 00172 ++u16_resyncCount; 00173 } 00174 00175 // ---------------------------------------------------------------------- 00176 // ScanInputGetNextValue() 00177 // 00178 // 00179 // ---------------------------------------------------------------------- 00180 static void ScanInputGetNextValue(bool b_allowPlotting) 00181 { 00182 float f_analogValue = ScanInputGetInputVoltage(); 00183 00184 // Dows the input indicate that we are in porch? 00185 if (f_analogValue < 1.0f) 00186 { 00187 // Did we previously know that we were in porch? 00188 if (false == b_inPorch) 00189 { 00190 float f_plusFourPercent = 0.0f; 00191 00192 // Flag the fact that we're in porch now 00193 b_inPorch = true; 00194 00195 // Since we detected a new porch, start the plot over 00196 u16_nextScanLine = 49; 00197 00198 // The last height we consider to be 1 pixel on porch 00199 u16_lastHeight = 1; 00200 00201 // Update our scan frequency 00202 ScanInputUpdateScanFrequency(); 00203 00204 // Since our timing in this device is off, we add a correction 00205 f_plusFourPercent = (((float)u16_scanFrequency / 100.0f) * 4.3f); 00206 00207 // Let the main module know what the scan rate is for display 00208 // and for testing and evaluating 00209 LaserMonMainInformScanInformation((uint16_t)((float)u16_scanFrequency + f_plusFourPercent), ++u32_scanCount); 00210 } 00211 } 00212 else 00213 { 00214 // We are in the ramp so flag the fact even if we already know 00215 b_inPorch = false; 00216 00217 // Keep track of the scan frequency 00218 u16_msFromPorchToPorch++; 00219 } 00220 00221 // Indicate the next line to plot this reading on to 00222 u16_nextScanLine++; 00223 00224 // The display may be in use for other functionality so we 00225 // check to ensure that we are permitted to plot the input 00226 if (true == b_allowPlotting) 00227 { 00228 // Call the function which plots this value 00229 (void)ScanInputPlotThisValue(f_analogValue); 00230 } 00231 00232 // Are we about to exceed the display? 00233 if (u16_nextScanLine >= (LCD_HEIGHT - 10)) 00234 { 00235 // We have lost track of porch so we must search for it again 00236 b_waitingForPorch = true; 00237 } 00238 00239 // Set the LED with whether we are at porch or not 00240 st_scanInputLED = b_inPorch; 00241 } 00242 00243 // ---------------------------------------------------------------------- 00244 // ScanInputThread() 00245 // 00246 // This is called once a millisecond however it is not a thread, the 00247 // thread class on this board ended up with timing that could not be 00248 // controlled so the main() loop calls us once a millisecond. 00249 // 00250 // ---------------------------------------------------------------------- 00251 void ScanInputThread(bool b_allowPlotting) 00252 { 00253 // Are we waiting for porch synchronization? 00254 if (true == b_waitingForPorch) 00255 { 00256 // Start out searching for porch 00257 ScanInputWaitForPorch(); 00258 } 00259 00260 // Scan the signal coming in and optionally plot it 00261 ScanInputGetNextValue(b_allowPlotting); 00262 } 00263 00264 // ---------------------------------------------------------------------- 00265 // ScanInputInit() 00266 // 00267 // Initialize this module's locally-held data 00268 // 00269 // ---------------------------------------------------------------------- 00270 void ScanInputInit(void) 00271 { 00272 // Start out with the LED turned ON 00273 st_scanInputLED = 1; 00274 00275 // Initialize loc ally-held variables 00276 u16_nextScanLine = 50; 00277 b_inPorch = false; 00278 b_waitingForPorch = true; 00279 u16_scanFrequency = 0; 00280 u16_resyncCount = 0; 00281 u32_scanCount = 0; 00282 u16_msFromPorchToPorch = 0; 00283 } 00284 00285 // End of file 00286
Generated on Thu Jul 14 2022 16:41:21 by
1.7.2