Accurate Frequency Counter up to 25MHz. Base clock is compensated by GPS 1PPS pulse. This program runs only on mbed NucleoF411RE.

Dependencies:   ADT7410 CheckRTC DRV8830 Frq_cuntr_full PID TextLCD mbed-rtos mbed iSerial

Fork of Frequency_Counter by Kenji Arai

Please refer following.
/users/kenjiArai/notebook/frequency-counters/

Committer:
kenjiArai
Date:
Thu Jan 01 05:08:31 2015 +0000
Revision:
9:e98e94ba17f9
Parent:
8:7b033903c8fb
Child:
11:20e7a45f1448
Combined Temperature Control for Peltier device, Get GPS time and set RTC, runs on RTOS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 5:af9fa3d0731c 1 /*
kenjiArai 8:7b033903c8fb 2 * mbed Application program / Frequency Counter with GPS 1PPS Compensation
kenjiArai 5:af9fa3d0731c 3 *
kenjiArai 5:af9fa3d0731c 4 * Copyright (c) 2014 Kenji Arai / JH1PJL
kenjiArai 5:af9fa3d0731c 5 * http://www.page.sannet.ne.jp/kenjia/index.html
kenjiArai 5:af9fa3d0731c 6 * http://mbed.org/users/kenjiArai/
kenjiArai 5:af9fa3d0731c 7 * Created: October 18th, 2014
kenjiArai 9:e98e94ba17f9 8 * Revised: January 1st, 2015
kenjiArai 5:af9fa3d0731c 9 *
kenjiArai 5:af9fa3d0731c 10 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
kenjiArai 5:af9fa3d0731c 11 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
kenjiArai 5:af9fa3d0731c 12 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
kenjiArai 5:af9fa3d0731c 13 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kenjiArai 5:af9fa3d0731c 14 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
kenjiArai 5:af9fa3d0731c 15 */
mio 0:c988614df67a 16
kenjiArai 6:44c2bcbdd77b 17 #define USE_COM // use Communication with PC(UART)
kenjiArai 9:e98e94ba17f9 18 #define SET_RTC
kenjiArai 9:e98e94ba17f9 19 //#define USE_DEBUG
kenjiArai 6:44c2bcbdd77b 20
kenjiArai 5:af9fa3d0731c 21 // Include ---------------------------------------------------------------------------------------
mio 0:c988614df67a 22 #include "mbed.h"
kenjiArai 9:e98e94ba17f9 23 #include "rtos.h"
kenjiArai 9:e98e94ba17f9 24 #include "TextLCD.h"
kenjiArai 9:e98e94ba17f9 25 #include "DRV8830.h"
kenjiArai 9:e98e94ba17f9 26 #include "ADT7410.h"
kenjiArai 9:e98e94ba17f9 27 #include "PID.h"
kenjiArai 8:7b033903c8fb 28 #include "frq_cuntr_full.h"
kenjiArai 9:e98e94ba17f9 29 #include "CheckRTC.h"
kenjiArai 9:e98e94ba17f9 30 #include "gps.h"
kenjiArai 8:7b033903c8fb 31
kenjiArai 8:7b033903c8fb 32 using namespace Frequency_counter;
mio 0:c988614df67a 33
kenjiArai 5:af9fa3d0731c 34 // Definition ------------------------------------------------------------------------------------
kenjiArai 5:af9fa3d0731c 35 #ifdef USE_COM
kenjiArai 5:af9fa3d0731c 36 #define BAUD(x) pc.baud(x)
kenjiArai 5:af9fa3d0731c 37 #define GETC(x) pc.getc(x)
kenjiArai 5:af9fa3d0731c 38 #define PUTC(x) pc.putc(x)
kenjiArai 5:af9fa3d0731c 39 #define PRINTF(...) pc.printf(__VA_ARGS__)
kenjiArai 5:af9fa3d0731c 40 #define READABLE(x) pc.readable(x)
kenjiArai 5:af9fa3d0731c 41 #else
kenjiArai 5:af9fa3d0731c 42 #define BAUD(x) {;}
kenjiArai 5:af9fa3d0731c 43 #define GETC(x) {;}
kenjiArai 5:af9fa3d0731c 44 #define PUTC(x) {;}
kenjiArai 5:af9fa3d0731c 45 #define PRINTF(...) {;}
kenjiArai 5:af9fa3d0731c 46 #define READABLE(x) {;}
kenjiArai 5:af9fa3d0731c 47 #endif
mio 1:2a347c40b1da 48
kenjiArai 9:e98e94ba17f9 49 #ifdef USE_DEBUG
kenjiArai 9:e98e94ba17f9 50 #define DEBUGBAUD(x) pc.baud(x)
kenjiArai 9:e98e94ba17f9 51 #define DEBUG(...) pc.printf(__VA_ARGS__)
kenjiArai 9:e98e94ba17f9 52 #else
kenjiArai 9:e98e94ba17f9 53 #define DEBUGBAUD(x) {;}
kenjiArai 9:e98e94ba17f9 54 #define DEBUG(...) {;}
kenjiArai 9:e98e94ba17f9 55 #endif
kenjiArai 9:e98e94ba17f9 56
kenjiArai 9:e98e94ba17f9 57 #define CLOCK_BASE (24.999982f)
kenjiArai 9:e98e94ba17f9 58
kenjiArai 9:e98e94ba17f9 59 #define GSP_BUF_B (128 * 3)
kenjiArai 9:e98e94ba17f9 60 #define GPS_BUF_S (128 * 2)
kenjiArai 9:e98e94ba17f9 61
kenjiArai 5:af9fa3d0731c 62 // Object ----------------------------------------------------------------------------------------
kenjiArai 9:e98e94ba17f9 63 DigitalOut led_gate(LED1);
kenjiArai 8:7b033903c8fb 64 Serial pc(USBTX, USBRX);
kenjiArai 9:e98e94ba17f9 65 Serial gps(NC, PA_10); // GPS RX
kenjiArai 8:7b033903c8fb 66 I2C i2cBus(PB_9,PB_8); // SDA, SCL
kenjiArai 9:e98e94ba17f9 67 DRV8830 heater(i2cBus, (uint8_t)DRV8830ADDR_00);
kenjiArai 9:e98e94ba17f9 68 ADT7410 t(i2cBus, ADT7410ADDR_NN);
kenjiArai 9:e98e94ba17f9 69 TextLCD lcd(PB_0, PA_4, PC_0, PC_1, PC_2, PC_3, TextLCD::LCD20x4); // rs, e, d4-d7
kenjiArai 9:e98e94ba17f9 70 PID pid(14.0f, 50.0f, 1.5f, 1.0f);
kenjiArai 9:e98e94ba17f9 71 // PC_6,PC_7 & PB_6 use for Timer3 & 4(16+16bit)
kenjiArai 9:e98e94ba17f9 72 // PA_0,PA_1 & PB_10 use for Timer2(32bit)
kenjiArai 9:e98e94ba17f9 73 // PA_8 & PC_7 use for MCO (Test purpose)
kenjiArai 9:e98e94ba17f9 74 FRQ_CUNTR fc(PC_6, 1.0, CLOCK_BASE); // Input port, gate time[sec] and External clock freq.
kenjiArai 6:44c2bcbdd77b 75
kenjiArai 5:af9fa3d0731c 76 // RAM -------------------------------------------------------------------------------------------
kenjiArai 9:e98e94ba17f9 77 // Freq.
kenjiArai 9:e98e94ba17f9 78 uint32_t counter_1pps;
kenjiArai 9:e98e94ba17f9 79 double new_frequency;
kenjiArai 9:e98e94ba17f9 80 double base_clock_1pps;
kenjiArai 9:e98e94ba17f9 81 // Temp Control
kenjiArai 9:e98e94ba17f9 82 float volt = 0.0;
kenjiArai 9:e98e94ba17f9 83 float tmp = 0;
kenjiArai 9:e98e94ba17f9 84 float pid_val = 0;
kenjiArai 9:e98e94ba17f9 85 uint32_t n = 0;
kenjiArai 9:e98e94ba17f9 86 // GPS
kenjiArai 9:e98e94ba17f9 87 uint32_t gps_status;
kenjiArai 9:e98e94ba17f9 88 uint8_t gps_rmc_ready;
kenjiArai 9:e98e94ba17f9 89 char GPS_Buffer[GSP_BUF_B]; //GPS data buffer
kenjiArai 9:e98e94ba17f9 90 char MsgBuf_RMC[GPS_BUF_S];
kenjiArai 9:e98e94ba17f9 91 char MsgBuf_GGA[GPS_BUF_S];
kenjiArai 9:e98e94ba17f9 92 // Time
kenjiArai 9:e98e94ba17f9 93 time_t seconds;
kenjiArai 9:e98e94ba17f9 94 time_t seconds_jst;
kenjiArai 9:e98e94ba17f9 95 struct tm t_gps;
kenjiArai 9:e98e94ba17f9 96 // rtos
kenjiArai 9:e98e94ba17f9 97 Queue<uint32_t, 2> queue0;
kenjiArai 6:44c2bcbdd77b 98
kenjiArai 5:af9fa3d0731c 99 // ROM / Constant data ---------------------------------------------------------------------------
kenjiArai 9:e98e94ba17f9 100 // 12345678901234567890
kenjiArai 9:e98e94ba17f9 101 static char *const msg_clear = " ";
kenjiArai 9:e98e94ba17f9 102 static char *const msg_msg0 = "Frequency Counter ";
kenjiArai 9:e98e94ba17f9 103 static char *const msg_msg1 = " mbed Nucleo F411RE";
kenjiArai 9:e98e94ba17f9 104 static char *const msg_msg2 = " by JH1PJL K.Arai";
kenjiArai 9:e98e94ba17f9 105 static char *const msg_msg3 = " "__DATE__" ";
mio 1:2a347c40b1da 106
kenjiArai 5:af9fa3d0731c 107 // Function prototypes ---------------------------------------------------------------------------
kenjiArai 9:e98e94ba17f9 108 void gps_rcv(void);
kenjiArai 9:e98e94ba17f9 109 uint32_t check_gps_ready(void);
kenjiArai 9:e98e94ba17f9 110 uint8_t check_gps_rmc_ready(void);
kenjiArai 9:e98e94ba17f9 111 void get_time_and_date(struct tm *pt);
kenjiArai 9:e98e94ba17f9 112 void getline_gps(void);
kenjiArai 5:af9fa3d0731c 113
kenjiArai 5:af9fa3d0731c 114 //-------------------------------------------------------------------------------------------------
kenjiArai 5:af9fa3d0731c 115 // Control Program
kenjiArai 5:af9fa3d0731c 116 //-------------------------------------------------------------------------------------------------
kenjiArai 9:e98e94ba17f9 117 void measure_freq(void const *args)
kenjiArai 9:e98e94ba17f9 118 {
kenjiArai 9:e98e94ba17f9 119 while(true) {
kenjiArai 9:e98e94ba17f9 120 if (fc.status_freq_update() != 0) {
kenjiArai 9:e98e94ba17f9 121 new_frequency = fc.read_freq_data();
kenjiArai 9:e98e94ba17f9 122 queue0.put((uint32_t*)1);
kenjiArai 9:e98e94ba17f9 123 }
kenjiArai 9:e98e94ba17f9 124 if (fc.status_1pps() != 0) {
kenjiArai 9:e98e94ba17f9 125 counter_1pps = fc.read_avarage_1pps();
kenjiArai 9:e98e94ba17f9 126 }
kenjiArai 9:e98e94ba17f9 127 Thread::wait(100);
kenjiArai 9:e98e94ba17f9 128 }
kenjiArai 9:e98e94ba17f9 129 }
kenjiArai 9:e98e94ba17f9 130
kenjiArai 9:e98e94ba17f9 131 void temp_control(void const *args)
kenjiArai 9:e98e94ba17f9 132 {
kenjiArai 9:e98e94ba17f9 133 t.set_config(OPERATION_MODE_CONT + RESOLUTION_16BIT);
kenjiArai 9:e98e94ba17f9 134 pid.setInputLimits(0.0, 4.5);
kenjiArai 9:e98e94ba17f9 135 pid.setOutputLimits(0.0, 5.0);
kenjiArai 9:e98e94ba17f9 136 pid.setSetPoint(2.5);
kenjiArai 9:e98e94ba17f9 137 while(true) {
kenjiArai 9:e98e94ba17f9 138 tmp = t.read_temp();
kenjiArai 9:e98e94ba17f9 139 pid.setProcessValue(tmp / 10);
kenjiArai 9:e98e94ba17f9 140 pid_val = pid.compute();
kenjiArai 9:e98e94ba17f9 141 volt = pid_val - 2.5f;
kenjiArai 9:e98e94ba17f9 142 if (volt < -0.8f) {
kenjiArai 9:e98e94ba17f9 143 volt = -0.8f;
kenjiArai 9:e98e94ba17f9 144 } else if (volt > 0.8f) {
kenjiArai 9:e98e94ba17f9 145 volt = 0.8f;
kenjiArai 9:e98e94ba17f9 146 }
kenjiArai 9:e98e94ba17f9 147 heater.set_voltage(volt);
kenjiArai 9:e98e94ba17f9 148 if (heater.status()) {
kenjiArai 9:e98e94ba17f9 149 heater.reset();
kenjiArai 9:e98e94ba17f9 150 }
kenjiArai 9:e98e94ba17f9 151 /* Wait until it is time to check again. */
kenjiArai 9:e98e94ba17f9 152 Thread::wait(1000);
kenjiArai 9:e98e94ba17f9 153 }
kenjiArai 9:e98e94ba17f9 154 }
kenjiArai 9:e98e94ba17f9 155
kenjiArai 9:e98e94ba17f9 156 // Get GAA data
kenjiArai 9:e98e94ba17f9 157 void gps_data_rcv(void const *args)
kenjiArai 5:af9fa3d0731c 158 {
kenjiArai 9:e98e94ba17f9 159 int8_t i;
kenjiArai 9:e98e94ba17f9 160 time_t old_ave_sec[2];
kenjiArai 9:e98e94ba17f9 161 uint32_t diff;
kenjiArai 9:e98e94ba17f9 162
kenjiArai 9:e98e94ba17f9 163 gps.baud(9600);
kenjiArai 9:e98e94ba17f9 164 seconds = time(NULL);
kenjiArai 9:e98e94ba17f9 165 DEBUG("\r\nCurrent Time: %s\r\n", ctime(&seconds));
kenjiArai 9:e98e94ba17f9 166 old_ave_sec[0] = 0;
kenjiArai 9:e98e94ba17f9 167 old_ave_sec[1] = 0;
kenjiArai 9:e98e94ba17f9 168 while(true) {
kenjiArai 9:e98e94ba17f9 169 getline_gps(); // Get GPS data from UART
kenjiArai 9:e98e94ba17f9 170 if (strncmp(GPS_Buffer, "$GPRMC",6) == 0) {
kenjiArai 9:e98e94ba17f9 171 for (i=0; GPS_Buffer[i] != 0; i++) {// Copy msg to RMC buffer
kenjiArai 9:e98e94ba17f9 172 MsgBuf_RMC[i] = GPS_Buffer[i];
kenjiArai 9:e98e94ba17f9 173 }
kenjiArai 9:e98e94ba17f9 174 MsgBuf_RMC[i+1] = 0;
kenjiArai 9:e98e94ba17f9 175 DEBUG("GET RMC\r\n");
kenjiArai 9:e98e94ba17f9 176 if (gps_status > 3) {
kenjiArai 9:e98e94ba17f9 177 get_time_and_date(&t_gps);
kenjiArai 9:e98e94ba17f9 178 seconds = mktime(&t_gps);
kenjiArai 9:e98e94ba17f9 179 if (old_ave_sec[0] == 0){
kenjiArai 9:e98e94ba17f9 180 old_ave_sec[0] = seconds;
kenjiArai 9:e98e94ba17f9 181 } else if (old_ave_sec[1] == 0){
kenjiArai 9:e98e94ba17f9 182 old_ave_sec[1] = seconds;
kenjiArai 9:e98e94ba17f9 183 } else {
kenjiArai 9:e98e94ba17f9 184 if (old_ave_sec[0] >= old_ave_sec[1]){
kenjiArai 9:e98e94ba17f9 185 diff = old_ave_sec[0] - old_ave_sec[1];
kenjiArai 9:e98e94ba17f9 186 } else {
kenjiArai 9:e98e94ba17f9 187 diff = old_ave_sec[1] - old_ave_sec[0];
kenjiArai 9:e98e94ba17f9 188 }
kenjiArai 9:e98e94ba17f9 189 if (diff > 100 ){
kenjiArai 9:e98e94ba17f9 190 old_ave_sec[0] = seconds;
kenjiArai 9:e98e94ba17f9 191 old_ave_sec[1] = 0;
kenjiArai 9:e98e94ba17f9 192 } else {
kenjiArai 9:e98e94ba17f9 193 if (old_ave_sec[0] > old_ave_sec[1]){
kenjiArai 9:e98e94ba17f9 194 diff = seconds - old_ave_sec[0];
kenjiArai 9:e98e94ba17f9 195 if (diff < 100){
kenjiArai 9:e98e94ba17f9 196 old_ave_sec[1] = seconds;
kenjiArai 9:e98e94ba17f9 197 }
kenjiArai 9:e98e94ba17f9 198 } else {
kenjiArai 9:e98e94ba17f9 199 diff = seconds - old_ave_sec[1];
kenjiArai 9:e98e94ba17f9 200 if (diff < 100){
kenjiArai 9:e98e94ba17f9 201 old_ave_sec[0] = seconds;
kenjiArai 9:e98e94ba17f9 202 }
kenjiArai 9:e98e94ba17f9 203 }
kenjiArai 9:e98e94ba17f9 204 set_time(seconds);
kenjiArai 9:e98e94ba17f9 205 DEBUG("SET RTC\r\n");
kenjiArai 9:e98e94ba17f9 206 }
kenjiArai 9:e98e94ba17f9 207 }
kenjiArai 9:e98e94ba17f9 208 }
kenjiArai 9:e98e94ba17f9 209 } else if (strncmp(GPS_Buffer, "$GPGGA",6) == 0) {
kenjiArai 9:e98e94ba17f9 210 for (i=0; GPS_Buffer[i] != 0; i++) {// Copy msg to GGA buffer
kenjiArai 9:e98e94ba17f9 211 MsgBuf_GGA[i] = GPS_Buffer[i];
kenjiArai 9:e98e94ba17f9 212 }
kenjiArai 9:e98e94ba17f9 213 MsgBuf_GGA[i+1] = 0;
kenjiArai 9:e98e94ba17f9 214 DEBUG("GET GGA\r\n");
kenjiArai 9:e98e94ba17f9 215 gps_status = check_gps_ready();
kenjiArai 9:e98e94ba17f9 216 }
kenjiArai 9:e98e94ba17f9 217 }
kenjiArai 9:e98e94ba17f9 218 }
kenjiArai 9:e98e94ba17f9 219
kenjiArai 9:e98e94ba17f9 220 void display_data(void const *args)
kenjiArai 9:e98e94ba17f9 221 {
kenjiArai 9:e98e94ba17f9 222 char buf[40];
kenjiArai 8:7b033903c8fb 223
kenjiArai 8:7b033903c8fb 224 BAUD(9600);
kenjiArai 9:e98e94ba17f9 225 DEBUGBAUD(9600);
kenjiArai 6:44c2bcbdd77b 226 PRINTF("\r\nFrequency Counter by JH1PJL created on "__DATE__"\r\n");
kenjiArai 9:e98e94ba17f9 227 // Initial screen
kenjiArai 9:e98e94ba17f9 228 lcd.locate(0, 0);
kenjiArai 9:e98e94ba17f9 229 lcd.printf(msg_msg0);
kenjiArai 9:e98e94ba17f9 230 lcd.printf(msg_msg1);
kenjiArai 9:e98e94ba17f9 231 lcd.printf(msg_msg2);
kenjiArai 9:e98e94ba17f9 232 lcd.printf(msg_msg3);
kenjiArai 9:e98e94ba17f9 233 Thread::wait(3000);
kenjiArai 9:e98e94ba17f9 234 lcd.locate(0, 0);
kenjiArai 9:e98e94ba17f9 235 lcd.printf(msg_clear);
kenjiArai 9:e98e94ba17f9 236 lcd.printf(msg_clear);
kenjiArai 9:e98e94ba17f9 237 lcd.printf(msg_clear);
kenjiArai 9:e98e94ba17f9 238 lcd.printf(msg_clear);
kenjiArai 5:af9fa3d0731c 239 while(true) {
kenjiArai 9:e98e94ba17f9 240 osEvent evt = queue0.get();
kenjiArai 9:e98e94ba17f9 241 PRINTF("FRQ= %11.1f Hz, ", new_frequency);
kenjiArai 9:e98e94ba17f9 242 PRINTF("1PPS= %9d , %9d (new), ",counter_1pps, fc.read_newest_1pps());
kenjiArai 9:e98e94ba17f9 243 PRINTF("%+6.3f dC, ", tmp);
kenjiArai 9:e98e94ba17f9 244 PRINTF("PID= %+6.3f , ", volt);
kenjiArai 9:e98e94ba17f9 245 // PRINTF("t= %5d S, ", n++);
kenjiArai 9:e98e94ba17f9 246 seconds = time(NULL);
kenjiArai 9:e98e94ba17f9 247 seconds_jst = seconds + 32400; // +9 hours ->JST
kenjiArai 9:e98e94ba17f9 248 // December 31,'14, 13:12:11
kenjiArai 9:e98e94ba17f9 249 // strftime(buf, 40, "%B %d,'%y, %H:%M:%S", localtime(&seconds));
kenjiArai 9:e98e94ba17f9 250 // 31 Dec 2014 13:12:11
kenjiArai 9:e98e94ba17f9 251 // strftime(buf,40, "%x %X ", localtime(&seconds));
kenjiArai 9:e98e94ba17f9 252 // 1:12:11 PM (2014/12/31)
kenjiArai 9:e98e94ba17f9 253 strftime(buf,40, "%I:%M:%S %p (%Y/%m/%d)", localtime(&seconds_jst));
kenjiArai 9:e98e94ba17f9 254 PRINTF("%s, ", buf);
kenjiArai 9:e98e94ba17f9 255 if (fc.status_gps()) {
kenjiArai 9:e98e94ba17f9 256 PRINTF("RDY");
kenjiArai 9:e98e94ba17f9 257 } else {
kenjiArai 9:e98e94ba17f9 258 PRINTF("NO ");
kenjiArai 9:e98e94ba17f9 259 }
kenjiArai 9:e98e94ba17f9 260 PRINTF("\r\n");
kenjiArai 9:e98e94ba17f9 261 lcd.locate(0, 0);
kenjiArai 9:e98e94ba17f9 262 lcd.printf("Freq= %11.2f Hz", new_frequency);
kenjiArai 9:e98e94ba17f9 263 lcd.locate(0, 1);
kenjiArai 9:e98e94ba17f9 264 lcd.printf("1PPS=%9d Hz", counter_1pps);
kenjiArai 9:e98e94ba17f9 265 lcd.locate(0, 2);
kenjiArai 9:e98e94ba17f9 266 strftime(buf,40, " %I:%M:%S %p (%m/%d)", localtime(&seconds_jst));
kenjiArai 9:e98e94ba17f9 267 lcd.printf("%s, ", buf);
kenjiArai 9:e98e94ba17f9 268 lcd.locate(0, 3);
kenjiArai 9:e98e94ba17f9 269 lcd.printf("t= %+4.1f%cC", tmp, 0xdf);
kenjiArai 9:e98e94ba17f9 270 if (fc.status_gps()) {
kenjiArai 9:e98e94ba17f9 271 lcd.printf(" GPS RDY");
kenjiArai 9:e98e94ba17f9 272 } else {
kenjiArai 9:e98e94ba17f9 273 lcd.printf(" NO GPS ");
kenjiArai 5:af9fa3d0731c 274 }
kenjiArai 9:e98e94ba17f9 275 base_clock_1pps = (double)counter_1pps / 1000000;
kenjiArai 9:e98e94ba17f9 276 double diff = base_clock_1pps - CLOCK_BASE;
kenjiArai 9:e98e94ba17f9 277 if (diff < 0) {
kenjiArai 9:e98e94ba17f9 278 diff *= -1;
kenjiArai 9:e98e94ba17f9 279 }
kenjiArai 9:e98e94ba17f9 280 if (diff < 0.00001) { // less than 10Hz
kenjiArai 9:e98e94ba17f9 281 fc.set_external_clock(base_clock_1pps);
kenjiArai 5:af9fa3d0731c 282 }
kenjiArai 9:e98e94ba17f9 283 /* Wait until it is time to check again. */
kenjiArai 9:e98e94ba17f9 284 Thread::wait(100);
kenjiArai 9:e98e94ba17f9 285 }
kenjiArai 9:e98e94ba17f9 286 }
kenjiArai 9:e98e94ba17f9 287
kenjiArai 9:e98e94ba17f9 288 // Thread definition
kenjiArai 9:e98e94ba17f9 289 osThreadDef(measure_freq, osPriorityNormal,1024);
kenjiArai 9:e98e94ba17f9 290 osThreadDef(temp_control, osPriorityNormal,1024);
kenjiArai 9:e98e94ba17f9 291 osThreadDef(display_data, osPriorityNormal,3072);
kenjiArai 9:e98e94ba17f9 292 osThreadDef(gps_data_rcv, osPriorityNormal,3072);
kenjiArai 9:e98e94ba17f9 293
kenjiArai 9:e98e94ba17f9 294 int main()
kenjiArai 9:e98e94ba17f9 295 {
kenjiArai 9:e98e94ba17f9 296 // PA8 & PC9 uses for MCO_1 & MCO_2 -> Clock output for checking
kenjiArai 9:e98e94ba17f9 297 fc.port_mco1_mco2_set(4); // Clk/4 ->1/1(100MHz) cannot measure!!
kenjiArai 9:e98e94ba17f9 298 osThreadCreate(osThread(measure_freq), NULL);
kenjiArai 9:e98e94ba17f9 299 Thread::wait(5); //wait
kenjiArai 9:e98e94ba17f9 300 osThreadCreate(osThread(temp_control), NULL);
kenjiArai 9:e98e94ba17f9 301 Thread::wait(8); //wait
kenjiArai 9:e98e94ba17f9 302 osThreadCreate(osThread(display_data), NULL);
kenjiArai 9:e98e94ba17f9 303 Thread::wait(10); //wait
kenjiArai 9:e98e94ba17f9 304 if (CheckRTC() == OK) { // If RTC is NG, no need to start GPS RX function
kenjiArai 9:e98e94ba17f9 305 DEBUG("\r\nGPS task starts\r\n");
kenjiArai 9:e98e94ba17f9 306 osThreadCreate(osThread(gps_data_rcv), NULL);
kenjiArai 9:e98e94ba17f9 307 }
kenjiArai 9:e98e94ba17f9 308 while(true) {
kenjiArai 9:e98e94ba17f9 309 /* Wait until it is time to check again. */
kenjiArai 9:e98e94ba17f9 310 Thread::wait(5000);
mio 1:2a347c40b1da 311 }
mio 1:2a347c40b1da 312 }
kenjiArai 9:e98e94ba17f9 313
kenjiArai 9:e98e94ba17f9 314 ///////////////////////////////////////////////////////////////////////////////
kenjiArai 9:e98e94ba17f9 315 // GPS data Analysis
kenjiArai 9:e98e94ba17f9 316 //
kenjiArai 9:e98e94ba17f9 317 // PA6C GPS Module
kenjiArai 9:e98e94ba17f9 318 // http://www.gtop-tech.com/en/product/MT3339_GPS_Module_03.html
kenjiArai 9:e98e94ba17f9 319 // Update time: 1 second (1PPS: ±10ns RMS)
kenjiArai 9:e98e94ba17f9 320 // MediaTek MT3339 Chipset, L1 Frequency, C/A code, 66 Channels
kenjiArai 9:e98e94ba17f9 321 // NMEA 0183
kenjiArai 9:e98e94ba17f9 322 //
kenjiArai 9:e98e94ba17f9 323 // current setting: GGA, VTG, GGA, RMC
kenjiArai 9:e98e94ba17f9 324 //
kenjiArai 9:e98e94ba17f9 325 ///////////////////////////////////////////////////////////////////////////////
kenjiArai 9:e98e94ba17f9 326 // Get line of data from GPS
kenjiArai 9:e98e94ba17f9 327 void getline_gps(void)
kenjiArai 9:e98e94ba17f9 328 {
kenjiArai 9:e98e94ba17f9 329 while (gps.getc() != '$') {
kenjiArai 9:e98e94ba17f9 330 //DEBUG("GETC but not $\r\n");
kenjiArai 9:e98e94ba17f9 331 Thread::yield();
kenjiArai 9:e98e94ba17f9 332 }
kenjiArai 9:e98e94ba17f9 333 GPS_Buffer[0] = '$';
kenjiArai 9:e98e94ba17f9 334 for (int8_t i = 1; i < GSP_BUF_B; i++) {
kenjiArai 9:e98e94ba17f9 335 GPS_Buffer[i] = gps.getc();
kenjiArai 9:e98e94ba17f9 336 if (GPS_Buffer[i] == '\r' || GPS_Buffer[i] == '\n') {
kenjiArai 9:e98e94ba17f9 337 GPS_Buffer[i] = '\r';
kenjiArai 9:e98e94ba17f9 338 GPS_Buffer[i+1] = '\n';
kenjiArai 9:e98e94ba17f9 339 GPS_Buffer[i+2] = 0;
kenjiArai 9:e98e94ba17f9 340 GPS_Buffer[i+3] = 0;
kenjiArai 9:e98e94ba17f9 341 //DEBUG("Get one GPS data\r\n");
kenjiArai 9:e98e94ba17f9 342 return;
kenjiArai 9:e98e94ba17f9 343 }
kenjiArai 9:e98e94ba17f9 344 }
kenjiArai 9:e98e94ba17f9 345 }
kenjiArai 9:e98e94ba17f9 346
kenjiArai 9:e98e94ba17f9 347 // ASCII to hex
kenjiArai 9:e98e94ba17f9 348 uint8_t hex(char c)
kenjiArai 9:e98e94ba17f9 349 {
kenjiArai 9:e98e94ba17f9 350 if(c<= '/') return( ERR );
kenjiArai 9:e98e94ba17f9 351 if(((c -= '0')<= 9 || 10 <= ( c -= 'A' - '0' - 10)) && c <= 15) {
kenjiArai 9:e98e94ba17f9 352 return((uint8_t)c);
kenjiArai 9:e98e94ba17f9 353 }
kenjiArai 9:e98e94ba17f9 354 return(ERR);
kenjiArai 9:e98e94ba17f9 355 }
kenjiArai 9:e98e94ba17f9 356
kenjiArai 9:e98e94ba17f9 357 // Search next ',' (comma)
kenjiArai 9:e98e94ba17f9 358 char *next_comma( char *p )
kenjiArai 9:e98e94ba17f9 359 {
kenjiArai 9:e98e94ba17f9 360 while (1) {
kenjiArai 9:e98e94ba17f9 361 if ( *p== ',' ) {
kenjiArai 9:e98e94ba17f9 362 return ++p;
kenjiArai 9:e98e94ba17f9 363 } else if ( *p == 0 ) {
kenjiArai 9:e98e94ba17f9 364 return (char*)-1;
kenjiArai 9:e98e94ba17f9 365 } else {
kenjiArai 9:e98e94ba17f9 366 p++;
kenjiArai 9:e98e94ba17f9 367 }
kenjiArai 9:e98e94ba17f9 368 }
kenjiArai 9:e98e94ba17f9 369 }
kenjiArai 9:e98e94ba17f9 370
kenjiArai 9:e98e94ba17f9 371 // 2 digits ASCII char to one byte hex
kenjiArai 9:e98e94ba17f9 372 unsigned char change_acii_hex( char*p )
kenjiArai 9:e98e94ba17f9 373 {
kenjiArai 9:e98e94ba17f9 374 unsigned char c;
kenjiArai 9:e98e94ba17f9 375
kenjiArai 9:e98e94ba17f9 376 c = hex(*p++); /* No concern ERR condition! */
kenjiArai 9:e98e94ba17f9 377 c = (c * 10) + hex(*p++);
kenjiArai 9:e98e94ba17f9 378 return c;
kenjiArai 9:e98e94ba17f9 379 }
kenjiArai 9:e98e94ba17f9 380
kenjiArai 9:e98e94ba17f9 381 // Skip number of comma
kenjiArai 9:e98e94ba17f9 382 char *num_of_comma( char *p, int8_t n )
kenjiArai 9:e98e94ba17f9 383 {
kenjiArai 9:e98e94ba17f9 384 for (; n> 0; n--) {
kenjiArai 9:e98e94ba17f9 385 if ( (p = next_comma(p)) == (char*) -1 ) {
kenjiArai 9:e98e94ba17f9 386 return (char*)-1;
kenjiArai 9:e98e94ba17f9 387 }
kenjiArai 9:e98e94ba17f9 388 }
kenjiArai 9:e98e94ba17f9 389 return p;
kenjiArai 9:e98e94ba17f9 390 }
kenjiArai 9:e98e94ba17f9 391
kenjiArai 9:e98e94ba17f9 392 // Get GPS status and number of satelites
kenjiArai 9:e98e94ba17f9 393 uint32_t check_gps_ready(void)
kenjiArai 9:e98e94ba17f9 394 {
kenjiArai 9:e98e94ba17f9 395 char *p;
kenjiArai 9:e98e94ba17f9 396 uint32_t x;
kenjiArai 9:e98e94ba17f9 397 uint8_t d;
kenjiArai 9:e98e94ba17f9 398
kenjiArai 9:e98e94ba17f9 399 // pick-up time
kenjiArai 9:e98e94ba17f9 400 p = MsgBuf_GGA;
kenjiArai 9:e98e94ba17f9 401 p = num_of_comma(p,6); // skip ','
kenjiArai 9:e98e94ba17f9 402 // reach to "Position Fix Indicator"
kenjiArai 9:e98e94ba17f9 403 if (*p == '0') {
kenjiArai 9:e98e94ba17f9 404 x = 0;
kenjiArai 9:e98e94ba17f9 405 } else if (*p == '1') {
kenjiArai 9:e98e94ba17f9 406 x = 0x10;
kenjiArai 9:e98e94ba17f9 407 } else if (*p == '2') {
kenjiArai 9:e98e94ba17f9 408 x = 0x20;
kenjiArai 9:e98e94ba17f9 409 } else {
kenjiArai 9:e98e94ba17f9 410 x= 0;
kenjiArai 9:e98e94ba17f9 411 }
kenjiArai 9:e98e94ba17f9 412 ++p;
kenjiArai 9:e98e94ba17f9 413 if (*p == ',') {
kenjiArai 9:e98e94ba17f9 414 ++p;
kenjiArai 9:e98e94ba17f9 415 d = hex(*p++);
kenjiArai 9:e98e94ba17f9 416 if (d != ERR) {
kenjiArai 9:e98e94ba17f9 417 x += (uint32_t)d;
kenjiArai 9:e98e94ba17f9 418 if (*p != ',') {
kenjiArai 9:e98e94ba17f9 419 x = 0;
kenjiArai 9:e98e94ba17f9 420 }
kenjiArai 9:e98e94ba17f9 421 } else {
kenjiArai 9:e98e94ba17f9 422 x = 0;
kenjiArai 9:e98e94ba17f9 423 }
kenjiArai 9:e98e94ba17f9 424 } else {
kenjiArai 9:e98e94ba17f9 425 x = 0;
kenjiArai 9:e98e94ba17f9 426 }
kenjiArai 9:e98e94ba17f9 427 return x;
kenjiArai 9:e98e94ba17f9 428 }
kenjiArai 9:e98e94ba17f9 429
kenjiArai 9:e98e94ba17f9 430 // Get time(UTC) from GPS data
kenjiArai 9:e98e94ba17f9 431 void get_time_and_date(struct tm *pt)
kenjiArai 9:e98e94ba17f9 432 {
kenjiArai 9:e98e94ba17f9 433 char *p;
kenjiArai 9:e98e94ba17f9 434
kenjiArai 9:e98e94ba17f9 435 p = MsgBuf_RMC;
kenjiArai 9:e98e94ba17f9 436 p = num_of_comma(p,1); /* skip one ',' */
kenjiArai 9:e98e94ba17f9 437 pt->tm_hour = change_acii_hex(p);
kenjiArai 9:e98e94ba17f9 438 p += 2;
kenjiArai 9:e98e94ba17f9 439 pt->tm_min = change_acii_hex(p);
kenjiArai 9:e98e94ba17f9 440 p += 2;
kenjiArai 9:e98e94ba17f9 441 pt->tm_sec = change_acii_hex(p);
kenjiArai 9:e98e94ba17f9 442 p = MsgBuf_RMC;
kenjiArai 9:e98e94ba17f9 443 p = num_of_comma(p,9); /* skip one ',' */
kenjiArai 9:e98e94ba17f9 444 pt->tm_mday = change_acii_hex(p);
kenjiArai 9:e98e94ba17f9 445 p += 2;
kenjiArai 9:e98e94ba17f9 446 pt->tm_mon = change_acii_hex(p) - 1;
kenjiArai 9:e98e94ba17f9 447 p += 2;
kenjiArai 9:e98e94ba17f9 448 pt->tm_year = change_acii_hex(p) + 100;
kenjiArai 9:e98e94ba17f9 449 }