My Serial Camera L1 Module (batch #447) appears to be taking two pictures, when I have only requested one… I can’t really explain it, and I’ve been trying to debug it for ~20 hours.
The issue I have is that serCam.TakePicture() sometimes causes the camera to freeze up; saying: “Cannot take picture at this time” when I request (via WebEventHandlers) pictures faster than it can take them… That’s not really an issue; I would totally love to wait for the camera to be done, but when I get that message “Cannot take picture at this time”; it’s almost surely a sign that the camera will freeze up (and future web requests time out)… Eventually the camera does unfreeze, something like 5 minutes… I added a timeout of 30 seconds to the WebRequest and a dirty timeout (since serCam.thread is private) to the web event handler: i.e. the camera has been busy too long, time to send a response that it’s exceptionally lame.
I’m totally open to the idea that the problem is being caused by me. I have multiple Cobra II boards, and multiple serial camera modules. No combo can surmount this issue; in my mind…
Almost certainly related is another issue… After requesting ~10 or 20 pictures, the board eventually freaks out and completely freezes (must be reset)… I never stick around long enough to see if it will unfreeze (freeze for 10+ minutes). the GC.Debug() shows plenty of memory; which makes me suspect that there isn’t a memory leak when handling the images.
However… The Debugger doesn’t even recognize the board’s real mac address; so I wouldn’t know if I could/should trust the output from Debug.GC() or not.
On a side note; I am very pleased with the quality of the pictures
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by the Gadgeteer Designer.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;
namespace GadgeteerApp1
{
public partial class Program : Gadgeteer.Program
{
// GTM.Module definitions
public static Gadgeteer.Modules.GHIElectronics.SerCam serCam;
public static void Main()
{
//Important to initialize the Mainboard first
Mainboard = new GHIElectronics.Gadgeteer.FEZCobra_II();
Program program = new Program();
program.InitializeModules();
program.ProgramStarted();
program.Run(); // Starts Dispatcher
}
private void InitializeModules()
{
// Initialize GTM.Modules and event handlers here.
serCam = new GTM.GHIElectronics.SerCam(5);
serCam.StartDataCaptured += new SerCam.StartDataCapturedEventHandler(PMCam_StartDataCaptured);
serCam.OnDataCaptured += new SerCam.DataCapturedEventHandler(PMCam_OnDataCaptured);
serCam.FinishDataCaptured += new SerCam.FinishDataCapturedEventHandler(PMCam_FinishDataCaptured);
}
}
}
Program.cs
using System;
using System.Threading;
using Microsoft.SPOT;
using Gadgeteer.Networking;
using GHINET = GHI.Premium.Net;
using GHI.Premium.Hardware;
using Gadgeteer.Modules.GHIElectronics;
namespace GadgeteerApp1 {
public partial class Program {
/**
* <summary>
* This is the web server port that is hosted on the localhost (the board running this code)
* </summary>
*/
const int WEB_SERVER_PORT = 80;
/**
* <summary>
* This is "name" of the wireless network.
* </summary>
*/
private static string WIRELESS_SSID = "***";
/**
* <summary>
* This is "password"/key to join the wireless network.
* </summary>
*/
private static string WIRELESS_PASS = "***"; //WPA2 incase it matters for this forum post
public static GHINET.WiFiRS9110 wifi;
public static Boolean webServerStarted = false;
/**
* <summary>
* This is a buffer to hold the image (combine the fragments)
* after Camera.OnDataCaptured is called.
*
* @ TODO check if this image can be unbuffered (this would be fastest),
* or maybe it should be buffered incase the WebResponse fails to go through?
* </summary>
*/
public static byte[] bitmapData;
/**
* <summary>
* This holds the offset for the byte[] datajpg variable.
* It's only used by the serial camera.
* </summary>
*/
private int serialCameraBufferedImageIndex;
public void ProgramStarted() {
Debug.EnableGCMessages(true);
serCam.SetImageSize(SerCam.Camera_Resolution.SIZE_QVGA);
// initialize wifi
wifi = new GHINET.WiFiRS9110(Microsoft.SPOT.Hardware.SPI.SPI_module.SPI2, G120.Pin.P1_10, G120.Pin.P2_11, G120.Pin.P1_9, 4000);
if (!wifi.IsOpen)
wifi.Open();
if (!wifi.NetworkInterface.IsDhcpEnabled)
wifi.NetworkInterface.EnableDhcp();
wifi.NetworkAddressChanged += new GHINET.NetworkInterfaceExtension.NetworkAddressChangedEventHandler(wifi_NetworkAddressChanged);
wifi.WirelessConnectivityChanged += new GHINET.WiFiRS9110.WirelessConnectivityChangedEventHandler(wifi_WirelessConnectivityChanged);
GHINET.NetworkInterfaceExtension.AssignNetworkingStackTo(wifi);
GHINET.WiFiNetworkInfo[] scanResult = wifi.Scan();
// scan for the wifi AP i intend to connect to
for (int i = 0; i < scanResult.Length; i++)
if (scanResult[i].SSID == WIRELESS_SSID) {
wifi.Join(scanResult[i], WIRELESS_PASS);
break; // once found, stop iterating. the rest of the results are useless (unless evil twin attack)
}
}
static byte[] GetBytes(string str) {
byte[] bytes = new byte[str.Length * sizeof(char)];
Array.Copy(str.ToCharArray(), bytes, bytes.Length);
return bytes;
}
static void wifi_WirelessConnectivityChanged(object sender, GHINET.WiFiRS9110.WirelessConnectivityEventArgs e) {
}
static void wifi_NetworkAddressChanged(object sender, EventArgs e) {
/* Start the HTTPD server every time the network address changes */
if (wifi.IsActivated) {
webServerStarted = true;
//WebServer.StartLocalServer(wifi.NetworkInterface.IPAddress, WEB_SERVER_PORT);
startHTTPServer();
}
/* Stop the HTTP Server... since we aren't connected */
else {
webServerStarted = false;
WebServer.StopLocalServer();
}
}
static void webEventReceivedPictureHandler(string path, WebServer.HttpMethod method, Responder responder) {
int sleeping = 0;
serCam.TakePicture();
while (serCam.isBusy) {
sleeping += 200;
Thread.Sleep(200);
Debug.Print("Sleeping " + sleeping);
if (sleeping > 3000) {
responder.Respond(GetBytes("The camera took exceptionally long to generate a picture!"), "text/html");
return;
}
}
responder.Respond(bitmapData, "image/bmp");
}
public static void startHTTPServer() {
WebEvent webEventtakepicture;
Debug.Print("------------------------------------------------------");
Debug.Print("Starting the Web Server listening on " + wifi.NetworkInterface.IPAddress + ":" + WEB_SERVER_PORT.ToString());
WebServer.StartLocalServer(wifi.NetworkInterface.IPAddress, WEB_SERVER_PORT);
webServerStarted = true;
/* this web event does not seem to be working properly... */
webEventtakepicture = WebServer.SetupWebEvent("picture");
webEventtakepicture.WebEventReceived += new WebEvent.ReceivedWebEventHandler(webEventReceivedPictureHandler);
Debug.Print("Handlers have been added to the web server. " +
"try: http://" + wifi.NetworkInterface.IPAddress + ":" + WEB_SERVER_PORT + "/picture");
Debug.Print("------------------------------------------------------");
}
void PMCam_StartDataCaptured(SerCam sender, int sizeImage) {
sender.DebugPrintEnabled = true;
Debug.Print("Starting to take picture");
Debug.Print("(sender.ToString()): " + (sender.ToString()));
Debug.Print("Image Size (Bytes): " + sizeImage.ToString());
serialCameraBufferedImageIndex = 0;
bitmapData = new byte[sizeImage];
}
void PMCam_OnDataCaptured(SerCam sender, byte[] data) {
sender.DebugPrintEnabled = true;
if (serialCameraBufferedImageIndex + data.Length > bitmapData.Length)
throw new Exception("Error");
Array.Copy(data, 0, bitmapData, serialCameraBufferedImageIndex, data.Length);
serialCameraBufferedImageIndex += data.Length;
}
void PMCam_FinishDataCaptured(SerCam sender) {
}
}
}
Debug Output:
Found debugger!
Create TS.
Loading start at a0e856b0, end a0e9ce0c
Assembly: mscorlib (4.2.0.0) Assembly: Microsoft.SPOT.Native (4.2.0.0) Assembly: Microsoft.SPOT.Hardware (4.2.0.0)
Assembly: Microsoft.SPOT.Hardware.PWM (4.2.0.1) Assembly: Microsoft.SPOT.Security.PKCS11 (4.2.0.0)
Assembly: System.Security (4.2.0.0) Loading Deployment Assemblies.
Attaching deployed file.
Assembly: Microsoft.SPOT.IO (4.2.0.0) Attaching deployed file.
Assembly: GHI.Premium.IO (4.2.9.0) Attaching deployed file.
Assembly: Microsoft.SPOT.Graphics (4.2.0.0) Attaching deployed file.
Assembly: System.Http (4.2.0.0) Attaching deployed file.
Assembly: System (4.2.0.0) Attaching deployed file.
Assembly: Microsoft.SPOT.Net.Security (4.2.0.0) Attaching deployed file.
Assembly: Gadgeteer.WebServer (2.42.0.0) Attaching deployed file.
Assembly: GHI.Premium.System (4.2.9.0) Attaching deployed file.
Assembly: Microsoft.SPOT.TinyCore (4.2.0.0) Attaching deployed file.
Assembly: Gadgeteer.Serial (2.42.0.0) Attaching deployed file.
Assembly: GadgeteerApp1 (1.0.0.0) Attaching deployed file.
Assembly: System.Net.Security (4.2.0.0) Attaching deployed file.
Assembly: GHI.Premium.Net (4.2.9.0) Attaching deployed file.
Assembly: System.IO (4.2.0.0) Attaching deployed file.
Assembly: Microsoft.SPOT.Net (4.2.0.0) Attaching deployed file.
Assembly: GTM.GHIElectronics.SerCam (1.1.1.0) Attaching deployed file.
Assembly: Microsoft.SPOT.Touch (4.2.0.0) Attaching deployed file.
Assembly: GHI.Premium.Hardware (4.2.9.0) Attaching deployed file.
Assembly: Gadgeteer (2.42.0.0) Attaching deployed file.
Assembly: GHIElectronics.Gadgeteer.FEZCobra_II (1.1.1.0) Attaching deployed file.
Assembly: Microsoft.SPOT.Hardware.SerialPort (4.2.0.0) Attaching deployed file.
Assembly: GHI.Premium.Hardware.G120 (4.2.9.0) Resolving.
GC: 3msec 527844 bytes used, 6811824 bytes available
Type 0F (STRING ): 24 bytes
Type 15 (FREEBLOCK ): 6811824 bytes
Type 17 (ASSEMBLY ): 35064 bytes
Type 1E (BINARY_BLOB_HEAD ): 492684 bytes
Type 34 (APPDOMAIN_HEAD ): 72 bytes
GC: performing heap compaction...
The debugging target runtime is loading the application assemblies and starting execution.
Ready.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\mscorlib.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.Native.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.Hardware.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.Hardware.PWM.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.Security.PKCS11.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\System.Security.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.IO.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\GHI Electronics\GHI Premium NETMF v4.2 SDK\Assemblies\le\GHI.Premium.System.dll'
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\GHI Electronics\GHI Premium NETMF v4.2 SDK\Assemblies\le\GHI.Premium.IO.dll'
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.Graphics.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.Net.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\System.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.Net.Security.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\System.Net.Security.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\System.Http.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.TinyCore.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\System.IO.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Gadgeteer\Core\Assemblies\.NET Micro Framework 4.2\le\Gadgeteer.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Gadgeteer\Core\Assemblies\.NET Micro Framework 4.2\le\Gadgeteer.WebServer.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.Hardware.SerialPort.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Gadgeteer\Core\Assemblies\.NET Micro Framework 4.2\le\Gadgeteer.Serial.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\GHI Electronics\GHI Premium NETMF v4.2 SDK\Assemblies\le\GHI.Premium.Net.dll'
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\GHI Electronics\GHI .NET Gadgeteer SDK\Modules\SerCam\NETMF 4.2\le\GTM.GHIElectronics.SerCam.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\GHI Electronics\GHI Premium NETMF v4.2 SDK\Assemblies\le\GHI.Premium.Hardware.dll'
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\GHI Electronics\GHI .NET Gadgeteer SDK\Mainboards\FEZCobra_II\NETMF 4.2\le\GHIElectronics.Gadgeteer.FEZCobra_II.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Users\ethos-one\AppData\Local\Temporary Projects\GadgeteerApp1\bin\Debug\le\GadgeteerApp1.exe', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.2\Assemblies\le\Microsoft.SPOT.Touch.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.dll' (Managed): Loaded 'C:\Program Files (x86)\GHI Electronics\GHI Premium NETMF v4.2 SDK\Assemblies\le\GHI.Premium.Hardware.G120.dll'
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
Using mainboard GHI Electronics FEZCobra II version 1.0
RS9110 firmware version Number is 4.4.5
RS9110 driver version Number is 4.4.5
The thread '<No Name>' (0x3) has exited with code 0 (0x0).
------------------------------------------------------
Starting the Web Server listening on 192.168.1.102:80
Web server started at http://192.168.1.102:80/
Handlers have been added to the web server. try: http://192.168.1.102:80/picture
------------------------------------------------------
The thread '<No Name>' (0x6) has exited with code 0 (0x0).
Sleeping 200
Sleeping 400
Sleeping 600
Starting to take picture
(sender.ToString()): SerCam
Image Size (Bytes): 12608
Sleeping 800
Sleeping 1000
Sleeping 1200
Sleeping 1400
Sleeping 1600
Sleeping 1800
The thread '<No Name>' (0x8) has exited with code 0 (0x0).
Sleeping 2000
The thread '<No Name>' (0x7) has exited with code 0 (0x0).
Sleeping 200
Sleeping 400
Sleeping 600
Starting to take picture
(sender.ToString()): SerCam
Image Size (Bytes): 12696
Sleeping 800
Sleeping 1000
Sleeping 1200
Sleeping 1400
Sleeping 1600
Sleeping 1800
Sleeping 2000
The thread '<No Name>' (0xa) has exited with code 0 (0x0).
Sleeping 2200
Edit: This debug output is from requesting a single picture. I confirm with wireshark that this is the case.
huge buffer of karma for anyone who can return my sanity