Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: Custom_LSM303 Custom_UBloxGPS LRAT-mbed-os USBDevice mbed-lora-radio-drv stm32EEPROM
Fork of LRAT-example-lorawan by
main.cpp
- Committer:
- lpeters
- Date:
- 2018-08-27
- Revision:
- 35:73b3963c6dd3
- Parent:
- 34:341fb423e74b
- Child:
- 36:dcc6f89fa39a
File content as of revision 35:73b3963c6dd3:
/** * Copyright (c) 2017, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ //#define TARGET_LRAT 1 #define TARGET_DISCO1 1 //#define TARGET_DISCO2 1 //#define SENSOR_TEMP 1 #include <stdio.h> #include "mbed.h" #include "lorawan/LoRaWANInterface.h" #include "lorawan/system/lorawan_data_structures.h" #include "events/EventQueue.h" // Application helpers #include "DummySensor.h" #include "trace_helper.h" #include "lora_radio_helper.h" #include "mbed-trace/mbed_trace.h" #define TRACE_GROUP "MAIN" using namespace events; // Max payload size can be LORAMAC_PHY_MAXPAYLOAD. // This example only communicates with much shorter messages (<30 bytes). // If longer messages are used, these buffers must be changed accordingly. uint8_t tx_buffer[30]; uint8_t rx_buffer[30]; /* * Sets up an application dependent transmission timer in ms. Used only when Duty Cycling is off for testing */ #define TX_TIMER 10000 /** * Maximum number of events for the event queue. * 10 is the safe number for the stack events, however, if application * also uses the queue for whatever purposes, this number should be increased. */ #define MAX_NUMBER_OF_EVENTS 10 /** * Maximum number of retries for CONFIRMED messages before giving up */ #define CONFIRMED_MSG_RETRY_COUNTER 15 /** * Dummy pin for dummy sensor */ #define PC_9 0 /** * Dummy sensor class object */ DS1820 ds1820(PC_9); /** * This event queue is the global event queue for both the * application and stack. To conserve memory, the stack is designed to run * in the same thread as the application and the application is responsible for * providing an event queue to the stack that will be used for ISR deferment as * well as application information event queuing. */ static EventQueue ev_queue(MAX_NUMBER_OF_EVENTS * EVENTS_EVENT_SIZE); /** * Event handler. * * This will be passed to the LoRaWAN stack to queue events for the * application which in turn drive the application. */ static void lora_event_handler(lorawan_event_t event); /** * Constructing Mbed LoRaWANInterface and passing it down the radio object. */ static LoRaWANInterface lorawan(radio); /** * Application specific callbacks */ static lorawan_app_callbacks_t callbacks; /* #if defined(TARGET_LRAT) or defined(TARGET_DISCO2) #include "USBSerial.h" USBSerial serial; FileHandle* mbed::mbed_override_console(int) { return &serial; } #endif */ uint32_t mytime = 0; uint8_t mybatt = 0; double mylat = 0; double mylon = 0; int16_t myAccX = 0; int16_t myAccY = 0; int16_t myAccZ = 0; int16_t myMagX = 0; int16_t myMagY = 0; int16_t myMagZ = 0; int16_t myOffX = 0; int16_t myOffY = 0; int16_t myOffZ = 0; int16_t myTemp = 0; int16_t accMinX = 0; int16_t accMinY = 0; int16_t accMinZ = 0; int16_t accMaxX = 0; int16_t accMaxY = 0; int16_t accMaxZ = 0; int16_t magMinX = 0; int16_t magMinY = 0; int16_t magMinZ = 0; int16_t magMaxX = 0; int16_t magMaxY = 0; int16_t magMaxZ = 0; #define NEOM8M_ADR_GPS 0x84 //#define LSM303_ADR_ACC 0x32 #define LSM303_ADR_MAG 0x3C #define NEOM8M_REG_GPS_LENH 0xFD #define NEOM8M_REG_GPS_LENL 0xFE #define NEOM8M_REG_GPS_DATA 0xFE #define LSM303_REG_ACC_STATUS_REG_AUX_A 0x07 //#define LSM303_REG_ACC_OUT_TEMP_L_A 0x0C //#define LSM303_REG_ACC_OUT_TEMP_H_A 0x0D #define LSM303_REG_ACC_WHO_AM_I_A 0x0F //#define LSM303_REG_ACC_TEMP_CFG_REG_A 0x1F #define LSM303_REG_ACC_CTRL_REG1_A 0x20 #define LSM303_REG_ACC_CTRL_REG2_A 0x21 #define LSM303_REG_ACC_CTRL_REG3_A 0x22 #define LSM303_REG_ACC_CTRL_REG4_A 0x23 #define LSM303_REG_ACC_CTRL_REG5_A 0x24 #define LSM303_REG_ACC_CTRL_REG6_A 0x25 #define LSM303_REG_ACC_STATUS_REG_A 0x27 #define LSM303_REG_ACC_OUT_X_L_A 0x28 #define LSM303_REG_ACC_OUT_X_H_A 0x29 #define LSM303_REG_ACC_OUT_Y_L_A 0x2A #define LSM303_REG_ACC_OUT_Y_H_A 0x2B #define LSM303_REG_ACC_OUT_Z_L_A 0x2C #define LSM303_REG_ACC_OUT_Z_H_A 0x2D #define LSM303_REG_ACC_INT1_CFG_A 0x30 #define LSM303_REG_ACC_INT1_SRC_A 0x31 #define LSM303_REG_ACC_INT1_THS_A 0x32 #define LSM303_REG_ACC_INT1_DURATION_A 0x33 #define LSM303_REG_MAG_OFFSET_X_REG_L_M 0x45 #define LSM303_REG_MAG_OFFSET_X_REG_H_M 0x46 #define LSM303_REG_MAG_OFFSET_Y_REG_L_M 0x47 #define LSM303_REG_MAG_OFFSET_Y_REG_H_M 0x48 #define LSM303_REG_MAG_OFFSET_Z_REG_L_M 0x49 #define LSM303_REG_MAG_OFFSET_Z_REG_H_M 0x4A //#define LSM303_REG_MAG_WHO_AM_I_M 0x4F //#define LSM303_REG_MAG_CFG_REG_A_M 0x60 //#define LSM303_REG_MAG_CFG_REG_B_M 0x61 //#define LSM303_REG_MAG_CFG_REG_C_M 0x62 #define LSM303_REG_MAG_INT_CTRL_REG_M 0x63 #define LSM303_REG_MAG_INT_SOURCE_REG_M 0x64 #define LSM303_REG_MAG_INT_THS_L_REG_M 0x65 #define LSM303_REG_MAG_INT_THS_H_REG_M 0x66 //#define LSM303_REG_MAG_STATUS_REG_M 0x67 //#define LSM303_REG_MAG_OUTX_L_REG_M 0x68 //#define LSM303_REG_MAG_OUTX_H_REG_M 0x69 //#define LSM303_REG_MAG_OUTY_L_REG_M 0x6A //#define LSM303_REG_MAG_OUTY_H_REG_M 0x6B //#define LSM303_REG_MAG_OUTZ_L_REG_M 0x6C //#define LSM303_REG_MAG_OUTZ_H_REG_M 0x6D #define EEPROM_MAX 0x17FF #if defined(TARGET_LRAT) #define LEDR PB_6 #define LEDG PB_7 #define LEDB PB_5 #define LEDW PB_2 #define PIN_ACC PB_14 #define PIN_MAG PB_12 #define PIN_BTN PA_5 #define PIN_ALT PA_4 #define LSM303_ADR_ACC 0x3A #define LSM303_REG_MAG_WHO_AM_I_M 0x0F #define LSM303_WHO_ACC 0x41 #define LSM303_WHO_MAG 0x3D #define LSM303_CTRL_REG7_A 0x26 #define LSM303_REG_MAG_CTRL_REG1_M 0x20 #define LSM303_REG_MAG_CTRL_REG2_M 0x21 #define LSM303_REG_MAG_CTRL_REG3_M 0x22 #define LSM303_REG_MAG_CTRL_REG4_M 0x23 #define LSM303_REG_MAG_CTRL_REG5_M 0x24 #define LSM303_REG_MAG_STATUS_REG_M 0x27 #define LSM303_REG_MAG_OUTX_L_REG_M 0x28 #define LSM303_REG_MAG_OUTX_H_REG_M 0x29 #define LSM303_REG_MAG_OUTY_L_REG_M 0x2A #define LSM303_REG_MAG_OUTY_H_REG_M 0x2B #define LSM303_REG_MAG_OUTZ_L_REG_M 0x2C #define LSM303_REG_MAG_OUTZ_H_REG_M 0x2D #define LSM303_REG_MAG_TEMP_L_M 0x2E #define LSM303_REG_MAG_TEMP_H_M 0x2F #define LSM303_REG_MAG_TEMP_CFG_REG_A 0x1F #define CFG_ACC_ADR LSM303_REG_ACC_CTRL_REG1_A #define CFG_ACC_LEN 7 #define CFG_MAG_ADR LSM303_REG_MAG_CTRL_REG1_M #define CFG_MAG_LEN 5 #else #define LEDR PB_7 #define LEDG PB_5 #define LEDB PB_6 #define LEDW PA_5 #define PIN_ACC PB_14 // Not really. #if defined(TARGET_DISCO2) #define PIN_MAG PB_13 #else #define PIN_MAG PA_10 #endif #define PIN_BTN PB_2 #define LSM303_ADR_ACC 0x32 #define LSM303_REG_MAG_WHO_AM_I_M 0x4F #define LSM303_WHO_ACC 0x33 #define LSM303_WHO_MAG 0x40 #define LSM303_REG_ACC_OUT_TEMP_L_A 0x0C #define LSM303_REG_ACC_OUT_TEMP_H_A 0x0D #define LSM303_REG_ACC_TEMP_CFG_REG_A 0x1F #define LSM303_REG_MAG_CFG_REG_A_M 0x60 #define LSM303_REG_MAG_CFG_REG_B_M 0x61 #define LSM303_REG_MAG_CFG_REG_C_M 0x62 #define LSM303_REG_MAG_STATUS_REG_M 0x67 #define LSM303_REG_MAG_OUTX_L_REG_M 0x68 #define LSM303_REG_MAG_OUTX_H_REG_M 0x69 #define LSM303_REG_MAG_OUTY_L_REG_M 0x6A #define LSM303_REG_MAG_OUTY_H_REG_M 0x6B #define LSM303_REG_MAG_OUTZ_L_REG_M 0x6C #define LSM303_REG_MAG_OUTZ_H_REG_M 0x6D #define CFG_ACC_ADR LSM303_REG_ACC_TEMP_CFG_REG_A // Start Disco at TEMP CFG. #define CFG_ACC_LEN 7 #define CFG_MAG_ADR LSM303_REG_MAG_CFG_REG_A_M #define CFG_MAG_LEN 3 #endif I2C i2c(PB_9, PB_8); InterruptIn accPin(PIN_ACC); InterruptIn magPin(PIN_MAG); InterruptIn btnPin(PIN_BTN); uint8_t cfg; char ret; char rda = '\0'; char cmd[2]; char buf[83]; uint8_t pos = 0; int accShift = 0; int accScale = 0; int accEvent = 0; uint8_t accSFire = 0; uint8_t accHFire = 0; uint8_t accSLIRQ = 0; uint8_t accSHIRQ = 0; int magEvent = 0; uint8_t magSFire = 0; uint8_t magHFire = 0; uint8_t magSLIRQ = 0; uint8_t magSHIRQ = 0; uint8_t btnHFire = 0; char *res; char sPass[26] = "[\u001b[32mPASS\u001b[0m]"; char sFail[26] = "[\u001b[31mFAIL\u001b[0m]"; char cmdSendLoop[9] = "SendLoop"; time_t tInit = 0; time_t tBump = 0; time_t tLast = 0; time_t tNext = 0; DigitalOut myLedR(LEDR); DigitalOut myLedG(LEDG); DigitalOut myLedB(LEDB); DigitalOut myLedW(LEDW); void magInitSequence(); void accInitSequence(); void gpsInitSequence(); void tmpRead(); void magRead(); void accRead(); void gpsRead(); void onBtnIrq() { btnHFire++; // tBump = time(NULL); // tNext = tBump; tNext = 0; } void onAccIrq() { accHFire++; // tBump = time(NULL); // tNext = tBump; tNext = 0; } void onMagIrq() { magHFire++; // tBump = time(NULL); // tNext = tBump; tNext = 0; } void accDumpCfg() { char start = CFG_ACC_ADR; for (int i = 0; i < CFG_ACC_LEN; i++) { cmd[0] = start + i; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &buf[i], 1); } printf("CFGACC: | "); for (int i = 0; i < CFG_ACC_LEN; i++) { printf("%02X ", buf[i]); } printf("|\r\n"); } void magDumpCfg() { char start = CFG_MAG_ADR; for (int i = 0; i < CFG_MAG_LEN; i++) { cmd[0] = start + i; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &buf[i], 1); } printf("CFGMAG: | "); for (int i = 0; i < CFG_MAG_LEN; i++) { printf("%02X ", buf[i]); } printf("|\r\n"); } /** * Entry point for application */ int main (void) { //i2c.frequency(400000); wait(4); printf("\r\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\r\n"); // Boot Flash for (int i = 0; i <= 64; i++) { myLedR = i & 0x01; myLedG = i & 0x02; myLedB = i & 0x04; myLedW = i & 0x08; wait(0.01); } wait(4); // btnPin.rise(&onBtnIrq); // setup tracing setup_trace(); // stores the status of a call to LoRaWAN protocol lorawan_status_t retcode; /* I2C init */ ret = 0x00; magDumpCfg(); accDumpCfg(); magInitSequence(); accInitSequence(); gpsInitSequence(); magDumpCfg(); accDumpCfg(); cfg = 0x00; #if defined(TARGET_LRAT) cmd[0] = LSM303_REG_ACC_CTRL_REG1_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &ret, 1); cfg |= (ret & 0x80) >> 7; cmd[0] = LSM303_REG_ACC_CTRL_REG4_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &ret, 1); accScale = 1 << (!(ret & 0x30) ? 0 : ((ret & 0x30) >> 4) - 1); cmd[0] = LSM303_REG_MAG_CTRL_REG2_M; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &ret, 1); cfg |= (ret & 0x60) >> 1; //accShift = 0; // Full 16-bit resolution accShift = 4; #else cmd[0] = LSM303_REG_ACC_CTRL_REG1_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &ret, 1); cfg |= (ret & 0x08) >> 3; cmd[0] = LSM303_REG_ACC_CTRL_REG4_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &ret, 1); cfg |= (ret & 0x08) >> 2; accScale = 1 << ((ret & 0x30) >> 4); cmd[0] = LSM303_REG_MAG_CFG_REG_A_M; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &ret, 1); cfg |= (ret & 0x10); if (cfg & 0x01) accShift = 8; else if (cfg & 0x02) accShift = 4; else accShift = 6; #endif printf("Quality: %02x AccShift: %d AccScale: %d\r\n", cfg, accShift, accScale); time_t tNow; /* // while(1) // { tNow = time(NULL); printf("RTC: %08X\r\n", tNow); #if defined(SENSOR_TEMP) tmpRead(); #endif magRead(); accRead(); gpsRead(); printf("TIM: %d, SAT: %d, LAT: %f, LON: %f\r\n", mytime, mybatt, mylat, mylon); printf("IRQ: A=%02X M=%02X B=%02X\r\n", accHFire, magHFire, btnHFire); wait(1); // } */ printf("CONTROL LOOP GOES HERE!\r\n"); #if defined(TARGET_LRAT) #else for (int i = 0; i < 6; i++) { tNow = time(NULL); printf("RTC: %08X\r\n", tNow); tNext = tNow + 10; printf("NXT: %08X\r\n", tNext); // Clear any pending IRQs cmd[0] = LSM303_REG_MAG_INT_SOURCE_REG_M; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &ret, 1); while (time(NULL) < tNext) { wait(1); } printf("Timer #%d complete.\r\n", i); } #endif for (int i = 0; i <= 64; i++) { myLedR = i & 0x01; myLedG = i & 0x02; myLedB = i & 0x04; myLedW = i & 0x08; wait(0.01); } // Initialize LoRaWAN stack if (lorawan.initialize(&ev_queue) != LORAWAN_STATUS_OK) { printf("\r\n LoRa initialization failed! \r\n"); return -1; } printf("\r\n Mbed LoRaWANStack initialized \r\n"); printf("MBED_CONF_LORA_APP_PORT: %d", MBED_CONF_LORA_APP_PORT); printf("MBED_CONF_LORA_DUTY_CYCLE_ON: %d", MBED_CONF_LORA_DUTY_CYCLE_ON); // prepare application callbacks callbacks.events = mbed::callback(lora_event_handler); lorawan.add_app_callbacks(&callbacks); // Set number of retries in case of CONFIRMED messages if (lorawan.set_confirmed_msg_retries(CONFIRMED_MSG_RETRY_COUNTER) != LORAWAN_STATUS_OK) { printf("\r\n set_confirmed_msg_retries failed! \r\n\r\n"); return -1; } printf("\r\n CONFIRMED message retries : %d \r\n", CONFIRMED_MSG_RETRY_COUNTER); // Enable adaptive data rate if (lorawan.enable_adaptive_datarate() != LORAWAN_STATUS_OK) { printf("\r\n enable_adaptive_datarate failed! \r\n"); return -1; } printf("\r\n Adaptive data rate (ADR) - Enabled \r\n"); retcode = lorawan.connect(); if (retcode == LORAWAN_STATUS_OK || retcode == LORAWAN_STATUS_CONNECT_IN_PROGRESS) { } else { printf("\r\n Connection error, code = %d \r\n", retcode); return -1; } printf("\r\n Connection - In Progress ...\r\n"); // make your event queue dispatching events forever ev_queue.dispatch_forever(); return 0; } /** * Sends a message to the Network Server */ static void send_message() { uint16_t packet_len; int16_t retcode; float sensor_value; if (ds1820.begin()) { ds1820.startConversion(); sensor_value = ds1820.read(); printf("\r\n Dummy Sensor Value = %3.1f \r\n", sensor_value); ds1820.startConversion(); } else { printf("\r\n No sensor found \r\n"); return; } time_t tNow = time(NULL); printf("Clock: %d\r\n", tNow); #if defined(SENSOR_TEMP) tmpRead(); #endif magRead(); accRead(); gpsRead(); int ilat = (int)(mylat * 100000); int ilon = (int)(mylon * 100000); printf("TIM: %d, SAT: %d, LAT: %d, LON: %d\r\n", mytime, mybatt, ilat, ilon); packet_len = 11; tx_buffer[0] = (mytime >> 24) & 0xFF; tx_buffer[1] = (mytime >> 16) & 0xFF; tx_buffer[2] = (mytime >> 8) & 0xFF; tx_buffer[3] = (mytime >> 0) & 0xFF; tx_buffer[4] = ((mybatt << 4) & 0xF0) | ((ilat >> 22) & 0x0F); tx_buffer[5] = (ilat >> 14) & 0xFF; tx_buffer[6] = (ilat >> 6) & 0xFF; tx_buffer[7] = ((ilat << 2) & 0xFC) | ((ilon >> 24) & 0x03); tx_buffer[8] = (ilon >> 16) & 0xFF; tx_buffer[9] = (ilon >> 8) & 0xFF; tx_buffer[10] = (ilon >> 0) & 0xFF; printf("\r\nBUF: |"); for (int i = 0; i < packet_len; i++) { printf("%02X", tx_buffer[i]); } printf("|\r\n"); retcode = lorawan.send(MBED_CONF_LORA_APP_PORT, tx_buffer, packet_len, MSG_CONFIRMED_FLAG); if (retcode < 0) { retcode == LORAWAN_STATUS_WOULD_BLOCK ? printf("send - WOULD BLOCK\r\n") : printf("\r\n send() - Error code %d \r\n", retcode); if (retcode == LORAWAN_STATUS_WOULD_BLOCK) { //retry in 3 seconds if (MBED_CONF_LORA_DUTY_CYCLE_ON) { ev_queue.call_in(3000, send_message); } } return; } printf("\r\n %d bytes scheduled for transmission \r\n", retcode); memset(tx_buffer, 0, sizeof(tx_buffer)); //LED Confirmation Output - MESSAGE SENT for (int i = 0; i < 10; i++) { myLedG = 1; wait(0.1); myLedG = 0; myLedR = 1; wait(0.1); myLedR = 0; myLedB = 1; wait(0.1); myLedB = 0; } } /** * Receive a message from the Network Server */ static void receive_message() { int16_t retcode; retcode = lorawan.receive(MBED_CONF_LORA_APP_PORT, rx_buffer, sizeof(rx_buffer), MSG_CONFIRMED_FLAG|MSG_UNCONFIRMED_FLAG); if (retcode < 0) { printf("\r\n receive() - Error code %d \r\n", retcode); return; } printf(" Data:"); for (uint8_t i = 0; i < retcode; i++) { printf("%x", rx_buffer[i]); } printf("\r\n Data Length: %d\r\n", retcode); /* int startLoop = 0; if (strncmp((char *)rx_buffer, cmdSendLoop, 8) == 0) { printf("SendLoop Command Received!\r\n"); startLoop = 1; } */ memset(rx_buffer, 0, sizeof(rx_buffer)); /* if (startLoop) send_message(); */ } /** * Event handler */ static void lora_event_handler(lorawan_event_t event) { tr_debug("In lora_event_handler(%d)...", event); switch (event) { case CONNECTED: printf("\r\n Connection - Successful \r\n"); if (MBED_CONF_LORA_DUTY_CYCLE_ON) { send_message(); } else { ev_queue.call_every(TX_TIMER, send_message); } break; case DISCONNECTED: ev_queue.break_dispatch(); printf("\r\n Disconnected Successfully \r\n"); break; case TX_DONE: printf("\r\n Message Sent to Network Server \r\n"); if (MBED_CONF_LORA_DUTY_CYCLE_ON) { send_message(); } break; case TX_TIMEOUT: case TX_ERROR: case TX_CRYPTO_ERROR: case TX_SCHEDULING_ERROR: printf("\r\n Transmission Error - EventCode = %d \r\n", event); // try again if (MBED_CONF_LORA_DUTY_CYCLE_ON) { send_message(); } break; case RX_DONE: printf("\r\n Received message from Network Server \r\n"); receive_message(); break; case RX_TIMEOUT: case RX_ERROR: printf("\r\n Error in reception - Code = %d \r\n", event); break; case JOIN_FAILURE: printf("\r\n OTAA Failed - Check Keys \r\n"); break; case UPLINK_REQUIRED: printf("\r\n Uplink required by NS \r\n"); if (MBED_CONF_LORA_DUTY_CYCLE_ON) { send_message(); } break; default: MBED_ASSERT("Unknown Event"); } } void magInitSequence() { printf("In magInitSequence()...\r\n"); myLedR = 0; myLedG = 0; cmd[0] = LSM303_REG_MAG_WHO_AM_I_M; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &ret, 1); res = (ret == LSM303_WHO_MAG ? sPass : sFail); printf("MAG WhoAmI: %02X %s\r\n", ret, res); if (ret == LSM303_WHO_MAG) myLedG = 1; else myLedR = 1; for (int i = 0; i < 2; i++) { myLedB = 1; wait(0.3); myLedB = 0; wait(0.3); } #if defined(TARGET_LRAT) cmd[0] = LSM303_REG_MAG_CTRL_REG1_M; cmd[1] = 0x70; // Ultra-High Performance Mode on XY axes, ODR=10Hz i2c.write(LSM303_ADR_MAG, cmd, 2); cmd[0] = LSM303_REG_MAG_CTRL_REG3_M; cmd[1] = 0x00; // High Resolution? (Full-power), Continuous i2c.write(LSM303_ADR_MAG, cmd, 2); cmd[0] = LSM303_REG_MAG_CTRL_REG4_M; cmd[1] = 0x0C; // Ultra-High Performance Mode on Z axis i2c.write(LSM303_ADR_MAG, cmd, 2); #if defined(SENSOR_TEMP) // Enable Temp Sensor cmd[0] = LSM303_REG_MAG_CTRL_REG1_M; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &ret, 1); cmd[0] = LSM303_REG_MAG_CTRL_REG1_M; cmd[1] = ret | 0x80; i2c.write(LSM303_ADR_MAG, cmd, 2); /* cmd[0] = LSM303_REG_MAG_CTRL_REG5_M; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &ret, 1); cmd[0] = LSM303_REG_MAG_CTRL_REG5_M; cmd[1] = ret | 0x40; i2c.write(LSM303_ADR_MAG, cmd, 2); */ #endif #else cmd[0] = LSM303_REG_MAG_CFG_REG_A_M; cmd[1] = 0x00; // Mag = 10 Hz (high-resolution and continuous mode) i2c.write(LSM303_ADR_MAG, cmd, 2); cmd[0] = LSM303_REG_MAG_CFG_REG_C_M; //cmd[1] = 0x01; // Mag data-ready interrupt enable cmd[1] = 0x40; // Mag enable interrupt on pin i2c.write(LSM303_ADR_MAG, cmd, 2); #endif for (int i = 0; i < 2; i++) { myLedR = 1; myLedG = 1; myLedB = 1; wait(0.5); myLedR = 0; myLedG = 0; myLedB = 0; wait(0.5); } #if defined(TARGET_LRAT) // LRAT MAG IRQ SETUP GOES HERE #else // MAG INTERRUPT SETUP cmd[0] = LSM303_REG_MAG_INT_THS_L_REG_M; cmd[1] = 0xE8; i2c.write(LSM303_ADR_MAG, cmd, 2); cmd[0] = LSM303_REG_MAG_INT_THS_H_REG_M; cmd[1] = 0x03; i2c.write(LSM303_ADR_MAG, cmd, 2); cmd[0] = LSM303_REG_MAG_INT_CTRL_REG_M; cmd[1] = 0xE7; i2c.write(LSM303_ADR_MAG, cmd, 2); magPin.rise(&onMagIrq); #endif } void accInitSequence() { printf("In accInitSequence()...\r\n"); myLedR = 0; myLedG = 0; cmd[0] = LSM303_REG_ACC_WHO_AM_I_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &ret, 1); res = (ret == LSM303_WHO_ACC ? sPass : sFail); printf("ACC WhoAmI: %02X %s\r\n", ret, res); if (ret == LSM303_WHO_ACC) myLedG = 1; else myLedR = 1; for (int i = 0; i < 2; i++) { myLedB = 1; wait(0.3); myLedB = 0; wait(0.3); } #if defined(TARGET_LRAT) cmd[0] = LSM303_REG_ACC_CTRL_REG1_A; cmd[1] = 0xB7; // High Resolution, ODR=100Hz, Enable XYZ Axes i2c.write(LSM303_ADR_ACC, cmd, 2); #else cmd[0] = LSM303_REG_ACC_CTRL_REG1_A; cmd[1] = 0x57; // Enable XYZ Axes, ODR=100Hz i2c.write(LSM303_ADR_ACC, cmd, 2); // Enable High Resolution Mode cmd[0] = LSM303_REG_ACC_CTRL_REG4_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &ret, 1); cmd[0] = LSM303_REG_ACC_CTRL_REG4_A; cmd[1] = ret | 0x08; // High Resolution i2c.write(LSM303_ADR_ACC, cmd, 2); #if defined(SENSOR_TEMP) // Enable Temp Sensor cmd[0] = LSM303_REG_ACC_TEMP_CFG_REG_A; cmd[1] = 0xC0; i2c.write(LSM303_ADR_ACC, cmd, 2); cmd[0] = LSM303_REG_ACC_CTRL_REG4_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &ret, 1); cmd[0] = LSM303_REG_ACC_CTRL_REG4_A; cmd[1] = ret | 0x80; i2c.write(LSM303_ADR_ACC, cmd, 2); #endif #endif //LED Confirmation Output - ACC INIT COMPLETE for (int i = 0; i < 2; i++) { myLedR = 1; myLedG = 1; myLedB = 1; wait(0.5); myLedR = 0; myLedG = 0; myLedB = 0; wait(0.5); } // Set Full Scale to 4g /* cmd[0] = LSM303_REG_ACC_CTRL_REG4_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &ret, 1); cmd[0] = LSM303_REG_ACC_CTRL_REG4_A; //cmd[1] = ret | 0x30; // 16g //cmd[1] = (ret & ~0x10) | 0x20; // 8g cmd[1] = (ret & ~0x20) | 0x10; // 4g //cmd[1] = ret & ~0x30; // 2g i2c.write(LSM303_ADR_ACC, cmd, 2); */ /* // IRQ Init from Datasheet. cmd[0] = LSM303_REG_ACC_CTRL_REG1_A; cmd[1] = 0xA7; i2c.write(LSM303_ADR_ACC, cmd, 2); cmd[0] = LSM303_REG_ACC_CTRL_REG2_A; cmd[1] = 0x00; i2c.write(LSM303_ADR_ACC, cmd, 2); cmd[0] = LSM303_REG_ACC_CTRL_REG3_A; cmd[1] = 0x40; i2c.write(LSM303_ADR_ACC, cmd, 2); cmd[0] = LSM303_REG_ACC_CTRL_REG4_A; cmd[1] = 0x00; //cmd[1] = 0x10; i2c.write(LSM303_ADR_ACC, cmd, 2); cmd[0] = LSM303_REG_ACC_CTRL_REG5_A; cmd[1] = 0x08; i2c.write(LSM303_ADR_ACC, cmd, 2); */ #if defined(TARGET_LRAT) // LRAT ACC IRQ SETUP GOES HERE #else // ACC INTERRUPT SETUP // Enable Interrupt Pin cmd[0] = LSM303_REG_ACC_CTRL_REG3_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &ret, 1); cmd[0] = LSM303_REG_ACC_CTRL_REG3_A; cmd[1] = ret | 0x40; i2c.write(LSM303_ADR_ACC, cmd, 2); // Enable Interrupt Latch cmd[0] = LSM303_REG_ACC_CTRL_REG5_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &ret, 1); cmd[0] = LSM303_REG_ACC_CTRL_REG5_A; cmd[1] = ret | 0x08; i2c.write(LSM303_ADR_ACC, cmd, 2); // Set Threshold/Duration/Config cmd[0] = LSM303_REG_ACC_INT1_THS_A; //cmd[1] = 0x10; //cmd[1] = 0x40; //cmd[1] = 0x60; cmd[1] = 0x7D; i2c.write(LSM303_ADR_ACC, cmd, 2); cmd[0] = LSM303_REG_ACC_INT1_DURATION_A; cmd[1] = 0x00; i2c.write(LSM303_ADR_ACC, cmd, 2); cmd[0] = LSM303_REG_ACC_INT1_CFG_A; cmd[1] = 0x2A; //cmd[1] = 0x0A; i2c.write(LSM303_ADR_ACC, cmd, 2); accPin.rise(&onAccIrq); #endif } void gpsInitSequence() { printf("In gpsInitSequence()...\r\n"); gpsRead(); if (mytime > 0) { set_time(mytime); tInit = mytime; myLedG = 1; } else myLedR = 1; for (int i = 0; i < 2; i++) { myLedB = 1; wait(0.3); myLedB = 0; wait(0.3); } myLedG = 0; myLedR = 0; } void magRead() { cmd[0] = LSM303_REG_MAG_STATUS_REG_M; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &rda, 1); if (rda) { cmd[0] = LSM303_REG_MAG_OUTX_L_REG_M; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &buf[0], 1); cmd[0] = LSM303_REG_MAG_OUTX_H_REG_M; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &buf[1], 1); cmd[0] = LSM303_REG_MAG_OUTY_L_REG_M; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &buf[2], 1); cmd[0] = LSM303_REG_MAG_OUTY_H_REG_M; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &buf[3], 1); cmd[0] = LSM303_REG_MAG_OUTZ_L_REG_M; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &buf[4], 1); cmd[0] = LSM303_REG_MAG_OUTZ_H_REG_M; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &buf[5], 1); myMagX = (buf[0] | (buf[1] << 8)); myMagY = (buf[2] | (buf[3] << 8)); myMagZ = (buf[4] | (buf[5] << 8)); if (myMagX < magMinX) magMinX = myMagX; if (myMagY < magMinY) magMinY = myMagY; if (myMagZ < magMinZ) magMinZ = myMagZ; if (myMagX > magMaxX) magMaxX = myMagX; if (myMagY > magMaxY) magMaxY = myMagY; if (myMagZ > magMaxZ) magMaxZ = myMagZ; cmd[0] = LSM303_REG_MAG_INT_SOURCE_REG_M; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &ret, 1); if (ret & 0x01 && magEvent == 0 && ret & 0xFC) { magSFire++; magEvent = 1; magSHIRQ++; } else if (!(ret & 0x01) && magEvent == 1 && !(ret & 0xFC)) { magSFire++; magEvent = 0; magSLIRQ++; } printf("M|%02X|%02X %02X %02X %02X %02X %02X|%*d,%*d,%*d|%*d,%*d,%*d|%*d,%*d,%*d|%02X|%02X/%02X %02X/%02X\r\n", rda, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], 6, myMagX, 6, myMagY, 6, myMagZ, 6, magMinX, 6, magMinY, 6, magMinZ, 6, magMaxX, 6, magMaxY, 6, magMaxZ, ret, magSHIRQ, magSLIRQ, magSFire, magHFire); } } void accRead() { cmd[0] = LSM303_REG_ACC_STATUS_REG_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &rda, 1); if (rda) { cmd[0] = LSM303_REG_ACC_OUT_X_L_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &buf[0], 1); cmd[0] = LSM303_REG_ACC_OUT_X_H_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &buf[1], 1); cmd[0] = LSM303_REG_ACC_OUT_Y_L_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &buf[2], 1); cmd[0] = LSM303_REG_ACC_OUT_Y_H_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &buf[3], 1); cmd[0] = LSM303_REG_ACC_OUT_Z_L_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &buf[4], 1); cmd[0] = LSM303_REG_ACC_OUT_Z_H_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &buf[5], 1); myAccX = ((int16_t)(buf[0] | (buf[1] << 8)) >> accShift); myAccY = ((int16_t)(buf[2] | (buf[3] << 8)) >> accShift); myAccZ = ((int16_t)(buf[4] | (buf[5] << 8)) >> accShift); if (myAccX < accMinX) accMinX = myAccX; if (myAccY < accMinY) accMinY = myAccY; if (myAccZ < accMinZ) accMinZ = myAccZ; if (myAccX > accMaxX) accMaxX = myAccX; if (myAccY > accMaxY) accMaxY = myAccY; if (myAccZ > accMaxZ) accMaxZ = myAccZ; cmd[0] = LSM303_REG_ACC_INT1_SRC_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &ret, 1); if (ret & 0x40) { accSFire++; if (accEvent == 1) { accEvent = 0; accSLIRQ++; cmd[0] = LSM303_REG_ACC_INT1_THS_A; cmd[1] = 0x7D; i2c.write(LSM303_ADR_ACC, cmd, 2); cmd[0] = LSM303_REG_ACC_INT1_DURATION_A; cmd[1] = 0x00; i2c.write(LSM303_ADR_ACC, cmd, 2); cmd[0] = LSM303_REG_ACC_INT1_CFG_A; cmd[1] = 0x2A; i2c.write(LSM303_ADR_ACC, cmd, 2); } else { accEvent = 1; accSHIRQ++; cmd[0] = LSM303_REG_ACC_INT1_THS_A; cmd[1] = 0x50; i2c.write(LSM303_ADR_ACC, cmd, 2); cmd[0] = LSM303_REG_ACC_INT1_DURATION_A; //cmd[1] = 0x7D; cmd[1] = 0x03; i2c.write(LSM303_ADR_ACC, cmd, 2); cmd[0] = LSM303_REG_ACC_INT1_CFG_A; cmd[1] = 0x95; i2c.write(LSM303_ADR_ACC, cmd, 2); } } printf("A|%02X|%02X %02X %02X %02X %02X %02X|%*d,%*d,%*d|%*d,%*d,%*d|%*d,%*d,%*d|%02X|%02X/%02X %02X/%02X\r\n", rda, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], 6, myAccX, 6, myAccY, 6, myAccZ, 6, accMinX, 6, accMinY, 6, accMinZ, 6, accMaxX, 6, accMaxY, 6, accMaxZ, ret, accSHIRQ, accSLIRQ, accSFire, accHFire); } } void tmpRead() { #if defined(TARGET_LRAT) cmd[0] = LSM303_REG_MAG_TEMP_L_M; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &buf[0], 1); cmd[0] = LSM303_REG_MAG_TEMP_H_M; i2c.write(LSM303_ADR_MAG, cmd, 1); i2c.read(LSM303_ADR_MAG, &buf[1], 1); myTemp = (int16_t)(buf[0] | (buf[1] << 8)); printf("T|%02X %02X| (%d)\r\n", buf[0], buf[1], myTemp); #else cmd[0] = LSM303_REG_ACC_STATUS_REG_AUX_A; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &rda, 1); if (rda & 0x04) { cmd[0] = LSM303_REG_ACC_OUT_TEMP_L_A | 0x80; i2c.write(LSM303_ADR_ACC, cmd, 1); i2c.read(LSM303_ADR_ACC, &buf[0], 2); myTemp = (int16_t)(buf[0] | (buf[1] << 8)) >> 6; printf("T|%02X %02X %02X| (%d)\r\n", rda, buf[0], buf[1], myTemp); } #endif } void gpsRead() { bool gpsDone = false; bool fixGood = false; uint8_t crcPass = 0; uint8_t crcFail = 0; uint32_t tDate = 0; uint32_t tTime = 0; myLedW = 1; pos = 0; ret = 0xFF; cmd[0] = 0xFF; i2c.write(NEOM8M_ADR_GPS, cmd, 1); while(!gpsDone) { while (ret == 0xFF) { i2c.read(NEOM8M_ADR_GPS, &ret, 1); } while (ret != 0xFF) { buf[pos++] = ret; i2c.read(NEOM8M_ADR_GPS, &ret, 1); if (ret == '\r') { i2c.read(NEOM8M_ADR_GPS, &ret, 1); if (ret == '\n') { buf[pos] = 0x00; // NMEA Validation uint16_t crc = 0; char clr = '\0'; if (buf[0] == '$' && buf[pos-3] == '*') { for (int i = 1; i < pos-3; i++) { crc ^= buf[i]; } } if (crc == ((buf[pos-2] < 'A' ? buf[pos-2] - '0' : buf[pos-2] - '7') << 4 | (buf[pos-1] < 'A' ? buf[pos-1] - '0' : buf[pos-1] - '7'))) { clr = '2'; // 2 = Green crcPass++; } else { clr = '1'; // 1 = Red crcFail++; } printf("GPS: [\u001b[3%cm%02X\u001b[0m] |%s|\r\n", clr, crc, buf); if (clr == '2') { // Global Positioning System Fix Data if(strncmp(buf, "$GNGGA", 6) == 0) { printf("GNGGA> "); //sscanf(cmd, "$GPGGA,%f,%f,%c,%f,%c,%d,%d,%*f,%f", &timefix, &latitude, &ns, &longitude, &ew, &fq, &nst, &altitude); //pc.printf("GPGGA Fix taken at: %f, Latitude: %f %c, Longitude: %f %c, Fix quality: %d, Number of sat: %d, Altitude: %f M\n", timefix, latitude, ns, longitude, ew, fq, nst, altitude); float fldTim, fldAlt; double fldLat, fldLon; char fldN_S, fldE_W; int fldFix, fldSat; sscanf(buf, "$GNGGA,%f,%lf,%c,%lf,%c,%d,%d,%*f,%f", &fldTim, &fldLat, &fldN_S, &fldLon, &fldE_W, &fldFix, &fldSat, &fldAlt); printf("Sec: %.2f, Lat: %.5f %c, Lon: %.5f %c, Fix: %d, Sat: %d, Alt: %.1f M\r\n", fldTim, fldLat, fldN_S, fldLon, fldE_W, fldFix, fldSat, fldAlt); if (clr == '2') { mylat = fldLat / (fldN_S == 'S' ? -100 : 100); mylon = fldLon / (fldE_W == 'W' ? -100 : 100); //mytime = (uint32_t)fldTim; mybatt = (fldSat & 0xF0 ? 0x0F : fldSat & 0x0F); } } // Satellite status if(strncmp(buf, "$GNGSA", 6) == 0) { //printf("GNGSA> "); //sscanf(cmd, "$GPGSA,%c,%d,%d", &tf, &fix, &nst); //pc.printf("GPGSA Type fix: %c, 3D fix: %d, number of sat: %d\r\n", tf, fix, nst); char fldTyp; int fldDim, fldSat; sscanf(buf, "$GNGSA,%c,%d,%d", &fldTyp, &fldDim, &fldSat); //printf("Typ: %c, Pos: %d, Sat: %d\r\n", fldTyp, fldDim, fldSat); } // Geographic position, Latitude and Longitude if(strncmp(buf, "$GNGLL", 6) == 0) { //printf("GNGLL> "); //sscanf(cmd, "$GPGLL,%f,%c,%f,%c,%f", &latitude, &ns, &longitude, &ew, &timefix); //pc.printf("GPGLL Latitude: %f %c, Longitude: %f %c, Fix taken at: %f\n", latitude, ns, longitude, ew, timefix); float fldTim; double fldLat, fldLon; char fldN_S, fldE_W; sscanf(buf, "$GNGLL,%lf,%c,%lf,%c,%f", &fldLat, &fldN_S, &fldLon, &fldE_W, &fldTim); //printf("Lat: %.5f %c, Lon: %.5f %c, Sec: %.2f\r\n", fldLat, fldN_S, fldLon, fldE_W, fldTim); } // Geographic position, Latitude and Longitude if(strncmp(buf, "$GNRMC", 6) == 0) { //printf("GPS: [\u001b[3%cm%02X\u001b[0m] |%s|\r\n", clr, crc, buf); printf("GNRMC> "); //sscanf(cmd, "$GPRMC,%f,%c,%f,%c,%f,%c,%f,,%d", &timefix, &status, &latitude, &ns, &longitude, &ew, &speed, &date); //pc.printf("GPRMC Fix taken at: %f, Status: %c, Latitude: %f %c, Longitude: %f %c, Speed: %f, Date: %d\n", timefix, status, latitude, ns, longitude, ew, speed, date); float fldTim, fldSpd, fldTrk; fldTrk = 0; double fldLat, fldLon; char fldSts, fldN_S, fldE_W; uint32_t fldDat; if (sscanf(buf, "$GNRMC,,%c", &fldSts) != 1 && sscanf(buf, "$GNRMC,%f,%c,,,,,,,%d", &fldTim, &fldSts, &fldDat) != 3 && sscanf(buf, "$GNRMC,%f,%c,%lf,%c,%lf,%c,%f,,%d", &fldTim, &fldSts, &fldLat, &fldN_S, &fldLon, &fldE_W, &fldSpd, &fldDat) != 8 && sscanf(buf, "$GNRMC,%f,%c,%lf,%c,%lf,%c,%f,%f,%d", &fldTim, &fldSts, &fldLat, &fldN_S, &fldLon, &fldE_W, &fldSpd, &fldTrk, &fldDat) != 9) printf("[\u001b[33mWARN\u001b[0m] Invalid GNRMC packet detected.\r\n"); //sscanf(buf, "$GNRMC,%f,%c,%lf,%c,%lf,%c,%f,%7[^,],%d", &fldTim, &fldSts, &fldLat, &fldN_S, &fldLon, &fldE_W, &fldSpd, fldFoo, &fldDat); printf("Sec: %.2f, Sts: %c, Lat: %.5f %c, Lon: %.5f %c, Spd: %.3f, Dat: %06d\r\n", fldTim, fldSts, fldLat, fldN_S, fldLon, fldE_W, fldSpd, fldDat); if (clr == '2') { tTime = (uint32_t)fldTim; tDate = fldDat; if (fldSts == 'A') fixGood = true; } } } pos = 0; i2c.read(NEOM8M_ADR_GPS, &ret, 1); } else { printf("[\u001b[33mWARN\u001b[0m] Expected '0A', received '%02X'.\r\n", ret); } } else if (pos == 82) { buf[pos] = 0x00; printf("GPS: |%s| ...\r\n", buf); pos = 0; i2c.read(NEOM8M_ADR_GPS, &ret, 1); } } buf[pos] = 0x00; gpsDone = true; } if (pos > 0) printf("GPS: |%s|\r\n", buf); myLedW = 0; if (crcFail) printf("[\u001b[33mWARN\u001b[0m] CRC PASS: %d FAIL: %d\r\n", crcPass, crcFail); struct tm ts; time_t t; uint8_t tDay = tDate / 10000; uint8_t tMon = (tDate - (tDay * 10000)) / 100; uint8_t tYear = (tDate - ((tDay * 10000) + (tMon * 100))) + 100; uint8_t tHour = tTime / 10000; uint8_t tMin = (tTime - (tHour * 10000)) / 100; uint8_t tSec = (tTime - ((tHour * 10000) + (tMin * 100))); ts.tm_year = tYear; ts.tm_mon = tMon - 1; ts.tm_mday = tDay; ts.tm_hour = tHour; ts.tm_min = tMin; ts.tm_sec = tSec; t = mktime(&ts); //printf("DAT: %06d TIM: %d\r\n", tDate, tTime); //printf("CNV: %04d-%02d-%02d@%02d:%02d:%02d\r\n", tYear, tMon, tDay, tHour, tMin, tSec); //printf("T: %d\t%s", t, ctime(&t)); printf("GPS: %08X\t%s", t, ctime(&t)); mytime = t; if (fixGood) myLedG = 1; else myLedR = 1; for (int i = 0; i < 10; i++) { myLedB = 1; wait(0.1); myLedB = 0; wait(0.1); } } // EOF