Today you can hardly surprise anyone with a mobile phone with a camera, wireless gadgets and other technical advances. Thanks to the Arduino platform, millions of people have discovered the wonderful world of electronics and programming. 100, 500 instructions were written on how to exchange data between a mobile phone and Arduino over bluetooth... What am I talking about? Yes. I want to exchange data between a mobile phone on Android and Arduino UNO over bluetooth in 100, 501 times. But I want to transmit not just a set of characters and numbers, but pictures.
Someone will say that this is impossible, Arduino is too slow to process large amounts of data with good speed. And he will be absolutely right. And what if a little bit of help Arduino - to transfer all the "hard" work on the shoulders of other device? And there is such a device!
This is a unique TFT shield for Arduino. Information about this logo is in these articles: article 1, article 2 In this tutorial, I will demonstrate how you can connect via bluetooth between Arduino and Android phone, get a picture from the OV7670 camera on Arduino UNO and transfer it to Android phone. Then, on the contrary, transfer the picture (image from the camera) from the Android phone to Arduino UNO and display it on the screen of a unique TFT shield.
A special application was written for the Android phone.
Brief characteristics of TFT shield:
- Size 3.5 " diagonal,
- Resolution 320x240,
- Number of colors 65536 (16-bit),
- Resistive touch screen (XPT2046 controller),
- 5 buttons,
- RTC IC DS1307 with 3V lithium battery CR1220,
- Slot for connecting a micro SD card,
- 4-pin (2.54 mm) connector for connecting the Bluetooth module HC-05 (-06), ESP8286 WiFi module.
- 20-pin (2.54 mm) connector for camera (OV7670).
Hardware:
- AC-DC power adapter 6-12 volt, >600mA;
- Android phone.
Attention: It is necessary (!) To use a 6-12 volt power adapter to operate the TFT shield, because the maximum current of 500 mA from USB is not enough for normal operation.
Software:
PreparingSoftware
All demonstration sketches are written in the Arduino IDE environment, therefore at the beginning it is necessary to install the Arduino IDE - https://www.arduino.cc/en/main/software.Then you need to install a library for TFT shield - github.com/YATFT/YATFT (download the library and unpack it into the "libraries" folder in the Arduino IDE directory).
After installing the Arduino IDE, you must program the Arduino UNO board. For simplicity, I recommend flashing it separately, without TFT shield. For this:
- Connect the USB cable to the Arduino UNO board;
- Run the Arduino IDE on the computer;
- Select the corresponding port to which the Arduino UNO is connected;
- Download the ArduinoBluetoothCamera.ino demo sketch (and file ov7670_regs.h for camera init);
- Click the button Upload.
If the Arduino UNO board is successfully programmed, you can proceed to the next step.
ArduinoBluetoothCamera.ino sketch:
/**********************************************************************
* SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A
* PARTICULAR PURPOSE. IN NO EVENT SHALL AUTHOR OR ITS LICENSORS BE
* LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY,
* CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY
* DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO
* ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES,
* LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS,
* TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT
* NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
***********************************************************************/
#include <YATFT.h>
#include <util/yacam.h>
#include <util/yacodec.h>
#include <util/yasrl.h>
#include "ov7670_regs.h"
JPEG_DECODE jpeg_decode;
YATFT tft(0);
INTRFC ifc;
CAM cam;
CODEC codec;
SRL srl;
#define IMG_SizeX 320
#define IMG_SizeY 240
uint8_t mode = 0;
uint8_t last_mode = 0;
uint8_t start_capt = 0;
uint16_t err;
void setup()
{
// initialize the serial port
Serial.begin(115200);
// initialize the display
tft.begin();
tft.SetColor(BRIGHTRED);
tft.ClearDevice();
}
void loop()
{
// put your main code here, to run repeatedly:
if (Serial.available())
{
uint8_t temp = Serial.read();
switch (temp)
{
case 0x10: // Send single Photo
mode = 1;
start_capt = 1;
if (last_mode != mode && last_mode != 2) {
tft.begin();
tft.SetRGB(); // Switch to RGB mode
cam.CamInit(&OV7670_QVGA[0][0]);
cam.CamVideoPreview(0, 0, 1, true);
codec.JPEGInit();
codec.JPEGSetRegs(IMG_SizeX, IMG_SizeY);
delay(1000);
}
break;
case 0x20: // Continuous send Photo
mode = 2;
start_capt = 2;
if (last_mode != mode && last_mode != 1) {
tft.begin();
tft.SetRGB(); // Switch to RGB mode
cam.CamInit(&OV7670_QVGA[0][0]);
cam.CamVideoPreview(0, 0, 1, true);
codec.JPEGInit();
codec.JPEGSetRegs(IMG_SizeX, IMG_SizeY);
}
break;
case 0x30: // Receive single Photo
mode = 3;
start_capt = 3;
if (last_mode != mode && last_mode != 4) {
tft.begin();
tft.SetYUV(); // Switch to YUV mode
}
break;
case 0x40: // Continuous receive Photo
mode = 4;
start_capt = 4;
if (last_mode != mode && last_mode != 3) {
tft.begin();
tft.SetYUV(); // Switch to YUV mode
}
break;
default:
break;
}
}
if (mode == 1) // Send single Photo
{
if (start_capt == 1)
{
start_capt = 0;
last_mode = mode;
mode = 0;
CamCapture();
}
}
else if (mode == 2) // Continuous send Photo
{
while (1)
{
uint8_t temp = Serial.read();
if (start_capt == 2)
{
start_capt = 0;
}
if (temp == 0x21) // Stop ?
{
start_capt = 0;
last_mode = mode;
mode = 0;
break;
}
if (CamCapture()) continue;
}
}
else if (mode == 3) // Receive single Photo
{
if (start_capt == 3)
{
//Start capture
start_capt = 0;
last_mode = mode;
mode = 0;
Serial.print("!");
srl.JPEGReadFromSerial(&jpeg_decode, // jpeg decode structure
0, // x0 (left)
0, // y0 (top)
GetMaxX()+1, // x1 (right)
GetMaxY()+1, // y1 (bottom)
32000); // max image size
}
}
else if (mode == 4) // Continuous receive Photo
{
uint8_t temp = Serial.read();
while (1)
{
if (start_capt == 4)
{
//Start capture
start_capt = 0;
}
if (temp == 0x41) // Stop ?
{
start_capt = 0;
last_mode = mode;
mode = 0;
break;
}
Serial.print("!");
srl.JPEGReadFromSerial(&jpeg_decode, // jpeg decode structure
0, // x0 (left)
0, // y0 (top)
GetMaxX()+1, // x1 (right)
GetMaxY()+1, // y1 (bottom)
32000); // max image size
}
}
}
uint8_t CamCapture(void)
{
uint8_t temp = 0xff, temp_last = 0;
bool is_header = false;
uint32_t length = 0;
length = codec.JPEGStart();
uint32_t en_jpeg_address = ifc.rdReg32(0x414)<<2;
int k = 0;
if ((length >= 0x5FFFF) | (length == 0))
{
start_capt = 2;
return 1;
}
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.write(temp_last);
Serial.write(temp);
}
if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
break;
}
is_header = false;
return 0;
}
OV7670_regs.h:
#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}, {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}, {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
Android
On the Android phone, you need to install the ArduinoTFT.apk. Allow the app to use the Bluetooth and Camera.
Update 05/26/2020 !
I added sourcecode of ArduinoTFT.apk. AS IS! Download ArduinoTFT.zip.h
, rename to ArduinoTFT.zip and unzip. Enjoy!
Update 07/25/2020 !
"Hi, i had the same problem with the Android App wich doesn't work. Solved after authorized the App to access at the smartphone camera. That's it. Bye" (c)
Bluetooth module
It is necessary to set the exchange rate in the Bluetooth module to be 115200 (command "AT+UART=115200, 0, 0"). This is the optimal speed at which Arduino UNO manages to receive and process data. (Theoretically, you can increase the speed, optimize data reception and processing, but this requires a larger amount of RAM).More detailed instructions on how to set the exchange rate can be found on the Internet, for example, here: https://www.instructables.com/id/Communication-Bluetooth-Module-With-HC-05-HC-06/ .
(!) Please note that the Bluetooth module connects to the debug port of Arduino UNO. Thus, when working with bluetooth, the debug port is not available. And before programming the Arduino UNO (complete with the Bluetooth module) must disconnect the Bluetooth module. And after programming, set it back (!)
AssemblyAssembly of the device is quite simple:
- Connect together Arduino UNO and TFT-shield;
- Connect the OV7670 camera to the 20-pin connector on the TFT-shield of the shield (sometimes I use an angled 18-20 pin connector with a 2.54 mm pitch as an adapter);
- Connect the Bluetooth module HC-06 (HC-05) to the 4-pin connector with the words "Bluetooth" on the TFT-shield;
- Connect the 6-12V power adapter to the power input on the Arduino UNO board.
After turning on the power, the TFT shield's screen should turn red. This means the willingness to receive commands from the Android phone.
DemonstrationPerform the following operations on the Android phone:
- Launch the ArduinoTFT application on the Android phone;
- Turn the phone in a horizontal position;
- Enable the Bluetooth connection, select the detected Bluetooth module (HC-06);
Two windows and four buttons should appear on the screen:
- The top right window is the phone's camera viewfinder window;
- Large left window - received or sent images.
Button functions:
- Transfer single image from Android phone to Arduino;
- Continuous transfer of images from the Android phone to Arduino;
- Transfer single image from Arduino to Android phone;
- Continuous transfer of images from Arduino to Android phone.
The image size is 320x240 pixels (2-5 kB). This chapter has a demo video.
If you like my article, I would appreciate an assessment. Perhaps this will give me motivation for new articles. :-)
Thanks for watching!
Previous articles:
1) Unique TFT Shield for Arduino Uno - Start,
2) Unique Arduino TFT Shield - OV7670 Cam.
Next articles:
3) TFT shield for Arduino Nano - Start,
4) Photos and RGB video on TFT SPI display.
5) Control by Smartphone 4WD Robot Car over Bluetooth.
Update 01.04.2021:
Hello again! There is an updated library for a series of screens, which currently consists of two shields and two breakout boards. The sketch is compiled depending on the selected version (from 1 to 4) and the type of microcontroller (MegaAVR or ESP-32). Added photos, examples. More information can be found in the https://github.com/Ekaburg/EkaTFT.
Comments