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.

Committer:
pkoirala3
Date:
Sat Mar 18 14:36:05 2017 +0000
Revision:
5:e3916a6d72b8
Parent:
4:9a4d22a279b3
Formatted ECE 2036 Lab3 MBED

Who changed what in which revision?

UserRevisionLine numberNew contents of line
4180_1 0:cc87c48aa43c 1 #include "mbed.h"
4180_1 2:58d85409f7ff 2 #include "SDFileSystem.h"
4180_1 4:9a4d22a279b3 3 #include "uLCD_4DGL.h"
4180_1 0:cc87c48aa43c 4 #include "PinDetect.h"
4180_1 2:58d85409f7ff 5 #include "Speaker.h"
pkoirala3 5:e3916a6d72b8 6 #include <cstdlib>
pkoirala3 5:e3916a6d72b8 7 #include <ctime>
4180_1 0:cc87c48aa43c 8
pkoirala3 5:e3916a6d72b8 9 uLCD_4DGL uLCD(p28, p27, p29); // serial tx, serial rx, reset pin;
pkoirala3 5:e3916a6d72b8 10 SDFileSystem sd(p5, p6, p7, p8, "sd");
pkoirala3 5:e3916a6d72b8 11 AnalogIn noise(p20); // For Random Number Generation
pkoirala3 5:e3916a6d72b8 12 Timer timer; // For measuring Elapsed time
pkoirala3 5:e3916a6d72b8 13 DigitalIn pbLeft(p16);
pkoirala3 5:e3916a6d72b8 14 DigitalIn pbRight(p17);
pkoirala3 5:e3916a6d72b8 15 DigitalIn pbExit(p18);
4180_1 0:cc87c48aa43c 16
pkoirala3 5:e3916a6d72b8 17 int ObjLeftNum;
pkoirala3 5:e3916a6d72b8 18 int ObjRightNum;
pkoirala3 5:e3916a6d72b8 19 int CorrectNum = 0;
pkoirala3 5:e3916a6d72b8 20 int TrialNum = 0;
4180_1 2:58d85409f7ff 21
pkoirala3 5:e3916a6d72b8 22 int DrawWorld();
pkoirala3 5:e3916a6d72b8 23 int ChooseSide();
pkoirala3 5:e3916a6d72b8 24 void Print(int Result, int CompareMe, int netTime);
pkoirala3 5:e3916a6d72b8 25 void ExitLemur();
4180_1 0:cc87c48aa43c 26
4180_1 2:58d85409f7ff 27 int main()
4180_1 2:58d85409f7ff 28 {
pkoirala3 5:e3916a6d72b8 29 uLCD.display_GETOUT(PORTRAIT); // Portrait screen
pkoirala3 5:e3916a6d72b8 30 uLCD.background_color(RED); // Background color Red
pkoirala3 5:e3916a6d72b8 31 uLCD.printf("Welcome Lemur!"); // Welcome message
pkoirala3 5:e3916a6d72b8 32 wait(2.0); // pause system for 2.0
pkoirala3 5:e3916a6d72b8 33 uLCD.cls(); // clear screen
pkoirala3 5:e3916a6d72b8 34
pkoirala3 5:e3916a6d72b8 35 // Seed of random number with the noise from pin20
pkoirala3 5:e3916a6d72b8 36 uint32_t seed = 0;
pkoirala3 5:e3916a6d72b8 37 for(int i = 0; i<32; ++i) {
pkoirala3 5:e3916a6d72b8 38 seed ^= noise.read_u16();
pkoirala3 5:e3916a6d72b8 39 if(seed & 1<31) {
pkoirala3 5:e3916a6d72b8 40 seed <<=1;
pkoirala3 5:e3916a6d72b8 41 seed |= 1;
pkoirala3 5:e3916a6d72b8 42 } else {
pkoirala3 5:e3916a6d72b8 43 seed <<= 1;
pkoirala3 5:e3916a6d72b8 44 }
pkoirala3 5:e3916a6d72b8 45 }
pkoirala3 5:e3916a6d72b8 46 srand(seed);
4180_1 2:58d85409f7ff 47
pkoirala3 5:e3916a6d72b8 48 // Calling the Game functions and it's implementation
pkoirala3 5:e3916a6d72b8 49 int Result, CompareMe, startT, endT; // Local vars
pkoirala3 5:e3916a6d72b8 50 while(CompareMe != 3) { // Check untill user presses the exit pushbutton
pkoirala3 5:e3916a6d72b8 51 Result = DrawWorld(); // Drawing two rectangles
pkoirala3 5:e3916a6d72b8 52 timer.start(); // Starting timer to keep track how much time taken
pkoirala3 5:e3916a6d72b8 53 startT = timer.read_ms();
pkoirala3 5:e3916a6d72b8 54 CompareMe = ChooseSide(); // Lemur decide
pkoirala3 5:e3916a6d72b8 55 endT = timer.read_ms();
pkoirala3 5:e3916a6d72b8 56 timer.stop(); // End of timer
pkoirala3 5:e3916a6d72b8 57 if (CompareMe != 3) {
pkoirala3 5:e3916a6d72b8 58 ++TrialNum; // Update trail numbers
pkoirala3 5:e3916a6d72b8 59 Print(Result, CompareMe, endT-startT); // Print result
pkoirala3 5:e3916a6d72b8 60 }
pkoirala3 5:e3916a6d72b8 61 }
pkoirala3 5:e3916a6d72b8 62 ExitLemur(); // Execute after user pressed exit button
pkoirala3 5:e3916a6d72b8 63 }
4180_1 2:58d85409f7ff 64
pkoirala3 5:e3916a6d72b8 65 int DrawWorld()
pkoirala3 5:e3916a6d72b8 66 {
pkoirala3 5:e3916a6d72b8 67 // Drawing two rectangles
pkoirala3 5:e3916a6d72b8 68 uLCD.rectangle(2, 4, 62, 124, WHITE);
pkoirala3 5:e3916a6d72b8 69 uLCD.rectangle(64, 4, 124, 124, WHITE);
4180_1 2:58d85409f7ff 70
pkoirala3 5:e3916a6d72b8 71 // Defining co-ordinate map vectors
pkoirala3 5:e3916a6d72b8 72 int LeftX[18] = {12, 32, 52, 12, 32, 52, 12, 32, 52, 12, 32, 52, 12, 32, 52, 12, 32, 52};
pkoirala3 5:e3916a6d72b8 73 int RightX[18] = {74, 94, 114, 74, 94, 114, 74, 94, 114, 74, 94, 114, 74, 94, 114, 74, 94, 114};
pkoirala3 5:e3916a6d72b8 74 int Y[18] = {14, 14, 14, 34, 34, 34, 54, 54, 54, 74, 74, 74, 94, 94, 94, 114, 114, 114};
pkoirala3 5:e3916a6d72b8 75
pkoirala3 5:e3916a6d72b8 76 // Left bin objects
pkoirala3 5:e3916a6d72b8 77 ObjLeftNum = rand()%15 + 1;
pkoirala3 5:e3916a6d72b8 78 bool valid;
pkoirala3 5:e3916a6d72b8 79 while(true) {
pkoirala3 5:e3916a6d72b8 80 ObjRightNum = rand()%15 + 1;
pkoirala3 5:e3916a6d72b8 81 if(!(ObjRightNum == ObjLeftNum)) {
pkoirala3 5:e3916a6d72b8 82 break;
pkoirala3 5:e3916a6d72b8 83 }
4180_1 2:58d85409f7ff 84 }
pkoirala3 5:e3916a6d72b8 85 int color[6] = {BLACK,LGREY,DGREY, GREEN, BLUE,WHITE}; // six different color
pkoirala3 5:e3916a6d72b8 86 int LNum, RNum, Shape, Radius, ColorIdx;
pkoirala3 5:e3916a6d72b8 87 bool Flag[18] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};;
4180_1 2:58d85409f7ff 88
pkoirala3 5:e3916a6d72b8 89 // draw left bin objects
pkoirala3 5:e3916a6d72b8 90 for (int i = 0; i < ObjLeftNum; i++) {
pkoirala3 5:e3916a6d72b8 91 do {
pkoirala3 5:e3916a6d72b8 92 valid = false;
pkoirala3 5:e3916a6d72b8 93 LNum = rand()%18;
pkoirala3 5:e3916a6d72b8 94 if (Flag[LNum]) {
pkoirala3 5:e3916a6d72b8 95 valid = true;
pkoirala3 5:e3916a6d72b8 96 }
pkoirala3 5:e3916a6d72b8 97 } while(valid);
pkoirala3 5:e3916a6d72b8 98 Flag[LNum] = true;
pkoirala3 5:e3916a6d72b8 99 ColorIdx = rand()%6;
pkoirala3 5:e3916a6d72b8 100 Shape = rand()%3;
pkoirala3 5:e3916a6d72b8 101 Radius = rand()%9 + 1;
pkoirala3 5:e3916a6d72b8 102 if (Shape == 0) {
pkoirala3 5:e3916a6d72b8 103 uLCD.filled_circle(LeftX[LNum],Y[LNum], Radius, color[ColorIdx]);
pkoirala3 5:e3916a6d72b8 104 } else if (Shape == 1) {
pkoirala3 5:e3916a6d72b8 105 uLCD.triangle(LeftX[LNum], Y[LNum] + Radius, LeftX[LNum]-Radius, Y[LNum]-Radius, LeftX[LNum]+Radius,Y[LNum]-Radius, color[ColorIdx]);
pkoirala3 5:e3916a6d72b8 106 } else {
pkoirala3 5:e3916a6d72b8 107 uLCD.filled_rectangle(LeftX[LNum]-Radius, Y[LNum] + Radius, LeftX[LNum]+Radius, Y[LNum]-Radius, color[ColorIdx]);
pkoirala3 5:e3916a6d72b8 108 }
pkoirala3 5:e3916a6d72b8 109 }
4180_1 2:58d85409f7ff 110
pkoirala3 5:e3916a6d72b8 111 // draw right bin objects
pkoirala3 5:e3916a6d72b8 112 for (int i = 0; i < 18; i++) {
pkoirala3 5:e3916a6d72b8 113 Flag[i] = false;
pkoirala3 5:e3916a6d72b8 114 }
pkoirala3 5:e3916a6d72b8 115 for (int i = 0; i < ObjRightNum; i++) {
pkoirala3 5:e3916a6d72b8 116 while(true) {
pkoirala3 5:e3916a6d72b8 117 RNum = rand()%18;
pkoirala3 5:e3916a6d72b8 118 if(!Flag[RNum]) {
pkoirala3 5:e3916a6d72b8 119 break;
4180_1 2:58d85409f7ff 120 }
4180_1 2:58d85409f7ff 121 }
pkoirala3 5:e3916a6d72b8 122 Flag[RNum] = true;
pkoirala3 5:e3916a6d72b8 123 Radius = rand()%9 + 1;
pkoirala3 5:e3916a6d72b8 124 ColorIdx = rand()%6;
pkoirala3 5:e3916a6d72b8 125 Shape = rand()%3;
pkoirala3 5:e3916a6d72b8 126 if (Shape == 0) {
pkoirala3 5:e3916a6d72b8 127 uLCD.filled_circle(RightX[RNum],Y[RNum], Radius, color[ColorIdx]);
pkoirala3 5:e3916a6d72b8 128 } else if (Shape == 1) {
pkoirala3 5:e3916a6d72b8 129 uLCD.triangle(RightX[RNum], Y[RNum] + Radius,RightX[RNum]-Radius, Y[RNum]-Radius, RightX[RNum]+Radius,Y[RNum]-Radius, color[ColorIdx]);
pkoirala3 5:e3916a6d72b8 130 } else {
pkoirala3 5:e3916a6d72b8 131 uLCD.filled_rectangle(RightX[RNum]-Radius, Y[RNum] + Radius, RightX[RNum]+Radius, Y[RNum]-Radius, color[ColorIdx]);
pkoirala3 5:e3916a6d72b8 132 }
4180_1 0:cc87c48aa43c 133 }
pkoirala3 5:e3916a6d72b8 134 // Comparing number of objects in left and right
pkoirala3 5:e3916a6d72b8 135 if (ObjLeftNum < ObjRightNum) {
pkoirala3 5:e3916a6d72b8 136 return 1;
pkoirala3 5:e3916a6d72b8 137 } else {
pkoirala3 5:e3916a6d72b8 138 return 2;
pkoirala3 5:e3916a6d72b8 139 }
pkoirala3 5:e3916a6d72b8 140 }
pkoirala3 5:e3916a6d72b8 141
pkoirala3 5:e3916a6d72b8 142 // This return what button is pressed and GETOUT to be performed
pkoirala3 5:e3916a6d72b8 143 int ChooseSide()
pkoirala3 5:e3916a6d72b8 144 {
pkoirala3 5:e3916a6d72b8 145 pbLeft.mode(PullUp);
pkoirala3 5:e3916a6d72b8 146 pbRight.mode(PullUp);
pkoirala3 5:e3916a6d72b8 147 pbExit.mode(PullUp);
pkoirala3 5:e3916a6d72b8 148
pkoirala3 5:e3916a6d72b8 149 // Implementation of left, right and exit buttons
pkoirala3 5:e3916a6d72b8 150 bool GETOUT = false;
pkoirala3 5:e3916a6d72b8 151 int Choose = 0;
pkoirala3 5:e3916a6d72b8 152 while(!GETOUT) {
pkoirala3 5:e3916a6d72b8 153 if(!pbLeft) {
pkoirala3 5:e3916a6d72b8 154 GETOUT = true;
pkoirala3 5:e3916a6d72b8 155 Choose = 1; // Choosing left button
pkoirala3 5:e3916a6d72b8 156 }
pkoirala3 5:e3916a6d72b8 157 if(!pbRight) {
pkoirala3 5:e3916a6d72b8 158 GETOUT = true;
pkoirala3 5:e3916a6d72b8 159 Choose = 2; // Choosing right button
pkoirala3 5:e3916a6d72b8 160 }
pkoirala3 5:e3916a6d72b8 161 if(!pbExit) {
pkoirala3 5:e3916a6d72b8 162 GETOUT = true;
pkoirala3 5:e3916a6d72b8 163 Choose = 3; // Choosing Exit button
pkoirala3 5:e3916a6d72b8 164 }
pkoirala3 5:e3916a6d72b8 165 }
pkoirala3 5:e3916a6d72b8 166 return Choose;
pkoirala3 5:e3916a6d72b8 167 }
pkoirala3 5:e3916a6d72b8 168
pkoirala3 5:e3916a6d72b8 169 // To Print out the Results such as: if Lemur is correct or not,
pkoirala3 5:e3916a6d72b8 170 // Num of objs in each bin, time taken, number of trials, accuracy
pkoirala3 5:e3916a6d72b8 171 void Print(int Result, int CompareMe, int netTime)
pkoirala3 5:e3916a6d72b8 172 {
pkoirala3 5:e3916a6d72b8 173 uLCD.cls();
pkoirala3 5:e3916a6d72b8 174 // Compare the Lemur choise
pkoirala3 5:e3916a6d72b8 175 if (Result == CompareMe) { // if Correct
pkoirala3 5:e3916a6d72b8 176 ++CorrectNum; // Increase CorrectNumber by 1
pkoirala3 5:e3916a6d72b8 177 uLCD.printf("Correct Lemur!!\n\n");
pkoirala3 5:e3916a6d72b8 178 } else { // If incorrect
pkoirala3 5:e3916a6d72b8 179 uLCD.printf("Incorrect Lemur!!\n\n");
pkoirala3 5:e3916a6d72b8 180 }
pkoirala3 5:e3916a6d72b8 181 double Accuracy = (double)CorrectNum/TrialNum; // Calculate Accuracy
pkoirala3 5:e3916a6d72b8 182 uLCD.printf("ObjInLeft: %i\nObjInRight: %i\nDelay(ms): %d\n", ObjLeftNum, ObjRightNum,netTime);
pkoirala3 5:e3916a6d72b8 183 uLCD.printf("TrialNum: %i\nAccuracy: %.2f\n\n", TrialNum, Accuracy);
pkoirala3 5:e3916a6d72b8 184
pkoirala3 5:e3916a6d72b8 185 mkdir("/sd/mydir/LemurResults.txt", 0777);
pkoirala3 5:e3916a6d72b8 186 FILE *fp = fopen("/sd/mydir/LemurResults.txt", "a");
pkoirala3 5:e3916a6d72b8 187 if(fp == NULL) {
pkoirala3 5:e3916a6d72b8 188 uLCD.printf("Error Open \n");
pkoirala3 5:e3916a6d72b8 189 }
pkoirala3 5:e3916a6d72b8 190 if (Result == CompareMe) {
pkoirala3 5:e3916a6d72b8 191 fprintf(fp, "Correct Lemur!!\n");
pkoirala3 5:e3916a6d72b8 192 } else {
pkoirala3 5:e3916a6d72b8 193 fprintf(fp, "Incorrect Lemur!!\n");
pkoirala3 5:e3916a6d72b8 194 }
pkoirala3 5:e3916a6d72b8 195 fprintf(fp,"LObj: %i RObj: %i Trial#: %i Accur: %#.2f Delay(ms): %i\n\n\n",ObjLeftNum, ObjRightNum, TrialNum, (double)CorrectNum/(TrialNum),netTime);
pkoirala3 5:e3916a6d72b8 196 fclose(fp);
pkoirala3 5:e3916a6d72b8 197
pkoirala3 5:e3916a6d72b8 198 wait(1.0);
pkoirala3 5:e3916a6d72b8 199 uLCD.cls();
pkoirala3 5:e3916a6d72b8 200 }
pkoirala3 5:e3916a6d72b8 201
pkoirala3 5:e3916a6d72b8 202 // Exiting the game with message
pkoirala3 5:e3916a6d72b8 203 void ExitLemur()
pkoirala3 5:e3916a6d72b8 204 {
pkoirala3 5:e3916a6d72b8 205 uLCD.cls();
pkoirala3 5:e3916a6d72b8 206 uLCD.text_width(1.8);
pkoirala3 5:e3916a6d72b8 207 uLCD.text_height(2);
pkoirala3 5:e3916a6d72b8 208 uLCD.color(WHITE);
pkoirala3 5:e3916a6d72b8 209 uLCD.printf("\nBYE LEMUR\n\nTake a break!\n");
4180_1 0:cc87c48aa43c 210 }