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