Program that uses the QuickStart Library to interface a SmartMesh IP mote: Connects to the default network and starts publishing a random walk value every 5 seconds.
Fork of QSL_SimplePublish by
QSL SimplePublish
SmartMesh IP QuickStart Library
- GitHub repository
- Current release used: REL-1.0.2.2
- Documentation
- Discussion
main.cpp@8:8eb144b9ada3, 2016-11-03 (annotated)
- Committer:
- jhbr
- Date:
- Thu Nov 03 09:35:50 2016 +0000
- Revision:
- 8:8eb144b9ada3
- Parent:
- 6:bb0ffa1d5be3
Replaced use of Time and Timer with SysTick
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jhbr | 6:bb0ffa1d5be3 | 1 | /* |
jhbr | 6:bb0ffa1d5be3 | 2 | Copyright (c) 2016, Dust Networks. All rights reserved. |
jhbr | 6:bb0ffa1d5be3 | 3 | |
jhbr | 6:bb0ffa1d5be3 | 4 | SimplePublish example application for the mbed OS. |
jhbr | 6:bb0ffa1d5be3 | 5 | |
jhbr | 6:bb0ffa1d5be3 | 6 | \license See attached DN_LICENSE.txt. |
jhbr | 6:bb0ffa1d5be3 | 7 | */ |
jhbr | 6:bb0ffa1d5be3 | 8 | |
jhbr | 0:d3f5fdf2e6da | 9 | #include "mbed.h" |
jhbr | 8:8eb144b9ada3 | 10 | #include "millis.h" |
jhbr | 8:8eb144b9ada3 | 11 | #include "dn_qsl_api.h" // Only really need this include from QSL |
jhbr | 0:d3f5fdf2e6da | 12 | #include "dn_debug.h" // Included to borrow debug macros |
jhbr | 0:d3f5fdf2e6da | 13 | #include "dn_endianness.h" // Included to borrow array copying |
jhbr | 0:d3f5fdf2e6da | 14 | #include "dn_time.h" // Included to borrow sleep function |
jhbr | 0:d3f5fdf2e6da | 15 | |
jhbr | 0:d3f5fdf2e6da | 16 | #define NETID 0 // Factory default value used if zero (1229) |
jhbr | 0:d3f5fdf2e6da | 17 | #define JOINKEY NULL // Factory default value used if NULL (44 55 53 54 4E 45 54 57 4F 52 4B 53 52 4F 43 4B) |
jhbr | 5:eb02ec8b90f8 | 18 | #define BANDWIDTH_MS 5000 // Not changed if zero (default base bandwidth given by manager is 9 s) |
jhbr | 0:d3f5fdf2e6da | 19 | #define SRC_PORT 60000 // Default port used if zero (0xf0b8) |
jhbr | 0:d3f5fdf2e6da | 20 | #define DEST_PORT 0 // Default port used if zero (0xf0b8) |
jhbr | 5:eb02ec8b90f8 | 21 | #define DATA_PERIOD_MS 5000 // Should be longer than (or equal to) bandwidth |
jhbr | 0:d3f5fdf2e6da | 22 | |
jhbr | 0:d3f5fdf2e6da | 23 | // We can use debug macros from dn_debug, as stdio defaults to this serial |
jhbr | 0:d3f5fdf2e6da | 24 | Serial serialDebug(SERIAL_TX, SERIAL_RX); |
jhbr | 2:f177b47313ba | 25 | // LED2 is the green LED on the NUCLEO-L053R8; might change for other boards |
jhbr | 2:f177b47313ba | 26 | DigitalOut myled(LED2); |
jhbr | 0:d3f5fdf2e6da | 27 | |
jhbr | 0:d3f5fdf2e6da | 28 | static uint16_t randomWalk(void); |
jhbr | 0:d3f5fdf2e6da | 29 | static void parsePayload(const uint8_t *payload, uint8_t size); |
jhbr | 0:d3f5fdf2e6da | 30 | |
jhbr | 0:d3f5fdf2e6da | 31 | int main() |
jhbr | 0:d3f5fdf2e6da | 32 | { |
jhbr | 0:d3f5fdf2e6da | 33 | uint8_t payload[3]; |
jhbr | 0:d3f5fdf2e6da | 34 | uint8_t inboxBuf[DN_DEFAULT_PAYLOAD_SIZE_LIMIT]; |
jhbr | 0:d3f5fdf2e6da | 35 | uint8_t bytesRead; |
jhbr | 2:f177b47313ba | 36 | uint8_t i; |
jhbr | 0:d3f5fdf2e6da | 37 | |
jhbr | 8:8eb144b9ada3 | 38 | // Configure SysTick for timing |
jhbr | 8:8eb144b9ada3 | 39 | millisStart(); |
jhbr | 8:8eb144b9ada3 | 40 | |
jhbr | 5:eb02ec8b90f8 | 41 | // Set PC debug serial baudrate |
jhbr | 0:d3f5fdf2e6da | 42 | serialDebug.baud(115200); |
jhbr | 0:d3f5fdf2e6da | 43 | |
jhbr | 0:d3f5fdf2e6da | 44 | log_info("Initializing..."); |
jhbr | 0:d3f5fdf2e6da | 45 | dn_qsl_init(); |
jhbr | 2:f177b47313ba | 46 | |
jhbr | 2:f177b47313ba | 47 | // Flash LED to indicate start-up complete |
jhbr | 2:f177b47313ba | 48 | for (i = 0; i < 10; i++) |
jhbr | 2:f177b47313ba | 49 | { |
jhbr | 2:f177b47313ba | 50 | myled = !myled; |
jhbr | 2:f177b47313ba | 51 | dn_sleep_ms(50); |
jhbr | 2:f177b47313ba | 52 | } |
jhbr | 0:d3f5fdf2e6da | 53 | |
jhbr | 0:d3f5fdf2e6da | 54 | while(TRUE) { |
jhbr | 0:d3f5fdf2e6da | 55 | if (dn_qsl_isConnected()) |
jhbr | 0:d3f5fdf2e6da | 56 | { |
jhbr | 0:d3f5fdf2e6da | 57 | uint16_t val = randomWalk(); |
jhbr | 0:d3f5fdf2e6da | 58 | static uint8_t count = 0; |
jhbr | 2:f177b47313ba | 59 | myled = 0; // Turn off LED during send/read |
jhbr | 0:d3f5fdf2e6da | 60 | |
jhbr | 0:d3f5fdf2e6da | 61 | dn_write_uint16_t(payload, val); |
jhbr | 0:d3f5fdf2e6da | 62 | payload[2] = count; |
jhbr | 0:d3f5fdf2e6da | 63 | |
jhbr | 0:d3f5fdf2e6da | 64 | if (dn_qsl_send(payload, sizeof (payload), DEST_PORT)) |
jhbr | 0:d3f5fdf2e6da | 65 | { |
jhbr | 0:d3f5fdf2e6da | 66 | log_info("Sent message nr %u: %u", count, val); |
jhbr | 0:d3f5fdf2e6da | 67 | count++; |
jhbr | 0:d3f5fdf2e6da | 68 | } else |
jhbr | 0:d3f5fdf2e6da | 69 | { |
jhbr | 0:d3f5fdf2e6da | 70 | log_info("Send failed"); |
jhbr | 0:d3f5fdf2e6da | 71 | } |
jhbr | 0:d3f5fdf2e6da | 72 | |
jhbr | 0:d3f5fdf2e6da | 73 | do |
jhbr | 0:d3f5fdf2e6da | 74 | { |
jhbr | 0:d3f5fdf2e6da | 75 | bytesRead = dn_qsl_read(inboxBuf); |
jhbr | 0:d3f5fdf2e6da | 76 | parsePayload(inboxBuf, bytesRead); |
jhbr | 0:d3f5fdf2e6da | 77 | } while (bytesRead > 0); |
jhbr | 0:d3f5fdf2e6da | 78 | |
jhbr | 2:f177b47313ba | 79 | myled = 1; // Turn on LED |
jhbr | 0:d3f5fdf2e6da | 80 | dn_sleep_ms(DATA_PERIOD_MS); |
jhbr | 0:d3f5fdf2e6da | 81 | } else |
jhbr | 0:d3f5fdf2e6da | 82 | { |
jhbr | 0:d3f5fdf2e6da | 83 | log_info("Connecting..."); |
jhbr | 2:f177b47313ba | 84 | myled = 0; // Not connected; turn off LED |
jhbr | 0:d3f5fdf2e6da | 85 | if (dn_qsl_connect(NETID, JOINKEY, SRC_PORT, BANDWIDTH_MS)) |
jhbr | 0:d3f5fdf2e6da | 86 | { |
jhbr | 2:f177b47313ba | 87 | myled = 1; // Connected; turn on LED |
jhbr | 0:d3f5fdf2e6da | 88 | log_info("Connected to network"); |
jhbr | 0:d3f5fdf2e6da | 89 | } else |
jhbr | 0:d3f5fdf2e6da | 90 | { |
jhbr | 0:d3f5fdf2e6da | 91 | log_info("Failed to connect"); |
jhbr | 0:d3f5fdf2e6da | 92 | } |
jhbr | 0:d3f5fdf2e6da | 93 | } |
jhbr | 0:d3f5fdf2e6da | 94 | |
jhbr | 0:d3f5fdf2e6da | 95 | } |
jhbr | 0:d3f5fdf2e6da | 96 | } |
jhbr | 0:d3f5fdf2e6da | 97 | |
jhbr | 0:d3f5fdf2e6da | 98 | static uint16_t randomWalk(void) |
jhbr | 0:d3f5fdf2e6da | 99 | { |
jhbr | 0:d3f5fdf2e6da | 100 | static bool first = TRUE; |
jhbr | 0:d3f5fdf2e6da | 101 | static uint16_t lastValue = 0x7fff; // Start in middle of uint16 range |
jhbr | 0:d3f5fdf2e6da | 102 | const int powerLevel = 9001; |
jhbr | 0:d3f5fdf2e6da | 103 | |
jhbr | 0:d3f5fdf2e6da | 104 | // Seed random number generator on first call |
jhbr | 0:d3f5fdf2e6da | 105 | if (first) |
jhbr | 0:d3f5fdf2e6da | 106 | { |
jhbr | 0:d3f5fdf2e6da | 107 | first = FALSE; |
jhbr | 0:d3f5fdf2e6da | 108 | srand(dn_time_ms()); |
jhbr | 0:d3f5fdf2e6da | 109 | } |
jhbr | 0:d3f5fdf2e6da | 110 | |
jhbr | 0:d3f5fdf2e6da | 111 | // Random walk within +/- powerLevel |
jhbr | 0:d3f5fdf2e6da | 112 | lastValue += rand() / (RAND_MAX / (2*powerLevel) + 1) - powerLevel; |
jhbr | 0:d3f5fdf2e6da | 113 | return lastValue; |
jhbr | 0:d3f5fdf2e6da | 114 | } |
jhbr | 0:d3f5fdf2e6da | 115 | |
jhbr | 0:d3f5fdf2e6da | 116 | static void parsePayload(const uint8_t *payload, uint8_t size) |
jhbr | 0:d3f5fdf2e6da | 117 | { |
jhbr | 0:d3f5fdf2e6da | 118 | uint8_t i; |
jhbr | 0:d3f5fdf2e6da | 119 | char msg[size + 1]; |
jhbr | 0:d3f5fdf2e6da | 120 | |
jhbr | 0:d3f5fdf2e6da | 121 | if (size == 0) |
jhbr | 0:d3f5fdf2e6da | 122 | { |
jhbr | 0:d3f5fdf2e6da | 123 | // Nothing to parse |
jhbr | 0:d3f5fdf2e6da | 124 | return; |
jhbr | 0:d3f5fdf2e6da | 125 | } |
jhbr | 0:d3f5fdf2e6da | 126 | |
jhbr | 0:d3f5fdf2e6da | 127 | // Parse bytes individually as well as together as a string |
jhbr | 0:d3f5fdf2e6da | 128 | log_info("Received downstream payload of %u bytes:", size); |
jhbr | 0:d3f5fdf2e6da | 129 | for (i = 0; i < size; i++) |
jhbr | 0:d3f5fdf2e6da | 130 | { |
jhbr | 0:d3f5fdf2e6da | 131 | msg[i] = payload[i]; |
jhbr | 0:d3f5fdf2e6da | 132 | log_info("\tByte# %03u: %#.2x (%u)", i, payload[i], payload[i]); |
jhbr | 0:d3f5fdf2e6da | 133 | } |
jhbr | 0:d3f5fdf2e6da | 134 | msg[size] = '\0'; |
jhbr | 0:d3f5fdf2e6da | 135 | log_info("\tMessage: %s", msg); |
jhbr | 0:d3f5fdf2e6da | 136 | } |