Frequency Counter. User interface are used DISCO-F746NG GUI with touch panel.
Dependencies: BSP_DISCO_F746NG F746_GUI LCD_DISCO_F746NG RingBuffer TS_DISCO_F746NG fc_GPS1PPS_f746_f4xx mbed
Please refer following.
/users/kenjiArai/notebook/frequency-counters/
main.cpp
- Committer:
- kenjiArai
- Date:
- 2016-11-19
- Revision:
- 0:52c5dc2b2b68
File content as of revision 0:52c5dc2b2b68:
/* * mbed Application program / Frequency Counter using GPS 1PPS gate puls * Only for ST DISCO-F746NG * Worked on a dedicated Grafic LCD Module * * Copyright (c) 2014,'15,'16 Kenji Arai / JH1PJL * http://www.page.sannet.ne.jp/kenjia/index.html * http://mbed.org/users/kenjiArai/ * Created: October 18th, 2014 * Revised: January 2nd, 2015 * Re-started: June 25th, 2016 ported from F411 to F746 * Re-started: Nobember 13th, 2016 Only for DISCO-F746NG LCD * Revised: Nobember 19th, 2016 * * Base program: FreqCntr_GPS1PPS_F746F4xx_w_recipro * https://developer.mbed.org/users/kenjiArai * /code/FreqCntr_GPS1PPS_F746F4xx_w_recipro/ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* REFRENCE: see the source code in this file bottom area 2016/11/12, Copyright (c) 2016 MIKAMI, Naoki https://developer.mbed.org/users/MikamiUitOpen/code/F746_GUI_Demo/ Thanks Mikammi-san! */ #define USE_COM // use Communication with PC(UART) // Include -------------------------------------------------------------------- #include "mbed.h" #include "F746_GUI.hpp" #include "GPSrcvr.h" #include "fc_GPS1PPS.h" // Definition ----------------------------------------------------------------- #ifdef USE_COM #define BAUD(x) pc.baud(x) #define GETC(x) pc.getc(x) #define PUTC(x) pc.putc(x) #define PRINTF(...) pc.printf(__VA_ARGS__) #define READABLE(x) pc.readable(x) #else #define BAUD(x) {;} #define GETC(x) {;} #define PUTC(x) {;} #define PRINTF(...) {;} #define READABLE(x) {;} #endif enum input_select { BNC_NORMAL = 1, RECIPRO_AC, RECIPRO_DC, SMA_10, SMA_20 }; using namespace Frequency_counter; // Object --------------------------------------------------------------------- DigitalOut input_frq_select(PF_9); DigitalInOut prescaler10or20(PB_15); DigitalOut recipro_select(PA_8); DigitalOut led1(LED1); Serial pc(USBTX, USBRX); Timer tmr; //**** Req. Counter FRQ_CUNTR fc; //**** GUI LCD_DISCO_F746NG lcd_; // RAM ------------------------------------------------------------------------ // Freq. double new_frequency; double f_10sec; double f_100sec; double f_1000sec; double freq_recipro; // Operation mode uint8_t input_mode; // ROM / Constant data -------------------------------------------------------- // 12345678901234567890 static char *const msg_msg0 = "Frequency Counter by JH1PJL K.Arai"; static char *const msg_msg1 = "on DISCO-F746NG System"; static char *const msg_msg2 = " "__DATE__" "; static char *const msg_mode1 = " BNC none-prescaler "; static char *const msg_mode2 = " BNC recipro(BNC none-prescaler) "; static char *const msg_mode3 = " BNC recipro(dedicated BNC input)"; static char *const msg_mode4 = " SMA prescaler 1/10 "; static char *const msg_mode5 = " SMA prescaler 1/20 "; char *const open_msg[] = { "(1) BNC(AC) div = 1/1 10Hz to 100MHz", "(2) BNC(AC)(same as above) Reciprocal mode less than 5KHz", "(3) BNC(DC) (another BNC) Reciprocal mode less than 5KHz", "(4) SMA div = 1/10 up to 1GHz", "(5) SMA(same as above) div = 1/20 up to 1.5GHz" }; char *const select_msg[] = { "(1) BNC(AC) div = 1/1 ", "(2) BNC(AC) Reciprocal", "(3) BNC(DC) Reciprocal", "(4) SMA div = 1/10", "(5) SMA div = 1/20" }; // Function prototypes -------------------------------------------------------- void gps_data_rcv(void); void freq_measurement(uint8_t mode); void recipro(uint8_t mode); void opening(void); void show_time(void); uint8_t mode_slect(void); //------------------------------------------------------------------------------ // Control Program //------------------------------------------------------------------------------ void freq_measurement(uint8_t mode) { uint16_t n = 0; char buf[48]; double scale; Button button(400, 3, 70, 40, "MODE", Font16); Label obj20(180, 5, "Frequency Counter", Label::CENTER, Font24, LCD_COLOR_GREEN, LCD_COLOR_BLACK); if (mode == SMA_20){ Label obj21(200, 30, "Input=SMA, Division=1/20", Label::CENTER, Font16, LCD_COLOR_WHITE, LCD_COLOR_BLACK); scale = 20.0f; } else if(mode == SMA_10){ Label obj21(200, 30, "Input=SMA, Division=1/10", Label::CENTER, Font16, LCD_COLOR_WHITE, LCD_COLOR_BLACK); scale = 10.0f; } else { Label obj21(200, 30, "Input=BNC(AC), Division=1/1", Label::CENTER, Font16, LCD_COLOR_WHITE, LCD_COLOR_BLACK); scale = 1.0f; } while(true){ tmr.reset(); tmr.start(); if (fc.status_freq_update() != 0) { new_frequency = fc.read_freq_data() * scale; f_10sec = fc.read_freq_w_gate_time(10) * scale; f_100sec = fc.read_freq_w_gate_time(100) * scale; f_1000sec = fc.read_freq_w_gate_time(1000) * scale; PRINTF("%8d, Freq: %9.0f,", ++n, new_frequency); PRINTF(" F10s: %10.1f, F100s: %11.2f,", f_10sec, f_100sec); PRINTF(" F1000s: %12.3f,", f_1000sec); sprintf(buf, "Freq: %11.0f [Hz]", new_frequency); Label obj22(40, 60, buf, Label::LEFT, Font24, LCD_COLOR_GREEN, LCD_COLOR_BLACK); sprintf(buf, "F10S: %12.1f [Hz]", f_10sec); Label obj23(40, 90, buf, Label::LEFT, Font24, LCD_COLOR_WHITE, LCD_COLOR_BLACK); sprintf(buf, "F100: %13.2f [Hz]", f_100sec); Label obj24(40, 120, buf, Label::LEFT, Font24, LCD_COLOR_WHITE, LCD_COLOR_BLACK); } else { PRINTF("%8d, No data,,,,", ++n); Label obj25(40, 60, "Data is NOT available!", Label::LEFT, Font24, LCD_COLOR_GREEN, LCD_COLOR_BLACK); sprintf(buf, " "); Label obj26(40, 80, buf, Label::LEFT, Font24, LCD_COLOR_WHITE, LCD_COLOR_BLACK); Label obj27(40, 100, buf, Label::LEFT, Font24, LCD_COLOR_MAGENTA, LCD_COLOR_BLACK); } if (mode == SMA_20){ PRINTF(" Div: 1/20,"); } else if(mode == SMA_10){ PRINTF(" Div: 1/10,"); } else { PRINTF(" Div: 1/1 ,"); } show_time(); while (1000 > tmr.read_ms()){ // 1 second interval if (button.Touched()){ // if user touched "MODE" panel then return return; } wait_ms(1); } } } void recipro(uint8_t mode) { uint16_t n = 0; char buf[48]; double freq_recipro; uint32_t interval_recipro; uint32_t base_clk; int32_t run2stop; Button button(400, 3, 70, 40, "MODE", Font16); Label obj30(180, 5, "Frequency Counter", Label::CENTER, Font24, LCD_COLOR_GREEN, LCD_COLOR_BLACK); if (mode == RECIPRO_AC){ Label obj31(200, 30, "Input=BNC(AC) Reciprocal Mode", Label::CENTER, Font16, LCD_COLOR_WHITE, LCD_COLOR_BLACK); } else if (mode == RECIPRO_DC){ Label obj31(200, 30, "Input=BNC(DC) Reciprocal Mode", Label::CENTER, Font16, LCD_COLOR_WHITE, LCD_COLOR_BLACK); } while(true){ tmr.reset(); tmr.start(); fc.recipro_start_measure(); PRINTF("Start measurement\r"); while (fc.recipro_check_trigger() == 0){ run2stop = tmr.read_ms(); if (run2stop >= 100000){ // 100sec 0.001Hz break; } if (button.Touched()){ // if user touched "MODE" panel then return return; } } if (button.Touched()){ // if user touched "MODE" panel then return return; } if (run2stop >= 1000000){ // 100sec 0.001Hz //freq_recipro = 0; } else { interval_recipro = fc.recipro_read_data(); base_clk = fc.recipro_base_clk_data(1); if (interval_recipro >= 9000){// Measure less than 10KHz frequency freq_recipro = (double)base_clk / (double)interval_recipro; } else { //freq_recipro = 0; } } PRINTF("%8d, Freq: %11.5f [Hz] , ", n++, freq_recipro); PRINTF("Raw: %11u [cnt] , ", interval_recipro); PRINTF("Base: %11u [Hz], ", base_clk); sprintf(buf, "Freq:%11.5f [Hz]", freq_recipro); Label obj32(40, 60, buf, Label::LEFT, Font24, LCD_COLOR_GREEN, LCD_COLOR_BLACK); sprintf(buf, "Raw: %11u [Counts]", interval_recipro); Label obj33(40, 90, buf, Label::LEFT, Font24, LCD_COLOR_WHITE, LCD_COLOR_BLACK); sprintf(buf, "Base:%11u (Sys Clk)", base_clk); Label obj34(40, 120, buf, Label::LEFT, Font24, LCD_COLOR_MAGENTA, LCD_COLOR_BLACK); show_time(); run2stop = tmr.read_ms(); if (run2stop < 1000){ while (tmr.read_ms() < 1000){ // 1 second interval if (button.Touched()){ return; } wait_ms(1); } } } } void show_time(void) { char buf[48]; time_t seconds; seconds = time(NULL) + 32400; // Adjust UTC to JST strftime(buf, 40, " %I:%M:%S %p JST %y/%m/%d", localtime(&seconds)); PRINTF("%s\r\n", buf); Label obj0(40, 240, buf, Label::LEFT, Font24, LCD_COLOR_ORANGE, LCD_COLOR_BLACK); } int main() { // Initial input mode input_mode = BNC_NORMAL; input_frq_select = 1; prescaler10or20.output(); prescaler10or20 = 0; recipro_select = 0; while(true){ lcd_.Clear(LCD_COLOR_BLACK); // openning message opening(); PRINTF("\r\n%s%s\r\n", msg_msg0, msg_msg2); PRINTF("%s\r\n", msg_msg1); PRINTF("Wait GPS 1PPS signal\r\n"); // GPS (not return until 3D condition) gps_data_rcv(); lcd_.Clear(LCD_COLOR_BLACK); input_mode = mode_slect(); lcd_.Clear(LCD_COLOR_BLACK); PRINTF("\r\nInput mode # is %u\r\n", input_mode); PRINTF("If you want to change the input signal,"); PRINTF(" please restart the system (Enter Alt+B from your PC)\r\n"); PRINTF("\r\nStart measuring\r\nMeasureing mode = "); switch(input_mode){ case RECIPRO_AC: PRINTF("%s\r\n", msg_mode2); input_frq_select = 1; prescaler10or20.output(); prescaler10or20 = 0; recipro_select = 0; recipro(input_mode); break; case RECIPRO_DC: PRINTF("%s\r\n", msg_mode3); input_frq_select = 1; prescaler10or20.output(); prescaler10or20 = 0; recipro_select = 1; recipro(input_mode); break; case SMA_10: PRINTF("%s\r\n", msg_mode4); input_frq_select = 0; prescaler10or20.output(); prescaler10or20 = 0; recipro_select = 0; freq_measurement(input_mode); break; case SMA_20: PRINTF("%s\r\n", msg_mode5); input_frq_select = 0; prescaler10or20.input(); recipro_select = 0; freq_measurement(input_mode); break; case BNC_NORMAL: default: input_mode = BNC_NORMAL; PRINTF("%s\r\n", msg_mode1); input_frq_select = 1; prescaler10or20.output(); prescaler10or20 = 0; recipro_select = 0; freq_measurement(input_mode); break; } } } void opening() { Label obj10(240, 2, "Frequency Counter using GPS 1PPS", Label::CENTER, Font16); Label obj11(240, 20, " created on Nov. 2016 by JH1PJL/Kenji Arai", Label::CENTER); Label obj12(240, 100, " Please wait to receive", Label::CENTER, Font24, LCD_COLOR_LIGHTYELLOW); Label obj13(240, 120, " GPS signal!! ", Label::CENTER, Font24, LCD_COLOR_LIGHTYELLOW); } uint8_t mode_slect() { Label obj10(240, 2, "Set ""Operationg Mode""", Label::CENTER, Font24, LCD_COLOR_LIGHTGREEN); Label obj11(40, 30, open_msg[0], Label::LEFT); Label obj12(40, 42, open_msg[1], Label::LEFT); Label obj13(40, 54, open_msg[2], Label::LEFT); Label obj14(40, 66, open_msg[3], Label::LEFT); Label obj15(40, 78, open_msg[4], Label::LEFT); const int NUMBER_BUTTONS = 5; const string STR1[NUMBER_BUTTONS] = {"1) Nor(AC)", "2) Rec(AC)", "3) Rec(DC)", "4) 1/10","5) 1/20"}; ButtonGroup bGroup1(18, 120, 85, 40, NUMBER_BUTTONS, STR1, 5, 5, 5, 5, Font12, LCD_COLOR_WHITE, 0xFF003538, 0xFFB70068, 0xFFFF7FFF); NumericLabel<int> bTouch(50, 240, "", Label::LEFT, Font24, LCD_COLOR_ORANGE); Button button1(300, 170, 100, 50, "ENTER", Font16); while (true) { int num; if (bGroup1.GetTouchedNumber(num)){ char buf[32]; strcpy(buf, select_msg[num]); bTouch.Draw(buf, num); } if (button1.Touched()){ return (uint8_t)(num + 1); } wait(0.02f); } } //------------------------------------------------------------------------------ // ORIGINAL PROGRAM FOR F746_GUI_DEMO // by MIKAMI, Naoki // 2016/11/12, Copyright (c) 2016 MIKAMI, Naoki //------------------------------------------------------------------------------ #if 0 //----------------------------------------------------------------------- // GuiBase とその派生クラスのデモプログラム // Demo program for GuiBase class and its derivertive classes // // GuiBase, Button, ButtonGroup, Label, NumericLabel, BlinkLabel, // SeekBar, SeekbarGroup // // 2016/11/12, Copyright (c) 2016 MIKAMI, Naoki //----------------------------------------------------------------------- #include "F746_GUI.hpp" int main() { Label obj10(240, 2, "Dome: GUI parts, 2016/07/30, 19:43", Label::CENTER, Font16); Label obj11(240, 20, "Button, ButtonGroup, Label, NumericLabel, BlinkLabel,", Label::CENTER); Label obj12(240, 32, "SeekBar, SeekbarGroup", Label::CENTER); Button button1(10, 54, 50, 40, "1"); Button button2(62, 54, 50, 40, "2"); const int NUMBER_BUTTONS = 4; const string STR1[NUMBER_BUTTONS] = {"Button1", "Button2", "Button3", "Activate"}; ButtonGroup bGroup1(160, 54, 66, 40, NUMBER_BUTTONS, STR1, 5, 5, 3, 1, Font12, LCD_COLOR_WHITE, 0xFF003538, 0xFFB70068, 0xFFFF7FFF); NumericLabel<int> bTouch(240, 112, "", Label::LEFT, Font12, LCD_COLOR_MAGENTA); // Control status of bGroup1 ButtonGroup bGroup2(160, 150, 66, 40, 3, (string[]){"0", "1", "2"}, 5, 5, 3); bGroup2.InactivateAll(); // Switching buttons to control barH active or inactive ButtonGroup bGroup3(10, 150, 66, 40, 2, (string[]){"ON", "OFF"}, 0, 0, 2); bGroup3.TouchedColor(0); Button doNotTouch(250, 220, 120, 40, "Don't Touch", Font12, GuiBase::ENUM_TEXT, GuiBase::ENUM_BACK, LCD_COLOR_DARKGREEN, LCD_COLOR_RED); // Using default value for argument (Horizontal) SeekBar barH(20, 250, 200, -5, 5, 0, "-5", "", "5"); NumericLabel<float> numLabel1(80, 205, "%5.1f", barH.GetValue()); NumericLabel<int> numLabel2(130, 205, "%3d", (int)barH.GetValue()); NumericLabel<int> numLabel3(160, 205, "%3d"); // SeekbarGroup (vertical) SeekbarGroup barV(410, 130, 121, 2, 45, -6, 6, 2, SeekBar::Vertical, 0xFFA0FFC0); NumericLabel<float> **numLabel4; numLabel4 = new NumericLabel<float> *[2]; for (int n=0; n<2; n++) numLabel4[n] = new NumericLabel<float>(410+n*45, 104, "%4.1f", barV.GetValue(n), Label::CENTER); NumericLabel<int> numLabel5(455, 92, "%1d", barV.GetIntValue(0), Label::CENTER); // Test of left-, cenrer-, and right-justified Label leftJustified(420, 54, "ABC", Label::LEFT); Label centerJustified(420, 64, "ABC", Label::CENTER); Label rightJustified1(420, 74, "ABC", Label::RIGHT); while (true) { if (button1.Touched()) button2.Draw(); if (button2.Touched()) button1.Draw(); int num; if (bGroup1.GetTouchedNumber(num)) bTouch.Draw("Button%d touched", num+1); if (num == 3) bGroup2.ActivateAll(); if (bGroup2.GetTouchedNumber(num)) switch (num) { case 0: button1.Activate(); bGroup1.Activate(1); bGroup1.DrawAll(); break; case 1: button1.Inactivate(); bGroup1.Inactivate(1); break; case 2: bGroup1.EraseAll();//for (int n=0; n<4; n++) bGroup1.Erase(n); for (int n=0; n<2; n++) { barV.Draw(n, 0); // reset seekbar numLabel4[n]->Draw("%4.1f", barV.GetValue(n)); } break; } if (barH.Slide()) { numLabel1.Draw("%5.1f", barH.GetValue()); int8_t x = (int8_t)barH.GetValue(); numLabel2.Draw("%3d", x); numLabel3.Draw(barH.GetIntValue()); } int sbNum; if (barV.GetSlidedNumber(sbNum)) { if (sbNum == 0) numLabel4[sbNum]->Draw("%4.1f", barV.GetValue(sbNum)); else numLabel4[sbNum]->Draw("%4.1f", barV.GetValue(sbNum)); if (sbNum == 1) numLabel5.Draw("%1d", barV.GetIntValue(sbNum)); } // If "doNotTouch" button touched, trapped into endless loop if (doNotTouch.Touched()) BlinkLabel warning(250, 200, "You must reset", Label::LEFT, Font16); // SeekBar active inactive switching if (bGroup3.Touched(0)) { barH.Activate(); barV.ActivateAll(); } if (bGroup3.Touched(1)) { barH.Inactivate(); barV.InactivateAll(); } wait(0.02f); } } #endif