Wireless take a picture can't display on time

The scenario is the domino(with Xbee) send a packet to the Spider(has xbee also) every 5 seconds.
When the spider receive the packet then taking a picture and display the image.
But the image can’t display on time. it always has a delay time for displaying picture.
The screen shows the picture which is not the current picture.

    public partial class Program
    {
        // This method is run when the mainboard is powered up or reset.   
        public static byte[] input = new byte[12];
        GT.Timer timer = new GT.Timer(3000);
        void ProgramStarted()
        {
            //string test = "test";
            var font = Resources.GetFont(Resources.FontResources.small);
            xBee.SerialLine.Open();
            timer.Tick += new GT.Timer.TickEventHandler(timer_Tick);
            camera.PictureCaptured += new Camera.PictureCapturedEventHandler(camera_PictureCaptured);
            timer.Start();
        }
        void camera_PictureCaptured(Camera sender, GT.Picture picture)
        {
            display.SimpleGraphics.DisplayImage(picture, 5, 5);
            
        }
        
        void timer_Tick(GT.Timer timer)
        {

            var font = Resources.GetFont(Resources.FontResources.small);
            int count = xBee.SerialLine.Read(input, 0, input.Length);
            if (count > 0)
            {
                char[] chars = Encoding.UTF8.GetChars(input);
                string str = new string(chars, 0, count);
                Debug.Print(str);
                camera.TakePicture();                               
                Debug.Print("picture captured");
              
            }
        }
    }

Hello, is there any specific question behind?

I guess you are wondering: “Why it does not work as expected?”

Actually, I do not see where do you set the timer to be 5 second… May be the delay is coming from the size of your picture, May you resize it and see if if changes the delay.

I set the timer to 3 seconds.
Should I set the timer to 5 seconds because the remote xbee sending packet every 5 seconds?

GT.Timer timer = new GT.Timer(3000);

stupid question, how to resize the picture?

Thanks

T1 = Take a picture, T2= display to screen, how can I know T1+T2=?

            var startTime = DateTime.Now;
            var elapedTime = DateTime.Now.Subtract(startTime);

Measure time from the moment you start taking picture till the image gets displayed on the screen.

Dear Gralin:

Why the display shows the picture after 4 pictures captured ?
The time span is nearly 26 seconds.
Thanks.

Can you make a simple program that only captures one picture and displays it? Measure the time it takes and print it (don’t use breakpoint as it might slow it down). Also you could try something like this (sorry if it doesn’t compile but i was using notepad).

public partial class Program
{
	GT.Picture picture;
	AutoResetEvent pictureReady;
	
	void ProgramStarted()
	{
		pictureReady = new AutoResetEvent(false);
		
		camera.PictureCaptured += (s,p) => 
		{
			picture = p;
			pictureReady.Set();
		};
		
		var startTime = DateTime.Now;
		camera.TakePicture();
		pictureReady.WaitOne();
		display.SimpleGraphics.DisplayImage(picture, 5, 5);
		Debug.Print(DateTime.Now.Subtract(startTime));
	}
}

Dear Gralin:
I test your code.
The output shows "Camera ERROR : Unable to take picture. Camera is not ready. Is the Camera connected?"
But I think the camera is ok, because I can run my other application.
And I don’t understand what it mean “+= (s,p) =>”.
Thanks for your help.

This is called “Lambda Expression”. It is very powerful concept in programming.

You can start reading about it with this document:

I have no experience with Gadgeteer boards/modules but if the camera is not ready at the start maybe add some delay at the beginning or create a timer and make it trigger your code.

I use the button to test it.

It need 1.3 seconds for pushing the button, take the picture and shows on the display.

So the remote Xbee send a packet to the spider every 5 seconds then the spider takes the picture and shows the picture should be work in this time interval.
But it is not.
Something wrong in my code.
Maybe the problem is the timer?
I don’t know.

void camera_PictureCaptured(Camera sender, GT.Picture picture)
        {

            display.SimpleGraphics.DisplayImage(picture, 5, 5);
            var elapedTime = DateTime.Now.Subtract(startTime);

            Debug.Print(elapedTime.ToString());

        }
void button_ButtonPressed(Button sender, Button.ButtonState state)
        {
            startTime = DateTime.Now;
            camera.TakePicture();
            Debug.Print("picture captured");

        }

after several takes
Outputs are:
00:00:01.2963572
picture captured
00:00:01.3484455
picture captured
00:00:01.3134689
picture captured
00:00:01.4029222
picture captured
00:00:01.2387110
picture captured
00:00:01.3754618
picture captured
00:00:01.3860627
picture captured
00:00:01.3281295

What is the result of this:

public partial class Program
{
	GT.Timer timer = new GT.Timer(3000, GT.Timer.BehaviorType.RunOnce);
	
	void ProgramStarted()
	{
		timer.Tick += OnTimerTick;
		camera.PictureCaptured += OnPictureCaptured;
		timer.Start();
	}
	void OnPictureCaptured(Camera sender, GT.Picture picture)
	{
		display.SimpleGraphics.DisplayImage(picture, 5, 5);
	}

	void OnTimerTick(GT.Timer timer)
	{
		camera.TakePicture(); 
		timer.Restart();
	}
}

you need to always break down the testing of this kind of thing into modules.

Does the periodic sending of the signal from one device to the other, and only doing debug.prints, work reliably? If not, then fix that and then move forward.

Does a periodic “take picture” work reliably on a single board with the camera? If not, then work on that issue and then move forward. (remembering that there’s the big thread on “Type B” cameras and issues that are known to only allow cameras to take a few pics before going into a failure state).

Does a periodic “take picture and display” work reliably on that single board? Again, make that work reliably and then move forward.

Then, you have all the components working individually and you can mash them all together. Any issue you have mashing them is only caused by the mashing, not anything else, and is much easier to diagnose for both you and us.

Agree with Brett 100%

Thank you brett, I will check it under your comments. Thanks Gralin, I will test your code tomorrow.
My english is not very good so sometimes hard to explan exactly. My programming ability
is not so good also. Thank you all are patiently to help me.

Dear Gralin:
I use your code to modify my code.
It works now.
So the different is the timer.

Mine:

GT.Timer timer = new GT.Timer(3000);
timer.Tick += new GT.Timer.TickEventHandler(timer_Tick);

Yours:

GT.Timer timer = new GT.Timer(3000, GT.Timer.BehaviorType.RunOnce);
timer.Tick += OnTimerTick;

Why your timer works better?
What is the difference between these two timers?
I don’t know the theory.

Thanks.

Lin

Dear Gralin:

Thanks your driver.
I can combine Xbee and NRF24L01Plus using Domino and Spider to do a simple two hop transmitting. It demos a simple mixing networks.
I will put an example to the code share page.
My example works fine, but my programming skill is not very good.
So,could you help me to optimize the code, then I can put in the page. Maybe useful for some newbies.
If you could , how to send my code to you?
Thanks.

Timers invoke your code after given time no matter if the previous invoke already ended. This can cause errors when your invoked method takes more time then timer time. This is why i always set the timer to run only once and restart it at the end. This way i make sure i don’t get parallel calls to my method. In regular .NET you would use

new Timer(MyMethod,3000,-1);

The -1 in the third param informs the timer not to repeat after one invoke.

You will find my e-mail on my forum profile page. Feel free to send me the code and I’ll try to contribute.