Alf81010
Published © LGPL

Image transmit and Control by Smartphone 4WD Robot Car

Image transmit and Control by Smartphone 4WD Robot Car over Bluetooth

IntermediateShowcase (no instructions)2 hours8,601
Image transmit and Control by Smartphone 4WD Robot Car

Things used in this project

Story

Read more

Schematics

Motor driver scheme

Code

TFT_shield_Robot.ino

C/C++
/*
 * Arduino TFT_shield_v1.00 ROBOT example
 * 
 * Authors: Kamil Lee, Iron Khan (2018)
 * 
 * Comments:
 * 
 * 
 */

#include <YATFT.h> // Hardware-specific library
#include <util/yasdc.h>
#include <util/yacam.h>
#include <util/yacodec.h>
#include "ov7670_regs.h"

int mode = 0;
uint8_t start_capt = 0;
int k;

YATFT tft(0);
CAM   cam;
INTRFC ifc;
SDC   sdc;
CODEC codec;

/* 
   If using the shield, all control and data lines are fixed, and
   a simpler declaration can optionally be used:
*/
uint16_t  err;
bool      f_light = false;

#define RIGHT_TRACK_FORWARD 13
#define RIGHT_TRACK_ON       2 //12
#define LEFT_TRACK_BACK     11
#define LEFT_TRACK_ON        2

//#define IMG_VGA
#define IMG_QVGA

#ifdef IMG_VGA
#define IMG_SizeX    640
#define IMG_SizeY    480
#else // IMG_QVGA
#define IMG_SizeX    320
#define IMG_SizeY    240
#endif

/*********************************************************************************
*
*********************************************************************************/
void setup()
{
    uint8_t state;

    // initialize the serial port
    Serial.begin(115200);
    Serial.println(F("TFT_shield_Robot example!"));

    pinMode(    LEFT_TRACK_BACK, OUTPUT);
    pinMode(RIGHT_TRACK_FORWARD, OUTPUT);
    pinMode(      LEFT_TRACK_ON, OUTPUT);
    pinMode(     RIGHT_TRACK_ON, OUTPUT);

    digitalWrite(    LEFT_TRACK_BACK, LOW);
    digitalWrite(RIGHT_TRACK_FORWARD, LOW);
    digitalWrite(      LEFT_TRACK_ON, LOW);
    digitalWrite(     RIGHT_TRACK_ON, LOW);

    // initialize the display
    tft.begin();

    tft.SetColor(BLACK);
    tft.ClearDevice();

    delay(100);

    err = cam.CamInit(&OV7670_QVGA[0][0]);
    cam.CamVideoPreview(0, 0, 1, true);

    delay(1000);

    tft.SetColor(BLACK);
    tft.ClearDevice();

    codec.JPEGInit();
    codec.JPEGSetRegs(IMG_SizeX, IMG_SizeY);

    pinMode(    LEFT_TRACK_BACK, OUTPUT);
    pinMode(RIGHT_TRACK_FORWARD, OUTPUT);
    pinMode(      LEFT_TRACK_ON, OUTPUT);
    pinMode(     RIGHT_TRACK_ON, OUTPUT);
}


