Concept code which launches two threads, one of which implements a Modbus Tunnel protocol to talk with an ISEM, the other which launches a Modbus RTU protocol to talk to a CPUM (most of the Modbus code has been removed prior to publishing.) A canned AC and DC spectra is provided to display wave forms on start-up however the project normally polls for spectra from the ISEM and then plots is (that functionality has been removed prior to publishing.)
Dependencies: LCD_DISCO_F429ZI mbed TS_DISCO_F429ZI mbed-os BSP_DISCO_F429ZI
Plot of the initial start-up canned AC and DC spectra.
Diff: NextGen-Exerciser-Main.cpp
- Revision:
- 1:01394e5db95b
- Parent:
- 0:387684ec9d92
- Child:
- 2:346119b3db6c
diff -r 387684ec9d92 -r 01394e5db95b NextGen-Exerciser-Main.cpp --- a/NextGen-Exerciser-Main.cpp Thu May 30 05:16:27 2019 +0000 +++ b/NextGen-Exerciser-Main.cpp Thu May 30 18:24:08 2019 +0000 @@ -112,10 +112,83 @@ -191.656234000,-180.377243000,-169.183487000,-158.009185000,-146.788055440,-135.456863440,-123.959488000,-112.251495330, -100.304824000,-88.112571711,-75.693458500,-63.095802300,-50.400745400,-37.724391933,-25.218734744,-13.071174622 } ; + + static float f_decimatedDCSpectrum[] = + { + 164622.859, 156185.187, 130679.648, 94457.766, 60629.086, 35816.664, 20260.646, 12169.420, + 9521.371, 9680.042, 10389.553, 14924.355, 29797.771, 54048.340, 79677.930, 100584.007, + 114916.859, 123130.789, 126640.937, 127108.539, 125978.539, 124264.656, 122565.765, 121160.593, + 120120.234, 119405.492, 118934.531, 118622.812, 118402.031, 118224.390, 118060.507, 117896.296, + 117727.086, 117552.828, 117375.304, 117196.453, 117017.570, 116837.726, 116656.039, 116473.492, + 116289.906, 116104.265, 115915.937, 115723.570, 115526.664, 115325.656, 115120.421, 114911.429, + 114697.828, 114476.804, 114247.992, 114013.179, 113771.867, 113522.140, 113264.578, 113002.109, + 112735.640, 112462.671, 112182.187, 111892.171, 111590.554, 111280.000, 110962.125, 110639.429, + 110312.679, 109975.781, 109623.398, 109255.132, 108878.789, 108498.742, 108109.039, 107706.664, + 107291.461, 106863.039, 106420.086, 105960.101, 105483.578, 104994.242, 104495.437, 103984.203, + 103457.976, 102917.992, 102363.515, 101794.343, 101214.031, 100629.211, 100040.492, 99439.859, + 98819.461, 98173.063, 97503.469, 96825.117, 96144.188, 95452.000, 94738.039, 93996.977, + 93228.984, 92435.734, 91625.875, 90815.219, 90004.086, 89177.555, 88331.219, 87471.523, + 86607.555, 85742.336, 84864.008, 83967.336, 83058.867, 82140.016, 81212.930, 80285.523, + 79358.758, 78424.992, 77494.000, 76579.289, 75662.469, 74731.563, 73808.039, 72908.133, + 72025.875, 71144.391, 70256.500, 69372.094, 68501.109, 67648.109, 66813.898, 65996.867, + 65195.641, 64414.758, 63665.418, 62947.723, 62251.930, 61577.820, 60930.938, 60310.703, + 59717.070, 59153.746, 58622.043, 58124.535, 57664.281, 57239.590, 56849.543, 56495.852, + 56177.289, 55892.000, 55643.016, 55431.777, 55257.840, 55124.254, 55029.434, 54971.840, + 54955.445, 54979.289, 55040.957, 55139.879, 55278.230, 55457.840, 55673.457, 55925.805, + 56220.500, 56554.961, 56925.184, 57330.996, 57773.441, 58253.074, 58770.402, 59326.258, + 59917.891, 60538.234, 61187.504, 61875.184, 62605.102, 63370.285, 64161.137, 64974.477, + 65816.297, 66691.320, 67592.148, 68503.984, 69422.414, 70364.266, 71343.883, 72351.906, + 73372.016, 74390.320, 75401.859, 76421.227, 77464.242, 78523.742, 79582.586, 80642.227, + 81714.758, 82804.367, 83906.422, 85006.211, 86092.281, 87169.992, 88245.125, 89310.359, + 90360.758, 91407.516, 92457.242, 93497.219, 94524.414, 95552.211, 96577.430, 97588.609, + 98588.539, 99575.063, 100543.234, 101498.179, 102434.992, 103344.476, 104234.867, 105114.281, + 105982.656, 106839.539, 107682.593, 108518.468, 109349.765, 110166.625, 110967.500, 111753.843, + 112524.437, 113279.453, 114016.820, 114732.929, 115433.171, 116129.640, 116820.101, 117493.351, + 118144.578, 118774.367, 119390.500, 119997.554, 120589.562, 121168.031, 121741.507, 122308.328, + 122861.468, 123400.164, 123925.187, 124437.125, 124944.039, 125448.539, 125940.484, 126416.187, + 126881.367, 127340.125, 127790.164, 128227.226, 128651.578, 129064.890, 129469.812, 129867.937, + 130259.703, 130648.023, 131031.523, 131406.046, 131770.140, 132124.406, 132471.937, 132814.875, + 133153.359, 133487.703, 133816.296, 134134.171, 134439.421, 134738.953, 135040.187, 135338.218, + 135628.468, 135915.687, 136198.750, 136474.656, 136746.062, 137011.234, 137270.937, 137531.343, + 137787.781, 138033.875, 138274.046, 138511.078, 138741.453, 138967.078, 139194.343, 139418.796, + 139635.859, 139849.718, 140059.359, 140263.546, 140464.187, 140661.343, 140856.937, 141051.328, + 141241.859, 141427.875, 141610.156, 141789.250, 141965.359, 142139.234, 142310.125, 142476.343, + 142639.187, 142799.046, 142954.359, 143106.234, 143255.687, 143402.343, 143547.250, 143690.609, + 143830.875, 143967.234, 144099.421, 144228.046, 144353.625, 144475.734, 144594.656, 144710.671, + 144823.093, 144931.390, 145036.046, 145138.921, 145240.593, 145339.421, 145434.562, 145525.906, + 145612.765, 145694.562, 145771.609, 145845.453, 145916.843, 145984.953, 146049.296, 146109.531, + 146165.484, 146216.843, 146262.718, 146304.031, 146341.515, 146373.906, 146400.953, 146423.250, + 146440.265, 146451.703, 146457.453, 146456.968, 146450.687, 146439.015, 146420.750, 146395.453, + 146364.703, 146329.000, 146286.328, 146235.890, 146179.187, 146116.390, 146046.562, 145970.250, + 145888.875, 145802.343, 145709.578, 145611.015, 145507.875, 145400.656, 145289.718, 145175.437, + 145058.906, 144941.578, 144823.593, 144704.640, 144585.046, 144464.984, 144345.546, 144229.687, + 144119.281, 144013.609, 143912.671, 143818.609, 143732.531, 143654.062, 143584.265, 143524.062, + 143472.843, 143430.656, 143398.421, 143376.796, 143365.031, 143361.171, 143364.421, 143375.312, + 143393.546, 143417.750, 143448.921, 143488.828, 143537.078, 143593.468, 143657.265, 143727.843, + 143806.734, 143893.125, 143984.609, 144081.359, 144184.625, 144293.546, 144406.218, 144524.500, + 144650.468, 144782.187, 144918.953, 145061.843, 145211.578, 145369.562, 145536.781, 145712.218, + 145895.156, 146085.937, 146284.156, 146491.125, 146708.437, 146934.328, 147168.796, 147413.734, + 147668.906, 147933.296, 148206.078, 148487.953, 148777.734, 149071.968, 149373.265, 149686.093, + 150007.109, 150328.703, 150648.953, 150969.625, 151287.671, 151603.171, 151921.078, 152239.421, + 152552.781, 152860.218, 153163.453, 153463.234, 153758.718, 154050.921, 154341.515, 154628.250, + 154907.796, 155179.656, 155444.531, 155703.500, 155957.656, 156205.265, 156446.359, 156685.718, + 156922.781, 157152.437, 157374.281, 157590.484, 157802.796, 158010.562, 158211.375, 158407.156, + 158600.015, 158787.093, 158967.703, 159144.312, 159317.187, 159486.218, 159652.437, 159816.218, + 159976.906, 160135.031, 160291.250, 160443.359, 160590.359, 160733.843, 160875.171, 161015.390, + 161154.515, 161291.843, 161427.000, 161559.953, 161689.953, 161815.781, 161939.203, 162063.375, + 162187.312, 162307.875, 162424.328, 162538.328, 162651.750, 162765.296, 162878.078, 162987.562, + 163093.531, 163199.171, 163305.312, 163410.593, 163514.609, 163617.453, 163720.437, 163824.093, + 163926.906, 164028.125, 164126.515, 164224.531, 164334.281, 164304.281, 163889.750, 164209.968 + } ; // We will be using the LCD so instantiate an object locally static LCD_DISCO_F429ZI st_lcd; + // When searching for the intersection of AC and DC curves, we store the values here + static uint16_t u16_firstIntersectionHeight; + static uint16_t u16_secondIntersectionHeight; + + // ---------------------------------------------------------------------- // MainProcessDecimatedSpectrum() // @@ -140,45 +213,74 @@ // ---------------------------------------------------------------------- static void MainProcessDecimatedSpectrum(void) { - uint16_t u16_searchLoop = 0; - uint32_t u32_sampleRatio = 0; - uint16_t u16_resultIndex = 0; - float f_smallNumber = 10000000.0f; - float f_largeNumber = 0.0f; + uint16_t u16_searchLoop = 0; + uint32_t u32_sampleACRatio = 0; + uint32_t u32_sampleDCRatio = 0; + uint16_t u16_resultIndex = 0; + float f_smallACNumber = 10000000.0f; + float f_largeACNumber = 0.0f; + float f_smallDCNumber = 10000000.0f; + float f_largeDCNumber = 0.0f; // Search through the AC spectrum for the smallest and the largest values for (u16_searchLoop = 0; u16_searchLoop < 512; u16_searchLoop++) { - if (f_decimatedACSpectrum[u16_searchLoop] < f_smallNumber) + // First do the AC SPectrum + if (f_decimatedACSpectrum[u16_searchLoop] < f_smallACNumber) { // This value is the new lowest number - f_smallNumber = f_decimatedACSpectrum[u16_searchLoop]; + f_smallACNumber = f_decimatedACSpectrum[u16_searchLoop]; + } + + if (f_decimatedACSpectrum[u16_searchLoop] > f_largeACNumber) + { + // This value is the new highest number + f_largeACNumber = f_decimatedACSpectrum[u16_searchLoop]; } - if (f_decimatedACSpectrum[u16_searchLoop] > f_largeNumber) + // Now do the DC spectrum + if (f_decimatedDCSpectrum[u16_searchLoop] < f_smallDCNumber) + { + // This value is the new lowest number + f_smallDCNumber = f_decimatedDCSpectrum[u16_searchLoop]; + } + + if (f_decimatedDCSpectrum[u16_searchLoop] > f_largeDCNumber) { // This value is the new highest number - f_largeNumber = f_decimatedACSpectrum[u16_searchLoop]; + f_largeDCNumber = f_decimatedDCSpectrum[u16_searchLoop]; } } - // Is the smallest number negative? We know that it is but we check - if (f_smallNumber < 0.0f) + // Is the smallest AC number negative? We know that it is but we check + if (f_smallACNumber < 0.0f) { // Make the value absolute so that it is positive - f_smallNumber = abs(f_smallNumber); + f_smallACNumber = abs(f_smallACNumber); } + // Is the smallest DC number negative? + if (f_smallDCNumber < 0.0f) + { + // Make the value absolute so that it is positive + f_smallDCNumber = abs(f_smallDCNumber); + } + // To make all values positive, add the newly-derived positive value. // This makes all numbers positive and ensures that the smallest // value in the spectra is zero. for (u16_searchLoop = 0; u16_searchLoop < 512; u16_searchLoop++) { - f_decimatedACSpectrum[u16_searchLoop] += f_smallNumber; + // Do the AC spectrum + f_decimatedACSpectrum[u16_searchLoop] += f_smallACNumber; + + // Do the DC spectrum + f_decimatedDCSpectrum[u16_searchLoop] += f_smallDCNumber; } // Also add the newly-positive number to our largest known value - f_largeNumber += f_smallNumber; + f_largeACNumber += f_smallACNumber; + f_largeDCNumber += f_smallDCNumber; // Determine the ratio to use, the LCD screen is 240 by 320 so we // take the highest number value in the spectra and divide by 240 @@ -186,19 +288,28 @@ // plotted across the 320 by averaging every 2 samples to yield // 256 horizontal positions. We plot with the screen laying on // its side - u32_sampleRatio = (f_largeNumber / LCD_WIDTH); + u32_sampleACRatio = (f_largeACNumber / LCD_WIDTH); + u32_sampleDCRatio = (f_largeDCNumber / LCD_WIDTH); // Go through each pairs of samples and average them and then // divide the result by the ratio. Step through in twos for (u16_searchLoop = 0; u16_searchLoop < 512; u16_searchLoop += 2, u16_resultIndex++) { - // Take the next two samples and average them, putting the result + // Take the next two AC samples and average them, putting the result // in to the next result index of the same buffer we're processing f_decimatedACSpectrum[u16_resultIndex] = (f_decimatedACSpectrum[u16_searchLoop] + f_decimatedACSpectrum[u16_searchLoop]) / 2; // Divide the sample value by the ratio - f_decimatedACSpectrum[u16_resultIndex] /= u32_sampleRatio; + f_decimatedACSpectrum[u16_resultIndex] /= u32_sampleACRatio; + + // Take the next two DC samples and average them, putting the result + // in to the next result index of the same buffer we're processing + f_decimatedDCSpectrum[u16_resultIndex] = + (f_decimatedDCSpectrum[u16_searchLoop] + f_decimatedDCSpectrum[u16_searchLoop]) / 2; + + // Divide the sample value by the ratio + f_decimatedDCSpectrum[u16_resultIndex] /= u32_sampleDCRatio; } } @@ -217,7 +328,7 @@ // Plot the spectrum values, plotting a line from point to point for (u16_searchLoop = 0; u16_searchLoop < ((512 / 2) - 1); u16_searchLoop++) { - // Ensure that we actually fit. The sample should + // Ensure that we actually fit. The AC sample should if (f_decimatedACSpectrum[u16_searchLoop] <= LCD_WIDTH) { st_lcd.DrawLine(f_decimatedACSpectrum[u16_searchLoop], u16_searchLoop, @@ -228,6 +339,105 @@ // Mathematically we topped-out past the maximum some how st_lcd.DrawPixel(0, u16_searchLoop, LCD_COLOR_WHITE); } + + // Ensure that we actually fit. The DC sample should + if (f_decimatedDCSpectrum[u16_searchLoop] <= LCD_WIDTH) + { + st_lcd.DrawLine(f_decimatedDCSpectrum[u16_searchLoop], u16_searchLoop, + f_decimatedDCSpectrum[u16_searchLoop + 1], u16_searchLoop + 1); + } + else + { + // Mathematically we topped-out past the maximum some how + st_lcd.DrawPixel(0, u16_searchLoop, LCD_COLOR_WHITE); + } + } +} + +// ---------------------------------------------------------------------- +// MainFindACandDCintersections() +// +// This function attempts to locate the intersections where the AC and +// DC spectra curve meets. It locates the last intersection point +// encountered sweeping from left to right across the spectra, and for +// the second intersection point it locates the first intersection +// point. +// +// In this way we find the two locations at LCT_HEIGHT which indicates +// the surface area volume arena of the water peak, bounded by the AC +// curve to the top of the peak, and the DC curve at the bottom of +// the curve. +// +// ---------------------------------------------------------------------- +static void MainFindACandDCintersections(void) +{ + uint16_t u16_searchLoop = 0; + bool b_atFirstIntersection = false; + uint16_t u16_possibleFirst = 0; + uint16_t u16_areaACMin = 0; + uint16_t u16_areaACMax = 0; +#if 0 + uint16_t u16_areaDCMin = 0; + uint16_t u16_areaDCMax = 0; +#endif + + // Go through the 256 sample within both the AC and the DC + // spectra and first locate the first insersection point and + // then the second intersection point + for (u16_searchLoop = 0; u16_searchLoop < 256; u16_searchLoop++) + { + // Make sure that what we're looking at can be generally examined + if ((int)f_decimatedACSpectrum[u16_searchLoop] > 10 && + (int)f_decimatedDCSpectrum[u16_searchLoop] > 10) + { + // Each point on the plot is examined to see if the point is + // plus or minus 5 pixels to determine if they intersect. + u16_areaACMin = (int)f_decimatedACSpectrum[u16_searchLoop] - 5; + u16_areaACMax = (int)f_decimatedACSpectrum[u16_searchLoop] + 5; +#if 0 + u16_areaDCMin = (int)f_decimatedDCSpectrum[u16_searchLoop] - 5; + u16_areaDCMax = (int)f_decimatedDCSpectrum[u16_searchLoop] + 5; +#endif + + // Do these two points intersect? + if ((int)f_decimatedDCSpectrum[u16_searchLoop] >= u16_areaACMin && + (int)f_decimatedDCSpectrum[u16_searchLoop] <= u16_areaACMax) + { + // Do we have the first intersection already? + if (0 != u16_firstIntersectionHeight) + { + // We have the first intersection so this is the second + u16_secondIntersectionHeight = u16_searchLoop; + + // We have found both intersections so we are done + break; + } + else + { + // We are still searching for the first intersection + // so because we intersect here, note that we found it + b_atFirstIntersection = true; + + // Record the point at which the first intersected + u16_possibleFirst = u16_searchLoop; + } + } + else + { + // These two points do not intersect. + // Did we already find the first intersection point? + if (true == b_atFirstIntersection) + { + // We found the intersection point and then left the area where + // it intersected, so the last possible intersection point is + // the first area of intersection + u16_firstIntersectionHeight = u16_possibleFirst; + + // Since we have the first intersectiopn point located + b_atFirstIntersection = false; + } + } + } } } @@ -242,6 +452,12 @@ // ---------------------------------------------------------------------- static void MainInit(void) { + uint8_t ach_intersectionString[31] = { 0 }; + + // Initialize the module's locall-held data + u16_firstIntersectionHeight = 0; + u16_secondIntersectionHeight = 0; + // Bring the LCD up and set its various colors st_lcd.Clear(LCD_COLOR_BLACK); st_lcd.SetBackColor(LCD_COLOR_BLACK); @@ -250,6 +466,16 @@ // Process the decimated spectrum and then plot it MainProcessDecimatedSpectrum(); MainPlotFinalSpectrum(); + + // Search the AC and DC plots for where they intersect + MainFindACandDCintersections(); + + (void)sprintf((char *)ach_intersectionString, + "Intersections %d and %d", + u16_firstIntersectionHeight, + u16_secondIntersectionHeight); + + st_lcd.DisplayStringAt(0, LINE(1), (uint8_t *)ach_intersectionString, LEFT_MODE); } // ----------------------------------------------------------------------