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();
}
}
//---------------------------------------------------------------------------------------------
Nelson Neves