Main Site Documentation

SerCam exception


#1

Hi –
I am getting the following exception output spew when attempting to write a basic program on my FEZ Raptor that captures streams from the SerCam L1 and displays it on the T43:

A first chance exception of type ‘System.Exception’ occurred in GTM.GHIElectronics.SerCam.dll
#### Exception System.Exception - 0x00000000 (5) ####
#### Message:
#### Gadgeteer.Modules.GHIElectronics.SerCam::ReadBytes [IP: 002f] ####
#### Gadgeteer.Modules.GHIElectronics.SerCam::ReadFrameBuffer [IP: 006b] ####
#### Gadgeteer.Modules.GHIElectronics.SerCam::UpdateStreaming [IP: 003a] ####

Here is the code:


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.Presentation.Shapes;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

namespace GadgeteerCamera
{
    public partial class Program
    {
        static Bitmap LCD = new Bitmap(320, 240);
        GT.Timer timer = new GT.Timer(2000);

        void ProgramStarted()
        {
            button.ButtonPressed += new Button.ButtonEventHandler(button_ButtonPressed);

            serCam.SetImageSize(SerCam.Camera_Resolution.SIZE_QVGA);
            serCam.StartStreaming();
            Debug.Print("Streaming started...");
            
            timer.Behavior = GT.Timer.BehaviorType.RunContinuously;
            timer.Tick += new GT.Timer.TickEventHandler(timer_Tick);

            timer.Start();

            Debug.Print("Program Started");
        }

        void timer_Tick(GT.Timer timer)
        {
            if (serCam.isNewImageReady)
            {
                serCam.DrawImage(LCD, 0, 0, 320, 240);
                display_T43.SimpleGraphics.DisplayImage(LCD, 0, 0);
            }
        }

        private void button_ButtonPressed(Button sender, Button.ButtonState state)
        {
            Debug.Print("Stop streaming...");

            timer.Stop();
        }
    }
} 

Anyone have any suggestions? The T port solution from another thread didn’t address this issue, though an earlier iteration of the code where I put it all within a while(true) loop in the main body of the program worked only when I was NOT in debug mode. Seems like some kind of threading/timing issue, but I am not sure what it might be. Also not sure why putting the code in the main method and not triggering an event works when NOT in debug mode.

Thanks!


#2

no that’s a different person with exactly the same problem :slight_smile:


#3

@ bruce.e.brown - I ran your code almost completely the same, albeit, a difference in the name of the project, and I am not receiving the error that you are experiencing.

the following are a few questions to figure out the problem:

  1. What is the firmware version of your device?
  2. On which sockets do you have everything connected to? (I have the SerCam in socket 1 and the button in 3 and all of the T43 connected to their default connections, sockets 14~17)
  3. How are you powering your Raptor?

I am posting my code that is being used:

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.Presentation.Shapes;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

namespace RaptorGadgeteerSerCamL1
{
    public partial class Program
    {
        static Bitmap LCD = new Bitmap(320, 240);
        GT.Timer timer = new GT.Timer(2000);
        void ProgramStarted()
        {
            button.ButtonPressed += button_ButtonPressed;

            serCam.SetImageSize(SerCam.Camera_Resolution.SIZE_QVGA);
            serCam.StartStreaming();
            Debug.Print("Streaming started...");

            timer.Behavior = GT.Timer.BehaviorType.RunContinuously;
            timer.Tick += timer_Tick;

            timer.Start();

            Debug.Print("Program Started");
        }

        void timer_Tick(GT.Timer timer)
        {
            if (serCam.isNewImageReady)
            {
                serCam.DrawImage(LCD, 0, 0, 320, 240);
                display_T43.SimpleGraphics.DisplayImage(LCD, 0, 0);
            }
        }

        void button_ButtonPressed(Button sender, Button.ButtonState state)
        {
            Debug.Print("Stop streaming...");

            timer.Stop();
        }
    }
}


#4

and: Disable Touch in your code, then disconnect wires in socket T if any.

Serial UART works incorrectly sometime if Touch is enable.

And, check all your cables if you tried above steps.


#5

Hey guys, thanks for the replies.

Here is what FEZConfig tells me with regard to my Firmware on my FEZ Raptor:

