Release 1.0 supporting the Kinetis Freedom K64F board and NimbeLink NL-AB-ST-NCL and NimbeLink NL-SWSK. Tested with NL-SW-1xRTT-V and NL-SW-EVDO-V modems.

Dependencies:   LIS3DH LM75B LPS331 mbed hts221

Getting Started Guide

Note for the NL-AB-ST-NCL: In order to use the NimbeLink NL-AB-ST-NCL with the NXP FRDM-K64F, you must populate Resistors R2 and R8 while removing resistors R1 and R7. The NimbeLink NL-AB-ST-NCL will not work with the FRDM-K64F unless this change is made.

Note for the NL-SWSK: In order to use the NimbeLink NL-SWSK with the NXP FRDM-K64F, you must move Jumpers J3 and J4 to pins 2 and 3. The NimbeLink NL-SWSK will not work with the FRDM-K64F unless this change is made.

  • Place the Skywire Shield onto the FRDM-K64F as pictured
  • Place the Skywire modem onto the Shield as picture and attach the antenna U.FL coax cable as pictured
  • Screw in the antenna
  • Plug the 12V wall supply into the Skywire Shield
  • For serial debugging, plug a micro-USB cable into port J26 of the FRDM-K64F. If you are using Windows, make sure you have the serial drivers installed-please consult the guide at https://developer.mbed.org/handbook/Windows-serial-configuration for installation.Use a terminal emulation program such as TeraTerm with the following settings:
    • Baud Rate: 115200
    • Data: 8 bit
    • Parity: none
    • Stop: 1 bit
    • Flow Control: none /media/uploads/kylerodgers/fdrm-k64f.jpg
  • The new dashboard will show up on you account list under My Freeboards, you can then edit the name to whatever you like /media/uploads/kholland/default_skywire2.jpg
  • Under the Datasources tab on the dashboard, click the skywire link /media/uploads/kholland/default_skywire5.jpg
  • Change the THING NAME field to the MEID of the Skywire Modem. The MEID is printed on top of the modem. Otherwise, you can get the MEID from the serial output. /media/uploads/kholland/default_skywire4.jpg
  • Next Import the Skywire_Kinetis_K64_demo program into the online compiler
  • Compile and upload to the FRDM-K64F, cycle power to the shield and the sensor data should start to upload to your new Freeboard.
