48675_LAB04: Controlling Motors

Made by Phoebe

A physical notification flag that waves with respect to important emails

Created: December 3rd, 2022

0
int motorPin = A3;
int buttonPin = D3; 

//https://maker.ifttt.com/trigger/button_pressed/json/with/key/bcFhSXZcj5VFoJT1n0CjFo


int medSpeed = 100; 
int lowSpeed = 50;
int hiSpeed = 180; 
int motorSpeed = 100;  
String statename[4] = {"WORK","QUICK BREAK","LONG BREAK","INACTIVE"};
String currentState = "NOT STARTED";

typedef struct {
    uint32_t totalTime = 0; 
    uint8_t state = 3; 
    unsigned long timer = 0; 
    unsigned long totaltimer = 0;
    bool active = false; 
}Pomodoro;

uint32_t pomTime[3] = {25,5,15};
Pomodoro myPom; 
Pomodoro *pPom;

long motorTimer = 0; 
int motorDelayMillis = 5000;
int timeLeft = 0; 

bool motorOn = false; 
bool button_press = false; 
long buttonTimer = 0; 
long buttonLength; 
int buttonState; 

void initPom(){
    pomTime[0] = min2milli(pomTime[0]);
    pomTime[1] = min2milli(pomTime[1]);
    pomTime[2] = min2milli(pomTime[2]);
    
    pPom = &myPom;
}


int startPomSession(String command){
    int mintime = command.toInt(); 
    myPom.totalTime = min2milli(mintime);
    myPom.state = 0; 
    myPom.active = true; 
    myPom.timer = millis();
    myPom.totaltimer = millis(); 
    motorControl(myPom.state);
    return myPom.totalTime; 
}

void pomCheck(){
    currentState = statename[myPom.state];
    timeLeft = milli2min(myPom.totalTime-millis()-myPom.totaltimer);
    if (myPom.active == false || myPom.state == 3){
        motorOn = false; 
        analogWrite(motorPin, 0);
        return;
    }
    if (millis()-myPom.totaltimer>=myPom.totalTime){
        myPom.active = false; 
        myPom.state = 3;
        motorOn = false; 
        motorControl(4);
        return;
    }
    else if (millis()-myPom.timer>=pomTime[myPom.state]){
        //go to next state and restart timer
        myPom.state ++; 
        if (myPom.state > 3) myPom.state = 0; 
        myPom.timer = millis();
        //trigger appropriate flag wave
        motorControl(myPom.state);
    }
}

void setup() {
    initPom();
    pinMode(motorPin, OUTPUT);
    pinMode(buttonPin, INPUT_PULLUP);
    Particle.function("StartPomSession", startPomSession);
    Particle.variable("PomodoroState", &currentState, STRING); 
    Particle.variable("PomLeft", &timeLeft, INT); 


}

void loop() {
    pomCheck(); 
    motorTimerCheck(); 
    buttonCheck();

}


void motorControl(int command)
{
    // Set Activation Time and Speed
    if (command == 0){
        TimerAdj(8);
        motorSpeed = hiSpeed;
    }
    else if (command == 1){
        TimerAdj(3);
        motorSpeed = hiSpeed;
    }
    else if (command == 2){
        TimerAdj(12);
        motorSpeed = medSpeed;
    }
    else if (command == 3){
        TimerAdj(2);
        motorSpeed = 0;
    }
    else if (command == 4){
        //finish
        TimerAdj(2);
        motorSpeed = lowSpeed;
        analogWrite(motorPin, motorSpeed);
        delay(4000);
        return;
    }
    
    analogWrite(motorPin, motorSpeed);
    motorOn = true;
    motorTimer = millis();
    // done
}

void motorTimerCheck(){
    // if timer has elapsed
    if (motorOn && millis()-motorTimer>= motorDelayMillis){
        motorSpeed = 0; 
        motorOn = false;
        analogWrite(motorPin, motorSpeed);
    }
    if (motorOn == false) analogWrite(motorPin, 0);
}

void TimerAdj(int seconds){
    // convert to seconds
    motorDelayMillis = 1000* seconds;
}
int min2milli(int minutes){
    return 1000*60*60*minutes; 
}

int milli2min(int milli){
    return milli/1000/60/60; 
}

void buttonCheck(){
    if (digitalRead(buttonPin)==LOW){
        analogWrite(motorPin,0);
        myPom.state = 3; 
        motorControl(3);
        myPom.active = false; 
        
    }
}
Click to Expand
0
Waving Flag: DIOT Lab4
Phoebe Degroot - https://www.youtube.com/shorts/wYVfnCp4WsU
0

For this lab I experimented with controlling a couple different types of motors using the Particle Argon and IFTTT. The setup I eventually landed upon was a sort of eccentric cam/ yoke driven by a DC motor that causes a flag to wave back and forth. Originally my plan was to have the flag wave when I received any emails tagged "important" or "urgent" however IFTTT doesn't support any triggers based on receiving an email, my next thought was to setup a pomodoro timer - I was hoping to link this with one of my existing focus apps or the iOS focus time setting but this was also unavailable. Ultimately I landed on a simple pomodoro timer set in the console which can be shut off by a button. This theoretically could be connected to a webhook app so I can use the button to start a focus time or gcal event to trigger the pomodoro.

The total time for the pomodoro session is entered via the console. The flag waves at different speeds and lengths of time for different pomodoro states - fast for 8 seconds is "time to work", fast for 3 seconds is "short break", med for 10 seconds is "long break". When the total pomodoro duration elapses or the button is pressed the flag waves slowly for 5 seconds and then will go to an inactive state.


Setting up the pomodoro timer function ended up taking me a few hours of extra coding and debugging. I ended up having some contradictions in managing both flag waving and pomodoro states as well as mishaps with using out of range arrays or calling functions with the wrong type of variable. The online Particle IDE doesn't notify you of many of these issues unless you go into the raw error data which makes me want to switch to VS.code. I was also frustrated around the narrow options for IFTTT - many are available only for paid accounts or with paid apps.

0
Original code for the email notification
int motorPin = A3;

int hiSpeed = 150;
int medSpeed = 100; 
int lowSpeed = 50;
int motorSpeed = 100;  

long motorTimer = 0; 
int motorDelayMillis = 5000;

bool motorOn = false; 

void setup() {
    pinMode(motorPin, OUTPUT);
    Particle.function("motorSpeed", motorControl);
    Particle.variable(  "motorSpeed" , &motorSpeed , INT );
}

void loop() {
    motorTimerCheck();
}

int motorControl(String command)
{
    // Set Activation Time and Speed
    if (command == "HIGH"){
        TimerAdj(10);
        motorSpeed = hiSpeed;
    }
    else if (command == "MED"){
        TimerAdj(5);
        motorSpeed = medSpeed;
    }
    else if (command == "LOW"){
        TimerAdj(2);
        motorSpeed = lowSpeed;
    }
    
    analogWrite(motorPin, motorSpeed);
    motorOn = true;
    motorTimer = millis();
    return 1; 

    // done
}

void TimerAdj(int seconds){
    // convert to seconds
    motorDelayMillis = 1000* seconds;
}

void motorTimerCheck(){
    // if timer has elapsed
    if (motorOn && (millis()-motorTimer>= motorDelayMillis)){
        motorSpeed = 0; 
        motorOn = false;
        analogWrite(motorPin, motorSpeed);
    }
}
Click to Expand
x
Share this Project

Courses

About

A physical notification flag that waves with respect to important emails