/** * 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; } } }
/** * 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; }
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; } }
/** * 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; }