- An integer representing the speed to drive the motors at
- An integer representing the time in seconds that the motors should run for the command.
In my first iteration of the project I "hard coded" a series of commands for the robot, i.e. fixed the motor speed and time values in a series of function calls, just to get an idea of the dynamics of the motor driver and motors. Once deployed to the Netduino I "started up" the robot by pressing the on board button; the Netduino is being powered by a 9v battery for testing the robot. The only shortcoming of this approach is that every time I wished to change the motor speed and / or time values for the function calls I needed to modify the code and redeploy it. I thought that since I had a 9 volt battery attached to the Netduino I could use the USB to serial port communication approach presented in the Forums by Hari to type in the paramters I wanted and have them stored in an array and then run a test to see how the robot performed. The idea was that after I input my parameters on the terminal program on my PC I could detach the USB/serial cable, put the robot on the floor, press the on board button to start things up and see how the robot performed. Well, it almost works.
Entering the desired parameters via the console program on my PC does work. They are stored in an array in memory on the Netduino and since I have the Netduino powered by a 9v battery, the array contents are preserved when I detach the USB/serial connection. The problem seems to come about when I attempt to start the Netduino using the on board button: nothing happens.
Running in debug mode I quickly discovered the following:
- At start up the event handler for the on board button is made and pressing the on board button produces the expected results.
- After I type in paramter values using the console program on my PC, the event handler for the on board button seems to become "unassigned."
The problem seems to be related to the fact that after I make the assignement for the on board button interrupt handler and then type in some data, the serial input class for reading the values I typed and echoing them back to the console program on the PC assigns an interrupt handler to read and write the serial data from the PC which results in my losing the event handler for the on board button.
I'm not sure what is causing this - my own lack of understanding of assigning interrupt handlers or some limitation of the Netduino, my feeling is that it is my loack of understanding. In any case the code for the program that defines the on board interrupt handler and the code for the USB/serial communication appears below.
Main Line Code:
using System; using System.IO.Ports; using System.Threading; using Microsoft.SPOT; using Microsoft.SPOT.Hardware; using SecretLabs.NETMF.Hardware; using SecretLabs.NETMF.Hardware.Netduino; namespace PoluluRobot_010 { public class Program { static SerialIinput serialInput = new SerialIinput(); static DualSerialMotorController motorController = new DualSerialMotorController(); static char[] operators = { ',', ';' }; static string[] operands; public static void Main() { SetupButton(); while (true) { string line = serialInput.ReadLine(); if (line.Length > 0) { Thread.Sleep(250); operands = line.Split(operators); serialInput.ClearBuffer(); } } } private static void SetupButton() { InterruptPort interruptPort = new InterruptPort(Pins.ONBOARD_SW1, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLow); interruptPort.OnInterrupt += new NativeEventHandler(interruptPort_OnInterrupt); } static void interruptPort_OnInterrupt(uint data1, uint data2, DateTime time) { motorController.Forward(Int32.Parse(operands[0].ToString()), Int32.Parse(operands[1].ToString())); motorController.TurnRight(Int32.Parse(operands[0].ToString())); motorController.Forward(Int32.Parse(operands[0].ToString()), Int32.Parse(operands[1].ToString())); motorController.Stop(); } } }
The code for the USB/Serial I/O is below. It is pretty much a copy of Hari's post and it works very nicely.
using System; using System.Threading; using System.IO.Ports; using System.Text; using Microsoft.SPOT; using SecretLabs.NETMF.Hardware.Netduino; namespace PoluluRobot_010 { class SerialIinput { static SerialPort serialPort; const int bufferMax = 1024; static byte[] buffer = new Byte[bufferMax]; static int bufferLength = 0; public SerialIinput(string portName = SerialPorts.COM2, int baudRate = 9600, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One) { serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits); serialPort.ReadTimeout = 50; // Set to 10ms. Default is -1?! serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived); serialPort.Open(); } private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { { int bytesReceived = serialPort.Read(buffer, bufferLength, bufferMax - bufferLength); if (bytesReceived > 0) { string line; line = "" + new string(Encoding.UTF8.GetChars(buffer)); Print(line.Substring(bufferLength)); bufferLength += bytesReceived; if (bufferLength >= bufferMax) throw new ApplicationException("Buffer Overflow. Send shorter lines, or increase lineBufferMax."); } } } //TODO: Need to prevent serialPort_DataReceived from clobberring buffer and bufferSize while we are processing buffer public string ReadLine() { string line = ""; { //-- Look for Return char in buffer -- for (int i = 0; i < bufferLength; i++) { //-- Consider EITHER CR or LF as end of line, so if both were received it would register as an extra blank line. -- if (buffer[i] == '\r' || buffer[i] == '\n') { buffer[i] = 0; // Turn NewLine into string terminator line = "" + new string(Encoding.UTF8.GetChars(buffer)); // The "" ensures that if we end up copying zero characters, we'd end up with blank string instead of null string. //Debug.Print("LINE: <" + line + ">"); bufferLength = bufferLength - i - 1; Array.Copy(buffer, i + 1, buffer, 0, bufferLength); // Shift everything past NewLine to beginning of buffer break; } } return line; } } public void Print(string line) { System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding(); byte[] bytesToSend = encoder.GetBytes(line); serialPort.Write(bytesToSend, 0, bytesToSend.Length); } public void PrintLine(string line) { Print(line + "\r"); } public void ClearBuffer() { for (int i = 0; i < bufferMax; i++) { buffer[i] = 0; } bufferLength = 0; } } }