What happened before:
For almost a year I have a vintage turntable from Perpetuum Ebner at home. It's not mine. It belongs to someone that asked me to fix it. And it turned out that fixing the motor would cost too much. I asked the owner to collect the tt. That hasn't happened yet and the machine is collecting dust at my home.
So I'll take the freedom to attempt a non-intrusive repair with modern components. I'm also thinking about making it an Enchanted Objects Design Challenge. |
In post 1 I present the turntable, talk about my previous repair attempts and brainstorm on some modding ideas.
In post 2 I'm measuring up the different gears, pulleys and wheels, and I calculate the speed of the original motor.
Post 3 is the first post on motor control. I'm reviewing the operation of the Infineon DC Motor Control Shield.
In post number 4 I'm using the enhanced PWM module of my The specified item was not found. Hercules LaunchPad to test drive the motor.
The table is spinning for the first time in post 5.
In post 6, I put it all together. I now have a turntable that works, with PWM speed regulation.
In post 7, I harvest a speed sensor from a video recorder and test it out.
This blog is a follow up on the speed sensor integration. I'm sampling the motor speed with the microcontroller.
I'm using a microcontroller in my setup since post 4. The Hercules LaunchPad ePWM module drives the motor speed. I'll now use the eCAP module to sample the speed sensor from the previous post.
The first thing I noticed when hooking up my sensor to the microcontroller was that my design didn't drive the infrared receiver enough. In isolation it was working ok, but it didn't get enough light from the mirror to drive the controller's input.
I could have solved it by giving the IR transmitter more current. But when I tried that, I started to get more noise. The increased IR beam started to reflect on the 'non-shiny' parts of the pulley surface. I also didn't want to push my transmitter to its limits.
Plan B is to add a buffer. I tried it out a one transistor amp with a jellybean NPN. That works out very nice.
You can see that my signal is inverted because of this (see scope image in the previous post). That doesn't matter. I'm only interested in the interval between to rotations and can derive that from the inverted signal too.
Now I have enough drive for the controller's input. Over to the firmware.
The program
The RM46x microcontroller that I'm using has a module called eCAP that is specifically suited to sample digital signals.
The turntable repair is just an excuse to learn the features of the RM46x, so after today I can check off ePWM and eCAP from my bucket list.
eCAP
eCAP stands for enhanced Capture. With very little code I can get the period of my sensor signal.
And that period is exactly the same as one rotation of the tapped pulley.
To get the interval between two sensor pulses, we can configure the eCAP driver this way:
Listen to the signal's edges. There are 3 edges that define a period:
- a rising edge when the mirror reaches the sensors and reflects the beam. It defines the start of the measurement
- a faling edge when the mirror has fully passed under the sensors and the beam isn't reflected anymore. I ignore that flank at the moment because I'm not interested in the duty cycle.
- a new rising edge when the mirror has gone full circle and reflects the beam. It defines both the end of this turn and the start of a new one.
To make the magic work, you have to set up a few things in HALCoGen. First enable the eCAP driver and module eCAP1 (I use the first out of 6 capture modules).
Then you have to configure that eCAP1 to reflect the scenario described above:
These settings will generate the framework, and our interrupt service routine will get called at edge 3.
In our firmware, we have to make these two function calls to get the eCAP module running.
_enable_interrupt_(); ecapInit();
Our ISR reads the values of the first and third edge,and stores the gap between them (the period of one turn of that pulley) in a variable for later use in our feedback loop.
volatile uint32 uDelta = 0u; // ... void ecapNotification(ecapBASE_t *ecap,uint16 flags) { uint32 cap_1, cap_3; cap_1 = ecapGetCAP1(ecapREG1); cap_3 = ecapGetCAP3(ecapREG1); uDelta = cap_3 - cap_1; }
The variable is marked as volatile because we are setting it in an interrupt call and we'll be using it later in the main thread of our code.
For today's post, I'm sending the period value to the console when user button A is pressed. But that's just to show the results in my prototype.
while(1) { if (! gioGetBit(gioPORTB, 2)) { printf("delta = %u\n\n", uDelta); }
The end game is to check this value on a regular base and use it to drive the duty cycle of the PWM motor signal.