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
main.cpp
- Committer:
- jprocter3
- Date:
- 2019-04-22
- Revision:
- 15:02e772571d48
- Parent:
- 14:7e45dbeb0acf
File content as of revision 15:02e772571d48:
#include "mbed.h" #include "motordriver.h" #include "rtos.h" #include "uLCD_4DGL.h" #include "mpr121.h" #include "ultrasonic.h" #include "SDFileSystem.h" #include "wave_player.h" #include "Servo.h" uLCD_4DGL uLCD(p13,p14,p29); // serial tx, serial rx, reset pin; SDFileSystem sd(p5, p6, p7, p21, "sd"); //SD card AnalogOut DACout(p18); wave_player waver(&DACout); Motor m1(p23, p30, p8, 1); // pwm, fwd, rev Motor m2(p24, p9, p10, 1); // pwm, fwd, rev InterruptIn interrupt(p26); I2C i2c(p28, p27); Mpr121 mpr121(&i2c, Mpr121::ADD_VSS); Servo myservo(p22); DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); enum {ROAM, STOP, SLEEP}; volatile int state; volatile int energy; volatile bool touched; volatile bool fed; volatile bool touchpad; void fallInterrupt() { touchpad = true; mpr121.read(0x00); mpr121.read(0x01); } void dist(int distance) { //control wheels if (state == ROAM) { if(distance < 250) { m1.stop(0); m2.stop(0); Thread::wait(100); m1.speed(.6); m2.speed(-.6); Thread::wait(400); } else { m1.speed(.5); m2.speed(.5); } } else { // stop for STOP and SLEEP m1.stop(0); m2.stop(0); } if (state == STOP && distance < 60) { //increase food status fed = true; Thread::wait(3000); // make sure fed state lasts atleast 3 seconds fed = false; } } ultrasonic mu(p11, p12, .1, 1, &dist); void sonar(void const *argument) { while(1) { mu.checkDistance(); Thread::wait(100); } } void touch(void const *argument) { while(1) { if (touchpad) { touched = true; Thread::wait(5000); touchpad = false; } else { touched = false; } Thread::wait(100); // runs 10 times a second } } void screen(void const *argument) { while(1) { uLCD.filled_rectangle(0, 0, 127, 127, BLACK); // clear screen switch(state) { case ROAM: { uLCD.circle(64, 64, 30, BLUE); // blue circle in the center uLCD.filled_circle(64, 64, 5, BLUE); // blue circle in the center } break; case STOP: { uLCD.locate(0,0); uLCD.text_width(12); uLCD.text_height(12); if (fed || touched) { // touched or fed uLCD.text_width(9); uLCD.text_height(9); uLCD.color(RED); uLCD.printf("<3"); } else if (energy < 30) { // tired uLCD.color(RED+GREEN); uLCD.printf("0"); // yellow 0's } else { // wondering uLCD.color(BLUE); uLCD.printf("?"); // blue ?'s } } break; case SLEEP: { uLCD.locate(0,0); uLCD.text_width(12); uLCD.text_height(12); uLCD.color(BLUE); uLCD.printf("Z"); // blue Z's } } Thread::wait(100); } } void sound(void const *argument) { FILE *wave_file; while(1) { switch(state) { case STOP: { if (fed) { // fed wave_file=fopen("/sd/eat.wav","r"); // 2 seconds } else if (touched) { // touched wave_file=fopen("/sd/purr.wav","r"); // 3 seconds } else if (energy < 30) { // tired wave_file=fopen("/sd/bark.wav","r"); // < 1 second Thread::wait(500); } else { // wondering wave_file=fopen("/sd/curious.wav","r"); // 1 second Thread::wait(1000); } waver.play(wave_file); fclose(wave_file); } break; case SLEEP: { wave_file=fopen("/sd/sleep.wav","r"); // 8 seconds waver.play(wave_file); fclose(wave_file); } } Thread::wait(100); } } void tail(void const *argument) { while(1) { if (state == STOP && (touched || fed)) { for(int i=0; i<100; i++) { myservo = i/100.0; Thread::wait(10); } for(int i=100; i>0; i--) { myservo = i/100.0; Thread::wait(10); } } else { myservo = 0.5; } Thread::wait(500); } } int main() { uLCD.cls(); uLCD.printf("Change baudrate....."); uLCD.baudrate(3000000); //jack up baud rate to max uLCD.background_color(BLACK); uLCD.cls(); uLCD.text_bold(ON); uLCD.text_mode(OPAQUE); mu.startUpdates(); interrupt.fall(&fallInterrupt); interrupt.mode(PullUp); state = ROAM; energy = 70; Thread thread1(sonar); Thread thread2(touch); Thread thread3(screen); Thread thread4(sound); Thread thread5(tail); while(1) { // Status LEDS led3 = touched; led4 = fed; // Update state if (energy < 5) { // sleeps for 10 seconds and wake up with 50 more energy state = SLEEP; led1 = 1; led2 = 1; Thread::wait(10000); energy += 50; } else if (energy < 30 || touched || fed) { state = STOP; led1 = 0; led2 = 1; } else if (state == STOP) { Thread::wait(6000); // wait wondering for 5 seconds after touched or fed state = ROAM; } else { state = ROAM; led1 = 1; led2 = 0; } // Update energy switch(state) { case ROAM: energy -= 2; break; case STOP : energy -= 1; if (fed) { energy += 10; // +10 energy a second while fed } break; } // Make sure energy stays in 0-100 if (energy < 0) { energy = 0; } else if (energy > 100) { energy = 100; } Thread::wait(1000); // runs once per second } }