Wow, its been a while!
So I’ve been slaving away at school as well as working at a gaming shop my brother, myself and a hanfdul of our friends have acquired. Check it out! http://www.legendaryrealmsgames.com/ . I've also acquired a handful of new toys including a CNC router, Manual Lathe and 3d printer. So expect tons of posts on each of my new toys in the future as well as new services that i will be adding to my store: http://mcuplace.com/store/.
So, with the whole 3d printer movement, I’ve always kind of held back. I've always preferred the precision of a cnc mill over the lack of with a 3d printer. Add this with the ability to use any material a carbide endmill can chew through, cncs are just more refined than the repraps and makerbots that were coming out. Every one of my friends who had a 3d printer, never used it because it was either broken or didn’t meet their specs. Why spend $2000 on a 3d printer when the same amount can get you a cnc mill that allows you to make production grade parts?
Today, things have changed a bit. This year is an exciting one for FDM printers as they have become ridiculously cheap and new materials allows some pretty interesting prototypes. The resolution still kinda sucks, but hey, for prototypes its great.
Recently on hackaday, a few posts about the XYZ Davinci printer have popped up, and it's everything I could want. A consumer grade printer that uses real manufactured parts rather than printed crap that falls apart.
The davinci printer, is a $500 printer that prints down to 100 micron, has a fairly decent sized bed and (hopefully) comes out of the box ready to print. Best of all, its sold through amazon, and is eligible for prime shipping. Surely there must be a catch and there are, two of them.
First catch, is it used proprietary filament container, this is a moot point simply because the design is to make filament loading and use simpler for the lay person. The filament comes in a nice cartridge and there’s a small eeprom chip which tells the printer what material it is, the color, length of spool and material type. This allows seamless switching of print materials as the user has zero setting to adjust. However, these filament contains are pricey at $28 per 600g vs the standard $35 for 1kg.
But we, are hackers and fooling the printer is as easy as cake, there are many guides out there on fooling the printer and resetting the filament count, allowing you to use any filament.
Honestly, their filament isn’t that much more expensive than aftermarket stuff, and for the time being i'd recommend just using their stuff until you get familiar with the printer. As im sure hacking the filament container voids any warranty.
The second major flaw with the printer is well... it doesn’t quite always work out of the box. I had two major issues with my printer and spend about an hour trying to get it working properly. Fortunately, support does exist, and you can always return through amazon easy as pie. So if you're patient, this can be a non issue.
The y axis sensor.
When i first turned on the unit i was greeted to the sound of gears grinding. When the unit turns on, it does a quick calibration, where it homes the x and y axis. The x axis homes no problem, the y axis crashed into the machine and an error 0032 flashed on the screen. Looking in the manual its the code for y-axis home sensor/motor failure. I look inside the unit, i find the optoswitch for the y axis and then test the unit by tripping the optoswitch with a piece of paper, sue enough, the unit passes the start up test and i'm greeted by a ready state.
The fix begins with me taking off the side of the unit. If you lift up the front cover, you can pop the side off the unit, the back clips can come off by hand but one clip in the front you need something to pry it off with, a flat head screwdriver works fine, be careful you shouldn’t need to much force.
After that the side should lift upwards.
The y axis sensor is attached to the side of the case with two screws. It looks like it was planned to make the sensor movable, but either the wrong pattern was stamped or the wrong mechanism was use. My y-axis sensor was fixed in position and properly mounted in the housing.
My solution was to simply tape a piece of paper to the y axis carriage. This gave the carriage just enough protrusion to hit the sensor.
The Z axis cable.
The next error i came across was when i tried to do my first print. I selected the sample print and i was greeted by a "building" message on the LCD, after about 5 minutes of nothing happening, an error code for z-axis sensor/motor not working flashed on the screen. I looked at the z-axis stepper and sure enough there was a cable housing with no cable attached.
I removed the back of the unit and found the cable and proceeded to try and plug it in. One small problem....
The connector for the z axis is mounted UNDERNEETH the steel chassis, and to plug it in, you have to route the cable underneath. The problem with this is, there is no access hatch or way to do this WITHOUT taking the ENTIRE printer apart. So i was pretty annoyed at this.
The solution was to plug the cable in from above, however this required taking the z-axis apart and lifting the stepper out.
To do this:
-Loosen the z axis coupler, on the STEPPER side with a m2 Allen wrench.
-Lift the bed and screw up, support it with some kind of block (I had 2 123 block which i used)
-Loosen the two torx screws holding the stepper plate to the machine
-Lift the stepper up, and attach the cable
-Reattach the stepper to the machine, rest the coupler on the shaft and re tighten.
Everything should work after doing this.
Once you get printing, your rage starts to subside, the quality is pretty decent and for a $500 machine its quite awesome. Their software is quite limiting, but any .stl file you can slice, and modify basic parameters, there are also ways to bypass the software completely.
I still think some fine tuning of the machine can be done, but in the coming weeks im sure there will be tons of write ups and hacks. Overall i think this is a great printer and an excellent device to get into 3d printing with.
Overall im quite happy with the printer and already have some projects i will be printing parts for.
If you have any further questions, feel free to leave a comment, if you are having issues with the same problems i had, send me an email and ill try and help you through your problems!
For all you shibes out there, comment with your doge address and ill send you 50 doge!
Ps.. Main board shots
So I am on my second filament cartridge, there are a few small issues i've encountered i'd like to document.
I began having alot of issues with the levelness of my bed, while printing it was clearly misaligned and caused alot of bubbling on the first layers. Running through the leveling calibration improved prints alot, especially since i was able to get all 3 points exactly the same height.
Follow the procedures here: Yourtube video: xTKKcVMo7LU
It takes a good 30-45 minutes, but vastly improves print quality.
Running out of filament
The cartridges are suppose to tell you when they run out, but for some reason mine was mis calibrated, this meant that i ran out of filament midway through a print. Now this causes an issue when loading new filament because there is still old filament that cant be ejected. To fix this issue, squeeze the black clip at the top rear of the extruder, pull the housing off and pull out any remaining filament in the hotend. Once you do this, loading new filament should work fine.
I've noticed that the x-axis on my unit squeeks quite alot, i dont know if this is a common issue and i've yet to resolve it.
Let me start by telling a little about myself. Ever since I arrived at Stony Brook I've been involved in the Solar Boat club. Were basically an organization that designs, builds and races solar powered boats. Now, when I tell people we build solar powered boats, they think RC race boats; no, we build typically around 14ft vessels meant for speed (At least we hope). Also by build, I mean we build pretty much everything from scratch including the hull, drive train and other systems. Anyway, not too long into when i joined the club i toyed with making our own motor controllers. Little did i know this design would take almost 2 years. What i want to now share with the everyone are the lessons that i have learned while working on this design. It began as something that i would expect to be done with quickly, but has turned into something which i still work on.
So why build a motor controller? There are companies that already offer plenty of solutions for electric vehicles that will work in a variety of voltage ranges and currents right? Well the truth is, not really. At our competition all the controller are either.. AllTrax, Curtis or 4QD. And all of them either are: Stuck in the 70's in terms of logic and control signals or have a micro but don't actually allow you to usefully use the information they spit out. This being a custom race boat, we want specific information so knowing how the controller is operating at all times is crucial for our boat. That is, if we design the micro system that controls the controller, we can get whatever information we want and use it however we want. We would have digital freedom, which doesn't limit our design(Hello iPhone controlled solar boat?). Secondly, if you actually design a motor controller you know the specifications on the controller are completely artificial. Can a Curtis 1205 actually only source 400 amps? Well... no, the mosfet bank is rated for quite a bit more than that. But due to thermal limitations, they manufacturer sets these limits. Same goes for voltage, most controller have over-voltage ratings to limit the input voltage, despite the fact all the components on the inside are rated for much higher voltages. When you actually design a system from the ground up, you can set those limits and maximize performance of your system. You aren't limited to designing a product specifically for consumer use. You can test the limits of your hardware and learn more about your system in the long run.(for real world design, i suggest against this, but we are racing, so we can take some things to their limits in a blaze of glory :P) These two reasons were the main reasons why i decided to begin this design. Now i would like to go over a little bit about the basics of the design of a switching motor controller
A switching motor controller, at its heart is super simple; We have a battery source, motor and mosfet bank like such:
When we apply a positive voltage on the gate(with respect to the source) The mosfets are fully conducting and the motor turns on. When we apply 0 or a negative voltage, the motors turn off. Yay! we finished our design and we can all go home, the controller works perfectly! Well... not really, we have 0 RPM and Max RPM, when the hell did you ever use a vehicle where you could only go full speed and 0 speed? The technology that we use is called pulse width modulation. I am not going to bore everyone with what it is, it's fairly simple. We have a square wave of frequency x and we vary the time that is is on, versus off. this is called the Duty Cycle and varies from 0 to 1. We can roughly estimate that Iavg = DC * Imax. Since we know P = t*w = I*v, with a constant supply voltage by changing the average current, we change the average power, and therefor for a constant torque load, we change the RPM.
To do this with any mircocontroller is fairly trivial, all decent micro's have some way of outputting a PWM wave at a specified frequency. For a PIC microcontroller, we use a single timer and we compare TMRx to the CCPRxH register, when they are equal, we have a transition from HI/LOW or LOW/HI (settable in the control register). When the TMRx register equals the PRx register we have another transitional and a new period starts. Operation is pretty simple, we have two registers, one for the Period of the wave PR2 and one for the Duty Cycle of the wave CCPRxH. The same is true for the AVR, its just different register names. So with this in mind our updated schematic is now: With this design, we have exactly what we want, we have a micro-controller that can adjust the average power going through a DC motor from a full stop to maximum RPMs. We can add various sensors to adjust the duty cycle and we can chose our mosfets however big to pass as much current we want! There is one small problem..... This setup would NEVER work.
Models and why they are important
A model is a way of representing a very complicated system with one which is much more manageable and well defined. An extreme example of a model is the law of gravitational forces:
This model allows us to tell what two forces an object will see on each other separated by a distance R. As far as well can tell, this is a very accurate model which works for most cases. However, it doesn't represent reality perfectly. We know that the law of gravity doesn't hold for the quantum scale and it especially doesn't hold true for black holes and, even when we calculate a force using this law, we only know this force to a certain amount of uncertainty. How fitting an equation the law of gravitational forces to nature is also a matter of interpretation. for a MUCH better explanation o this subject I recommend those to Richard Feynman's lecture on the character of physical law: http://research.microsoft.com/apps/tools/tuva/ The one thing that annoys me about many engineers is that many of them take a schematic as a golden rule. It exactly shows how a circuit is to operate and if you follow a schematic you will get precisely the operation you desire. This is simply not true. Lets take a simple system of a 9 volt battery with a resistor attached to it:
Now, we want to find the current so we use , great. For most applications this works great, we find what we need and now we can move on with our design. However, lets think about this, what if R is 0? Well then , which is undefined, so that means every time you short your common 9v battery, universe should explode, no? How come it doesnt? Ok, R=0 is a little extreme, but you'll also find, even with small resistances where R!=0, the system wont behave as expected. The above schematic, is only a model to a certain degree, it doesn't tell us everything about the system. For most batteries, there is an internal resistance. This internal resistance, is in series with our load resistance and limits the total output current. We can add this resistance to our schematic and improve our model by a degree:
If we keep digging we can find more and more parameters we can add to our model. One important thing is to realize when we work with REAL components vs ideal components. What makes an inductor? an inductor is a coil of wire...a coil.. of WIRE. Every piece of wire in our circuit has an inductance. What makes a capacitor? two of anything with area, separated by a distance with a potential between them, everything has capacitance, and unless you're working with superconductors, everything has a resistance. These are called parasitic components and for the most part, they have such low values, we arent concerned since they don't affect our circuit in a region we are operating it. Lets add some of these components to our schematic and we get (and yes i know i may be "missing" a few):
Whats great about this model, is that well know exactly the frequency of oscillation when an incident photon strikes the body of the resistor creating a mobile electron.We can even go further! If we add quantum mechanics we'll have a decent idea of what any individuality electron might do. Do we need this? When making a model, you have to define what you NEED to know and you design your model accordingly, for 99% of us, our simple schematic will do. When your designs start failing, and you don't know why, chances are, its because of the parasitics. For high power electronics, the parasitics own your design and your job is to constantly fight them and try to tame them.
Where we stand
Our job is to take a look at our design and find where the parasitics are, the most obvious place to start looking is the electric motor. For our motor we use either a Lynch permanent magnet dc motor or a mars e-tek electric motor. If you're curious about motors check out:
its a good video with some well made diagrams and doesn't move at too fast a pace. At the end of the day, the simplest model we can apply to our motor is an inductor in series with the armature resistance. Four our cabling we use 00 gauge welding wire, if you haven't worked with large gauge welding cable, its the most fantastic cable you can ever hope to work with, its awesome stuff, but i digress. Our wire has both inductance and resistance to it. Adding to original schematic we get:
Now to get back to the "switching" part of this design. We are using a bank of NMOS transistors to turn on and off the motor. When the bank is on, it has a resistance of RDSon/nmosfets . When it is off, the resistance is a few mega-ohms. When the mosfet is going from off to on, it is a resistance between those two. To minimize the power dissipated in the mosfets, we want to switch them as fast as possible. Once again we must look at the inside of a mosfet and understand what makes it tick. A Metal Oxide Field Effect Transistor works by using an electric field to change the concentration of carriers in a semiconductor bulk. On the gate pin, there is no physical connection to the body of the device, it is separated by a later of oxide. This gate, is analogous to a capacitor, and to apply any voltage, it must be charged. Every mosfet has a gate capacitance, and to turn on the device, we have to charge this capacitor.
We know to charge a capacitor C to a voltage of V through a resistor of R is:
where is the RC time constant. Here we can find the time it takes to charge the gate capacitor to a voltage V. To charge this capacitor we generally use an IC called a mosfet driver, we do this simple because the pins of a microcontroller can only source 20mA. At that rate it would simply take too long to turn on/off and we would waste alot of energy in our fets switching. Ok, so that problem is solved, whats next? well, lets get back to that schematic of the motor controller with the inductors, once equation you may recall is the following:
this is the equation for voltage across an inductor, is the same as saying how fast the current changes over time, now we have a mosfet that's trying its absolute hardest to turn on and off as fast as possible, di is the same as the magnitude of on current and off current and dt is how fast it takes to go from on to off. well crap.. it doesn't matter how small L is, is HUGE, it dominates that term. and everywhere in that schematic where we have an inductor, we have a very large spike in voltage. Below is an old capture of a probe across the mosfet bank. I would see spikes well past 100V on a 24V system! I essentially made a really nice boost converter! (Add output caps in the right place, and this IS how you make a boost converter)
Crap, what do we do
Because i didn't set out to design a boost converter, those spikes are unpleasant, plus they'll destroy about every component in the controller if i don't control them. Now, if we have a large positive voltage across the mosfet bank, and the input to the motor is a smaller positive voltage, we have a negative voltage across the motor (with respect to current flow). If anyone has ever worked with inductive loads before, you know the answer to this problem, we need a flyback diode. A very large bank of flyback diodes. A flyback diode does miracles to take care of the motor but we also need something to take care of the inductors in the wires, the short answer is we use a bank of capacitors on the input of the controller. The bank of capacitors act as a low impedance short to "ground" for any spikes in the wires, keeping the voltage across the controller very stable. It isn't perfect, since we have to deal with alot of energy, but it makes things safe enough that we wont unnecessarily kill anything.
This schematic represents closely what I did on the actual controller, replace the diodes, capacitors and mosfets with many in parallel and you got the basic picture of the real thing.
Now, flyback diodes are only one possible solution, another is making a synchronous half bridge controller, This is something that i am also working on, but i wanted to perfect the passive system before i moved onto an active one.
So lets dive into what the motor controller has evolved into, this is the 3(or fourth) major revision of my design and so far it is the best operating version I have.
Below is a picture of the PCB mostly populated and the mosfet bank:
Here is a picture of it connected and ready to be used!:
Picture of the watercooling:
It has the following features:
-pic18f26K22 runs the show, all pins and power are broken out to a set of headers which allow the use of "shields"
-TX Shield has filtered and buffered inputs, 3.3v supply for xbee
-Inputs for various current, temperature, tachometer, battery voltage and other sensors
-Dual independent logic and drive power supplies, coupled optically
-4 layer PCB
-Large bank of schottky high current diodes for flyback
-Bank of 12 high capacitance electrolytic capacitors, Hexagonal closed packed D.
-Breakout for 10 high power mosfets each with own gate resistor connected to two mosfet drivers in parallel
-Watercooled Mosfet Drain bus bar
I used the following components:
-PIC18F26K22 Microcontroller : http://ww1.microchip.com/downloads/en/DeviceDoc/41412F.pdf
-FOD220 optocoupler: http://ww1.microchip.com/downloads/en/DeviceDoc/41412F.pdf
- UCC27424 Low side mosfet driver: http://www.ti.com/lit/ds/symlink/ucc27424.pdf
-LM2796 Simple switcher: http://www.ti.com/lit/ds/symlink/lm2596.pdf
-SBR60a200ct rectifier: http://www.diodes.com/datasheets/sbr/SBR60A200CT.pdf
-FDP036n10a N channel mosfets: http://www.fairchildsemi.com/ds/FD/FDP036N10A.pdf
Two logic signals from the microare sent to the mosfet drivers, the PWM and Enable signal. everything has external pull down resistors to ensure reliable operation in case something goes wrong with the micro. Like i mentioned above, the pins of the microcontroller are broken out into two 14 pin headers, +5V and +12V are available to any header accessories. There is also a 5 pin programming port for the micro.
The header "shield" board looks like this:
Each sensor input goes to a low pass filter and an op amp buffer. This keeps the signal low noise ans allows me to temporarily ignore any real need for DSP at the moment.
Finally, the mosfet bank is watercooled using PC watercooling supplies i had lying around. This allows me to push them a little further than what you could normally get from just air cooling, ans allows me to reach the datasheet speced currents a little easier.
The code is written entirely in assembly. As of now it is 6 asm files:
main.asm - Just a file which includes all the other .ASM files.
Setup.asm - Includes the setup routine and configures on board peripherals.
FSM.asm - Contains the code for the Finite State machine.
int.asm - Contains interrupt code.
subs.asm - Contains all the subroutines.
A finite state machine was chosen because it allows very robust control loop. As long as next state/current state are in bounds, you wont have your code running out of boundaries. There is no checking to see if the next state variable is in range, but this can be easily added.
The state machine handles all the motor controller functions, including ensuring safe operation. Some of the safety features includes are to limit the change in throttle, disable the throttle when first turning on, and use of a key/killswitch. Any hazardous operation return to an idle default state which waits for key input. The code is incredibly modular and adding/removing states is relatively simple. The state diagram is shown below:
The interrupt routine simply polls all the analog inputs, stores each 10 bit a2d in two 8 bit registers and then transmits the data wirelesly to be processed off board. Also existing in the interrupt routine is limit code which defaults the controller to safe operation if it exceed software set limits.
Some features i plan to include are addition of code to read a tachometer output, and the ability to receive commands.
As of now, don't trust my comments too much, always best to look in the data sheet or ask me a question if you are confused.
Below is a video of the controller running a MARS permamemnt magnet DC motor connected by chain to a lynch motor with it's terminals shorted by a piece of welding cable. I only go to about 50% duty cycle. I am still in the process of testing and verifying the current output of the controller. I have been using the Allegro acs758 hall effect current sensor, but i haven't been getting reliable data from them. I hope that i can refine my current measurement procedure to get a better estimate of the current through the controller. Regardless, I have verified peak currents of 250 amps and continuous current of around 100-150 amps. The main limitation is cooling of the flyback diodes as they get very hot. In the video they are passively cooled with a failed waterblock, in the next revision they will be actively cooled and should allow me to push thing a little harder.
Also a little note about the setup, We made a simple dynometer to put load on our controller, its pretty simple, Motor controller drives the Mars motor, lynch motor provides load for it. By varying the restive load on the Lynch, we can vary the load on the Mars. So far we have two settings, no load and full load :P seems makng a many-KW power resistor is not simple...
Conclusion and things to improve
I am far from done with this project, but this is the first major milestone and i think most of the hard work is done. The micro code is very mature and very adaptable, the TX shield does what is suppose to, the XBEE sends data effortlessly. The Mosfet bank remains very cool and i feel safe pushing it further, the biggest limitation right now are my diodes and keeping them cool. I have reduced the switching frequency to around 250hz and this seems to be working. I will be pushing another revision of the PCB to make mounting the lugs easier, i want to also look into diodes that can be mounted on the bus bar directly with the mosfets (they are hard to find, most diodes are wired backwards of what i want).Another alternative is to make a full half bridge controller and using a back of mosfets for the back emf, this is much better than using a bank of diodes as power dissipated in a bank of mosfets is proportional to Rdson and not a constant voltage drop. However, this adds much complexity to design as I now have to make the two banks of mosfets synchronous. Even worse, you cannot find PMOS transistors of these current ranges (In a cheap, useful package) so its best to use NMOS transistors on the high side with a boost cap mosfet driver. I've used them in the past and they can be unreliable, but i will be looking into the possibility of using them in my next design.
As with all my project, files are below, if you take from my design, give me credit. I dont mind you taking and improving where I leave off.
I wanted to introduce the new store i am attaching to the blog. http://mcuplace.com/store/ . The primary purpose of the store is to sell the PCBs and designs featured in the blog. All projects will have all source code/project files on the project page and if you choose you can get any design as assembled, kit or bare PCB. I will also be selling a handful of basic components at competitive prices!
I hope that the store can hold the information in the blog in a more static nature.
In the next few weeks I have some exciting projects coming up including the documentation for my switching motor controller!
Thanks everyone, I cant wait for the PCBs to start rolling in.
I play Dungeons and Dragons, and like any geek who plays DND i felt like making electronic dice (how clever and original?) with a catch, it has to be ultra portable and has to last at least the length of a standard gaming session on a single charge, it also has to be relatively cheap. I started this build last year around April time, and finished around May last year, i haven't really had much time to write lately so i've been putting off this post. Finally got some free time today, so here it is, my D20 Roller.
One resource i took well advantage of was Dorkbot's PCB service. After three separate revisions i settled on my final design, essentially its a micro (pic18f13k50) 22 SMD LEDs, two push buttons, and a super cap with all the appropriate passives on a 2x1" PCB.
So for this design i wanted to try and make everything as small as possible, which meant surface mount... everything. Personally, i prefer soldering surface mount, once you get used to is its pretty easy, just sucks when you lose stuff under the bench.
Laying things out when using surface mount is pretty trivial, put the stuff that's important for operation on one side, the junk that runs the show on the other side. Making it portable on the other hand, well that's another story. If you want portability, whats the most obvious choice for power? Battery of course, well aa's and aaa's are bulky and don't provide enough voltage for our LEDs, we could add a boost converter or some sort of power system, but that adds cost and space. We could also use coin cell batteries, these too however can be bulky and the holders can take quite a bit of space. My solution was to use a 1F 5.5v super capacitor.
The biggest advantage is they require no charge circuitry (a current limit resistor is plenty sufficient) They hold whatever voltage they're charged to (in this case 5 volts) and they pack plenty of juice to run a micro and some LEDs for a few hours (if you manage your power well). I provide a mini-usb b type receptacle for plugging into a USB port and siphoning off 5V, a current limit resistor limits the current so smart sources (like a PC) don't freak out when there's this huge current draw on the USB port. A smarter design would of been to add a LDO regulator, since then you can accept a wider range of voltages, this adds costs and takes up space.
Now, as for the actual operation of the die roller itself; there are two thing i'd like the roller to accomplish:
Firstly, you need to be able to tell it when to roll a die, so we need a button for rolling dice. Secondly, we would like to be able to select the die type we would like to roll, this is our second button. Operation is simple, hit select until the the die type you want is highlighted, hit roll and you'll get a value within the range of what you want. Simple, and effective.
A note about random numbers:
Well first off, there is absolutely nothing random about this die roller, it is completely synchronous, if you could time yourself perfectly, you'll get the same value every time. But, if you do the statistics (i have) with this roller and an actual d20, you'll find they both have the same statistical distribution. So how do I do it?
1) Humans are slow and all push-buttons suck.
That is the key to this algorithm, in the background of the program I have timer0 cycling as fast as possible. When a random number is requested, I multiply timer0 with the range, i take the higher byte of the result and that is the "random" value which gets displayed.
The trick is timer0 is a 8 bit counter, with a range of 0-255, at 1MHz it overflows approximately 3900 times a second. The fastest human reaction time is around ~100 milliseconds, average is about 200. So before you can even react to your brain saying "hey i wanna push that button, timer0 has already cycled a few hundred times.
In essence you cant time yourself to get the same value twice, its humanly impossible, the error to your reaction time is much greater than the refresh rate of the timer.
Secondly buttons suck. Anyone who has used a pushbutton knows about a problem called switch de-bouncing. When a switches mechanical contacts come together, they dont make a perfect connection, they bounce against each other untill actually settling into a set state. If you have a scope, set it to single trigger and hook it across a switch, you'll notice have many times the switch "bounces" until it settles into a value. This article explains switch debouncing better than I could:
The result of this, even if you could perfectly time yourself down to the microsecond, the time it takes the switch to settle, is random. This is actually the source for many random number generators, but I mostly use the first phenomenon, my switch denouncing algorithm is rather simple, I just kill some time before looking at the switch again, its simple and it works!
So yea, my algorithm is't truly random, but it's incredibly efficient (takes 4 instructions) and it generates results indistinguishable from a real die.
Dice in action
The software is pretty simple, and it's mostly incomplete. For the final iteration i wanted to run a finite state machine and work hard on implementing sleep features, but i never got around to it. The current code is pretty basic, but it works pretty well. Here is the state diagram for how i wanted to implement the code :P
Below i've attached a few things, the source code, the schematic, and a sample excel file where I've done some stats.
If anyone is interested in buying one to play with, I have plenty that need a good home and i'd love to have some funding for a better revision!
You can contact me by email at: email@example.com
I've written a brief manual that those who bought either a kit or the dice themselves will find useful!
Also, I've written another firmware revision, which i will be updating and i'm in the process of writing one more!
Finally, i have another revision of the board, which i am getting printed, i will have these available as kits and assembled versions.
I have two new firmware revisions:
First up is version 4 of the firmware, if i remember correctly, this version puts the display as interrupts making the display a little cleaner and smoother.
This revision focuses on power saving and improving how inputs are handled. Inputs are now handled by interrupts and the main routine is completely freed up. Sleep is enabled and clock speed is reduced to 500khz.
Any questions! Email me!
I've been out of the game of writing blog posts for a while now, but i promise its only because I've been working on some cool stuff. I'm going to be making a few posts on simple concepts before i roll out some larger projects I've been working on.
Finite State Machines:
A very important part of digital/software design is being able to control how a piece of software "flows", how the user interacts the software and how it behaves to certain stimuli. Finite State Machines associate actions (things your software/hardware does) with a current state and an input combination (Mealy State Machine) or just the current state alone (Moore Machine).
Finite state machines involve breaking your problem down into states, in which each state; the possible inputs to your code produce different results. Its a very simple paradigm, but its often hard to abstract, so we'll start with an example.
Lets say we have a digital clock, and we have 3 buttons, there are several features we'd like to implement. Lets say for now, we can only set the time, the alarm time and turn on and off the alarm. If we list all the possible actions we find we can:
-Turn on and off the alarm
-Change the hours of the alarm
-Change the minutes of the alarm
-Change the hours of the actual time
-Change the minutes of the actual time
-So and and so forth.
So now we can do several things; one thing we can do is to have a button for every action. This really tends to eat up hardware and makes the end result sloppy and very user unfriendly (imagine having a button for every aspect of the operation of a more complicated device) Plus we stated above, we only have 3 buttons!
A much better example is to use a finite state machine, in which each button will have a different function dependent on the state that it is in.
For simplicity sake, we will be implementing the design as a Mealy machine (where the action is determined by the inputs and current state.
A state diagram is a way of representing the states that a system can take, for our clock we have Three:
State 1: The idle state, in this state we simply keep time, the user can enter programming mode from here or turn on and off the alarm
Button 1 - Will turn on or off the alarm
Button 2 - Enters programming mode (goes to state 2)
Button 3 - Does nothing
State 2: Programming mode for clock/alarm HOURS setting
Button 1 - Does nothing
Button 2 - Sets the current HOURS setting (goes to state 3)
Button 2 - Increments the set value
State 3: Programming mode for clock/alarm MINUTES Setting
Button 1 - Does nothing
Button 2 - Sets the current MINUTES setting (goes back into run mode after)
Button 3 - Increments the set values
So here, we implemented all the functions we wanted to do, with the buttons we had, and we even had ability to add extra functionality to each state!
Here is the state diagram for such a system:
Besides for making hardware much more simple, FSM also has some major code benefits. The most major is now we can abstract our design into actions. We assign actions to a state/input combination and call this action when the criteria is met, with this we can break down out code and avoid "spaghetti code." This allows us to segment our code into different parts, making things easier to work on in the long run. FSM also allows us to avoid duplicate code, for example, with our clock, we have to increment the minutes and the hours, with this FSM we can write one routine to increment a register and have the current state determine what register to increment. Here we use the current state as a parameter to avoid having two routines for one thing(a simple example). There are many benefits to using FSM in your code, below i included a FSM routine for PIC microcontrollers using lookup tables. The same routine can be written with ROM tables as well.
Below I've written very simple code for a PIC18F micro which allows you to implement a Mealy FSM into your design. It's very simple code and is completely stand-alone, so you can implement it into any project you wish!
cblock 0x00 INPUT CURRENTSTATE NEXTSTATE TEMP endc org 0x00 PORTS: ;;;;;;;;;;;;;;;;;;;;;;; ;SETUP STUFF GOES HERE; ;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;MAIN ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INIT: movlw 0x00 movwf CURRENTSTATE movwf NEXTSTATE ;Initialize States to idle MAIN_LOOP: call FSM goto MAIN_LOOP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;This is the main FSM Code ; ;INPUT must be from 0-256 ; ;Each state calls the INPUT numbered ; ;Action from the lookup table ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; FSM: rlncf CURRENTSTATE,w call GETSTATE movff NEXTSTATE,CURRENTSTATE return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Lookup Tables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GETSTATE: movff PCL,TEMP addwf PCL goto STATE0 goto STATE1 goto STATE2 return STATE0: rlncf INPUT,w movff PCL,TEMP ;Pics are stupid addwf PCL goto ACTION0 goto ACTION1 goto ACTION2 goto ACTION3 return STATE1: rlncf INPUT,w movff PCL,TEMP ;Pics are stupid addwf PCL goto ACTION0 goto ACTION1 goto ACTION2 goto ACTION3 return STATE2: rlncf INPUT,w movff PCL,TEMP ;Pics are stupid addwf PCL goto ACTION0 goto ACTION1 goto ACTION2 goto ACTION3 return ;State actions ACTION0: movlw 0x01 movwf NEXTSTATE return ACTION1: movlw 0x02 movwf NEXTSTATE return ACTION2: movlw 0x03 movwf NEXTSTATE return ACTION3: movlw 0x00 movwf NEXTSTATE return end
Essentially, we have three system variables, NEXTSTATE, PRESENTSTATE and INPUT, when we call FSM the program uses PRESENTSTATE as an offset for a look-up table, calling the current set state. Once a state is loaded, we use INPUT as a offset for the action associated with a state. Thus we get an action that is associated with an input/state combination.
The major downside to this code is that STATE and INPUT MUST BE FORMATTED! If they are not, you will get erratic program behavior. (I.e. if there is 3 states, the first must be equivalent to 0x00, second, 0x01, and third 0x02, same for input)
This code can also be used with interrupts as well.
|<< <||> >>|