Timo Karppinen / Mbed OS UDP_RoundTripEcho_OS6_H743ZI
Committer:
timo_k2
Date:
Mon Nov 23 12:48:48 2020 +0000
Revision:
5:fb39c8c13b34
Parent:
2:150dadff3c6b
Child:
6:11edc8f9d870
Testing with the UDP_RoundTripEcho 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 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 5:fb39c8c13b34 7 * An other microcontroller with "Round trip 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 5:fb39c8c13b34 44 DigitalIn sw2(SW2); // sw2 on K64F, button pressed = FALSE
timo_k2 5:fb39c8c13b34 45 DigitalOut led2(LED2); // RGB LED green on K64F
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 2:150dadff3c6b 51 int newDatagramOld = 0;
timo_k2 0:2a5da7b2278c 52 time_t timeNTP = 0;
timo_k2 0:2a5da7b2278c 53
timo_k2 1:961861d73841 54 //using namespace std::chrono;
timo_k2 0:2a5da7b2278c 55 Timer stopwatch;
timo_k2 2:150dadff3c6b 56 Timer armedFor;
timo_k2 0:2a5da7b2278c 57
timo_k2 0:2a5da7b2278c 58 int main() {
timo_k2 5: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 0:2a5da7b2278c 62 net.connect();
timo_k2 0:2a5da7b2278c 63
timo_k2 0:2a5da7b2278c 64 // Show network address
timo_k2 0:2a5da7b2278c 65 SocketAddress netAddress;
timo_k2 0:2a5da7b2278c 66 net.get_ip_address(&netAddress);
timo_k2 0:2a5da7b2278c 67 printf("\n\n NTPClient - UDPServer IP Address: %s\n", netAddress.get_ip_address() ? netAddress.get_ip_address():"None");
timo_k2 0:2a5da7b2278c 68
timo_k2 0:2a5da7b2278c 69 // NTP client at ntp thread
timo_k2 0:2a5da7b2278c 70 ntp_thread.start(getNTP);
timo_k2 0:2a5da7b2278c 71
timo_k2 0:2a5da7b2278c 72 // UDP server
timo_k2 0:2a5da7b2278c 73
timo_k2 0:2a5da7b2278c 74 serverUDP.open(&net);
timo_k2 0:2a5da7b2278c 75 int err = serverUDP.bind(LOCAL_PORT);
timo_k2 0:2a5da7b2278c 76 printf("Port status is: %d\n",err);
timo_k2 0:2a5da7b2278c 77
timo_k2 0:2a5da7b2278c 78 recv_thread.start(udpReceive);
timo_k2 0:2a5da7b2278c 79 printf("Listening has been started at port number %d\n", LOCAL_PORT);
timo_k2 0:2a5da7b2278c 80
timo_k2 0:2a5da7b2278c 81 send_thread.start(udpSend);
timo_k2 0:2a5da7b2278c 82 printf("Sending out demo data to port number %d", REMOTE_PORT);
timo_k2 0:2a5da7b2278c 83 printf(" has been started.\n");
timo_k2 0:2a5da7b2278c 84 printf("The IP will be taken from the incoming message\n");
timo_k2 0:2a5da7b2278c 85
timo_k2 0:2a5da7b2278c 86
timo_k2 0:2a5da7b2278c 87 while(1) {
timo_k2 0:2a5da7b2278c 88 sw2state = sw2.read();
timo_k2 5:fb39c8c13b34 89 printf( "\nsw2state is %d\n", sw2state);
timo_k2 0:2a5da7b2278c 90
timo_k2 0:2a5da7b2278c 91 if((sw2state == 0)&&(sw2state != sw2old)) {
timo_k2 0:2a5da7b2278c 92 led2.write(0);
timo_k2 2:150dadff3c6b 93 armedFor.reset(); // reset timer to zero
timo_k2 0:2a5da7b2278c 94 stopwatch.reset(); // reset stopwatch timer to zero
timo_k2 0:2a5da7b2278c 95 timeNTP = getNTP();
timo_k2 2:150dadff3c6b 96 armedFor.start();
timo_k2 0:2a5da7b2278c 97 stopwatch.start();
timo_k2 0:2a5da7b2278c 98 udpSend();
timo_k2 0:2a5da7b2278c 99
timo_k2 0:2a5da7b2278c 100
timo_k2 2:150dadff3c6b 101 // Start polling for the incomening "Echo" UDP datagram
timo_k2 2:150dadff3c6b 102 while ( armedFor.elapsed_time().count() < 8000000 ){
timo_k2 2:150dadff3c6b 103 if((newDatagram == 1)&&(newDatagram != newDatagramOld)){
timo_k2 2:150dadff3c6b 104 char firstChar;
timo_k2 2:150dadff3c6b 105 firstChar = in_data[0];
timo_k2 2:150dadff3c6b 106 if (firstChar == 69){ // ASCII symbol 69 = "E" for the Echo
timo_k2 2:150dadff3c6b 107 stopwatch.stop();
timo_k2 2:150dadff3c6b 108 printf( "firstChar: %s\n", &firstChar);
timo_k2 2:150dadff3c6b 109 }
timo_k2 2:150dadff3c6b 110 for (int k =0; k < BUFF_SIZE; k++){
timo_k2 2:150dadff3c6b 111 in_data[k] = 0;
timo_k2 2:150dadff3c6b 112 }
timo_k2 0:2a5da7b2278c 113 }
timo_k2 2:150dadff3c6b 114 newDatagramOld = newDatagram; //Reading the stopwatch once only
timo_k2 2:150dadff3c6b 115
timo_k2 0:2a5da7b2278c 116 }
timo_k2 2:150dadff3c6b 117
timo_k2 2:150dadff3c6b 118 // printing for testing. Replace with writing once to a SD memory card.
timo_k2 2:150dadff3c6b 119 printf("Current time in day month hour.min.sec year is %s\r\n", ctime(&timeNTP));
timo_k2 2:150dadff3c6b 120 printf("The time taken was %llu microseconds\n", stopwatch.elapsed_time().count());
timo_k2 0:2a5da7b2278c 121 }
timo_k2 2:150dadff3c6b 122 newDatagram = 0;
timo_k2 0:2a5da7b2278c 123 sw2old = sw2state; // Once only with pushing the button as long as you like.
timo_k2 0:2a5da7b2278c 124 led2.write(1);
timo_k2 2:150dadff3c6b 125 armedFor.stop();
timo_k2 0:2a5da7b2278c 126 stopwatch.stop(); // Stop the stopwatch if we did not receive the echo.
timo_k2 0:2a5da7b2278c 127
timo_k2 0:2a5da7b2278c 128 printf("\nWe stopped sending more UDP packets to the server.\nYou can unplug your device!\n");
timo_k2 2:150dadff3c6b 129 ThisThread::sleep_for(4000ms);
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 0:2a5da7b2278c 143 //printf("The timestamp seconds from the NTP server in\r\n 32 bit hexadecimal number is %X\r\n", timestamp);
timo_k2 0:2a5da7b2278c 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 0:2a5da7b2278c 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 5:fb39c8c13b34 156 newDatagram = 1; // set this before using time for printing
timo_k2 0:2a5da7b2278c 157 printf("\n");
timo_k2 0:2a5da7b2278c 158 printf("bytes received: %d\n",bytes);
timo_k2 0:2a5da7b2278c 159 printf("string: %s\n",in_data);
timo_k2 0:2a5da7b2278c 160 printf("client address: %s\n", clientUDP.get_ip_address());
timo_k2 0:2a5da7b2278c 161 printf("\n");
timo_k2 5:fb39c8c13b34 162
timo_k2 0:2a5da7b2278c 163 }
timo_k2 0:2a5da7b2278c 164 }
timo_k2 0:2a5da7b2278c 165
timo_k2 0:2a5da7b2278c 166 void udpSend()
timo_k2 0:2a5da7b2278c 167 {
timo_k2 0:2a5da7b2278c 168 char out_data[BUFF_SIZE];
timo_k2 0:2a5da7b2278c 169
timo_k2 2:150dadff3c6b 170 snprintf(out_data, BUFF_SIZE, "UDP message for getting the Echo" );
timo_k2 0:2a5da7b2278c 171 clientUDP.set_port(REMOTE_PORT);
timo_k2 0:2a5da7b2278c 172 serverUDP.sendto(clientUDP, out_data, sizeof(out_data));
timo_k2 0:2a5da7b2278c 173 printf("Sending out: %s\n", out_data);
timo_k2 0:2a5da7b2278c 174 printf("with %d" , sizeof(out_data));
timo_k2 0:2a5da7b2278c 175 printf(" data bytes in UDP datagram\n");
timo_k2 0:2a5da7b2278c 176
timo_k2 0:2a5da7b2278c 177 }