Code used in the table for the Pong Demo

Dependencies:   PixelArray WS2812 mbed

The project for the code used in the table of the "Pong Demo"

main.cpp

Committer:
benswindell
Date:
2017-03-20
Revision:
1:24bc4d8ed2ae
Parent:
0:f2b739e846ae

File content as of revision 1:24bc4d8ed2ae:

#include "mbed.h"
#include "WS2812.h"
#include "PixelArray.h"

#define WS2812_BUF 112
#define NUM_COLORS 6
#define NUM_LEDS_PER_COLOR 1

//-------- Colours -----------
#define RED 0x2f0000
#define YELLOW 0x2f2f00
#define GREEN 0x002f00
#define LIGHTBLUE 0x002f2f
#define DARKBLUE 0x00002f
#define BLUE 0x0000ff // Player scored a goal
#define PINK 0x2f002f
#define OFF 0x000000
#define WHITE 0xffffaa
#define ARMBLUE 0x128BAB
#define PURPLE 0xff0055 // Player has conceded a goal

// GPIO
AnalogIn robotBreakBeam(A0);
AnalogIn playerBreakBeam(A1);
DigitalOut led_green(LED_GREEN, 1);

// SERIAL
Serial pc(USBTX, USBRX); // tx, rx

// LED STRIPS
// See the program page for information on the timing numbers
// The given numbers are for the K64F
WS2812 robotScoreLED(D9, WS2812_BUF, 0, 5, 5, 0);
WS2812 playerScoreLED(D8,WS2812_BUF, 0, 5, 5, 0);
WS2812 robotGoalLED(D5,WS2812_BUF, 0, 5, 5, 0);
WS2812 playerGoalLED(D3,WS2812_BUF, 0, 5, 5, 0);

// LED Variables
bool seg1A, seg1B, seg1C, seg1D, seg1E, seg1F, seg1G;
int seg1Array[112];
int mainArray[11][122];
PixelArray robotScorePx(WS2812_BUF);
PixelArray playerScorePx(WS2812_BUF);
PixelArray robotGoalPx(WS2812_BUF);
PixelArray playerGoalPx(WS2812_BUF);
const int PLAYERGOALLEDS = 55;
const int ROBOTGOALLEDS = 55;

// Score counters
int robotScore;
int playerScore;
int scoreLimit = 3;
bool finishedGame = false;
int endFlashes = 3;
int numFlashes;

// Robot Bream Beam value
double prevRbbValue; // Previous Robot break beam value
double prevPbbValue; // Previous player break beam value

// FUNCTION DECLERATIONS
void Write7Seg(int num);
void SetLEDArray(int x);
void WriteRobotGoal(bool scored);
void WritePlayerGoal(bool scored);
void WriteScores();
void HandleGoal(bool hasRobotScored);
void WritePxScores(int line_num, bool isRobot);
void WritePxGoal(unsigned int colour,bool isRobot);
void HandleWin();
void WriteGoalsOff();


void setup()
{

    // Turn on green LED
    led_green = 0;

    // Set brightness of the 4 LED strips
    robotScoreLED.setII(0x19);
    robotScoreLED.useII(WS2812::GLOBAL);
    playerScoreLED.setII(0x19);
    playerScoreLED.useII(WS2812::GLOBAL);
    robotGoalLED.setII(0x19);
    robotGoalLED.useII(WS2812::GLOBAL);
    playerGoalLED.setII(0x80);
    playerGoalLED.useII(WS2812::GLOBAL);

    // Fills 2D array with data
    for(int i=0; i<10; i++) {
        Write7Seg(i);
    }

    // Set scores to 0
    robotScore = 0;
    playerScore = 0;
    numFlashes = 0;

    // Set LEDS to start values
    WriteScores();
    wait(0.01);
    WritePlayerGoal(true);
    wait(0.01);
    WriteRobotGoal(true);

    wait(5);

    WriteGoalsOff();
    // Turn off green LED
    led_green = 1;
}

