Timo Karppinen / Mbed OS UDP_RoundTripDelay_OS6_K64F

Dependencies:   ntp-client

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?

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 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(&timestamp));
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 }