Timo Karppinen / Mbed OS UDP_RoundTripEcho_OS6_H743ZI

main.cpp

Committer:
timo_k2
Date:
2020-11-20
Revision:
0:2a5da7b2278c
Child:
1:961861d73841

File content as of revision 0:2a5da7b2278c:

/*
 * Copyright (c) 2006-2020 Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 ***********************************
 * Round trip delay meter. Date and time is taken from a NTP server. 
 * A microcontroller board with an Ethernet interface.
 * An other microcontroller with "Round trip delay echo" will be needed. 
 * NXP FRDM-K64F used for testing.
 *   
 * Timo Karppinen 20.11.2020
 ***********************************/
#include "mbed.h"
#include "EthernetInterface.h"
#include "ntp-client/NTPClient.h"

#define REMOTE_PORT 5000
#define LOCAL_PORT 5001
#define BUFF_SIZE 128

//Network interface
EthernetInterface net;

//Threads
    Thread ntp_thread;
    Thread recv_thread;
    Thread send_thread; 
    
// UDP
SocketAddress clientUDP;  // Client on remote device
UDPSocket serverUDP;   // UDP server in this device


//NTP server is a time server used for delivering timing information for networks.
// Returns 32 bits for seconds and 32 bits for fraction of seconds. 
//#define ntpAddress "2.pool.ntp.org"
#define ntpAddress "time.mikes.fi"  // The VTT Mikes in Helsinki
#define ntpPort 123

// Functions
time_t getNTP();
void udpReceive( void );
void udpSend( void );

DigitalIn sw2(SW2);
DigitalOut led2(LED2);
int sw2state = 0;
int sw2old = 1;

char in_data[BUFF_SIZE];
int newDatagram = 0;
time_t timeNTP = 0;

using namespace std::chrono;
Timer stopwatch;
    
int main() {
    printf("\nNTP Client example (using Ethernet)\r\n");
    
    //Bring up the network interface
    net.connect();
    
    // Show network address
    SocketAddress netAddress;
    net.get_ip_address(&netAddress);
    printf("\n\n NTPClient - UDPServer IP Address: %s\n", netAddress.get_ip_address() ? netAddress.get_ip_address():"None");
    
    // NTP client at ntp thread
    ntp_thread.start(getNTP);
    
    // UDP server 
    
    serverUDP.open(&net);
    int err = serverUDP.bind(LOCAL_PORT);
    printf("Port status is: %d\n",err);
    
    recv_thread.start(udpReceive);
    printf("Listening has been started at port number %d\n", LOCAL_PORT);
    
    send_thread.start(udpSend);
    printf("Sending out demo data to port number %d", REMOTE_PORT);
    printf(" has been started.\n");
    printf("The IP will be taken from the incoming message\n");
  

    while(1) {  
    sw2state = sw2.read();
    printf( "sw2state is  %d\n", sw2state);
    
    if((sw2state == 0)&&(sw2state != sw2old)) {
        led2.write(0);
        stopwatch.reset();   // reset stopwatch timer to zero
        timeNTP = getNTP();
        stopwatch.start();
        udpSend();
        
    
        // Start polling for the incomening "echo" UDP datagram   
        while ( stopwatch.elapsed_time().count() < 8000000 ){
        if(newDatagram == 1){
            char firstChar;
            firstChar = in_data[0];
            if (firstChar == 83){    // ASCII symbol 83 = "S" 
                stopwatch.stop();
                }
            newDatagram = 0;
            }
        for (int k =0; k < BUFF_SIZE; k++){
            in_data[k] = 0;
            }
        }
    }
    sw2old = sw2state; // Once only with pushing the button as long as you like.
    led2.write(1);
    stopwatch.stop();  // Stop the stopwatch if we did not receive the echo.
    ThisThread::sleep_for(10000ms);
    // printing for testing. Replace with writing once to a SD memory card.
    printf("Current time in day month hour.min.sec year is  %s\r\n", ctime(&timeNTP));
    printf("The time taken was %llu microseconds\n", stopwatch.elapsed_time().count());
    
    printf("\nWe stopped sending more UDP packets to the server.\nYou can unplug your device!\n");
    //ThisThread::sleep_for(2s);
    }
}

// The functions
  
time_t getNTP() {
    NTPClient ntp(&net);
    ntp.set_server(ntpAddress, ntpPort);
    time_t timestamp = ntp.get_timestamp();
    if (timestamp < 0) {
        printf("An error occurred when getting the time. Code: %u\r\n", timestamp);
    } 
    else {     // the printings for testing only!
        //printf("The timestamp seconds from the NTP server in\r\n  32 bit hexadecimal number is %X\r\n", timestamp);
        //printf("  decimal number is %u\r\n", timestamp);
        timestamp += (60*60*2);  //  GMT +2  for Finland for the winter time.
        //printf("Current time is %s\r\n", ctime(&timestamp));
    } 
    return timestamp; 
}
    
void udpReceive()
{
    int bytes;
    while(1) {
        bytes = serverUDP.recvfrom(&clientUDP, &in_data, BUFF_SIZE);
        printf("\n");
        printf("bytes received: %d\n",bytes);
        printf("string: %s\n",in_data);
        printf("client address: %s\n", clientUDP.get_ip_address());
        printf("\n");
        newDatagram = 1;;
        }
}

void udpSend()
{
        char out_data[BUFF_SIZE];
        
        snprintf(out_data, BUFF_SIZE, "UDP message for getting the echo" );
        clientUDP.set_port(REMOTE_PORT);
        serverUDP.sendto(clientUDP, out_data, sizeof(out_data));
        printf("Sending out: %s\n", out_data);
        printf("with %d" , sizeof(out_data));
        printf(" data bytes in UDP datagram\n");
        
}