WappAutomation 2 : - WITH RESET - WITHOUT Switch Cable Tested on TEL50

Dependencies:   MFRC522

main.cpp

Committer:
cybermars
Date:
2019-12-13
Revision:
12:81209b6a2318
Parent:
11:275b5ff86ab0

File content as of revision 12:81209b6a2318:

#include "mbed.h"
#include "MFRC522.h"
#include "EthernetInterface.h"


//***************************** Change this for each new prober installation ********************************
#define PROBER_NAME "tl50"
#define IP          "10.129.97.130"
/*Please update the list below:
    TEL12 : 10.129.97.100
    TEL20 : 10.129.97.101
    TEL23 : 10.129.97.102
    TEL36 : 10.129.97.103
    TEL01 : 10.129.97.105
    TEL19 : 10.129.97.106
    TEL27 : 10.129.97.107
    TEL37 : 10.129.97.108
    TEL38 : 10.129.97.109
    TEL39 : 10.129.97.110
    TEL40 : 10.129.97.111
    TEL16 : 10.129.97.112
    TEL21 : 10.129.97.113
    TEL22 : 10.129.97.114
    TEL34 : 10.129.97.115
    TEL30 : 10.129.97.116
    TEL32 : 10.129.97.117
    TEL26 : 10.129.97.118
    TEL25 : 10.129.97.119
    TEL28 : 10.129.97.120
    TEL29 : 10.129.97.121
    TEL31 : 10.129.97.122
    TEL33 : 10.129.97.123
    TEL42 : 10.129.97.124
    TEL43 : 10.129.97.125
    TEL44 : 10.129.97.126
    TEL45 : 10.129.97.127
    TEL46 : 10.129.97.128
    TEL47 : 10.129.97.129
    TEL48 : 10.129.97.104
    TEL50 : 10.129.97.130
************************************************************************************************************/


//******************************************* RFID Antenna **************************************************
//Cheap 13.56 Mhz RFID-RC522 module (This code is based on Martin Olejar's MFRC522 library. Minimal changes)
//On Nucleo-F429ZI, SPI1 and SPI2 could not be used in the same time with EthernetInterface -> SPI4 used
//RFID IRQ=pin5    ->   Not used. Leave open
//RFID MISO=pin4   ->   Nucleo SPI_MISO   ->  White   -> PE_5
//RFID MOSI=pin3   ->   Nucleo SPI_MOSI   ->  Green   -> PE_6
//RFID SCK=pin2    ->   Nucleo SPI_SCK    ->  Yellow  -> PE_2
//RFID SDA=pin1    ->   Nucleo SPI_CS     ->  Blue    -> PE_4
//RFID RST=pin7    ->   Nucleo DigitalOut ->  Brown   -> D8
//***********************************************************************************************************


//********************************************* Antenna LED *************************************************
//Anode     ->  +3.3v pin
//Cathode   ->  D3 pin
//Use LED_ON and LED_OFF to use the LED
//***********************************************************************************************************


//****************************************** Interlock Relay ************************************************
//Power +   ->  +5v pin
//Power -   ->  GND pin
//Command   ->  D4 pin
//Use RELAY_OPEN and RELAY_CLOSE to use the relay
//***********************************************************************************************************


#define MF_RESET D8                   // Nucleo Pin for MFRC522 reset
#define LED_ON 0
#define LED_OFF 1
#define RELAY_CLOSED 0
#define RELAY_OPEN 1

#define INTERLOCK_DELAY 5000          // Delay (in milliseconds) between alarm received and relay off to simulate open interlock
#define APCD_READ_DELAY 500           // Delay (in milliseconds) before read the APCD data
#define SOCKETCONNECTION_ATTEMPT 5    // Number of attempts for socket connection
#define TIMEOUT_WAITTAG 20            // Timeout in case of New Tag Present detected

#define GATEWAY    "10.129.97.254"    //The gateway to go out the prober VLAN
#define MASK       "255.255.255.0"
#define SERVER     "10.18.47.90"      //Automation server IP Address - { 164, 129, 103, 88 } for Dev Automation server
#define PORT       7778               //Automation port

#define MBX_OPEN        "MBX_OPEN srvpat"  //"MBX_OPEN srv_pat"
#define MBX_CLOSE       "MBX_DISCONNECT"
#define MBX_COUNT       "MBX_COUNT STM32Insrv_" PROBER_NAME
#define MBX_GET         "MBX_GET 5,STM32Insrv_" PROBER_NAME
#define MBX_PUT_BEGIN   "MBX_PUT STM32Outsrv, CMD/A=\"WAPP\" MID/A=\"gnb3t" PROBER_NAME "\" MTY/A=\"E\" WAPPID/A=\""
#define MBX_PUT_END     "\""


