Skip to content

Instantly share code, notes, and snippets.

@ksasao
Last active August 21, 2018 07:54
Show Gist options
  • Save ksasao/879715cc86c6980ce82a333f5a1c81d8 to your computer and use it in GitHub Desktop.
Save ksasao/879715cc86c6980ce82a333f5a1c81d8 to your computer and use it in GitHub Desktop.
Grove Serial Camera Kit demo for M5Stack
//
// Grove Serial Camera Kit demo for M5Stack
//
// !! CAUTION !!
// This code uses M5Stack Grove I2C as Grove UART (serial port).
// REMOVE all I2C devices.
//
// original code:
// https://github.com/Seeed-Studio/Grove_Serial_Camera_Kit/blob/master/SerialCameral_DemoCode_CJ_OV528_SoftSer/SerialCameral_DemoCode_CJ_OV528_SoftSer.ino
// File SerialCamera_DemoCode_CJ-OV528.ino
// 8/8/2013 Jack Shao
// Demo code for using seeeduino or Arduino board to cature jpg format
// picture from seeed serial camera and save it into sd card. Push the
// button to take the a picture .
// For more details about the product please check http://www.seeedstudio.com/depot/
#include <M5Stack.h>
HardwareSerial Serial2(2);
#define PIC_PKT_LEN 128 //data length of each read, dont set this too big because ram is limited
#define PIC_FMT_VGA 7
#define PIC_FMT_CIF 5
#define PIC_FMT_OCIF 3
#define CAM_ADDR 0
#define PIC_FMT PIC_FMT_CIF
File myFile;
const byte cameraAddr = (CAM_ADDR << 5); // addr
const int buttonPin = A5; // the number of the pushbutton pin
unsigned long picTotalLen = 0; // picture length
int picNameNum = 0;
/*********************************************************************/
void setup()
{
M5.begin();
M5.Lcd.setBrightness(200);
Serial.begin(115200);
Serial2.begin(9600, SERIAL_8N1, 22, 21); //cant be faster than 9600, maybe difference with diff board.
initialize();
}
int n = 0;
/*********************************************************************/
void loop()
{
if(M5.BtnA.wasPressed()) {
if (n == 0) preCapture();
Capture();
GetData();
Serial.print("\r\nDone ,number : ");
Serial.println(n);
n++ ;
}
M5.update();
}
/*********************************************************************/
void clearRxBuf()
{
while (Serial2.available())
{
Serial2.read();
}
}
/*********************************************************************/
void sendCmd(char cmd[], int cmd_len)
{
for (char i = 0; i < cmd_len; i++) Serial2.write(cmd[i]);
}
/*********************************************************************/
int readBytes(char *dest, int len, unsigned int timeout)
{
int read_len = 0;
unsigned long t = millis();
while (read_len < len)
{
while (Serial2.available()<1)
{
if ((millis() - t) > timeout)
{
return read_len;
}
}
//
*(dest+read_len) = Serial2.read();
//Serial.write(*(dest+read_len));
read_len++;
}
return read_len;
}
/*********************************************************************/
void initialize()
{
char cmd[] = {0xaa,0x0d|cameraAddr,0x00,0x00,0x00,0x00} ;
unsigned char resp[6];
Serial.print("initializing camera...");
while (1)
{
sendCmd(cmd,6);
if (readBytes((char *)resp, 6,1000) != 6)
{
Serial.print(".");
continue;
}
if (resp[0] == 0xaa && resp[1] == (0x0e | cameraAddr) && resp[2] == 0x0d && resp[4] == 0 && resp[5] == 0)
{
if (readBytes((char *)resp, 6, 500) != 6) continue;
if (resp[0] == 0xaa && resp[1] == (0x0d | cameraAddr) && resp[2] == 0 && resp[3] == 0 && resp[4] == 0 && resp[5] == 0) break;
}
}
cmd[1] = 0x0e | cameraAddr;
cmd[2] = 0x0d;
sendCmd(cmd, 6);
Serial.println("\nCamera initialization done.");
}
/*********************************************************************/
void preCapture()
{
char cmd[] = { 0xaa, 0x01 | cameraAddr, 0x00, 0x07, 0x00, PIC_FMT };
unsigned char resp[6];
while (1)
{
clearRxBuf();
sendCmd(cmd, 6);
if (readBytes((char *)resp, 6, 100) != 6) continue;
if (resp[0] == 0xaa && resp[1] == (0x0e | cameraAddr) && resp[2] == 0x01 && resp[4] == 0 && resp[5] == 0) break;
}
}
void Capture()
{
char cmd[] = { 0xaa, 0x06 | cameraAddr, 0x08, PIC_PKT_LEN & 0xff, (PIC_PKT_LEN>>8) & 0xff ,0};
unsigned char resp[6];
while (1)
{
clearRxBuf();
sendCmd(cmd, 6);
if (readBytes((char *)resp, 6, 100) != 6) continue;
if (resp[0] == 0xaa && resp[1] == (0x0e | cameraAddr) && resp[2] == 0x06 && resp[4] == 0 && resp[5] == 0) break;
}
cmd[1] = 0x05 | cameraAddr;
cmd[2] = 0;
cmd[3] = 0;
cmd[4] = 0;
cmd[5] = 0;
while (1)
{
clearRxBuf();
sendCmd(cmd, 6);
if (readBytes((char *)resp, 6, 100) != 6) continue;
if (resp[0] == 0xaa && resp[1] == (0x0e | cameraAddr) && resp[2] == 0x05 && resp[4] == 0 && resp[5] == 0) break;
}
cmd[1] = 0x04 | cameraAddr;
cmd[2] = 0x1;
while (1)
{
clearRxBuf();
sendCmd(cmd, 6);
if (readBytes((char *)resp, 6, 100) != 6) continue;
if (resp[0] == 0xaa && resp[1] == (0x0e | cameraAddr) && resp[2] == 0x04 && resp[4] == 0 && resp[5] == 0)
{
if (readBytes((char *)resp, 6, 1000) != 6)
{
continue;
}
if (resp[0] == 0xaa && resp[1] == (0x0a | cameraAddr) && resp[2] == 0x01)
{
picTotalLen = (resp[3]) | (resp[4] << 8) | (resp[5] << 16);
Serial.print("picTotalLen:");
Serial.println(picTotalLen);
break;
}
}
}
}
/*********************************************************************/
char picName[] = "/pic00.jpg";
void GetData()
{
unsigned int pktCnt = (picTotalLen) / (PIC_PKT_LEN - 6);
if ((picTotalLen % (PIC_PKT_LEN-6)) != 0) pktCnt += 1;
char cmd[] = { 0xaa, 0x0e | cameraAddr, 0x00, 0x00, 0x00, 0x00 };
unsigned char pkt[PIC_PKT_LEN];
picName[4] = picNameNum/10 + '0';
picName[5] = picNameNum%10 + '0';
if (SD.exists(picName))
{
SD.remove(picName);
}
myFile = SD.open(picName, FILE_WRITE);
if(!myFile){
//Serial.println("myFile open fail...");
}
else{
for (unsigned int i = 0; i < pktCnt; i++)
{
cmd[4] = i & 0xff;
cmd[5] = (i >> 8) & 0xff;
int retry_cnt = 0;
retry:
delay(10);
clearRxBuf();
sendCmd(cmd, 6);
uint16_t cnt = readBytes((char *)pkt, PIC_PKT_LEN, 200);
unsigned char sum = 0;
for (int y = 0; y < cnt - 2; y++)
{
sum += pkt[y];
}
if (sum != pkt[cnt-2])
{
if (++retry_cnt < 100) goto retry;
else break;
}
myFile.write((const uint8_t *)&pkt[4], cnt-6);
//if (cnt != PIC_PKT_LEN) break;
}
cmd[4] = 0xf0;
cmd[5] = 0xf0;
sendCmd(cmd, 6);
}
myFile.close();
Serial.println(picName);
M5.Lcd.drawJpgFile(SD, picName);
picNameNum ++;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment