Lepton Deku mod

Awesome, glad it’s working out.

Correct, there are multiple solutions. The reason is that this allows you to fine tune the clocks of the various sub-systems of the MCU, as you found out by messing the UART timing.


Just out of curiosity I tried one of the old sensor placements again (green dots on the diagram), and whaddya know, it works! The usual preferred direction spins about 5% faster, but both are equally smooth and have similar scatter in the sensor intervals (around 630-830us and 660-860us).

But I do find it interesting that the cyan placement resulted in 20-25% higher top speed in the good direction (500-700us). I wonder if it would be better to stick with how I have it now, or try the other again and advance the electrical angle by 60 degrees when going the bad direction. Maybe it will smooth out and run fast too. But it may be performing some crude field weakening, getting that high speed at the cost of requiring more current to produce the same torque.

On to tuning velocity mode. First attempt with P=0.2, I=2, D=0 from the example vibrated horribly and wouldn’t stop. Second attempt with my “wait for sensor change” code removed (so it’s running motor.move/loopFOC at the highest possible rate now) wouldn’t move at all for a while, then vibrated for a while, then went back to not moving.

EDIT: Yep, I’m pretty sure yellow/green is the correct sensor placement and cyan is field weakening in one direction. I tried converting those microsecond times into RPM, and got this (I’m running at 2 volts, so kv is RPM/2):
600us = 2778RPM = 1388kv
730us = 2283RPM = 1141kv
760us = 2193RPM = 1096kv

The motor was originally listed as 2300kv, and I rewound it from 29 turns delta to 36 turns wye, so it should theoretically be 2300 * 29 / 36 / sqrt(3) = 1070kv.

1 Like

@runger I’ve found a tricky bug.

