yuki makura / Mbed 2 deprecated mbed_driver_ver_0_3_0

Dependencies:   EthernetInterface mbed-rtos mbed

Fork of mbed_driver_ver_0_2_0 by yuki makura

main.cpp

Committer:
yukisega
Date:
2018-09-28
Revision:
0:c490b05d753e
Child:
1:b1c3d31236f8

File content as of revision 0:c490b05d753e:


/**

    @file main.cpp
    @brief Thrust Motor Controller 2018 edition ver. 0.2.0
    \mainpage Thrust Motor Controller 2018 edition
    TCPSocket経由でスラスターを制御するプログラムです。
    DHCPサーバとしては機能しません。
    固定IPを割り振る必要があります。
    \htmlonly
    <font color="red">mbedの電源を投入する前に,あらかじめクライアントのコンピュータを接続しておく必要があります。</font>
    \endhtmlonly
    @sa ethernet_thread
    @author Wada Suisei   Copyright (C) 2018 - All rights reserved          
    @author modified by yukimakura

    @date LastModified:2018 July 2 
*/

/*** Including Libraries ***/
#include "mbed.h"
#include "EthernetInterface.h"
#include "rtos.h"


/**
 * @brief PWMの周期(秒)
 * 
 */
#define PWM_FREQ 0.01 

/**
 * @brief 接続のタイムアウト(ミリ秒)
 * 
 */
#define TIMEOUT_MS 3000 


/*** Network Information ***/
///myIpAddrこのモータドライバのIPアドレスを入力
const char myIpAddr[] = "192.168.39.10";   
/// myPortこのプログラムで使用するポートを入力  
const uint16_t myPort = 50000;
/// NetMask このモータドライバ用のネットマスクを入力 
const char NetMask[] = "255.255.255.0"; 
/// Gateway このモータドライバ用のゲートウェイを入力 
const char Gateway[] = "192.168.39.1";


/*** Instantiation ***/
//Interruption
Timeout linkdown_catcher;
Timer Timeout_timer;

//! PWM信号の差動出力ピンを指定
PwmOut motor_P(p26);
//! PWM信号の差動出力ピンを指定
PwmOut motor_N(p25);

double pipe_pwmduty;


//Network
DigitalOut EthRecv_LED(LED1);
DigitalOut EthSend_LED(LED2);
DigitalOut Ethconnect_LED(LED4);
EthernetInterface eth;





/**
 * 
 * @brief コネクション時に重大なエラーが発生した時に呼び出されます
 * 
 * pwmをduty比それぞれ50%にしてから、
 * mbedOSに−1を返します。
 * \htmlonly  
 * <font color="red">こうなった場合は再起動が必要です。</font>  
 * \endhtmlonly
 * 
 * 
 */
void INT_TIMER_LINKDOWN_CATCHER(void){
    pipe_pwmduty = 0.0;
    motor_P = 0.5;
    motor_N = 0.5;
    exit(-1);
}



/**
 * 
 * @brief TCP/IPソケットでコミュニケーションかつデータ受信を行います
 * 
 *  RTOSによって管理されているスレッドで,
 * TCPSocketの確立前にデータリンク層あたりでコネクションされていないと
 * mbedOSに−1を返します。
 * \htmlonly  
 * <font color="red">mbedの電源を投入する前に,あらかじめクライアントのコンピュータを接続しておく必要があります。</font>  
 * \endhtmlonly
 */
