Serial camera on Cobra II (wifi)

I have Cobra II (wifi) and serial camera L2. I tried example from Dat in his post at http://www.tinyclr.com/forum/topic?id=9506&page=1#msg94738.
Everything works very well, but when I turn on wifi, video streaming hangs.

Not enough memory?


using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;
 
using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;
 
namespace TestSerCam4._2
{
    public partial class Program
    {
        // This method is run when the mainboard is powered up or reset. 
        byte[] datajpg;
        int index = 0;
        void ProgramStarted()
        {
            /*******************************************************************************************
            Modules added in the Program.gadgeteer designer view are used by typing 
            their name followed by a period, e.g.  button.  or  camera.
 
            Many modules generate useful events. Type +=<tab><tab> to add a handler to an event, e.g.:
                button.ButtonPressed +=<tab><tab>
 
            If you want to do something periodically, use a GT.Timer and handle its Tick event, e.g.:
                GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
                timer.Tick +=<tab><tab>
                timer.Start();
            *******************************************************************************************/
 
 
            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");
            serCam.StartDataCaptured += new SerCam.StartDataCapturedEventHandler(serCam_StartDataCaptured);
            serCam.OnDataCaptured += new SerCam.DataCapturedEventHandler(serCam_OnDataCaptured);
            serCam.FinishDataCaptured += new SerCam.FinishDataCapturedEventHandler(serCam_FinishDataCaptured);
            new Thread(VideoStreamming).Start();
        }
        void VideoStreamming()
        {
            while (true)
            {
                if (!serCam.isBusy)
                {
                    serCam.TakePicture();
                }
                else Thread.Sleep(50);
            }
        }
        void serCam_FinishDataCaptured(SerCam sender)
        {
            display_T35.SimpleGraphics.DisplayImage(new Bitmap(datajpg, Bitmap.BitmapImageType.Jpeg), 0, 0);
        }
 
        void serCam_OnDataCaptured(SerCam sender, byte[] data)
        {
            if (index + data.Length > datajpg.Length)
            {
                throw new Exception("Error");
            }
            Array.Copy(data, 0, datajpg, index, data.Length);
            index += data.Length;
        }
 
        void serCam_StartDataCaptured(SerCam sender, int sizeImage)
        {
            index = 0;
            datajpg = new byte[sizeImage];
        }
    }
}

wifi code:


        static WiFiRS9110 WifiInterface = new WiFiRS9110(SPI.SPI_module.SPI2, G120.Pin.P1_10, G120.Pin.P2_11, G120.Pin.P1_9);

        void StartWifi()
        {            
            if (!WifiInterface.IsOpen)
                WifiInterface.Open();

            //Enable DHCP
            if (!WifiInterface.NetworkInterface.IsDhcpEnabled)
                WifiInterface.NetworkInterface.EnableDhcp();

            //Assign the TCP/IP stack
            NetworkInterfaceExtension.AssignNetworkingStackTo(WifiInterface);
 
            //Setup our events
            WifiInterface.NetworkAddressChanged += new NetworkInterfaceExtension.NetworkAddressChangedEventHandler(GHI_Wifi_NetworkAddressChanged);
            WifiInterface.WirelessConnectivityChanged += new WiFiRS9110.WirelessConnectivityChangedEventHandler(GHI_Wifi_WirelessConnectivityChanged);
 
           //Scan for networks
            WiFiNetworkInfo[] wifiInfo = WifiInterface.Scan();
 
            bool found = false;
 
            for (int i = 0; i < wifiInfo.Length; i++)
            {
                if (wifiInfo[i].SSID == "ap")
                {
                    found = true;
                    WifiInterface.Join(wifiInfo[i], "");
                    Debug.Print(wifiInfo[i].RSSI.ToString());
                    break;
                }
            }
 
            if (!found)
                Debug.Print("could not find network");
 
            while (true)
            {
 
                IPAddress ip = IPAddress.GetDefaultLocalAddress();
 
                if (ip != IPAddress.Any) break;
 
                Thread.Sleep(1000);
            }
        }

