.NET Gadgeteer Bluetooth Control of Motor Driver

A previous example .NET Gadgeteer Motor Driver with Two Motors and Potentiometer demonstrated the GHI Electronics Motor Driver L298 module.  This post uses a similar code scenario, but in this case we control the motors from a serial console that sends messages to a GHI Bluetooth module on the device.  This example also demonstrates how to reverse direction of the motors.

The Bluetooth module in this example uses the beta driver implemented by Eduardo Velloso.  Eduardo’s solution contains the driver implementation project and a test project.  All the required sources are linked from: Eduardo Velloso completes Beta Driver for .NET Gadgeteer Bluetooth Module.

I used Windows Devices and Printers to discover the Bluetooth module and connect to it from Windows, but it took me a while to start sending messages to the .NET Gadgeteer device with the module.

The device code is pretty simple, assuming the connection is working.  The core of it reads data sent over the Bluetooth connection.  The following code block shows the Bluetooth.DataReceived event handler.  Comments in the code explain the syntax of commands that specify which motor to start and the speed and direction of the motor.

    void bluetooth_DataReceived(Bluetooth sender, string data)
    {
        Debug.Print("Received: " + data);

        // Data should be sent in form: motor:1 speed:75
        // Motor values: 1 or 2  Speed values: 0 - 99
        // Negative speed values will turn the motor in reverse direction.
        // Changing direction at high speed may damage motors or parts.

        int index = data.IndexOf("motor:");

        if (index != -1)
        {
            // parse the motor number from data.
            char c = data[index + 6];
            motorNumber = int.Parse(c.ToString());
        }

        index = data.IndexOf("speed:");
        if (index != -1)
        {
            // parse the speed value from data.
            speed = int.Parse(data.Substring(index + 6));
        }
    }

Making the Bluetooth Connection

We can add a Bluetooth device from the Devices and Printers of Windows 7 operating system, but the connection is useless without a way to send messages to the device.  I found a couple of libraries that are useful.  The library named 32feet.NET – Personal Area Networking for .NET  is apparently the best for .NET and C# development.  Eduardo recommended a serial console available from Seeed Studio.  Here is the download link: http://www.seeedstudio.com/forum/download/file.php?id=182&sid=e19ac1b35ae38f6ad5bbbf0391c7e3ca .  The link displayed on the running console goes to a page in Chinese.  The application works fine after a little experimentation.   Set the options: Baudrate: 38400, Databits: 8, and Stopbits: 1  as shown in the following illustration (click to enlarge).

SSCom 3.2 Serial Console

SSCom 3.2 Serial Console

The sequence of events while connecting may not be what you expect. Windows device discovery continues to prompt every time the Bluetooth device starts.  I had to use a PIN code to get the connection working with the device (see the following section with complete application code).

Using the Bluetooth Connection with the .NET Gadgeteer Device

Build the device using the complete application code as follows. Note that the the namespace Gadgeteer.Modules.Velloso contains the Bluetooth class. Do not add the GHI Bluetooth module to the .NET Gadgeteer Designer. Instead, create an instance of the Bluetooth class by calling its constructor in the ProgramStarted method.  Instantiate the Motor Driver L298 module and button module by dragging them onto the Designer surface.

using Microsoft.SPOT;

using GT = Gadgeteer;
using Gadgeteer.Modules.GHIElectronics;

using Gadgeteer.Modules.Velloso;

namespace BlueToothMotorControl
{
    public partial class Program
    {
        Bluetooth bluetooth;
        int motorNumber;
        GT.Timer timer;
        Bluetooth.Client client;
        int speed;

        void ProgramStarted()
        {
            bluetooth = new Bluetooth(9);
            client = bluetooth.ClientMode;
            bluetooth.SetDeviceName("gmdTestDevice");
            bluetooth.SetPinCode("1234");

            bluetooth.DataReceived += new Bluetooth.DataReceivedHandler(bluetooth_DataReceived);
            bluetooth.BluetoothStateChanged +=
                        new Bluetooth.BluetoothStateChangedHandler(bluetooth_BluetoothStateChanged);

            speed = 0;

            button.ButtonPressed += new Button.ButtonEventHandler(button_ButtonPressed);

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

            Debug.Print("Program Started");
        }

        void button_ButtonPressed(Button sender, Button.ButtonState state)
        {
            if (!button.IsLedOn)
            {
                timer.Start();
                button.TurnLEDOn();
            }
            else
            {
                timer.Stop();
                motorControllerL298.MoveMotor(MotorControllerL298.Motor.Motor1, 0);
                motorControllerL298.MoveMotor(MotorControllerL298.Motor.Motor2, 0);
                button.TurnLEDOff();
            }
        }

        void bluetooth_BluetoothStateChanged(Bluetooth sender, Bluetooth.BluetoothState btState)
        {
            if (btState == Bluetooth.BluetoothState.Connected)
            {
                client.Send("HELLO - sent by test module.");
            }
        }

        void bluetooth_DataReceived(Bluetooth sender, string data)
        {
            Debug.Print("Received: " + data);

            // Data should be sent in form: motor:1 speed:75
            // Motors: 1 or 2  with  speed: 0 - 100
            // Negative speed values will turn the motor in reverse direction.
            // Changing direction at high speed may damage motors or parts driven.

            int index = data.IndexOf("motor:");

            if (index != -1)
            {
                // parse the motor number from data.
                char c = data[index + 6];
                motorNumber = int.Parse(c.ToString());
            }

            index = data.IndexOf("speed:");
            if (index != -1)
            {
                // parse the speed value from data.
                speed = int.Parse(data.Substring(index + 6));
            }
        }

        void timer_Tick(GT.Timer timer)
        {
            if(button.IsLedOn)
            {
                if (motorNumber == 1)
                {
                    motorControllerL298.MoveMotor(MotorControllerL298.Motor.Motor1, speed);
                }
                else if (motorNumber == 2)
                {
                    motorControllerL298.MoveMotor(MotorControllerL298.Motor.Motor2, speed);
                }
            }
        }
    }
}

Build and run the .NET Gadgeteer device with the Motor Driver L298 and GHI Bluetooth module.  Windows will prompt you to initialize the Bluetooth connection and supply the PIN code specified by the line: bluetooth.SetPinCode(“1234”). If the serial console is already running when you start the device, you may have to do this repeatedly.  The COM Port (serial port) should be set automatically when you connect.  If you have to set the COM Port, it will probably be in the midst of reconnecting.

There should be evidence of communication between the serial console and the device, both on the console and in the debug output of the device running in Visual Studio.  After a few tests you’ll recognize the various strings that show in the console and in the debugger.

The button on the device turns the timer on and off, and it will light a LED on the button to indicate when the motors are receiving messages sent from the serial console.  When the timer is running,  use the Send button on the serial console with syntax such as: motor:1 speed:35.  To reverse the direction of the motor, send motor:1 speed:-10.  In many cases it is advisable to stop the motors before reversing direction.  Both motors can be stopped by pushing the button, which also turns off the LED on the button.

, , , ,

  1. .NET Gadgeteer Motor Driver with Two Motors and Potentiometer « Integral Design

Leave a comment