Frequency counter using GPS 1PPS signal and temperature controlled 50MHz Base clock. Ported from F411 Frequency Counter.
Dependencies: QEI DRV8830 PID ADT7410 TextLCD Frq_cuntr_Nucleo-F746ZG RingBuffer
Fork of Frequency_Counter_w_GPS_1PPS by
Please refer following.
/users/kenjiArai/notebook/frequency-counters/
User_IF/uif.cpp
- Committer:
- kenjiArai
- Date:
- 2019-12-17
- Revision:
- 14:ba6ea409ab05
- Parent:
- 13:1041596c416c
- Child:
- 15:ae0413277bc6
File content as of revision 14:ba6ea409ab05:
/* * mbed Application program / User Interface subroutines * * Copyright (c) 2016,'19 Kenji Arai / JH1PJL * http://www.page.sannet.ne.jp/kenjia/index.html * http://mbed.org/users/kenjiArai/ * Created: September 28th, 2016 * Revised: December 12th, 2019 */ #define USE_COM // use Communication with PC(UART) // Include -------------------------------------------------------------------- #include "mbed.h" #include "rtos.h" #include "frq_cuntr_f746.h" #include "TextLCD.h" #include "QEI.h" #include "uif.h" // Definition ----------------------------------------------------------------- #define ONLY_VALUE 1 // Uart (output only value) #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 // Object --------------------------------------------------------------------- extern Serial pc; extern Ticker enter_irq; extern DigitalOut in_frq_slct; extern DigitalInOut prescaler10or20; QEI rotary(PE_9, PF_13, NC, 24, QEI::X4_ENCODING); //Rotary chB,chA TextLCD lcd(PD_3, PC_3, PD_4, PD_5, PD_6, PD_7, TextLCD::LCD20x4); DigitalOut led_R_gps1pps(PE_7); DigitalOut led_G_temp_ok(PE_8); DigitalOut led_B_recipro(PG_9); DigitalOut led_W_prescaler(PG_14); DigitalOut led_R_rotary(PF_15); DigitalOut led_G_rotary(PE_13); DigitalOut led_B_rotary(PF_14); DigitalIn rotary_sw(PE_11); // RAM ------------------------------------------------------------------------ int8_t function_num; // working area char buf[40]; // write mode control uint8_t mode_change_flg = 0; // Prescaler selct uint8_t prescaler_on = 0; uint8_t prescaler_div20 = 0; // Rotary switch uint32_t enter = 0; uint8_t enter_first_flg = 0; // Time time_t seconds; time_t seconds_jst; // Reciprocal data extern uint8_t recipro_new_data_ready; // Function prototypes -------------------------------------------------------- static int8_t rotary_sw_update(void); static void change_setting(void); static void uart_output(dispDef *dt); static void led_update(dispDef *dt); static void dsp_freq(dispDef *dt); static void dsp_1pps(dispDef *dt); static void dsp_detail(dispDef *dt); static void dsp_simple(dispDef *dt); static void dsp_recipro(dispDef *dt); static void dsp_gps_status(dispDef *dt); static void dsp_current_setting(dispDef *dt); // ROM / Constant data -------------------------------------------------------- // 12345678901234567890 static const char *const msg_clear = " "; static const char *const msg_msg0 = "Frequency Counter "; static const char *const msg_msg1 = " mbed Nucleo F746ZG "; static const char *const msg_msg2 = " by JH1PJL K.Arai "; static const char *const msg_msg3 = " " __DATE__" UTC"; static const char *const msg_msg4 = "Getting GPS,pls wait"; // function table void (*functptr[])(dispDef*) = { dsp_freq, dsp_1pps, dsp_detail, dsp_simple, dsp_recipro, dsp_gps_status, dsp_current_setting }; //------------------------------------------------------------------------------ // Control Program //------------------------------------------------------------------------------ void dispay_LCD_and_UART(dispDef *dt) { uint8_t size; uart_output(dt); display_clear_all(); led_update(dt); if (mode_change_flg == 0){ led_B_rotary = !led_B_rotary; led_R_rotary = 0; function_num += rotary_sw_update(); //size = sizeof(*functptr); // doesn't work size = 7; if (function_num >= size){ function_num = 0; } else if (function_num < 0){ function_num = size - 1; } (*functptr[function_num])(dt); // pick one function from a table } else { led_B_rotary = 0; led_R_rotary = !led_R_rotary; change_setting(); } } void change_setting() { static int8_t n; static int8_t old_mode_change_flg; uint8_t p; lcd.locate(0, 0); // 12345678901234567890 lcd.printf(" 1/1 BNC"); lcd.locate(0, 1); // 12345678901234567890 lcd.printf(" 1/10 SMA"); lcd.locate(0, 2); // 12345678901234567890 lcd.printf(" 1/20 SMA"); lcd.locate(0, 3); // 12345678901234567890 lcd.printf("Select then push SW!"); n += rotary_sw_update(); if (n < 0){ p = n * -1; } else { p = n; } p %= 3; lcd.locate(0, p); // 12345678901234567890 lcd.printf("--->>>"); if (old_mode_change_flg != mode_change_flg){ if (mode_change_flg == 1){ old_mode_change_flg = mode_change_flg; } else { select_input_div_1or10or20(p); mode_change_flg = 0; old_mode_change_flg = 0; } } } // Display LED's static void led_update(dispDef *dt) { if (dt->ready_1pps == 3) { led_R_gps1pps = 1; } else { led_R_gps1pps = 0; } if (prescaler_on){ if (prescaler_div20){ led_W_prescaler = !led_W_prescaler; } else { led_W_prescaler = 1; } } else { led_W_prescaler = 0; } if (dt->recipro_of == 0){ led_B_recipro = 1; } else { led_B_recipro = 0; } if (dt->temp_is_okay == 1){ led_G_temp_ok = 1; } else { led_G_temp_ok = 0; } } // Data output via VCOM line static void uart_output(dispDef *dt) { static uint32_t n = 0; PRINTF("%9.0f,", dt->m_frq); PRINTF("%10d,", dt->b_1pps_new); // compensated PRINTF("%12.3f,", dt->m_frq_comp); PRINTF("%13.3f,", dt->b_1pps_lng); // 10sec data PRINTF("%10.1f,", dt->m_frq_10); // 100sec data PRINTF("%11.2f,", dt->m_frq_100); // 1000sec data PRINTF("%12.3f,", dt->m_frq_1000); if (recipro_new_data_ready){ recipro_new_data_ready = 0; if (dt->recipro_of){ PRINTF("over5KHz ,"); } else { PRINTF("%12.6f,", dt->m_frq_recipro); } } else { PRINTF("measuring ,"); } if (prescaler_on){ if (prescaler_div20){ PRINTF("Div20,"); } else { PRINTF("Div10,"); } } else { PRINTF("Div1 ,"); } PRINTF("%+6.3f,", dt->box_tmp); seconds = time(NULL); seconds_jst = seconds + 32400; // +9 hours ->JST // 13:12:11 strftime(buf, 40, "%H:%M:%S", localtime(&seconds_jst)); PRINTF("%s,", buf); // Number PRINTF("%08d\r\n", n++); } void select_input_div_1or10or20(uint8_t mode) { if (mode == 2){ // 1/20 prescaler_on = 1; prescaler_div20 = 1; in_frq_slct = 0; // Select SMA input with pre-scaler prescaler10or20.input(); } else if (mode == 1){ // 1/10 prescaler_on = 1; prescaler_div20 = 0; in_frq_slct = 0; // Select SMA input with pre-scaler prescaler10or20.output(); prescaler10or20 = 0; } else { prescaler_on = 0; prescaler_div20 = 0; in_frq_slct = 1; // Select BNC //prescaler10or20 = 1; prescaler10or20.output(); prescaler10or20 = 0; } } // Interrupt handler for Rotary SW Push bottom void enter_action() { if (rotary_sw == 1){ enter_first_flg = 1; } else { if (enter_first_flg){ if (enter++ > 2){ enter = 0; mode_change_flg++; // action trigger for SW on enter_first_flg = 0; } } } } // Detect rotary switch rotation static int8_t rotary_sw_update() { static int8_t position_old; int8_t pos, dt; pos = rotary.getPulses()/4; if (pos != position_old){ if (pos > position_old){ if (pos < 0){ dt = -1; } else { dt = 1; } } else { if (pos < 0){ dt = 1; } else { dt = -1; } } } else { dt = 0; } position_old = pos; return dt; } //****************************************************************************** static void dsp_freq(dispDef *dt) { lcd.locate(0, 0); if (prescaler_on == 0){ lcd.printf("Freq = %8.0f Hz", dt->m_frq); } else if (prescaler_div20){ lcd.printf("Freq = %7.4fMHz", dt->m_frq * 20.0f); // 1/20 } else { lcd.printf("Freq = %8.5fMHz", dt->m_frq * 10.0f); // 1/10 } lcd.locate(0, 1); if (dt->m_frq_10 == 0.0f){ lcd.printf("10s = not yet"); } else { if (prescaler_on == 0){ lcd.printf("10s = %9.1f", dt->m_frq_10); } else if (prescaler_div20){ lcd.printf("10s = %8.5f", dt->m_frq_10 * 20.0f); // 1/20 } else { lcd.printf("10s = %9.6f", dt->m_frq_10 * 10.0f); // 1/10 } } lcd.locate(0, 2); if (dt->m_frq_100 == 0.0f){ lcd.printf("100s = not yet"); } else { if (prescaler_on == 0){ lcd.printf("100s = %10.2f", dt->m_frq_100); } else if (prescaler_div20){ lcd.printf("100s = %9.6f", dt->m_frq_100 * 20.0f); // 1/20 } else { lcd.printf("100s = %10.7f", dt->m_frq_100 * 10.0f); // 1/10 } } lcd.locate(0, 3); if (dt->m_frq_1000 == 0.0f){ strftime(buf,40, "%I:%M:%S%p (%m/%d)", localtime(&seconds_jst)); lcd.printf("%s %d", buf, function_num); } else { if (prescaler_on == 0){ lcd.printf("1000s= %11.3f", dt->m_frq_1000); } else if (prescaler_div20){ lcd.printf("1000s= %10.7f", dt->m_frq_1000 * 20.0f); // 1/20 } else { lcd.printf("1000s= %11.8f", dt->m_frq_1000 * 10.0f); // 1/10 } } } static void dsp_1pps(dispDef *dt) { lcd.locate(0, 0); if (dt->m_frq_10 == 0.0f){ lcd.printf("10s = not yet"); } else { if (prescaler_on == 0){ lcd.printf("10s = %9.1f", dt->m_frq_10); } else if (prescaler_div20){ lcd.printf("10s = %8.5f", dt->m_frq_10 * 20.0f); // 1/20 } else { lcd.printf("10s = %9.6f", dt->m_frq_10 * 10.0f); // 1/10 } } lcd.locate(0, 1); lcd.printf("1PPS = %8d Hz", dt->b_1pps_new); lcd.locate(0, 2); lcd.printf("Oven Temp= %+5.2f%cC", dt->box_tmp, 0xdf); lcd.locate(0, 3); strftime(buf,40, "%I:%M:%S%p (%m/%d)", localtime(&seconds_jst)); lcd.printf("%s %d", buf, function_num); } static void dsp_detail(dispDef *dt) { lcd.locate(0, 0); if (dt->m_frq_100 == 0.0f){ lcd.printf("100s = not yet"); } else { if (prescaler_on == 0){ lcd.printf("100s = %11.2f", dt->m_frq_100); } else if (prescaler_div20){ lcd.printf("100s = %9.6f", dt->m_frq_100 * 20.0f); // 1/20 } else { lcd.printf("100s = %10.7f", dt->m_frq_100 * 10.0f); // 1/10 } } lcd.locate(0, 1); if (dt->gps_1pps_ave == 1000){ lcd.printf("1PPS = %12.3f ", dt->b_1pps_lng); } else if (dt->gps_1pps_ave == 100){ lcd.printf("1PPS = %11.2f ", dt->b_1pps_lng); } else if (dt->gps_1pps_ave == 10){ lcd.printf("1PPS = %10.1f ", dt->b_1pps_lng); } else { lcd.printf("1PPS = %9.0f " , dt->b_1pps_lng); } lcd.locate(0, 2); lcd.printf("Oven Temp= %+6.3f%cC", dt->box_tmp, 0xdf); lcd.locate(0, 3); strftime(buf,40, "%I:%M:%S%p (%m/%d)", localtime(&seconds_jst)); lcd.printf("%s %d", buf, function_num); } static void dsp_simple(dispDef *dt) { lcd.locate(0, 0); if (prescaler_on == 0){ lcd.printf("Freq = %8.0f Hz", dt->m_frq); } else if (prescaler_div20){ lcd.printf("Freq = %7.4fMHz", dt->m_frq * 20.0f); // 1/20 } else { lcd.printf("Freq = %8.5fMHz", dt->m_frq * 10.0f); // 1/10 } lcd.locate(0, 1); lcd.printf("1PPS = %8d Hz", dt->b_1pps_new); lcd.locate(0, 2); lcd.printf("Oven Temp= %+3.0f%cC", dt->box_tmp, 0xdf); lcd.locate(0, 3); strftime(buf,40, "%I:%M:%S%p (%m/%d)", localtime(&seconds_jst)); lcd.printf("%s %d", buf, function_num); } static void dsp_recipro(dispDef *dt) { if ((prescaler_on != 0) || (dt->recipro_of == 1)){ display_clear_all(); lcd.locate(0, 0); // 12345678901234567890 lcd.printf(" Reciprocal data is"); lcd.locate(0, 1); lcd.printf(" Not avairable "); lcd.locate(0, 3); // 12345678901234567890 lcd.printf(" %d", function_num); } else { lcd.locate(0, 0); // 12345678901234567890 lcd.printf("Reciprocal [Hz] "); lcd.locate(0, 1); if (dt->recipro_of){ // 12345678901234567890 lcd.printf(" 5KHz over "); } else { lcd.printf(" %11.6f,", dt->m_frq_recipro); } lcd.locate(0, 2); lcd.printf("Oven Temp= %+6.3f%cC", dt->box_tmp, 0xdf); lcd.locate(0, 3); strftime(buf,40, "%I:%M:%S%p (%m/%d)", localtime(&seconds_jst)); lcd.printf("%s %d", buf, function_num); } } static void dsp_current_setting(dispDef *dt) { lcd.locate(0, 0); // 12345678901234567890 lcd.printf("Current setting "); lcd.locate(0, 1); if (prescaler_on == 1){ if (prescaler_div20 == 1){ // 12345678901234567890 lcd.printf(" Prescaler =ON 1/20"); } else { // 12345678901234567890 lcd.printf(" Prescaler =ON 1/10"); } } else { // 12345678901234567890 lcd.printf(" None-Prescaler(BNC)"); } lcd.locate(0, 2); // 12345678901234567890 lcd.printf("Change parameter "); lcd.locate(0, 3); // 12345678901234567890 lcd.printf(" -> Push Switch %d", function_num); } static void dsp_gps_status(dispDef *dt) { lcd.locate(0, 0); // 12345678901234567890 lcd.printf("GPS status "); lcd.locate(0, 1); // 12345678901234567890 lcd.printf(" 3D or not --> %u ", dt->ready_1pps); lcd.locate(0, 2); lcd.printf("Oven Temp= %+6.3f%cC", dt->box_tmp, 0xdf); lcd.locate(0, 3); strftime(buf,40, "%I:%M:%S%p (%m/%d)", localtime(&seconds_jst)); lcd.printf("%s %d", buf, function_num); } // Clear LCD screen void display_clear_all(void) { lcd.locate(0, 0); lcd.printf(msg_clear); lcd.printf(msg_clear); lcd.printf(msg_clear); lcd.printf(msg_clear); } // Openning message on LCD & message via VCOM void disp_first_msg(void) { // lcd.setCursor(LCDCursol 0); // Cursol off // LCD Initial screen lcd.locate(0, 0); lcd.printf(msg_msg0); lcd.printf(msg_msg1); lcd.printf(msg_msg2); lcd.printf(msg_msg3); // Clear all LED led_R_gps1pps = 0; led_W_prescaler = 0; led_R_rotary = 0; led_G_rotary = 0; led_B_rotary = 0; // VCOM message BAUD(9600); //PRINTF("\r\nFrequency Counter by JH1PJL created on \r\n"); PRINTF("\r\nFrequency Counter by JH1PJL created on " __DATE__"\r\n"); PRINTF("\r\nStarted!\r\n"); PRINTF("SystemCoreClock = %d Hz\r\n", SystemCoreClock); // Rotary switch control enter_irq.attach_us(&enter_action, 5000); // every 5mS } // GPS waiting message void disp_wait_gps(void) { lcd.locate(0, 3); lcd.printf(msg_msg4); }