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.

Files at this revision

API Documentation at this revision

Comitter:
pkoirala3
Date:
Sat Mar 18 14:36:05 2017 +0000
Parent:
4:9a4d22a279b3
Commit message:
Formatted ECE 2036 Lab3 MBED

Changed in this revision

4DGL-uLCD-SE.lib Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
Shiftbrite.h Show diff for this revision Revisions of this file
TMP36.h Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/4DGL-uLCD-SE.lib	Thu Jan 23 16:47:05 2014 +0000
+++ b/4DGL-uLCD-SE.lib	Sat Mar 18 14:36:05 2017 +0000
@@ -1,1 +1,1 @@
-https://mbed.org/users/4180_1/code/4DGL-uLCD-SE/#e39a44de229a
+https://mbed.org/users/4180_1/code/4DGL-uLCD-SE/#2cb1845d7681
--- a/SDFileSystem.lib	Thu Jan 23 16:47:05 2014 +0000
+++ b/SDFileSystem.lib	Sat Mar 18 14:36:05 2017 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/SDFileSystem/#c8f66dc765d4
+http://mbed.org/users/mbed_official/code/SDFileSystem/#8db0d3b02cec
--- a/Shiftbrite.h	Thu Jan 23 16:47:05 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-#include "mbed.h"
-
-//Setup a new class for a Shiftbrite RGB LED module
-class Shiftbrite
-{
-public:
-    Shiftbrite(PinName pin_e, PinName pin_l, PinName pin_do, PinName pin_di, PinName pin_clk);
-    void write(int red, int green, int blue);
-
-private:
-//class sets up the pins
-    DigitalOut _pin_e;
-    DigitalOut _pin_l;
-    SPI _spi;
-};
-
-Shiftbrite::Shiftbrite(PinName pin_e, PinName pin_l, PinName pin_do, PinName pin_di, PinName pin_clk)
-    : _pin_e(pin_e), _pin_l(pin_l), _spi(pin_do, pin_di, pin_clk)
-{
- // ADD CODE HERE
-}
-
-void Shiftbrite::write(int red, int green, int blue)
-{
- // ADD CODE HERE
-}
--- a/TMP36.h	Thu Jan 23 16:47:05 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-#include "mbed.h"
-
-//Setup a new class for TMP36 sensor
-class TMP36
-{
-public:
-    TMP36(PinName pin);
-    TMP36();
-    operator float ();
-    float read();
-private:
-//class sets up the AnalogIn pin
-    AnalogIn _pin;
-};
-
-TMP36::TMP36(PinName pin) : _pin(pin)
-{
-// _pin(pin) means pass pin to the AnalogIn constructor
-}
-
-float TMP36::read()
-{
-//convert sensor reading to temperature in degrees C
-    return ((_pin.read()*3.3)-0.500)*100.0;
-}
-//overload of float conversion (avoids needing to type .read() in equations)
-TMP36::operator float ()
-{
-//convert sensor reading to temperature in degrees C
-    return ((_pin.read()*3.3)-0.500)*100.0;
-}
\ No newline at end of file
--- a/main.cpp	Thu Jan 23 16:47:05 2014 +0000
+++ b/main.cpp	Sat Mar 18 14:36:05 2017 +0000
@@ -1,141 +1,210 @@
-// skeleton code for ECE 2036 thermostat lab
-// code must be added by students
 #include "mbed.h"
-#include "TMP36.h"
 #include "SDFileSystem.h"
 #include "uLCD_4DGL.h"
 #include "PinDetect.h"
 #include "Speaker.h"
-// must add your new class code to the project file Shiftbrite.h
-#include "Shiftbrite.h"
-
-// use class to setup temperature sensor pins
-TMP36 myTMP36(p15);  //Analog in
-
-// use class to setup microSD card filesystem
-SDFileSystem sd(p5, p6, p7, p8, "sd");
-
-// use class to setup the  Color LCD
-uLCD_4DGL uLCD(p28, p27, p29); // create a global uLCD object
-
-// use class to setup pushbuttons pins
-PinDetect pb1(p23);
-PinDetect pb2(p24);
-PinDetect pb3(p25);
-
-// use class to setup speaker pin
-Speaker mySpeaker(p21); //PWM out
-
-// use class to setup Shiftbrite pins
-Shiftbrite myShiftbrite(p9, p10, p11, p12, p13);// ei li di n/c ci
-
-// use class to setup Mbed's four on-board LEDs
-DigitalOut myLED1(LED1);
-DigitalOut myLED2(LED2);
-DigitalOut myLED3(LED3);
-DigitalOut myLED4(LED4);
-
-
+#include <cstdlib>
+#include <ctime>
 
