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-ScanInput.cpp

Committer:
Damotclese
Date:
2019-06-14
Revision:
1:b9d4b9b8884c
Parent:
0:1ebe7d222470
Child:
2:cbcf2695a4a1

File content as of revision 1:b9d4b9b8884c:


// ----------------------------------------------------------------------
// LaserMon-ScanInput.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-TestOutput.h"    // For test signal

// ----------------------------------------------------------------------
// Options, defined constants, and MACROs
//
// ----------------------------------------------------------------------

#define WANT_TEST_SIGNAL        1

// ----------------------------------------------------------------------
// Local data storage
//
// ----------------------------------------------------------------------

    // We create an analog input
    static AnalogIn st_scanInput(LASER_SCAN_IN);

    // For diagnostic purposes to show that the Laser Scan is operating
    static DigitalOut st_scanInputLED(LED2);
    
    // There are LCD_HEIGHT possible scan lines with a height of
    // LCD_WIDTH -- yes, the defined constant names are swapped
    // because we plot sideways.
    //
    // 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;
    
    // 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()
//
// What percentage of LCD_HEIGHT is the voltage? We need to scale 0 to 
// 3.3 volts across LCD_HEIGHT, with 0 being zero, and 3.3 volts being 
// LCD_HEIGHT.
//
// We compute the percentage of 3.3 volts that the input signal is 
// currently showing, then we compute that percentage of LCD_HEIGHT to
// determine how many pixels on a scan line that percentage is. That
// gives us the height of the plot line while u16_nextScanLine gives 
// us the line to plot it on.
//
// This is easy because the value passed to this function is a value
// from 0.0 to 1.0 which is a percentage of 3.3 volts, so we use the
// value against LCD_HEIGHT to yield the percentage of height.
//
// ----------------------------------------------------------------------
static void ScanInputPlotThisValue(float f_analogValue)
{
    // Compute the percentage of LCD height
    uint16_t u16_pixelHeight = ((f_analogValue / 3.3f) * ((float)LCD_HEIGHT - 10.0f));
    
    u16_pixelHeight /= 2;
    u16_pixelHeight += 10;
    
    // 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)
    {
        // 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
    {
        // 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;
    
#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)
    {
        return;
    }
        
    // 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;
}

// ----------------------------------------------------------------------
// ScanInputGetNextValue()
//
//
// ----------------------------------------------------------------------
static void ScanInputGetNextValue(void)
{
    float f_analogValue = ScanInputGetInputVoltage();

    // 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
    (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;
}
    
// ----------------------------------------------------------------------
// 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.
//
// ----------------------------------------------------------------------
void ScanInputThread(void)
{
    if (true == b_waitingForPorch)
    {
        // Start out searching for porch
        ScanInputWaitForPorch();
    }

    ScanInputGetNextValue();
}

// ----------------------------------------------------------------------
// ScanInputInit()
//
// ----------------------------------------------------------------------
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;
}

// End of file