The scope function is slowly coming to life. It was really hard work to debug. It has to be real-time so I wrote it in assembler. All those unit conversions, trigger conditions, buffering and transmission via USB resulted in lots of opportunities to Murphy to screw me up. The bug with the most weired result was a SETQ before WRLONG with the argument set to the number of longwords instead of n-1 which resulted in a buffer overflow and some overwritten variable. Trigger is still not working in all modes, but it's getting better...
Have you seen the sliders at the bottom and the right side of the waveform display? They can be used to move the trigger point horizontally and vertically. In the picture the trigger point is in the center of the screen, so yes, pre-trigger recording is supported.
Some progress... I have bended the first prototype of the sheet metal case. Debugging the software takes the most time. I've found a few bugs in the compiler and lots more in my own code. Now, the auto-tuning of the current PID control loop is working. It automatically measures resistance and inductance of the motor windings. High level language and floating point arithmetic is really useful, here. I have to compensate parasitic effects like IGBT saturation voltage and dead time to get accurate measurements. But now, I come close to 1..2% of the readings of my LCR meter.
Did you leave enough space between Ethernet connectors for the wider housing of field wireable connectors? (Like profinet style?)
Good question. How wide are they? I think there is enough space in the left/right direction (in the picture) but not enough between the top and bottom RJ45 socket, the shielded one in the picture and the one on the optional extension board (not shown in the picture). It doesn't matter though as I can't think of an application where you need both. The bottom one is for optical encoder feedback, the other for resolvers.
can I ask what company is doing the metal fab and about what kind of cost is associated?
I've tried out several fabs but wasn't happy with the results. Only laser cut sheet metal is affordable in small batches. Mild steel is cheap but needs painting. Bare aluminium is too soft and chemically instable. It soon gets ugly due to fingerprints and scratches. Anodized aluminium doesn't cut well with lasers, too much dross and discoloring at the edges. Stainless steel is expensive and is too shiny for well readable labelling, IMHO.
So I use anodized aluminium which a friend of mine is milling on his home made router. Milling with a 1mm cutter at 50kRPM results in straight, smooth and dross free edges and the silky surface looks nice and can be labelled with laser printer adhesive film. I can't tell the exact cost since I don't pay him in cash but trade against hardware for his workshop. Maybe something around $2 per sheet. For bending I use my own manual knee lever press.
I forgot to say that the T-shaped cut-out with the holding tabs at the front face can be removed for the connectors of an optional daughter board. The main board only has connectors for the absolute required minimum configuration:
power and motor
encoder feedback (left RJ45)
command input (right RJ45, step/dir in, enable in, alarm out)
tuning and dioagnosis (RJ12, RS485 to PC)
The daughter board additionally offers
resolver feedback (upper RJ45)
analogue inputs (left terminals, command and tachometer)
digital IO (right terminals, holding brake, limit switches...)
The trick to anodizing is to do it after all the work is done. Since it is an immersion process, it really doesn't matter if it's bent into a finished shape as long as you don't trap air any place you want anodizing.
The typical way to produce that part is with a high speed rotary turret punch press. They take an entire sheet of metal and have a turret of tools that can punch hundreds of holes per minute. The edges are nibbled with slot shaped cutters and internal cutouts are often nibbled with a round cutter if not standard size.
They won't want to punch anodized aluminum because it'll wear their cutters out faster.
The trick to anodizing is to do it after all the work is done. Since it is an immersion process, it really doesn't matter if it's bent into a finished shape
I know, it doesn't matter for the anodizing process but it does matter for handling and shipping. The volume of the bent part is 50+ times higher than the flat sheet and the raw aluminium surface is very sensitive to scratches. You have to touch it with gloves only.
For masss production punching would be better. But for small batches I prefere processes I can also do in my own shop. Anodized sheet metal is available as standard material.
A whole lot can be done in your own shop. I agree. Given the thinner gauges, making bent parts can be done on a vice, or home brew break.
Saw someone 3d print tooling and bend parts on a common vice. (cool)
You are thinking process. Good. That's where some of the profit dollars are.
Jobs has been known to say, "there are no margins in shipped air."
The sheets are cheap because the anodizing tanks can do a ton of them too. Those people do quote by the batch, how many can be handled per batch, and operator time per batch. Sheets are ultra cheap.
While all the background stuff like ADC auto calibration, Park transformation, current control + PWM, encoder drivers and so on are quite complex and took a lot of time to develop, the core functionality of the servo drive looks amazingly small, efficient and sexy:
void VelCtrlLoop ()
// main loop for position + velocity control, running in a separate cog
{
InitFilterLut ();
float acc, vDiff;
int32_t t= cc->syncTime;
for (;;)
{
t+= vcCycleTime;
_waitcnt (t);
// command/nominal position filter
int in= GetPnom() - lastPnom;
sum1+= in - fifo1[i1];
fifo1[i1]= in;
if (++i1 > tf1) i1= 0;
sum2+= sum1 - fifo2[i2];
fifo2[i2]= sum1;
if (++i2 > tf2) i2= 0;
cmdVel= sum2;
pFilt+= sum2;
lastPnom+= in;
// position control
int32_t pActRaw= GetPact();
pDiff= pFilt - pActRaw - pOffs;
nomVel= pDiff * pGain + cmdVel * cGain; // P+FF
// velocity observer
actVel= (pActRaw - lastPact) * PosToRadFactor;
lastPact= pActRaw;
if (useObserver)
{
acc= cc->currActQ * currToAccFactor;
actVel= GetFilterOutput (&lpf, actVel) + GetFilterOutput (&hpf, acc);
}
// velocity control
vDiff= nomVel - actVel;
vAccu+= vDiff;
LIMIT (vAccu, intLimit);
acc= vDiff * vGain + vAccu * iGain; // PI
LIMIT (acc, accLimit);
cc->currNomQ= acc / currToAccFactor;
velTime= _getcnt() - t; // ~94µs or 17k cycles
}
}
It all breaks down to a number of linear operations like averaging, differenciation, scaling and summing. All position values are of integer type to avoid rounding errors. All velocity and acceleration values are floating point, so there's no need for shifting and no danger of overflows for a wide range of motor characteristics. Simple pre-calculated scaling factors do the job.
BTW, GetPact and GetPnom are function pointer variables. So the actual signal sources are configurable allowing for different types of encoders and command input interfaces like step/dir, incremental encoders and several brands of absolute encoders. PosToRadFactor takes care of the input resolution so that the velocity always scales in rad/s independent of encoder resolution. currToAccFactor expresses the ratio of current to acceleration and includes the torque constant (Nm/A) of the motor and the rotor inertia.
It's amazing how powerful the P2 is. Even without a hardware FPU the whole loop only takes ~13000 cycles without and ~17000 cycles with observer and filtering (that's ~50% of vcCycleTime). And because of the built in floating point math of the C compiler (again, great job, Eric!) the code looks very clear... one of the reasons I've choosen C instead of Spin.
I'm still debugging, so no guarantee that the code above will actually work. pOffs is short form for "position offset", of course. As I use absolute encoders I can't just start counting at the current position. I have to add an offset to cancel out the position error at the time the servo is enabled, first.
It's always difficult with jokes if not natively a speaker, so there is this silent majority. Silent just to be not the loving stock of the world! We remember to draw the joke in the old times at the oldtimers
I'm still debugging, so no guarantee that the code above will actually work. pOffs is short form for "position offset", of course. As I use absolute encoders I can't just start counting at the current position. I have to add an offset to cancel out the position error at the time the servo is enabled, first.
Not a joke, buddy. I'm just delighted that this is nothing of a task for the P2.
I have been repeatedly stating that Chip has unwittingly created the ultimate motion controller...and it's a general purpose MCU.
Lower performance, single axis, dedicated devices sell for $30+
Comments
Will it be DIN rail mountable? Mounting tabs?
Did you leave enough space between Ethernet connectors for the wider housing of field wireable connectors? (Like profinet style?)
This looks really clean!
Good question. How wide are they? I think there is enough space in the left/right direction (in the picture) but not enough between the top and bottom RJ45 socket, the shielded one in the picture and the one on the optional extension board (not shown in the picture). It doesn't matter though as I can't think of an application where you need both. The bottom one is for optical encoder feedback, the other for resolvers.
I've tried out several fabs but wasn't happy with the results. Only laser cut sheet metal is affordable in small batches. Mild steel is cheap but needs painting. Bare aluminium is too soft and chemically instable. It soon gets ugly due to fingerprints and scratches. Anodized aluminium doesn't cut well with lasers, too much dross and discoloring at the edges. Stainless steel is expensive and is too shiny for well readable labelling, IMHO.
So I use anodized aluminium which a friend of mine is milling on his home made router. Milling with a 1mm cutter at 50kRPM results in straight, smooth and dross free edges and the silky surface looks nice and can be labelled with laser printer adhesive film. I can't tell the exact cost since I don't pay him in cash but trade against hardware for his workshop. Maybe something around $2 per sheet. For bending I use my own manual knee lever press.
- power and motor
- encoder feedback (left RJ45)
- command input (right RJ45, step/dir in, enable in, alarm out)
- tuning and dioagnosis (RJ12, RS485 to PC)
The daughter board additionally offersVery, very impressive, my friend.
I don't suppose you're anywhere close to the Nurburgring track are you?
I have a client there. Would be cool to hook up for a few beers, some day
No, I'm 350km south of the Nurburgring. But I sometimes visit a friend and a client in Dortmund and the Nurburgring then would be only 20km detour.
The typical way to produce that part is with a high speed rotary turret punch press. They take an entire sheet of metal and have a turret of tools that can punch hundreds of holes per minute. The edges are nibbled with slot shaped cutters and internal cutouts are often nibbled with a round cutter if not standard size.
They won't want to punch anodized aluminum because it'll wear their cutters out faster.
I know, it doesn't matter for the anodizing process but it does matter for handling and shipping. The volume of the bent part is 50+ times higher than the flat sheet and the raw aluminium surface is very sensitive to scratches. You have to touch it with gloves only.
For masss production punching would be better. But for small batches I prefere processes I can also do in my own shop. Anodized sheet metal is available as standard material.
Saw someone 3d print tooling and bend parts on a common vice. (cool)
You are thinking process. Good. That's where some of the profit dollars are.
Jobs has been known to say, "there are no margins in shipped air."
The sheets are cheap because the anodizing tanks can do a ton of them too. Those people do quote by the batch, how many can be handled per batch, and operator time per batch. Sheets are ultra cheap.
All that leaves room for us to make a few bucks.
BTW, GetPact and GetPnom are function pointer variables. So the actual signal sources are configurable allowing for different types of encoders and command input interfaces like step/dir, incremental encoders and several brands of absolute encoders. PosToRadFactor takes care of the input resolution so that the velocity always scales in rad/s independent of encoder resolution. currToAccFactor expresses the ratio of current to acceleration and includes the torque constant (Nm/A) of the motor and the rotor inertia.
It's amazing how powerful the P2 is. Even without a hardware FPU the whole loop only takes ~13000 cycles without and ~17000 cycles with observer and filtering (that's ~50% of vcCycleTime). And because of the built in floating point math of the C compiler (again, great job, Eric!) the code looks very clear... one of the reasons I've choosen C instead of Spin.
13,000
Sorry, I don't get the joke...
I'm still debugging, so no guarantee that the code above will actually work. pOffs is short form for "position offset", of course. As I use absolute encoders I can't just start counting at the current position. I have to add an offset to cancel out the position error at the time the servo is enabled, first.
Not a joke, buddy. I'm just delighted that this is nothing of a task for the P2.
I have been repeatedly stating that Chip has unwittingly created the ultimate motion controller...and it's a general purpose MCU.
Lower performance, single axis, dedicated devices sell for $30+
Awesome job
Today, I gave my P&P machine some food:
+1
Nice. Good to see double sided placement used with P2