This program is done as an Lab assignment for ECE2036.

Dependencies:   4DGL-uLCD-SE PinDetect SDFileSystem mbed

Fork of mythermostat by jim hamblen

This program is a lab assignment to ECE 2036. It uses uLCD, pushputtons and SDCard via sdFileSystem. This is designed as a concept to train animal that could be used by biologist to determine if lemurs have a concept of numbers. uLCD is divided into two different rectangle. In each rectangle, program generate random shapes of different color. Pushbutton is used to select which side has smaller number of shapes. Each trial, result is stored in sdCard as datalogging.

main.cpp

Committer:
pkoirala3
Date:
2017-03-18
Revision:
5:e3916a6d72b8
Parent:
4:9a4d22a279b3

File content as of revision 5:e3916a6d72b8:

#include "mbed.h"
#include "SDFileSystem.h"
#include "uLCD_4DGL.h"
#include "PinDetect.h"
#include "Speaker.h"
#include <cstdlib>
#include <ctime>

uLCD_4DGL uLCD(p28, p27, p29); // serial tx, serial rx, reset pin;
SDFileSystem sd(p5, p6, p7, p8, "sd");
AnalogIn noise(p20);    // For Random Number Generation
Timer timer;            // For measuring Elapsed time
DigitalIn pbLeft(p16);
DigitalIn pbRight(p17);
DigitalIn pbExit(p18);

int ObjLeftNum;
int ObjRightNum;
int CorrectNum = 0;
int TrialNum = 0;

int DrawWorld();
int ChooseSide();
void Print(int Result, int CompareMe, int netTime);
void ExitLemur();

int main()
{
    uLCD.display_GETOUT(PORTRAIT); // Portrait screen
    uLCD.background_color(RED);     // Background color Red
    uLCD.printf("Welcome Lemur!");  // Welcome message
    wait(2.0);                      // pause system for 2.0
    uLCD.cls();                     // clear screen

    // Seed of random number with the noise from pin20
    uint32_t seed = 0;
    for(int i = 0; i<32; ++i) {
        seed ^= noise.read_u16();
        if(seed & 1<31) {
            seed <<=1;
            seed |= 1;
        } else {
            seed <<= 1;
        }
    }
    srand(seed);

    // Calling the Game functions and it's implementation
    int Result, CompareMe, startT, endT;        // Local vars
    while(CompareMe != 3) {         // Check untill user presses the exit pushbutton
        Result = DrawWorld();       // Drawing two rectangles
        timer.start();              // Starting timer to keep track how much time taken
        startT = timer.read_ms();
        CompareMe = ChooseSide();   // Lemur decide
        endT = timer.read_ms();
        timer.stop();               // End of timer
        if (CompareMe != 3) {
            ++TrialNum;             // Update trail numbers
            Print(Result, CompareMe, endT-startT);      // Print result
        }
    }
    ExitLemur();    // Execute after user pressed exit button
}

