Best way to collect sentences from serial

I’m coding the driver for my 9DoF IMU, and the actual drier should be easy, but I am having a hard time getting NETMF to read complete sentences from the serial port.

So, first question is: What’s the best way to read sentances?

Method A is to simply subscribe to the data present event and proces that data that way.

Method B is to only try to read the serial port when a property’s getter is triggered (IE, at razor.Yaw).

Method A is bad because it will always be using processor time, regardless of whether or not I am actually using the readings it is working so hard to process.

Method B is bad because I’m having a very difficult time getting it to read the sentence.

I uploaded custom code to the IMU, so the data format is…
!,roll,pitch,yaw,;\n
(each comma separated token is sent individually, so it’s not as easy as coming down in one chunk)

My idea was to listen to serial until I found the \n, then try to parse it, but this is getting to be a real hassle.

Any ideas?

sorry if this is hard to read. It’s late, I’m tired ::slight_smile:

Hoi Chris,

Is this something you are already looked at?
[url]Google Code Archive - Long-term storage for Google Code Project Hosting.

It is for the Arduino but that does not need to be a problem is it not?

suc6
Niels

Hi Nielsnl,

That si the code that I am running on the IMU, or at least a slightly modified version. What I need to figure out is how best to read that data.

Owww sorry,
I was really sure it was the part that should be used on the Arduino and not on the IMU.

On many forum this google site was given when someone asked about how to use the IMU with there Arduino. So i expected it was the right code.
I’m no Arduino user and it did like to do what i was expecting from seeing parts of the code. But i did not do a fully code check.

I do some more research, because i want to buy that same board soon :smiley:

The board works pretty well and, as always, I will be releasing source code as I go along with it, so if you buy the same board it will be very easy for you to use it.

As far as I understand the UART, it will buffer the last 256 bytes (probably can be changed), and the rest will be lost. So if youre not constantly handling the input you have to flush the buffer and wait for the latest information.
So either you have to constantly deal with the input and have an object that constantly has the latest information, -or you have to flush the input and wait for a complete sentence.
If you can spare the processing time I would go for the constant handling and have an object that you can trust having the latest information. -If that doesnt work out, go for the forced flush / read approach.

Ok, so let’s assume that I am using the interrupt approach. What happens if I am handling the data when that same event fires? Will it fire if the event is currently being handled, or will it start in a new thread?

I would think that as long as you have a handler for the COM port, no new threads will be started. This thread will never stop and only use processing time as long as there is activity on the port.
Your open the port, attach a handler and forget about the processing going on in the background leaving you with an object always carrying the latest information.

Ok, that’s what I thought, but I wasn’t sure. I guess I’ll make another attempt at coding it tonight.

Chris one thing I am looking at doing is moving some of the navigation processing over to the second board and leaving the Domino in charge of driving and processing the sensor input (since that requires the absolute lowest latency to avoid crashes).

I’ll be moving the GPS and IMU over to the other board to handle all that processing - the advantage is since the second board is also the auto “kill switch” if it detects a rollover, end over end or other catastrophe (too many G’s etc) I can drop the heartbeat low and let the Domino kill power to the ESC.

Since the other board will be handling “macro” navigation (waypoint acquisition and navigation) it frees up the Domino to pay attention to what I really want it doing, handling the engine, the steering and the sensors to prevent crashes (or at least try to).

What I’m trying to work out now is communication between the two boards since I’m out of UARTs – might have to look into that - because I’ll need the two boards talking to each other not just because of the killswitch (easy with a single pin) but also for steering information from the navigation subsystem.

Hi Greg,

I was going to do exactly the same thing, but the IMU was going to be hooked u pthe the Domino, which will be handling navigation and GPS. The Netduino will be handling everything else.

As for code, I now have this:

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.IO.Ports;
using System.Threading;

namespace Razor_9DoF_API
{
	class Razor_9DoF
	{
		/// <summary>
		/// The Serial Port handle for the Razor
		/// </summary>
		private SerialPort _Razor;

		/// <summary>
		/// 
		/// </summary>
		private double grad2rad = 3.141592/180.0;

		/// <summary>
		/// Yaw degrees 
		/// </summary>
		public double Yaw
		{
			get
			{
				return raws[2];
			}
		}

		/// <summary>
		/// Keep the values here until we process them
		/// </summary>
		private double[] raws = new double[3];

		/// <summary>
		/// Construct, set the recv event, bind the serial handle
		/// </summary>
		/// <param name="razorPort"></param>
		public Razor_9DoF(string razorPort)
		{
			// Bind the serial port
			_Razor = new SerialPort(razorPort, 57600);

			// Options..
			_Razor.ReadTimeout = 0;

			// Open the port
			_Razor.Open();

			// Set the event handler
			_Razor.DataReceived += new SerialDataReceivedEventHandler(_Razor_DataReceived);
		}

		void _Razor_DataReceived(object sender, SerialDataReceivedEventArgs e)
		{
			// Create the buffer
			byte[] buffer = new byte[50];

			// Read the serial buffer
			_Razor.Read(buffer, 0, buffer.Length);

			// Get one sentence (Yes, I know, FUGLY!)
			string[] recv = bytesToString(buffer).Split('\n')[0].Split(',');

			// If it's complete, process it
			if (recv.Length > 4)
			{
				// Loop through the values in the sentence, parse 
				// them and add them to the raws array
				for (int i = 1; i <= 3; i++)
					raws[i - 1] = double.Parse(recv[i]);
			}
		}

		/// <summary>
		/// Turn a byte array into a string
		/// </summary>
		/// <param name="bytes"></param>
		/// <returns></returns>
		public string bytesToString(byte[] bytes)
		{
			string s = "";

			// Loop through the bytes in the arry and cast the values as chars,
			// then append them to the string
			for (int i = 0; i < bytes.Length; ++i)
				s += (char)bytes[i];

			return s;
		}
	}
}

The only thing is that I need help doing the post processing on the values it picks. I filled in the overloaded property “Yaw” which will be post processed to return degrees (0-360). Anybody better in math than I have any good ideas on how to do this?

Yeah I’m stil thinking the Domino will be doing the driving (ESC and servo control) and handling the collision avoidance sensors (sonar & IR). I’ll feed navigation commands to the Domino from the Netduino via PWM and have the GPS and IMU plugged in over there.

My only problem (again) is UARTs dangit.

Well that and my truck doesn’t arrive until tomorrow. :stuck_out_tongue:

For bearings Chris I’m thinking about throwing a HMC6343 onto the bot since it has the PIC built in to spit out current bearing in degrees automatically. Plus its tilt-compensated.

Right now, I need someone to help with some of the math. I’m gettign really confused as to what exactly the IMU is sending, and there is very little documentation that I can find on it (RE: None)

All of the data processing is totally done, I just need to write the post processing stuff.

Have you looked a the python code

Yes. It converts the degrees to radians then does some weird math to point the arrow.