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
Diff: main.cpp
- 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