Implementatie van de opdracht Round Robin

Dependencies:   C12832

StateMachine.cpp

Committer:
benboydens
Date:
2020-11-03
Revision:
1:0016a14c76bb
Parent:
0:825bd2920b6d

File content as of revision 1:0016a14c76bb:

#include "StateMachine.h"
#include "LM75B.h"
#include "C12832.h"

#define CLIENT_IP "192.168.0.24"


C12832 lcd(D11, D13, D12, D7, D10);     // Using Arduino pin notation
LM75B lm75b(D14,D15);                   // Temperature sensor
AnalogIn pot1 (A0);                     // Potentiometer 1

// Joystick Pins
DigitalIn up(A2);
DigitalIn down(A3);
DigitalIn left(A4);
DigitalIn right(A5);
DigitalIn fire(D4);


StateMachine::StateMachine()
{
    currentState = INIT;
    startState = RECEIVE;
    eth = new EthernetInterface();
    eth->set_network(CLIENT_IP, "255.255.255.0", "192.168.0.1");
    eth->connect();
    rcount = 3;
}

StateMachine::~StateMachine()
{
    delete eth;
}

void StateMachine::start()
{
    bool end = true;
    while(end) {
        switch(currentState) {
            case INIT:
                actionInit();
                currentState = startState;
                break;
            case TRANSMIT:
                actionTransmit();
                currentState = RECEIVE;
                break;
            case RECEIVE:
                actionReceive();
                for(int i = 3; i < rcount; i++) {
                    if (rbuffer[i] == ipbytes[3]) {
                        // received payload contains client id
                        currentState = END;
                        break;
                    }
                }
                break;
            case END:
                end = false;
                break;
            default:
                currentState = CERROR;
                break;
        }
    }
}


// choose ip address to send (up/down) and wich state to start (left/right)
void StateMachine::actionInit()
{
    bool stop = true;
    uint8_t senderId = 1;
    while(stop) {
        if(left) {
            startState = RECEIVE;
        }
        if(right) {
            startState = TRANSMIT;
        }
        if(up) {
            senderId = senderId < 254 ? senderId+1 : 1;
        }
        if(down) {
            senderId = senderId > 0 ? senderId-1 : 254;
        }
        if(fire) {
            stop = false;
        }

        // display info on lcd screen
        lcd.cls();
        lcd.locate(0,3);
        lcd.printf("Start state = %s", startState == RECEIVE ? "Received" : "Transmit");
        lcd.locate(1,3);
        lcd.printf("Sender IP = 192.168.0.%d", senderId);
        wait(0.05);
    }
    lcd.cls();

    // set ipbytes (bytes are used because its easier then using strings also big endian notation is used)
    ipbytes[0] = (char) 192;
    ipbytes[1] = (char) 168;
    ipbytes[2] = (char) 0;
    ipbytes[3] = (char) senderId;
}



// actions to be taken when node is a client
void StateMachine::actionTransmit()
{
    // set client address
    SocketAddress clientAddress;
    clientAddress.set_ip_address(CLIENT_IP);

    // set server ip and port
    SocketAddress address;
    address.set_ip_bytes(ipbytes, NSAPI_IPv4);
    address.set_port(4000);

    // display transmit info
    lcd.cls();
    lcd.locate(0,0);
    lcd.printf("Sending data to %s", address.get_ip_address());
    wait(1);

    // create socket and connect to server address
    TCPSocket socket;
    socket.open(eth);
    socket.connect(address);

    // get values to send
    uint16_t temp = lm75b.read();
    uint8_t pwm = ((float)pot1) * 255;
    int* addressBytes = (int*) clientAddress.get_ip_bytes(); // get bytes of ip address
    uint8_t clientId = (*addressBytes) >> 24;   // get last number of ip address

    // create new payload
    rbuffer[0] = (char) temp & 0xFF;
    rbuffer[1] = (char) (temp >> 8);
    rbuffer[2] = (char) pwm;
    rbuffer[rcount] = (char) clientId;

    // print temp and pwm on lcd screen
    lcd.cls();
    lcd.locate(0,3);
    lcd.printf("Temperature = %d", temp);
    lcd.locate(1,3);
    lcd.printf("PWM value = %0.2f", ((float) pwm)/255);
    wait(1);

    // send and close socket
    socket.send(rbuffer, rcount + 1);
    socket.close();
}



// actions to be taken when node is a server
void StateMachine::actionReceive()
{
    // create server listingen on port 4000
    TCPServer srv(eth);
    srv.bind(4000);
    srv.listen();

    // display receive info
    lcd.cls();
    lcd.locate(0,0);
    lcd.printf("Listening on %s:%d", CLIENT_IP, 4000);
    wait(1);

    // open a socket and wait for the client on the server
    TCPSocket client;
    SocketAddress client_addr;
    srv.accept(&client, &client_addr);

    // create buffer and wait for client to connect
    rcount = client.recv(rbuffer, sizeof rbuffer);
    printf("received: %d bytes\r\n", rcount);

    // convert received bytes into values
    uint16_t temp = ((uint16_t) rbuffer[0]) | (((uint16_t) rbuffer[1]) << 8);
    uint8_t pwm = (uint8_t) rbuffer[2];

    // print temp and pwm on lcd screen
    lcd.cls();
    lcd.locate(0,3);
    lcd.printf("Temperature = %d", temp);
    lcd.locate(1,3);
    lcd.printf("PWM value = %0.2f", ((float) pwm)/255);
    wait(1);

    client.close();
    srv.close();
}