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.
main.cpp@0:2a5da7b2278c, 2020-11-20 (annotated)
- Committer:
- timo_k2
- Date:
- Fri Nov 20 16:47:14 2020 +0000
- Revision:
- 0:2a5da7b2278c
- Child:
- 1:961861d73841
Initial commit. The "Round trip delay echo" will be needed in an other microcontroller.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
timo_k2 | 0:2a5da7b2278c | 1 | /* |
timo_k2 | 0:2a5da7b2278c | 2 | * Copyright (c) 2006-2020 Arm Limited and affiliates. |
timo_k2 | 0:2a5da7b2278c | 3 | * SPDX-License-Identifier: Apache-2.0 |
timo_k2 | 0:2a5da7b2278c | 4 | *********************************** |
timo_k2 | 0:2a5da7b2278c | 5 | * Round trip delay meter. Date and time is taken from a NTP server. |
timo_k2 | 0:2a5da7b2278c | 6 | * A microcontroller board with an Ethernet interface. |
timo_k2 | 0:2a5da7b2278c | 7 | * An other microcontroller with "Round trip delay echo" will be needed. |
timo_k2 | 0:2a5da7b2278c | 8 | * NXP FRDM-K64F used for testing. |
timo_k2 | 0:2a5da7b2278c | 9 | * |
timo_k2 | 0:2a5da7b2278c | 10 | * Timo Karppinen 20.11.2020 |
timo_k2 | 0:2a5da7b2278c | 11 | ***********************************/ |
timo_k2 | 0:2a5da7b2278c | 12 | #include "mbed.h" |
timo_k2 | 0:2a5da7b2278c | 13 | #include "EthernetInterface.h" |
timo_k2 | 0:2a5da7b2278c | 14 | #include "ntp-client/NTPClient.h" |
timo_k2 | 0:2a5da7b2278c | 15 | |
timo_k2 | 0:2a5da7b2278c | 16 | #define REMOTE_PORT 5000 |
timo_k2 | 0:2a5da7b2278c | 17 | #define LOCAL_PORT 5001 |
timo_k2 | 0:2a5da7b2278c | 18 | #define BUFF_SIZE 128 |
timo_k2 | 0:2a5da7b2278c | 19 | |
timo_k2 | 0:2a5da7b2278c | 20 | //Network interface |
timo_k2 | 0:2a5da7b2278c | 21 | EthernetInterface net; |
timo_k2 | 0:2a5da7b2278c | 22 | |
timo_k2 | 0:2a5da7b2278c | 23 | //Threads |
timo_k2 | 0:2a5da7b2278c | 24 | Thread ntp_thread; |
timo_k2 | 0:2a5da7b2278c | 25 | Thread recv_thread; |
timo_k2 | 0:2a5da7b2278c | 26 | Thread send_thread; |
timo_k2 | 0:2a5da7b2278c | 27 | |
timo_k2 | 0:2a5da7b2278c | 28 | // UDP |
timo_k2 | 0:2a5da7b2278c | 29 | SocketAddress clientUDP; // Client on remote device |
timo_k2 | 0:2a5da7b2278c | 30 | UDPSocket serverUDP; // UDP server in this device |
timo_k2 | 0:2a5da7b2278c | 31 | |
timo_k2 | 0:2a5da7b2278c | 32 | |
timo_k2 | 0:2a5da7b2278c | 33 | //NTP server is a time server used for delivering timing information for networks. |
timo_k2 | 0:2a5da7b2278c | 34 | // Returns 32 bits for seconds and 32 bits for fraction of seconds. |
timo_k2 | 0:2a5da7b2278c | 35 | //#define ntpAddress "2.pool.ntp.org" |
timo_k2 | 0:2a5da7b2278c | 36 | #define ntpAddress "time.mikes.fi" // The VTT Mikes in Helsinki |
timo_k2 | 0:2a5da7b2278c | 37 | #define ntpPort 123 |
timo_k2 | 0:2a5da7b2278c | 38 | |
timo_k2 | 0:2a5da7b2278c | 39 | // Functions |
timo_k2 | 0:2a5da7b2278c | 40 | time_t getNTP(); |
timo_k2 | 0:2a5da7b2278c | 41 | void udpReceive( void ); |
timo_k2 | 0:2a5da7b2278c | 42 | void udpSend( void ); |
timo_k2 | 0:2a5da7b2278c | 43 | |
timo_k2 | 0:2a5da7b2278c | 44 | DigitalIn sw2(SW2); |
timo_k2 | 0:2a5da7b2278c | 45 | DigitalOut led2(LED2); |
timo_k2 | 0:2a5da7b2278c | 46 | int sw2state = 0; |
timo_k2 | 0:2a5da7b2278c | 47 | int sw2old = 1; |
timo_k2 | 0:2a5da7b2278c | 48 | |
timo_k2 | 0:2a5da7b2278c | 49 | char in_data[BUFF_SIZE]; |
timo_k2 | 0:2a5da7b2278c | 50 | int newDatagram = 0; |
timo_k2 | 0:2a5da7b2278c | 51 | time_t timeNTP = 0; |
timo_k2 | 0:2a5da7b2278c | 52 | |
timo_k2 | 0:2a5da7b2278c | 53 | using namespace std::chrono; |
timo_k2 | 0:2a5da7b2278c | 54 | Timer stopwatch; |
timo_k2 | 0:2a5da7b2278c | 55 | |
timo_k2 | 0:2a5da7b2278c | 56 | int main() { |
timo_k2 | 0:2a5da7b2278c | 57 | printf("\nNTP Client example (using Ethernet)\r\n"); |
timo_k2 | 0:2a5da7b2278c | 58 | |
timo_k2 | 0:2a5da7b2278c | 59 | //Bring up the network interface |
timo_k2 | 0:2a5da7b2278c | 60 | net.connect(); |
timo_k2 | 0:2a5da7b2278c | 61 | |
timo_k2 | 0:2a5da7b2278c | 62 | // Show network address |
timo_k2 | 0:2a5da7b2278c | 63 | SocketAddress netAddress; |
timo_k2 | 0:2a5da7b2278c | 64 | net.get_ip_address(&netAddress); |
timo_k2 | 0:2a5da7b2278c | 65 | printf("\n\n NTPClient - UDPServer IP Address: %s\n", netAddress.get_ip_address() ? netAddress.get_ip_address():"None"); |
timo_k2 | 0:2a5da7b2278c | 66 | |
timo_k2 | 0:2a5da7b2278c | 67 | // NTP client at ntp thread |
timo_k2 | 0:2a5da7b2278c | 68 | ntp_thread.start(getNTP); |
timo_k2 | 0:2a5da7b2278c | 69 | |
timo_k2 | 0:2a5da7b2278c | 70 | // UDP server |
timo_k2 | 0:2a5da7b2278c | 71 | |
timo_k2 | 0:2a5da7b2278c | 72 | serverUDP.open(&net); |
timo_k2 | 0:2a5da7b2278c | 73 | int err = serverUDP.bind(LOCAL_PORT); |
timo_k2 | 0:2a5da7b2278c | 74 | printf("Port status is: %d\n",err); |
timo_k2 | 0:2a5da7b2278c | 75 | |
timo_k2 | 0:2a5da7b2278c | 76 | recv_thread.start(udpReceive); |
timo_k2 | 0:2a5da7b2278c | 77 | printf("Listening has been started at port number %d\n", LOCAL_PORT); |
timo_k2 | 0:2a5da7b2278c | 78 | |
timo_k2 | 0:2a5da7b2278c | 79 | send_thread.start(udpSend); |
timo_k2 | 0:2a5da7b2278c | 80 | printf("Sending out demo data to port number %d", REMOTE_PORT); |
timo_k2 | 0:2a5da7b2278c | 81 | printf(" has been started.\n"); |
timo_k2 | 0:2a5da7b2278c | 82 | printf("The IP will be taken from the incoming message\n"); |
timo_k2 | 0:2a5da7b2278c | 83 | |
timo_k2 | 0:2a5da7b2278c | 84 | |
timo_k2 | 0:2a5da7b2278c | 85 | while(1) { |
timo_k2 | 0:2a5da7b2278c | 86 | sw2state = sw2.read(); |
timo_k2 | 0:2a5da7b2278c | 87 | printf( "sw2state is %d\n", sw2state); |
timo_k2 | 0:2a5da7b2278c | 88 | |
timo_k2 | 0:2a5da7b2278c | 89 | if((sw2state == 0)&&(sw2state != sw2old)) { |
timo_k2 | 0:2a5da7b2278c | 90 | led2.write(0); |
timo_k2 | 0:2a5da7b2278c | 91 | stopwatch.reset(); // reset stopwatch timer to zero |
timo_k2 | 0:2a5da7b2278c | 92 | timeNTP = getNTP(); |
timo_k2 | 0:2a5da7b2278c | 93 | stopwatch.start(); |
timo_k2 | 0:2a5da7b2278c | 94 | udpSend(); |
timo_k2 | 0:2a5da7b2278c | 95 | |
timo_k2 | 0:2a5da7b2278c | 96 | |
timo_k2 | 0:2a5da7b2278c | 97 | // Start polling for the incomening "echo" UDP datagram |
timo_k2 | 0:2a5da7b2278c | 98 | while ( stopwatch.elapsed_time().count() < 8000000 ){ |
timo_k2 | 0:2a5da7b2278c | 99 | if(newDatagram == 1){ |
timo_k2 | 0:2a5da7b2278c | 100 | char firstChar; |
timo_k2 | 0:2a5da7b2278c | 101 | firstChar = in_data[0]; |
timo_k2 | 0:2a5da7b2278c | 102 | if (firstChar == 83){ // ASCII symbol 83 = "S" |
timo_k2 | 0:2a5da7b2278c | 103 | stopwatch.stop(); |
timo_k2 | 0:2a5da7b2278c | 104 | } |
timo_k2 | 0:2a5da7b2278c | 105 | newDatagram = 0; |
timo_k2 | 0:2a5da7b2278c | 106 | } |
timo_k2 | 0:2a5da7b2278c | 107 | for (int k =0; k < BUFF_SIZE; k++){ |
timo_k2 | 0:2a5da7b2278c | 108 | in_data[k] = 0; |
timo_k2 | 0:2a5da7b2278c | 109 | } |
timo_k2 | 0:2a5da7b2278c | 110 | } |
timo_k2 | 0:2a5da7b2278c | 111 | } |
timo_k2 | 0:2a5da7b2278c | 112 | sw2old = sw2state; // Once only with pushing the button as long as you like. |
timo_k2 | 0:2a5da7b2278c | 113 | led2.write(1); |
timo_k2 | 0:2a5da7b2278c | 114 | stopwatch.stop(); // Stop the stopwatch if we did not receive the echo. |
timo_k2 | 0:2a5da7b2278c | 115 | ThisThread::sleep_for(10000ms); |
timo_k2 | 0:2a5da7b2278c | 116 | // printing for testing. Replace with writing once to a SD memory card. |
timo_k2 | 0:2a5da7b2278c | 117 | printf("Current time in day month hour.min.sec year is %s\r\n", ctime(&timeNTP)); |
timo_k2 | 0:2a5da7b2278c | 118 | printf("The time taken was %llu microseconds\n", stopwatch.elapsed_time().count()); |
timo_k2 | 0:2a5da7b2278c | 119 | |
timo_k2 | 0:2a5da7b2278c | 120 | printf("\nWe stopped sending more UDP packets to the server.\nYou can unplug your device!\n"); |
timo_k2 | 0:2a5da7b2278c | 121 | //ThisThread::sleep_for(2s); |
timo_k2 | 0:2a5da7b2278c | 122 | } |
timo_k2 | 0:2a5da7b2278c | 123 | } |
timo_k2 | 0:2a5da7b2278c | 124 | |
timo_k2 | 0:2a5da7b2278c | 125 | // The functions |
timo_k2 | 0:2a5da7b2278c | 126 | |
timo_k2 | 0:2a5da7b2278c | 127 | time_t getNTP() { |
timo_k2 | 0:2a5da7b2278c | 128 | NTPClient ntp(&net); |
timo_k2 | 0:2a5da7b2278c | 129 | ntp.set_server(ntpAddress, ntpPort); |
timo_k2 | 0:2a5da7b2278c | 130 | time_t timestamp = ntp.get_timestamp(); |
timo_k2 | 0:2a5da7b2278c | 131 | if (timestamp < 0) { |
timo_k2 | 0:2a5da7b2278c | 132 | printf("An error occurred when getting the time. Code: %u\r\n", timestamp); |
timo_k2 | 0:2a5da7b2278c | 133 | } |
timo_k2 | 0:2a5da7b2278c | 134 | else { // the printings for testing only! |
timo_k2 | 0:2a5da7b2278c | 135 | //printf("The timestamp seconds from the NTP server in\r\n 32 bit hexadecimal number is %X\r\n", timestamp); |
timo_k2 | 0:2a5da7b2278c | 136 | //printf(" decimal number is %u\r\n", timestamp); |
timo_k2 | 0:2a5da7b2278c | 137 | timestamp += (60*60*2); // GMT +2 for Finland for the winter time. |
timo_k2 | 0:2a5da7b2278c | 138 | //printf("Current time is %s\r\n", ctime(×tamp)); |
timo_k2 | 0:2a5da7b2278c | 139 | } |
timo_k2 | 0:2a5da7b2278c | 140 | return timestamp; |
timo_k2 | 0:2a5da7b2278c | 141 | } |
timo_k2 | 0:2a5da7b2278c | 142 | |
timo_k2 | 0:2a5da7b2278c | 143 | void udpReceive() |
timo_k2 | 0:2a5da7b2278c | 144 | { |
timo_k2 | 0:2a5da7b2278c | 145 | int bytes; |
timo_k2 | 0:2a5da7b2278c | 146 | while(1) { |
timo_k2 | 0:2a5da7b2278c | 147 | bytes = serverUDP.recvfrom(&clientUDP, &in_data, BUFF_SIZE); |
timo_k2 | 0:2a5da7b2278c | 148 | printf("\n"); |
timo_k2 | 0:2a5da7b2278c | 149 | printf("bytes received: %d\n",bytes); |
timo_k2 | 0:2a5da7b2278c | 150 | printf("string: %s\n",in_data); |
timo_k2 | 0:2a5da7b2278c | 151 | printf("client address: %s\n", clientUDP.get_ip_address()); |
timo_k2 | 0:2a5da7b2278c | 152 | printf("\n"); |
timo_k2 | 0:2a5da7b2278c | 153 | newDatagram = 1;; |
timo_k2 | 0:2a5da7b2278c | 154 | } |
timo_k2 | 0:2a5da7b2278c | 155 | } |
timo_k2 | 0:2a5da7b2278c | 156 | |
timo_k2 | 0:2a5da7b2278c | 157 | void udpSend() |
timo_k2 | 0:2a5da7b2278c | 158 | { |
timo_k2 | 0:2a5da7b2278c | 159 | char out_data[BUFF_SIZE]; |
timo_k2 | 0:2a5da7b2278c | 160 | |
timo_k2 | 0:2a5da7b2278c | 161 | snprintf(out_data, BUFF_SIZE, "UDP message for getting the echo" ); |
timo_k2 | 0:2a5da7b2278c | 162 | clientUDP.set_port(REMOTE_PORT); |
timo_k2 | 0:2a5da7b2278c | 163 | serverUDP.sendto(clientUDP, out_data, sizeof(out_data)); |
timo_k2 | 0:2a5da7b2278c | 164 | printf("Sending out: %s\n", out_data); |
timo_k2 | 0:2a5da7b2278c | 165 | printf("with %d" , sizeof(out_data)); |
timo_k2 | 0:2a5da7b2278c | 166 | printf(" data bytes in UDP datagram\n"); |
timo_k2 | 0:2a5da7b2278c | 167 | |
timo_k2 | 0:2a5da7b2278c | 168 | } |