In a previous post I had replaced a Netduino and Elecfreaks Joystick shield based remote control with a MikrobusNet Quail, thumbstick click and an nRF-C click. The next step was to replace the Netduino on the robot chassis with a MikrobusNet Quail, a pair of DC Motor Clicks and an nRF-C click.
Bill of materials (prices in USD as at Feb 2016)
The first version of the robot uses a pair of battery packs one for the motors the other for the Quail board.
The drivers developed by MikroBUSNet team greatly reduced the amount of code I had to write to get the robot to work.
public class Program
{
private static double Scale = 100.0;
private static byte RobotControlChannel = 10;
private static byte[] ControllerAddress = Encoding.UTF8.GetBytes("RC1");
private static byte[] RobotAddress = Encoding.UTF8.GetBytes("RB1");
private static TimeSpan MessageMaximumInterval = new TimeSpan(0, 0, 1);
private static DateTime _MessageLastReceivedAt = DateTime.UtcNow;
private static DCMotorClick motor1 = new DCMotorClick(Hardware.SocketOne);
private static DCMotorClick motor2 = new DCMotorClick(Hardware.SocketTwo);
public static void Main()
{
NRFC nrf = new NRFC(Hardware.SocketFour);
nrf.Configure(RobotAddress, RobotControlChannel);
nrf.OnTransmitFailed += nrf_OnTransmitFailed;
nrf.OnTransmitSuccess += nrf_OnTransmitSuccess;
nrf.OnDataReceived += nrf_OnDataReceived;
nrf.Enable();
Timer CommunicationsMonitorTimer = new Timer(CommunicationsMonitorTimerProc, null, 500, 500);
Thread.Sleep(Timeout.Infinite);
}
static void nrf_OnDataReceived(byte[] data)
{
Hardware.Led1.Write(true);
_MessageLastReceivedAt = DateTime.UtcNow;
if (data.Length != 5)
{
return;
}
Debug.Print("M1D=" + data[0].ToString() + " M2D=" + data[1].ToString() + " M1S=" + data[2].ToString() + " M2S=" + data[3].ToString());
if (data[0] == 1)
{
motor1.Move(DCMotorClick.Directions.Forward, (data[2] / Scale ));
}
else
{
motor1.Move(DCMotorClick.Directions.Backward, (data[2] / Scale ));
}
if (data[1] == 1)
{
motor2.Move(DCMotorClick.Directions.Forward, (data[3] / Scale ));
}
else
{
motor2.Move(DCMotorClick.Directions.Backward, (data[3] / Scale ));
}
}
private static void CommunicationsMonitorTimerProc(object status)
{
if ((DateTime.UtcNow - _MessageLastReceivedAt) > MessageMaximumInterval)
{
Debug.Print("Communications timeout");
motor1.Move(MBN.Modules.DCMotorClick.Directions.Forward, 0.0);
motor2.Move(MBN.Modules.DCMotorClick.Directions.Forward, 0.0);
}
}
I have kept the communications monitoring functionality which stops the motors when the robot gets out of range of the remote control software fails.