Code Optimization for Domino Data Acquisition?

I’m trying to use my FEZ Domino as a wireless data acquisition sensor.
I’m reading the analog values from a 3-axis accelerometer and sending the resulting data through an Xbee to a remote computer.
I want to sample as fast as possible. Based on the millisecond time stamp of the samples, I’m getting about 128 samples per second with the current code.

Take a look and any suggestions to optimize would be appreciated.


using System;
using System.Text;
using System.Threading;

using System.IO.Ports;

using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Hardware;

namespace FEZ_Domino_Accel
{
    public class Program
    {

        static AnalogIn accelY = new AnalogIn(AnalogIn.Pin.Ain0);
        static AnalogIn accelX = new AnalogIn(AnalogIn.Pin.Ain1);      
        static AnalogIn accelZ = new AnalogIn(AnalogIn.Pin.Ain2);

        static SerialPort xbeePort;
        static byte[] outBuffer;

        public static void Main()
        {
            accelX.SetLinearScale(-500, 500);
            accelY.SetLinearScale(-500, 500);
            accelZ.SetLinearScale(-500, 500);
            double accelXValue = 0;
            double accelYValue = 0;
            double accelZValue = 0;

            xbeePort = new SerialPort("COM1", 38400, Parity.None, 8, StopBits.One);
            xbeePort.Open();

            Debug.Print("GO!!");

            while (true)
            {
                accelXValue = accelX.Read();
                accelYValue = accelY.Read();
                accelZValue = accelZ.Read();
                outBuffer = Encoding.UTF8.GetBytes(DateTime.Now.Millisecond + "," + accelXValue.ToString() + "," + accelYValue.ToString() + "," + accelZValue.ToString() + "\n"); ;
                xbeePort.Write(outBuffer, 0, outBuffer.Length);
            }
        }



    }
}

Can you send non formated data and then on the PC you can format them?

The output from AnalogIn.Read() is an int. Why are you reading it into a double?

oh yes, I missed that! Why?

Mike,

Changed Double to Int. I was not thinking…
That change bumped me from 128 samples per second to 153.

Gus,

I know that ToString() is the next area to tackle.
Whats the quickest way to convert int’s to a byte array?

Use the method inside “Utilities” class from Microsoft…I can’t remember the name

You could also let the PC do the scaling.

Scaling is done natively and it is very efficient

Probably Utility.InsertValueIntoArray (for those following along)
http://msdn.microsoft.com/en-us/library/ee434354.aspx

Why try to do data collection and transmission in the same thread? My inclination would be to have one thread collecting data and saving it to a buffer and when the buffer is so full, write it out.

Hi… Very new to Fez & NETMF but not to C#. In the full .NET stuff, string concats are painful because they always create a new string, which means tons & tons of allocs for a project like this.

The Marshal class or even StringBuilder/string.Format would be a big help but since we don’t seem to have those, binary is the way to go if you really want speed.

I just ran this in the emulator…


byte[] bytes = new byte[5 * 4]; // 5 uints

DateTime start;
			
start = DateTime.Now;
for (int i = 0; i < 10000; i++)
{
	long ticks = DateTime.Now.Ticks;

	Utility.InsertValueIntoArray(bytes,  0, 4, (uint)(ticks & 0xFFFFFFFF));
	Utility.InsertValueIntoArray(bytes,  4, 4, (uint)(ticks >> 32));
	Utility.InsertValueIntoArray(bytes,  8, 4, 0x01); // todo: real x
	Utility.InsertValueIntoArray(bytes, 12, 4, 0x02); // todo: real y
	Utility.InsertValueIntoArray(bytes, 16, 4, 0x03); // todo: real z
	// todo: xbeePort.Write (bytes, 0, bytes.Length);
}

Debug.Print("elapsed: " + (DateTime.Now - start).ToString());


start = DateTime.Now;
for (int i = 0; i < 10000; i++)
{
	string str = DateTime.Now.Ticks.ToString() + "," +
		0.ToString() + "," + // todo: real x
		1.ToString() + "," + // todo: real y
		2.ToString() + "\n"; // todo: real z
	// todo: xbeePort.Write (...
}

Debug.Print("elapsed: " + (DateTime.Now - start).ToString());

The output:
elapsed: 00:00:01.6875000
elapsed: 00:00:09.0312500

Because this isn’t really doing anything like talking to an actual xbee, you probably won’t see a 5x performance improvement but for packing up the data, this is probably as fast as the stock netmf will let you do. (then again, again, I’m new to this)

Also, I think DateTime.Now.Millisecond gives you the number of ms into the current second so logging that will appear sorta random. The Ticks member is probably what you want there.