Loader (TinyBooter) version information:
4.2.11.1 on this computer.
4.2.11.1 on this device.

The Loader (TinyBooter) is up to date. <<<

Firmware (TinyCLR) version information:
4.2.11.1 on this computer.
4.2.11.1 on this device.

The Firmware (TinyCLR) is up to date. <<<
Please wait for the device to reboot… Done.

I have the button plugged into port 10, the LCD in 15/16/17 (unplugged T from another post), the Camera is plugged into 4, and I am powering everything through my USB Client DP v1.3 in port 8 (the “D” port) plugged into the USB on my computer.

With regard to disabling touch, I’m not seeing any methods or properties on the display_T43 that jump out at me as “disable touch”, so is there something I should be doing other than unplugging the Touch cable?

As mentioned I can get the code to work if I am not using events and just put the camera>display loop in a while(true) as long as I am NOT in debug mode.

I tried your configuration (port 1 for the serCam, 3 for the button, plugged T back in), and while I am no longer hitting the exception, the “IsNewImageReady” bool is never getting set:

        void timer_Tick(GT.Timer timer)
        {
            Debug.Print("Checking image...");

            if (serCam.isNewImageReady)
            {
                Debug.Print("Drawing image...");
                serCam.DrawImage(LCD, 0, 0, 320, 240);
                display_T43.SimpleGraphics.DisplayImage(LCD, 0, 0);
            }
        }

So while I see a steady stream of “Checking image…” from above in the debug output, I am not ever seeing the “Drawing image…” message, and the screen isn’t being updated (regardless of running in debug mode).

I am attempting to follow the code here:
https://www.ghielectronics.com/docs/176/serial-camera-module
but without the for loop per the debugger output suggestion to use a timer rather than a while(true).

Is there a timing/setup issue somewhere that I am not addressing?

Thanks for the quick replies and the help!


#6

@ bruce.e.brown - to disable touch, all that is needed is to disconnect the touch socket in the designer.

I did not experience the issue that you are having regarding the “IsNewImageReady” flag.


#7

I had forgotten to re-wire the connections to the ports you suggested. Once I did that, everything worked. It also worked with touchscreen enabled.

I am wondering what the difference is between ports 1 (your suggestion) and 4 (my original port) as far as the serCam is concerned as that seems to be the only difference.

Any ideas?

Thanks again for your help.


#8