/*********************************************************************************
*
*********************************************************************************/
void loop()
{
    // put your main code here, to run repeatedly:
    uint8_t temp = 0xff, temp_last = 0;
    bool is_header = false;
    if (Serial.available())
    {
        temp = Serial.read();

        SerialRoutine(temp);
        temp = 0xff;
    }
    if (mode == 1)
    {
        if (start_capt == 1)
        {
            start_capt = 0;
        }
        Serial.println(F("ACK CMD CAM Capture Done."));

        uint8_t temp, temp_last;
        uint32_t length = 0;

        codec.JPEGSetRegs(IMG_SizeX, IMG_SizeY);
        length = codec.JPEGStart();
        uint32_t en_jpeg_address = ifc.rdReg32(0x414)<<2;
        k = 0;

        if (length >= 0x5FFFF) 
        {
            Serial.println(F("ACK CMD Over size."));
            return;
        }
        if (length == 0 ) //0 kb
        {
            Serial.println(F("ACK CMD Size is 0."));
            return;
        }
        temp = ifc.GetMem(en_jpeg_address+k);
        k++;
        length --;
        while ( length-- )
        {
            temp_last = temp;
            temp = ifc.GetMem(en_jpeg_address+k);
            k++;
            if (is_header == true)
            {
                Serial.write(temp);
            }
            else if ((temp == 0xD8) & (temp_last == 0xFF))
            {
                is_header = true;
                Serial.println(F("ACK IMG"));
                Serial.write(temp_last);
                Serial.write(temp);
            }
            if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
            {
                break;
            }
        }
        is_header = false;

        start_capt = 0;
        mode = 0;
    
        Serial.println("");
        Serial.println(F("ACK END"));
    }
    else if (mode == 2)
    {
        while (1)
        {
            temp = Serial.read();
            if (temp == 0x21)
            {
                start_capt = 0;
                mode = 0;
                Serial.println(F("ACK CMD CAM stop video streaming."));
                break;
            }
            if (start_capt == 2)
            {
                //Start capture
                start_capt = 0;
            }
            SerialRoutine2 (temp);
            uint32_t length = 0;

            codec.JPEGSetRegs(IMG_SizeX, IMG_SizeY);
            length = codec.JPEGStart();
            uint32_t en_jpeg_address = ifc.rdReg32(0x414)<<2;
            k = 0;
                
            if ((length >= 0x5FFFF) | (length == 0))
            {
                start_capt = 2;
                continue;
            }
            temp = ifc.GetMem(en_jpeg_address+k);
            k++;
            length --;
            while ( length-- )
            {
                temp_last = temp;
                temp = ifc.GetMem(en_jpeg_address+k);
                k++;
                if (is_header == true)
                {
                    Serial.write(temp);
                }
                else if ((temp == 0xD8) & (temp_last == 0xFF))
                {
                    is_header = true;
                    Serial.println(F("ACK IMG"));
                    Serial.write(temp_last);
                    Serial.write(temp);
                }
                if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
                {
                    break;
                }
            }
            start_capt = 2;
            is_header = false;
        }
    }
    else if (mode == 3)
    {
    }
}

void SerialRoutine (uint8_t temp)
{
    switch (temp)
    {
        case 0x10:
             mode = 1;
             start_capt = 1;
             Serial.println(F("ACK CMD CAM start single shoot."));
             break;
        case 0x11: 
             break;
        case 0x20:
             mode = 2;
             start_capt = 2;
             Serial.println(F("ACK CMD CAM start video streaming."));
             break;
        case 0x21:
             start_capt = 0;
             mode = 0;
             Serial.println(F("ACK CMD CAM stop video streaming."));
             break;
        case 0x31:
             break;
        case 'F':    // Forward
             Forward();
             break;
        case 'B':    // Back
             Back();
             break;
        case 'L':    // Left
             Left();
             break;
        case 'R':    // Right
             Right();
             break;
        case 'S':    // Stop
             Stop();
             break;
        case 'I':    // Illuminate
             if (f_light == true)
             {
                 tft.gpio_bl(0); // Backlight Off
                 f_light = false;
             } else {
                 tft.gpio_bl(1); // Backlight On
                 f_light = true;
             }
             break;
        default:
//             Serial.println(temp, HEX);
             break;
    }
}

void SerialRoutine2 (uint8_t temp)
{
    switch (temp)
    {
        case 'F':    // Forward
             digitalWrite( LEFT_TRACK_BACK,     LOW);
             digitalWrite(RIGHT_TRACK_FORWARD, HIGH);
             digitalWrite(      LEFT_TRACK_ON, HIGH);
             digitalWrite(     RIGHT_TRACK_ON, HIGH);
             break;
        case 'B':    // Back
             digitalWrite( LEFT_TRACK_BACK,    HIGH);
             digitalWrite(RIGHT_TRACK_FORWARD,  LOW);
             digitalWrite(      LEFT_TRACK_ON, HIGH);
             digitalWrite(     RIGHT_TRACK_ON, HIGH);
             break;
        case 'L':    // Left
             digitalWrite( LEFT_TRACK_BACK,    HIGH);
             digitalWrite(RIGHT_TRACK_FORWARD, HIGH);
             digitalWrite(      LEFT_TRACK_ON, HIGH);
             digitalWrite(     RIGHT_TRACK_ON, HIGH);
             delay(200);
             digitalWrite(     RIGHT_TRACK_ON,  LOW);
             digitalWrite(      LEFT_TRACK_ON,  LOW);
             break;
        case 'R':    // Right
             digitalWrite( LEFT_TRACK_BACK,     LOW);
             digitalWrite(RIGHT_TRACK_FORWARD,  LOW);
             digitalWrite(      LEFT_TRACK_ON, HIGH);
             digitalWrite(     RIGHT_TRACK_ON, HIGH);
             delay(200);
             digitalWrite(     RIGHT_TRACK_ON,  LOW);
             digitalWrite(      LEFT_TRACK_ON,  LOW);
             break;
        case 'S':    // Stop
             Stop();
             break;
        default:
             digitalWrite(     RIGHT_TRACK_ON,  LOW);
             digitalWrite(      LEFT_TRACK_ON,  LOW);
             break;
    }
}



