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@4:4118d38b68e1, 2021-01-17 (annotated)
- Committer:
- timo_k2
- Date:
- Sun Jan 17 19:09:05 2021 +0000
- Revision:
- 4:4118d38b68e1
- Parent:
- 3:fb39c8c13b34
- Child:
- 5:837b2680bebb
The code is cleaned and comments completed.
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 | 4:4118d38b68e1 | 5 | * Round trip delay meter. |
| timo_k2 | 4:4118d38b68e1 | 6 | * Mbed OS Timer with microsecond precision used for a stopwatch. |
| timo_k2 | 0:2a5da7b2278c | 7 | * A microcontroller board with an Ethernet interface. |
| timo_k2 | 4:4118d38b68e1 | 8 | * For measuring documentation the date and time is taken from a NTP server. |
| timo_k2 | 3:fb39c8c13b34 | 9 | * An other microcontroller with "Round trip echo" will be needed. |
| timo_k2 | 0:2a5da7b2278c | 10 | * NXP FRDM-K64F used for testing. |
| timo_k2 | 0:2a5da7b2278c | 11 | * |
| timo_k2 | 4:4118d38b68e1 | 12 | * Timo Karppinen 17.1.2021 |
| timo_k2 | 0:2a5da7b2278c | 13 | ***********************************/ |
| timo_k2 | 0:2a5da7b2278c | 14 | #include "mbed.h" |
| timo_k2 | 0:2a5da7b2278c | 15 | #include "EthernetInterface.h" |
| timo_k2 | 0:2a5da7b2278c | 16 | #include "ntp-client/NTPClient.h" |
| timo_k2 | 0:2a5da7b2278c | 17 | |
| timo_k2 | 0:2a5da7b2278c | 18 | #define REMOTE_PORT 5000 |
| timo_k2 | 0:2a5da7b2278c | 19 | #define LOCAL_PORT 5001 |
| timo_k2 | 4:4118d38b68e1 | 20 | #define BUFF_SIZE 128 // test with 32, 128, 512, etc |
| timo_k2 | 0:2a5da7b2278c | 21 | |
| timo_k2 | 0:2a5da7b2278c | 22 | //Network interface |
| timo_k2 | 0:2a5da7b2278c | 23 | EthernetInterface net; |
| timo_k2 | 0:2a5da7b2278c | 24 | |
| timo_k2 | 0:2a5da7b2278c | 25 | //Threads |
| timo_k2 | 0:2a5da7b2278c | 26 | Thread recv_thread; |
| timo_k2 | 4:4118d38b68e1 | 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 | //NTP server is a time server used for delivering timing information for networks. |
| timo_k2 | 4:4118d38b68e1 | 33 | //Returns 32 bits for seconds and 32 bits for fraction of seconds. |
| timo_k2 | 0:2a5da7b2278c | 34 | //#define ntpAddress "2.pool.ntp.org" |
| timo_k2 | 0:2a5da7b2278c | 35 | #define ntpAddress "time.mikes.fi" // The VTT Mikes in Helsinki |
| timo_k2 | 0:2a5da7b2278c | 36 | #define ntpPort 123 |
| timo_k2 | 4:4118d38b68e1 | 37 | // The address and port number can be replaced with the ones for the local |
| timo_k2 | 4:4118d38b68e1 | 38 | // network NTP server. |
| timo_k2 | 0:2a5da7b2278c | 39 | |
| timo_k2 | 0:2a5da7b2278c | 40 | // Functions |
| timo_k2 | 4:4118d38b68e1 | 41 | //time_t getNTP(); |
| timo_k2 | 0:2a5da7b2278c | 42 | void udpReceive( void ); |
| timo_k2 | 0:2a5da7b2278c | 43 | void udpSend( void ); |
| timo_k2 | 0:2a5da7b2278c | 44 | |
| timo_k2 | 3:fb39c8c13b34 | 45 | DigitalIn sw2(SW2); // sw2 on K64F, button pressed = FALSE |
| timo_k2 | 4:4118d38b68e1 | 46 | DigitalOut led2(LED2); // RGB LED on K64F, FALSE = Green |
| timo_k2 | 0:2a5da7b2278c | 47 | int sw2state = 0; |
| timo_k2 | 0:2a5da7b2278c | 48 | int sw2old = 1; |
| timo_k2 | 0:2a5da7b2278c | 49 | |
| timo_k2 | 0:2a5da7b2278c | 50 | char in_data[BUFF_SIZE]; |
| timo_k2 | 0:2a5da7b2278c | 51 | int newDatagram = 0; |
| timo_k2 | 2:150dadff3c6b | 52 | int newDatagramOld = 0; |
| timo_k2 | 4:4118d38b68e1 | 53 | //time_t timeNTP = 0; |
| timo_k2 | 0:2a5da7b2278c | 54 | |
| timo_k2 | 4:4118d38b68e1 | 55 | Timer stopwatch; // Timer is an operating system class since OS 6.0 |
| timo_k2 | 2:150dadff3c6b | 56 | Timer armedFor; |
| timo_k2 | 0:2a5da7b2278c | 57 | |
| timo_k2 | 0:2a5da7b2278c | 58 | int main() { |
| timo_k2 | 3:fb39c8c13b34 | 59 | printf("\nRound trip delay in UDP messaging (using Ethernet)\n"); |
| timo_k2 | 0:2a5da7b2278c | 60 | |
| timo_k2 | 0:2a5da7b2278c | 61 | //Bring up the network interface |
| timo_k2 | 4:4118d38b68e1 | 62 | //eth.set_network(IP_Adress,GATEWAY,MASK); // leave out if using DHCP |
| timo_k2 | 4:4118d38b68e1 | 63 | net.set_network("192.168.1.10","192.168.1.1","255.255.252.0"); |
| timo_k2 | 0:2a5da7b2278c | 64 | net.connect(); |
| timo_k2 | 0:2a5da7b2278c | 65 | |
| timo_k2 | 0:2a5da7b2278c | 66 | // Show network address |
| timo_k2 | 0:2a5da7b2278c | 67 | SocketAddress netAddress; |
| timo_k2 | 0:2a5da7b2278c | 68 | net.get_ip_address(&netAddress); |
| timo_k2 | 0:2a5da7b2278c | 69 | printf("\n\n NTPClient - UDPServer IP Address: %s\n", netAddress.get_ip_address() ? netAddress.get_ip_address():"None"); |
| timo_k2 | 0:2a5da7b2278c | 70 | |
| timo_k2 | 4:4118d38b68e1 | 71 | |
| timo_k2 | 4:4118d38b68e1 | 72 | // NTP client |
| timo_k2 | 4:4118d38b68e1 | 73 | |
| timo_k2 | 4:4118d38b68e1 | 74 | //printf("Message to NTP time server...\n"); |
| timo_k2 | 4:4118d38b68e1 | 75 | //timeNTP = getNTP(); |
| timo_k2 | 4:4118d38b68e1 | 76 | //printf("Current time in day month hour.min.sec year is %s\r\n", ctime(&timeNTP)); |
| timo_k2 | 0:2a5da7b2278c | 77 | |
| timo_k2 | 0:2a5da7b2278c | 78 | // UDP server |
| timo_k2 | 0:2a5da7b2278c | 79 | |
| timo_k2 | 0:2a5da7b2278c | 80 | serverUDP.open(&net); |
| timo_k2 | 0:2a5da7b2278c | 81 | int err = serverUDP.bind(LOCAL_PORT); |
| timo_k2 | 0:2a5da7b2278c | 82 | printf("Port status is: %d\n",err); |
| timo_k2 | 0:2a5da7b2278c | 83 | |
| timo_k2 | 0:2a5da7b2278c | 84 | recv_thread.start(udpReceive); |
| timo_k2 | 0:2a5da7b2278c | 85 | printf("Listening has been started at port number %d\n", LOCAL_PORT); |
| timo_k2 | 4:4118d38b68e1 | 86 | printf("The operator for the \"Echo board\" should send a message!\n "); |
| timo_k2 | 0:2a5da7b2278c | 87 | printf("The IP will be taken from the incoming message\n"); |
| timo_k2 | 4:4118d38b68e1 | 88 | printf("Press the blue switch after receiving \"Echo server listening\"\n"); |
| timo_k2 | 0:2a5da7b2278c | 89 | |
| timo_k2 | 0:2a5da7b2278c | 90 | while(1) { |
| timo_k2 | 0:2a5da7b2278c | 91 | sw2state = sw2.read(); |
| timo_k2 | 4:4118d38b68e1 | 92 | printf( "\nsw2state is %d\n", sw2state); // Printing showing "I am alive". |
| timo_k2 | 0:2a5da7b2278c | 93 | |
| timo_k2 | 4:4118d38b68e1 | 94 | if((sw2state == 0)&&(sw2state != sw2old)) { // Note! Checking for FALSE sw |
| timo_k2 | 4:4118d38b68e1 | 95 | led2.write(1); |
| timo_k2 | 2:150dadff3c6b | 96 | armedFor.reset(); // reset timer to zero |
| timo_k2 | 0:2a5da7b2278c | 97 | stopwatch.reset(); // reset stopwatch timer to zero |
| timo_k2 | 4:4118d38b68e1 | 98 | //timeNTP = getNTP(); |
| timo_k2 | 2:150dadff3c6b | 99 | armedFor.start(); |
| timo_k2 | 4:4118d38b68e1 | 100 | //stopwatch.start(); // moved to udpSend subroutine |
| timo_k2 | 0:2a5da7b2278c | 101 | udpSend(); |
| timo_k2 | 0:2a5da7b2278c | 102 | |
| timo_k2 | 0:2a5da7b2278c | 103 | |
| timo_k2 | 4:4118d38b68e1 | 104 | // Start polling for the incoming "Echo" UDP datagram |
| timo_k2 | 2:150dadff3c6b | 105 | while ( armedFor.elapsed_time().count() < 8000000 ){ |
| timo_k2 | 2:150dadff3c6b | 106 | if((newDatagram == 1)&&(newDatagram != newDatagramOld)){ |
| timo_k2 | 4:4118d38b68e1 | 107 | stopwatch.stop(); |
| timo_k2 | 2:150dadff3c6b | 108 | char firstChar; |
| timo_k2 | 2:150dadff3c6b | 109 | firstChar = in_data[0]; |
| timo_k2 | 4:4118d38b68e1 | 110 | printf( "firstChar: %s\n", &firstChar); |
| timo_k2 | 2:150dadff3c6b | 111 | for (int k =0; k < BUFF_SIZE; k++){ |
| timo_k2 | 2:150dadff3c6b | 112 | in_data[k] = 0; |
| timo_k2 | 4:4118d38b68e1 | 113 | } |
| timo_k2 | 0:2a5da7b2278c | 114 | } |
| timo_k2 | 4:4118d38b68e1 | 115 | newDatagramOld = newDatagram; //Reading the stopwatch once only |
| timo_k2 | 4:4118d38b68e1 | 116 | newDatagram = 0; |
| timo_k2 | 0:2a5da7b2278c | 117 | } |
| timo_k2 | 2:150dadff3c6b | 118 | |
| timo_k2 | 2:150dadff3c6b | 119 | // printing for testing. Replace with writing once to a SD memory card. |
| timo_k2 | 4:4118d38b68e1 | 120 | //printf("Measured at ( day month hour.min.sec year ) %s\r\n", ctime(&timeNTP)); |
| timo_k2 | 2:150dadff3c6b | 121 | printf("The time taken was %llu microseconds\n", stopwatch.elapsed_time().count()); |
| timo_k2 | 4:4118d38b68e1 | 122 | |
| timo_k2 | 0:2a5da7b2278c | 123 | } |
| timo_k2 | 0:2a5da7b2278c | 124 | sw2old = sw2state; // Once only with pushing the button as long as you like. |
| timo_k2 | 4:4118d38b68e1 | 125 | led2.write(0); |
| timo_k2 | 2:150dadff3c6b | 126 | armedFor.stop(); |
| timo_k2 | 0:2a5da7b2278c | 127 | stopwatch.stop(); // Stop the stopwatch if we did not receive the echo. |
| timo_k2 | 0:2a5da7b2278c | 128 | |
| timo_k2 | 4:4118d38b68e1 | 129 | ThisThread::sleep_for(1000ms); |
| timo_k2 | 0:2a5da7b2278c | 130 | } |
| timo_k2 | 0:2a5da7b2278c | 131 | } |
| timo_k2 | 0:2a5da7b2278c | 132 | |
| timo_k2 | 0:2a5da7b2278c | 133 | // The functions |
| timo_k2 | 0:2a5da7b2278c | 134 | |
| timo_k2 | 0:2a5da7b2278c | 135 | time_t getNTP() { |
| timo_k2 | 0:2a5da7b2278c | 136 | NTPClient ntp(&net); |
| timo_k2 | 0:2a5da7b2278c | 137 | ntp.set_server(ntpAddress, ntpPort); |
| timo_k2 | 0:2a5da7b2278c | 138 | time_t timestamp = ntp.get_timestamp(); |
| timo_k2 | 0:2a5da7b2278c | 139 | if (timestamp < 0) { |
| timo_k2 | 0:2a5da7b2278c | 140 | printf("An error occurred when getting the time. Code: %u\r\n", timestamp); |
| timo_k2 | 0:2a5da7b2278c | 141 | } |
| timo_k2 | 0:2a5da7b2278c | 142 | else { // the printings for testing only! |
| timo_k2 | 4:4118d38b68e1 | 143 | printf("The timestamp seconds from the NTP server in\r\n 32 bit hexadecimal number is %X\r\n", timestamp); |
| timo_k2 | 4:4118d38b68e1 | 144 | printf(" decimal number is %u\r\n", timestamp); |
| timo_k2 | 0:2a5da7b2278c | 145 | timestamp += (60*60*2); // GMT +2 for Finland for the winter time. |
| timo_k2 | 4:4118d38b68e1 | 146 | printf("Current time is %s\r\n", ctime(×tamp)); |
| timo_k2 | 0:2a5da7b2278c | 147 | } |
| timo_k2 | 0:2a5da7b2278c | 148 | return timestamp; |
| timo_k2 | 0:2a5da7b2278c | 149 | } |
| timo_k2 | 0:2a5da7b2278c | 150 | |
| timo_k2 | 0:2a5da7b2278c | 151 | void udpReceive() |
| timo_k2 | 0:2a5da7b2278c | 152 | { |
| timo_k2 | 0:2a5da7b2278c | 153 | int bytes; |
| timo_k2 | 0:2a5da7b2278c | 154 | while(1) { |
| timo_k2 | 0:2a5da7b2278c | 155 | bytes = serverUDP.recvfrom(&clientUDP, &in_data, BUFF_SIZE); |
| timo_k2 | 3:fb39c8c13b34 | 156 | newDatagram = 1; // set this before using time for printing |
| timo_k2 | 4:4118d38b68e1 | 157 | ThisThread::sleep_for(400ms); // waiting for the print buffer |
| timo_k2 | 0:2a5da7b2278c | 158 | printf("\n"); |
| timo_k2 | 0:2a5da7b2278c | 159 | printf("bytes received: %d\n",bytes); |
| timo_k2 | 0:2a5da7b2278c | 160 | printf("string: %s\n",in_data); |
| timo_k2 | 0:2a5da7b2278c | 161 | printf("client address: %s\n", clientUDP.get_ip_address()); |
| timo_k2 | 0:2a5da7b2278c | 162 | printf("\n"); |
| timo_k2 | 3:fb39c8c13b34 | 163 | |
| timo_k2 | 0:2a5da7b2278c | 164 | } |
| timo_k2 | 0:2a5da7b2278c | 165 | } |
| timo_k2 | 0:2a5da7b2278c | 166 | |
| timo_k2 | 0:2a5da7b2278c | 167 | void udpSend() |
| timo_k2 | 0:2a5da7b2278c | 168 | { |
| timo_k2 | 0:2a5da7b2278c | 169 | char out_data[BUFF_SIZE]; |
| timo_k2 | 0:2a5da7b2278c | 170 | |
| timo_k2 | 2:150dadff3c6b | 171 | snprintf(out_data, BUFF_SIZE, "UDP message for getting the Echo" ); |
| timo_k2 | 0:2a5da7b2278c | 172 | printf("Sending out: %s\n", out_data); |
| timo_k2 | 0:2a5da7b2278c | 173 | printf("with %d" , sizeof(out_data)); |
| timo_k2 | 0:2a5da7b2278c | 174 | printf(" data bytes in UDP datagram\n"); |
| timo_k2 | 4:4118d38b68e1 | 175 | clientUDP.set_port(REMOTE_PORT); |
| timo_k2 | 4:4118d38b68e1 | 176 | stopwatch.start(); // starting the stopwatch after preparations are done |
| timo_k2 | 4:4118d38b68e1 | 177 | serverUDP.sendto(clientUDP, out_data, sizeof(out_data)); |
| timo_k2 | 4:4118d38b68e1 | 178 | } |