I now added the Simple Http Server to my program (https://www.ghielectronics.com/community/codeshare/entry/588) using the ENC28, and I am back to getting the same exceptions from the camera.

I have tried connecting the ENC28 to both ports 3 and 11 but am not able to get the camera to work. It is connected to port 1, with the USB Client DP on 8 and the LCD on 15/16/17.

I was hoping to stream the camera images to a locally hosted webpage. Here is the code now. Note that I haven’t tried streaming the image to the page yet. I just wanted to get an Http Server up and running in the same program as the camera code.

Any idea how I might get this to work?


using System;
using System.Net;
using System.Text;
using System.Threading;
using Gadgeteer.Modules.GHIElectronics;
using GHI.Premium.Net;
using Microsoft.SPOT;

namespace GadgeteerCamera
{
    public partial class Program
    {
        private const string MyIP = "192.168.1.202";
        private const int SampleRate = 100;

        private bool cameraOn = true;
        private Bitmap lcd;

        private EthernetENC28J60 ethernet;
        private byte[] outBuffer;
        private ManualResetEvent networkAvailablityBlocking = null;

        private void ProgramStarted()
        {
            Debug.Print("Program Started");

            InitializeCamera();

            InitializeWebServer();
        }

        private void InitializeCamera()
        {
            // Setup timer and button events
            var timer = new Gadgeteer.Timer(SampleRate, Gadgeteer.Timer.BehaviorType.RunContinuously);

            // Setup timer and button events
            timer.Tick += new Gadgeteer.Timer.TickEventHandler(SampleCamera);
            button.ButtonPressed += new Button.ButtonEventHandler(ToggleCamera);

            // Setup image resolution
            lcd = new Bitmap((int) display_T43.Width, (int) display_T43.Height);
            serCam.SetImageSize(SerCam.Camera_Resolution.SIZE_VGA);

            // Start the timer and streaming
            timer.Start();
            serCam.StartStreaming();
            Debug.Print("Streaming started...");
        }

        private void InitializeWebServer()
        {
            ethernet = ethernet_ENC28.Interface;
            ethernet.Open();

            NetworkInterfaceExtension.AssignNetworkingStackTo(ethernet);
            ethernet.CableConnectivityChanged += 
                new EthernetENC28J60.CableConnectivityChangedEventHandler(ConnectivityChanged);
            ethernet.NetworkAddressChanged +=
                new NetworkInterfaceExtension.NetworkAddressChangedEventHandler(NetworkAddressChanged);

            ethernet.NetworkInterface.EnableStaticIP(MyIP, "255.255.255.0", "192.168.1.1");

            if (!ethernet.IsCableConnected)
            {
                networkAvailablityBlocking = new ManualResetEvent(false);

                do
                {
                    if (!ethernet.IsCableConnected)
                    {
                        Debug.Print("Ethernet cable is not connected.");
                    }
                    else
                    {
                        break;
                    }
                } while (!networkAvailablityBlocking.WaitOne(5000, false));
            }

            while (Equals(IPAddress.GetDefaultLocalAddress(), IPAddress.Any))
            {
                Debug.Print("IP Address is not set.");
            }

            Debug.Print("IP address is set.");

            const string defaultMessage = "Welcome to the Brown Family internal website.";
            outBuffer = Encoding.UTF8.GetBytes(defaultMessage);

            try
            {
                Debug.Print("Running HttpServer");
                Debug.Print("Type this address to access the webpage: " + ethernet.NetworkInterface.IPAddress);

                RunServer();
            }
            catch (Exception e)
            {
                Debug.Print(e.Message);
            }
        }

        private void ConnectivityChanged(object sender, EthernetENC28J60.CableConnectivityEventArgs e)
        {
            Debug.Print("Built-in Ethernet Cable is " + (e.IsConnected ? "Connected." : "Disconneced."));

            if (e.IsConnected)
            {
                networkAvailablityBlocking.Set();
            }
        }

        private void NetworkAddressChanged(object sender, EventArgs e)
        {
            Debug.Print("New address for the Ethernet Network Interface ");

            Debug.Print("Is DhCp enabled: " + ethernet.NetworkInterface.IsDhcpEnabled);
            Debug.Print("Is DynamicDnsEnabled enabled: " + ethernet.NetworkInterface.IsDynamicDnsEnabled);
            Debug.Print("NetworkInterfaceType " + ethernet.NetworkInterface.NetworkInterfaceType);
            Debug.Print("Network settings:");
            Debug.Print("IP Address: " + ethernet.NetworkInterface.IPAddress);
            Debug.Print("Subnet Mask: " + ethernet.NetworkInterface.SubnetMask);
            Debug.Print("Default Getway: " + ethernet.NetworkInterface.GatewayAddress);
            Debug.Print("Number of DNS servers:" + ethernet.NetworkInterface.DnsAddresses.Length);

            for (var i = 0; i < ethernet.NetworkInterface.DnsAddresses.Length; i++)
            {
                Debug.Print("DNS Server " + i.ToString() + ":" + ethernet.NetworkInterface.DnsAddresses[i]);
            }

            Debug.Print("------------------------------------------------------");
        }

        private void RunServer()
        {
            var listener = new HttpListener("http");
            listener.Start();

            while (true)
            {
                HttpListenerContext context = null;

                try
                {
                    context = listener.GetContext();
                    var response = context.Response;
                    var request = context.Request;

                    switch (request.HttpMethod.ToUpper())
                    {
                        case "GET": ProcessClientGetRequest(context); 
                            break;
                    }

                    if (response != null)
                    {
                        response.Close();
                    }
                }
                catch
                {
                    if (context != null)
                    {
                        context.Close();
                    }
                }
            }
        }

        private void ProcessClientGetRequest(HttpListenerContext context)
        {
            var request = context.Request;
            var response = context.Response;

            Debug.Print(request.RawUrl);
            response.OutputStream.Write(outBuffer, 0, outBuffer.Length);
        }

        private void SampleCamera(Gadgeteer.Timer timer)
        {
            // If the camera is ready to stream a new image, then stream it
            if (serCam.isNewImageReady && cameraOn)
            {
                Debug.Print("Drawing image...");
                serCam.DrawImage(lcd, 0, 0, (int) display_T43.Width, (int) display_T43.Height);
                display_T43.SimpleGraphics.DisplayImage(lcd, 0, 0);
            }
        }

        private void ToggleCamera(Button sender, Button.ButtonState state)
        {
            if (cameraOn)
            {
                Debug.Print("Streaming stopped");
                display_T43.SimpleGraphics.Clear();
                cameraOn = false;
            }
            else
            {
                cameraOn = true;
            }
        }
    }
}


#9

@ bruce.e.brown - If you comment out the InitializeWebServer() function, will you still get the exception?

Can you post the exception that you are getting? Post the complete output window until you see that message, unless it is way too big to post.


#10

No – no exception if I comment out the WebServer code. Exception is the same from earlier:

#### Exception System.Exception - 0x00000000 (5) ####
#### Message: 
#### Gadgeteer.Modules.GHIElectronics.SerCam::ReadBytes [IP: 002f] ####
#### Gadgeteer.Modules.GHIElectronics.SerCam::ReadFrameBuffer [IP: 006b] ####
#### Gadgeteer.Modules.GHIElectronics.SerCam::UpdateStreaming [IP: 003a] ####

A first chance exception of type ‘System.Exception’ occurred in GTM.GHIElectronics.SerCam.dll

I updated the WebServer to spin off separate threads and refactored into classes as follows below (it couldn’t handle more than one simultaneous request as written), but I still get the same exception if I try to run both the Camera code and the server:

Program.cs:


using Gadgeteer.Modules;

namespace GadgeteerCamera
{
    public partial class Program
    {
        private WebServer server;
        private LcdConsole lcdConsole;
        private StreamingCamera streamingCamera;

        private void ProgramStarted()
        {
            InitializeLcd();
            InitializeCamera();
            InitializeWebServer();
        }

        private void InitializeLcd()
        {
            bool rotationEnabled = display_T43.SetLCDRotation(Module.DisplayModule.LCDRotation.Clockwise90Degrees);
            this.lcdConsole = new LcdConsole(Resources.GetFont(Resources.FontResources.small), display_T43, true);

            lcdConsole.WriteLine("Initializing LCD...");
            lcdConsole.WriteLine("Rotation Enabled: " + rotationEnabled.ToString());
        }

        private void InitializeCamera()
        {
            lcdConsole.WriteLine("Initializing Camera...");
            this.streamingCamera = new StreamingCamera(serCam, display_T43, button, lcdConsole);
        }

        private void InitializeWebServer()
        {
            lcdConsole.WriteLine("Initializing Web Server...");
            this.server = new WebServer("http", 8080, 200, ethernet_ENC28.Interface, lcdConsole);
        }
    }
}

WebServer.cs:


using System;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using GHI.Premium.Net;
using Microsoft.SPOT;

namespace GadgeteerCamera
{
    public class WebServer
    {
        private const string MyIP = "192.168.1.202";
        private Thread serverThread = null;
        private readonly Queue responseQueue;
        private string prefix;
        private int port = 8080;
        private int timeout = 200;
        private ManualResetEvent networkAvailablityBlocking = null;
        private EthernetENC28J60 ethernet;
        private LcdConsole lcdConsole;

        public WebServer(string prefix, int port, int timeout, EthernetENC28J60 ethernet, LcdConsole lcdConsole)
        {
            this.lcdConsole = lcdConsole;
            this.responseQueue = new Queue();

            this.prefix = prefix;
            this.port = port;
            this.timeout = timeout;
            this.ethernet = ethernet;

            this.InitializeWebServer();

            this.serverThread = new Thread(() => RunServer());
            this.serverThread.Start();
        }

        private void InitializeWebServer()
        {
            ethernet.Open();

            NetworkInterfaceExtension.AssignNetworkingStackTo(ethernet);
            ethernet.CableConnectivityChanged += (o, args) => ConnectivityChanged(o, args);
            ethernet.NetworkAddressChanged += (o, args) => NetworkAddressChanged(o, args, ethernet);

            ethernet.NetworkInterface.EnableStaticIP(MyIP, "255.255.255.0", "192.168.1.1");

            if (!ethernet.IsCableConnected)
            {
                networkAvailablityBlocking = new ManualResetEvent(false);

                do
                {
                    if (!ethernet.IsCableConnected)
                    {
                        lcdConsole.WriteLine("Ethernet cable is not connected.");
                    }
                    else
                    {
                        break;
                    }
                } while (!networkAvailablityBlocking.WaitOne(5000, false));
            }

            while (Equals(IPAddress.GetDefaultLocalAddress(), IPAddress.Any))
            {
                lcdConsole.WriteLine("IP Address is not set.");
            }

            lcdConsole.WriteLine("IP address is set: " + ethernet.NetworkInterface.IPAddress);
        }

        private void NetworkAddressChanged(object sender, EventArgs e, EthernetENC28J60 ethernet)
        {
            lcdConsole.WriteLine("New address for the Ethernet Network Interface ");

            lcdConsole.WriteLine("Is DhCp enabled: " + ethernet.NetworkInterface.IsDhcpEnabled);
            lcdConsole.WriteLine("Is DynamicDnsEnabled enabled: " + ethernet.NetworkInterface.IsDynamicDnsEnabled);
            lcdConsole.WriteLine("NetworkInterfaceType " + ethernet.NetworkInterface.NetworkInterfaceType);
            lcdConsole.WriteLine("Network settings:");
            lcdConsole.WriteLine("IP Address: " + ethernet.NetworkInterface.IPAddress);
            lcdConsole.WriteLine("Subnet Mask: " + ethernet.NetworkInterface.SubnetMask);
            lcdConsole.WriteLine("Default Getway: " + ethernet.NetworkInterface.GatewayAddress);
            lcdConsole.WriteLine("Number of DNS servers:" + ethernet.NetworkInterface.DnsAddresses.Length);

            for (var i = 0; i < ethernet.NetworkInterface.DnsAddresses.Length; i++)
            {
                lcdConsole.WriteLine("DNS Server " + i.ToString() + ":" + ethernet.NetworkInterface.DnsAddresses[i]);
            }

            lcdConsole.WriteLine("------------------------------------------------------");
        }

        private void ConnectivityChanged(object sender, EthernetENC28J60.CableConnectivityEventArgs e)
        {
            lcdConsole.WriteLine("Built-in Ethernet Cable is " + (e.IsConnected ? "Connected." : "Disconneced."));

            if (e.IsConnected)
            {
                networkAvailablityBlocking.Set();
            }
        }

        private void RunServer()
        {
            var listener = new HttpListener(this.prefix, this.port);

            if (prefix == "https")
            {
                var serverCertAsString = Resources.GetString(Resources.StringResources.cert_device_microsoft_com);
                var serverCertAsArray = Encoding.UTF8.GetBytes(serverCertAsString);
                listener.HttpsCert = new X509Certificate(serverCertAsArray, "NetMF");
            }

            while (true)
            {
                try
                {
                    if (!listener.IsListening)
                    {
                        listener.Start();
                    }

                    var context = listener.GetContext();
                    lock (responseQueue)
                    {
                        responseQueue.Enqueue(context);
                    }

                    var handleRequestThread = new Thread(() => HandleRequestThread());
                    handleRequestThread.Start();
                }
                catch (InvalidOperationException)
                {
                    listener.Stop();
                    Thread.Sleep(200);
                }
                catch (ObjectDisposedException)
                {
                    listener.Start();
                }
                catch
                {
                    Thread.Sleep(200);
                }
            }
        }

        private void HandleRequestThread()
        {
            HttpListenerContext context = null;

            try
            {
                lock (responseQueue)
                {
                    context = (HttpListenerContext)responseQueue.Dequeue();
                }

                if (context != null)
                {
                    var request = context.Request;
                    switch (request.HttpMethod.ToUpper())
                    {
                        case "GET":
                            ProcessClientGetRequest(context);
                            break;

                        case "POST":
                            ProcessClientPostRequest(context);
                            break;
                    }
                }
            }
            catch (SocketException)
            {
            }
            finally
            {
                if (context != null)
                {
                    context.Close();
                }
            }
        }

        private void ProcessClientGetRequest(HttpListenerContext context)
        {
            var request = context.Request;
            var response = context.Response;
            var clientAddress = request.RemoteEndPoint.Address.ToString();
            var user = request.UserAgent;

            lcdConsole.WriteLine(clientAddress + " (" + user + ") " + request.HttpMethod.ToUpper()
                + ": " + request.RawUrl);

            const string defaultMessage = "Welcome to the Brown Family internal website.";
            var outBuffer = Encoding.UTF8.GetBytes(defaultMessage);
            response.OutputStream.Write(outBuffer, 0, outBuffer.Length);
        }

        private void ProcessClientPostRequest(HttpListenerContext context)
        {
            throw new NotImplementedException();
        }
    }
}


StreamingCamera.cs:


using Gadgeteer.Modules.GHIElectronics;
using Microsoft.SPOT;

namespace GadgeteerCamera
{
    public class StreamingCamera
    {
        private const int SampleRate = 100; 
        
        private SerCam serCam;
        private Display_T43 display;
        private Button button;
        private LcdConsole lcdConsole;
        private Bitmap lcd;

        private bool cameraOn = true;

        public StreamingCamera(SerCam serCam, Display_T43 display, Button button, LcdConsole lcdConsole)
        {
            this.serCam = serCam;
            this.display = display;
            this.button = button;
            this.lcdConsole = lcdConsole;

            InitializeCamera();
        }

        public void InitializeCamera()
        {
            // Setup timer and button events
            var timer = new Gadgeteer.Timer(SampleRate, Gadgeteer.Timer.BehaviorType.RunContinuously);

            // Setup timer and button events
            timer.Tick += new Gadgeteer.Timer.TickEventHandler(SampleCamera);
            button.ButtonPressed += new Button.ButtonEventHandler(ToggleCamera);

            // Setup image resolution
            lcd = new Bitmap((int) display.Width, (int) display.Height);
            serCam.SetImageSize(SerCam.Camera_Resolution.SIZE_VGA);

            // Start the timer and streaming
            timer.Start();
            serCam.StartStreaming();
            lcdConsole.WriteLine("Streaming started...");
        }

        private void SampleCamera(Gadgeteer.Timer timer)
        {
            lcdConsole.WriteLine("Camera");
            // If the camera is ready to stream a new image, then stream it
            if (serCam.isNewImageReady && cameraOn)
            {
                lcdConsole.WriteLine("Drawing image...");
                serCam.DrawImage(lcd, 0, 0, (int) display.Width, (int) display.Height);
                display.SimpleGraphics.DisplayImage(lcd, 0, 0);
            }
        }

        private void ToggleCamera(Button sender, Button.ButtonState state)
        {
            if (cameraOn)
            {
                lcdConsole.WriteLine("Streaming stopped");
                display.SimpleGraphics.Clear();
                cameraOn = false;
            }
            else
            {
                cameraOn = true;
            }
        }
    }
}

LcdConsole.cs:


using System.Collections;
using Gadgeteer;
using Gadgeteer.Modules.GHIElectronics;
using Microsoft.SPOT;

namespace GadgeteerCamera
{
    public class LcdConsole
    {
        private const int LineSpacing = 0;

        private ArrayList screenText;
        private Font font;
        private Display_T43 display;

        private int fontHeight;
        private int fontWidth;

        private int widthInCharacters;
        private int lineHeight; 
        private int linesPerScreen;
        private bool debugOutput;

        public LcdConsole(Font font, Display_T43 display, bool debugOutput)
        {
            this.font = font;
            this.display = display;
            this.debugOutput = debugOutput;

            this.fontHeight = this.font.Height;
            this.fontWidth = this.font.AverageWidth + this.font.AverageWidth/2;

            this.widthInCharacters = (int) (this.display.Width/this.fontWidth);

            this.lineHeight = this.fontHeight + LineSpacing;
            this.linesPerScreen = (int) (this.display.Height/this.lineHeight);

            this.screenText = new ArrayList();
        }

        public void WriteLine(string line)
        {
            if (line.Length <= this.widthInCharacters)
            {
                screenText.Add(line);
            }
            else
            {
                var lineIndex = 0;
                var lineLength = line.Length;

                do
                {
                    screenText.Add(lineLength <= this.widthInCharacters
                        ? line.Substring(lineIndex, lineLength)
                        : line.Substring(lineIndex, this.widthInCharacters));

                    lineLength -= this.widthInCharacters;
                    lineIndex += this.widthInCharacters;
                } while (lineLength > 0);
            }

            this.DisplayText();

            if (debugOutput)
            {
                Debug.Print(line);
            }
        }

        private void DisplayText()
        {
            if (this.screenText.Count <= this.linesPerScreen)
            {
                DrawScreen(0);
            }
            else
            {
                DrawScreen(screenText.Count - this.linesPerScreen);
            }
        }

        private void DrawScreen(int arrayIndex)
        {
            uint whichLine = 0;

            for (var i = arrayIndex; i < screenText.Count; i++)
            {
                this.display.SimpleGraphics.DisplayText(
                    (string) screenText[i],
                    font,
                    Color.White,
                    0,
                    whichLine);

                whichLine += (uint) this.lineHeight;
            }
        }
    }
}



#11

@ bruce.e.brown - using your code example, we have indeed reproduced this issue. We will need to do further investigation as we are not certain at this moment if the bug lies with the implementation of this example (as removing the net code will solve the issue), the firmware, or in NetMF (considering this issue can be reproduced as is on a Spider as well). We will be investigating the issue and if it is in the firmware, we will see if we can implement a fix for a future firmware update.


#12

Thanks Aron!! I really appreciate your willingness to take my code and go the extra mile here to get a repro and debug. Amazing level.of support. You guys rock.

Do you think you could update the thread when you figure out the issue?

Very much appreciated!


#13

@ bruce.e.brown -

How about if we add Thread.sleep(x) for while loop into private void RunServer() function

private void RunServer()
{
       ..................
       while(true)
      {
            Thread.sleep(1);    
      }
      .....................
}

#14

Tried the sleep – no change. The camera is still throwing exceptions.


#15

Any updates?

I went ahead and bought the Camera Module:
https://www.ghielectronics.com/docs/62/camera-module

It is able to stream just fine with my web server code as I am able to accept connections to the web server while streaming images to the LCD. Here is the code I wrote for it:


using System.Threading;
using Gadgeteer.Modules.GHIElectronics;
using Microsoft.SPOT;

namespace GadgeteerCamera
{
    public class StillCamera
    {
        private const int SampleRate = 100; 

        private Camera camera;
        private Display_T43 display;
        private Button button;
        private LcdConsole lcdConsole;
        private Bitmap bitmap;

        private bool cameraOn = true;

        public StillCamera(Camera camera, Display_T43 display, Button button, LcdConsole lcdConsole)
        {
            this.camera = camera;
            this.display = display;
            this.button = button;
            this.lcdConsole = lcdConsole;

            InitializeCamera();
        }

        public void InitializeCamera()
        {
            camera.BitmapStreamed += new Camera.BitmapStreamedEventHandler(DisplayPicture);
            button.ButtonPressed += new Button.ButtonEventHandler(ToggleCamera);

            camera.CurrentPictureResolution = 
                new Camera.PictureResolution(Camera.PictureResolution.DefaultResolutions._320x240);
            this.bitmap = new Bitmap(camera.CurrentPictureResolution.Width, camera.CurrentPictureResolution.Height);

            while (!camera.CameraReady)
            {
                lcdConsole.WriteLine("Camera not ready");
                Thread.Sleep(1000);
            }
            camera.StartStreamingBitmaps(this.bitmap);

            lcdConsole.WriteLine("Streaming started...");
        }

        private void DisplayPicture(Camera sender, Bitmap picture)
        {
            if (cameraOn)
            {
                this.display.SimpleGraphics.DisplayImage(picture, 0, 0);
            }
        }

        private void ToggleCamera(Button sender, Button.ButtonState state)
        {
            if (this.cameraOn)
            {
                lcdConsole.WriteLine("Streaming stopped");
                display.SimpleGraphics.Clear();
                camera.StopStreamingBitmaps();
                this.cameraOn = false;
            }
            else
            {
                camera.StartStreamingBitmaps(this.bitmap);
                this.cameraOn = true;
            }
        }
    }
}

This points to something in the firmware of the SerCam, perhaps?


#16

Wow… I just can’t get a break with the Raptor…

I just tried hookup up my SerCam module and am getting the same issue. So are you saying that we can’t use a touch screen with this module? Or is it a Raptor issue with the firmware? Will it be fixed?

Roy