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
RemovedSources/Camera.cpp.txt
- Committer:
- hazheng
- Date:
- 2017-03-14
- Revision:
- 36:7e747e19f660
- Parent:
- Hardwares/Camera.cpp@ 29:f87d8790f57d
File content as of revision 36:7e747e19f660:
#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]; }