Hi there,
I'm trying to capture an image (jpg) with an Arducam Mini 5MP OV5640, my Arduino pro Mini 16 MHz and an ENC28J60 Ethernet-Adapter. The arduino should trigger the capturee when a special UDP-Message arrives. That works. After capture, I'd like to transfer the captured image to a server running a very simple python script to save incoming UDP-data.
However, capturing seems to work fine but there are several things I don't get really into:
- If I output the FIFO-data it is only Int-values due to the fact that I read the FIFO-Data as uint8_t. I'd expect a jpeg is a sequence of bytes. But the SPI-library does not offer the possibility to read bytes from FIFO. Do I need to convert the Int-values into bytes?
- When I print out the Int-values with Serial.println I get, as mentioned above, a sequence of Int-Values in the Serial-Monitor. On the Output of the python-server however I only get "crap", like also a "B" and things like that. What is going on there?
Actually it is not only about these questions, it's more how to get the program running as expected. Any help is highly appreciated. Thanks in advance!
Here is my code:
#include <Wire.h>
#include <ArduCAM.h>
#include <SPI.h>
#include "memorysaver.h"
#include <EtherCard.h>
#include <IPAddress.h>
//This demo can only work on OV5640_MINI_5MP_Plus platform.
#if !(defined OV5640_MINI_5MP_PLUS )
#error Please select the hardware platform and camera module in the ../libraries/ArduCAM/memorysaver.h file
#endif
#define BMPIMAGEOFFSET 66
#define REQUEST_RATE 5000
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
static byte hostip[] = { 192,168,178,21 };
const int dstPort PROGMEM = 1337;
const int srcPort PROGMEM = 4321;
// remote website name
const char website[] PROGMEM = "google.com";
uint8_t temp, temp_last;
bool is_header = false;
byte Ethernet::buffer[700];
static long timer;
static void my_result_cb (byte status, word off, word len) {
Serial.print("<<< reply ");
Serial.print(millis() - timer);
Serial.println(" ms");
Serial.println((const char*) Ethernet::buffer + off);
}
// set pin 7 as the slave select for the digital pot:
const int CS = 7;
ArduCAM myCAM( OV5640, CS );
//uint8_t read_fifo_burst(ArduCAM myCAM);
void serverCapture(){
byte buf[256];
static int i = 0;
uint8_t temp = 0,temp_last=0;
uint32_t length = 0;
bool is_header = false;
//Flush the FIFO
myCAM.flush_fifo();
//Clear the capture done flag
myCAM.clear_fifo_flag();
//Start capture
myCAM.start_capture();
Serial.println(F("start Capture"));
while(!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK)) ;
Serial.println(F("Capture Done."));
length = myCAM.read_fifo_length();
Serial.print(F("The fifo length is :"));
Serial.println(length, DEC);
if (length >= MAX_FIFO_SIZE) //384K
{
Serial.println(F("Over size."));
return;
}
if (length == 0 ) //0 kb
{
Serial.println(F("Size is 0."));
return;
}
myCAM.CS_LOW();
myCAM.set_fifo_burst();
while ( length-- )
{
temp_last = temp;
temp = SPI.transfer(0x00);
Serial.println(temp);
//Read JPEG data from FIFO
if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
{
buf[i++] = temp; //save the last 0XD9
//Write the remain bytes in the buffer
myCAM.CS_HIGH();
ether.sendUdp(buf, i, srcPort, hostip, dstPort);
Serial.println(F("Image save OK."));
is_header = false;
i = 0;
}
if (is_header == true)
{
//Write image data to buffer if not full
if (i < 256)
buf[i++] = temp;
else
{
//Write 256 bytes image data to file
myCAM.CS_HIGH();
ether.sendUdp(buf, 256, srcPort, hostip, dstPort);
i = 0;
buf[i++] = temp;
myCAM.CS_LOW();
myCAM.set_fifo_burst();
}
}
else if ((temp == 0xD8) & (temp_last == 0xFF))
{
is_header = true;
buf[i++] = temp_last;
buf[i++] = temp;
}
}
}
void udpSerialPrint(uint16_t dest_port, uint8_t src_ip[IP_LEN], uint16_t src_port, const char *data, uint16_t len){
IPAddress src(src_ip[0],src_ip[1],src_ip[2],src_ip[3]);
Serial.print("dest_port: ");
Serial.println(dest_port);
Serial.print("src_port: ");
Serial.println(src_port);
Serial.print("src_port: ");
ether.printIp(src_ip);
Serial.println("data: ");
Serial.println(data);
serverCapture();
}
void setup() {
uint8_t vid, pid;
uint8_t temp;
#if defined(__SAM3X8E__)
Wire1.begin();
Serial.begin(115200);
#else
Wire.begin();
Serial.begin(115200);
#endif
Serial.println(F("ACK CMD ArduCAM Start!"));
// set the CS as an output:
pinMode(CS, OUTPUT);
// initialize SPI:
SPI.begin();
while(1) {
//Check if the ArduCAM SPI bus is OK
myCAM.write_reg(ARDUCHIP_TEST1, 0x55);
temp = myCAM.read_reg(ARDUCHIP_TEST1);
if (temp != 0x55) {
Serial.println(F("ACK CMD SPI interface Error!"));
delay(1000); continue;
}else{
Serial.println(F("ACK CMD SPI interface OK.")); break;
}
}
while(1) {
//Check if the camera module type is OV5642
myCAM.wrSensorReg16_8(0xff, 0x01);
myCAM.rdSensorReg16_8(OV5640_CHIPID_HIGH, &vid);
myCAM.rdSensorReg16_8(OV5640_CHIPID_LOW, &pid);
if((vid != 0x56) || (pid != 0x40)) {
Serial.println(F("ACK CMD Can't find OV5640 module!"));
delay(1000); continue;
}
else{
Serial.println(F("ACK CMD OV5640 detected.")); break;
}
}
//Change to JPEG capture mode and initialize the OV5642 module
myCAM.set_format(JPEG);
myCAM.InitCAM();
myCAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK); //VSYNC is active HIGH
myCAM.OV5640_set_JPEG_size(OV5640_320x240);
delay(1000);
myCAM.clear_fifo_flag();
myCAM.write_reg(ARDUCHIP_FRAMES,0x00);
Serial.println("\n[getDHCPandDNS]");
if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
Serial.println( "Failed to access Ethernet controller");
if (!ether.dhcpSetup())
Serial.println("DHCP failed");
ether.printIp("My IP: ", ether.myip);
// ether.printIp("Netmask: ", ether.mymask);
ether.printIp("GW IP: ", ether.gwip);
ether.printIp("DNS IP: ", ether.dnsip);
if (!ether.dnsLookup(website))
Serial.println("DNS failed");
ether.printIp("Server: ", ether.hisip);
timer = -REQUEST_RATE; // start timing out right away
ether.udpServerListenOnPort(&udpSerialPrint, 1337);
//register udpSerialPrint() to port 42.
ether.udpServerListenOnPort(&udpSerialPrint, 42);
}
void loop() {
uint8_t temp = 0xff, temp_last = 0;
ether.packetLoop(ether.packetReceive());
}
And the python server-script:
# ----- receiver.py -----
#!/usr/bin/env python
from socket import *
import sys
import select
host="192.168.178.21"
port = 1337
s = socket(AF_INET,SOCK_DGRAM)
s.bind((host,port))
addr = (host,port)
buf=1024
data,addr = s.recvfrom(buf)
print "Received File:"
f = open("out.jpg",'wb')
data, addr = s.recvfrom(buf)
try:
while(data):
f.write(data)
s.settimeout(5)
data,addr = s.recvfrom(buf)
except timeout:
f.close()
s.close()
print "File Downloaded"