Are you sure you getting an IP and not stuck inside the indefinite loop inside StartWifi?

There might also be a race condition.

There is a thread looking at the camera, waiting for it to be not busy. It then starts the next picture.

When the picture is ready, the serCam_FinishDataCaptured event is call, where the
picture is displayed.

What might be happening, is the camera is set not busy before the event is called,
and the thread that is looking for an idle camera starts another picture while
the event thread is preparing the image for display.

This might be a problem.

How about starting the next picture from the event handler, after the prior picture is displayed?

Interesting idea. Still doesn’t explain why it is not working with Wifi (but does without it), although timing can be different and he was just lucky to avoid the race condition in first case.

Yes i sure, because i can ping to device.

Yep, you got it! :slight_smile:

Possible the datajpg reference is changed before the event handler is called, and then the handler is trying to display an incorrect jpg buffer.

Is it possible to avoid this situation?

Yes, you can use an Event (autoreset or manual synchronization primitive) in the Picture Taken handler. And check if that event is set in your streaming loop instead of checking Boolean property of the camera object.

Well I’m not sure if this will help any of you smart people to figure this out. But I can add the following information to this…

I have basically copied the SerCam code from this thread, and it works fine. I define “fine” as the program continues to take pictures. Or in other words the serCam_FinishDataCaptured is fired. I don’t have a display hooked up to my G120 so I don’t try to “display” anything at this point.



        public static void Main()
        {

            MainBoard = new GHIElectronics.Gadgeteer.FEZCobra_II();

            // WifiSetup();  <-- Notice this is commented out.
            cameratest();

            


            while (true)
            {
            } // Main Control Loop

        } // End Main



        private static void cameratest()
        {
            sercam = new SerCam(5);
            sercam.DebugPrintEnabled = true;
            sercam.StartDataCaptured += new SerCam.StartDataCapturedEventHandler(serCam_StartDataCaptured);
            sercam.OnDataCaptured += new SerCam.DataCapturedEventHandler(serCam_OnDataCaptured);
            sercam.FinishDataCaptured += new SerCam.FinishDataCapturedEventHandler(serCam_FinishDataCaptured);
            new Thread(VideoStreamming).Start();
        }

        private static void VideoStreamming()
        {
            Debug.Print("Video Streaming");
            while (true)
            {
                if (!sercam.isBusy)
                {
                    Debug.Print("Take Picture");
                    sercam.TakePicture();
                }
                else Thread.Sleep(50);
            }
        }

        private static void serCam_FinishDataCaptured(SerCam sender)
        {
           // display_T35.SimpleGraphics.DisplayImage(new Bitmap(datajpg, Bitmap.BitmapImageType.Jpeg), 0, 0);
            Debug.Print("Picture Captured");
           // Uplink.sendByteToServer(datajpg);
        }

        private static void serCam_OnDataCaptured(SerCam sender, byte[] data)
        {
            if (index + data.Length > datajpg.Length)
            {
                throw new Exception("Error");
            }
            Array.Copy(data, 0, datajpg, index, data.Length);
            index += data.Length;
        }

        private static void serCam_StartDataCaptured(SerCam sender, int sizeImage)
        {
            index = 0;
            datajpg = new byte[sizeImage];
        }

Ok so I’m happy I think I have JPEG data so now let’s shoot it back to my server program to “See” the JPEG.

Step one, add the Wifi setup back in… Run… It takes picture, but never fires the serCam_FinishDataCaptured event. So it just sits there doing nothing…

