diff --git a/2020-08_psu-breakout/2020-08_psu-breakout.brd b/2020-08_psu-breakout/2020-08_psu-breakout.brd index 839e1c55767dcdfcd87489d7aeb7b9c4bcc8d1f9..875f50688377118c762b348e8437fd0ad161f4f9 100644 --- a/2020-08_psu-breakout/2020-08_psu-breakout.brd +++ b/2020-08_psu-breakout/2020-08_psu-breakout.brd @@ -1170,7 +1170,7 @@ design rules under a new name.</description> <attribute name="PRECISION" value="" x="36.5" y="17" size="1.778" layer="27" rot="R90" display="off"/> <attribute name="VALUE" x="50.294" y="31.603" size="1.016" layer="27" rot="R90"/> </element> -<element name="R6" library="passives" package="1206" value="470R" x="54" y="39" smashed="yes" rot="R270"> +<element name="R6" library="passives" package="1206" value="1K" x="54" y="39" smashed="yes" rot="R270"> <attribute name="NAME" x="55.143" y="40.27" size="1.016" layer="25" rot="R270"/> <attribute name="PACKAGE" value="1206" x="60" y="39" size="1.778" layer="27" rot="R270" display="off"/> <attribute name="PRECISION" value="" x="60" y="39" size="1.778" layer="27" rot="R270" display="off"/> diff --git a/2020-08_psu-breakout/2020-08_psu-breakout.sch b/2020-08_psu-breakout/2020-08_psu-breakout.sch index 7d589fc8e7378aa39d5966fff6a8473539ddc561..a9a7f4faa95a77d81b51f08f5df63eaaed1279bc 100644 --- a/2020-08_psu-breakout/2020-08_psu-breakout.sch +++ b/2020-08_psu-breakout/2020-08_psu-breakout.sch @@ -6368,7 +6368,7 @@ chip</description> <part name="GND16" library="supply1" deviceset="GND" device=""/> <part name="GND21" library="supply1" deviceset="GND" device=""/> <part name="R5" library="passives" deviceset="RESISTOR" device="1206" value="1k"/> -<part name="R6" library="passives" deviceset="RESISTOR" device="1206" value="470R"/> +<part name="R6" library="passives" deviceset="RESISTOR" device="1206" value="1K"/> <part name="D8" library="lights" deviceset="LED" device="1206" value="LED1206"/> <part name="GND22" library="supply1" deviceset="GND" device=""/> <part name="P+3" library="supply1" deviceset="+5V" device=""/> @@ -6411,6 +6411,7 @@ chip</description> <sheets> <sheet> <plain> +<text x="152.4" y="104.14" size="1.778" layer="91">^ this is an error, should be +24v</text> </plain> <instances> <instance part="U1" gate="G$1" x="35.56" y="63.5" smashed="yes"/> diff --git a/2020-08_psu-breakout/eagle.epf b/2020-08_psu-breakout/eagle.epf index a2531fdcf2f0a0e9e7cea3795e9aea20bf786a62..b1a7d4be82b90753765bcd0231c4ac131c0581b9 100644 --- a/2020-08_psu-breakout/eagle.epf +++ b/2020-08_psu-breakout/eagle.epf @@ -19,7 +19,7 @@ UsedLibrary="C:/Dropbox/CBA/circuits/eagle/parts/SparkFun-Eagle-Libraries/SparkF Type="Schematic Editor" Number=1 File="2020-08_psu-breakout.sch" -View="191.998 139.609 359.952 189.822" +View="69.5535 84.1823 359.778 170.95" WireWidths=" 0.0762 0.1016 0.127 0.15 0.2 0.2032 0.254 0.3048 0.4064 0.508 0.6096 0.8128 1.016 1.27 2.54 0.1524" PadDiameters=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0" PadDrills=" 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6" @@ -58,14 +58,14 @@ ArcDirection=0 AddLevel=2 PadsSameType=0 Layer=91 -Views=" 1: 191.998 139.609 359.952 189.822" +Views=" 1: 69.5535 84.1823 359.778 170.95" Sheet="1" [Win_2] Type="Board Editor" Number=2 File="2020-08_psu-breakout.brd" -View="22.6761 -7.9544 114.036 68.529" +View="-10.2873 -48.3803 179.157 110.216" WireWidths=" 0.1016 0.15 0.2 2.54 0 0.508 0.2032 0.254 0.3048 0.4064 0.1524 1.016 1.27 0.127 0.6096 0.8128" PadDiameters=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0" PadDrills=" 0.2 0.25 0.3 0.35 0.4 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6 0.45" diff --git a/firmware/motion-head/src/indicators.h b/firmware/motion-head/src/indicators.h index 5de5ba9fb781ee179d87d937e937fcf6afbc3750..24d74a0c73094630b5cc48797ba1b85c2be3102a 100644 --- a/firmware/motion-head/src/indicators.h +++ b/firmware/motion-head/src/indicators.h @@ -26,12 +26,12 @@ #define DEBUG1PIN_TOGGLE PIN_TGL(0, 13) #define DEBUG1PIN_SETUP PIN_SETUP_OUTPUT(0, 13); PIN_HI(0, 13) -#define DEBUG2PIN_ON PIN_LO(0, 13) -#define DEBUG2PIN_OFF PIN_HI(0, 13) -#define DEBUG2PIN_HI PIN_HI(0, 13) -#define DEBUG2PIN_LO PIN_LO(0, 13) -#define DEBUG2PIN_TOGGLE PIN_TGL(0, 13) -#define DEBUG2PIN_SETUP PIN_SETUP_OUTPUT(0, 13); PIN_HI(0, 13) +#define DEBUG2PIN_ON PIN_LO(0, 12) +#define DEBUG2PIN_OFF PIN_HI(0, 12) +#define DEBUG2PIN_HI PIN_HI(0, 12) +#define DEBUG2PIN_LO PIN_LO(0, 12) +#define DEBUG2PIN_TOGGLE PIN_TGL(0, 12) +#define DEBUG2PIN_SETUP PIN_SETUP_OUTPUT(0, 12); PIN_HI(0, 12) #define DEBUG3PIN_ON PIN_LO(1, 15) #define DEBUG3PIN_OFF PIN_HI(1, 15) diff --git a/firmware/motion-head/src/main.cpp b/firmware/motion-head/src/main.cpp index 7df92b750df60481e32e22e3a513a5d0dd823727..42d44d5063659ede8d2de40d5d9afb564257b38e 100644 --- a/firmware/motion-head/src/main.cpp +++ b/firmware/motion-head/src/main.cpp @@ -181,6 +181,102 @@ EP_ONDATA_RESPONSES onRateSettingsData(uint8_t* data, uint16_t len){ endpoint_t* rateSettingsEp = osapBuildEndpoint("rateSettings", onRateSettingsData); +// -------------------------------------------------------- SPU SETTINGS + +EP_ONDATA_RESPONSES onSPUData(uint8_t* data, uint16_t len){ + // also 4 floats, steps-per-unit... + uint16_t ptr = 0; + chunk_float32 targetChunks[4]; + targetChunks[0] = { .bytes = { data[ptr ++], data[ptr ++], data[ptr ++], data[ptr ++] } }; + targetChunks[1] = { .bytes = { data[ptr ++], data[ptr ++], data[ptr ++], data[ptr ++] } }; + targetChunks[2] = { .bytes = { data[ptr ++], data[ptr ++], data[ptr ++], data[ptr ++] } }; + targetChunks[3] = { .bytes = { data[ptr ++], data[ptr ++], data[ptr ++], data[ptr ++] } }; + // more motor stuff + for(uint8_t m = 0; m < SR_NUM_MOTORS; m ++){ + smoothieRoll->actuators[m]->set_steps_per_mm(targetChunks[m].f); + } + // recheck max rates + smoothieRoll->checkMaxRates(); + // probably all OK + return EP_ONDATA_ACCEPT; +} + +endpoint_t* spuEp = osapBuildEndpoint("stepsPerUnitSettings", onSPUData); + +// -------------------------------------------------------- POWER MODES + +#define V5_ON PIN_HI(0, 11) +#define V5_OFF PIN_LO(0, 11) +#define V5_SETUP PIN_SETUP_OUTPUT(0, 11); PIN_LO(0, 11) +#define V24_ON PIN_HI(0, 10) +#define V24_OFF PIN_LO(0, 10) +#define V24_SETUP PIN_SETUP_OUTPUT(0, 10); PIN_LO(0, 10) + +// 5V Switch on PA11, 24V Switch on PA10 +/* 5v | 24v | legal + 0 | 0 | yes + 1 | 0 | yes + 0 | 1 | no + 1 | 1 | yes + +lol, pretty easy I guess: just no 24v when no 5v... +we also want to turn on in-order though: 5v first, then 24v, and 24v off, then 5v +*/ + +// track states +boolean state5V = false; +boolean state24V = false; + +void publishPowerStates(void); + +// make changes +void powerStateUpdate(boolean st5V, boolean st24V){ + // guard against bad state + if(st24V && !st5V) st24V = false; + // check order-of-flip... if 5v is turning off, we will turn 24v first, + // in all other scenarios, we flip 5v first + if(state5V && !st5V){ + state24V = st24V; state5V = st5V; + // publish, 24v first, and allow charge to leave... + state24V ? V24_ON : V24_OFF; + delay(50); + state5V ? V5_ON : V5_OFF; + } else { + state24V = st24V; state5V = st5V; + // publish, 5v first, and allow some bring-up... + state5V ? V5_ON : V5_OFF; + delay(10); + state24V ? V24_ON : V24_OFF; + } + // now ... would like to write to the endpoint + publishPowerStates(); +} + +EP_ONDATA_RESPONSES onPowerData(uint8_t* data, uint16_t len){ + // read requested states out + boolean st5V, st24V; + uint16_t rptr = 0; + ts_readBoolean(&st5V, data, &rptr); + ts_readBoolean(&st24V, data, &rptr); + // run the update against our statemachine + powerStateUpdate(st5V, st24V); + // here's a case where we'll never want to let senders to + // update our internal state, so we just return + return EP_ONDATA_REJECT; + // this means that the endpoint's data store will remain unchanged (from the write) + // but remains true to what was written in when we updated w/ the powerStateUpdate fn... +} + +endpoint_t* powerEp = osapBuildEndpoint("powerSwitches", onPowerData); + +void publishPowerStates(void){ + uint8_t powerData[2]; + uint16_t wptr = 0; + ts_writeBoolean(state5V, powerData, &wptr); + ts_writeBoolean(state24V, powerData, &wptr); + endpointWrite(powerEp, powerData, 2); +} + // -------------------------------------------------------- SETUP void setup() { @@ -191,6 +287,10 @@ void setup() { DEBUG3PIN_SETUP; DEBUG4PIN_SETUP; DEBUG5PIN_SETUP; + // setup the power stuff + V5_SETUP; + V24_SETUP; + powerStateUpdate(false, false); // osap osapSetup("modularMotionHead"); // ports @@ -212,13 +312,20 @@ void setup() { osapAddEndpoint(accelSettingsEp); // 7 // r8 settings osapAddEndpoint(rateSettingsEp); // 8 + // steps-per-unit settings + osapAddEndpoint(spuEp); // 9 + // power settings + osapAddEndpoint(powerEp); // 10 // smoothie (and frequency of loop below) - smoothieRoll->init(10000); + smoothieRoll->init(SR_TICK_FREQ); + smoothieRoll->checkMaxRates(); // 25kHz base (40us period) or // 20kHz base (50us period) // 10kHz base (100us period) // 5kHz base (200us period) - d51ClockBoss->start_ticker_a(100); + d51ClockBoss->start_ticker_a(1000000/SR_TICK_FREQ); + // test... + // powerStateUpdate(true, false); } unsigned long epUpdateInterval = 100; // ms @@ -228,7 +335,7 @@ void loop() { // main recursive osap loop: osapLoop(); // smoothie checks / etc: - //conveyor->on_idle(nullptr); + conveyor->on_idle(nullptr); // run 10Hz endpoint update: if(millis() > lastUpdate + epUpdateInterval){ DEBUG5PIN_TOGGLE; @@ -237,12 +344,16 @@ void loop() { updateSpeeds(); updateMotionState(); } - } // end loop // runs on period defined by timer_a setup: volatile uint32_t timeTick = 0; volatile uint64_t timeBlink = 0; + + +volatile uint8_t cachePtr = 0; +uint8_t stepCache[2]; // xyze: step & dir (8 bit) for two cycles + uint16_t blinkTime = 1000; uint8_t motion_packet[64]; // three floats bb, space @@ -258,6 +369,20 @@ void TC0_Handler(void){ // do step tick smoothieRoll->step_tick(); + // cache ticks + stepCache[cachePtr] = smoothieRoll->actuators[3]->get_step_mask() << 6 | + smoothieRoll->actuators[2]->get_step_mask() << 4 | + smoothieRoll->actuators[1]->get_step_mask() << 2 | + smoothieRoll->actuators[0]->get_step_mask(); + cachePtr ++; + + if(cachePtr > 1){ + DEBUG2PIN_TOGGLE; + ucBusHead_transmitA(stepCache, 2); + cachePtr = 0; + } + + /* // every n ticks, ship position? // each of these ticks drops 10 data bytes, so if we have 17 byte packet, can do every 2nd packet // which would occupy the full bus - notgood - or we can do every 3rd... I'll pick every 4th. @@ -281,6 +406,7 @@ void TC0_Handler(void){ ucBusHead_transmitA(motion_packet, 17); DEBUG2PIN_LO; } + */ // do blinking, lol timeBlink ++; diff --git a/firmware/motion-head/src/osape-d51 b/firmware/motion-head/src/osape-d51 index acbff5f3f0333d072780d32246ac15a6aa7f1a62..34b5c2d86fd126bc0074418404bea77e96d3dcae 160000 --- a/firmware/motion-head/src/osape-d51 +++ b/firmware/motion-head/src/osape-d51 @@ -1 +1 @@ -Subproject commit acbff5f3f0333d072780d32246ac15a6aa7f1a62 +Subproject commit 34b5c2d86fd126bc0074418404bea77e96d3dcae diff --git a/firmware/motion-head/src/smoothie/SmoothieConfig.h b/firmware/motion-head/src/smoothie/SmoothieConfig.h index 517fbea28721890a7afc5e2e894d745afdf89f4c..eb43cba9a654b8a1fc19bf50398fc0989491755c 100644 --- a/firmware/motion-head/src/smoothie/SmoothieConfig.h +++ b/firmware/motion-head/src/smoothie/SmoothieConfig.h @@ -8,6 +8,8 @@ // default accel #define SR_DEFAULT_ACCEL 5000.0F +// and tick period, in us +#define SR_TICK_FREQ 10000 // Keep MAX_ROBOT_ACTUATORS as small as practical it impacts block size and therefore free memory. const size_t k_max_actuators = SR_NUM_MOTORS; diff --git a/firmware/motion-head/src/smoothie/SmoothieRoll.cpp b/firmware/motion-head/src/smoothie/SmoothieRoll.cpp index 8591ae9a4b2afcece445246ed14bddc3fc84b609..127de94f2f85d2ab96e08f8f4727e811b5c5bccd 100644 --- a/firmware/motion-head/src/smoothie/SmoothieRoll.cpp +++ b/firmware/motion-head/src/smoothie/SmoothieRoll.cpp @@ -42,4 +42,15 @@ void SmoothieRoll::init(float frequency){ void SmoothieRoll::step_tick(void){ stepTicker->step_tick(); +} + +void SmoothieRoll::checkMaxRates(void){ + // we have frequency, SR_TICK_FREQ, and period which is 1000000/SR_TICK_FREQ + // we also have per-axis steps per unit, and max rates, + // if rate * spu exceeds the tick frequency, we are in trouble: + for(uint8_t m = 0; m < SR_NUM_MOTORS; m ++){ + if(actuators[m]->get_max_rate() * actuators[m]->get_steps_per_mm() > SR_TICK_FREQ){ + sysError("motor " + String(m) + " exceeds max rate"); + } + } } \ No newline at end of file diff --git a/firmware/motion-head/src/smoothie/SmoothieRoll.h b/firmware/motion-head/src/smoothie/SmoothieRoll.h index 7fff37932177d3f7d6c8ff226e45406238e0573c..f5d8e42f49dfd20afed30df5c2c7ea0677365e63 100644 --- a/firmware/motion-head/src/smoothie/SmoothieRoll.h +++ b/firmware/motion-head/src/smoothie/SmoothieRoll.h @@ -31,6 +31,7 @@ class SmoothieRoll{ static SmoothieRoll* getInstance(void); void init(float frequency); void step_tick(void); + void checkMaxRates(void); StepInterface* actuators[SR_NUM_MOTORS]; diff --git a/firmware/motion-head/src/smoothie/modules/robot/StepInterface.cpp b/firmware/motion-head/src/smoothie/modules/robot/StepInterface.cpp index bfb318d3e287ed77f8e7c57ee17a88a1c3f30a5c..defb0de02a3354675b371abb841f0209dc299f89 100644 --- a/firmware/motion-head/src/smoothie/modules/robot/StepInterface.cpp +++ b/firmware/motion-head/src/smoothie/modules/robot/StepInterface.cpp @@ -55,6 +55,15 @@ void StepInterface::set_accel(float acc){ accel = fabsf(acc); } +void StepInterface::set_steps_per_mm(float spu){ + steps_per_mm = spu; + mm_per_step = 1 / steps_per_mm; +} + +float StepInterface::get_steps_per_mm(void){ + return steps_per_mm; +} + float StepInterface::get_current_speed(void){ if(!moving){ return 0.0F; @@ -75,10 +84,23 @@ boolean StepInterface::step(void){ now = micros(); current_speed = (mm_per_step * 1000000) / (now - last_tick); last_tick = now; - + // upd8 step mask, is step-dir: + if(direction){ + step_mask = 0b00000011; + } else { + step_mask = 0b00000010; + } return moving; } +uint8_t StepInterface::get_step_mask(void){ + // stash the return + uint8_t mask = step_mask; + // reset this, + step_mask = 0; + return mask; +} + void StepInterface::set_direction(boolean dir){ direction = dir; } diff --git a/firmware/motion-head/src/smoothie/modules/robot/StepInterface.h b/firmware/motion-head/src/smoothie/modules/robot/StepInterface.h index 5e4813d1881a182dd41dfa0a895b2b7a5f151bd5..bed0a6123988f3f069f6563e31f44de41562b549 100644 --- a/firmware/motion-head/src/smoothie/modules/robot/StepInterface.h +++ b/firmware/motion-head/src/smoothie/modules/robot/StepInterface.h @@ -25,6 +25,8 @@ class StepInterface { void set_max_rate(float rate); float get_accel(void); void set_accel(float acc); + void set_steps_per_mm(float spu); + float get_steps_per_mm(void); // util to track speed per motor: float get_current_speed(void); @@ -36,6 +38,10 @@ class StepInterface { boolean is_moving(void); // could also use this structure to setup steps / mm, max accel, max rate per actuator + // yonder awkward step-mask-getter for network step-mask + volatile uint8_t step_mask = 0; + uint8_t get_step_mask(void); + // for net interface, volatile int32_t stepwise_position = 0; volatile float floating_position = 0.0F; diff --git a/log/ucbus-psu-breakout-log.md b/log/modular-motion-head-log.md similarity index 88% rename from log/ucbus-psu-breakout-log.md rename to log/modular-motion-head-log.md index c4d84a9a8b743d33d8e7854894d7b98ed018791f..25e3d5f0014d99f884f2996f3353af8bfa7d83bc 100644 --- a/log/ucbus-psu-breakout-log.md +++ b/log/modular-motion-head-log.md @@ -109,7 +109,19 @@ God bless, just a recursive overloaded function that was calling itself, when I OK I can try a 5v turn-on-off code. I guess I'll build my little one-motor-single-page-demo controller as well, sheesh. -- 5v src / sinks ? +OK these look setup, I'm going to build an example controller here... or in another repo? + +The 5v switch works, so I want a little demo-test for the 24v. + +Also at the control head... some tiny distributed statemachine w/ a front end. I have been thinking about this kind of structure - a UI coupled virtual machine. It'd be a good stopgap, but I think I should focus on the typeset OSAP work & what would be a more complete version of this type of thing. + +In any case, the 24v stress testing. I'll solder one of these heat beds up. This provides 2.3 Ohms, at 24v that's just about 250 watts, 10 amps: the PSU is rated for 350W. I could butcher one of these 30-pin ribbons, or just solder a few leads to the BFC pinout. #2, I think. + +Alright well here it goes ffs. Seems like it works, though I suppose that shouldn't be too surprising, the FETS are rated to like 50A each, there's two, and this is 10A. I think I'll stick some little fets on there anyways. + +- test power draw, heat buildup... +- watch power on scope, is it chill? +- test 24v w/ no usb power... ## Part Purchase