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/
Diff: User_IF/uif.cpp
- Revision:
- 13:1041596c416c
- Child:
- 14:ba6ea409ab05
diff -r 05098414599b -r 1041596c416c User_IF/uif.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/User_IF/uif.cpp Wed Nov 23 07:35:20 2016 +0000 @@ -0,0 +1,558 @@ +/* + * mbed Application program / User Interface subroutines + * + * Copyright (c) 2016 Kenji Arai / JH1PJL + * http://www.page.sannet.ne.jp/kenjia/index.html + * http://mbed.org/users/kenjiArai/ + * Created: September 28th, 2016 + * Revised: Novemeber 23rd, 2016 + * + * 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. + */ + +#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 char *const msg_clear = " "; +static char *const msg_msg0 = "Frequency Counter "; +static char *const msg_msg1 = " mbed Nucleo F746ZG "; +static char *const msg_msg2 = " by JH1PJL K.Arai "; +static char *const msg_msg3 = " "__DATE__" UTC"; +static 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 "__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); +}