Code for automatic pill box dispenser
Dependencies: mbed-rtos mbed sMotor
main.cpp
- Committer:
- cchoi63
- Date:
- 2017-12-13
- Revision:
- 0:d223f8829ec0
- Child:
- 1:71eb56bcafce
File content as of revision 0:d223f8829ec0:
/* ----- Authors ----- Sahithi Bonala Stephen Brotman Christie Choi Brandon Sheu ----- Acknowledgements ----- Samuel Matildes (sam.naeec@gmail.com) for the sMotor v0.1 Test Program that interfaces between the mbed and 4-phase stepper motors. */ #include "mbed.h" #include "sMotor.h" #include "rtos.h" //Interrupts InterruptIn touchsensor(p12); // Touch sensor //Digital Inputs DigitalIn refill_pb(p30); // Pushbutton to refill //Digital Outputs DigitalOut myled(LED1); DigitalOut myled2(LED2); //PWM Outputs PwmOut led_red(p21); // Red LED of an RGB LED PwmOut led_green(p22); // Green LED of an RGB LED PwmOut led_blue(p23); // Blue LED of an RGB LED //Serial Connection Serial pc(USBTX, USBRX); //sMotor Interface sMotor motor(p8, p9, p10, p11); // Creates new stepper motor: IN1, IN2, IN3, IN4 //Threads Thread thread_motor; // Motor thread Thread thread_refill; // Refill thread Thread thread_control; // Timing controller thread Thread thread_led; // LED thread Thread thread_cmd; // Serial command thread //Timing Timer timer; Ticker ticker; //Initialization for LED float led_red_value = 0.0; //current red LED value float led_green_value = 0.0; //current green LED value float led_blue_value = 0.0; //current blue LED value int led_color = 0x000000; //color of the LED int led_gradient_duration = 3; //duration of gradient between LED colors bool led_blink = false; //whether to blink the LED bool led_update = false; //whether to update the color of the LED //Initialization for stepper motor int step_speed = 1200; //set default motor speed int numstep = 512 ; //defines full turn of 360 degree bool motor_turn = false; //whether to turn the motor or not //Initialization for the pill container float pill_interval = 15.0; //time between pills (seconds) int pill_taken_counter = 0; int pill_refill_counter = 0; bool pill_taken = false; bool pill_refilled = false; bool cmd_send = false; int cmd_type = 0; //1 is time, 2 is pill void SendCmdTime() { //Send a command through Serial telling the mySQL database to update the //time //pc.printf("cmdTime\n"); cmd_type = 1; cmd_send = true; } void SendCmdPill() { // Send a command through Serial telling the mySQL database to update the // pill status //pc.printf("cmdPill\n"); cmd_type = 2; cmd_send = true; } void ControlCmd() { while (true) { if (cmd_send) { switch (cmd_type) { case 1: pc.printf("cmdTime\n"); break; case 2: pc.printf("cmdPill\n"); break; } cmd_type = 0; cmd_send = false; } Thread::wait(200); } } void TouchDetected() { // Called when the touch sensor detects a touch pill_taken = true; myled2 = true; // Update the status in the database SendCmdPill(); } void TouchRemoved() { // Called to reset variables when the touch sensor no longer detects a touch pill_taken = false; myled2 = false; } void UpdateLed(int color, bool blink = false, int duration = 3) { // Update the color of the LED led_color = color; led_blink = blink; led_gradient_duration = duration; led_update = true; } void ControlLed() { //thread for RGB LED that uses global variables //(int) led_color - a hexadecimal value for the color, e.g. 0xFF0000 for red //(int) led_blink (optional) - whether to blink or not //(int) led_gradient_duration (optional) - duration for gradient in seconds while (true) { if (led_update) { float r = ((float)((0xFF0000 & led_color)>>16))/255.0; float g = ((float)((0x00FF00 & led_color)>>8))/255.0; float b = ((float)(0x0000FF & led_color))/255.0; //pc.printf("R: %0.2f, G: %0.2f, B: %0.2f\n", r, g, b); float dR = (r-led_red_value)/(100.0); float dG = (g-led_green_value)/(100.0); float dB = (b-led_blue_value)/(100.0); for (int i = 1; i <= 100; i++) { led_red.write(led_red_value + (dR*i)); led_green.write(led_green_value + (dG*i)); led_blue.write(led_blue_value + (dB*i)); wait(((float)led_gradient_duration)/(100.0)); } if (led_blink) { float time_wait = (float)led_gradient_duration*0.125; for (int i = 0; i < 4; i++) { // Turn off LED led_red.write(0.0); led_green.write(0.0); led_blue.write(0.0); wait(time_wait); // Turn on LED led_red.write(r); led_green.write(g); led_blue.write(b); wait(time_wait); } } led_red_value = r; led_green_value = g; led_blue_value = b; led_update = false; } Thread::wait(500); } } void ControlTiming() { timer.start(); ticker.attach(&SendCmdTime, pill_interval); while(true) { int delay = (pill_taken_counter+1)*pill_interval; float time_difference = timer.read()-delay; float time_limit_warn = pill_interval/5.0; float time_limit_alert = pill_interval/4.0; if (pill_taken) { // Pill is taken UpdateLed(0x000000, false); if (timer.read() >= delay) { // Increment container motor_turn = true; } else { motor_turn = false; } } else if (time_difference >= -pill_interval && time_difference < time_limit_warn) { // Pill is ready to be taken UpdateLed(0x00FF00, false); } else if (time_difference >= time_limit_warn && time_difference < time_limit_alert) { // Pill still not taken, warning // change LED color UpdateLed(0xFFFF00, true); } else if (time_difference >= time_limit_alert) { // Pill still not taken, alert UpdateLed(0xFF0000, true); } else { UpdateLed(0x000000, false); } if (pill_taken_counter == 7) { UpdateLed(0x0000FF, false); } if (pill_refilled) { ticker.detach(); timer.stop(); timer.reset(); timer.start(); ticker.attach(&SendCmdTime, pill_interval); pill_refilled = false; UpdateLed(0x000000, false); } Thread::wait(100); } } void ControlMotor() { while(true) { while (pill_taken_counter < 7) { if (motor_turn == true) { motor.step(numstep/7, 0, step_speed); // Number of steps, direction, speed pill_taken_counter++; // Reest touch sensor variables TouchRemoved(); motor_turn = false; } } Thread::wait(500); } } void ControlRefill() { //refill_pb.mode(PullUp); while(true) { while (pill_taken_counter == 7) { myled = 1; wait(0.2); myled = 0; wait(0.2); if (refill_pb == 0 && pill_refill_counter < 6) { pill_refill_counter++; motor.step(numstep/7, 0, step_speed); } if (pill_refill_counter == 6 && refill_pb == 0) { motor.step(numstep/7, 0, step_speed); pill_taken_counter = 0; pill_refill_counter = 0; pill_refilled = true; } } Thread::wait(500); } } int main() { //Set refill pushbutton as a pull-up refill_pb.mode(PullUp); //Initiate touch sensor interrupt touchsensor.fall(&TouchDetected); //Start threads thread_motor.start(ControlMotor); thread_refill.start(ControlRefill); thread_control.start(ControlTiming); thread_led.start(ControlLed); thread_cmd.start(ControlCmd); //Write LED values led_red.period(0.0005); //2kHz period for less flicker led_green.period(0.0005); //2kHz period for less flicker led_blue.period(0.0005); //2kHz period for less flicker led_red.write(led_red_value); led_green.write(led_green_value); led_blue.write(led_blue_value); }