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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* //---------------------------------------------------------------------------------------------
00002 // disable/enable auto-run
00003 http://192.168.1.100/rpc/enable/write%200
00004 http://192.168.1.100/rpc/enable/write%201
00005 
00006 // normal/inverse direction
00007 http://192.168.1.100/rpc/direction/write%200
00008 
00009 // timer delay - motor speed
00010 http://192.168.1.100/rpc/delay/write%200.00001 (default)
00011 http://192.168.1.100/rpc/delay/write%200.0000025 (max)
00012 
00013 http://192.168.1.100/rpc/delay/write%200.00048 (super slow)
00014 
00015 // RPC number of steps
00016 http://192.168.1.100/rpc/nsteps/run%2016 (16 microsteps => 1 step)
00017 http://192.168.1.100/rpc/nsteps/run%203200 (200 Steps -> 360�)
00018 
00019 // RPC StepCmd
00020 http://192.168.1.100/rpc/stepcmd/run%201000%20100%201
00021 
00022 // RPC StepMode
00023 http://192.168.1.100/rpc/stepmode/run%200
00024 http://192.168.1.100/rpc/stepmode/run%201
00025 
00026 //Sleep mode
00027 http://192.168.1.100/rpc/sleepmode/run%200
00028 http://192.168.1.100/rpc/sleepmode/run%201
00029 
00030 //---------------------------------------------------------------------------------------------
00031 // resources
00032 //---------------------------------------------------------------------------------------------
00033 http://mbed.org/handbook/C-Data-Types
00034 http://mbed.org/cookbook/RPC-Interface-Library
00035 http://mbed.org/cookbook/HTTP-Server
00036 http://mbed.org/cookbook/Ethernet
00037 http://mbed.org/handbook/Ticker
00038 //--------------------------------------------------------------------------------------------- */
00039 #include "mbed.h"
00040 #include "EthernetNetIf.h"
00041 #include "HTTPServer.h"
00042 #include "RPCVariable.h"
00043 #include "RPCFunction.h"
00044 #include "A4983.h"
00045 // TListObjects units
00046 #include "TList.h"
00047 #include "TObjects.h"
00048 
00049 //#include <memory>
00050 //#include <vector>
00051 //---------------------------------------------------------------------------------------------
00052 // Defines - remove comments to enable special mode
00053 //---------------------------------------------------------------------------------------------
00054 #define internaldebug // send debug messages to USB Serial port (9600,1,N)
00055 //#define dhcpenable    // auto-setup IP Address from DHCP router
00056 //---------------------------------------------------------------------------------------------
00057 // Ethernet Object Setup
00058 //---------------------------------------------------------------------------------------------
00059 #ifdef dhcpenable
00060   EthernetNetIf eth;  
00061 #else
00062 /*
00063   EthernetNetIf eth(
00064     IpAddr(192,168,0,100), //IP Address
00065     IpAddr(255,255,255,0), //Network Mask
00066     IpAddr(192,168,0,1),   //Gateway - Laptop sharing Internet via 3G
00067     IpAddr(208,67,220,220) //OpenDNS
00068   );
00069 */  
00070   EthernetNetIf eth(
00071     IpAddr(192,168,1,100), //IP Address
00072     IpAddr(255,255,255,0), //Network Mask
00073     IpAddr(192,168,1,254), //Gateway
00074     IpAddr(192,168,1,254)  //DNS
00075   );
00076 #endif
00077 //---------------------------------------------------------------------------------------------
00078 // HTTP Server
00079 //---------------------------------------------------------------------------------------------
00080 HTTPServer svr;
00081 LocalFileSystem fs("webfs");
00082 //---------------------------------------------------------------------------------------------
00083 // Misc
00084 //---------------------------------------------------------------------------------------------
00085 
00086 //---------------------------------------------------------------------------------------------
00087 // Timer Interrupt - NetPool
00088 //---------------------------------------------------------------------------------------------
00089 Ticker netpool;
00090 //---------------------------------------------------------------------------------------------
00091 // auxiliar pointer - necessary for the rpc_nsteps(char *input, char *output) function
00092 //---------------------------------------------------------------------------------------------
00093 A4983 *p_stepmotor;
00094 //---------------------------------------------------------------------------------------------
00095 // temporary TList object
00096 TList *pListPointer = NULL;
00097 //---------------------------------------------------------------------------------------------
00098 
00099 bool request_handle = false;
00100 
00101 //#############################################################################################
00102 
00103 //---------------------------------------------------------------------------------------------
00104 // Pool Ethernet - will be triggered by netpool ticker
00105 //---------------------------------------------------------------------------------------------
00106 void netpoolupdate()
00107 {
00108     Net::poll();
00109 }
00110 //---------------------------------------------------------------------------------------------
00111 // RPC function
00112 //---------------------------------------------------------------------------------------------
00113 void rpc_nsteps(char *input, char *output)
00114 {
00115   while(request_handle);
00116   
00117   request_handle = true;
00118 
00119   int arg1 = 0; // number of steps
00120   sscanf(input, "%i", &arg1);
00121 
00122   #ifdef internaldebug
00123     printf("Calling RCP Function Step.\r\n");
00124     printf("INPUT: %s.\r\n", input);
00125     printf("OUTPUT: %s.\r\n", output);
00126     printf("ARG1: %i.\r\n", arg1);
00127   #endif 
00128   
00129   p_stepmotor->loopstop();             
00130   for(int i=0; i<arg1; i++)
00131   {
00132     wait(p_stepmotor->k_delay);
00133     p_stepmotor->singlestep();
00134   }
00135 
00136   sprintf(output, "<html><body>RCP NSteps Completed!</body></html>");  
00137   request_handle = false;
00138 }
00139 //---------------------------------------------------------------------------------------------
00140 void rpc_stepmode(char *input, char *output)
00141 {
00142   while(request_handle);
00143   
00144   request_handle = true;
00145   
00146   int arg1 = 0; // microstep=1; fullstep=0;
00147   sscanf(input, "%i", &arg1);
00148 
00149   #ifdef internaldebug
00150     printf("Calling RCP Function Step Mode.\r\n");
00151     printf("INPUT: %s.\r\n", input);
00152     printf("OUTPUT: %s.\r\n", output);
00153     printf("ARG1: %i.\r\n", arg1);
00154   #endif 
00155   
00156   if(arg1 == 0)  
00157   {
00158     p_stepmotor->adjust_microstepping_mode(1); // full step
00159 
00160     #ifdef internaldebug
00161       printf("--> FullStep\r\n");
00162     #endif
00163   }
00164   else
00165   {
00166     p_stepmotor->adjust_microstepping_mode(16); // microstep 1/16
00167 
00168     #ifdef internaldebug
00169       printf("--> MicroStep 1/16\r\n");
00170     #endif    
00171   }
00172 
00173   sprintf(output, "<html><body>RCP Step Mode Completed!</body></html>");  
00174   request_handle = false;
00175 }
00176 //---------------------------------------------------------------------------------------------
00177 void rpc_sleepmode(char *input, char *output)
00178 {
00179   while(request_handle);
00180   
00181   request_handle = true;
00182   
00183   int arg1 = 0; // microstep=1; fullstep=0;
00184   sscanf(input, "%i", &arg1);
00185 
00186   #ifdef internaldebug
00187     printf("Calling RCP Function Sleep CMD.\r\n");
00188     printf("INPUT: %s.\r\n", input);
00189     printf("OUTPUT: %s.\r\n", output);
00190     printf("ARG1: %i.\r\n", arg1);    
00191   #endif 
00192   
00193   if(arg1 == 1)
00194     p_stepmotor->sleep(true);
00195   else
00196     p_stepmotor->sleep(false);
00197 
00198   sprintf(output, "<html><body>RCP Sleep CMD Completed!</body></html>");  
00199   request_handle = false;
00200 }
00201 //---------------------------------------------------------------------------------------------
00202 // RPC TList Commands (Task/Job List)
00203 //---------------------------------------------------------------------------------------------
00204 void rpc_stepcmd(char *input, char *output)
00205 {
00206   while(request_handle);
00207   
00208   request_handle = true;
00209   
00210   int insteps = 0; // number of steps
00211   int ideltatime = 0; // time in ms between Step Motor SPI frames  
00212   int idirection = 0; // direction {0->CCW; 1->CW}
00213   
00214   sscanf(input, "%i %i %i", &insteps, &ideltatime, &idirection);    
00215     
00216   #ifdef internaldebug
00217     printf("Calling RCP Function StepCmd.\r\n");
00218     printf("INPUT: %s.\r\n", input);
00219     printf("OUTPUT: %s.\r\n", output);
00220     printf("ARG1: %d\r\n", insteps);
00221     printf("ARG2: %d\r\n", ideltatime);
00222     printf("ARG3: %d\r\n", idirection);
00223   #endif 
00224   
00225   // adding cmd (TObjectStep) to TList
00226   pListPointer = SetListNextObject();
00227   TObjectStep *pobjectstep = new TObjectStep(insteps, ideltatime, idirection);
00228   pListPointer->cmdtype = 0x01;
00229   pListPointer->cmdobject = (TObjectStep*)pobjectstep;
00230 
00231   sprintf(output, "<html><body>RCP Step Cmd Completed!</body></html>");
00232   request_handle = false;
00233 }
00234 //---------------------------------------------------------------------------------------------
00235 
00236 
00237 //---------------------------------------------------------------------------------------------
00238 // MAIN routine
00239 //---------------------------------------------------------------------------------------------
00240 int main() 
00241 {   
00242   //std::auto_ptr<int>abc;
00243   //std::vector<int>def;
00244   //--------------------------------------------------------
00245   // Setting RPC
00246   //--------------------------------------------------------  
00247   /*
00248   Base::add_rpc_class<AnalogIn>();
00249   Base::add_rpc_class<AnalogOut>();
00250   Base::add_rpc_class<DigitalIn>();
00251   Base::add_rpc_class<DigitalOut>();
00252   Base::add_rpc_class<DigitalInOut>();
00253   Base::add_rpc_class<PwmOut>();
00254   Base::add_rpc_class<Timer>();
00255   Base::add_rpc_class<BusOut>();
00256   Base::add_rpc_class<BusIn>();
00257   Base::add_rpc_class<BusInOut>();
00258   Base::add_rpc_class<Serial>();  */ 
00259    
00260   //--------------------------------------------------------
00261   // Setting Ethernet
00262   //--------------------------------------------------------    
00263   #ifdef internaldebug
00264     printf("Setting up...\r\n");
00265   #endif
00266   EthernetErr ethErr = eth.setup(); 
00267   if(ethErr)
00268   {
00269     #ifdef internaldebug
00270       printf("Error %d in setup.\r\n", ethErr);
00271     #endif
00272     return -1;
00273   }
00274   #ifdef internaldebug
00275     printf("Setup OK\r\n");
00276   #endif  
00277 
00278   //--------------------------------------------------------
00279   // instance of the Step Motor Driver interface
00280   //--------------------------------------------------------
00281   A4983 stepmotor;
00282   p_stepmotor = &stepmotor; // auxiliar pointer for rpc_nsteps(char *input, char *output);
00283   
00284   //--------------------------------------------------------
00285   // adding RPC variables 
00286   //--------------------------------------------------------
00287   RPCVariable<uint8_t> RPCenable(&stepmotor.f_motor_enable, "enable");
00288   RPCVariable<uint8_t> RPCdir(&stepmotor.f_motor_direction, "direction");
00289   RPCVariable<float> RPCdelay(&stepmotor.k_delay, "delay");
00290 
00291   //--------------------------------------------------------
00292   // adding RPC functions
00293   //--------------------------------------------------------
00294   RPCFunction RPCnsteps(&rpc_nsteps, "nsteps");  
00295   RPCFunction RPCsleepmode(&rpc_sleepmode, "sleepmode"); 
00296   RPCFunction RPCstepmode(&rpc_stepmode, "stepmode"); 
00297   
00298   RPCFunction RPCstepcmd(&rpc_stepcmd, "stepcmd");    
00299  
00300   //--------------------------------------------------------
00301   // adding Handlers 
00302   //--------------------------------------------------------
00303   FSHandler::mount("/webfs", "/files"); //Mount /webfs path on /files web path
00304   FSHandler::mount("/webfs", "/"); //Mount /webfs path on web root path
00305 
00306   //svr.addHandler<SimpleHandler>("/hello");
00307   svr.addHandler<RPCHandler>("/rpc");
00308   svr.addHandler<FSHandler>("/files");
00309   svr.addHandler<FSHandler>("/"); //Default handler
00310   //Example : Access to mbed.htm : http://a.b.c.d/mbed.htm or http://a.b.c.d/files/mbed.htm  
00311 
00312   //--------------------------------------------------------
00313   // bind http server to port 80 (Listen)
00314   //--------------------------------------------------------       
00315   svr.bind(80);  
00316   #ifdef internaldebug
00317     printf("Listening on port 80 ...\r\n");
00318   #endif
00319     
00320   //--------------------------------------------------------
00321   // attach timer interrupt to update Net::Pool();
00322   //--------------------------------------------------------
00323   netpool.attach(&netpoolupdate, 0.1);
00324 
00325   //--------------------------------------------------------
00326   // main loop
00327   //--------------------------------------------------------        
00328   //stepmotor.f_motor_enable = 1; // used for debug, force motor to star when micro is reset         
00329   //stepmotor.k_delay = 0.01;
00330   while(1) 
00331   {          
00332     stepmotor.looprun();    
00333     //stepmotor.singlestep();
00334   }  
00335 }
00336 //---------------------------------------------------------------------------------------------