void run_pwm(uint8_t pin, struct Event *event) { int32_t time = current_time(); if (pin == PWM0_PD6) { if (event->type == CLOUDS) { //*** // CLOUDS mode int32_t subevent_passed_time = time - event->temp_time; // new cloud: if no cloud before (new event) or passed time of last cloud if ((event->temp_duration == 0) | (subevent_passed_time > event->temp_duration)) { if (subevent_passed_time > event->temp_duration) { if (event->temp_duration == 0) send_string("new cloud - beginning "); else send_string("new cloud "); // start value for new subevent event->pin_state = event->pin_state + event->inc; } // start time for subevent event->temp_time = time; // if last cloud int32_t margin = 200; // 200 seconds before end of the duration of CLOUDS event if (((event->time + event->duration) - time) <= margin) { // last cloud send_string("last cloud "); event->temp_duration = (event->time + event->duration) - time; // final pin_state event->inc = event->final_state - event->pin_state; } else { event->temp_duration = util_rand2(10, margin); // range of changes: 70..100% int new_state = util_rand2(70, 100); event->inc = new_state - event->pin_state; } } // start value // convert % => 0..255 uint8_t ti = (event->pin_state * 255) / 100; // increment/decrement value // convert % => 0..255 int16_t tinc = (event->inc * 255) / 100; if (subevent_passed_time <= event->temp_duration) { ti = ti + ((int32_t) tinc * subevent_passed_time) / event->temp_duration; } else { // correction // 50%/15s = 3.3%/s (3%/s) => 15s * 3% = 45% => 50% - 45% = 5% of error ti = ti + tinc; } set_pwm0(ti); } else if (event->type == PWM) { // start value // convert % => 0..255 uint8_t ti = (event->pin_state * 255) / 100; if (event->duration != 0) { // increment/decrement value // convert % => 0..255 int16_t tinc = (event->inc * 255) / 100; int32_t passed_time = time - event->time; if (passed_time <= event->duration) { ti = ti + ((int32_t) tinc * passed_time) / event->duration; } else { // correction // 50%/15s = 3.3%/s (3%/s) => 15s * 3% = 45% => 50% - 45% = 5% of error ti = ti + tinc; } } set_pwm0(ti); } } else if (pin == PWM1_PD5) { if (event->type == CLOUDS) { //*** // CLOUDS mode int32_t subevent_passed_time = time - event->temp_time; // new cloud: if no cloud before (new event) or passed time of last cloud //if ((event->temp_time == 0) | (event->temp_time < time)) if ((event->temp_duration == 0) | (subevent_passed_time > event->temp_duration)) { if (subevent_passed_time > event->temp_duration) { if (event->temp_duration == 0) send_string("new cloud - beginning "); else send_string("new cloud "); // start value for new subevent event->pin_state = event->pin_state + event->inc; } // start time for subevent event->temp_time = time; // if last cloud int32_t margin = 200; // 200 seconds before end of the duration of CLOUDS event if (((event->time + event->duration) - time) <= margin) { // last cloud send_string("last cloud "); event->temp_duration = (event->time + event->duration) - time; // final pin_state event->inc = event->final_state - event->pin_state; } else { event->temp_duration = util_rand2(10, margin); // range of changes: 70..100% int new_state = util_rand2(70, 100); event->inc = new_state - event->pin_state; } } // start value // convert % => 0..255 uint8_t ti = (event->pin_state * 255) / 100; // increment/decrement value // convert % => 0..255 int16_t tinc = (event->inc * 255) / 100; if (subevent_passed_time <= event->temp_duration) { ti = ti + ((int32_t) tinc * subevent_passed_time) / event->temp_duration; } else { // correction // 50%/15s = 3.3%/s (3%/s) => 15s * 3% = 45% => 50% - 45% = 5% of error ti = ti + tinc; } set_pwm1(ti); } else if (event->type == PWM) { // start value // convert % => 0..255 uint8_t ti = (event->pin_state * 255) / 100; if (event->duration != 0) { // increment/decrement value // convert % => 0..255 int16_t tinc = (event->inc * 255) / 100; int32_t passed_time = time - event->time; if (passed_time <= event->duration) { ti = ti + ((int32_t) tinc * passed_time) / event->duration; } else { // correction // 50%/15s = 3.3%/s (3%/s) => 15s * 3% = 45% => 50% - 45% = 5% of error ti = ti + tinc; } } set_pwm1(ti); } } }
static void do_encoder(uint32_t enc) { uint32_t i; int32_t lspeed, rspeed; int32_t diff; /* reset odometer counters */ rodo = 0; lodo = 0; /* set pwms from speed */ rspeed = clamp(speed / 2, 0, 128); lspeed = rspeed; set_pwm0(128 + (ldir == 1 ? lspeed : -lspeed)); set_pwm1(128 + (rdir == 1 ? rspeed : -rspeed)); /* wait until dont */ i = 0; while (i < enc) { i += (lodo + rodo) / 2; diff = (int32_t)(lenc - renc); if (diff > 0) { /* left faster than right */ if ((lspeed > speed) || (rspeed > 244)) lspeed -= CONFIG_SPEED_INTEGRATOR; else rspeed += CONFIG_SPEED_INTEGRATOR; } else if (diff < 0) { /* right faster than left */ if ((rspeed > speed) || (lspeed > 244)) rspeed -= CONFIG_SPEED_INTEGRATOR; else lspeed += CONFIG_SPEED_INTEGRATOR; } /* reset the odometer */ rodo = 0; lodo = 0; /* set motor pwms */ lspeed = clamp(lspeed / 2, 0, 128); rspeed = clamp(rspeed / 2, 0, 128); set_pwm0(128 + (ldir == 1 ? lspeed : -lspeed)); set_pwm1(128 + (rdir == 1 ? rspeed : -rspeed)); /* small delay */ { volatile int i; for (i = 0; i < 1000; ++i) __asm__ __volatile__ ("nop\n\t"); } } /* stop the motor */ set_pwm0(0); set_pwm1(0); }