Serial Camera L2 Module take single image and save to microSD

Hi, i am trying to take a single picture using an L2 serial camera module and save it to microSD. But when the code goes to NewImageReady line it throws a System.InvalidOperationException.
This way i am trying to do the job:


void ProgramStarted()
        {
             

            Debug.Print("Program Started");         

            if (VolumeInfo.GetVolumes()[0].IsFormatted)
            {
                try
                {
                    
                   
                    serialCameraL2.ImageResolution = SerialCameraL2.Resolution.QQVGA;
                    serialCameraL2.StartStreaming();
                    if (serialCameraL2.NewImageReady)
                    {
                        var image = serialCameraL2.GetImage();
                        string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;
                        FileStream FileHandle = new FileStream(rootDirectory + @ "\picture.bmp", FileMode.Create);
                        byte[] data = image.GetBitmap();
                        FileHandle.Write(data, 0, data.Length);
                        FileHandle.Close();
                        Debug.Print("Picture stored on sd");
                        Debug.Print("Finalize volumes");
                        VolumeInfo[] vi = VolumeInfo.GetVolumes();
                        for (int i = 0; i < vi.Length; i++)
                            vi[i].FlushAll();
                    }
               
                }
                catch (Exception exp)
                {
                    Debug.Print(exp.Message.ToString());
                }
            }
            else
            {
                Debug.Print("Storage is not formatted. " + "Format on PC with FAT32/FAT16 first!");
            }

             }

What am i doing wrong?

ProgramStarted is for initialization. Take a look at this tutorial and start a timer. Inside the timer proc poll for the availability of an image.

https://www.ghielectronics.com/docs/176/serial-camera-module

1 Like

Hi, Architect! I changed my code to use a timer tick eventhandler, but now i have another problem… I have System.OutOfMemory exception:

A first chance exception of type ‘System.OutOfMemoryException’ occurred in Microsoft.SPOT.Graphics.dll
Exception performing Timer operation
Failed allocation for 3205 blocks, 38460 bytes

How to allocate bitmap properly? Help me please.

Here is my changed code:


 void ProgramStarted()
        {                     
            serialCameraL2.ImageResolution = SerialCameraL2.Resolution.QQVGA;
            serialCameraL2.StartStreaming();
            timer = new GT.Timer(100);
            timer.Tick += timer_Tick;
            timer.Start();
            Debug.Print("Program Started"); 
         }

 private void timer_Tick(GT.Timer timer)
        {
            if (serialCameraL2.NewImageReady)
            {
                byte[] data = new byte[serialCameraL2.GetImage().GetBitmap().Length];

                if (VolumeInfo.GetVolumes()[0].IsFormatted)
                {
                    try
                    {                        
                        string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;
                        FileStream FileHandle = new FileStream(rootDirectory + @ "\picture.bmp", FileMode.Create);
                        data = serialCameraL2.GetImage().GetBitmap();
                        FileHandle.Write(data, 0, data.Length);
                        FileHandle.Close();
                        Debug.Print("Picture stored on sd");
                        Debug.Print("Finalize volumes");
                        VolumeInfo[] vi = VolumeInfo.GetVolumes();
                        for (int i = 0; i < vi.Length; i++)
                            vi[i].FlushAll();


                    }
                    catch (Exception exp)
                    {
                        Debug.Print(exp.Message.ToString());
                    }
                }
                else
                {
                    Debug.Print("Storage is not formatted. " + "Format on PC with FAT32/FAT16 first!");
                }
                timer.Stop();
            }
        }

@ Alex Bilityuk - Don’t allocate new array just use the image data from the module

Look for method: GetImageData

1 Like

The difference is that you now create a byte array.
The maximum size of a byte array is 76kByte.
Bitmap uses a LargeBuffer instead of an array. By this it can allocate more data in one block.
See:
https://www.ghielectronics.com/docs/58/large-memory-objects-and-bitmaps

me thinking
this is the 3rd time this week I have posted this link :think:

That is ~760KB…

1 Like

You saved my time! Thank you!!! It works!!!

You are the best! You helped me! It works!

@ Alex Bilityuk - You are welcome.

yeah, same same :wink:

Need your help guys! I can’t use a serialCameraL2.StartStreaming() and wifi module thread simultaneosly, because it fails with error:

A first chance exception of type ‘System.InvalidOperationException’ occurred in GTM.GHIElectronics.SerialCameraL2.dll
The thread ‘’ (0x5) has exited with code 0 (0x0).