int DrawWorld()
{
    // Drawing two rectangles
    uLCD.rectangle(2, 4, 62, 124, WHITE);
    uLCD.rectangle(64, 4, 124, 124, WHITE);

    // Defining co-ordinate map vectors
    int LeftX[18] = {12, 32, 52, 12, 32, 52, 12, 32, 52, 12, 32, 52, 12, 32, 52, 12, 32, 52};
    int RightX[18] = {74, 94, 114, 74, 94, 114, 74, 94, 114, 74, 94, 114, 74, 94, 114, 74, 94, 114};
    int Y[18] = {14, 14, 14, 34, 34, 34, 54, 54, 54, 74, 74, 74, 94, 94, 94, 114, 114, 114};

    // Left bin objects
    ObjLeftNum = rand()%15 + 1;
    bool valid;
    while(true) {
        ObjRightNum = rand()%15 + 1;
        if(!(ObjRightNum == ObjLeftNum)) {
            break;
        }
    }
    int color[6] = {BLACK,LGREY,DGREY, GREEN, BLUE,WHITE};      // six different color
    int LNum, RNum, Shape, Radius, ColorIdx;
    bool Flag[18] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};;

    // draw left bin objects
    for (int i = 0; i < ObjLeftNum; i++) {
        do {
            valid = false;
            LNum = rand()%18;
            if (Flag[LNum]) {
                valid = true;
            }
        } while(valid);
        Flag[LNum] = true;
        ColorIdx = rand()%6;
        Shape = rand()%3;
        Radius = rand()%9 + 1;
        if (Shape == 0) {
            uLCD.filled_circle(LeftX[LNum],Y[LNum], Radius, color[ColorIdx]);
        } else if (Shape == 1) {
            uLCD.triangle(LeftX[LNum], Y[LNum] + Radius, LeftX[LNum]-Radius, Y[LNum]-Radius, LeftX[LNum]+Radius,Y[LNum]-Radius, color[ColorIdx]);
        } else {
            uLCD.filled_rectangle(LeftX[LNum]-Radius, Y[LNum] + Radius, LeftX[LNum]+Radius, Y[LNum]-Radius, color[ColorIdx]);
        }
    }

    // draw right bin objects
    for (int i = 0; i < 18; i++) {
        Flag[i] = false;
    }
    for (int i = 0; i < ObjRightNum; i++) {
        while(true) {
            RNum = rand()%18;
            if(!Flag[RNum]) {
                break;
            }
        }
        Flag[RNum] = true;
        Radius = rand()%9 + 1;
        ColorIdx = rand()%6;
        Shape = rand()%3;
        if (Shape == 0) {
            uLCD.filled_circle(RightX[RNum],Y[RNum], Radius, color[ColorIdx]);
        } else if (Shape == 1) {
            uLCD.triangle(RightX[RNum], Y[RNum] + Radius,RightX[RNum]-Radius, Y[RNum]-Radius, RightX[RNum]+Radius,Y[RNum]-Radius, color[ColorIdx]);
        } else {
            uLCD.filled_rectangle(RightX[RNum]-Radius, Y[RNum] + Radius, RightX[RNum]+Radius, Y[RNum]-Radius, color[ColorIdx]);
        }
    }
    // Comparing number of objects in left and right
    if (ObjLeftNum < ObjRightNum) {
        return 1;
    } else {
        return 2;
    }
}

// This return what button is pressed and GETOUT to be performed
int ChooseSide()
{
    pbLeft.mode(PullUp);
    pbRight.mode(PullUp);
    pbExit.mode(PullUp);

    // Implementation of left, right and exit buttons
    bool GETOUT = false;
    int Choose = 0;
    while(!GETOUT) {
        if(!pbLeft) {
            GETOUT = true;
            Choose = 1;     // Choosing left button
        }
        if(!pbRight) {
            GETOUT = true;
            Choose = 2;     // Choosing right button
        }
        if(!pbExit) {
            GETOUT = true;
            Choose = 3;     // Choosing Exit button
        }
    }
    return Choose;
}

// To Print out the Results such as: if Lemur is correct or not,
// Num of objs in each bin, time taken, number of trials, accuracy
void Print(int Result, int CompareMe, int netTime)
{
    uLCD.cls();
    // Compare the Lemur choise
    if (Result == CompareMe) {              // if Correct
        ++CorrectNum;                       // Increase CorrectNumber by 1
        uLCD.printf("Correct Lemur!!\n\n");
    } else {                                // If incorrect
        uLCD.printf("Incorrect Lemur!!\n\n");
    }
    double Accuracy = (double)CorrectNum/TrialNum;  // Calculate Accuracy
    uLCD.printf("ObjInLeft:  %i\nObjInRight:  %i\nDelay(ms): %d\n", ObjLeftNum, ObjRightNum,netTime);
    uLCD.printf("TrialNum: %i\nAccuracy: %.2f\n\n", TrialNum, Accuracy);

    mkdir("/sd/mydir/LemurResults.txt", 0777);
    FILE *fp = fopen("/sd/mydir/LemurResults.txt", "a");
    if(fp == NULL) {
        uLCD.printf("Error Open \n");
    }
    if (Result == CompareMe) {
        fprintf(fp, "Correct Lemur!!\n");
    } else {
        fprintf(fp, "Incorrect Lemur!!\n");
    }
    fprintf(fp,"LObj: %i RObj: %i Trial#: %i Accur: %#.2f Delay(ms): %i\n\n\n",ObjLeftNum, ObjRightNum, TrialNum, (double)CorrectNum/(TrialNum),netTime);
    fclose(fp);

    wait(1.0);
    uLCD.cls();
}

// Exiting the game with message
void ExitLemur()
{
    uLCD.cls();
    uLCD.text_width(1.8);
    uLCD.text_height(2);
    uLCD.color(WHITE);
    uLCD.printf("\nBYE LEMUR\n\nTake a break!\n");
}