Example #1
0
void led_init()
{
	// turn on LEDs (max)
	led_setPWM(LED_RED, LED_MAX_PWM);
	led_setPWM(LED_GREEN, LED_MAX_PWM);
	led_setPWM(LED_BLUE, LED_MAX_PWM);

	// wait for things to settle...
	delayus(20000);

	// get current of each led.  This is needed because each LED has a different forward voltage.  But current determines
	// brightness regardless of voltage drop.  So we normalize with respect to current for best color accuracy. 
	g_ledOnCurrent[LED_RED] = (float)adc_get(LED_RED_ADCCHAN)/ADC_MAX*ADC_VOLTAGE/LED_RED_RESISTOR;
	g_ledOnCurrent[LED_GREEN] = (float)adc_get(LED_GREEN_ADCCHAN)/ADC_MAX*ADC_VOLTAGE/LED_GREEN_RESISTOR;
	g_ledOnCurrent[LED_BLUE] = (float)adc_get(LED_BLUE_ADCCHAN)/ADC_MAX*ADC_VOLTAGE/LED_BLUE_RESISTOR;	

	g_ledVal[LED_RED] = 0xff;
	g_ledVal[LED_GREEN] = 0xff;
	g_ledVal[LED_BLUE] = 0xff;

	// turn off LEDs
	led_set(0);
		
	// set other vals...
	g_ledScale = LED_DEFAULT_SCALE;
	led_setMaxCurrent(LED_DEFAULT_MAX_CURRENT);	
	
	g_chirpUsb->registerModule(g_module);
}
void ButtonMachine::setSignature()
{
	uint32_t current, saveCurrent; 
	int goodness;

	// grow region, create model, save
	goodness = cc_setSigPoint(0, m_index, CAM_RES2_WIDTH/2, CAM_RES2_HEIGHT/2, g_chirpUsb);
	if (goodness>0)
	{
		cprintf("goodness=%d\n", goodness);
		saveCurrent = led_getMaxCurrent(); // save off value
		current = (float)LED_MAX_CURRENT/100.0f*goodness;
		led_setMaxCurrent(current);
		flashLED(4); 
		led_setMaxCurrent(saveCurrent);
	}
}
// this routine needs to provide good feedback to the user as to whether the camera sees and segments the object correctly.
// The key is to integrate the "growing algorithm" such that the growing algorithm is executed continuously and feedback about
// the "goodness" of the grown region is returned.  We're choosing goodness to be some combination of size (because the bigger 
// the grown region the better) and saturation (because more saturation the more likely we've found the intended target, vs 
// the background, which is typically not saturated.)  
// In general with an RGB LED, you can only communicate 2 things--- brightness and hue, so you have 2 dof to play with....   
void scaleLED(uint32_t r, uint32_t g, uint32_t b, uint32_t n)
{
	uint32_t max, min, current, sat, t; 

#if 0  // it seems that green is a little attenuated on this sensor
	t = (uint32_t)(G_GAIN*g);
	if (t>255)
		g = 255;
	else
		g = t;
#endif

   	// find min
	min = MIN(r, g);
	min = MIN(min, b);

	// find max
	max = MAX(r, g);
	max = MAX(max, b);

	// subtract min and form sataration from the distance from origin
	sat = sqrt((float)((r-min)*(r-min) + (g-min)*(g-min) + (b-min)*(b-min)));
	if (sat>30) // limit saturation to preven things from getting too bright
		sat = 30;
	if (sat<10) // anything less than 15 is pretty uninteresting, no sense in displaying....
		current = 0;
	else
	{
		//sat2 = exp(sat/13.0f);
		//current = (uint32_t)(SAT_GAIN*sat2) + (uint32_t)(AREA_GAIN*n) + (uint32_t)(SA_GAIN*n*sat2);
		current = (uint32_t)(SA_GAIN*n*sat);
	}
	if (current>LED_MAX_CURRENT/5)
		current = LED_MAX_CURRENT/5;
	led_setMaxCurrent(current);

#if 0
	// find reasonable bias to subtract out
	bias = min*75/100;
	r -= bias;
	g -= bias;
	b -= bias;
	
	// saturate
	m = 255.0f/(max-bias);
	r = (uint8_t)(m*r);
	g = (uint8_t)(m*g);
	b = (uint8_t)(m*b);
#endif
#if 1
	// saturate
	rgbUnpack(saturate(rgbPack(r, g, b)), &r, &g, &b);
#endif
	//cprintf("r %d g %d b %d min %d max %d sat %d sat2 %d n %d\n", r, g, b, min, max, sat, sat2, n);
	led_setRGB(r, g, b);	 	
}
bool ButtonMachine::handleSignature()
{
	uint32_t bt;

	bt = button();

   	if (m_ledPipe) // if ledpipe, grab frame, but don't flush 
	{
		cam_getFrameChirpFlags(CAM_GRAB_M1R2, 0, 0, CAM_RES2_WIDTH, CAM_RES2_HEIGHT, g_chirpUsb, 0);
		ledPipe();
	}
	else if (m_goto!=0) // else grab frame and flush
		cam_getFrameChirpFlags(CAM_GRAB_M1R2, 0, 0, CAM_RES2_WIDTH, CAM_RES2_HEIGHT, g_chirpUsb);

	switch(m_goto)
	{
	case 0:  // wait for button press
		if (bt)
		{
			setTimer(&m_timer);
			led_setMaxCurrent(g_ledBrightness); // restore default brightness
			m_goto = 1;
			led_set(0);
		}
		break;

	case 1: // wait for button timeout
		if (!bt)
			m_goto = 0;
		else if (getTimer(m_timer)>BT_INITIAL_BUTTON_TIMEOUT)
		{
			if (cam_getAWB())
				m_index = 1;
			else
				m_index = 0;
			setTimer(&m_timer);
			setLED();
			m_goto = 2;
		}
		break;

	case 2: // wait and increment index 
		if (!bt)
		{
			flashLED(3);
			setTimer(&m_timer);
			if (m_index==0)
				cam_setAWB(1);
			else
				m_ledPipe = true;
			m_goto = 3;
		}
		else if (getTimer(m_timer)>BT_INDEX_CYCLE_TIMEOUT)
		{
			setTimer(&m_timer);
			m_index++;
			if (m_index==CL_NUM_SIGNATURES+1)
				m_index = 0;

			setLED();
		}							   
		break;

	case 3: // wait for button down
		if (bt)
		{
			setTimer(&m_timer);
			m_goto = 4;
		}
		else if (getTimer(m_timer)>BT_LIGHTPIPE_TIMEOUT) // abort
			reset();
		break;

	case 4: // wait for button up
		if (!bt)
		{
			if (m_index==0)
			{
				cam_setAWB(0);
				flashLED(4); 
			}
			else
				setSignature();
			reset(); // done	
		}
		else if (getTimer(m_timer)>BT_INITIAL_BUTTON_TIMEOUT)
		{
 			if (m_index==0)
				cam_setAWB(0);

			reset();
			m_goto = 5;
		}
	 	break;

	case 5: // wait for button up only
		if (!bt)
			reset();
		break;

	default:
		reset();
	}	

	return m_goto!=0;
}