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 haofan Zheng

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