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)
- MikrosBUSNet Quail board USD49.00
- Mikros nRF-C click USD19.00
- DC Motor click x 2 USD18.00
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.