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
LaserMon-Main.cpp
- Committer:
- Damotclese
- Date:
- 2019-06-17
- Revision:
- 2:cbcf2695a4a1
- Parent:
- 1:b9d4b9b8884c
File content as of revision 2:cbcf2695a4a1:
// ---------------------------------------------------------------------- // LaserMon-Main.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-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 // ---------------------------------------------------------------------- // Local data storage // // ---------------------------------------------------------------------- const char * pch_firstMessage = "Test signal on PA_5"; 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 // // ---------------------------------------------------------------------- // We will be using the LCD so instantiate an object locally LCD_DISCO_F429ZI st_lcd; // We will be using the touch screen so instantiate an object TS_DISCO_F429ZI st_touchScreen; // ---------------------------------------------------------------------- // MainInit() // // ---------------------------------------------------------------------- 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); // Set the default text color st_lcd.SetTextColor(LCD_COLOR_BLUE); // Set the background color st_lcd.SetBackColor(LCD_COLOR_WHITE); // 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; } // ---------------------------------------------------------------------- // main() // // // ---------------------------------------------------------------------- int main(void) { uint16_t u16_oneSecondCounter = 0; bool b_restartOneSecondTimer = false; // Perform local module initialization, if any MainInit(); // Initialize the generating of the output test signal module TestOutputInit(); // 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(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(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; } } } } // End of file