Hello,
Since we can see many drivers coded by many people, I was wondering if some rules should/could not be applied to such drivers.
My idea would consist in providing “Interfaces” that driver class should implement. These interfaces would contain the minimal set of methods/properties the driver has to implement, so that the same program could use different drivers by only changing some declaration in its source.
Let me give an example, to be more explicit. Here’s what the interfaces could look like :
namespace FEZInterfaces
{
public enum ElcdCursorShape { Full, Line, None}
public enum ElcdCursorKind { Steady, Blink }
public interface ICommon
{
string Author { get; }
System.Version DriverVersion { get; }
}
public interface IStepper : ICommon
{
long CurrentPosition { get; set; }
long TargetPosition { get; set; }
bool IsMoving { get; }
bool Move(long destPosition);
void Stop();
}
public interface ILcd : ICommon
{
byte MaxCol { get; }
byte MaxRow { get; }
void Print(byte xCol, byte yRow, string text);
void SetCursor(ElcdCursorShape newShape, ElcdCursorKind newKind);
void SetCursor(byte[] byteArray);
}
}
Then, if I implement a driver for the EasyDriver stepper controler, I would code like this :
using System;
using FEZInterfaces;
namespace EasyDriver
{
public class EasyDriverV4 : IStepper
{
public long CurrentPosition
{
get { return 10; }
set { throw new NotImplementedException(); }
}
public long TargetPosition
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public bool IsMoving
{
get { throw new NotImplementedException(); }
}
public bool Move(long destPosition)
{
throw new NotImplementedException();
}
public void Stop()
{
throw new NotImplementedException();
}
public string Author
{
get { return "Christophe Gerbier"; }
}
public Version DriverVersion
{
get { return new Version(1,2); }
}
}
}
Another stepper driver for the Phidget1062 controler could look like this one :
using System;
using FEZInterfaces;
namespace Phidget1062
{
public class Phidget1062Stepper : IStepper
{
public long CurrentPosition
{
get { return 123; }
set { throw new NotImplementedException(); }
}
public long TargetPosition
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public bool IsMoving
{
get { throw new NotImplementedException(); }
}
public bool Move(long destPosition)
{
throw new NotImplementedException();
}
public void Stop()
{
throw new NotImplementedException();
}
public long AccelerationMax
{
get { return 100; }
}
public string Author
{
get { return "Christophe Gerbier"; }
}
public Version DriverVersion
{
get { return new Version(2, 0); }
}
}
}
Then an LCD driver for the Devantech LCD03 could look like this :
using System;
using Microsoft.SPOT;
using FEZInterfaces;
namespace DevantechLCD03
{
public class LCD03 : ILcd
{
public byte MaxCol
{
get { throw new NotImplementedException(); }
}
public byte MaxRow
{
get { throw new NotImplementedException(); }
}
public void Print(byte xCol, byte yRow, string text)
{
throw new NotImplementedException();
}
public void SetCursor(ElcdCursorShape newShape, ElcdCursorKind newKind)
{
Debug.Print("Setting cursor");
}
public void SetCursor(byte[] byteArray)
{
// No custom shape available so throw exception
throw new NotImplementedException();
}
public string Author
{
get { return "Christophe Gerbier"; }
}
public Version DriverVersion
{
get { return new Version(1, 0); }
}
}
}
Finally, the “real” program using such drivers would look like :
using System;
using Microsoft.SPOT;
using EasyDriver;
using Phidget1062;
using DevantechLCD03;
namespace FEZ_Domino_Application1
{
public class Program
{
static EasyDriverV4 Stepper1 = new EasyDriverV4();
static Phidget1062Stepper Stepper2 = new Phidget1062Stepper();
static LCD03 MyLCD = new LCD03();
public static void Main()
{
Debug.Print("EasyDriver stepper position : "+Stepper1.CurrentPosition);
Debug.Print("Phidget1062 stepper position : " + Stepper2.CurrentPosition);
Debug.Print("Phidget1062 acceleration max : "+Stepper2.AccelerationMax);
try
{
MyLCD.Print(5,2,"Some text");
MyLCD.SetCursor(new byte[8]{1,2,3,4,5,6,7,8});
}
catch (Exception)
{
Debug.Print("Command not available");
}
}
}
}
As you can see, the same command (method) is used with both stepper drivers to get the actual position of the motor. Here, I have included both drivers for the example.
Also, the Phidget1062 driver has an extra property that is not part of the standard interface : AccelerationMax.
Of course, these are all examples, to show you what I have in mind. Interfaces are not complete at all nor they are good “as-is”. But I think that having such “rules” to follow when coding drivers may help coding programs with different devices without having to worry about it.
Interfaces content could be decided and validated by the community.
Do you understand what I want to say ? Am I wrong or not ? Do you find it useful or useless ? :-[
[italic]Edit:[/italic]
the “NotImplementedException” is here because I didn’t want to code real drivers. The real properties/methods should do real work, of course