Generic Step Motor WebInterface - control a step motor using a Pololu A4983 driver from a webinterface (EXPERIMENTAL PROTOTYPE - just to be used as a proof-of-concept for a IoT talk, will not be updating this code so often)

Dependencies:   EthernetNetIf RPCInterface mbed HTTPServer

Files at this revision

API Documentation at this revision

Comitter:
botdream
Date:
Mon Apr 16 09:41:53 2012 +0000
Commit message:

Changed in this revision

A4983StepMotorDriver/A4983.c Show annotated file Show diff for this revision Revisions of this file
A4983StepMotorDriver/A4983.h Show annotated file Show diff for this revision Revisions of this file
CmdListObjects/TList.cpp Show annotated file Show diff for this revision Revisions of this file
CmdListObjects/TList.h Show annotated file Show diff for this revision Revisions of this file
CmdListObjects/TObjects.h Show annotated file Show diff for this revision Revisions of this file
Libs/EthernetNetIf.lib Show annotated file Show diff for this revision Revisions of this file
Libs/HTTPServer.lib Show annotated file Show diff for this revision Revisions of this file
Libs/RPCInterface.lib Show annotated file Show diff for this revision Revisions of this file
Libs/mbed.bld Show annotated file Show diff for this revision Revisions of this file
index.html.cpp Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/A4983StepMotorDriver/A4983.c	Mon Apr 16 09:41:53 2012 +0000
@@ -0,0 +1,195 @@
+//---------------------------------------------------------------------------------------------
+#include "mbed.h"
+#include "A4983.h"
+//---------------------------------------------------------------------------------------------
+// Pins configuration
+//---------------------------------------------------------------------------------------------
+//LEDs port definition on mbed
+DigitalOut myled1(LED1);
+DigitalOut myled2(LED2);
+DigitalOut myled3(LED3);
+DigitalOut myled4(LED4);
+
+//ports connected to pololu driver board = straightforward connection of one side of mbed
+DigitalOut Dir(p23); //direction of movement
+DigitalOut Step(p24); //make one step at rising edge
+DigitalOut nSleep(p25); // be HIGH to make it work
+DigitalOut nReset(p26); // be HIGH to make it work
+DigitalOut MS3(p19); //microstep mode selectors
+DigitalOut MS2(p18);
+DigitalOut MS1(p17);
+DigitalOut nEnable(p27);// be LOW to make it work
+
+#define HIGH 1
+#define LOW 0
+#define ON 1
+#define OFF 0
+#define Clockwise LOW
+#define CounterClockwise HIGH
+
+//which mode of driver to be used. This is now 1/16 stepping.
+#define Factor  16
+//---------------------------------------------------------------------------------------------
+// USB serial port setup - debug messages
+//---------------------------------------------------------------------------------------------
+Serial pc(USBTX, USBRX); // tx, rx  
+//---------------------------------------------------------------------------------------------  
+
+//---------------------------------------------------------------------------------------------  
+// constructor
+//---------------------------------------------------------------------------------------------
+A4983::A4983()
+{
+  //set communication speed
+  pc.baud(115200);
+  //test to see if comm is working
+  printf("\r\nInitialize MBED Serial Port!\r\n");
+  
+  myled1 = 0;
+  myled2 = 0;
+  myled3 = 0;
+  myled4 = 0;
+
+  //-------------------------------------------------------------------------------------------
+  // adjust microstepping mode
+  adjust_microstepping_mode(16);
+
+  // initialisation of power stage
+  Dir = CounterClockwise;
+  Step = LOW;
+  nSleep = HIGH;
+  nEnable = HIGH;
+  nReset = LOW;
+  myled1 = 1;
+  myled2 = 0;
+  myled3 = 0;
+  myled4 = 0;
+
+  wait(0.5);
+
+  nReset = HIGH;
+  myled1 = 0;
+  myled2 = 1;
+  myled3 = 0;
+  myled4 = 0;
+
+  wait(0.5);
+
+  nEnable = LOW;
+  myled1 = 1;
+  myled2 = 1;
+  myled3 = 0;
+  myled4 = 0;
+
+  wait(0.5);
+
+  Step = HIGH;
+  myled1 = 0;
+  myled2 = 0;
+  myled3 = 1;
+  myled4 = 0;
+
+  wait(0.5);
+
+  Step = LOW;
+  myled1 = 1;
+  myled2 = 0;
+  myled3 = 1;
+  myled4 = 0;
+
+  wait(0.5);
+  //-------------------------------------------------------------------------------------------
+ 
+  f_motor_enable = 0;    // flag to Enable/Disable Step Motor, 0 => Disable, 1 => Enable
+  f_motor_direction = 0; // flag for the Step Motor direction, 0 => Normal, 1 => Inverted
+  k_delay = 0.001;       // delay constant in seconds (Step Motor Speed)
+}
+//---------------------------------------------------------------------------------------------
+void A4983::adjust_microstepping_mode(uint8_t factor)
+{
+  if(factor==1)
+  {
+    MS1 = LOW;
+    MS2 = LOW;
+    MS3 = LOW;  // 1/1
+  }
+  else if(factor==2)
+  {
+    MS1 = HIGH;
+    MS2 = LOW;
+    MS3 = LOW;  // 1/2
+  }    
+  else if(factor==4)
+  {
+    MS1 = LOW;
+    MS2 = HIGH;
+    MS3 = LOW;  // 1/4
+  }
+  else if(factor==8)
+  { 
+    MS1 = HIGH;
+    MS2 = HIGH;
+    MS3 = LOW;  // 1/8
+  }
+  else if(factor==16)
+  {
+    MS1 = HIGH;
+    MS2 = HIGH;
+    MS3 = HIGH; // 1/16
+  }
+}
+//---------------------------------------------------------------------------------------------
+// Step function
+//---------------------------------------------------------------------------------------------
+void A4983::singlestep()
+{
+  if(Dir != f_motor_direction)
+    Dir = f_motor_direction;
+       
+  Step = HIGH;
+  wait(k_delay/2);
+
+  Step = LOW;
+  wait(k_delay/2);
+}
+//---------------------------------------------------------------------------------------------
+// Release Motor Command
+//---------------------------------------------------------------------------------------------
+void A4983::sleep(bool value)
+{
+  if(value == true)
+  {
+    //nEnable = LOW;
+    nSleep = LOW;
+  }
+  else
+  {
+    //nEnable = HIGH;
+    nSleep = HIGH; 
+  }
+}
+//---------------------------------------------------------------------------------------------
+// check if f_motor_enable is true and call singlestep() - loop mode
+//---------------------------------------------------------------------------------------------
+void A4983::looprun()
+{
+  if(f_motor_enable == 1)  
+  {    
+    singlestep();
+  }  
+}
+//---------------------------------------------------------------------------------------------
+// enable loop mode
+//---------------------------------------------------------------------------------------------
+void A4983::loopstart()
+{
+  f_motor_enable = 1;
+}
+//---------------------------------------------------------------------------------------------
+// disable loop mode
+//---------------------------------------------------------------------------------------------
+void A4983::loopstop()
+{
+  f_motor_enable = 0;
+}
+//---------------------------------------------------------------------------------------------
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/A4983StepMotorDriver/A4983.h	Mon Apr 16 09:41:53 2012 +0000
@@ -0,0 +1,28 @@
+//---------------------------------------------------------------------------------------------
+// Class to interface Pololu A4983 Stepper Motor Driver
+// http://www.coolcomponents.co.uk/catalog/product_info.php?products_id=358&currency=EUR
+// https://www.pololu.com/file/download/a4983_DMOS_microstepping_driver_with_translator.pdf?file_id=0J199
+//---------------------------------------------------------------------------------------------
+class A4983
+{
+  //-------------------------------------------------------------------------------------------
+  private:
+  //-------------------------------------------------------------------------------------------
+  
+  //-------------------------------------------------------------------------------------------
+  public:
+  //-------------------------------------------------------------------------------------------
+  uint8_t  f_motor_enable;             // flag to Enable/Disable Step Motor, 0 => Disable, 1 => Enable
+  uint8_t  f_motor_direction;          // flag for the Step Motor direction, 0 => Normal, 1 => Inverted
+  float    k_delay;                    // delay constant in seconds (Step Motor Speed) [0.0001;0.000025]
+  //-------------------------------------------------------------------------------------------
+  A4983();
+
+  void adjust_microstepping_mode(uint8_t factor);
+  void singlestep();
+  void sleep(bool value);
+  void looprun();
+  void loopstart();
+  void loopstop();
+};
+//---------------------------------------------------------------------------------------------
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CmdListObjects/TList.cpp	Mon Apr 16 09:41:53 2012 +0000
@@ -0,0 +1,181 @@
+//---------------------------------------------------------------------------------------------
+#include "TList.h"
+//---------------------------------------------------------------------------------------------
+//#define internaldebug // send debug messages to USB Serial port (9600,1,N)
+//---------------------------------------------------------------------------------------------
+uint8_t ListCount; // Global TList counter
+//---------------------------------------------------------------------------------------------
+TList *pListFirst;
+TList *pListLast;
+//---------------------------------------------------------------------------------------------
+// Main TList demo code
+//---------------------------------------------------------------------------------------------
+/*
+  // temporary TList object
+  TList *pListPointer;
+  
+  pListPointer = SetListNextObject();
+  TObjectStep *pobjectstep = new TObjectStep(1000, 100, 0);
+  pListPointer->cmdtype = 0x01;
+  pListPointer->cmdobject = (TObjectStep*)pobjectstep;
+ 
+  pListPointer = SetListNextObject();  
+  TObjectWait *pobjectwait = new TObjectWait(750);
+  pListPointer->cmdtype = 0x04;
+  pListPointer->cmdobject = (TObjectWait*)pobjectwait;  
+  
+  pListPointer = SetListNextObject();
+  TObjectStep *pobjectstep1 = new TObjectStep(2500, 150, 1);
+  pListPointer->cmdtype = 0x01;
+  pListPointer->cmdobject = (TObjectStep*)pobjectstep1;
+
+  pListPointer = SetListNextObject();  
+  TObjectWait *pobjectwait2 = new TObjectWait(225);
+  pListPointer->cmdtype = 0x04;
+  pListPointer->cmdobject = (TObjectWait*)pobjectwait2;    
+  
+  #ifdef internaldebug  
+    // set pListPointer to the first object of the list
+    pListPointer = GetListFirstObject();
+    TObjectStep *ptemp = static_cast<TObjectStep*>(pListPointer->cmdobject);  
+    printf("ObjectsStep(%d) %ld|%ld|%d\r\n",ptemp->typecode,ptemp->nsteps, ptemp->deltatime, ptemp->direction);
+   
+    pListPointer = pListPointer->nextobject;
+    TObjectWait *ptemp2 = static_cast<TObjectWait*>(pListPointer->cmdobject);  
+    printf("ObjectsWait(%d) %ld\r\n",ptemp2->typecode,ptemp2->waittime);   
+    
+    pListPointer = pListPointer->nextobject;
+    ptemp = static_cast<TObjectStep*>(pListPointer->cmdobject);  
+    printf("ObjectsStep(%d) %ld|%ld|%d\r\n",ptemp->typecode,ptemp->nsteps, ptemp->deltatime, ptemp->direction);    
+    
+    pListPointer = pListPointer->nextobject;
+    TObjectWait *ptemp3 = static_cast<TObjectWait*>(pListPointer->cmdobject);  
+    printf("ObjectsWait(%d) %ld\r\n",ptemp3->typecode,ptemp3->waittime);               
+  #endif
+  
+  printf("ListCount=%d\r\n",GetListCount());
+
+  // deleting list elements and internal objects
+  while(DeleteListFirstObject() != 0);
+  
+  printf("ListCount=%d\r\n",GetListCount());
+*/
+//---------------------------------------------------------------------------------------------
+// Global helper function
+//---------------------------------------------------------------------------------------------
+uint8_t GetListCount()
+{
+  return ListCount;
+}
+//---------------------------------------------------------------------------------------------
+TList *GetListFirstObject()
+{
+  return pListFirst;
+}
+//---------------------------------------------------------------------------------------------
+uint8_t DeleteListFirstObject()
+{
+  // verify if First Object is NULL
+  if(pListFirst == NULL)
+    return 0; //nothing to delete
+  
+  TList *ptemp = pListFirst->nextobject;
+  if(ptemp == NULL) // first object doesn't link with other objects (unique)
+  {
+    #ifdef internaldebug      
+        printf("Deleting Unique Object\r\n");
+    #endif    
+
+    // removes inner object first
+    delete pListFirst->cmdobject;
+    pListFirst->cmdobject = NULL;
+    
+    #ifdef internaldebug      
+        printf("->removing inner object\r\n");
+    #endif    
+    
+    // removes the outter list object
+    delete pListFirst;
+    pListFirst = NULL;
+    pListLast = NULL;
+
+    #ifdef internaldebug      
+        printf("->removing outter object\r\n");
+    #endif    
+    
+    // no more objects - resets the list counter
+    ListCount = 0;
+    
+    #ifdef internaldebug      
+        printf("->reseting Listcount\r\n");
+    #endif    
+    
+  }
+  else
+  {
+    #ifdef internaldebug      
+        printf("Deleting first object of List[%d]\r\n",ListCount);
+    #endif    
+
+    // removes inner object first
+    delete pListFirst->cmdobject;
+    pListFirst->cmdobject = NULL;
+    
+    #ifdef internaldebug      
+        printf("->removing inner object\r\n");
+    #endif    
+    
+    // removes the outter list object
+    delete pListFirst;
+    pListFirst = NULL;
+    
+    #ifdef internaldebug      
+        printf("->removing outter object\r\n");
+    #endif    
+    
+    // sets the new header object
+    pListFirst = ptemp; 
+    
+    #ifdef internaldebug      
+        printf("->Setting new header object\r\n");
+    #endif    
+    
+    // decreases list counter
+    ListCount -= 1;
+    
+    #ifdef internaldebug      
+        printf("->Setting ListCount new value = %d\r\n",ListCount);
+    #endif    
+    
+  }
+  return 1;
+}
+//---------------------------------------------------------------------------------------------
+TList *SetListNextObject()
+{  
+  if(ListCount == 0)
+  {
+    // List is empty - initialize list
+    pListFirst = new TList;
+    pListLast = pListFirst;
+    pListFirst->nextobject = NULL;    
+    
+    ListCount++;
+  }
+  else
+  {
+    // list not empty, adds new object to the list and point the 'nextobject' 
+    // from previous object to the recently created object
+    TList *ptemp = new TList;
+    ptemp->nextobject = NULL;
+    
+    pListLast->nextobject = ptemp;
+    
+    pListLast = ptemp;
+    
+    ListCount++;
+  }
+  
+  return pListLast;
+}  
+//---------------------------------------------------------------------------------------------
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CmdListObjects/TList.h	Mon Apr 16 09:41:53 2012 +0000
@@ -0,0 +1,23 @@
+//---------------------------------------------------------------------------------------------
+#include "mbed.h"
+//---------------------------------------------------------------------------------------------
+class TList
+{
+  private:
+  
+  public:
+  TList *nextobject;
+  
+  uint8_t cmdtype;
+  void *cmdobject;   
+  
+  TList(){};  
+};
+//---------------------------------------------------------------------------------------------
+// Global helper function
+//---------------------------------------------------------------------------------------------
+uint8_t GetListCount();
+TList *GetListFirstObject();
+uint8_t DeleteListFirstObject();
+TList *SetListNextObject(); 
+//---------------------------------------------------------------------------------------------
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CmdListObjects/TObjects.h	Mon Apr 16 09:41:53 2012 +0000
@@ -0,0 +1,52 @@
+//---------------------------------------------------------------------------------------------
+#include "mbed.h"
+//---------------------------------------------------------------------------------------------
+#define internaldebug
+//---------------------------------------------------------------------------------------------
+class TObjects
+{
+  private:
+ 
+  public:
+
+  TObjects();  
+};
+//---------------------------------------------------------------------------------------------
+
+class TObjectStep
+{
+  private:
+ 
+  public:
+  static const uint8_t typecode = 0x01;
+  uint32_t nsteps;
+  uint32_t deltatime;
+  uint8_t direction;
+  
+  TObjectStep(uint32_t insteps, uint32_t ideltatime, uint8_t idirection)
+  {
+    nsteps = insteps;
+    deltatime = ideltatime;
+    direction = idirection;
+    
+  #ifdef internaldebug
+    printf("->->TObjectStep(%d,%d,%d).\r\n",nsteps,deltatime,direction);    
+  #endif     
+  };  
+};
+//---------------------------------------------------------------------------------------------
+
+class TObjectWait
+{
+  private:
+ 
+  public:
+  static const uint8_t typecode = 0x04;
+  uint32_t waittime;
+    
+  TObjectWait(uint32_t iwaittime)
+  {
+    waittime = iwaittime;
+  };  
+};
+//---------------------------------------------------------------------------------------------
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/EthernetNetIf.lib	Mon Apr 16 09:41:53 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/donatien/code/EthernetNetIf/#bc7df6da7589
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/HTTPServer.lib	Mon Apr 16 09:41:53 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/donatien/code/HTTPServer/#d753966e4d97
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/RPCInterface.lib	Mon Apr 16 09:41:53 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/MichaelW/code/RPCInterface/#a9e2c45097c8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/mbed.bld	Mon Apr 16 09:41:53 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/index.html.cpp	Mon Apr 16 09:41:53 2012 +0000
@@ -0,0 +1,112 @@
+/*
+<html>
+<head>
+<script type="text/javascript">
+function sendrequest(request_uri)
+{
+  var xmlhttp;
+  if(window.XMLHttpRequest)
+  {// code for IE7+, Firefox, Chrome, Opera, Safari
+    xmlhttp=new XMLHttpRequest();
+  }
+  else
+  {// code for IE6, IE5
+    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
+  }
+  xmlhttp.onreadystatechange=function()
+  {
+    if (xmlhttp.readyState==4 && xmlhttp.status==200)
+    {
+      <!-- document.getElementById("myDiv").innerHTML=xmlhttp.responseText; -->
+    }
+  }
+  console.log(request_uri);
+  xmlhttp.open("GET",request_uri,true);
+  xmlhttp.send();
+}
+
+function adjustvalues1(){
+  var dataval = document.getElementById("timevalue1").value;
+  
+  document.getElementById("timevalue2").value = dataval*1000;
+  
+  document.getElementById("timevalue3").value = dataval*1000*1000;
+}
+
+function adjustvalues2(){
+  var dataval = document.getElementById("timevalue2").value;
+  
+  document.getElementById("timevalue1").value = dataval/1000;
+  
+  document.getElementById("timevalue3").value = dataval*1000;
+}
+
+function adjustvalues3(){
+  var dataval = document.getElementById("timevalue3").value;
+  
+  document.getElementById("timevalue1").value = dataval/1000/1000;
+  
+  document.getElementById("timevalue2").value = dataval/1000;
+}
+
+function demo(){
+  // set timer to 100ms
+  sendrequest('./rpc/delay/write%20'+(100/1000000));
+
+  // set direction 0
+  sendrequest('./rpc/direction/write%200');
+  
+  // 360 º
+  sendrequest('./rpc/nsteps/run%20'+(1*64*50));
+  
+  // set direction 1
+  sendrequest('./rpc/direction/write%201');
+
+  // set timer to 200ms
+  sendrequest('./rpc/delay/write%20'+(200/1000000));
+
+  // 360 º
+  sendrequest('./rpc/nsteps/run%20'+(1*64*50));
+}
+</script>
+</head>
+<body>
+
+<div id="myDiv"><h2>Step Motor HTTP REST (RPC) interface.</h2></div>
+<button type="button" onclick="sendrequest('./rpc/enable/write%201')">Start Autorun</button>
+<button type="button" onclick="sendrequest('./rpc/enable/write%200')">Stop Autorun</button>
+<!--<button type="button" onclick="sendrequest('./rpc/releasecmd')">Release Motor CMD</button>-->
+<br>
+<button type="button" onclick="sendrequest('./rpc/sleepmode/run%2001')">Sleep</button>
+<button type="button" onclick="sendrequest('./rpc/sleepmode/run%2000')">Wake up</button>
+<br>
+<button type="button" onclick="sendrequest('./rpc/stepmode/run%201')">MicroStep Mode</button>
+<button type="button" onclick="sendrequest('./rpc/stepmode/run%200')">FullStep Mode</button>
+<br>
+<button type="button" onclick="sendrequest('./rpc/direction/write%200')">Normal Direction</button>
+<button type="button" onclick="sendrequest('./rpc/direction/write%201')">Inverse Direction</button>
+<br>
+<input type="text" id="timevalue1" name="timevalue1" onKeyUp="adjustvalues1();" maxlength="10" size="10" value="0.001" />
+<button type="button" onclick="sendrequest('./rpc/delay/write%20'+timevalue.value)">Time value (Seconds)</button>
+<br>
+<input type="text" id="timevalue2" name="timevalue2" onKeyUp="adjustvalues2()" maxlength="10" size="10" value="1" />
+<button type="button" onclick="sendrequest('./rpc/delay/write%20'+(timevalue2.value/1000))">Time value (mili-Seconds)</button>
+<br>
+<input type="text" id="timevalue3" name="timevalue3" onKeyUp="adjustvalues3()" maxlength="10" size="10" value="1000" />
+<button type="button" onclick="sendrequest('./rpc/delay/write%20'+(timevalue3.value/1000000))">Time value (micro-Seconds)</button>
+<br>
+<br>
+<input type="text" id="nmicrosteps" name="nmicrosteps" maxlength="10" size="10" value="1" />
+<button type="button" onclick="sendrequest('./rpc/nsteps/run%20'+nmicrosteps.value)">Manual MicroSteps</button>
+<br>
+<input type="text" id="nsteps" name="nsteps" maxlength="10" size="10" value="1" />
+<button type="button" onclick="sendrequest('./rpc/nsteps/run%20'+(nsteps.value*16))">Manual Steps</button>
+<br>
+<input type="text" id="nsteps360" name="nsteps360" maxlength="10" size="10" value="1" />
+<button type="button" onclick="sendrequest('./rpc/nsteps/run%20'+(nsteps360.value*16*200))">Manual Step 360º</button>
+<br>
+<br>
+<!-- <button type="button" onclick="demo()">Demo</button> -->
+</body>
+</html>
+*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Apr 16 09:41:53 2012 +0000
@@ -0,0 +1,336 @@
+/* //---------------------------------------------------------------------------------------------
+// disable/enable auto-run
+http://192.168.1.100/rpc/enable/write%200
+http://192.168.1.100/rpc/enable/write%201
+
+// normal/inverse direction
+http://192.168.1.100/rpc/direction/write%200
+
+// timer delay - motor speed
+http://192.168.1.100/rpc/delay/write%200.00001 (default)
+http://192.168.1.100/rpc/delay/write%200.0000025 (max)
+
+http://192.168.1.100/rpc/delay/write%200.00048 (super slow)
+
+// RPC number of steps
+http://192.168.1.100/rpc/nsteps/run%2016 (16 microsteps => 1 step)
+http://192.168.1.100/rpc/nsteps/run%203200 (200 Steps -> 360&#65533;)
+
+// RPC StepCmd
+http://192.168.1.100/rpc/stepcmd/run%201000%20100%201
+
+// RPC StepMode
+http://192.168.1.100/rpc/stepmode/run%200
+http://192.168.1.100/rpc/stepmode/run%201
+
+//Sleep mode
+http://192.168.1.100/rpc/sleepmode/run%200
+http://192.168.1.100/rpc/sleepmode/run%201
+
+//---------------------------------------------------------------------------------------------
+// resources
+//---------------------------------------------------------------------------------------------
+http://mbed.org/handbook/C-Data-Types
+http://mbed.org/cookbook/RPC-Interface-Library
+http://mbed.org/cookbook/HTTP-Server
+http://mbed.org/cookbook/Ethernet
+http://mbed.org/handbook/Ticker
+//--------------------------------------------------------------------------------------------- */
+#include "mbed.h"
+#include "EthernetNetIf.h"
+#include "HTTPServer.h"
+#include "RPCVariable.h"
+#include "RPCFunction.h"
+#include "A4983.h"
+// TListObjects units
+#include "TList.h"
+#include "TObjects.h"
+
+//#include <memory>
+//#include <vector>
+//---------------------------------------------------------------------------------------------
+// Defines - remove comments to enable special mode
+//---------------------------------------------------------------------------------------------
+#define internaldebug // send debug messages to USB Serial port (9600,1,N)
+//#define dhcpenable    // auto-setup IP Address from DHCP router
+//---------------------------------------------------------------------------------------------
+// Ethernet Object Setup
+//---------------------------------------------------------------------------------------------
+#ifdef dhcpenable
+  EthernetNetIf eth;  
+#else
+/*
+  EthernetNetIf eth(
+    IpAddr(192,168,0,100), //IP Address
+    IpAddr(255,255,255,0), //Network Mask
+    IpAddr(192,168,0,1),   //Gateway - Laptop sharing Internet via 3G
+    IpAddr(208,67,220,220) //OpenDNS
+  );
+*/  
+  EthernetNetIf eth(
+    IpAddr(192,168,1,100), //IP Address
+    IpAddr(255,255,255,0), //Network Mask
+    IpAddr(192,168,1,254), //Gateway
+    IpAddr(192,168,1,254)  //DNS
+  );
+#endif
+//---------------------------------------------------------------------------------------------
+// HTTP Server
+//---------------------------------------------------------------------------------------------
+HTTPServer svr;
+LocalFileSystem fs("webfs");
+//---------------------------------------------------------------------------------------------
+// Misc
+//---------------------------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------------------------
+// Timer Interrupt - NetPool
+//---------------------------------------------------------------------------------------------
+Ticker netpool;
+//---------------------------------------------------------------------------------------------
+// auxiliar pointer - necessary for the rpc_nsteps(char *input, char *output) function
+//---------------------------------------------------------------------------------------------
+A4983 *p_stepmotor;
+//---------------------------------------------------------------------------------------------
+// temporary TList object
+TList *pListPointer = NULL;
+//---------------------------------------------------------------------------------------------
+
+bool request_handle = false;
+
+//#############################################################################################
+
+//---------------------------------------------------------------------------------------------
+// Pool Ethernet - will be triggered by netpool ticker
+//---------------------------------------------------------------------------------------------
+void netpoolupdate()
+{
+    Net::poll();
+}
+//---------------------------------------------------------------------------------------------
+// RPC function
+//---------------------------------------------------------------------------------------------
+void rpc_nsteps(char *input, char *output)
+{
+  while(request_handle);
+  
+  request_handle = true;
+
+  int arg1 = 0; // number of steps
+  sscanf(input, "%i", &arg1);
+
+  #ifdef internaldebug
+    printf("Calling RCP Function Step.\r\n");
+    printf("INPUT: %s.\r\n", input);
+    printf("OUTPUT: %s.\r\n", output);
+    printf("ARG1: %i.\r\n", arg1);
+  #endif 
+  
+  p_stepmotor->loopstop();             
+  for(int i=0; i<arg1; i++)
+  {
+    wait(p_stepmotor->k_delay);
+    p_stepmotor->singlestep();
+  }
+
+  sprintf(output, "<html><body>RCP NSteps Completed!</body></html>");  
+  request_handle = false;
+}
+//---------------------------------------------------------------------------------------------
+void rpc_stepmode(char *input, char *output)
+{
+  while(request_handle);
+  
+  request_handle = true;
+  
+  int arg1 = 0; // microstep=1; fullstep=0;
+  sscanf(input, "%i", &arg1);
+
+  #ifdef internaldebug
+    printf("Calling RCP Function Step Mode.\r\n");
+    printf("INPUT: %s.\r\n", input);
+    printf("OUTPUT: %s.\r\n", output);
+    printf("ARG1: %i.\r\n", arg1);
+  #endif 
+  
+  if(arg1 == 0)  
+  {
+    p_stepmotor->adjust_microstepping_mode(1); // full step
+
+    #ifdef internaldebug
+      printf("--> FullStep\r\n");
+    #endif
+  }
+  else
+  {
+    p_stepmotor->adjust_microstepping_mode(16); // microstep 1/16
+
+    #ifdef internaldebug
+      printf("--> MicroStep 1/16\r\n");
+    #endif    
+  }
+
+  sprintf(output, "<html><body>RCP Step Mode Completed!</body></html>");  
+  request_handle = false;
+}
+//---------------------------------------------------------------------------------------------
+void rpc_sleepmode(char *input, char *output)
+{
+  while(request_handle);
+  
+  request_handle = true;
+  
+  int arg1 = 0; // microstep=1; fullstep=0;
+  sscanf(input, "%i", &arg1);
+
+  #ifdef internaldebug
+    printf("Calling RCP Function Sleep CMD.\r\n");
+    printf("INPUT: %s.\r\n", input);
+    printf("OUTPUT: %s.\r\n", output);
+    printf("ARG1: %i.\r\n", arg1);    
+  #endif 
+  
+  if(arg1 == 1)
+    p_stepmotor->sleep(true);
+  else
+    p_stepmotor->sleep(false);
+
+  sprintf(output, "<html><body>RCP Sleep CMD Completed!</body></html>");  
+  request_handle = false;
+}
+//---------------------------------------------------------------------------------------------
+// RPC TList Commands (Task/Job List)
+//---------------------------------------------------------------------------------------------
+void rpc_stepcmd(char *input, char *output)
+{
+  while(request_handle);
+  
+  request_handle = true;
+  
+  int insteps = 0; // number of steps
+  int ideltatime = 0; // time in ms between Step Motor SPI frames  
+  int idirection = 0; // direction {0->CCW; 1->CW}
+  
+  sscanf(input, "%i %i %i", &insteps, &ideltatime, &idirection);    
+    
+  #ifdef internaldebug
+    printf("Calling RCP Function StepCmd.\r\n");
+    printf("INPUT: %s.\r\n", input);
+    printf("OUTPUT: %s.\r\n", output);
+    printf("ARG1: %d\r\n", insteps);
+    printf("ARG2: %d\r\n", ideltatime);
+    printf("ARG3: %d\r\n", idirection);
+  #endif 
+  
+  // adding cmd (TObjectStep) to TList
+  pListPointer = SetListNextObject();
+  TObjectStep *pobjectstep = new TObjectStep(insteps, ideltatime, idirection);
+  pListPointer->cmdtype = 0x01;
+  pListPointer->cmdobject = (TObjectStep*)pobjectstep;
+
+  sprintf(output, "<html><body>RCP Step Cmd Completed!</body></html>");
+  request_handle = false;
+}
+//---------------------------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------------------------
+// MAIN routine
+//---------------------------------------------------------------------------------------------
+int main() 
+{   
+  //std::auto_ptr<int>abc;
+  //std::vector<int>def;
+  //--------------------------------------------------------
+  // Setting RPC
+  //--------------------------------------------------------  
+  /*
+  Base::add_rpc_class<AnalogIn>();
+  Base::add_rpc_class<AnalogOut>();
+  Base::add_rpc_class<DigitalIn>();
+  Base::add_rpc_class<DigitalOut>();
+  Base::add_rpc_class<DigitalInOut>();
+  Base::add_rpc_class<PwmOut>();
+  Base::add_rpc_class<Timer>();
+  Base::add_rpc_class<BusOut>();
+  Base::add_rpc_class<BusIn>();
+  Base::add_rpc_class<BusInOut>();
+  Base::add_rpc_class<Serial>();  */ 
+   
+  //--------------------------------------------------------
+  // Setting Ethernet
+  //--------------------------------------------------------    
+  #ifdef internaldebug
+    printf("Setting up...\r\n");
+  #endif
+  EthernetErr ethErr = eth.setup(); 
+  if(ethErr)
+  {
+    #ifdef internaldebug
+      printf("Error %d in setup.\r\n", ethErr);
+    #endif
+    return -1;
+  }
+  #ifdef internaldebug
+    printf("Setup OK\r\n");
+  #endif  
+
+  //--------------------------------------------------------
+  // instance of the Step Motor Driver interface
+  //--------------------------------------------------------
+  A4983 stepmotor;
+  p_stepmotor = &stepmotor; // auxiliar pointer for rpc_nsteps(char *input, char *output);
+  
+  //--------------------------------------------------------
+  // adding RPC variables 
+  //--------------------------------------------------------
+  RPCVariable<uint8_t> RPCenable(&stepmotor.f_motor_enable, "enable");
+  RPCVariable<uint8_t> RPCdir(&stepmotor.f_motor_direction, "direction");
+  RPCVariable<float> RPCdelay(&stepmotor.k_delay, "delay");
+
+  //--------------------------------------------------------
+  // adding RPC functions
+  //--------------------------------------------------------
+  RPCFunction RPCnsteps(&rpc_nsteps, "nsteps");  
+  RPCFunction RPCsleepmode(&rpc_sleepmode, "sleepmode"); 
+  RPCFunction RPCstepmode(&rpc_stepmode, "stepmode"); 
+  
+  RPCFunction RPCstepcmd(&rpc_stepcmd, "stepcmd");    
+ 
+  //--------------------------------------------------------
+  // adding Handlers 
+  //--------------------------------------------------------
+  FSHandler::mount("/webfs", "/files"); //Mount /webfs path on /files web path
+  FSHandler::mount("/webfs", "/"); //Mount /webfs path on web root path
+
+  //svr.addHandler<SimpleHandler>("/hello");
+  svr.addHandler<RPCHandler>("/rpc");
+  svr.addHandler<FSHandler>("/files");
+  svr.addHandler<FSHandler>("/"); //Default handler
+  //Example : Access to mbed.htm : http://a.b.c.d/mbed.htm or http://a.b.c.d/files/mbed.htm  
+
+  //--------------------------------------------------------
+  // bind http server to port 80 (Listen)
+  //--------------------------------------------------------       
+  svr.bind(80);  
+  #ifdef internaldebug
+    printf("Listening on port 80 ...\r\n");
+  #endif
+    
+  //--------------------------------------------------------
+  // attach timer interrupt to update Net::Pool();
+  //--------------------------------------------------------
+  netpool.attach(&netpoolupdate, 0.1);
+
+  //--------------------------------------------------------
+  // main loop
+  //--------------------------------------------------------        
+  //stepmotor.f_motor_enable = 1; // used for debug, force motor to star when micro is reset         
+  //stepmotor.k_delay = 0.01;
+  while(1) 
+  {          
+    stepmotor.looprun();    
+    //stepmotor.singlestep();
+  }  
+}
+//---------------------------------------------------------------------------------------------
\ No newline at end of file