Serial PC(USBTX, USBRX);
MFRC522   Antenna(PE_6, PE_5, PE_2, PE_4, MF_RESET);
EthernetInterface eth;
TCPSocket apcd;
DigitalIn WappExchangeSwitch(D2);
DigitalOut TagReadLED(D3);
DigitalOut Interlock(D4);
DigitalOut red(LED3);
DigitalOut blue(LED2);
DigitalOut green(LED1);

char bufTagID[256];
int APCDsendData (char *tcpCmd);
char *APCDgetData ();


//IsTagPresent(): function to read the Tag ID
//  Return false if no Tag present
//  Return true if a Tag ID was read (Tag ID is saved int the bufTagID buffer)
bool IsTagPresent()
{
    /*
    if (Antenna.PICC_IsNewCardPresent() && WappExchangeSwitch == 1){
        PC.printf("TAG detected ... ");

        //Select one of the cards
        int count = 0;
        while (!Antenna.PICC_ReadCardSerial() && WappExchangeSwitch == 1 && count < TIMEOUT_WAITTAG){
             count++;
             wait_ms(100);
        }
        if (count == TIMEOUT_WAITTAG){
            PC.printf("Timeout occured -> no Tag present\r\n");
            return false;
        }
        if (WappExchangeSwitch == 0) return false;

        //Light during 1s Tag LED to indicate that a tag was read
        TagReadLED = LED_ON;
        wait_ms(500);
        TagReadLED = LED_OFF;

        //Save Tag ID into buffer
        PC.printf("ID = ");
        int pos = 0;
        char hexbuf[2];
        for (int i = 0; i < 256; i++) bufTagID[i] = '\0';
        for (uint8_t i = 0; i < Antenna.uid.size; i++) {
            sprintf(hexbuf, "%02x", Antenna.uid.uidByte[i]);
            PC.putc(hexbuf[0]);
            PC.putc(hexbuf[1]);
            bufTagID[pos] = hexbuf[0];
            pos++;
            bufTagID[pos] = hexbuf[1];
            pos++;
        }
        PC.printf("\r\n");
        return true;
    }
    else return false;
    */

    //Look for new cards during 5s
    int timeout = 0;
    while ( ! Antenna.PICC_IsNewCardPresent() == 1 && timeout < TIMEOUT_WAITTAG) {
        wait_ms(100);
        timeout++;
    }
    if (timeout >= TIMEOUT_WAITTAG) {
        PC.printf("Timeout occured -> no Tag present\r\n");
        return false;
    }
    //if (WappExchangeSwitch == 0) return false;
    PC.printf("TAG detected ... ");

    //pc.printf("Yes, tag is present... Try to read Tag ID\r\n");

    //Select one of the cards
    timeout = 0;
    while ( ! Antenna.PICC_ReadCardSerial() == 1 && timeout < TIMEOUT_WAITTAG) {
        wait_ms(100);
        timeout++;
    }
    if (timeout >= TIMEOUT_WAITTAG) {
        PC.printf("Timeout occured during ReadCardSerial\r\n");
        return false;
    }
    //if (WappExchangeSwitch == 0) return false;

    //Light during 1s Tag LED to indicate that a tag was read
    TagReadLED = LED_ON;
    wait_ms(500);
    TagReadLED = LED_OFF;

    //Save Tag ID into buffer
    PC.printf("ID = ");
    int pos = 0;
    char hexbuf[2];
    for (int i = 0; i < 256; i++) bufTagID[i] = '\0';
    for (uint8_t i = 0; i < Antenna.uid.size; i++) {
        sprintf(hexbuf, "%02x", Antenna.uid.uidByte[i]);
        PC.putc(hexbuf[0]);
        PC.putc(hexbuf[1]);
        bufTagID[pos] = hexbuf[0];
        pos++;
        bufTagID[pos] = hexbuf[1];
        pos++;
    }
    PC.printf("\r\n");

    return true;
}

//APCDGetWappAlarm: function to check from APCD mailbox if a wapp alarm was sent by automation
//  return 1 in case of alarm
//  return 2 if apcd.connect failed
//  return 0 if there is no alarm
int APCDGetWappAlarm()
{
    int result = 2;
    int rtrn = 2;
    int attempt = 0;

    //Open a TCP socket
    rtrn = apcd.open(&eth);
    PC.printf("\r\nAPCDGetWappAlarm:\r\n");
    PC.printf("\tOpen socket -> %d\r\n", rtrn);
    blue = 1;

    //Try APCD connection
    rtrn = apcd.connect(SERVER, PORT);
    while (rtrn < 0 && attempt < SOCKETCONNECTION_ATTEMPT) {
        wait_ms(500);
        rtrn = apcd.connect(SERVER, PORT);
        attempt++;
    }
    PC.printf("\tConnection -> %d\r\n", rtrn);

    if (rtrn == 0) { //Automation server connection successfully
        APCDsendData(MBX_OPEN); //Open the APCD bus
        APCDgetData();

        //Get message's number in the mailbox
        PC.printf("\tAPCD   -> %s\r\n", MBX_COUNT);
        APCDsendData(MBX_COUNT);

        //Extract the data from the string received
        char buf[256];
        sprintf(buf,"%s", APCDgetData());
        unsigned short int answerLen = strlen(buf);
        PC.printf("\tAnswer -> %s\r\n", buf);
        if (answerLen > 10) { //Answer will be MBX_COUNT,xx where xx is the number of message
            int nbMsg = 0;
            char nb[10];
            int pos = 10;
            while (buf[pos] != '\0' && pos < 20) {
                nb[pos-10] = buf[pos];
                pos++;
            }
            nb[pos-10] = '\0';
            nbMsg = atoi(nb);
            PC.printf("\tMsg count -> %d\r\n", nbMsg);
            //If there is a message or more, get all message (=> mailbox will be empty)
            if (nbMsg > 0) {
                result = 1;
                while (nbMsg > 0) { //Get all VFEI message in the mailbox
                    PC.printf("\tAPCD -> %s\r\n", MBX_GET);
                    APCDsendData(MBX_GET);
                    APCDgetData();
                    nbMsg--;
                }
            } else result = 0;
        }

        //Close the APCD bus
        APCDsendData(MBX_CLOSE);
        PC.printf("\tAPCD -> %s\r\n", MBX_CLOSE);
        APCDgetData();
    } else result = 2;

    apcd.close();
    blue = 0;
    return result;
}

//APCDSendTagID: function to send the VFEI message with TagID to the automation
//  return 1 if data sent correctly
//  return 2 if apcd.connect failed
//  return 0 if sent data lenght doesn't match with message lenght
int APCDSendTagID()
{
    int attempt = 0;
    int result = 2;
    int rtrn = 2;
    PC.printf("\r\nAPCDSendTagID:\r\n");

    //Build VFEI message
    char concatBuffer[256];
    sprintf(concatBuffer, "%s%s%s\0", MBX_PUT_BEGIN, bufTagID, MBX_PUT_END);
    PC.printf("\tVFEI message : %s\r\n", concatBuffer);

    //Open a TCP socket
    rtrn = apcd.open(&eth);
    PC.printf("\tOpen socket -> %d\r\n", rtrn);
    blue = 1;

    //Try APCD connection
    rtrn = apcd.connect(SERVER, PORT);
    while (rtrn < 0 && attempt < SOCKETCONNECTION_ATTEMPT) {
        wait_ms(500);
        rtrn = apcd.connect(SERVER, PORT);
        attempt++;
    }
    PC.printf("\tConnection -> %d\r\n", rtrn);

    //Send VFEI message if possible
    if (rtrn == 0) {
        PC.printf("\tAPCD -> %s\r\n", MBX_OPEN);
        APCDsendData(MBX_OPEN); //Open the APCD bus
        APCDgetData();
        rtrn = APCDsendData(concatBuffer); //Send the VFEI message
        APCDgetData();
        PC.printf("\tAPCD -> %s\r\n", MBX_CLOSE);
        APCDsendData(MBX_CLOSE); //Close the APCD bus
        APCDgetData();
        result = 1;
    } else result = 2;

    apcd.close();
    blue = 0;
    return result;
}

//APCDsendData: function to send data to APCD bus
//  Return 1 if data sent correctly, 0 in other case
//  Author: F. Frezot from Arduino code
int APCDsendData (char *tcpCmd)
{
    unsigned short int dataLength = strlen(tcpCmd);
    unsigned char len[2];

    len[0] = ((dataLength>>8)&0xFF); //MSB
    len[1] = ((dataLength>>0)&0xFF); //LSB

    int rtrnLenght = apcd.send(len, sizeof(len));
    rtrnLenght = apcd.send(tcpCmd, dataLength);
    if (rtrnLenght == dataLength) return 1;
    else return 0;
}


//APCDgetData: function to read data from APCD bus
//  Return a char array with data read
//  Author: F. Frezot from Arduino code
char *APCDgetData ()
{
    char MSB[1];
    char LSB[1];
    unsigned short int dataLength;
    char readBuf[256] = "\0";

    wait_ms(APCD_READ_DELAY);

    apcd.recv(MSB, 1);
    apcd.recv(LSB, 1);
    dataLength = ((MSB[0]<<8)&0xFF00)|(LSB[0]<<0)&0x00FF;
    apcd.recv(readBuf, dataLength);

    return (readBuf);
}

int main()
{
    // Init Serial and nucleo board LED (off)
    PC.baud(9600);
    PC.printf("Running ...\r\n");
    green = 0;
    red = 0;
    blue = 0;

    // Init RC522 Chip
    PC.printf("\tInit RFID...");
    wait_ms(500);
    Antenna.PCD_Init();
    wait_ms(100);
    Antenna.PCD_AntennaOff(); //Turn off the RFID antenna.
    TagReadLED = LED_OFF; //Turn off the LED who indicate if a TAG was read
    PC.printf("DONE\r\n");

    //PC.printf("\tClose relay for prober Interlock\r\n");
    //Interlock = RELAY_CLOSED; //Close relay for prober interlock

    //Ethernet Init
    PC.printf("\tInit Ethernet...");
    eth.set_network(IP, MASK, GATEWAY);
    int rtrn = eth.connect();
    int reset_eth = 0;
    if (rtrn == 0) {
        PC.printf("DONE\r\n");
        const char *ip = eth.get_ip_address();
        const char *mac = eth.get_mac_address();
        PC.printf("\tIP  address = %s\n\r", ip ? ip : "No IP");
        PC.printf("\tMAC address = %s\n\r", mac ? mac : "No MAC");
        PC.printf("Running DONE\r\n\r\n");
    } else {
        PC.printf("FAIL -> Check if Network cable is plug-in then reset the board\r\n");
        red = 0;
        green = 0;
        PC.printf("Running FAIL -> Program aborted\r\n\r\n");
        while (reset_eth <= 900) {
            blue = !blue;
            TagReadLED = !TagReadLED;
            wait_ms(200);
            reset_eth++;
        }
        NVIC_SystemReset(); // reset system if no ethernet connection succeeded after 180sec Added by B. Tournier

    }

    //Waiting Tag and WAPP alarm
    int count = 0;
    int reset_trigger = 0;
    while (true) {
        //Check if Tag read
        //if (true) {
            //Turn on the antenna
            Antenna.PCD_AntennaOn();
            wait_ms(100);

            //Waiting Tag ID
            if (IsTagPresent()) {
                green = 0;
                int rtrn = APCDSendTagID();
                if (rtrn == 1) {
                    PC.printf("\tTag ID sent correctly (Code=%d)\r\n", rtrn);
                    red = 0;
                    //Blink Tag LED during 3s
                    for (int i = 0; i < 10; i++) {
                        TagReadLED = !TagReadLED;
                        wait_ms(500);
                    }
                    //Tag LED continuous ON during 1s
                    TagReadLED = LED_ON;
                    wait_ms(2000);

                    //Turn off Tag LED
                    TagReadLED = LED_OFF;
                } else {
                    PC.printf("\tWARNING: Fail to send Tag ID (Code=%d)\r\n", rtrn);
                    red = 1;
                }
            }
            Antenna.PCD_AntennaOff();
        //}

        //Check alarm each 4s
        if (count >= 8) { // Count value = each xx seconds * 2. Example: Count >= 4 for check alarm each 2s
            green = 0;
            count = -1;
            int rtrn = APCDGetWappAlarm();
            if (rtrn == 1) {
                red = 0;
                PC.printf("Wapp alarm received");
                          //wait_ms(INTERLOCK_DELAY);
                          //Interlock = RELAY_OPEN; //Activate the relay on prober interlock
                          wait_ms(2000);
                          //Interlock = RELAY_CLOSED;
                          //PC.printf("                    -> Close interlock relay\r\n");
            } else if (rtrn == 2) {
                PC.printf("WARNING: Fail to check if alarm is present (Code=%d)\r\n", rtrn);
                red = 1;
            } else if (rtrn == 0) {
                red = 0;
            }
        }

        green = !green;
        count++;
        reset_trigger++;
        wait_ms(500);
        if (reset_trigger >= 14400) {
            NVIC_SystemReset(); // reset system each 2 hours
        }
    }
}