Skip to content
Snippets Groups Projects
Select Git revision
  • master
1 result

fab-step-log.md

Blame
  • Log

    2020 11 05

    Started in, have the schematic mostly roughed out: this'll be 1.5 sided (solid GND below a routed layer). I think... the largest challenge is just getting things around themselves without using any vias. Found a tranciever as well.

    2020 11 16

    Just routed out the program / power / data interface side of this.

    routing

    Success going forward will rely on a a fortuitous alignment of the RS485 interface pins against a SERCOM port somewhere on 11-16... not at all sure if any such alignment exists.

    2020 11 17

    Lucky me, those line up. I can put the SERCOM's TXPO at 0 (for TX on SER-0) and and RXPO at 3 (for RX on SER-3) and the middle two will do data enable and rx enable, just GPIO.

    routing

    So, sorted that out. I think it works OK. I can make one of these in the fab-version, and can copy the schematic onto a smaller 2-layer board to fab lots of at a board house, having pins 17-20 free for an AS5047 on the back... same RS485 interface, maybe the QFN D21, and 0805s or smaller passives, pinch traces / spaces etc.

    2021 06 12

    Re-routed this for UCBus compatibility, still looks like the best option despite SPI availability: SPI interrupt handlers are minimum ~ 2us, meaning byte period of 2.6us (at 3MHz) is limiting, might as well use simplicity of UART, and ability / option for it to self-configure as P2P connection, etc. RS485 UART is same pin count as TTL SPI, would rather have noise / distance immunity.

    I left off some pins (SERCOM0) to potentially add an encoder here, the routing for that would be tough but probably possible.

    route schem

    2021 06 19

    Realized today that I had 5v, 24v lines on the plug optimistically configured for easier routing: the cable symmetry results in a more awkward routing which I've corrected, just had to squish the connector / RS485 bit up 1.5mm or so, so that I could wiggle those 5v and 24v lines beneath the connector:

    route schem

    2022 01 10

    Back here but I am not working on the closed-loop version now... need to split these repos... writing code for the actually-fab-abble version.

    I think I'm just going to get right into a step-tick rather than float-tick operation.

    Though this means some re-work at the head first.

    It's totally easy though, I write a little step mask in the motor interface class, get that on interrupt - I am even caching two so that I can get the full 10kHz rather than 5.

    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.

    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.

    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.

    step

    Yeah, something like that: microsteps increment back but flipping ticks forwards so I'm somehow misaligned.

    had an 'a' where a 'b' was meant to be.

    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.

    Homing Routine

    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.

    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;

    #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

    Just a bunch of buttons, turns out to not be so bad. Done.

    New Motor API and JS Config

    This should actually be chill... it's working after all, right?

    I'm setting the SPUs in the motion-head now... meaning I could also calculate / guard against max rates there.

    • motion-head things
      • steps per unit
      • max accels
      • max rates
    • motor things
      • direction inversion
      • microstepping
      • axis picking

    OK I've diffed all that... need to make a microstep update actually do something, then this adventure is over.

    11752 / 24584 12520 / 24976

    Done, for the time being. Probably needs in-mcu guards against large rates.