When i use startstreaming function without wifi thread, everything goes well. I have no idea what to do…

Here is my complete code:


 void ProgramStarted()
        {        
                   
            Debug.Print("Program Started");     
     
            Thread t = new Thread(new ThreadStart(() =>
            {
               StartCommunications();// Wifi thread
            }));

            t.Start();
            Debug.Print("Wify thread started");

            serialCameraL2.ImageResolution = SerialCameraL2.Resolution.QVGA;
     
            serialCameraL2.StartStreaming();     

            timer = new GT.Timer(100);
   
            timer.Tick += timer_Tick;
  
            timer.Start(); 

        }

   private void timer_Tick(GT.Timer timer)
        {
           
            if (serialCameraL2.NewImageReady) // I cant reach this code 
            {
                DisplayStatus(1, "Taking a picture");

                byte[] data = serialCameraL2.GetImageData();


                if (VolumeInfo.GetVolumes()[0].IsFormatted)
                {
                    try
                    {

                        string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;
                        FileStream FileHandle = new FileStream(rootDirectory + @ "\picture.bmp", FileMode.Create);
                        FileHandle.Write(data, 0, data.Length);
                        FileHandle.Close();
                        Debug.Print("Picture stored on sd");
                        Debug.Print("Finalize volumes");
                        VolumeInfo[] vi = VolumeInfo.GetVolumes();
                        for (int i = 0; i < vi.Length; i++)
                            vi[i].FlushAll();
                        DisplayStatus(1, "Picture saved on SD");

                    }
                    catch (Exception exp)
                    {
                        Debug.Print(exp.Message.ToString());
                    }
                }
                else
                {
                    Debug.Print("Storage is not formatted. " + "Format on PC with FAT32/FAT16 first!");
                }

            }
            timer.Stop();     
            
        }

What line of code throws the exception?

It strange but i cant see a line of code throwing exception. I see that exception in output window only. But it seems like the problem in serialCameraL2.StartStreaming();

What your StartCommunication function looks like?

Does it matter if you start WiFi thread after you start Camera timer?

I also tried to delete the wifi thread code from the programstarted function. And i can’t even reach the code inside if (serialCameraL2.NewImageReady) close.


void ProgramStarted()
        {        
                   
            Debug.Print("Program Started");     
   
            serialCameraL2.ImageResolution = SerialCameraL2.Resolution.QVGA;
     
            serialCameraL2.StartStreaming();     

            timer = new GT.Timer(100);
   
            timer.Tick += timer_Tick;
  
            timer.Start(); 

        }

   private void timer_Tick(GT.Timer timer)
        {
           
            if (serialCameraL2.NewImageReady) // I cant reach this code 
            {
                DisplayStatus(1, "Taking a picture");

                byte[] data = serialCameraL2.GetImageData();


                if (VolumeInfo.GetVolumes()[0].IsFormatted)
                {
                    try
                    {

                        string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;
                        FileStream FileHandle = new FileStream(rootDirectory + @ "\picture.bmp", FileMode.Create);
                        FileHandle.Write(data, 0, data.Length);
                        FileHandle.Close();
                        Debug.Print("Picture stored on sd");
                        Debug.Print("Finalize volumes");
                        VolumeInfo[] vi = VolumeInfo.GetVolumes();
                        for (int i = 0; i < vi.Length; i++)
                            vi[i].FlushAll();
                        DisplayStatus(1, "Picture saved on SD");

                    }
                    catch (Exception exp)
                    {
                        Debug.Print(exp.Message.ToString());
                    }
                }
                else
                {
                    Debug.Print("Storage is not formatted. " + "Format on PC with FAT32/FAT16 first!");
                }

            }
            timer.Stop();     
            
        }

It seems like NewImageReady not ready at all… Maybe something happened with a camera module?? because the same code without “wifi thread” worked yesterday. With wifi thread it shows an exception in output window:

Is that the code that don’t have issues while running? I thought you said the problem is there when WiFi is running.

If i not use a wifi thread it doesn’t show an exception, but i cant reach the code inside the timer . If i use a wifi thread it shows an exception and still cant reach the code inside of the timer… I have no idea what happened. Yesterday i tried the same code with no wifi thread and it reached the code inside the timer i even can see a picture stored on SD card… I have no idea what is going on…

Is that the exact same code or did you change something?

Yes it is.

Hmm running out of options here try a different socket maybe. Put a breakpoint at the line where you start the timer. Did it stop there?