Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.
Category: Science
If you measure something often enough, it becomes science
Plotting the motor RPM every 500 ms while increasing the nominal current by 50 mA per step from 550 mA:
Motor RPM vs Current Steps – Accelerating
And then downward from 950 mA:
Motor RPM vs Current Steps – Decelerating
No, the steps aren’t the same size going down as they are going up. The nominal current setting is open-loop = constant DAC values: the actual current for a given DAC value varies as the transistors heat up.
The motor starts running at 3700 RPM with 550 mA and stops well under 1000 RPM with 400 mA. Obviously, starting slowly and smoothly will require finesse: a swift kick of maybe 600 mA to get it turning, then immediately drop to 400-ish mA for slow stitching. Those currents must be the actual motor current, not the nominal DAC values, so the motor sees the proper current regardless of the transistor temperature.
The sewing machine requires four samples = two seconds to stabilize at each new speed on the way up, so the mechanical time constant is 2/3 second. Trying to stabilize the speed with a loop running much faster than that will certainly cause oscillation.
There is absolutely no deceleration control authority: reducing the current allows freewheeling as the machinery slows down to match the current. The undershoot after each step on the way down lasts 2.5 s, then there’s a persistent oscillation with a period of 3 s.
Forcing the firmware to run slowly enough to match the hardware should pose an interesting challenge… you don’t want to lock up the UI while the motor stabilizes!
The first task: produce an equation that converts raw ADC values into actual motor current. This is not quite the same as the DC calibration, because the motor current is neither clean nor stable.
Step the output current setpoint in 50 mA increments from 450 mA to 1100 mA and remain at each setpoint for 10 seconds while dumping measurements every 500 ms. The ADC count comes from the sampling / sorting / selection process that attempts to pick out either the not really flat top of the current-limited waveform or the peak of the non-limited sine wave.
Convert the raw data dump into a spreadsheet to get a block like this for each current setpoint:
Motor RPM
Shaft RPM
Setpoint mA
DAC count
ADC count
Noisy mA
Comp mA
Setpoint: 600
DACvalue: 2372
3797
334
600
2372
266
724
540
4465
399
600
2372
263
715
532
4734
416
600
2372
265
721
538
4834
438
600
2372
263
715
532
4829
433
600
2372
264
718
535
4857
438
600
2372
264
718
535
4900
438
600
2372
265
721
538
4859
436
600
2372
266
724
540
4887
445
600
2372
265
721
538
4926
446
600
2372
263
715
532
4884
438
600
2372
265
721
538
4890
442
600
2372
264
718
535
4913
440
600
2372
264
718
535
4866
436
600
2372
263
715
532
4895
434
600
2372
264
718
535
4890
442
600
2372
266
724
540
4884
438
600
2372
266
724
540
4913
442
600
2372
265
721
538
4913
441
600
2372
266
724
540
4878
436
600
2372
264
718
535
265
The lone number on the bottom row is the computed average of the ADC counts for the block, which I did in the spreadsheet rather than in the firmware.
During each ten second interval, set the scope voltage cursor to the eyeballed “correct” value of the motor current waveform, as measured on the Tek current probe. There’s no way to automate this, because only the human eyeball can pick out the, ah, true current measurement amid all the clutter:
Calibrate – Hall amp – Tek 200 mA-div
For each current setpoint value, create a line with the manually measured true voltage from the scope trace, the calculated true current (using the Tek probe’s front panel scale), along with the DAC setpoint and the average ADC values extracted from each block of that giant data dump:
Setpoint mA
Scope mV
Actual mA
DAC count
ADC count
450
21.80
436
2205
197
500
25.94
519
2261
225
550
29.06
581
2316
245
600
31.56
631
2372
265
650
34.38
688
2427
285
700
36.88
738
2483
304
750
39.69
794
2538
324
800
42.19
844
2594
340
850
45.00
900
2649
350
900
47.50
950
2705
361
850
46.86
937
2649
356
800
43.75
875
2594
348
750
41.25
825
2538
335
700
39.06
781
2483
318
650
36.56
731
2427
302
600
34.38
688
2372
285
550
32.50
650
2316
270
500
30.31
606
2261
253
450
27.81
556
2205
237
400
25.63
513
2150
220
Plot each actual motor current against the corresponding average ADC value:
ADC Calibration Curve
The linear fit breaks down toward 1 A, because measuring the actual peak of a noisy sine wave doesn’t work well, but the values aren’t all that far off.
Given an ADC value, that equation converts it directly into the actual motor current as estimated by the human eyeball, taking into account all the measurement weirdness. The Hall sensor produces a voltage that’s linearly related to the current, so the reasonable linearity of the data says that the sampling / sorting / selection process actually produces pretty nearly the correct result across the entire operating current range.
Note that the equation doesn’t depend on the DAC output calibration; the ADC and Tek probe simply measure whatever current happens to pass through the motor for that DAC value. The current through the ET227 transistor doesn’t seem to change over the ten seconds required to take the manual measurement, so it’s all good.
Based on the poor performance of the NB-5L batteries I bought from Blue Nook, they sent me three NB-5L batteries from a fresh batch (date code BNI13) and I ran them through the same discharge test:
Canon NB-5L – OEM Wasabi – 2014-10-29
The red line off to the far right is the three year old Canon OEM battery, which remains far and away the best battery at 1 A·h.
The previous cells (BNF27) produced the three scattered traces with the lowest initial voltages, ending around 0.8 A·h.
The new cells (BNI13) produced the three tightly clustered traces. They have a higher initial voltage than the OEM cell, but much lower total capacity (about 0.75 A·h).
These batteries obviously don’t come close to their 1400 mA·h rating. The capacity depends on the load current, but I’m using 500 mA because that’s close to the camera’s drain; the results should correlate reasonably well with actual use.
The higher voltage from the new batteries will produce a longer runtime than the previous duds, but their total capacity is lower and they’re still no match for the old Canon OEM battery.
The new ones start out very similar to each other, but the previous batch hasn’t aged well on their shelf. If the date codes mean what I think, all of these batteries will fail quickly.
All that’s quite disappointing, because their NP-BX1 batteries for the Sony camera turned out quite well. The date codes all have the same format and typography, so I think they come from the same factory.
For whatever it’s worth, I think the date coding works like this:
B – factory? shift? OEM? Blue Nook?
M – last two digits of year: M=13, N=14
K – month: F=6, I=9, K=11
20 – day
For the four batteries / lots I have on hand:
BMK20 = 2013 Nov 20 – NP-BX1 bought in early 2014
BNI18 = 2014 Sep 18 – NP-BX1 bought in October – new lot
BNF27 = 2014 Jun 27 – NB-5L bought in October – old lot
BNI13 = 2014 Sep 13 – NB-5L supplied in late October – new lot
Because the ET227 transistor acts as a current limiter, the motor current waveform has flat tops at the level set by the DAC voltage. However, the current depends strongly on the temperature of all those transistor junctions, with some commutation noise mixed in for good measure, so the firmware must measure the actual current to know what’s going on out there.
Here’s one way to pull that off:
Motor current – ADC sample timing
The upper waveform shows the motor current sporting flat tops at 650 mA.
The lower waveform marks the current measurement routine, with samples taken just before the falling edge of the first nine pulses. The (manually tweaked) delay between the samples forces them to span one complete cycle of the waveform, but they’re not synchronized to the power line. Remember that the motor runs from a full wave rectifier, so each “cycle” in that waveform is half of a normal power line cycle.
Given an array containing those nine samples, the routine must return the maximum value of the waveform, ignoring the little glitch at the start of the flat top and taking into consideration that the waveform won’t have a flat top (or much of a glitch) when the current “limit” exceeds the maximum motor current.
After a bit of fumbling around with the scope and software, the routine goes like this:
Collect samples during one current cycle
Sort in descending order
Ignore highest sample
Return average of next two highest samples
Given that the array has only nine samples, I used a quick-and-dirty bubble sort. The runt pulse at the end of the series in the bottom waveform brackets the sort routine, so it’s not a real time killer.
Seeing as how this is one of the very few occasions I’ve had to sort anything, I wheeled out the classic XOR method of exchanging the entries. Go ahead, time XOR against swapping through a temporary variable; it surely doesn’t make any difference at all on an 8-bit microcontroller.
The sampling code, with all the tracing stuff commented out:
//------------------
// Sample current along AC waveform to find maximum value
// this is blocking, so don't call it every time around the main loop!
#define NUM_I_SAMPLES 9
unsigned int SampleCurrent(byte PinNum) {
unsigned int Samples[NUM_I_SAMPLES];
unsigned int AvgSample;
byte i,j;
// digitalWrite(PIN_SYNC,HIGH);
for (i=0; i < NUM_I_SAMPLES; i++) { // collect samples
// digitalWrite(PIN_SYNC,HIGH);
Samples[i] = ReadAI(PinNum);
// digitalWrite(PIN_SYNC,LOW);
delayMicroseconds(640);
}
// digitalWrite(PIN_SYNC,LOW);
// digitalWrite(PIN_SYNC,HIGH); // mark start of sorting
for (i=0; i < (NUM_I_SAMPLES - 1); i++)
for (j=0 ; j < (NUM_I_SAMPLES - 1 - i); j++)
if (Samples[j] < Samples[j+1]) {
Samples[j] ^= Samples[j+1]; // swap entries!
Samples[j+1] ^= Samples[j];
Samples[j] ^= Samples[j+1];
}
// digitalWrite(PIN_SYNC,LOW); // mark end of sorting
// printf("Samples: ");
// for (i=0; i < NUM_I_SAMPLES; i++)
// printf("%5d,",Samples[i]);
AvgSample = (Samples[1] + Samples[2])/2; // discard highest sample
// printf(" [%5d]\r\n",AvgSample);
return AvgSample;
}
Using basically the same Arduino firmware as before, so the pedal scales the motor current without feedback:
Curr Sense RPM Spindle Pos
The top trace is the motor current, sampled through the ferrite toroid / Hall effect sensor / differential amp, at about 525 mA/V, so the current limit along those flat tops is 630 mA. There’s a small initial spike leading into each flat top, where (I think) the rapidly rising collector voltage rams enough current through the Miller capacitance into the base to briefly push the collector current upward.
The next trace is the motor RPM sensor, ticking along at 14 revolutions in 160 ms = 87.5 rev/s = 5250 RPM. The glitch toward the right side comes from me hitting the scope’s STOP button to freeze the display in mid-trace. There’s no trace of the setscrew glitch, although that may be due to the compressed scale rather than the absence of the glitch.
The bottom trace is the shaft position sensor, with 1 rev in 125 ms = 8 rev/s = 480 RPM. It’s nicely divided into equal halves, which is what you’d expect from looking at the counterweight.
Under these conditions the speed ratio works out to 10.93, a whopping 9% over my original guesstimate.
The soil temperature near the base of the bird box, under a few inches of chipped leaf mulch, shows the expected trend for the growing season, but there’s a weird bump in mid-October:
Garden Soil Temperature
The NWS temperature summary confirms the anomaly, with the DEP column giving the departure from the historic average:
So the good folks in the wordpress.com support infrastructure have been manually exporting my blog and sending me a link to the ZIP file, pursuant to the still unresolved failure-while-exporting issue. A bit of back-and-forth around the latest backup / export produced an interesting data point:
The message about the export file not being found is simply an indicator that the huge export could not finish compiling before a more general time limit was reached — in this case because your site is easily in the top .1% for size. I will pass your suggestion for improved exporting along.
I’m sure that’s among the freebie blogs on wordpress.com, but I never thought of myself as a member of the 0.1% club.
Huh. Snuck up on me while I wasn’t paying attention. If I could do that with money, I’d be on to something.
I’ve never participated in their post-a-day challenges, because that’s what I do around here. Should you find something interesting, every now and again, that’s a bonus.