Intro: Attiny85 As a Step/Dir Stepper Motor Controller
Somewhere in Greece, someone did something never done before...
Seen those things before?
Oh, you have! You bought one of them you say? Oh... Don't worry, I did too.
They did the job, yeah. But we paid for them much. Really much. And while our whole project would cost less than 60 bucks or euros without them, they slapped as in the face, then took our money and ran ... our precious motors...
The revenge has come...
Step 1: Some Things About Steppers...
We all love steppers! They do some really nice things.
1) They ran great CNC systems, that make all kinds of goods!
2) They play music, sometimes better than humans!
Basically They do only those two things but they are enough...
We, people, often control them via computers or microcontrollers and make them do those nice things and live happily together.
Steppers differ from DC motors structurally and behaviorally. They have 4 control wires (instead of 2) and, in order to make the rotor move, you have to apply voltage to some combinations of them, and change the combinations over small (really small) time intervals (maybe every 0.01 seconds or less).
Why is that, you may ask. But it is for PRECISION! The god of productive machinery! Every time you drive the stepper wires with a correct combination the rotor moves by a certain amount of degrees... That way you can tell where the rotor is by just measuring how many such voltage combinations you have applied to the motor. Knowing the position of something without any kind of feedback is Really Something!!!
(You can read much more here. There is a decent explanation of microstepping inside. the thing that this project CAN'T do at the time of writing)
Step 2: Stating the Problem...
So, as you may have realized, steppers are a hassle to use and control. All those wires, voltages, combinations and degrees/step are simply too much for a human to control.
And when it comes to CNCing, computers find it hard too. It is difficult even for computers, to control all the above combined with the needs of a CNC device: steady velocity, measured acceleration, simultaneous motion and taking a note of every rotor at any given time.
But when we face problems with multitasking we have the most elegant solution (when it comes to engineering):
Split the tasks to more than one worker. And that happened. The computer got rid of anything that has to do with voltages and combinations of wires. A simple interface was given to the computer so it could communicate with the motor. An interface that only contains 2 signals. A Step signal that every time it goes High (edge triggering) the motor has to move 1 "step" and a Direction signal that decides at which direction would be the step (ex: High for CW, Low for CCW).
So this is the Step/Dir interface.
Now a second device was needed to translate the Step/Dir signals to actual 4-wire signals, move the motor and generally do the hard work. This device is the Stepper Controller. And as of today, only one type of this device exists commercially: the hardware one. It uses H-bridges along with some kind of hardware logic, and other tricks ending up to quite complicated device. So it isn't that cheap too... They can reach even 60 euros or more for multiple motors.
So, the first reaction when I got an idea about how to program Attinies was "Why hasn't anyone made a software controller, by just coding the combinations in an Attiny85" (There have been some success with Attiny2313 by another Instructable and a sole attempt with Attiny85 that isn't very satisfying)
Step 3: The Attiny85 Problem
Attiny85 is a microcontroller. It contains a processor, some RAM, some free space, to save and load things, and offers some of its processor's register bits as IO pins.
Here lies the problem. Attiny85 has 8 pins at its DIP package, 2 of them being power supply. And you may assume that the rest are pure IO. That's wrong. Well, almost, wrong... The 5 of the remaining pins are IO and there is that 1 pin that is used for RESET (if you bring it Low the microcontroller will restart). To make things worse, RESET pin is connected to some register, so it has the potential to BE an IO pin. There is also a fuse inside the microcontroller that decides if this pin is used for RESET or IO. BUT if you change the fuse (the famous RSTDSBL) to use the pin as IO, the microcontroller can't be reset again and, on top of it, it can't be reprogrammed.
Now, back to the stepper controller device. It needs 2 pins, to read the incoming Step and Dir signals, and 4 to connect the stepper motor wires (or the base of some transistors to amplify the power delivered to the motor) and do the actual voltage combinations. So a controller needs (*at least*) 6 pins.
You see it, don't you? The way god created things has made our little Attiny85 to be incapable of being used as a stepper controller properly. Until Now...
Step 4: The Circuit
This is the circuit.
We are using the Attiny at standard, inside-clock frequency, without external crystal. Using pins 6, 7, 2, 3 for the Stepper motor wires. Each side of the chip is used for a coil. A stepper motor has 2 coils inside it, both ends of both of them are its wires.
For Unipolar Motors
All 4 of them have to go to an array of transistors. TIP120 is a good idea, or a ULN2003 that contains 7 Darlington Transistors (like TIP120) capable of 500mA each. It is a common circuit and you can find it easily. I have added one. The a,b,c,d go to the 6,7,2,3. Use some "trial and error" for the connection order.
For Bipolar Motors
All 4 wires go to 2 H-bridges. You can find ICs containing single or dual H-bridges for 2-3 euros (that can drive up to 1-2 Amps). The 1a,1b,2a,2b are the signals to connect to the Attiny's 6,7,2,3 in this case... Again, trial and error is your friend... Be careful because h-bridges tend to heat up quickly if they get connected the wrong way...
The Step signal is read in pin 7. The microcontroller is programmed in a way that, every time it realizes that pin 7 went from Low to High it will trigger a combination change.
Aaand.. the Dir signal... It uses the RESET pin. No I have never messed with the fuses and I have not the intention too... There is a line somewhere in the Attiny85 datasheet that explains that the microcontroller will reset if pin RESET goes under 0.9V. This IS technically a Low signal. But what happens if the voltage is less than 5V (undoubtedly High signal) but more than 0.9V?
Step 5: Why It Works?
Well after tests from the Arduino community forum, the threshold of resetting is higher than 0.9V. More like 2.5V. But, there is still space between 2.5V and 5V. As you have seen in the pinout, the pin 1 (Reset) isn't just a PORTB, IO capable pin, but an ADC0 pin. Meaning that it can read analog signals. Inbetween Low and High lay analog signals...
So using a (common NPN) transistor and a pullup resistor would make the analogRead() (arduino language) command read a High (1023) when the transistor is disabled (Voltage at Base 0V) and an almost High 685 signal when the transistor is enabled. Both signals don't reset the microcontroller. So we can read different things when the transistor base goes High and Low. Now if we connect transistor's base to the Dir signal we can be aware of both of its states by reading the Reset pin.
Step 6: The Code
Code. Not much... It is self explanatory and fully commented.
(Written on Linux, windows users may need to add some Returns (new lines) or change to Linux.
The later is a Solution, the first is conditioning)
Both "firmwares" use half stepping (8 state driving). "RT" stands for Real-Time.
The "non_RT" code ensures that there will be no lost step if you feed it with step signals up to 1200Hz. But it may not execute steps exactly after a signal. If fed with steps more than 1200Hz it will rotate the motor for ever (due to an overflow) and only a reset will stop it.
The "RT" code doesn't ensure a thing! It is significantly faster but may lose steps if given in high frequency (more than 2000HZ - possible that your motor will stall before reaching that frequency). The code includes some AVR libC inlines to make things faster.
If you try "general tinkering" use the "non_RT" firmware, if trying a CNC definitely use the "RT" one (don't worry about lost steps, easy-drivers and pololuswork the same way too).
You can use the DIY AVR Programming Station to program this puppy. It is an easy, cheap and damn useful build.
Step 7: Room for Improvement
Well, making this circuit in a perfboard, breadboard, PCB or anything else isn't always the end. You may want to improve the controller. Well, guess what? Take the Attiny from the socket put it in your programmer (whatever that is) and change its "stepper control firmware" as you like.
You can change the delay time (because it actually depends on the motor), the threshold (if you change the resistors), the stepping technique (you can do Full Stepping - now it is Half Stepping - or create a new one)...
You CAN'T change the Pinout though. You may write a Real Time controller too (this is not *that* real time) and control big CNCs (not only hobby ones). Finally you can, somehow (some software PWM I guess), add MICROSTEPPING. The sky is the limit. And if you get bored of it, just make your Attiny a traffic light controller and scrap the motor project altogether (don't forget, the Attiny is easily reprogrammable - even on circuit - no fuse change made)
This driver can receive a step High signal every 1500 us (microseconds - 1.5ms milliseconds) and not lose any step (while half-stepping). That is 0.0015 sec period. So 666.6... Hz.
If you do any significant changes or add features, just let me know!
The best way to do that isn't sending me an email, but making an instructable about it or commenting your added features and maybe code!
If this project gets enough improvement, I will open a SourceForge entry about it to let everyone have an *almost* free stepper controller-driver!
Share your work...
Thank you for reading my second Instructable...
Step 8: Oh, I Almost Forgot. COST
Why make something when it is cheaper to buy it...
This controller's first purpose is to be cheap. Really cheap:
Attiny85 - 1.80 euros
Female headers pins - 0.10 euros
3 1KOhm resistors - 0.03 euros
1 2n3904 transistor - 0.05 euros
perfboard - 0.30 euros (ebay)
And if we buy a ULN2003 (some cheap steppers come with their own drive circuit)
ULN2003 - 0.35 euros
L298N (2 Amp dual H-bridge, the most expensive I could find) - 3.20 euros
Well, it is about 2.5 euros or 3 bucks for a unipolar motor
and about 5 for a really beasty bipolar one(used on CNC wood Routers and such big things)...
Not 10 or 20 euros...
And microstepping is on the way... After that there will be no reason to buy a "Stepper controller"...