Skip to content
Snippets Groups Projects
Commit 37111b9a authored by Jake Read's avatar Jake Read
Browse files

tighter homing routine

parent a1a23182
No related branches found
No related tags found
No related merge requests found
...@@ -15,7 +15,7 @@ is; no warranty is provided, and users accept all liability. ...@@ -15,7 +15,7 @@ is; no warranty is provided, and users accept all liability.
#ifndef STEP_A4950_H_ #ifndef STEP_A4950_H_
#define STEP_A4950_H_ #define STEP_A4950_H_
#include <arduino.h> #include <Arduino.h>
// AIN1 PA14 // AIN1 PA14
// AIN2 PA15 // AIN2 PA15
......
/*
homing.cpp
tiny homing routine for fab-step
Jake Read at the Center for Bits and Atoms
(c) Massachusetts Institute of Technology 2022
This work may be reproduced, modified, distributed, performed, and
displayed for any purpose, but must acknowledge the OSAP project.
Copyright is retained and must be preserved. The work is provided as
is; no warranty is provided, and users accept all liability.
*/
#include "homing.h"
#include "drivers/step_a4950.h"
endpoint_t* _homeStateEP;
uint8_t homeState = HOMESTATE_NONE;
uint32_t homeBackoffStepsTaken = 0;
// home settings
boolean homeDir = true;
unsigned long lastHomeOperation = 0;
unsigned long homeOperationPeriod = 1000; // in us
uint32_t homeBackoffDistance = 100;
void homeSetup(endpoint_t* homeStateEP){
// stash this
_homeStateEP = homeStateEP;
// make an input
PORT->Group[LIMIT_PORT].DIRCLR.reg = (1 << LIMIT_PIN);
PORT->Group[LIMIT_PORT].PINCFG[LIMIT_PIN].bit.INEN = 1;
// pullup
PORT->Group[LIMIT_PORT].OUTSET.reg = (1 << LIMIT_PIN);
}
// return true if limit switch is hit
boolean limitHit(void){
return (PORT->Group[LIMIT_PORT].IN.reg & (1 << LIMIT_PIN));
}
void writeHomeSettings(boolean dir, uint32_t stepsPerSecond, uint32_t offset){
homeDir = dir;
homeOperationPeriod = 1000000 / stepsPerSecond;
homeBackoffDistance = offset;
}
uint8_t getHomeState(void){
return homeState;
}
void startHomingRoutine(void){
homeState = HOMESTATE_APPROACH;
endpointWrite(_homeStateEP, &homeState, 1);
}
void runHomingRoutine(void){
// run this at a rate...
if(lastHomeOperation + homeOperationPeriod > micros()) return;
lastHomeOperation = micros();
// state switch;
switch(homeState){
case HOMESTATE_NONE:
break;
case HOMESTATE_APPROACH:
// check for contact,
if(limitHit()){
homeState = HOMESTATE_BACKOFF;
endpointWrite(_homeStateEP, &homeState, 1);
homeBackoffStepsTaken = 0;
} else {
step_a4950_dir(homeDir);
step_a4950_step();
}
break;
case HOMESTATE_BACKOFF:
step_a4950_dir(!homeDir);
step_a4950_step();
homeBackoffStepsTaken ++;
if(homeBackoffStepsTaken > homeBackoffDistance){
homeState = HOMESTATE_NONE;
endpointWrite(_homeStateEP, &homeState, 1);
}
break;
default:
// broken,
homeState = HOMESTATE_NONE;
endpointWrite(_homeStateEP, &homeState, 1);
break;
}
}
\ No newline at end of file
/*
homing.h
tiny homing routine for fab-step
Jake Read at the Center for Bits and Atoms
(c) Massachusetts Institute of Technology 2022
This work may be reproduced, modified, distributed, performed, and
displayed for any purpose, but must acknowledge the OSAP project.
Copyright is retained and must be preserved. The work is provided as
is; no warranty is provided, and users accept all liability.
*/
#ifndef HOMING_H_
#define HOMING_H_
#include <Arduino.h>
#include "osape-d21/osape/osap/endpoint.h"
// limit
#define LIMIT_PORT 0
#define LIMIT_PIN 3
// home states
#define HOMESTATE_NONE 0
#define HOMESTATE_APPROACH 1
#define HOMESTATE_BACKOFF 2
void homeSetup(endpoint_t* homeStateEP);
boolean limitHit(void);
uint8_t getHomeState(void);
void writeHomeSettings(boolean dir, uint32_t stepsPerSecond, uint32_t offset);
void startHomingRoutine(void);
void runHomingRoutine(void);
#endif
\ No newline at end of file
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "config.h" #include "config.h"
#include "drivers/step_a4950.h" #include "drivers/step_a4950.h"
#include "homing.h"
#include "osape-d21/osape/osap/osap.h" #include "osape-d21/osape/osap/osap.h"
#include "osape-d21/vertices/vt_usbSerial.h" #include "osape-d21/vertices/vt_usbSerial.h"
...@@ -70,6 +71,20 @@ endpoint_t* cScaleEp = osapBuildEndpoint("CScale", onCScaleData); ...@@ -70,6 +71,20 @@ endpoint_t* cScaleEp = osapBuildEndpoint("CScale", onCScaleData);
// -------------------------------------------------------- HOME ROUTINE // -------------------------------------------------------- HOME ROUTINE
EP_ONDATA_RESPONSES onHomeData(uint8_t* data, uint16_t len){ EP_ONDATA_RESPONSES onHomeData(uint8_t* data, uint16_t len){
chunk_int32 rate = { .bytes = { data[0], data[1], data[2], data[3] } };
chunk_uint32 offset = { .bytes = { data[4], data[5], data[6], data[7] } };
// sign of rate is dir,
boolean hdir;
uint32_t hrate;
if(rate.i < 0) {
hdir = false;
hrate = -1 * rate.i;
} else {
hdir = true;
hrate = rate.i;
}
writeHomeSettings(hdir, hrate, offset.u);
startHomingRoutine();
return EP_ONDATA_ACCEPT; return EP_ONDATA_ACCEPT;
} }
...@@ -86,7 +101,9 @@ endpoint_t* homeStateEp = osapBuildEndpoint("HomeState"); ...@@ -86,7 +101,9 @@ endpoint_t* homeStateEp = osapBuildEndpoint("HomeState");
void setup() { void setup() {
CLKLIGHT_SETUP; CLKLIGHT_SETUP;
BUSLIGHT_SETUP; BUSLIGHT_SETUP;
DEBUG1PIN_SETUP; // debug1pin is the limit pin: we can have one or the other
//DEBUG1PIN_SETUP;
homeSetup(homeStateEp);
// osap setup... // osap setup...
osapSetup("fab-step"); osapSetup("fab-step");
vt_usbSerial_setup(); vt_usbSerial_setup();
...@@ -119,6 +136,9 @@ unsigned long last_tick = 0; ...@@ -119,6 +136,9 @@ unsigned long last_tick = 0;
void loop() { void loop() {
// do osap things, // do osap things,
osapLoop(); osapLoop();
limitHit() ? BUSLIGHT_ON : BUSLIGHT_OFF;
// do homing things, if need be:
if(getHomeState() != HOMESTATE_NONE) runHomingRoutine();
// blink // blink
if(millis() > last_tick + CLK_TICK){ if(millis() > last_tick + CLK_TICK){
// step_a4950_step(); // step_a4950_step();
...@@ -141,6 +161,8 @@ void ucBusDrop_onPacketARx(uint8_t* inBufferA, volatile uint16_t len){ ...@@ -141,6 +161,8 @@ void ucBusDrop_onPacketARx(uint8_t* inBufferA, volatile uint16_t len){
void ucBusDrop_onRxISR(void){ void ucBusDrop_onRxISR(void){
// if we dont' have valid steps, bail // if we dont' have valid steps, bail
if(!stepValid) return; if(!stepValid) return;
// if we're currently homing the motor, bail
if(getHomeState() != HOMESTATE_NONE) return;
// extract our step mask // extract our step mask
stepMask = 0b00000011 & (stepCache[cachePtr] >> (axisPick * 2)); stepMask = 0b00000011 & (stepCache[cachePtr] >> (axisPick * 2));
// mask -> step api: // mask -> step api:
......
...@@ -205,6 +205,8 @@ I think I need a config / setup on the js side. ...@@ -205,6 +205,8 @@ I think I need a config / setup on the js side.
OK this is almost jogging - I need some motor config, then I think I actually have some driver level debug to do, not unlikely with the VREF stuff. OK this is almost jogging - I need some motor config, then I think I actually have some driver level debug to do, not unlikely with the VREF stuff.
### H-Bridge : Code Alignment
It has come to my attention that I changed the pins on all of these things, and hadn't re-written to use the timer-counter rc filters, whoops. It has come to my attention that I changed the pins on all of these things, and hadn't re-written to use the timer-counter rc filters, whoops.
Looking a lot better now that I sorted that haha - looks like I still need to scope the pwm'd lines, I am maybe flipping a phase improperly. Looking a lot better now that I sorted that haha - looks like I still need to scope the pwm'd lines, I am maybe flipping a phase improperly.
...@@ -219,12 +221,108 @@ Now I'm just not seeing it hold while it's microstepping... ...@@ -219,12 +221,108 @@ Now I'm just not seeing it hold while it's microstepping...
OK it's all up, and jogs around w/ the motion system, rad. OK it's all up, and jogs around w/ the motion system, rad.
- check that 'microstep' config does what it claims ### Homing Routine
- microstep image
- bring motor config back to JS side Next thing I need is a little homing routine... I think I will do `homingRate` in steps / second... rather than keep any other info in the motor.
- we need a homing routine still, write this little statemachine pls !
This is still kind of a pain.
Great, homing works. It's stateful, that's why it's such a pain - and has to work all asynchronously;
```cpp
#include "homing.h"
#include "drivers/step_a4950.h"
endpoint_t* _homeStateEP;
uint8_t homeState = HOMESTATE_NONE;
uint32_t homeBackoffStepsTaken = 0;
// home settings
boolean homeDir = true;
unsigned long lastHomeOperation = 0;
unsigned long homeOperationPeriod = 1000; // in us
uint32_t homeBackoffDistance = 100;
void homeSetup(endpoint_t* homeStateEP){
// stash this
_homeStateEP = homeStateEP;
// make an input
PORT->Group[LIMIT_PORT].DIRCLR.reg = (1 << LIMIT_PIN);
PORT->Group[LIMIT_PORT].PINCFG[LIMIT_PIN].bit.INEN = 1;
// pullup
PORT->Group[LIMIT_PORT].OUTSET.reg = (1 << LIMIT_PIN);
}
// return true if limit switch is hit
boolean limitHit(void){
return (PORT->Group[LIMIT_PORT].IN.reg & (1 << LIMIT_PIN));
}
void writeHomeSettings(boolean dir, uint32_t stepsPerSecond, uint32_t offset){
homeDir = dir;
homeOperationPeriod = 1000000 / stepsPerSecond;
homeBackoffDistance = offset;
}
uint8_t getHomeState(void){
return homeState;
}
void startHomingRoutine(void){
homeState = HOMESTATE_APPROACH;
endpointWrite(_homeStateEP, &homeState, 1);
}
void runHomingRoutine(void){
// run this at a rate...
if(lastHomeOperation + homeOperationPeriod > micros()) return;
lastHomeOperation = micros();
// state switch;
switch(homeState){
case HOMESTATE_NONE:
break;
case HOMESTATE_APPROACH:
// check for contact,
if(limitHit()){
homeState = HOMESTATE_BACKOFF;
endpointWrite(_homeStateEP, &homeState, 1);
homeBackoffStepsTaken = 0;
} else {
step_a4950_dir(homeDir);
step_a4950_step();
}
break;
case HOMESTATE_BACKOFF:
step_a4950_dir(!homeDir);
step_a4950_step();
homeBackoffStepsTaken ++;
if(homeBackoffStepsTaken > homeBackoffDistance){
homeState = HOMESTATE_NONE;
endpointWrite(_homeStateEP, &homeState, 1);
}
break;
default:
// broken,
homeState = HOMESTATE_NONE;
endpointWrite(_homeStateEP, &homeState, 1);
break;
}
}
```
Now I just want to touch up the motor APIs in JS, and add the steps-per-unit adjust stuff in the motion-head, etc... I should be pretty close now.
### Power State API
- do need this, and it needs to be part of the 'setup' routine
### New Motor API and JS Config
- check that 'microstep' config does what it claims (?)
- now ... we need to reconsider how / whomst makes SPU / dir configs, etc - now ... we need to reconsider how / whomst makes SPU / dir configs, etc
- inversion is per-motor - inversion is per-motor
- so is microstepping - so is microstepping
- so is the axis pick - so is the axis pick
- spu is per-axis in the head - spu is per-axis in the head
A final treat would be reconfiguring the ucbus-stepper firmware to match this. Another treat would be a tiny demo video for Donny.
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment