This is the coordinator node.

Dependencies:   mbed-rtos mbed Zigbee_communication EthernetInterface WebSocketClient

main.cpp

Committer:
EmileArseneault
Date:
2017-02-14
Revision:
2:51d67a8b2325
Parent:
0:4cfeffb4d773
Child:
4:d9968ed09187

File content as of revision 2:51d67a8b2325:

// Emile Arseneault : arse1503
// Raphael Drouin   : dror2204

// Coordinator Node

#include "mbed.h"
#define FRAMEDELIMITER 0x7E
#include "rtos.h"

// 4269
DigitalOut resetswitch(p8);
Serial xbee(p13, p14);
Serial pc(USBTX, USBRX);
DigitalOut myled(LED1);

void printhexa(char c)
{
    char msb = c >> 4;
    char lsb = c & 0xF;
    
    if (msb < 10)
        msb += 0x30;
    else
        msb += 0x37;
        
    if (lsb < 10)
        lsb += 0x30;
    else
        lsb += 0x37;
    
    pc.putc('0');
    pc.putc('x');
    pc.putc(msb);
    pc.putc(lsb);
    pc.putc(' ');
}

void ATCommandResponse(int len, char* ans)
{
    char total = 0x88;
    char id = xbee.getc();
    total += id;
    char command[2];
    command[0] = xbee.getc();
    total += command[0];
    command[1] = xbee.getc();
    total += command[1];
    char status = xbee.getc();
    total += status;
    if (status != 0)
    {
        pc.printf("Command failed with status code : %d\r\n", status);
    }
    int i = 0;
    len-= 4;
    char data[len];
    
    pc.printf("response to command %c%c", command[0], command[1]);
    pc.printf(" is ");
    if (len == 0)
    {
        switch (status)
        {
            case 0 : pc.printf("OK\r\n"); break;
            case 1 : pc.printf("ERROR\r\n"); break;
            case 2 : pc.printf("Invalid Command\r\n"); break;
            case 3 : pc.printf("Invalid Parameter\r\n"); break;
            case 4 : pc.printf("Tx Failure\r\n"); break;
            default : pc.printf("Unknow error ...\r\n"); break;
        }
    }
    
    while (i < len)
    {
        if (xbee.readable())
        {
            data[i] = xbee.getc();
            total += data[i];
            printhexa(data[i]);
            i++;
        }
    }
    
    char checksum = xbee.getc();
    total += checksum;
    // Verify checksum
    if (total != 0xFF)
    {
        pc.printf("Checksum is wrong");
    }
    pc.printf("\r\n");
    ans = data;
}
    
void ModemStatus(int len, char* ans)
{
    char status = xbee.getc();
    
    switch (status){
        case 0 : pc.printf("Hardware reset\r\n"); break;
        case 1 : pc.printf("Watchdog timer reset\r\n"); break;
        case 2 : pc.printf("Joined network (routers and end devices)\r\n"); break;
        case 3 : pc.printf("Disassociated\r\n"); break;
        case 6 : pc.printf("Coordinator started\r\n"); break;
        case 7 : pc.printf("Network security key was updated\r\n"); break;
        case 0x0D : pc.printf("Voltage supply limit exceeded\r\n"); break;
        case 0x11 : pc.printf("Modem configuration changed while join in progress\r\n"); break;
        default : pc.printf("stack error\r\n"); break;
    }
    
    char checksum = xbee.getc();
    
    checksum += 0x8A + status;
    
    if (checksum != 0xFF)
    {
        pc.printf("Checksum is wrong\r\n");
    }
    *ans = status;
}

void ZigBeeTransmitStatus(int len, char* ans)
{
    char id = xbee.getc();
    char msb = xbee.getc();
    char lsb = xbee.getc();
    char retry =  xbee.getc();
    char status = xbee.getc();
    char discovery = xbee.getc();
    
    pc.printf("Response to transmit id %d is : ", id);
    
    if (status == 0)
    {
        pc.printf("Success\r\n");
    }
    else
    {
        switch (status){
            case 0x01 : pc.printf("MAC ACK Failure\r\n"); break;
            case 0x02 : pc.printf("CCA Failure\r\n"); break;
            case 0x15 : pc.printf("Invalid destination endpoint\r\n"); break;
            case 0x21 : pc.printf("Network ACK Failure\r\n"); break;
            case 0x22 : pc.printf("Not Joined to Network\r\n"); break;
            case 0x23 : pc.printf("Self-addressed\r\n"); break;
            case 0x24 : pc.printf("Address Not Found\r\n"); break;
            case 0x25 : pc.printf("Route Not Found\r\n"); break;
            case 0x26 : pc.printf("Broadcast source failed to hear a neighbor relay the message\r\n"); break;
            case 0x2B : pc.printf("Invalid binding table index\r\n"); break;
            case 0x2C : pc.printf("Resource error lack of free buffers, timers, etc.\r\n"); break;
            case 0x2D : pc.printf("Attempted broadcast with APS transmission\r\n"); break;
            case 0x2E : pc.printf("Attempted unicast with APS transmission, but EE=0\r\n"); break;
            case 0x32 : pc.printf("Resource error lack of free buffers, timers, etc.\r\n"); break;
            case 0x74 : pc.printf("Data payload too large\r\n"); break;
            default : pc.printf("Unknow error ...\r\n"); break;
        }
    }
}

void ZigBeeReceivePacket(int len, char* ans)
{
    int i = 0;
    char adresse64bit[8];
    char adresse16bit[2];
    char receiveOptions;
        
    while(i < 8)
    {
        adresse64bit[i] = xbee.getc();
        i++;
    }
    
    adresse16bit[0] = xbee.getc();
    adresse16bit[1] = xbee.getc();
    
    receiveOptions = xbee.getc();
    
    pc.printf("Data received : ");
    
    i = 11;
    while (i < len)
    {
        printhexa(xbee.getc());
        i++;   
    }
    
    // Validate checksum TODO
}
    
char* InterpretMessage()
{
    char start = xbee.getc(); // = FRAMEDELIMITER
    //assert
    char len_msb = xbee.getc();
    char len_lsb = xbee.getc();
    
    int len = ((int) len_msb << 4) + (int) len_lsb;
    char frame_data[len];
    
    // Resolving frame type
    char type = xbee.getc();
    char *response;
    len--;
    
    switch (type){
        case 0x88: ATCommandResponse(len, response);
            break;
        case 0x8A: ModemStatus(len, response);
            break;
        case 0x8B: ZigBeeTransmitStatus(len, response);
            break;
        case 0x90: ZigBeeReceivePacket(len, response);
            break;
        default: pc.printf("Please implement response of type");
            printhexa(type);
            pc.printf("\r\n");
            for (int i = 0; i <len; i++) xbee.getc();
            break;
    }
    return response;
}

void SendAtCommand(char FirstChar, char SecondChar, char *OptionalParam = NULL, int ParamLen = 0)
{
    // Frame Type 0x08
    // Two char as parameters
    
    char cmdtosend[10];
    char sum = 0;
    int cmdlength = 8;
    int i = 0;
    
    cmdtosend[0] = FRAMEDELIMITER;
    cmdtosend[1] = 0x00;
    cmdtosend[2] = 0x04 + ParamLen;
    cmdtosend[3] = 0x08;
    cmdtosend[4] = 0x52;
    cmdtosend[5] = FirstChar;
    cmdtosend[6] = SecondChar;
    
    // Ajouter les parametres au message
    if(OptionalParam != NULL)
    {   
        i = 0;
        cmdlength += ParamLen;
        
        while (i < ParamLen)
        {
            cmdtosend[7 + i] = (OptionalParam)[i];
            i++;
        }
    }
    
    // Calculate checksum
    i = 3;
    while (i < (cmdlength - 1))
    {
        sum += cmdtosend[i];
        i++;
    }
    cmdtosend[cmdlength - 1] = 0xFF - sum;
    
    // Envoyer la commande sur UART
    i = 0;
    while (i < cmdlength)
    {
        xbee.putc(cmdtosend[i]);
        i++;
    }
    
    wait(0.1);
}