void ethernet_thread(void){
    //Declaration of Local Variables
    char in_buf[8];
    char out_buf[10];
    
    //Initializing Network
    SocketAddress SockAddr_Receive;
    eth.set_network(myIpAddr, NetMask, Gateway);
    if(0 != eth.connect()){
        exit(-1);
    }
    TCPServer srv;
    TCPSocket sock;
    srv.open(&eth);
    srv.bind(eth.get_ip_address(), myPort);
    while (true) {

        printf("waiting for client\r\n");
        /* Can handle 5 simultaneous connections */
        int err= srv.listen(1);
        printf("server listening error : %d\r\n",err);

        Timeout_timer.start();
        while(1){
            /* Initialize variables */
            memset(in_buf, '\0', sizeof(in_buf));
            memset(out_buf, '\0', sizeof(out_buf));
            printf("waiting for client connection\r\n");
            err = srv.accept(&sock, &SockAddr_Receive);
            Timeout_timer.reset();
            Ethconnect_LED = 1;
            //https://docs.mbed.com/docs/vignesh/en/latest/api/group__netsocket.html#ga67a8f07758d2ee2a1809293fa52bdf14
            switch(err){
                case NSAPI_ERROR_OK:
                    printf("client connected :%s:%d\r\n", SockAddr_Receive.get_ip_address(), SockAddr_Receive.get_port());
                    while(1){
                        int len = sock.recv(in_buf, sizeof(in_buf));
                        if(Timeout_timer.read_ms() < TIMEOUT_MS){

                            if(len > 0){
                                Timeout_timer.reset();
                                in_buf[len] = '\0';
                                //Get data
                                EthRecv_LED = !EthRecv_LED;
                                memcpy(&pipe_pwmduty, &in_buf[0], 8);
                                

                                /* Send Data */
                                //sock.send(out_buf, sizeof(out_buf));
                                EthSend_LED = !EthSend_LED;
                            }
                        }
                        else{//TIMEOUT
                            printf("Time_out (over %d ms)\n",TIMEOUT_MS);
                            memset(in_buf, '\0', sizeof(in_buf));
                            pipe_pwmduty = 0.0;
                            motor_P = 0.5;
                            motor_N = 0.5;
                            Ethconnect_LED = 0;
                            sock.close();
                            break;
                        }
                    }
                    break;
                case NSAPI_ERROR_WOULD_BLOCK :
                    printf("NSAPI_ERROR_WOULD_BLOCK\n");
                    memset(in_buf, '\0', sizeof(in_buf));
                    INT_TIMER_LINKDOWN_CATCHER();
                    break;
                case NSAPI_ERROR_NO_CONNECTION :
                    printf("NSAPI_ERROR_NO_CONNECTION\n");
                    memset(in_buf, '\0', sizeof(in_buf));
                    INT_TIMER_LINKDOWN_CATCHER();
                    break;
                case NSAPI_ERROR_NO_SOCKET :
                    printf("NSAPI_ERROR_NO_SOCKET\n");
                    memset(in_buf, '\0', sizeof(in_buf));
                    INT_TIMER_LINKDOWN_CATCHER();
                    break;
                case NSAPI_ERROR_NO_ADDRESS :
                    printf("NSAPI_ERROR_NO_ADDRESS\n");
                    memset(in_buf, '\0', sizeof(in_buf));
                    INT_TIMER_LINKDOWN_CATCHER();
                    break;
                default:
                    printf("other error");
                    break;
            }
        }
    }
}

/**
 * @brief エントリーポイント
 * 
 * @return OSに返します。
 */
int main(){
    /* Declaration of Local Variables */
    float pwmduty;

    /* Initializing Variables */
    EthRecv_LED = 0;
    EthSend_LED = 0;
        
    /* Initializing Interruption */


    
    /* Initializing PWM Out */
    motor_P.period (PWM_FREQ);
    motor_N.period (PWM_FREQ);
    motor_P = 0.5;
    motor_N = 0.5;
    
    /* Start Thread */
    Thread thread_get(ethernet_thread);

    
    /* Main Routine */
    while(true){
        //disconnect timeout
        if(Timeout_timer.read_ms() > TIMEOUT_MS){
            pipe_pwmduty = 0.0;
            EthRecv_LED = 0;
            EthSend_LED = 0;
            Ethconnect_LED = 0;
            //return -1;
        }
        
        /* Calculate PWM Duty */
        pwmduty = pipe_pwmduty / 2.0;

        /* Output PWM */
        motor_P = (0.5 + pwmduty);
        motor_N = (0.5 - pwmduty);

        
    }//while(1) END

}//main() END