void Forward (void)
{
    pinMode(    LEFT_TRACK_BACK, OUTPUT);
    pinMode(RIGHT_TRACK_FORWARD, OUTPUT);
    pinMode(      LEFT_TRACK_ON, OUTPUT);
    pinMode(     RIGHT_TRACK_ON, OUTPUT);

    digitalWrite( LEFT_TRACK_BACK,     LOW);
    digitalWrite(RIGHT_TRACK_FORWARD, HIGH);
    digitalWrite(      LEFT_TRACK_ON, HIGH);
    digitalWrite(     RIGHT_TRACK_ON, HIGH);
    delay(500);
    digitalWrite(     RIGHT_TRACK_ON,  LOW);
    digitalWrite(      LEFT_TRACK_ON,  LOW);
}

void Back (void)
{
    pinMode(    LEFT_TRACK_BACK, OUTPUT);
    pinMode(RIGHT_TRACK_FORWARD, OUTPUT);
    pinMode(      LEFT_TRACK_ON, OUTPUT);
    pinMode(     RIGHT_TRACK_ON, OUTPUT);

    digitalWrite( LEFT_TRACK_BACK,    HIGH);
    digitalWrite(RIGHT_TRACK_FORWARD,  LOW);
    digitalWrite(      LEFT_TRACK_ON, HIGH);
    digitalWrite(     RIGHT_TRACK_ON, HIGH);
    delay(500);
    digitalWrite(     RIGHT_TRACK_ON,  LOW);
    digitalWrite(      LEFT_TRACK_ON,  LOW);
}

void Left (void)
{
    pinMode(    LEFT_TRACK_BACK, OUTPUT);
    pinMode(RIGHT_TRACK_FORWARD, OUTPUT);
    pinMode(      LEFT_TRACK_ON, OUTPUT);
    pinMode(     RIGHT_TRACK_ON, OUTPUT);

    digitalWrite( LEFT_TRACK_BACK,    HIGH);
    digitalWrite(RIGHT_TRACK_FORWARD, HIGH);
    digitalWrite(      LEFT_TRACK_ON, HIGH);
    digitalWrite(     RIGHT_TRACK_ON, HIGH);
    delay(500);
    digitalWrite(     RIGHT_TRACK_ON,  LOW);
    digitalWrite(      LEFT_TRACK_ON,  LOW);
}

void Right (void)
{
    pinMode(    LEFT_TRACK_BACK, OUTPUT);
    pinMode(RIGHT_TRACK_FORWARD, OUTPUT);
    pinMode(      LEFT_TRACK_ON, OUTPUT);
    pinMode(     RIGHT_TRACK_ON, OUTPUT);

    digitalWrite( LEFT_TRACK_BACK,     LOW);
    digitalWrite(RIGHT_TRACK_FORWARD,  LOW);
    digitalWrite(      LEFT_TRACK_ON, HIGH);
    digitalWrite(     RIGHT_TRACK_ON, HIGH);
    delay(500);
    digitalWrite(     RIGHT_TRACK_ON,  LOW);
    digitalWrite(      LEFT_TRACK_ON,  LOW);
}

void Stop (void)
{
    digitalWrite(     RIGHT_TRACK_ON,  LOW);
    digitalWrite(      LEFT_TRACK_ON,  LOW);
}

ov7670_regs.h

C/C++
#ifndef OV7670_REGS_H
#define OV7670_REGS_H

