Timo Karppinen / Mbed OS UDP_RoundTripEcho_OS6_H743ZI
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?

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