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:
36:7e747e19f660
Parent:
29:f87d8790f57d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RemovedSources/Camera.cpp.txt	Tue Mar 14 22:23:15 2017 +0000
@@ -0,0 +1,227 @@
+#include "Camera.h"
+
+#include "Core.h"
+#include "OV7725RegAddr.h"
+#include "PinAssignment.h"
+#include "SWUSBServer.h"
+
+namespace
+{
+    DigitalOut testLED(LED_GREEN, 1);
+    DigitalOut testLED2(LED_RED, 1);
+    
+    BusIn dataBus(PIN_CC_D_0, PIN_CC_D_1, PIN_CC_D_2, PIN_CC_D_3, PIN_CC_D_4, PIN_CC_D_5, PIN_CC_D_6, PIN_CC_D_7);
+    
+    bool isInLine = false;
+    uint8_t currentCol = 0;
+    uint8_t outCurrentCol = 0;
+    
+    uint16_t currentRow = 0;
+    uint16_t outCurrentRow = 0;
+    
+    uint16_t outENum = 0;
+    
+    uint8_t pictureData[PICTURE_ARRAY_SIZE];
+    
+    bool hasPic = false;
+}
+
+
+static void OnPixelClock()
+{
+    if(hasPic)
+        return;
+    
+    unsigned int pos = (currentRow * (CAMERA_PIXEL_WIDTH/8)) + currentCol;
+    if(isInLine && (pos < PICTURE_ARRAY_SIZE))
+    {
+        pictureData[pos] = dataBus.read();
+        ++currentCol;
+    }
+    /*
+    else if(pos > PICTURE_ARRAY_SIZE)
+    {
+        outENum = pos;
+        testLED2 = 0;
+    }
+    */
+}
+
+static void OnHorizontalRise()
+{
+    if(hasPic)
+        return;
+    
+    isInLine = true;
+    
+    //++currentRow;
+}
+
+static void OnHorizontalFall()
+{
+    if(hasPic)
+        return;
+    
+    isInLine = false;
+    
+    if(currentCol > 0)
+    {
+        ++currentRow;
+    }
+    outCurrentCol = currentCol;
+    currentCol = 0;
+}
+
+static void OnFrameRise()
+{
+    if(currentRow >= CAMERA_PIXEL_HEIGHT)
+        hasPic = true;
+}
+
+static void OnFrameFall()
+{
+    if(hasPic)
+        return;
+    
+    outCurrentRow = currentRow;
+    currentRow = 0;
+    testLED = testLED.read() == 1 ? 0 : 1;
+}
+
+Camera::Camera(SW::Core & core) : 
+    m_core(core),
+    m_pClock(InterruptIn(PIN_CC_PCLOCK)),
+    m_href(InterruptIn(PIN_CC_HREF)),
+    m_vsnyc(InterruptIn(PIN_CC_VSYNC)),
+    m_regBuf(NULL),
+    m_debugOutputTimer(0.0f)
+{
+    m_regBuf = new OV7725RegBuf(m_core);
+
+/*
+    m_regBuf->WriteDefaultRegisters();
+    
+#if (CAMERA_PIXEL_WIDTH == 80)
+    m_regBuf->SCCBWrite(OV7725_HOutSize, 0x14);
+#elif (CAMERA_PIXEL_WIDTH == 160)
+    m_regBuf->SCCBWrite(OV7725_HOutSize, 0x28);
+#elif (CAMERA_PIXEL_WIDTH == 240)
+    m_regBuf->SCCBWrite(OV7725_HOutSize, 0x3c);
+#elif (CAMERA_PIXEL_WIDTH == 320)
+    m_regBuf->SCCBWrite(OV7725_HOutSize, 0x50);
+#endif
+
+#if (CAMERA_PIXEL_HEIGHT == 60 )
+    m_regBuf->SCCBWrite(OV7725_VOutSize, 0x1E);
+#elif (CAMERA_PIXEL_HEIGHT == 120 )
+    m_regBuf->SCCBWrite(OV7725_VOutSize, 0x3c);
+#elif (CAMERA_PIXEL_HEIGHT == 180 )
+    m_regBuf->SCCBWrite(OV7725_VOutSize, 0x5a);
+#elif (CAMERA_PIXEL_HEIGHT == 240 )
+    m_regBuf->SCCBWrite(OV7725_VOutSize, 0x78);
+#endif
+    
+    m_regBuf->SCCBWrite(OV7725_COM4,  0x01);
+    m_regBuf->SCCBWrite(OV7725_CLKRC, 0x89);
+*/    
+    char buf[20];
+    unsigned char tempV = m_regBuf->SCCBRead(OV7725_HOutSize);
+    sprintf(buf, "CamReg %#x=%#x", OV7725_HOutSize, tempV);
+    m_core.GetUSBServer().PushReliableMsg('D', buf);
+    
+    tempV = m_regBuf->SCCBRead(OV7725_VOutSize);
+    sprintf(buf, "CamReg %#x=%#x", OV7725_VOutSize, tempV);
+    m_core.GetUSBServer().PushReliableMsg('D', buf);
+    
+    tempV = m_regBuf->SCCBRead(OV7725_COM4);
+    sprintf(buf, "CamReg %#x=%#x", OV7725_COM4, tempV);
+    m_core.GetUSBServer().PushReliableMsg('D', buf);
+    
+    tempV = m_regBuf->SCCBRead(OV7725_CLKRC);
+    sprintf(buf, "CamReg %#x=%#x", OV7725_CLKRC, tempV);
+    m_core.GetUSBServer().PushReliableMsg('D', buf);
+    
+    delete m_regBuf;
+    m_regBuf = NULL;
+    
+    memset(pictureData, 0, PICTURE_ARRAY_SIZE);
+    
+    StartReceivingPic();
+}
+
+Camera::~Camera()
+{
+    
+}
+
+void Camera::Update(float deltaTime)
+{
+    m_debugOutputTimer += deltaTime;
+    
+    //if(hasPic)
+    //{
+    //    StopReceivingPic();
+    //}
+    
+    if(m_debugOutputTimer >= 10.0)
+    {
+        char buf[20];
+        sprintf(buf, "ColSize: %u", outCurrentCol);
+        m_core.GetUSBServer().PushUnreliableMsg('D', buf);
+        sprintf(buf, "RowSize: %u", outCurrentRow);
+        m_core.GetUSBServer().PushUnreliableMsg('D', buf);
+        //sprintf(buf, "ENum: %u", outENum);
+        //m_core.GetUSBServer().PushUnreliableMsg('D', buf);
+        
+        m_debugOutputTimer = 0.0f;
+        
+        //if(hasPic)
+        //{
+            StopReceivingPic();
+            testLED2 = testLED2.read() == 1 ? 0 : 1;
+            
+            for(uint8_t i = 0; i < CAMERA_PIXEL_HEIGHT; ++i)
+            {
+                std::string outBuf;
+                outBuf.push_back(i);
+                outBuf.insert(outBuf.end(), &pictureData[i * (CAMERA_PIXEL_WIDTH / 8)], &pictureData[(i + 1) * (CAMERA_PIXEL_WIDTH / 8)]);
+                m_core.GetUSBServer().PushReliableMsg('P', outBuf);
+                wait(0.02);
+            }
+            
+            StartReceivingPic();
+        //}
+    }
+    
+}
+
+void Camera::StartReceivingPic()
+{
+    hasPic = false;
+    
+    m_pClock.rise(&OnPixelClock);
+    m_href.rise(&OnHorizontalRise);
+    m_href.fall(&OnHorizontalFall);
+    m_vsnyc.fall(&OnFrameFall);
+    //m_vsnyc.rise(&OnFrameRise);
+}
+
+void Camera::StopReceivingPic()
+{
+    //m_vsnyc.rise(NULL);
+    m_vsnyc.fall(NULL);
+    m_href.fall(NULL);
+    m_href.rise(NULL);
+    m_pClock.rise(NULL);
+}
+
+bool Camera::HasPicture() const
+{
+    return hasPic;
+}
+
+const unsigned char * Camera::GetPicture() const
+{
+    return NULL; //m_pics[m_currentIndex == 0 ? 1 : 0];
+}
+