This should go on FEZZer, for points and will help others see it, please.
Please “code tag” your code so it is redable…here is your code but with tags this time
public static void Main()
{
Debug.EnableGCMessages(false);
using (var camera = new LinkspriteCamera(new SerialPort("COM1", 38400, Parity.None, 8, StopBits.One)))
{
if(camera.Reset())
camera.GetPicture(ProcessChunk);
camera.Stop();
}
}
private static void ProcessChunk(byte[] bytes)
{
foreach (var byter in bytes)
Debug.Print(byter.ToString());
}
This just returns the bytes over the debug cable, you can do something with the bytes if you have an SD card or are going to transmit, otherwise just copy the bytes to the clippboard from the output window and use the below snippet to create the jpg file and look at it on your computer:
var byteString = @ "<put bytes here>";
var lines = byteString.Split(Environment.NewLine.ToCharArray());
var bytes = new List<byte>();
foreach (var line in lines.Where(x => (x ?? "").Trim() != ""))
{
byte num = Convert.ToByte(line);
bytes.Add(num);
}
string file = @ "C:\temp.jpg";
File.WriteAllBytes(file, bytes.ToArray());
System.Diagnostics.Process.Start(file);
using System;
using Microsoft.SPOT;
using System.IO.Ports;
using System.Text;
using System.Threading;
using System.Collections;
namespace CameraController
{
public class LinkspriteCamera : IDisposable
{
public LinkspriteCamera(SerialPort port)
{
this.port = port;
port.ReadTimeout = 250; //so read call doesn't block forever
port.Open();
}
public bool Reset()
{
bool sendAndLookFor = SendAndLookFor(RESET_COMMAND, RESET_OK_RESPONSE);
//camera needs time after reset
if (sendAndLookFor)
{
ReadAllRemaining();
Thread.Sleep(3000);
}
return sendAndLookFor;
}
public bool SetPictureSize(byte[] sizeBytes)
{
bool sendAndLookFor = SendAndLookFor(sizeBytes, SET_SIZE_OK_RESPONSE);
if(sendAndLookFor)
ReadAllRemaining();
return sendAndLookFor;
}
public bool Stop()
{
ReadAllRemaining();
return SendAndLookFor(STOP_COMMAND, STOP_OK_RESPONSE);
}
public delegate void ActionBytes(byte[] chunk);
public delegate void Complete();
const int IN_BUFFER_SIZE = 512;
byte[] InBuffer = new byte[IN_BUFFER_SIZE];
public void GetPicture(ActionBytes bytesAction)
{
Send(SNAP_COMMAND);
if (LookFor(SNAP_OK_RESPONSE))
{
Send(SIZE_COMMAND);
if (LookFor(SIZE_OK_RESPONSE))
{
//MSB, LSB
var sizeBytesLength = Read(2);
int fileSize = (InBuffer[0] << 8) | InBuffer[1];
int startAddress = 0;
int bytesRead = 0;
GET_CHUNK_COMMAND[12] = MSB(IN_BUFFER_SIZE);
GET_CHUNK_COMMAND[13] = LSB(IN_BUFFER_SIZE);
bool endReached = false;
while (!endReached)
{
GET_CHUNK_COMMAND[8] = MSB(startAddress);
GET_CHUNK_COMMAND[9] = LSB(startAddress);
Send(GET_CHUNK_COMMAND);
if (LookFor(GET_CHUNK_OK_RESPONSE))
{
int chunkLength = 0;
do
{
chunkLength = Read();
//ditch footer
Read(junkBuffer, GET_CHUNK_OK_RESPONSE.Length);
//publish byte data
if (chunkLength > 0)
{
bytesRead += chunkLength;
if (bytesRead >= fileSize)
{
endReached = true;
chunkLength = FindEnd(chunkLength);
}
bytesAction(NewArray(chunkLength));
}
startAddress += chunkLength;
} while (!endReached && chunkLength > 0);
}
}
}
}
}
private byte[] NewArray(int chunkLength)
{
//make new array for bytes event so receiver can consume
//in sep thread without it changing during processing
var chunk = new byte[chunkLength];
Array.Copy(InBuffer, chunk, chunkLength);
return chunk;
}
private int FindEnd(int chunkLength)
{
if (chunkLength >= 2)
{
bool foundEnd = false;
for (int i = chunkLength - 1; i >= 2; i--)
{
if (InBuffer[i - 1] == 0xFF &&
InBuffer[i - 0] == 0xD9
)
{
chunkLength = i + 1; //include end marker in output
foundEnd = true;
break;
}
}
if (!foundEnd)
Debug.Print("Invalid JPG data");
}
return chunkLength;
}
private static byte LSB(int num)
{
return (byte)(num & 0xFF);
}
private static byte MSB(int num)
{
return (byte)(num >> 8);
}
private bool SendAndLookFor(byte[] command, byte[] lookFor)
{
Send(command);
return LookFor(lookFor);
}
byte[] junkBuffer = new byte[IN_BUFFER_SIZE];
private void ReadAllRemaining()
{
int readCount = 0;
do
{
readCount = Read(junkBuffer, IN_BUFFER_SIZE);
} while (readCount != 0);
}
private bool LookFor(byte[] expectedResponse)
{
var inSize = Read(expectedResponse.Length);
if (AreEqual(expectedResponse, inSize))
return true;
return false;
}
private int Read()
{
return Read(IN_BUFFER_SIZE);
}
private int Read(int bytes)
{
return Read(InBuffer, bytes);
}
private int Read(byte[] buffer, int bytes)
{
return port.Read(buffer, 0, bytes);
}
private void Send(byte[] command)
{
port.Write(command, 0, command.Length);
}
static readonly byte[] RESET_OK_RESPONSE = new byte[] { 0x76, 0x00, 0x26, 0x00 };
static readonly byte[] RESET_COMMAND = new byte[] { 0x56, 0x00, 0x26, 0x00 };
static readonly byte[] STOP_OK_RESPONSE = new byte[] { 0x76, 0x00, 0x36, 0x00, 0x00 };
static readonly byte[] STOP_COMMAND = new byte[] { 0x56, 0x00, 0x36, 0x01, 0x03 };
static readonly byte[] SNAP_OK_RESPONSE = new byte[] { 0x76, 0x00, 0x36, 0x00, 0x00 };
static readonly byte[] SNAP_COMMAND = new byte[] { 0x56, 0x00, 0x36, 0x01, 0x00 };
static readonly byte[] SIZE_OK_RESPONSE = new byte[] { 0x76, 0x00, 0x34, 0x00, 0x04, 0x00, 0x00 };
static readonly byte[] SIZE_COMMAND = new byte[] { 0x56, 0x00, 0x34, 0x01, 0x00 };
static readonly byte[] GET_CHUNK_OK_RESPONSE = new byte[] { 0x76, 0x00, 0x32, 0x00, 0x00 };
static readonly byte[] GET_CHUNK_COMMAND = new byte[] { 0x56, 0x00, 0x32, 0x0C, 0x00, 0x0A, 0x00, 0x00, 255, 255, 0x00, 0x00, 255, 255, 0x00, 0x0A };
public static readonly byte[] SET_SIZE_160x120 = new byte[] { 0x56, 0x00, 0x31, 0x05, 0x04, 0x01, 0x00, 0x19, 0x22 };
public static readonly byte[] SET_SIZE_320x240 = new byte[] { 0x56, 0x00, 0x31, 0x05, 0x04, 0x01, 0x00, 0x19, 0x11 };
public static readonly byte[] SET_SIZE_640x480 = new byte[] { 0x56, 0x00, 0x31, 0x05, 0x04, 0x01, 0x00, 0x19, 0x00 };
public static readonly byte[] SET_SIZE_OK_RESPONSE = new byte[] { 0x76, 0, 0x31, 0 };
SerialPort port;
private bool AreEqual(byte[] left, int inSize)
{
if (left == null || left.Length != inSize)
return false;
for (int i = 0; i < left.Length; i++)
if (left[i] != InBuffer[i])
return false;
return true;
}
#region IDisposable Members
public void Dispose()
{
if (port != null)
port.Dispose();
}
#endregion
}
}