Esempio n. 1
0
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);
		}
	}
}
Esempio n. 2
0
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);
}