Here is my WifiSetup code, which seems to be working just fine otherwise…



        //**********************************************************
        //***** Wifi Setup
        //**********************************************************
        private static void WifiSetup()
        {

            if (!wifi.IsOpen)
            {
                wifi.Open();
            }

            wifi.NetworkInterface.EnableStaticIP("216.62.58.6", "255.255.255.0", "216.62.58.34");

            GN.NetworkInterfaceExtension.AssignNetworkingStackTo(wifi);

            GN.WiFiNetworkInfo[] scanResults;

            scanResults = wifi.Scan();

            int ssidIDx = 0;
            for (int cnt = 0; cnt < scanResults.Length; cnt++)
            {
                Debug.Print(cnt.ToString() + "-" + scanResults[cnt].SSID);

                if (scanResults[cnt].SSID == "linksys")
                {
                    ssidIDx = cnt;
                }

            }


            wifi.Join(scanResults[ssidIDx], "danh5258");

            while (!wifi.IsLinkConnected)
            {
                Debug.Print("Not Connected");
                Thread.Sleep(2000);
            }


            while (true)
            {
                Debug.Print(wifi.NetworkInterface.IPAddress);
                Thread.Sleep(2000);

                if (wifi.NetworkInterface.IPAddress != "0.0.0.0")
                {
                    break;
                }
            }

        } // end WifiSetup
        //**********************************************************


One step forward 2 steps back!

Dan

I have a further update. I did away with the "moving pictures and changed it to just a “takePicture” Added some debug code to each of the event handlers. serCam_OnDataCaptured was called multiple times with and increasing length and then stopped. The Finished event never fired. I’m kind of at a loss as to what to do.

Dan

        private static void cameratest()
        {
            sercam = new SerCam(5);
            sercam.DebugPrintEnabled = true;
            sercam.StartDataCaptured += new SerCam.StartDataCapturedEventHandler(serCam_StartDataCaptured);
            sercam.OnDataCaptured += new SerCam.DataCapturedEventHandler(serCam_OnDataCaptured);
            sercam.FinishDataCaptured += new SerCam.FinishDataCapturedEventHandler(serCam_FinishDataCaptured);
            //new Thread(VideoStreamming).Start();


            Debug.Print("Take Picture");
            sercam.TakePicture();

and the only thing you did between the two was take the comment out so that WifiSetup() was called, right?

Yes sir!

Going to put a little more info on here…

By leaving the WifiSetup off, I can take a picture. And it really works. Saved the picture to the SD Card and it looks real good on the PC. But I really want to transmit it wirelessly for some reason…

Dan

Not sure what the appropriate thing to do is here. This is still a problem from me and it seems to be affecting more than just me? I understand if no one has an answer, but what do I do then? Is there any place I can turn for support on this? Not trying to be a pain, just kind of stuck until I can get my camera and my wifi working at the same time…

I think this issue is related to another thing, because he is working on FEZ Corba II, not like Hydra issue.
Anyway, we will check it.

I will give this a shot and see if anything changes. Will have to think about how I can tell if the picture is being taken without the debug running… Will post what I find.

Checking in to see if any progress has been made on this?

I have a little more information:

As stated before, as long as I do not init the wifi module my code runs fine. Even with all Debug.Prints in the code.

However, I did try removing them and still see to have the same problem.

I went to the trouble of copying the SerCam Namespace and Class directly into my project, renamed it a bit so that I could do some lower level debuging. I found pretty much the same thing as reported on the Hydra thread. It is the read bytes that is getting locked up. And once it gets locked up the serial interface seems to be hosed to the camera. It doesn’t download blocks from the camera anymore. (I know this is kind of vague, but it just the general impression I got).

I can “see” the readbytes get “stuck” trying to read bytes but never completing. I even tried to “workaround” it by “detecting” the stuck condition and dropping out of the read bytes loop. I would then call “Finish” and use the “resetCamera” helper function. But like I said camera seems hosed at this point.

Of course, don’t init the wifi and it works flawlessly.

So anyway, I can’t really think of a way to work around this… I’m not crazy thinking that somehow the wifi card and the serial port are interfering with each other.

One more tidbit, I have hooked a RS232 connector to Port 5 ( the same one I’m using the camera on), and can talk to my “Motor Controller” just fine over that serial connection. With Wifi on. But of course that is not really a very complicated stream. In looking at the inards of the SerCam class it looks like it is initializing the serial port the exact same way…

IDK… Just thought I would ping y’all again.

Dan

try to update to SDK 4.2.10.0