Advertisement
Guest User

CameraController.cs

a guest
Jan 2nd, 2013
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using Microsoft.SPOT;
  3. using System.IO.Ports;
  4. using System.Text;
  5. using System.Threading;
  6. using System.Collections;
  7.  
  8. namespace CameraController
  9. {
  10.     public class LinkspriteCamera : IDisposable
  11.     {
  12.         public LinkspriteCamera(SerialPort port)
  13.         {
  14.             this.port = port;
  15.  
  16.             port.ReadTimeout = 250; //so read call doesn't block forever
  17.             port.Open();
  18.         }
  19.  
  20.         public LinkspriteCamera(String serialPortName, int baudRate)
  21.         {
  22.             SerialPort aPort = new SerialPort(serialPortName, baudRate, Parity.None, 8, StopBits.One);
  23.             this.port = aPort;
  24.  
  25.             this.port.ReadTimeout = 250; //so read call doesn't block forever
  26.             this.port.Open();
  27.         }
  28.  
  29.         public static string HexStr(byte[] data)
  30.         {
  31.             char[] lookup = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
  32.  
  33.             StringBuilder sb = new StringBuilder(data.Length * 6 + 2);
  34.             sb.Append("{");
  35.             for (int buc = 0; buc < data.Length - 1; buc++)
  36.             {
  37.                 sb.Append("0x");
  38.                 sb.Append(lookup[(data[buc] >> 4) & 0x0F]);
  39.                 sb.Append(lookup[data[buc] & 0x0F]);
  40.                 sb.Append(", ");
  41.             }
  42.  
  43.             sb.Append("0x");
  44.             sb.Append(lookup[(data[data.Length - 1] >> 4) & 0x0F]);
  45.             sb.Append(lookup[data[data.Length - 1] & 0x0F]);
  46.             sb.Append("}");
  47.             return sb.ToString();
  48.         }
  49.  
  50.         public bool Reset()
  51.         {
  52.             Debug.Print("Send reset");
  53.             bool sendAndLookFor = SendAndLookFor(RESET_COMMAND, RESET_OK_RESPONSE);
  54.  
  55.             //camera needs time after reset
  56.             if (sendAndLookFor)
  57.             {
  58.                 ReadAllRemaining();
  59.                 Thread.Sleep(3000);
  60.             }
  61.  
  62.             return sendAndLookFor;
  63.         }
  64.  
  65.         public bool ChangeBaudRateTo115200()
  66.         {
  67.             byte[] bauderateBytes = BAUDRATE_COMMAND_115200;
  68.             String portName = this.port.PortName;
  69.             bool sendAndLookFor = SendAndLookFor(bauderateBytes, BAUDRATE_OK_RESPONSE);
  70.             if (sendAndLookFor)
  71.                 ReadAllRemaining();
  72.             this.port.Close();
  73.             SerialPort aPort = new SerialPort(portName, 115200, Parity.None, 8, StopBits.One);
  74.             this.port = aPort;
  75.             this.port.Open();
  76.             return sendAndLookFor;
  77.         }
  78.  
  79.         public bool SetPictureSize(byte[] sizeBytes)
  80.         {
  81.             bool sendAndLookFor = SendAndLookFor(sizeBytes, SET_SIZE_OK_RESPONSE);
  82.            if (sendAndLookFor)
  83.                 ReadAllRemaining();
  84.  
  85.             return sendAndLookFor;
  86.         }
  87.  
  88.         public bool Stop()
  89.         {
  90.             ReadAllRemaining();
  91.             return SendAndLookFor(STOP_COMMAND, STOP_OK_RESPONSE);
  92.         }
  93.  
  94.         public delegate void ActionBytes(byte[] chunk);
  95.         public delegate void Complete();
  96.  
  97.         const int IN_BUFFER_SIZE = 512;
  98.         byte[] InBuffer = new byte[IN_BUFFER_SIZE];
  99.  
  100.         public void GetPicture(ActionBytes bytesAction)
  101.         {
  102.             Debug.Print("Send snap");
  103.             Send(SNAP_COMMAND);
  104.             if (LookFor(SNAP_OK_RESPONSE))
  105.             {
  106.                 Debug.Print("Send size");
  107.                 Thread.Sleep(3000);
  108.                 Send(SIZE_COMMAND);
  109.                 if (LookFor(SIZE_OK_RESPONSE))
  110.                 {
  111.                     //MSB, LSB
  112.                     var sizeBytesLength = Read(2);
  113.                     int fileSize = (InBuffer[0] << 8) | InBuffer[1];
  114.                     Debug.Print("Image size is : " + fileSize);
  115.                     int startAddress = 0;
  116.                     int bytesRead = 0;
  117.  
  118.                     GET_CHUNK_COMMAND[12] = MSB(IN_BUFFER_SIZE);
  119.                     GET_CHUNK_COMMAND[13] = LSB(IN_BUFFER_SIZE);
  120.  
  121.                     bool endReached = false;
  122.                     while (!endReached)
  123.                     {
  124.                         GET_CHUNK_COMMAND[8] = MSB(startAddress);
  125.                         GET_CHUNK_COMMAND[9] = LSB(startAddress);
  126.  
  127.                         Send(GET_CHUNK_COMMAND);
  128.                         if (LookFor(GET_CHUNK_OK_RESPONSE))
  129.                         {
  130.                             int chunkLength = 0;
  131.                             do
  132.                             {
  133.                                 chunkLength = Read();
  134.  
  135.                                 //ditch footer
  136.                                 Read(junkBuffer, GET_CHUNK_OK_RESPONSE.Length);
  137.  
  138.                                 //publish byte data
  139.                                 if (chunkLength > 0)
  140.                                 {
  141.                                     bytesRead += chunkLength;
  142.                                     if (bytesRead >= fileSize)
  143.                                     {
  144.                                         endReached = true;
  145.  
  146.                                         chunkLength = FindEnd(chunkLength);
  147.                                     }
  148.  
  149.                                     bytesAction(NewArray(chunkLength));
  150.                                 }
  151.  
  152.                                 startAddress += chunkLength;
  153.  
  154.                             } while (!endReached && chunkLength > 0);
  155.                         }
  156.                     }
  157.                 }
  158.             }
  159.         }
  160.  
  161.         private byte[] NewArray(int chunkLength)
  162.         {
  163.             //make new array for bytes event so receiver can consume
  164.             //in sep thread without it changing during processing
  165.             var chunk = new byte[chunkLength];
  166.             Array.Copy(InBuffer, chunk, chunkLength);
  167.             return chunk;
  168.         }
  169.  
  170.         private int FindEnd(int chunkLength)
  171.         {
  172.             if (chunkLength >= 2)
  173.             {
  174.                 bool foundEnd = false;
  175.  
  176.                 for (int i = chunkLength - 1; i >= 2; i--)
  177.                 {
  178.                     if (InBuffer[i - 1] == 0xFF &&
  179.                         InBuffer[i - 0] == 0xD9
  180.                     )
  181.                     {
  182.                         chunkLength = i + 1; //include end marker in output
  183.                         foundEnd = true;
  184.                         break;
  185.                     }
  186.                 }
  187.  
  188.                 if (!foundEnd)
  189.                     Debug.Print("Invalid JPG data");
  190.             }
  191.             return chunkLength;
  192.         }
  193.  
  194.         private static byte LSB(int num)
  195.         {
  196.             return (byte)(num & 0xFF);
  197.         }
  198.  
  199.         private static byte MSB(int num)
  200.         {
  201.             return (byte)(num >> 8);
  202.         }
  203.  
  204.         private bool SendAndLookFor(byte[] command, byte[] lookFor)
  205.         {
  206.             Send(command);
  207.             return LookFor(lookFor);
  208.         }
  209.  
  210.         byte[] junkBuffer = new byte[IN_BUFFER_SIZE];
  211.         private void ReadAllRemaining()
  212.         {
  213.             int toRead = port.BytesToRead;
  214.             while (toRead > 0)
  215.             {
  216.                 port.Read(junkBuffer, 0, toRead);
  217.                 Debug.Print("Junk " + toRead + " " + HexStr(junkBuffer));
  218.                 //junkBuffer = null;
  219.                 //junkBuffer = new byte[IN_BUFFER_SIZE];
  220.                 toRead = port.BytesToRead;
  221.             }
  222.         }
  223.  
  224.         private bool LookFor(byte[] expectedResponse)
  225.         {
  226.             var inSize = Read(expectedResponse.Length);
  227.             if (AreEqual(expectedResponse, inSize))
  228.                 return true;
  229.  
  230.             return false;
  231.         }
  232.  
  233.         private int Read()
  234.         {
  235.             return Read(IN_BUFFER_SIZE);
  236.         }
  237.  
  238.         private int Read(int bytes)
  239.         {
  240.             return Read(InBuffer, bytes);
  241.         }
  242.  
  243.         private int Read(byte[] buffer, int bytes)
  244.         {
  245.             //Thread.Sleep(100);
  246.             Debug.Print("About to read");
  247.             int returnValue = port.Read(buffer, 0, bytes);
  248.             Debug.Print("Read " + returnValue + " " + HexStr(buffer));
  249.             return returnValue;
  250.         }
  251.  
  252.         private void Send(byte[] command)
  253.         {
  254.             port.Write(command, 0, command.Length);
  255.             Debug.Print("Sent : " + command.Length + " " + HexStr(command));
  256.         }
  257.  
  258.         static readonly byte[] RESET_OK_RESPONSE = new byte[] { 0x76, 0x00, 0x26, 0x00 };
  259.         static readonly byte[] RESET_COMMAND = new byte[] { 0x56, 0x00, 0x26, 0x00 };
  260.  
  261.         static readonly byte[] STOP_OK_RESPONSE = new byte[] { 0x76, 0x00, 0x36, 0x00, 0x00 };
  262.         static readonly byte[] STOP_COMMAND = new byte[] { 0x56, 0x00, 0x36, 0x01, 0x03 };
  263.  
  264.         static readonly byte[] SNAP_OK_RESPONSE = new byte[] { 0x76, 0x00, 0x36, 0x00, 0x00 };
  265.         static readonly byte[] SNAP_COMMAND = new byte[] { 0x56, 0x00, 0x36, 0x01, 0x00 };
  266.  
  267.         static readonly byte[] SIZE_OK_RESPONSE = new byte[] { 0x76, 0x00, 0x34, 0x00, 0x04, 0x00, 0x00 };
  268.         static readonly byte[] SIZE_COMMAND = new byte[] { 0x56, 0x00, 0x34, 0x01, 0x00 };
  269.  
  270.         static readonly byte[] GET_CHUNK_OK_RESPONSE = new byte[] { 0x76, 0x00, 0x32, 0x00, 0x00 };
  271.         static readonly byte[] GET_CHUNK_COMMAND = new byte[] { 0x56, 0x00, 0x32, 0x0C, 0x00, 0x0A, 0x00, 0x00, 255, 255, 0x00, 0x00, 255, 255, 0x00, 0x0A };
  272.  
  273.         public static readonly byte[] SET_SIZE_160x120 = new byte[] { 0x56, 0x00, 0x31, 0x05, 0x04, 0x01, 0x00, 0x19, 0x22 };
  274.         public static readonly byte[] SET_SIZE_320x240 = new byte[] { 0x56, 0x00, 0x31, 0x05, 0x04, 0x01, 0x00, 0x19, 0x11 };
  275.         public static readonly byte[] SET_SIZE_640x480 = new byte[] { 0x56, 0x00, 0x31, 0x05, 0x04, 0x01, 0x00, 0x19, 0x00 };
  276.         public static readonly byte[] SET_SIZE_OK_RESPONSE = new byte[] { 0x76, 0, 0x31, 0 };
  277.  
  278.         public static readonly byte[] BAUDRATE_OK_RESPONSE = new byte[] { 0x76, 0x00, 0x24, 0x00, 0x00 };
  279.         public static readonly byte[] BAUDRATE_COMMAND_115200 = new byte[] { 0x56, 0x00, 0x24, 0x03, 0x01, 0x0D, 0xA6 };
  280.  
  281.         SerialPort port;
  282.  
  283.         private bool AreEqual(byte[] left, int inSize)
  284.         {
  285.             if (left == null || left.Length != inSize)
  286.                 return false;
  287.  
  288.             for (int i = 0; i < left.Length; i++)
  289.                 if (left[i] != InBuffer[i])
  290.                     return false;
  291.  
  292.             return true;
  293.         }
  294.  
  295.         #region IDisposable Members
  296.  
  297.         public void Dispose()
  298.         {
  299.             if (port != null)
  300.                 port.Dispose();
  301.         }
  302.  
  303.         #endregion
  304.     }
  305. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement