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: RemovedSources/Camera.cpp.txt
- 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]; +} +