-//also setting any unused analog input pins to digital outputs reduces A/D noise a bit
-//see http://mbed.org/users/chris/notebook/Getting-best-ADC-performance/
-DigitalOut P16(p16);
-DigitalOut P17(p17);
-DigitalOut P18(p18);
-DigitalOut P19(p19);
-DigitalOut P20(p20);
-
-
-
-
-// Global variables used in callbacks and main program
-// C variables in interrupt routines should use volatile keyword
-int volatile heat_setting=78; // heat to temp
-int volatile cool_setting=68; // cool to temp
-bool volatile mode=false; // heat or cool mode
+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);
 
-// Callback routine is interrupt activated by a debounced pb1 hit
-void pb1_hit_callback (void)
-{
-// ADD CODE HERE
-}
-// Callback routine is interrupt activated by a debounced pb2 hit
-void pb2_hit_callback (void)
-{
-// ADD CODE HERE
-}
-// Callback routine is interrupt activated by a debounced pb3 hit
-void pb3_hit_callback (void)
-{
-// ADD CODE HERE
-}
+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()
 {
-    float Current_temp=0.0;
+    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);
 
-    // Use internal pullups for the three pushbuttons
-    pb1.mode(PullUp);
-    pb2.mode(PullUp);
-    pb3.mode(PullUp);
-    // Delay for initial pullup to take effect
-    wait(.01);
-    // Setup Interrupt callback functions for a pb hit
-    pb1.attach_deasserted(&pb1_hit_callback);
-    pb2.attach_deasserted(&pb2_hit_callback);
-    pb3.attach_deasserted(&pb3_hit_callback);
-    // Start sampling pb inputs using interrupts
-    pb1.setSampleFrequency();
-    pb2.setSampleFrequency();
-    pb3.setSampleFrequency();
-    // pushbuttons now setup and running
+    // 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);
 
-    // start I/O examples - DELETE THIS IN YOUR CODE..BUT WILL USE THESE I/O IDEAS ELSEWHERE
-    // since all this compiles - the needed *.h files for these are in the project
-    //
-    Current_temp = myTMP36; //Read temp sensor
-    printf("Hello PC World\n\r"); // need terminal application running on PC to see this output
-    uLCD.printf("\n\rHello LCD World\n\r"); // LCD
-    mySpeaker.PlayNote(500.0, 1.0, 1.0); // Speaker buzz
-    myShiftbrite.write( 0, 50 ,0); // Green RGB LED
-    // SD card write file example - prints error message on PC when running until SD card hooked up
-    // Delete to avoid run time error
-    mkdir("/sd/mydir", 0777); // set up directory and permissions
-    FILE *fp = fopen("/sd/mydir/sdtest.txt", "w"); //open SD
-    if(fp == NULL) {
-        error("Could not open file for write\n");
+    // 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;
+        }
     }
-    fprintf(fp, "Hello SD Card World!"); // write SD
-    fclose(fp); // close SD card
-    //
-    // end I/O examples
-
-
+    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]);
+        }
+    }
 
-    // State machine code below will need changes and additions
-    while (1) {
-        {
-            enum Statetype { Heat_off = 0, Heat_on };
-            Statetype state = Heat_off;
-            while(1) {
-                switch (state) {
-                    case Heat_off:
-                        myLED4 = 0;
-                        state = Heat_on;
-                        break;
-                    case Heat_on:
-                        myLED4 = 1;
-                        state = Heat_off;
-                        break;
-                }
-                wait(0.33);
-                // heartbeat LED - common debug tool
-                // blinks as long as code is running and not locked up
-                myLED1=!myLED1;
+    // 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");
 }
\ No newline at end of file