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:
Mon Apr 22 18:55:43 2019 +0000
Revision:
15:02e772571d48
Parent:
14:7e45dbeb0acf
fixed i2c interrupt block

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