SmartWheels self-driving race car. Designed for NXP Cup. Uses FRDM-KL25Z, area-scan camera, and simple image processing to detect and navigate any NXP spec track.
Dependencies: TSI USBDevice mbed-dev
Fork of SmartWheels by
Diff: Hardwares/ArduCAM.cpp
- Revision:
- 97:0ed9ede9a995
- Parent:
- 96:ec89c4d1383d
- Child:
- 99:c6665262fd3d
--- a/Hardwares/ArduCAM.cpp Wed Apr 19 19:43:15 2017 +0000 +++ b/Hardwares/ArduCAM.cpp Wed Apr 19 21:17:40 2017 +0000 @@ -40,35 +40,24 @@ inline void ardu_cam_spi_write_8(int address, int value) { // take the SS pin low to select the chip: -#ifdef SW_DEBUG - g_sw_spi_lock.lock(); -#endif cam_cs = 0; // send in the address and value via SPI: g_spi_port.write(address | 0x80); g_spi_port.write(value); // take the SS pin high to de-select the chip: cam_cs = 1; -#ifdef SW_DEBUG - g_sw_spi_lock.unlock(); -#endif } inline uint8_t ardu_cam_spi_read_8(int address) { // take the SS pin low to select the chip: -#ifdef SW_DEBUG - g_sw_spi_lock.lock(); -#endif cam_cs = 0; // send in the address and value via SPI: g_spi_port.write(address & 0x7F); uint8_t value = static_cast<uint8_t>(g_spi_port.write(0x00)); // take the SS pin high to de-select the chip: cam_cs = 1; -#ifdef SW_DEBUG - g_sw_spi_lock.unlock(); -#endif + return value; } @@ -88,8 +77,8 @@ delete camReg; camReg = NULL; - uint8_t VerNum = ardu_cam_spi_read_8(0x40); - VerNum = ardu_cam_spi_read_8(0x40); + uint8_t VerNum = ardu_cam_spi_read_8(ARDUCHIP_VER); + VerNum = ardu_cam_spi_read_8(ARDUCHIP_VER); ardu_cam_spi_write_8(ARDUCHIP_TEST1, ARDUCHIP_TEST_MSG); uint8_t testV = ardu_cam_spi_read_8(ARDUCHIP_TEST1); @@ -168,7 +157,7 @@ black_calibrate = temp * 0.7f; } -inline void get_img_row_info(const uint8_t display, const uint8_t rowI, uint8_t * left, uint8_t * right, uint8_t* isBorderFound) +inline void get_img_row_info(const uint8_t rowI, uint8_t * left, uint8_t * right, uint8_t* isBorderFound) { *left = 0; *right = RESOLUTION_WIDTH; @@ -287,7 +276,7 @@ #if defined(CAM_DISP_IMG) or defined(CAM_DISP_DEBUG) ardu_utft_set_camimg_row(CAM_ROI_UPPER_LIMIT - i); #endif - get_img_row_info(0, i, &leftPos, &rightPos, &isBorderFound); + get_img_row_info(i, &leftPos, &rightPos, &isBorderFound); temp_mid_pos = (leftPos + rightPos) / 2; uint8_t dis_btw_left_right = rightPos - leftPos - 1; if(dis_btw_left_right < TERMINATE_WIDTH) @@ -351,6 +340,46 @@ } +inline void get_img_row_disp(const uint8_t rowI, uint8_t * left, uint8_t * right) +{ + *left = 0; + *right = RESOLUTION_WIDTH; + uint8_t isRightFound = 0; + static uint16_t pixel = 0x0000; + static uint8_t pGreen = 0x00; + + for (uint8_t j = 0; j < RESOLUTION_WIDTH; ++j) + { + pixel = static_cast<uint16_t>(ardu_cam_spi_read_8(SINGLE_FIFO_READ)) << 8; + pixel = pixel | ardu_cam_spi_read_8(SINGLE_FIFO_READ); + + pGreen = static_cast<uint8_t>((pixel & 0x07E0) >> 3); + if((pGreen < black_calibrate)) + { + if(j < temp_mid_pos) + { + *left = j; + ardu_utft_write_DATA(0xF8, 0x00); + } + else if(!isRightFound) + { + *right = j; + isRightFound = 1; + ardu_utft_write_DATA(0xF8, 0x00); + } + else + { + ardu_utft_write_DATA(static_cast<uint8_t>(pixel >> 8), static_cast<uint8_t>(pixel)); + } + } + else + { + ardu_utft_write_DATA(static_cast<uint8_t>(pixel >> 8), static_cast<uint8_t>(pixel)); + } + } + +} + void ardu_cam_display_img_utft() { ardu_cam_start_capture(); @@ -358,18 +387,51 @@ while (!(ardu_cam_spi_read_8(ARDUCHIP_TRIG) & CAP_DONE_MASK)); temp_mid_pos = RESOLUTION_WIDTH / 2; +#ifdef CAM_BLK_CAL_ACTIVE + static float calTemp = 0.0f; + calTemp = 0.0f; + static uint16_t greenPixel = 0x00; + uint8_t isValid = 1; + for (uint8_t j = 0; j < RESOLUTION_WIDTH; ++j) + { + if(CAM_BLK_CAL_LEFT < j && j <= CAM_BLK_CAL_RIGHT) + { + greenPixel = static_cast<uint16_t>(ardu_cam_spi_read_8(SINGLE_FIFO_READ)) << 8; + greenPixel = greenPixel | ardu_cam_spi_read_8(SINGLE_FIFO_READ); + greenPixel = (greenPixel & 0x07E0) >> 3; + if(static_cast<uint8_t>(greenPixel) < black_calibrate) + { + isValid = 0; + } + calTemp += static_cast<uint8_t>(greenPixel); + } + else + { + ardu_cam_spi_read_8(SINGLE_FIFO_READ); + ardu_cam_spi_read_8(SINGLE_FIFO_READ); + } + } + if(isValid) + { + calTemp = calTemp / static_cast<float>(CAM_BLK_CAL_RIGHT - CAM_BLK_CAL_LEFT); + black_calibrate = static_cast<uint8_t>(calTemp * 0.7f); + } +#endif + //cal_black_calibrate(); + uint8_t leftPos = 0; + uint8_t rightPos = 0; + is_encounter_terminate = 0; for (uint8_t i = 0; i < CAM_ROI_UPPER_LIMIT; ++i) { ardu_utft_set_camimg_row(CAM_ROI_UPPER_LIMIT - i); - for (uint8_t j = 0; j < RESOLUTION_WIDTH; ++j) - { - uint8_t VH = ardu_cam_spi_read_8(SINGLE_FIFO_READ); - uint8_t VL = ardu_cam_spi_read_8(SINGLE_FIFO_READ); - - ardu_utft_write_DATA(VH, VL); - } + get_img_row_disp(i, &leftPos, &rightPos); + temp_mid_pos = (leftPos + rightPos) / 2; + + ardu_utft_set_camimg_rowcol(CAM_ROI_UPPER_LIMIT - i, temp_mid_pos); + ardu_utft_write_DATA(0xF8, 0x00); + } } @@ -383,6 +445,11 @@ return is_border_find; } +uint8_t ardu_cam_get_ver_num() +{ + return ardu_cam_spi_read_8(ARDUCHIP_VER); +} + #ifdef __cplusplus } #endif