// Set segment variables
void Write7Seg(int num)
{
    switch (num) {
        case 0 :
            // Off
            seg1A = 1;
            seg1B = 1;
            seg1C = 1;
            seg1D = 1;
            seg1E = 1;
            seg1F = 1;
            seg1G = 0;

            SetLEDArray(0);

            break;

        case 1 :
            // 1
            seg1A = 0;
            seg1B = 1;
            seg1C = 1;
            seg1D = 0;
            seg1E = 0;
            seg1F = 0;
            seg1G = 0;

            SetLEDArray(1);
            break;

        case 2 :
            // 2
            seg1A = 1;
            seg1B = 1;
            seg1C = 0;
            seg1D = 1;
            seg1E = 1;
            seg1F = 0;
            seg1G = 1;

            SetLEDArray(2);

            break;

        case 3 :
            // 3
            seg1A = 1;
            seg1B = 1;
            seg1C = 1;
            seg1D = 1;
            seg1E = 0;
            seg1F = 0;
            seg1G = 1;

            SetLEDArray(3);
            break;

        case 4:
            // 4
            seg1A = 0;
            seg1B = 1;
            seg1C = 1;
            seg1D = 0;
            seg1E = 0;
            seg1F = 1;
            seg1G = 1;

            SetLEDArray(4);

            break;

        case 5:
            // 5
            seg1A = 1;
            seg1B = 0;
            seg1C = 1;
            seg1D = 1;
            seg1E = 0;
            seg1F = 1;
            seg1G = 1;

            SetLEDArray(5);

            break;

        case 6:
            // 6
            seg1A = 1;
            seg1B = 0;
            seg1C = 1;
            seg1D = 1;
            seg1E = 1;
            seg1F = 1;
            seg1G = 1;

            SetLEDArray(6);

            break;

        case 7:
            // 7
            seg1A = 1;
            seg1B = 1;
            seg1C = 1;
            seg1D = 0;
            seg1E = 0;
            seg1F = 0;
            seg1G = 0;

            SetLEDArray(7);

            break;

        case 8:
            // 8
            seg1A = 1;
            seg1B = 1;
            seg1C = 1;
            seg1D = 1;
            seg1E = 1;
            seg1F = 1;
            seg1G = 1;

            SetLEDArray(8);
            break;

        case 9:
            // 9
            seg1A = 1;
            seg1B = 1;
            seg1C = 1;
            seg1D = 0;
            seg1E = 0;
            seg1F = 1;
            seg1G = 1;

            SetLEDArray(9);
            break;

        case 10:
            // OFF
            seg1A = 0;
            seg1B = 0;
            seg1C = 0;
            seg1D = 0;
            seg1E = 0;
            seg1F = 0;
            seg1G = 0;

            SetLEDArray(10);
            break;

        default :

            break;

    }
}

// Write segment config to main array
void SetLEDArray(int x)
{
    for (int i = 0; i < WS2812_BUF; i++) {
        if (i < 16) {
            mainArray[x][i] = seg1A;
        }

        if ( i >= 16 && i < 32) {
            mainArray[x][i] = seg1B;
        }

        if (i >= 32 && i < 48) {
            mainArray[x][i] = seg1C;
        }

        if (i >= 48 && i < 64) {
            mainArray[x][i]= seg1D;
        }

        if ( i >= 64 && i < 80) {
            mainArray[x][i] = seg1E;
        }

        if (i >= 80 && i < 96) {
            mainArray[x][i] = seg1F;
        }

        if ( i >= 96 && i < 112) {
            mainArray[x][i] = seg1G;
        }
    }// FOR LOOP
}

// Write to player 1 LED (ROBOT)
void WriteRobotGoal(bool scored)
{
    if(scored == true) {
        WritePxGoal(BLUE,true);
    } else {
        WritePxGoal(PURPLE,true);
    }
    robotGoalLED.write(robotGoalPx.getBuf());
}

// Write to player 1 LED (ROBOT)
void WritePlayerGoal(bool scored)
{
    if(scored == true) {
        WritePxGoal(BLUE,false);
    } else {
        WritePxGoal(PURPLE,false);
    }
    playerGoalLED.write(playerGoalPx.getBuf());
}

// Write OFF to both goals 
void WriteGoalsOff()
{
    WritePxGoal(OFF,true);
    robotGoalLED.write(robotGoalPx.getBuf());
    WritePxGoal(OFF,false);
    playerGoalLED.write(playerGoalPx.getBuf());
}

// Update both Score LEDs with the current score
void WriteScores()
{
    WritePxScores(playerScore,false);
    playerScoreLED.write(playerScorePx.getBuf());
    wait(0.01);
    WritePxScores(robotScore,true);
    robotScoreLED.write(robotScorePx.getBuf());
}

