Main Site Documentation

Code Optimization for Domino Data Acquisition?


#1

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);
            }
        }



    }
}


#2

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


#3

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


#4

oh yes, I missed that! Why?


#5

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?


#6

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


#7

You could also let the PC do the scaling.


#8

Scaling is done natively and it is very efficient


#9

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


#10

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.


#11

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.