09/12/2017 at 23:22 •
Initially, I thought I could just use acceleration on the z axis to turn the POV on and off. Since acceleration due to gravity was large compared to other accelerations (I thought), the z axis should tell me when I had picked up the POV (z acceleration low since the z axis would be perpendicular to gravity) and when I had put it down (z acceleration about 1G). What I quickly learned was that the force of my finger giving the POV a spin caused z accelerations as well as rotational accelerations. Although they didn't last long, they messed up my clever on-off scheme. Putting in time delays impacted the POV display and still didn't make it work.
Since I couldn't solve the on/off problem, I decided to split it into two problems: turn on and turn off. Reading over the accelerometer data sheet suggested a reliable way to turn the POV on: use double-tap. The ATTINY84 goes to sleep when it shuts off (discussed next), then the accelerometer issues an interrupt when it senses a double-tap. After spending some time tuning the sensing constants, I got this working reasonably well. Sometimes takes a few taps to get it going, but that's only mildly annoying. I'm sure more tuning could make the double-tap work better; I just wanted to get on with the project.
Once I understood how the accelerometer actually worked, it wasn't hard to get a turn off algorithm working. Acceleration of 1G on the z axis is sensed as originally implemented, but I also check that the x axis acceleration is small. That only happens when rotation has stopped. Basically, these two conditions mean that the POV must be laying on it's side and stopped. Now z accelerations which occur when the Fidget is given a hard spin don't cause a shut off. When the turn off condition is sensed, the ATTINY84 enters sleep mode and waits for the double tap event to occur.
The final control problem was to start the text display at a consistent location in the rotation to stabilize the display. Before I really understood the accelerometer response, I tried to use the 4D motion sensing capability of the accelerometer to determine when to display the text. But the algorithm uses only one value as a limit. If that is exceeded either by x or y accelerations, then the 4D interrupt is activated. Since y was always large, it dominated the response and kept 4D from being useful. Once I understood the accelerometer response, then I was able to just use an x value to position the display. That worked quite well and is part of my final program, T84_POV_Click_Text.ino. I'll create a video soon to show the POV in action.
09/12/2017 at 04:37 •
Soon, I will add a complete parts list, but I intend to provide Digikey links and that will take some time to put together. For now, it's perhaps helpful to say the accelerometer I'm using is the LIS2DE12 by ST. It's tiny (2mm square), cheap (< $2 in onesies), and has an easy I2C interface. Three tasks seemed reasonable for the accelerometer: Turn on the Fidget POV when I want to play with it, put it to sleep when I'm done, and stabilize the display of the text. (This last task is one I didn't anticipate until I actually put up the first letters. When I saw how they jumped around, I realized that stabilization was necessary!) Easy enough, I thought. But I soon discovered that accelerometers are not intuitively understood devices, at least not by me. What I will discuss in the following took me almost a month to figure out. I'll try to spare you all the sordid details, but still hit the key points.
My initial assumptions included:
- radial acceleration due to rotation was small - less than 1G.
- tangential acceleration due to rotation was negligible.
- the positive directions for sensing were as shown in the accelerometer data sheet.
Based on these assumptions, I selected the +/-2G scale and expected mostly positive values of acceleration. But nothing worked as I expected! So I had to do some testing. (Those last two sentences took a couple of weeks of experimenting!) There was no easy way to read out exact values of acceleration. Storing values in EEPROM and reading them back with avrdude was considered, but I couldn't figure out how to start gathering data at an "interesting" point. Then I realized that I could use the leds to indicate acceleration levels! Turned out to be a great idea and guided me to an understanding of the accelerometer. For anyone who would like to repeat my experiments, have a look at T84_POV_Test_Accel_Max.ino. You should be able to easily see where to change the accelerometer configuration (mainly the range) and how to adjust which axis and what values light the various leds. The accelerometer returns an eight bit result for each axis in two's compliment form. Since this is just what C uses as a signed number, no further manipulation is required. Just remember you're dealing with a signed number when you do comparisons.
To reach a workable level of understanding of the accelerometer, I also had to think carefully about exactly how the accelerations acted on it. The figure below shows the accelerations that act on the POV as it rotates, at four points in a rotation.
The black arrow is the radial acceleration, the blue arrow is the tangential acceleration, and the red arrow is gravity.
Skipping a lot of confusing experiments, here's the results:
- radial acceleration due to rotation is large - exceeding 16Gs if spun very hard. And it's in the negative y direction. Rotation must be nearly stopped before the rotational acceleration drops below 2Gs.
- tangential acceleration is small - less than 1G mostly - but not negligible.
- the positive axes directions for x an y are opposite those shown on the data sheet.
You can see that my assumptions were completely wrong! Convincing myself that my results were correct was probably the hardest part. The following figure shows the orientation of the accelerometer at four points in one rotation.
The positive sense directions are shown as the colored triangles. Comparing this to the figure above showing the accelerations acting on the POV, we can conclude that acceleration along y will always be large (like maximum negative value kind of large) and negative until the rotation is nearly stopped. So all control needs to be done with x values. The x values stay within +/-4Gs. Fortunately, that works great and results in a stable display of the POV text.
09/11/2017 at 04:11 •
A new body was needed for the fidget so that the battery and the board wouldn't fly off so easily when I spun it. The design was quickly done in FreeCAD and printed. The FreeCAD and STL files are both attached.
Have a look at the battery carrier as well. The part number is in the Parts List; I simply mounted it on a bit of perf board and ran a couple of wires to the main PCB. I put a small square of copper tape with some solder on it in the center of the perf board to serve as the negative post. Note the hot melt glue which provides strain relief and prevents fatigue failures of the wire.
Here's how it all fits together. I'm still using a rubber band to hold the battery and pcb in place while I bend the software.
09/10/2017 at 03:35 •
The accelerometer was removed because of shorting under it, but now it was time to re-install it. I cleaned up the solder pads for the accelerometer - both the ones on the accelerometer itself and the ones on the PCB. A short length of finely stranded wire with a drop of liquid flux on it made a great solder braid for these tiny pads. The accelerometer was placed carefully back on the pads for a quick trip to the toaster oven for reflow. I was hoping there was enough solder left to make the remount work.
"Hope" is never a good strategy, and, indeed, the accelerometer would not answer up on I2C. (Although it did at least stick to the pcb.) Hooking up the scope verified that. Either the SDA or the SCL, or both, were not connected. As a last hope, I used a straight pin to put a tiny amount of solder paste on the side of the accelerometer with pins 1 and 4 (yup, that's SDA and SCL) and a bit of liquid flux everywhere else. Then into the toaster oven again. Success! I2C queries now got correct responses. Picture shows the board all together with the accelerometer and the Interrupt 2 jumper (described next).
With I2C working, I could configure the accelerometer, but for it to be useful, the interrupt needed to work. Without trying anything so complicated as configuring and triggering an actual interrupt, I was able to test the operation by changing the polarity of the interrupt pin using the I2C bus. Doing this, I quickly discovered that the Interrupt 1 pin did not seem to be connected either! Rather than trying another repair, I used a stand-by scheme I had planned. Interrupt 2 was pinned out to a via on the board which could be routed to a via in the Interrupt 1 trace. So I verified that Interrupt 2 could change level under I2C control, then shorted the vias. Now Interrupt 2 was connected to the ATTINY84. Yahoo! With thanks to STM for their design, I found that all functions that Interrupt 1 could perform could be performed by Interrupt 2. The accelerometer was now ready to use.
09/10/2017 at 03:30 •
Now that I had Blink running and could program the ATTINY84 at will, developing the text display routine was easy. The first program is included as T84_POV1.ino. The algorithm is obvious, and the timing used is shown. See the picture. I'll add a video soon. Since this was my first POV device, I mistakenly thought I was nearly done. Next up was to try to put the accelerometer back on the board and use it for wake up.
08/02/2017 at 23:33 •
A short aside here to discuss the uProgrammer. In the last post, I kind of brushed over the uProgrammer, although it was an area I was very worried about. If it hadn't worked, the whole project would have been a Fail-of-the-Week! The concept was discussed in the Circuit Board and Programmer Project Log, but now that I know it works, I can talk about the implementation. The idea was to use a spring contactor to provide the connection to the board with the microprocessor on it. A footprint for the contactor contacts to hit was included in the microprocessor board design. As previously mentioned, a frame was 3D printed to provide the spacing between the contactor and the footprint so the contactor could be reused.A small notch in the board mates with a tab on the frame for easy alignment. These pictures should help you to get the idea.
This scheme turned out to work really well! A clothes pin works as a clamp to hold the microprocessor board and the uProgrammer together.
Since this approach allows building very small "Arduinos", it may be the most useful part of this project.
08/02/2017 at 23:29 •
My Perfect Purple PCBs showed up a few days ago, so it was time to build and bring up the boards. (OK. It's really been a few weeks ago. Never claimed I was quick.) I cut the solder paste stencil using my Silhouette Portrait and 3.5 mil overhead transparency film (mylar). Cleaning the chad out of the stencil holes took a bit of effort, especially on the tiny holes for the accelerometer. I broke one of the spaces between the holes, but thought it would be OK to have a tiny bit of extra solder paste. Reflowed in my toaster oven and began check-out.
Looking at the board, I noted that the accelerometer was skewed - both twisted and tilted.
Looked like that extra solder paste came back to bite me! I proceeded with check out any way. Power and ground were not shorted! That's always a relief. But then things got interesting. To check out anything more, I needed to program the ATTINY84. It was time to build at least one of the uProgrammers. I chose the 2x3 version since the pads on the POV board were larger. Here is the uProgrammer mounted to the exotic clip I fashioned to hold the programmer in place. Worked fine.
In the process of checking the board, I looked closely at the board design in KiCad and noticed to my dismay that I had left a section of ground plane floating free. You'll notice the bit of blue wire on the board to fix that. The problem happened when I added the uProgrammer positioning notches. Fortunately, the fix was easy. I fixed this before I did any other board testing.
In short order, I established that the contactor and spacer used for the uProgrammer had continuity. The signal paths from the wires on the uProgrammer to the POV board tested solid. But there was at least one obvious problem. The MOSI line should have shown a 4.7K resistance to Vcc, but instead was shorted. Checking the accelerometer footprint, Vcc and MOSI were next to each other in the corner that had the extra solder paste. Uh-oh! The only way I could think of to clear the short was to use my hot plate and unsolder the accelerometer. I did that and the short was obvious. I used my soldering iron to remove the extra solder paste and clear the short, but I haven't put the accelerometer back on yet. Lots I could test without that complication for now.
Moving ahead, I verified that the programming signals (Vcc and ground, MOSI, Reset,and SCLK) all looked good. But the part wouldn't program and MISO clearly was not sending the correct levels back. What could be wrong? I didn't know. After pondering the situation a while, I decided to take a look at the signals while programming the DIP version of the ATTINY84. Of course, these looked fine, so the next step was to try to mess them up and see if I could get MISO to look like what I saw on the POV. Disconnecting MISO was a possible, but I thought that might be too easy. Disconnecting VCC was another way, and this seemed more plausible - especially when I looked carefully at the pads around the ATTINY84. It appeared that the Vcc pad did not have any paste on it. I made the pad-to-pin connection with a pin point and got Blink to program! So I knew this was the problem. A little work with a very tiny soldering tip, a bit of paste and some liquid flux, and the joint looked better and the ATTINY84 programmed! On to developing the POV program.
07/30/2017 at 20:45 •
The accelerometer I'm experimenting with is the STM LSM330DLC. Although this is an older design, it's convenient since I have an IMU I designed nearly 5 years ago with that part on it. It's similar enough to the part on my new design that I can do useful experiments. Most applications using accelerometers and Arduinos involve implementing IMU functions, and most drivers support simply reading the data back quickly. But that's not how I plan to use the accelerometer in this application. What I want the accelerometer to do is to wake the ATTINY84 when the fidget is spun, then let it go back to sleep when spinning is over. Getting it all to work as desired will take some testing, but I can start now to get a feel for how to control the accelerometer.
With the accelerometer hooked to the Teensy2, I tested it's ability to generate interrupts to wake the Teensy. This was easy. The data sheet was very clear on how to configure the control registers. Next was how to know when to go back to sleep. My first approach was to read the interrupt status register on the accelerometer since that tells which interrupt (X, Y, or Z) was above or below threshold. However, this register is only updated when an interrupt occurs; useless for showing status otherwise. So I read the X and Y values, convert from two's compliment, and do the compare in the ATTINY84. Currently, the limit is arbitrary and will have to be tuned on the POV board. But it works! And it also works when ported to the ATTINY84. The code for the ATTINY84 is one of the files.
Quick battery life calculation: The CR-2032 battery is rated at 210mAh @ 15K load. With 3.0 V and 15K load, the rated current drain is 200uA. The STM LIS2DE12 accelerometer that is on the POV board draws 4uA at 25 samples per second (to watch for a spin) and the ATTINY84 draws 0.1uA in sleep mode. Life is then 210,000/4.1 > 50,000 hours or about 6 years. Conclusion: no power switch is needed.
07/30/2017 at 20:43 •
Here are the pictures I mentioned in the first two logs. These are also included as files.
Experimental Breadboard showing Teensy2, ATTINY84, and the IMU.
Rigol Scope I2C Capture and Decode.
Connector Board Design and Schematic. This shows the pad footprints that are on the back side of the POV board. The locating notches are shown in the board outline.
This is the board design for the 2x3 uProgrammer. All it does is carry the contactor and provide connection points.This shows how the uProgrammer pads are included in the schematic.
07/08/2017 at 22:54 •
Board design is pretty straightforward. Create footprints for the ATTINY84 and accelerometer (see Parts List for the deets), add test points for the I2C bus (so the Rigol can be connected), and put footprints for the contactors. Nothing special.
The contactors are worth a bit of discussion. See the Parts List for the Digikey part numbers. My concept is to make a small programmer board that mounts the contactor, and press the contacts to the footprint on the ATTINY84 board. The contactors were designed to be used with flex cable, if I read the data sheets correctly. Two versions are being tried. They are very similar, but differ in pin spacing and arrangement, and more importantly, in working height. The contactors are intended to compress to a working height, but no further. If they are compressed until their plastic bodies are flat against the board, the contacts will be permanently deformed and will only work once. The key is to keep the contactor bodies spaced away from the circuit board and for this I will 3D print a small spacer. This spacer will have a notch in it that will align with a notch in the board to be programmed to position the contacts. I'm planning to start off with a spacer that only allows a small amount of contact, then increase this as necessary until reliable programming results (hopefully!).
The board designs are complete (ATTINY84 plus 2 programmers) and have been shipped to OSHPark. While I'm waiting for them, I'll design the battery holder and work on accelerometer code.