// Write pixel array
void WritePxScores(int line_num,bool isRobot)
{
    if(isRobot == true) {

        for (int i = 0; i < WS2812_BUF; i++) {
            if (mainArray[line_num][i] == 0) {
                robotScorePx.Set(i,OFF);
            }

            if (mainArray[line_num][i] == 1) {
                robotScorePx.Set(i,WHITE);
            }
        }
    } else {
        for (int i = 0; i < WS2812_BUF; i++) {
            if (mainArray[line_num][i] == 0) {
                playerScorePx.Set(i,OFF);
            }

            if (mainArray[line_num][i] == 1) {
                playerScorePx.Set(i,WHITE);
            }
        }
    }

}

// Write Goal pixel array, using input colour for the specified goal
// INPUTS: colour, isRobot
//
//         colour - This is the colour that you wish to set the array to
//         isRobot - This specifies which goal to set the colours of, based on if it is the Robot side goal or not
//
void WritePxGoal(unsigned int colour,bool isRobot)
{
    if(isRobot == true) {
        for (int i = 0; i < WS2812_BUF; i++) {
            robotGoalPx.Set(i,colour);
        }
    } else {
        for (int i = 0; i < WS2812_BUF; i++) {
            playerGoalPx.Set(i,colour);
        }
    }
}

// Write the goal LEDs and score LEDs when a goal is recorded. Also check to see if the goal being scored
// is the final point of the game and the game is over.
// INPUTS: hasRobotScored
//      
//      hasRobotScored - true if the goal being recorded is from the playerside goal, meaning the robot has scored a point
//
void HandleGoal(bool hasRobotScored)
{
    if(hasRobotScored == true) {
        robotScore++;
        WriteRobotGoal(true);
        wait(0.01);
        WritePlayerGoal(false);
        wait(0.01);
        WriteScores();
    } else {
        playerScore++;
        WriteRobotGoal(false);
        wait(0.01);
        WritePlayerGoal(true);
        wait(0.01);
        WriteScores();
    }

    wait(5);

    // If either player reaches the score limit, then call HandleWin(). If not, then turn goal LEDs off
    if(robotScore == scoreLimit || playerScore == scoreLimit) {
        HandleWin();
    } else {
        WriteGoalsOff();
    }
}

// Handle behaviour when either the player or robot has won a game. 
void HandleWin()
{
    // Initalise variable as true
    bool isRobotWinner = true;
    
    // Decide if the robot is the winner. If not, then change isRobotWinner to false
    if(playerScore == scoreLimit) {
        isRobotWinner = false;
        pc.printf("Player won!");

        // Animation for goal LEDs. Turns off the robot Goal LEDs, working from in the middle point outwards.
        for(int i = 0; i < (ROBOTGOALLEDS / 2); i++) {
            robotGoalPx.Set((ROBOTGOALLEDS /2) - i, OFF);
            robotGoalPx.Set((ROBOTGOALLEDS /2) + i, OFF);
            robotGoalLED.write(robotGoalPx.getBuf());
            wait(0.15);
        }

        WriteGoalsOff();

    } else {
        pc.printf("Robot won!");

        // Animation for goal LEDs. Turns off the player Goal LEDs, working from in the middle point outwards.
        for(int i = 0; i < (PLAYERGOALLEDS / 2); i++) {
            playerGoalPx.Set((PLAYERGOALLEDS /2) - i, OFF);
            playerGoalPx.Set((PLAYERGOALLEDS /2) + i, OFF);
            playerGoalLED.write(playerGoalPx.getBuf());
            wait(0.25);
        }

        WriteGoalsOff();
    }

    // Reset scores then write to LEDs
    robotScore = 0;
    playerScore = 0;
    WriteScores();
}

int main()
{
    setup();

    while(1) {
        double rbbValue = robotBreakBeam; // Read Robot Break beam
        double pbbValue = playerBreakBeam; // Read Player Break beam

        // IF PLAYER HAS SCORED A GOAL
        if ((prevRbbValue - rbbValue)>0.03) {
            pc.printf("Player has scored a goal \n\r");
            HandleGoal(false);
        }

        // IF ROBOT HAS SCORED A GOAL
        if ((prevPbbValue - pbbValue) > 0.03) {
            pc.printf("Robot has scored a goal \n\r");
            HandleGoal(true);
        }

        prevRbbValue = rbbValue;
        prevPbbValue = pbbValue;

        pc.printf("PlayerGoal: %f, RobotGoal: %f \r\n",pbbValue,rbbValue);
        pc.printf("Player: %i v %i : Robot \r\n",playerScore,robotScore);
        wait(0.02);

    }
}