Committer:
KurtDiver
Date:
Wed Jun 24 17:49:02 2015 +0000
Revision:
0:a096c02fb1b0
Child:
1:e05da6207ebb
Release 1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
KurtDiver 0:a096c02fb1b0 1 #include "mbed.h"
KurtDiver 0:a096c02fb1b0 2 #include "LPS331.h"
KurtDiver 0:a096c02fb1b0 3 #include "LIS3DH.h"
KurtDiver 0:a096c02fb1b0 4 #include "LM75B.h"
KurtDiver 0:a096c02fb1b0 5
KurtDiver 0:a096c02fb1b0 6
KurtDiver 0:a096c02fb1b0 7 // #define DeviceID "A100003E4226B3" //Freeboard DweetIO unique ID
KurtDiver 0:a096c02fb1b0 8 // dynamically assigning this based on modem's unique identifier below
KurtDiver 0:a096c02fb1b0 9 char DeviceID[15];
KurtDiver 0:a096c02fb1b0 10
KurtDiver 0:a096c02fb1b0 11
KurtDiver 0:a096c02fb1b0 12 DigitalOut skywire_en(PTD3); //K64 FRDM
KurtDiver 0:a096c02fb1b0 13 DigitalOut skywire_rts(PTD2); //K64 FRDM
KurtDiver 0:a096c02fb1b0 14 DigitalOut skywire_dtr(PTD0); //K64 FRDM
KurtDiver 0:a096c02fb1b0 15
KurtDiver 0:a096c02fb1b0 16
KurtDiver 0:a096c02fb1b0 17
KurtDiver 0:a096c02fb1b0 18 DigitalOut led_red(LED_RED);
KurtDiver 0:a096c02fb1b0 19 DigitalOut led_green(LED_GREEN);
KurtDiver 0:a096c02fb1b0 20 DigitalIn sw2(SW2);
KurtDiver 0:a096c02fb1b0 21 DigitalIn sw3(SW3);
KurtDiver 0:a096c02fb1b0 22 Serial pc(USBTX, USBRX);
KurtDiver 0:a096c02fb1b0 23 Serial skywire(PTC17, PTC16); //K64 FRDM
KurtDiver 0:a096c02fb1b0 24
KurtDiver 0:a096c02fb1b0 25 I2C i2c(PTE25,PTE24);
KurtDiver 0:a096c02fb1b0 26 char msg[3];
KurtDiver 0:a096c02fb1b0 27
KurtDiver 0:a096c02fb1b0 28 LPS331 pressure(i2c);
KurtDiver 0:a096c02fb1b0 29 LM75B LM75_temp(PTE25,PTE24);
KurtDiver 0:a096c02fb1b0 30 LIS3DH accel(i2c, LIS3DH_V_CHIP_ADDR, LIS3DH_DR_NR_LP_100HZ, LIS3DH_FS_2G);
KurtDiver 0:a096c02fb1b0 31
KurtDiver 0:a096c02fb1b0 32
KurtDiver 0:a096c02fb1b0 33 char str[255];
KurtDiver 0:a096c02fb1b0 34
KurtDiver 0:a096c02fb1b0 35
KurtDiver 0:a096c02fb1b0 36
KurtDiver 0:a096c02fb1b0 37
KurtDiver 0:a096c02fb1b0 38 float latitude;
KurtDiver 0:a096c02fb1b0 39 float longitude;
KurtDiver 0:a096c02fb1b0 40 int number;
KurtDiver 0:a096c02fb1b0 41
KurtDiver 0:a096c02fb1b0 42 volatile int rx_in=0;
KurtDiver 0:a096c02fb1b0 43 volatile int rx_out=0;
KurtDiver 0:a096c02fb1b0 44 const int buffer_size = 255;
KurtDiver 0:a096c02fb1b0 45 char rx_buffer[buffer_size+1];
KurtDiver 0:a096c02fb1b0 46
KurtDiver 0:a096c02fb1b0 47 char rx_line[buffer_size];
KurtDiver 0:a096c02fb1b0 48
KurtDiver 0:a096c02fb1b0 49 void Skywire_Rx_interrupt() {
KurtDiver 0:a096c02fb1b0 50 // Loop just in case more than one character is in UART's receive FIFO buffer
KurtDiver 0:a096c02fb1b0 51 // Stop if buffer full
KurtDiver 0:a096c02fb1b0 52 while ((skywire.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) {
KurtDiver 0:a096c02fb1b0 53 rx_buffer[rx_in] = skywire.getc();
KurtDiver 0:a096c02fb1b0 54 rx_in = (rx_in + 1) % buffer_size;
KurtDiver 0:a096c02fb1b0 55 }
KurtDiver 0:a096c02fb1b0 56 return;
KurtDiver 0:a096c02fb1b0 57 }
KurtDiver 0:a096c02fb1b0 58
KurtDiver 0:a096c02fb1b0 59 void read_line() {
KurtDiver 0:a096c02fb1b0 60 int i;
KurtDiver 0:a096c02fb1b0 61 i = 0;
KurtDiver 0:a096c02fb1b0 62 // Start Critical Section - don't interrupt while changing global buffer variables
KurtDiver 0:a096c02fb1b0 63 __disable_irq();
KurtDiver 0:a096c02fb1b0 64 // Loop reading rx buffer characters until end of line character
KurtDiver 0:a096c02fb1b0 65 while ((i==0) || (rx_line[i-1] != '\n')) {
KurtDiver 0:a096c02fb1b0 66 // Wait if buffer empty
KurtDiver 0:a096c02fb1b0 67 if (rx_in == rx_out) {
KurtDiver 0:a096c02fb1b0 68 // End Critical Section - need to allow rx interrupt to get new characters for buffer
KurtDiver 0:a096c02fb1b0 69 __enable_irq();
KurtDiver 0:a096c02fb1b0 70 while (rx_in == rx_out) {
KurtDiver 0:a096c02fb1b0 71 //pc.printf("..Read_line entered2.5\r\n");
KurtDiver 0:a096c02fb1b0 72 }
KurtDiver 0:a096c02fb1b0 73 // Start Critical Section - don't interrupt while changing global buffer variables
KurtDiver 0:a096c02fb1b0 74 __disable_irq();
KurtDiver 0:a096c02fb1b0 75 }
KurtDiver 0:a096c02fb1b0 76 rx_line[i] = rx_buffer[rx_out];
KurtDiver 0:a096c02fb1b0 77 i++;
KurtDiver 0:a096c02fb1b0 78 rx_out = (rx_out + 1) % buffer_size;
KurtDiver 0:a096c02fb1b0 79 }
KurtDiver 0:a096c02fb1b0 80 // End Critical Section
KurtDiver 0:a096c02fb1b0 81 __enable_irq();
KurtDiver 0:a096c02fb1b0 82 rx_line[i-1] = 0;
KurtDiver 0:a096c02fb1b0 83 return;
KurtDiver 0:a096c02fb1b0 84 }
KurtDiver 0:a096c02fb1b0 85 int WaitForResponse(char* response, int num) {
KurtDiver 0:a096c02fb1b0 86 do {
KurtDiver 0:a096c02fb1b0 87 read_line();
KurtDiver 0:a096c02fb1b0 88 pc.printf("Waiting for: %s, Recieved: %s\r\n", response, rx_line);
KurtDiver 0:a096c02fb1b0 89 } while (strncmp(rx_line, response, num));
KurtDiver 0:a096c02fb1b0 90 return 0;
KurtDiver 0:a096c02fb1b0 91 }
KurtDiver 0:a096c02fb1b0 92
KurtDiver 0:a096c02fb1b0 93 void check_sw2(void)
KurtDiver 0:a096c02fb1b0 94 {
KurtDiver 0:a096c02fb1b0 95 if (sw2 == 0) {
KurtDiver 0:a096c02fb1b0 96 pc.printf("SW2 button pressed. \r\n");
KurtDiver 0:a096c02fb1b0 97 // turn RED LED on to indicate provisioning process has started
KurtDiver 0:a096c02fb1b0 98 led_red = 0;
KurtDiver 0:a096c02fb1b0 99 led_green = 1;
KurtDiver 0:a096c02fb1b0 100 wait(1);
KurtDiver 0:a096c02fb1b0 101 // turn LEDs off
KurtDiver 0:a096c02fb1b0 102 led_red = 1;
KurtDiver 0:a096c02fb1b0 103 led_green = 1;
KurtDiver 0:a096c02fb1b0 104 skywire.printf("ATD*22899;\r\n");
KurtDiver 0:a096c02fb1b0 105 WaitForResponse("#OTASP: 0", 9);
KurtDiver 0:a096c02fb1b0 106 pc.printf("Provisioning: #OTASP: 0 reached. \r\n");
KurtDiver 0:a096c02fb1b0 107 // turn RED LED on
KurtDiver 0:a096c02fb1b0 108 led_red = 0;
KurtDiver 0:a096c02fb1b0 109 led_green = 1;
KurtDiver 0:a096c02fb1b0 110 WaitForResponse("#OTASP: 1", 9);
KurtDiver 0:a096c02fb1b0 111 pc.printf("Provisioning: #OTASP: 1 reached. \r\n");
KurtDiver 0:a096c02fb1b0 112 // turn both LEDs on
KurtDiver 0:a096c02fb1b0 113 led_red = 0;
KurtDiver 0:a096c02fb1b0 114 led_green = 0;
KurtDiver 0:a096c02fb1b0 115 WaitForResponse("#OTASP: 2", 9);
KurtDiver 0:a096c02fb1b0 116 pc.printf("Provisioning: #OTASP: 2 reached. \r\n");
KurtDiver 0:a096c02fb1b0 117 // turn GREEN LED on
KurtDiver 0:a096c02fb1b0 118 led_red = 1;
KurtDiver 0:a096c02fb1b0 119 led_green = 0;
KurtDiver 0:a096c02fb1b0 120 WaitForResponse("NO CARRIER", 10);
KurtDiver 0:a096c02fb1b0 121 pc.printf("Provisioning successfully completed. \r\n");
KurtDiver 0:a096c02fb1b0 122
KurtDiver 0:a096c02fb1b0 123 skywire.printf("AT#REBOOT");
KurtDiver 0:a096c02fb1b0 124 // wait 10 seconds
KurtDiver 0:a096c02fb1b0 125 wait(10);
KurtDiver 0:a096c02fb1b0 126
KurtDiver 0:a096c02fb1b0 127
KurtDiver 0:a096c02fb1b0 128 }
KurtDiver 0:a096c02fb1b0 129 }
KurtDiver 0:a096c02fb1b0 130 void blinkRG(int blinkduration)
KurtDiver 0:a096c02fb1b0 131 {
KurtDiver 0:a096c02fb1b0 132 // blinkduration is measured in seconds
KurtDiver 0:a096c02fb1b0 133 led_red=1;
KurtDiver 0:a096c02fb1b0 134 led_green=0;
KurtDiver 0:a096c02fb1b0 135 while (blinkduration-- >=1){
KurtDiver 0:a096c02fb1b0 136 led_red = led_green;
KurtDiver 0:a096c02fb1b0 137 led_green=!led_red;
KurtDiver 0:a096c02fb1b0 138 wait(1);
KurtDiver 0:a096c02fb1b0 139 }
KurtDiver 0:a096c02fb1b0 140 // leave the function with LEDs both off
KurtDiver 0:a096c02fb1b0 141 led_red=1;
KurtDiver 0:a096c02fb1b0 142 led_green=1;
KurtDiver 0:a096c02fb1b0 143
KurtDiver 0:a096c02fb1b0 144 }
KurtDiver 0:a096c02fb1b0 145 void check_sw3(void)
KurtDiver 0:a096c02fb1b0 146 {
KurtDiver 0:a096c02fb1b0 147 if (sw3 == 0) {
KurtDiver 0:a096c02fb1b0 148 pc.printf("SW3 button pressed. \r\n");
KurtDiver 0:a096c02fb1b0 149 // this button press is used to pause transmissions (to save data if the device is on forever);
KurtDiver 0:a096c02fb1b0 150 pc.printf("Transmissions are paused. \r\n");
KurtDiver 0:a096c02fb1b0 151 // turn on RED LED
KurtDiver 0:a096c02fb1b0 152 led_green = 1;
KurtDiver 0:a096c02fb1b0 153 led_red = 0;
KurtDiver 0:a096c02fb1b0 154 // wait a few seconds for user to release the button.
KurtDiver 0:a096c02fb1b0 155 wait(3);
KurtDiver 0:a096c02fb1b0 156
KurtDiver 0:a096c02fb1b0 157 // wait until user presses the button again to unpause
KurtDiver 0:a096c02fb1b0 158 while(sw3 ==1);
KurtDiver 0:a096c02fb1b0 159 pc.printf("Transmissions resumed. \r\n");
KurtDiver 0:a096c02fb1b0 160 // turn LEDs off
KurtDiver 0:a096c02fb1b0 161 led_green = 1;
KurtDiver 0:a096c02fb1b0 162 led_red = 1;
KurtDiver 0:a096c02fb1b0 163 }
KurtDiver 0:a096c02fb1b0 164 }
KurtDiver 0:a096c02fb1b0 165
KurtDiver 0:a096c02fb1b0 166 int main() {
KurtDiver 0:a096c02fb1b0 167
KurtDiver 0:a096c02fb1b0 168 led_red = 1;
KurtDiver 0:a096c02fb1b0 169 led_green = 1;
KurtDiver 0:a096c02fb1b0 170 float axis[3];
KurtDiver 0:a096c02fb1b0 171 float press;
KurtDiver 0:a096c02fb1b0 172 float temp;
KurtDiver 0:a096c02fb1b0 173
KurtDiver 0:a096c02fb1b0 174 // turn on Skywire modem
KurtDiver 0:a096c02fb1b0 175 skywire_en = 1;
KurtDiver 0:a096c02fb1b0 176
KurtDiver 0:a096c02fb1b0 177 // setup skywire UART
KurtDiver 0:a096c02fb1b0 178 skywire_rts=0;
KurtDiver 0:a096c02fb1b0 179 skywire_dtr=0;
KurtDiver 0:a096c02fb1b0 180 skywire.baud(115200);
KurtDiver 0:a096c02fb1b0 181 skywire.format(8, Serial::None, 1);
KurtDiver 0:a096c02fb1b0 182
KurtDiver 0:a096c02fb1b0 183 // setup Skywire UART interrupt
KurtDiver 0:a096c02fb1b0 184 skywire.attach(&Skywire_Rx_interrupt, skywire.RxIrq);
KurtDiver 0:a096c02fb1b0 185
KurtDiver 0:a096c02fb1b0 186 pc.baud(115200);
KurtDiver 0:a096c02fb1b0 187 pc.printf("Hello World from FRDM-K64F board.\r\n");
KurtDiver 0:a096c02fb1b0 188 pc.printf("Starting Demo...\r\n");
KurtDiver 0:a096c02fb1b0 189 pc.printf("Waiting for Skywire to Boot...\r\n");
KurtDiver 0:a096c02fb1b0 190
KurtDiver 0:a096c02fb1b0 191 // wait 10 seconds for modem to boot up and connect to network
KurtDiver 0:a096c02fb1b0 192 blinkRG(10);
KurtDiver 0:a096c02fb1b0 193 pc.printf("Waiting complete...\r\n");
KurtDiver 0:a096c02fb1b0 194
KurtDiver 0:a096c02fb1b0 195 LM75_temp.open();
KurtDiver 0:a096c02fb1b0 196
KurtDiver 0:a096c02fb1b0 197 //Turn off echo
KurtDiver 0:a096c02fb1b0 198 skywire.printf("ATE0\r\n");
KurtDiver 0:a096c02fb1b0 199 WaitForResponse("OK", 2);
KurtDiver 0:a096c02fb1b0 200
KurtDiver 0:a096c02fb1b0 201 // check to see if switch 2 is pressed, if so, execute provisioning sequence
KurtDiver 0:a096c02fb1b0 202 check_sw2();
KurtDiver 0:a096c02fb1b0 203
KurtDiver 0:a096c02fb1b0 204
KurtDiver 0:a096c02fb1b0 205 // read out MEID number to use as unique identifier
KurtDiver 0:a096c02fb1b0 206 skywire.printf("AT#MEIDESN?\r\n");
KurtDiver 0:a096c02fb1b0 207 wait(2);
KurtDiver 0:a096c02fb1b0 208 read_line();
KurtDiver 0:a096c02fb1b0 209 read_line();
KurtDiver 0:a096c02fb1b0 210 sscanf(rx_line, "%*s %14s,", DeviceID);
KurtDiver 0:a096c02fb1b0 211
KurtDiver 0:a096c02fb1b0 212 pc.printf("Device MEID: %s \r\n", DeviceID);
KurtDiver 0:a096c02fb1b0 213
KurtDiver 0:a096c02fb1b0 214 pc.printf("Connecting to Network...\r\n");
KurtDiver 0:a096c02fb1b0 215 // get IP address
KurtDiver 0:a096c02fb1b0 216 skywire.printf("AT#SGACT=1,1\r\n");
KurtDiver 0:a096c02fb1b0 217 WaitForResponse("#SGACT", 6);
KurtDiver 0:a096c02fb1b0 218 WaitForResponse("OK", 2);
KurtDiver 0:a096c02fb1b0 219 // use LEDs to indicate we're connected to the newtork
KurtDiver 0:a096c02fb1b0 220 led_red=0;
KurtDiver 0:a096c02fb1b0 221 led_green=0;
KurtDiver 0:a096c02fb1b0 222
KurtDiver 0:a096c02fb1b0 223 // connect to dweet.io
KurtDiver 0:a096c02fb1b0 224 skywire.printf("AT#HTTPCFG=1,\"dweet.io\",80,0\r\n");
KurtDiver 0:a096c02fb1b0 225 WaitForResponse("OK", 2);
KurtDiver 0:a096c02fb1b0 226
KurtDiver 0:a096c02fb1b0 227 //get location approximation from cell tower information
KurtDiver 0:a096c02fb1b0 228 skywire.printf("AT#AGPSSND\r\n");
KurtDiver 0:a096c02fb1b0 229 WaitForResponse("#AGPSRING:", 10);
KurtDiver 0:a096c02fb1b0 230
KurtDiver 0:a096c02fb1b0 231 //debug_pc.printf("Skywire says: %s\r\n", rx_line);
KurtDiver 0:a096c02fb1b0 232 sscanf(rx_line, "%s %d,%f,%f,", str, &number, &latitude, &longitude);
KurtDiver 0:a096c02fb1b0 233 //debug_pc.printf("Location: Latt:%f, Long:%f\r\n", latitude, longitude);
KurtDiver 0:a096c02fb1b0 234 wait(3);
KurtDiver 0:a096c02fb1b0 235
KurtDiver 0:a096c02fb1b0 236 while(1) {
KurtDiver 0:a096c02fb1b0 237 temp = (float)LM75_temp;
KurtDiver 0:a096c02fb1b0 238 temp = temp *9 /5 + 32;
KurtDiver 0:a096c02fb1b0 239 pc.printf("Temp = %.3f\r\n", temp);
KurtDiver 0:a096c02fb1b0 240 press=(float)pressure.value() / 4096;
KurtDiver 0:a096c02fb1b0 241 pc.printf("Pressure = %.3f\r\n", press);
KurtDiver 0:a096c02fb1b0 242 accel.read_data(axis);
KurtDiver 0:a096c02fb1b0 243 pc.printf("Accel = %.3f, %.3f, %.3f\r\n", axis[0], axis[1], axis[2]);
KurtDiver 0:a096c02fb1b0 244
KurtDiver 0:a096c02fb1b0 245 wait(0.25);
KurtDiver 0:a096c02fb1b0 246 // turn LED Green to indicate transmission
KurtDiver 0:a096c02fb1b0 247 led_red=1;
KurtDiver 0:a096c02fb1b0 248 led_green = 0;
KurtDiver 0:a096c02fb1b0 249
KurtDiver 0:a096c02fb1b0 250
KurtDiver 0:a096c02fb1b0 251 //Report Sensor Data to dweet.io
KurtDiver 0:a096c02fb1b0 252 skywire.printf("AT#HTTPQRY=1,0,\"/dweet/for/%s?temperature=%.3f&pressure=%.3f&X=%.3f&Y=%.3f&Z=%.3f&Latitude=%f&Longitude=%f\"\r\n", DeviceID, temp, press, axis[0], axis[1], axis[2], latitude, longitude);
KurtDiver 0:a096c02fb1b0 253 WaitForResponse("#HTTPRING", 9);
KurtDiver 0:a096c02fb1b0 254 skywire.printf("AT#HTTPRCV=1\r\n");
KurtDiver 0:a096c02fb1b0 255 WaitForResponse("OK", 2);
KurtDiver 0:a096c02fb1b0 256 led_green = 1;
KurtDiver 0:a096c02fb1b0 257 wait(2);
KurtDiver 0:a096c02fb1b0 258 // see if user has requested to pause transmissions
KurtDiver 0:a096c02fb1b0 259 check_sw3();
KurtDiver 0:a096c02fb1b0 260 }
KurtDiver 0:a096c02fb1b0 261
KurtDiver 0:a096c02fb1b0 262
KurtDiver 0:a096c02fb1b0 263
KurtDiver 0:a096c02fb1b0 264
KurtDiver 0:a096c02fb1b0 265 }