Timo Karppinen / Mbed OS UDP_RoundTripDelay_OS6_K64F

Dependencies:   ntp-client

Committer:
timo_k2
Date:
Sat Apr 24 15:28:36 2021 +0000
Revision:
5:837b2680bebb
Parent:
4:4118d38b68e1
Sends a series of four UDP messages with different number of bytes. For each one prints the round trip delay. The number of bytes has no effect on the round trip delay, the latency.

Who changed what in which revision?

UserRevisionLine numberNew 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 5:837b2680bebb 12 * Timo Karppinen 24.4.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 5:837b2680bebb 20 #define BUFF_SIZE 512 // test with 32, 128, 512
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 5:837b2680bebb 29 SocketAddress clientUDP; // Client on remote device. IP address from incoming message.
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 5:837b2680bebb 43 void udpSend( int ii );
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 5:837b2680bebb 50 char in_data[BUFF_SIZE]; // 512 taken as max message 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 5:837b2680bebb 62 //eth.set_network(IP_Adress,MASK, GATEWAY); // leave out if using DHCP
timo_k2 5:837b2680bebb 63 net.set_network("192.168.1.10","255.255.252.0","192.168.1.1");
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 5:837b2680bebb 92 printf( "\nsw2 %d - Push for sending Echo Request\n", sw2state);
timo_k2 0:2a5da7b2278c 93
timo_k2 4:4118d38b68e1 94 if((sw2state == 0)&&(sw2state != sw2old)) { // Note! Checking for FALSE sw
timo_k2 5:837b2680bebb 95 led2.write(1);
timo_k2 5:837b2680bebb 96 for ( int i=0; i < 5; ++i){
timo_k2 2:150dadff3c6b 97 armedFor.reset(); // reset timer to zero
timo_k2 0:2a5da7b2278c 98 stopwatch.reset(); // reset stopwatch timer to zero
timo_k2 4:4118d38b68e1 99 //timeNTP = getNTP();
timo_k2 5:837b2680bebb 100 ThisThread::sleep_for(10ms); //time for resetting
timo_k2 2:150dadff3c6b 101 armedFor.start();
timo_k2 4:4118d38b68e1 102 //stopwatch.start(); // moved to udpSend subroutine
timo_k2 5:837b2680bebb 103 udpSend(i);
timo_k2 0:2a5da7b2278c 104
timo_k2 0:2a5da7b2278c 105
timo_k2 4:4118d38b68e1 106 // Start polling for the incoming "Echo" UDP datagram
timo_k2 5:837b2680bebb 107 while ( armedFor.elapsed_time().count() <2000000 ){
timo_k2 2:150dadff3c6b 108 if((newDatagram == 1)&&(newDatagram != newDatagramOld)){
timo_k2 4:4118d38b68e1 109 stopwatch.stop();
timo_k2 2:150dadff3c6b 110 char firstChar;
timo_k2 2:150dadff3c6b 111 firstChar = in_data[0];
timo_k2 5:837b2680bebb 112 printf( "\nfirstChar: %s\n", &firstChar);
timo_k2 5:837b2680bebb 113 ThisThread::sleep_for(120ms); // waiting for print buffer, 100 ms was just too short
timo_k2 2:150dadff3c6b 114 for (int k =0; k < BUFF_SIZE; k++){
timo_k2 2:150dadff3c6b 115 in_data[k] = 0;
timo_k2 4:4118d38b68e1 116 }
timo_k2 5:837b2680bebb 117 // printing for testing. Replace with writing once to a SD memory card.
timo_k2 5:837b2680bebb 118 //printf("Measured at ( day month hour.min.sec year ) %s\r\n", ctime(&timeNTP));
timo_k2 5:837b2680bebb 119 printf("The time taken was %llu microseconds\n", stopwatch.elapsed_time().count());
timo_k2 5:837b2680bebb 120 } // if new datagram
timo_k2 4:4118d38b68e1 121 newDatagramOld = newDatagram; //Reading the stopwatch once only
timo_k2 5:837b2680bebb 122 newDatagram = 0;
timo_k2 5:837b2680bebb 123 } // while armed
timo_k2 5:837b2680bebb 124 ThisThread::sleep_for(70ms); // Delay of 10ms + 120ms + 70ms = 200ms
timo_k2 5:837b2680bebb 125 } //for i loop
timo_k2 2:150dadff3c6b 126
timo_k2 2:150dadff3c6b 127 // printing for testing. Replace with writing once to a SD memory card.
timo_k2 4:4118d38b68e1 128 //printf("Measured at ( day month hour.min.sec year ) %s\r\n", ctime(&timeNTP));
timo_k2 5:837b2680bebb 129 //printf("The time taken was %llu microseconds\n", stopwatch.elapsed_time().count());
timo_k2 5:837b2680bebb 130 } // if sw2
timo_k2 0:2a5da7b2278c 131 sw2old = sw2state; // Once only with pushing the button as long as you like.
timo_k2 4:4118d38b68e1 132 led2.write(0);
timo_k2 2:150dadff3c6b 133 armedFor.stop();
timo_k2 0:2a5da7b2278c 134 stopwatch.stop(); // Stop the stopwatch if we did not receive the echo.
timo_k2 0:2a5da7b2278c 135
timo_k2 4:4118d38b68e1 136 ThisThread::sleep_for(1000ms);
timo_k2 5:837b2680bebb 137 } // while loop
timo_k2 5:837b2680bebb 138 } // main
timo_k2 0:2a5da7b2278c 139
timo_k2 0:2a5da7b2278c 140 // The functions
timo_k2 0:2a5da7b2278c 141
timo_k2 0:2a5da7b2278c 142 time_t getNTP() {
timo_k2 0:2a5da7b2278c 143 NTPClient ntp(&net);
timo_k2 0:2a5da7b2278c 144 ntp.set_server(ntpAddress, ntpPort);
timo_k2 0:2a5da7b2278c 145 time_t timestamp = ntp.get_timestamp();
timo_k2 0:2a5da7b2278c 146 if (timestamp < 0) {
timo_k2 0:2a5da7b2278c 147 printf("An error occurred when getting the time. Code: %u\r\n", timestamp);
timo_k2 0:2a5da7b2278c 148 }
timo_k2 0:2a5da7b2278c 149 else { // the printings for testing only!
timo_k2 4:4118d38b68e1 150 printf("The timestamp seconds from the NTP server in\r\n 32 bit hexadecimal number is %X\r\n", timestamp);
timo_k2 4:4118d38b68e1 151 printf(" decimal number is %u\r\n", timestamp);
timo_k2 0:2a5da7b2278c 152 timestamp += (60*60*2); // GMT +2 for Finland for the winter time.
timo_k2 4:4118d38b68e1 153 printf("Current time is %s\r\n", ctime(&timestamp));
timo_k2 0:2a5da7b2278c 154 }
timo_k2 0:2a5da7b2278c 155 return timestamp;
timo_k2 0:2a5da7b2278c 156 }
timo_k2 0:2a5da7b2278c 157
timo_k2 0:2a5da7b2278c 158 void udpReceive()
timo_k2 0:2a5da7b2278c 159 {
timo_k2 0:2a5da7b2278c 160 int bytes;
timo_k2 0:2a5da7b2278c 161 while(1) {
timo_k2 5:837b2680bebb 162 bytes = serverUDP.recvfrom(&clientUDP, &in_data, 512); // 512 as largest possible
timo_k2 3:fb39c8c13b34 163 newDatagram = 1; // set this before using time for printing
timo_k2 5:837b2680bebb 164 ThisThread::sleep_for(50ms); // waiting for the print buffer
timo_k2 0:2a5da7b2278c 165 printf("bytes received: %d\n",bytes);
timo_k2 0:2a5da7b2278c 166 printf("string: %s\n",in_data);
timo_k2 0:2a5da7b2278c 167 printf("client address: %s\n", clientUDP.get_ip_address());
timo_k2 0:2a5da7b2278c 168 }
timo_k2 0:2a5da7b2278c 169 }
timo_k2 0:2a5da7b2278c 170
timo_k2 5:837b2680bebb 171 void udpSend(int ii)
timo_k2 0:2a5da7b2278c 172 {
timo_k2 5:837b2680bebb 173 int BUFF_SIZE_NOW;
timo_k2 5:837b2680bebb 174 switch(ii){
timo_k2 5:837b2680bebb 175 case 0:
timo_k2 5:837b2680bebb 176 BUFF_SIZE_NOW = BUFF_SIZE/16;
timo_k2 5:837b2680bebb 177 break;
timo_k2 5:837b2680bebb 178 case 1:
timo_k2 5:837b2680bebb 179 BUFF_SIZE_NOW = BUFF_SIZE/8;
timo_k2 5:837b2680bebb 180 break;
timo_k2 5:837b2680bebb 181 case 2:
timo_k2 5:837b2680bebb 182 BUFF_SIZE_NOW = BUFF_SIZE/4;
timo_k2 5:837b2680bebb 183 break;
timo_k2 5:837b2680bebb 184 case 3:
timo_k2 5:837b2680bebb 185 BUFF_SIZE_NOW = BUFF_SIZE/2;
timo_k2 5:837b2680bebb 186 break;
timo_k2 5:837b2680bebb 187 case 4:
timo_k2 5:837b2680bebb 188 BUFF_SIZE_NOW = BUFF_SIZE;
timo_k2 5:837b2680bebb 189 break;
timo_k2 5:837b2680bebb 190 }
timo_k2 5:837b2680bebb 191 char out_data[BUFF_SIZE_NOW];
timo_k2 5:837b2680bebb 192 snprintf(out_data, BUFF_SIZE_NOW, "UDP message for getting the Echo" );
timo_k2 5:837b2680bebb 193 printf("\nSending out: %s\n", out_data);
timo_k2 0:2a5da7b2278c 194 printf("with %d" , sizeof(out_data));
timo_k2 0:2a5da7b2278c 195 printf(" data bytes in UDP datagram\n");
timo_k2 4:4118d38b68e1 196 clientUDP.set_port(REMOTE_PORT);
timo_k2 4:4118d38b68e1 197 stopwatch.start(); // starting the stopwatch after preparations are done
timo_k2 4:4118d38b68e1 198 serverUDP.sendto(clientUDP, out_data, sizeof(out_data));
timo_k2 4:4118d38b68e1 199 }