This program is done as an Lab assignment for ECE2036.
Dependencies: 4DGL-uLCD-SE PinDetect SDFileSystem mbed
Fork of mythermostat by
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@5:e3916a6d72b8, 2017-03-18 (annotated)
- 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?
User | Revision | Line number | New 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 | } |