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

Revision:
0:8b3857d4ce02
--- /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�)
+
+// 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