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
main.cpp
- Committer:
- botdream
- Date:
- 2012-04-16
- Revision:
- 0:8b3857d4ce02
File content as of revision 0:8b3857d4ce02:
/* //--------------------------------------------------------------------------------------------- // 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(); } } //---------------------------------------------------------------------------------------------