float HallSensor::getVelocity(){
  if (pulse_diff == 0 || ((long)(_micros() - pulse_timestamp) > pulse_diff) ) { // last velocity isn't accurate if too old
    return 0;
  } else {
    return direction * (_2PI / (float)cpr) / (pulse_diff / 1000000.0f);

Sometimes it returns infinity due to divide by zero, because pulse_diff is volatile and can be changed by interrupt. It needs to be cached in a local variable before checking if it’s equal to zero.

Thanks for finding this!
I’ve made a ticket: HallSensor.cpp volatile accèss bug · Issue #244 · simplefoc/Arduino-FOC · GitHub
and we’ll solve it for the next release…

While researching online, I did find companies that make bus bars suitable for automated assembly. None were cheap. Some can be soldered with paste in an oven and some used through holes.

Google “solderable bus bar” and you get lots of hits.

As for increasing current carrying ability by placing solder on traces. It does not work well. Generic solder has only on order of 10% the conductivity of copper. It can be as good as 40% if you use solder with a high silver content. But you likely want the lowest melting solder you can find for this

A simple solution, I have a vacuum tube based guitar amplifier made by Fender. It is a newer design that uses a PCB. Finder used a twisted pair of normal vinyl insulated wire for a high current path. It is loose with plenty of airspace under it.

Your solution seems ideal if you are making a few dozen PCBs,

I wanted what Tesla does? They make many thousands of cars with 100+ amp BLDC motor drivers.

The right solution for a few dozen boards will probably not be the right solution for thousands of boards. If you really are planning for ‘tesla’ scale you should probably start talks with a couple of PCB manufacturers and have your engineers hash out what each of them can do for your currents and at what price. About the wire solution as used in your amp, as far as I understand it (so check it with an actual engineer) these solder connection can degrade due to shock and vibe so it might no be the best solution for a robot.

I have also been thinking about high current capacity boards and what I can do within the limits of LCSC/JLCPCB (2oz copper). There is a nice thread at eevblog on high current capacity traces. I’m torn between soldering wire on top of the trace, getting plated slots and soldering in a ‘busbar’ (cut up some copper sheets myself) or just keeping the traces very short and having board to wire connections for each of the phases instead of using traces to distribute power.

With Tesla’s style of vertical integration, you could just make whatever size of bus bars you need in-house and load them on your pick-and-place machine :slight_smile:

One thing I’ve been thinking of trying is to replace those solder blobs with little copper blocks, maybe 1.5x1x3mm. I’m not sure if I could solder them with an iron, but probably could with low temp solder paste and a hot plate. I could even do the bars on the back at the same time, though I may have to give up the ceramic capacitors.

On the software side of things, I finally have angle control! 5 long years I’ve struggled with this. I feel like I need to write an academy award speech thanking everyone for your various contributions :stuck_out_tongue:

My velocity PID values are 0.1, 1.5, 0. Low-pass filter is 0.05, and angle P is 8. I still have a little more investigation to do because the voltage-based current limit doesn’t seem to be working, but that’s not essential.

One more trick I used is to restrict the target angle to cogging steps. Otherwise it jitters between them instead of settling.

target_angle = floor(target_angle / (_PI_3/motor.pole_pairs)) * (_PI_3/motor.pole_pairs);

Next I will try a 2208 motor that I already have set up with hall sensors which are probably in good locations, so hopefully it will be no trouble. That should allow testing up to 10-15 amps, and get a feel for how much the copper bars boost the current carrying capacity compared to one of the other boards without them.

EDIT: Turns out the current limit was working, I just wasn’t changing it on the fly properly. motor.current_limit only works before initialization, afterward you have to change motor.PID_velocity.limit. So now I can crank up the speed. I currently have it set to a fairly conservative current limit 1.5, voltage limit 4 and velocity limit 5000. I’ve also got it set up to skip calibration and initialize the sensor electric_rotations and electric_sector to the values I get when the servo tester is all the way to the left, so there’s no more jumping at startup. Now I can actually put this little linear actuator to use :slight_smile:


Did you have an angle sensor in this setup or only hall sensors? Because it should be able to settle at any position if you have an angle sensor.

My mechanical designs never have access to the end of the shaft for a magnetic angle sensor, so hall sensors are pretty much the only choice. Positioning is plenty precise as is, but I could still give linear halls a try for smoother motion and so I don’t have to solder all those tiny capacitors between the leads.

Here is the actuator in actual use :slight_smile: It works every bit as well as I’d hoped.




Magnetic sensors aren’t the only option and some of those options don’t need access to the end of the shaft, something like an AMT103 can fit an up to 8mm shaft going through it and other (more expensive) options can fit wider shafts. That seems unnecessary for your application though as the video shows it working very well in that amazing wing you made.

True, but AMT103 is bigger than the actuator :slight_smile:

I decided to give it a try soldering copper blocks below the MOSFET GND pins with an iron. I soaked up the old solder blobs as best I could with desoldering braid, but there was still enough left that it was difficult to get them in just the right place. After much heating and prodding with tweezers, they’re all half way decent. Paste and hot plate would be better.

1 Like

Those boards are tiny. They could potentially be used for PNP head actuator for rotating the part while the linear motion is pneumatic, air controlled, piston w. linear magnetic encoder. I remember back when I was engaged in the PNP community someone mentioned pneumatic linear control as a superior route. It still needs to rotate though, and the part has to be picked by vacuum, maybe even blown off, although the paste does grab the part. The part is analyzed by the up looking cámara w. Visual recognition for offset and rotation. It’s not safe to just rely on pick-up-coordinate and theoretical orientation, or maybe some parts like small Caps and resistors could work with a 0.1mm tolerance.

Pneumatic control is an entirely different ballgame, I know, I know. But perhaps PWM control is needed for that kind of piston/valve movement

Maybe we can 3d print the valve/piston housing and more or less just use basic coils with a well defined spring to counter the force (make it easier to control)

I’m afraid I have to Excalibur this a bit. Maybe it doesn’t need to be so complicated. What if, like when changing nozzle, the part could be rotated while being looked at by the up-looking cam. So the rotating mechanism/actuator would not need to be part of the head, but kind of like a robotic hand, nodging the part into the right angle. When rotated the cam then “sees” the offset, if any, and then moves on to the next part already picked (head w. eg. 10 linear pneumatic actuators). All controlled by SimpleFoc! :call_me_hand:

And OpenPnP of course…

Sometimes ideas like these has to be digested through some subconscious deep-dive (sleep). I think I’ve got it. So when the part has peen picked, and are ready for visual inspection by the up looking cam. The actuator plunges into a camera housing where the “entrance” is a soft maybe rubber BLDC roter. The actuator has a linear encoder attached so the movement is tightly controlled but still the “entrance” has some bounce/spring. So it’s rotating the part, if necessary, by friction while the actuator is resting on the soft rotor while the part is inside the housing for visual inspection. Tada :tada:

Large parts, like larger then the rotating entrance, would maybe need a small independent motor (stepper or bldc) but since 98% of the parts will fit inside the custom housing, only one of the linear actuators/PNP-nozzles will need it. Compared to 10 motors on the head this makes a huge difference.

This entails having two up-looking cameras, but that is actually not such a bad idea, because the camera inside the “custom housing” can have a close look at smaller parts (fixed focal length) and the other up-cam can “see” the larger parts in its view. Remember 0402 are really tiny. Having the same camera with fixed focal length look at 0402 caps and large MCUs may cause some detail issues or said in other words, if the cam has a close look at 0402 the visual recognition is smoother.

Maybe it does not need to be friction, but large “gears” which would need some clever code to match up when “docking”

1 Like