void ReadSerial()
{
    // 00 13 A2 00 
    // 40 3E 09 63
    SendAtCommand('S', 'H');
    SendAtCommand('S', 'L');
}

void InitialisePANID(char PANIDMSB, char PANIDLSB)
{
    char PanID[2] = {PANIDMSB, PANIDLSB};
    
    SendAtCommand('I', 'D', &PanID[0], 2);
}

void ZigBeeTransmit(int adresse16, int adresse64, char *data, int dataLength)
{
    // Frame Type 0x10
    // 0x0000000000000000 - Reserved 64-bit address for the coordinator
    // 0x000000000000FFFF - Broadcast address
    
    // The Transmit Status frame (0x8B) est la reponse
    char cmdtosend[25];
    char checksum = 0x00;
    int cmdlength = 18;
    int i = 3;
    
    //ID command to set/read operating 64 bit PAN ID
    //WR command to set operating 64 bit PAN ID across reboot
    //OI command to read operating 16 bit PAN ID
    //II command to set operating 16 bit PAN ID
    
    cmdtosend[0] = FRAMEDELIMITER;
    cmdtosend[1] = 0x00;
    cmdtosend[2] = 0x0E + dataLength;
    cmdtosend[3] = 0x10;        // Frame type
    cmdtosend[4] = 0x01;        // Frame number
    cmdtosend[5] = 0x00;        // MSB adresse 64-bit 
    cmdtosend[6] = 0x00;
    cmdtosend[7] = 0x00;
    cmdtosend[8] = 0x00;
    cmdtosend[9] = 0x00;
    cmdtosend[10] = 0x00;
    cmdtosend[11] = 0xFF;
    cmdtosend[12] = 0xFF; // LSB adresse 64-bit
    cmdtosend[13] = adresse16 >> 16;                  // MSB adresse 16-bit
    cmdtosend[14] = adresse16 && 0b0000000011111111;  // LSB adresse 16-bit
    cmdtosend[15] = 0x00;       // Broadcast Radius
    cmdtosend[16] = 0x00;       // Options
    
    // Set RF DATA
    if(data != NULL)
    {   
        i = 0;
        cmdlength += dataLength;
        
        while (i < dataLength)
        {
            cmdtosend[17 + i] = (data)[i];
            i++;
        }
    }
    
    //cmdtosend[17] = 0x00;       // Start RF DATA
    //cmdtosend[18] = 0x00;
    //cmdtosend[19] = 0x00;
    //cmdtosend[20] = 0x00;
    //cmdtosend[21] = 0x00;
    //cmdtosend[22] = 0x00;
    //cmdtosend[23] = 0x00;
    //cmdtosend[24] = 0x00;       // End RF DATA
    
    // Calculate checksum
    i = 3;
    while (i < (cmdlength - 1))
    {
        checksum += cmdtosend[i];
        i++;
    }
    cmdtosend[cmdlength - 1] = 0xFF - checksum;
    
    // Envoyer la commande sur UART
    i = 0;
    while (i < cmdlength)
    {
        xbee.putc(cmdtosend[i]);
        i++;
    }
    wait(0.1);
}

void BroadcastHelloWorld()
{
    char hello[5] = {'H', 'e', 'l', 'l', 'o'};
    char world[5] = {'w', 'o', 'r', 'l', 'd'};
    
    while (1)
    {
        ZigBeeTransmit(0xFFFE, 0x000000000000FFFF, &hello[0], 5);
        ZigBeeTransmit(0xFFFE, 0x000000000000FFFF, &world[0], 5);
        wait(2);
    }
}

void xbee_reader()
{
    while(1)
    {
        if (xbee.readable())
        {
            InterpretMessage();
        }
        wait(0.001);   
    }
}

void tick()
{
    myled = !myled;   
}

int main() {
    Thread thread(xbee_reader);
    Ticker ticker;
    ticker.attach(&tick, 1);
    pc.printf("\r\nI am coordinator\r\n");
    resetswitch = 0;
    wait(0.4);
    resetswitch = 1;
    
    wait(3);
    ReadSerial();
    InitialisePANID(0x42, 0x69);
    BroadcastHelloWorld();
    
    while(1) {
    }
}