Take picture from L2/Cerbuino bee

Hi all,

I would like to take a picture from my cerbuino bee with the L2 module. I know that the mainboard has not enough ram to display it on a screen but like explained on the L2 description it’s possible to upload a picture to a server or save it to the sd.

My code :

      void TakePicture()
        {
            serCam.StartStreaming();
            string fileName = Path.Combine(rootdir, "pic.jpg");
            while (true)
            {
                Thread.Sleep(100);
                if  (serCam.isNewImageReady)
                {
                    if (File.Exists(fileName))
                    {
                        File.Delete(fileName);
                    }
                    byte[] data = serCam.GetImageData();
                    File.WriteAllBytes(fileName, data);
                    serCam.StopStreaming();
                    break;
                }
            }
        }

rootdir contains the path pointing to the SD.

This code returns an OutOfMemoryException. Is there another way to do that ?

Thanks for your help !
André

Please check this thread. You have to get image in chunks, but there are might be some issues with the last chunk. There is supposed to be a better way of doing it soon (according to GHI)

https://www.ghielectronics.com/community/forum/topic?id=11161&page=1

The link for the example that thread is referring to:

https://www.ghielectronics.com/community/forum/topic?id=9506&page=1#msg94738

@ andre.m, @ Architect :

Yes that’s the problem but I don’t see how can I solve it because apparently these events are no longer available: StartDataCaptured , OnDataCaptured , FinishDataCaptured in the sercam driver.

Thanks for your assistance !

André

I have just recompiled the Sercam old driver and I’m able to take a picture and save it on my sd card. But the picture is not complete. It’s probably the fact that all bytes are not written because the FinishDataCaptured event is never triggered. There is no exception, my sd card is 1go formated in FAT. I already tried with a lower resolution, connect the DC power, same problem.

Anyone has an idea ?

My code :

        void ProgramStarted()
        {
            serCam.SetImageSize(GTM.GHIElectronics.SerCam.Camera_Resolution.SIZE_VGA);
            serCam.StartDataCaptured += new SerCam.StartDataCapturedEventHandler(serCam_StartDataCaptured);
            serCam.OnDataCaptured += new SerCam.DataCapturedEventHandler(DataCaptured);
            serCam.FinishDataCaptured += new SerCam.FinishDataCapturedEventHandler(serCam_FinishDataCaptured);

            GHI.OSHW.Hardware.StorageDev.MountSD();
            if (VolumeInfo.GetVolumes()[0].IsFormatted)
            {
                rootdir = VolumeInfo.GetVolumes()[0].RootDirectory;
                Thread.Sleep(5000);
            }
            fileName = Path.Combine(rootdir, "pic.jpg");

            Thread t = new Thread(new ThreadStart(() =>
            {
                if (!serCam.isBusy)
                {
                    serCam.TakePicture();
                }
            }));
        }

        private void serCam_FinishDataCaptured(SerCam sender)
        {
            Debug.Print("Finished !");
        }

        private void serCam_StartDataCaptured(SerCam sender, int sizeImage)
        {
            Debug.GC(true);
            if (File.Exists(fileName))
            {
                File.Delete(fileName);
            }
            index = 0;
        }

        private void DataCaptured(SerCam sender, byte[] data)
        {
            using (var imfile = new FileStream(fileName, FileMode.Append))
            {
                try
                {
                    imfile.Write(data, 0, data.Length);
                }
                catch (IOException ex)
                {
                        
                }
            }
            index += data.Length;
        }

@ andre.m : Yes @ Hoss seems to have the same issue. I already read this post, and maybe the only thing that I didn’t try is your recommandation to change the Gadgeteer.Serial with the one from Netmf. What do you think ?

Maybe I found something :

This code is a part of the old sercam driver that I used :

          // Read header
            ReadBytes(header, 0, 5);

            while (blocks > 0)
            {
                ReadBytes(data, 0, BLOCK_SIZE);
                OnDataCaptured(this, data);
                blocks--;

            }
            if (remaining > 0)
            {
                data = new byte[remaining];
                ReadBytes(data, 0, remaining);
                OnDataCaptured(this, data);
            }

            // read header
            ReadBytes(header, 5, 5);

            FinishDataCaptured(this);

“blocks” begin at ~417 and should go at 0 but when it crossed ~395, the code stop working, I mean it breaks the while loop and get out of this function without executing the code after.

I’m changing the serial with the one from netmf but I don’t see how can I do that ? because the serial from netmf accepts 0 argument and have no property (from System.IO.Ports) ???

Thanks for you code, I made the change just a question what should I set to the portName var ?

I have added some code in the sercam old driver espcially in the ReadFrameBuffer function and now I can take picture in QVGA format and save it on my sd card. There are sometimes a jerk line but it’s not too bad.

Now I have not enough time to change the serial but I will test it later and I hope make it working for VGA picture.

If somebody has a better solution I take it !

The ReadFrameBuffer function :

    private void ReadFrameBuffer(int size)
        {
            StartDataCaptured(this, size);
            CleanSerialPort();

            byte[] size4byte = new byte[4];
            byte[] header = new byte[10];
            int blocks = size / BLOCK_SIZE;
            int remaining = size % BLOCK_SIZE;
            size4byte[0] = (byte)(size >> 24);
            size4byte[1] = (byte)(size >> 16);
            size4byte[2] = (byte)(size >> 8);
            size4byte[3] = (byte)(size);

            byte[] data = new byte[BLOCK_SIZE];
            byte[] send = new byte[] { 0x56, 0x00, 0x32, 0x0C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, size4byte[0], size4byte[1], size4byte[2], size4byte[3], 0x0B, 0xB8 };
            serialPort.Write(send, 0, send.Length);

            Thread.Sleep(30);
            // Read header
            ReadBytes(header, 0, 5);
            Debug.GC(true); 
            while (blocks > 0)
            {
                try
                {
                    ReadBytes(data, 0, BLOCK_SIZE);
                    OnDataCaptured(this, data);
                    blocks--;
                    if (blocks % 3 == 0)
                    {
                        Debug.GC(true);
                    }
                }
                catch { }
            } 
            if (remaining > 0)
            {
                data = new byte[remaining];
                ReadBytes(data, 0, remaining);
                OnDataCaptured(this, data);
            }

            // read header
            ReadBytes(header, 5, 5);

            FinishDataCaptured(this);
        } 

Thanks for your help !

Ping. Has this problem been solved in the driver, so I can go ahead and play with my Cerbuino Bee for a little side-project?