예제 #1
0
/**
 * Waits to get RESUME on the serial.
 * Returns 0 if it gets it,
 * ABORTED if it gets ABORT.
 */
errv_t wait_for_resume() {
    while(1) {
        errv_t ret = check_aborted(true);
        if (ret == RESUMED) {
            return 0;
        }
        else if (ret) {
            return ret;
        }
    }
}
예제 #2
0
/**
 * Turns bottle 1 up while simultaneously turning bottle 2 down to
 * pause position. Works best if bottle 1 is at pause position at start.
 *
 * In audio, this is called a crossfade:
 *
 * b2 ______     ______ up
 *          \   /
 *           \ /
 *            x
 *           / \
 * b1 ______/   \______ pause position
 *
 * Returns ABORTED if aborted.
 */
errv_t crossfade(Bottle * b1, Bottle * b2, int delay_ms) {
    int step = 1;
    int b1_pos = b1->servo.readMicroseconds();
    int b2_pos = b2->servo.readMicroseconds();
    int new_pos=0;
    bool done_something;

    DEBUG_MSG_LN("crossfade " + String(b1->number) + String(" ") + String(b2->number));

    while(1) {
        done_something=false;

        // Turn bottle 1 up
        b1_pos += step;
        if(b1_pos < b1->pos_up) {
            b1->servo.writeMicroseconds(b1_pos);
            done_something=true;
        }

        delay(delay_ms/2); // Split delay in half so bottles move alternating

        // Turn bottle 2 down to pause position
        b2_pos -= step;
        if(b2_pos > b2->get_pause_pos() ) {
            b2->servo.writeMicroseconds(b2_pos);
            done_something=true;
        }

        // Both bottles are already in position
        if(done_something==false)
            break;

        delay(delay_ms/2);

        if (check_aborted()) {
            // no other cleanup, other bottles should be alright
            b1->turn_up(FAST_TURN_UP_DELAY);
            b2->turn_up(FAST_TURN_UP_DELAY);
            return ABORTED;
        }
    }

    return 0;
}
예제 #3
0
void
midifile()              /* The only non-static function in this file. */
{
        int ntrks;
        midifile_error = 0;

        if ( Mf_getc == 0 ) {
                mferror("mf.h() called without setting Mf_getc"); 
                return;
        }
        ntrks = readheader();
        if (midifile_error) return;
        if ( ntrks <= 0 ) {
                mferror("No tracks!");
                /* no need to return since midifile_error is set */
        }
        while ( ntrks-- > 0 && !midifile_error && !check_aborted())
                readtrack();
        if (check_aborted()) {
                mferror("Midifile read aborted\n\
\tthe rest of your file will be ignored.\n");
            if (abort_flag == BREAK_LEVEL) abort_flag = 0;
        }
}
예제 #4
0
/**
 * Turn servo towards 'pos' in 1 microsecond steps, waiting delay_ms
 * milliseconds between steps (speed = 1/delay). If check_weight weight
 * is true, might abort with WHERE_THE_FUCK_IS_THE_CUP error. If a valid pointer
 * stable_weight is passed, turns bottle until a stable weight is measured
 * (returns WEIGHT_NOT_STABLE if pos is reached before weight stable).
 *
 * Returns 0 when the position is reached or SERVO_OUT_OF_RANGE on error.
 *
 * For details about the built-in Servo class see:
 *     /usr/share/arduino/libraries/Servo/Servo.cpp
 *
 */
errv_t Bottle::turn_to(int pos, int delay_ms, bool check_weight, int* stable_weight, bool enable_abortcheck) {
    int weight_previous1 = -9999;  // just any impossible value
    int weight_previous2 = -9999;  // ..before we have real values

    if (pos < SERVO_MIN || pos > SERVO_MAX) {
        DEBUG_MSG_LN("Invalid pos");
        return SERVO_OUT_OF_RANGE;
    }

    int current_pos = servo.readMicroseconds();
    if (pos == current_pos)
        return 0;
    int step = (current_pos < pos) ? 1 : -1;

    DEBUG_START();
    DEBUG_MSG("turn ");
    DEBUG_MSG(number);
    DEBUG_MSG(", params ");
    DEBUG_VAL(current_pos);
    DEBUG_VAL(step);
    DEBUG_VAL(pos);
    DEBUG_VAL(delay_ms);
    DEBUG_END();
    unsigned long last_called = millis();
    for (int i = current_pos + step; i * step <= pos * step; i += step) {
        //                             ˆˆˆˆˆˆ        ˆˆˆˆˆˆ
        //                             this inverts the relation if turning down

        // Warning: printing to serial delays turning!
        // Might help to to debug servo movement. Not necessary now, commenting
        // out to save bytes.
        //if (print_steps && i % 10 == 0) {
        //    DEBUG_VAL_LN(i);
        //}

        // check abort only if not already aborted...
        if (enable_abortcheck) {
            // turn up and return if we should abort...
            errv_t ret = check_aborted();
            if (ret) {
                // turn_up might not be necessary here, called another time
                // later (does not matter if called twice)
                turn_up(FAST_TURN_UP_DELAY, false);
                return ret;
            }
        }

        if (check_weight || stable_weight) {
            int weight;
            int ret = ads1231_get_noblock(weight);
            if (ret == 0) {
                // we got a valid weight from scale
                if (check_weight && weight < WEIGHT_EPSILON) {
                    return WHERE_THE_FUCK_IS_THE_CUP;
                }

                // get next weight sample and return if weight is stable
                if (stable_weight) {
                    if (weight_previous2 == weight_previous1
                            && weight_previous1 == weight) {
                        *stable_weight = weight;
                        return 0;
                    }
                    weight_previous2 = weight_previous1;
                    weight_previous1 = weight;
                }
            }
            else if (ret != ADS1231_WOULD_BLOCK) {
                // ignoring if it would take too long to get weight, but
                // return in case of other error != 0
                return ret;
            }
        }

        // turn servo one step
        delay(delay_ms);
        servo.writeMicroseconds(i);
    }

    // pos reached before weight stable
    if (stable_weight) {
        return WEIGHT_NOT_STABLE;
    }

    return 0;
}