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:
Fri Jan 02 10:57:25 2015 +0000
Revision:
12:05098414599b
Parent:
11:20e7a45f1448
Back to original PID

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