const uint8_t OV7670_VGA[][2] PROGMEM =
{
    {   1, 0x42}, // Size of byte, Address (ID) 
    { 640/16,  480/16}, // Size X, Size Y
    {0b01000010, 0b00000100}, // Reset_Enable_N, 7|6|5|4|3|Vsync Invert|Hsync Invert|0

    {0x3a, 0x0C},
    {0x40, 0xC0},
    {0x12, 0x00}, // VGA
    {0x0c, 0x00},
    {0x3e, 0x00},
    {0x70, 0x3A},
    {0x71, 0x35},
    {0x72, 0x11},
    {0x73, 0xF0},
    {0xa2, 0x02},
    {0x11, 0x80},
    {0x7a, 0x18},
    {0x7b, 0x02},
    {0x7c, 0x07},
    {0x7d, 0x1F},
    {0x7e, 0x49},
    {0x7f, 0x5A},
    {0x80, 0x6A},
    {0x81, 0x79},
    {0x82, 0x87},
    {0x83, 0x94},
    {0x84, 0x9F},
    {0x85, 0xAF},
    {0x86, 0xBB},
    {0x87, 0xCF},
    {0x88, 0xEE},
    {0x89, 0xEE},
    {0x13, 0xE0},
    {0x00, 0x00},
    {0x10, 0x00},
    {0x0d, 0x00},
    {0x24, 0x98},
    {0x25, 0x63},
    {0x26, 0xD3},
    {0x2a, 0x00},
    {0x2b, 0x00},
    {0x2d, 0x00},
    {0x13, 0xe5},
    {0x13, 0xe7},
    {0x1e, 0x30},
    {0x74, 0x60},
    {0x01, 0x80},
    {0x02, 0x80},
    {0x15, 0x10},
    {0x4f, 0x40},
    {0x50, 0x34},
    {0x51, 0x0C},
    {0x52, 0x17},
    {0x53, 0x29},
    {0x54, 0x40},
    {0x57, 0x80},
    {0x58, 0x1e},
    {0x41, 0x10},
    {0x75, 0x60},
    {0x76, 0x50},
    {0x77, 0x48},
    {0x3d, 0x92},
    {0x3b, 0x00},
    {0x04, 0x00},
    {0xff, 0xff},
};        

const uint8_t OV7670_QVGA[][2] PROGMEM =
{
    {   1, 0x42}, // Size of byte, Address (ID) 
    { 320/16,  240/16}, // Size X, Size Y
    {0b01000010, 0b00000100}, // Reset_Enable_N, 7|6|5|4|3|Vsync Invert|Hsync Invert|0

    {0x3a, 0x0C},
    {0x40, 0xC0},
    {0x12, 0x10}, // QVGA
    {0x0c, 0x00},
    {0x3e, 0x00},
    {0x70, 0x3A},
    {0x71, 0x35},
    {0x72, 0x11},
    {0x73, 0xF0},
    {0xa2, 0x02},
    {0x11, 0x80},
    {0x7a, 0x18},
    {0x7b, 0x02},
    {0x7c, 0x07},
    {0x7d, 0x1F},
    {0x7e, 0x49},
    {0x7f, 0x5A},
    {0x80, 0x6A},
    {0x81, 0x79},
    {0x82, 0x87},
    {0x83, 0x94},
    {0x84, 0x9F},
    {0x85, 0xAF},
    {0x86, 0xBB},
    {0x87, 0xCF},
    {0x88, 0xEE},
    {0x89, 0xEE},
    {0x13, 0xE0},
    {0x00, 0x00},
    {0x10, 0x00},
    {0x0d, 0x00},
    {0x24, 0x98},
    {0x25, 0x63},
    {0x26, 0xD3},
    {0x2a, 0x00},
    {0x2b, 0x00},
    {0x2d, 0x00},
    {0x13, 0xe5},
    {0x13, 0xe7},
    {0x1e, 0x30},
    {0x74, 0x60},
    {0x01, 0x80},
    {0x02, 0x80},
    {0x15, 0x10},
    {0x4f, 0x40},
    {0x50, 0x34},
    {0x51, 0x0C},
    {0x52, 0x17},
    {0x53, 0x29},
    {0x54, 0x40},
    {0x57, 0x80},
    {0x58, 0x1e},
    {0x41, 0x10},
    {0x75, 0x60},
    {0x76, 0x50},
    {0x77, 0x48},
    {0x3d, 0x92},
    {0x3b, 0x00},
    {0x04, 0x00},
    {0xff, 0xff},
};        

#endif

Credits

Alf81010

Alf81010

7 projects • 58 followers

Comments