Code for a robotic pet to interact with.

Dependencies:   mbed wave_player Servo Motordriver mbed-rtos 4DGL-uLCD-SE SDFileSystem_OldbutworkswithRTOS HC_SR04_Ultrasonic_Library

Committer:
jprocter3
Date:
Sat Apr 20 21:55:34 2019 +0000
Revision:
14:7e45dbeb0acf
Parent:
12:492f2a122e39
Child:
15:02e772571d48
Worked on some timings, screen sizes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jprocter3 0:7b070cdce8bd 1 #include "mbed.h"
skrgo3 7:7050d3c2b720 2 #include "motordriver.h"
jprocter3 0:7b070cdce8bd 3 #include "rtos.h"
jprocter3 0:7b070cdce8bd 4 #include "uLCD_4DGL.h"
jprocter3 5:d7b32a06799d 5 #include "mpr121.h"
skrgo3 1:a2a5171ac99f 6 #include "ultrasonic.h"
jprocter3 12:492f2a122e39 7 #include "SDFileSystem.h"
jprocter3 12:492f2a122e39 8 #include "wave_player.h"
jprocter3 11:aa6d9d72b5a2 9 uLCD_4DGL uLCD(p13,p14,p29); // serial tx, serial rx, reset pin;
jprocter3 12:492f2a122e39 10 SDFileSystem sd(p5, p6, p7, p21, "sd"); //SD card
jprocter3 12:492f2a122e39 11 AnalogOut DACout(p18);
jprocter3 12:492f2a122e39 12 wave_player waver(&DACout);
jprocter3 11:aa6d9d72b5a2 13 Motor m1(p23, p30, p8, 1); // pwm, fwd, rev
skrgo3 7:7050d3c2b720 14 Motor m2(p24, p9, p10, 1); // pwm, fwd, rev
jprocter3 11:aa6d9d72b5a2 15 InterruptIn interrupt(p26);
jprocter3 11:aa6d9d72b5a2 16 I2C i2c(p28, p27);
jprocter3 11:aa6d9d72b5a2 17 Mpr121 mpr121(&i2c, Mpr121::ADD_VSS);
jprocter3 0:7b070cdce8bd 18
jprocter3 0:7b070cdce8bd 19 DigitalOut led1(LED1);
jprocter3 0:7b070cdce8bd 20 DigitalOut led2(LED2);
jprocter3 0:7b070cdce8bd 21 DigitalOut led3(LED3);
jprocter3 0:7b070cdce8bd 22 DigitalOut led4(LED4);
jprocter3 0:7b070cdce8bd 23
jprocter3 2:672f7335a017 24 enum {ROAM, STOP, SLEEP};
jprocter3 9:8a5b623fff86 25 volatile int state;
jprocter3 2:672f7335a017 26
jprocter3 8:ddddef6634cd 27 volatile int energy;
jprocter3 6:93e21d47480b 28 volatile bool touched;
jprocter3 2:672f7335a017 29 volatile bool fed;
jprocter3 11:aa6d9d72b5a2 30 volatile bool touchpad;
jprocter3 0:7b070cdce8bd 31
jprocter3 11:aa6d9d72b5a2 32 void fallInterrupt() {
jprocter3 11:aa6d9d72b5a2 33 touchpad = true;
jprocter3 11:aa6d9d72b5a2 34 }
jprocter3 11:aa6d9d72b5a2 35
jprocter3 11:aa6d9d72b5a2 36 void dist(int distance) {
jprocter3 9:8a5b623fff86 37 //control wheels
skrgo3 7:7050d3c2b720 38 if (state == ROAM) {
skrgo3 7:7050d3c2b720 39 if(distance < 250) {
skrgo3 7:7050d3c2b720 40 m1.stop(0);
skrgo3 7:7050d3c2b720 41 m2.stop(0);
skrgo3 7:7050d3c2b720 42 Thread::wait(100);
skrgo3 7:7050d3c2b720 43 m1.speed(.75);
skrgo3 7:7050d3c2b720 44 m2.speed(-.75);
skrgo3 7:7050d3c2b720 45 Thread::wait(500);
jprocter3 9:8a5b623fff86 46 } else {
jprocter3 9:8a5b623fff86 47 m1.speed(.5);
jprocter3 9:8a5b623fff86 48 m2.speed(.5);
jprocter3 9:8a5b623fff86 49 }
jprocter3 8:ddddef6634cd 50 } else { // stop for STOP and SLEEP
jprocter3 8:ddddef6634cd 51 m1.stop(0);
jprocter3 8:ddddef6634cd 52 m2.stop(0);
jprocter3 8:ddddef6634cd 53 }
jprocter3 9:8a5b623fff86 54
jprocter3 8:ddddef6634cd 55 if (state == STOP && distance < 60) {
skrgo3 1:a2a5171ac99f 56 //increase food status
jprocter3 5:d7b32a06799d 57 fed = true;
jprocter3 5:d7b32a06799d 58 Thread::wait(3000); // make sure fed state lasts atleast 3 seconds
jprocter3 5:d7b32a06799d 59 fed = false;
skrgo3 1:a2a5171ac99f 60 }
skrgo3 1:a2a5171ac99f 61 }
jprocter3 8:ddddef6634cd 62
jprocter3 10:29a382784838 63 ultrasonic mu(p11, p12, .1, 1, &dist);
jprocter3 0:7b070cdce8bd 64
jprocter3 0:7b070cdce8bd 65 void sonar(void const *argument) {
jprocter3 5:d7b32a06799d 66 while(1) {
skrgo3 1:a2a5171ac99f 67 mu.checkDistance();
skrgo3 1:a2a5171ac99f 68 Thread::wait(100);
skrgo3 1:a2a5171ac99f 69 }
jprocter3 0:7b070cdce8bd 70 }
jprocter3 0:7b070cdce8bd 71
jprocter3 11:aa6d9d72b5a2 72 void touch(void const *argument) {
jprocter3 11:aa6d9d72b5a2 73 while(1) {
jprocter3 11:aa6d9d72b5a2 74 if (touchpad) {
jprocter3 11:aa6d9d72b5a2 75 touched = true;
jprocter3 11:aa6d9d72b5a2 76 Thread::wait(5000);
jprocter3 11:aa6d9d72b5a2 77 touchpad = false;
jprocter3 11:aa6d9d72b5a2 78 } else {
jprocter3 11:aa6d9d72b5a2 79 touched = false;
jprocter3 11:aa6d9d72b5a2 80 }
jprocter3 11:aa6d9d72b5a2 81 Thread::wait(100); // runs 10 times a second
jprocter3 11:aa6d9d72b5a2 82 }
jprocter3 11:aa6d9d72b5a2 83 }
jprocter3 0:7b070cdce8bd 84
jprocter3 11:aa6d9d72b5a2 85 void screen(void const *argument) {
jprocter3 11:aa6d9d72b5a2 86 while(1) {
jprocter3 11:aa6d9d72b5a2 87 uLCD.filled_rectangle(0, 0, 127, 127, BLACK); // clear screen
jprocter3 11:aa6d9d72b5a2 88 switch(state) {
jprocter3 11:aa6d9d72b5a2 89 case ROAM: {
jprocter3 14:7e45dbeb0acf 90 uLCD.circle(64, 64, 30, BLUE); // blue circle in the center
jprocter3 14:7e45dbeb0acf 91 uLCD.filled_circle(64, 64, 5, BLUE); // blue circle in the center
jprocter3 11:aa6d9d72b5a2 92 } break;
jprocter3 11:aa6d9d72b5a2 93 case STOP: {
jprocter3 11:aa6d9d72b5a2 94 uLCD.locate(0,0);
jprocter3 14:7e45dbeb0acf 95 uLCD.text_width(12);
jprocter3 14:7e45dbeb0acf 96 uLCD.text_height(12);
jprocter3 14:7e45dbeb0acf 97 if (fed || touched) { // touched or fed
jprocter3 14:7e45dbeb0acf 98 uLCD.text_width(9);
jprocter3 14:7e45dbeb0acf 99 uLCD.text_height(9);
jprocter3 14:7e45dbeb0acf 100 uLCD.color(RED);
jprocter3 14:7e45dbeb0acf 101 uLCD.printf("<3");
jprocter3 14:7e45dbeb0acf 102 } else if (energy < 30) { // tired
jprocter3 11:aa6d9d72b5a2 103 uLCD.color(RED+GREEN);
jprocter3 11:aa6d9d72b5a2 104 uLCD.printf("0"); // yellow 0's
jprocter3 11:aa6d9d72b5a2 105 } else { // wondering
jprocter3 11:aa6d9d72b5a2 106 uLCD.color(BLUE);
jprocter3 11:aa6d9d72b5a2 107 uLCD.printf("?"); // blue ?'s
jprocter3 11:aa6d9d72b5a2 108 }
jprocter3 11:aa6d9d72b5a2 109 } break;
jprocter3 11:aa6d9d72b5a2 110 case SLEEP: {
jprocter3 11:aa6d9d72b5a2 111 uLCD.locate(0,0);
jprocter3 14:7e45dbeb0acf 112 uLCD.text_width(12);
jprocter3 14:7e45dbeb0acf 113 uLCD.text_height(12);
jprocter3 11:aa6d9d72b5a2 114 uLCD.color(BLUE);
jprocter3 11:aa6d9d72b5a2 115 uLCD.printf("Z"); // blue Z's
jprocter3 11:aa6d9d72b5a2 116 }
jprocter3 11:aa6d9d72b5a2 117 }
jprocter3 11:aa6d9d72b5a2 118
jprocter3 11:aa6d9d72b5a2 119 Thread::wait(100);
jprocter3 11:aa6d9d72b5a2 120 }
jprocter3 11:aa6d9d72b5a2 121 }
jprocter3 11:aa6d9d72b5a2 122
jprocter3 12:492f2a122e39 123 void sound(void const *argument) {
jprocter3 12:492f2a122e39 124 FILE *wave_file;
jprocter3 12:492f2a122e39 125 while(1) {
jprocter3 12:492f2a122e39 126 switch(state) {
jprocter3 12:492f2a122e39 127 case STOP: {
jprocter3 14:7e45dbeb0acf 128 if (fed) { // fed
jprocter3 12:492f2a122e39 129 wave_file=fopen("/sd/eat.wav","r"); // 2 seconds
jprocter3 12:492f2a122e39 130 } else if (touched) { // touched
jprocter3 12:492f2a122e39 131 wave_file=fopen("/sd/purr.wav","r"); // 3 seconds
jprocter3 14:7e45dbeb0acf 132 } else if (energy < 30) { // tired
jprocter3 14:7e45dbeb0acf 133 wave_file=fopen("/sd/bark.wav","r"); // < 1 second
jprocter3 14:7e45dbeb0acf 134 Thread::wait(500);
jprocter3 12:492f2a122e39 135 } else { // wondering
jprocter3 12:492f2a122e39 136 wave_file=fopen("/sd/curious.wav","r"); // 1 second
jprocter3 14:7e45dbeb0acf 137 Thread::wait(1000);
jprocter3 12:492f2a122e39 138 }
jprocter3 12:492f2a122e39 139 waver.play(wave_file);
jprocter3 12:492f2a122e39 140 fclose(wave_file);
jprocter3 12:492f2a122e39 141 } break;
jprocter3 12:492f2a122e39 142 case SLEEP: {
jprocter3 12:492f2a122e39 143 wave_file=fopen("/sd/sleep.wav","r"); // 8 seconds
jprocter3 12:492f2a122e39 144 waver.play(wave_file);
jprocter3 12:492f2a122e39 145 fclose(wave_file);
jprocter3 12:492f2a122e39 146 }
jprocter3 12:492f2a122e39 147 }
jprocter3 12:492f2a122e39 148
jprocter3 12:492f2a122e39 149 Thread::wait(100);
jprocter3 12:492f2a122e39 150 }
jprocter3 12:492f2a122e39 151 }
jprocter3 0:7b070cdce8bd 152
jprocter3 0:7b070cdce8bd 153 int main() {
jprocter3 11:aa6d9d72b5a2 154 uLCD.cls();
jprocter3 11:aa6d9d72b5a2 155 uLCD.printf("Change baudrate.....");
jprocter3 11:aa6d9d72b5a2 156 uLCD.baudrate(3000000); //jack up baud rate to max
jprocter3 11:aa6d9d72b5a2 157 uLCD.background_color(BLACK);
jprocter3 14:7e45dbeb0acf 158 uLCD.cls();
jprocter3 11:aa6d9d72b5a2 159 uLCD.text_bold(ON);
jprocter3 11:aa6d9d72b5a2 160 uLCD.text_mode(OPAQUE);
jprocter3 11:aa6d9d72b5a2 161
skrgo3 1:a2a5171ac99f 162 mu.startUpdates();
jprocter3 11:aa6d9d72b5a2 163
jprocter3 11:aa6d9d72b5a2 164 interrupt.fall(&fallInterrupt);
jprocter3 11:aa6d9d72b5a2 165 interrupt.mode(PullUp);
jprocter3 0:7b070cdce8bd 166
jprocter3 8:ddddef6634cd 167 state = ROAM;
jprocter3 8:ddddef6634cd 168 energy = 70;
jprocter3 8:ddddef6634cd 169
skrgo3 7:7050d3c2b720 170 Thread thread1(sonar);
jprocter3 11:aa6d9d72b5a2 171 Thread thread2(touch);
jprocter3 11:aa6d9d72b5a2 172 Thread thread3(screen);
jprocter3 12:492f2a122e39 173 Thread thread4(sound);
jprocter3 0:7b070cdce8bd 174
jprocter3 0:7b070cdce8bd 175 while(1) {
jprocter3 2:672f7335a017 176 // Status LEDS
jprocter3 2:672f7335a017 177 led3 = touched;
jprocter3 2:672f7335a017 178 led4 = fed;
jprocter3 0:7b070cdce8bd 179
jprocter3 2:672f7335a017 180 // Update state
jprocter3 2:672f7335a017 181 if (energy < 5) { // sleeps for 10 seconds and wake up with 50 more energy
jprocter3 2:672f7335a017 182 state = SLEEP;
jprocter3 10:29a382784838 183 led1 = 1;
jprocter3 10:29a382784838 184 led2 = 1;
jprocter3 2:672f7335a017 185 Thread::wait(10000);
jprocter3 2:672f7335a017 186 energy += 50;
jprocter3 6:93e21d47480b 187 } else if (energy < 30 || touched || fed) {
jprocter3 2:672f7335a017 188 state = STOP;
jprocter3 10:29a382784838 189 led1 = 0;
jprocter3 10:29a382784838 190 led2 = 1;
jprocter3 14:7e45dbeb0acf 191 } else if (state == STOP) {
jprocter3 14:7e45dbeb0acf 192 Thread::wait(6000); // wait wondering for 5 seconds after touched or fed
jprocter3 14:7e45dbeb0acf 193 state = ROAM;
jprocter3 2:672f7335a017 194 } else {
jprocter3 2:672f7335a017 195 state = ROAM;
jprocter3 11:aa6d9d72b5a2 196 led1 = 1;
jprocter3 10:29a382784838 197 led2 = 0;
jprocter3 2:672f7335a017 198 }
jprocter3 2:672f7335a017 199
jprocter3 2:672f7335a017 200 // Update energy
jprocter3 2:672f7335a017 201 switch(state) {
jprocter3 4:9c2c77d61a15 202 case ROAM: energy -= 2;
jprocter3 2:672f7335a017 203 break;
jprocter3 4:9c2c77d61a15 204 case STOP : energy -= 1;
jprocter3 11:aa6d9d72b5a2 205 if (fed) {
jprocter3 11:aa6d9d72b5a2 206 energy += 10; // +10 energy a second while fed
jprocter3 11:aa6d9d72b5a2 207 }
jprocter3 2:672f7335a017 208 break;
jprocter3 2:672f7335a017 209 }
jprocter3 2:672f7335a017 210
jprocter3 2:672f7335a017 211 // Make sure energy stays in 0-100
jprocter3 2:672f7335a017 212 if (energy < 0) {
jprocter3 2:672f7335a017 213 energy = 0;
jprocter3 2:672f7335a017 214 } else if (energy > 100) {
jprocter3 2:672f7335a017 215 energy = 100;
jprocter3 2:672f7335a017 216 }
jprocter3 4:9c2c77d61a15 217
jprocter3 4:9c2c77d61a15 218 Thread::wait(1000); // runs once per second
jprocter3 0:7b070cdce8bd 219 }
jprocter3 0:7b070cdce8bd 220 }