Tuesday, January 22, 2013

Stepper Motor Setup

Well after getting my stepper motor to work last night with full steps, today I got it to work with half steps and so wrote up the circuit and the major problem I had encountered.

Firstly here is another video of the stepper, this time running at a decent speed, using half steps.
You can't tell from the video, but the motor does run much smoother with half steps as well as being able to run faster (logical if you think about how charging the coils works).

So I'll give the schematic next to show you the circuit layout, then I'll go into the problem I had and finally the code. The schematic does look messy, I would fix this by labelling the wires but I found out tonight that KiCAD doesn't have this functionality so it will have to do.

In the test program shown working in the video, the LEDs in the bottom right seem like they are on all the time but they are actually connected to each coil of the stepper and so turn on when that coil is on in that direction. This was so I could work out what was happening and can easily be removed. I will go into why they were useful in a second. Other things to note are that the switches on the left are attached but not used in this test program as these were for my original demo program which I will get working soon and so can do more tests. In the video there is a SMD chip on a red board. This is not actually attached to the circuit at the moment. This is because it is the other stepper driver chip (A3982SLB-T) which I will test later when I have a better heat sink for it than the tiny one I bought at the time which doesn't fully cover it.

OK, so my problem for why the stepper wasn't working was quite trivial in the end. It turned out that I had connected the stepper in a non standard way and so the guides on programming for a stepper motor didn't work.
Basically the standard order is connecting the coils in alphabetic order as shown in their data sheets. This means that the coils are intertwined as shown on the left of the above picture. This wasn't how I connected them as it seemed more logical to me to attach them so the coils were attached next to each other as shown on the right. As a side note, the letters in the picture are the letters from the data sheet, the numbers are the logical output of the pins on the pins of the microcontroller, and so when in the wrong order do weird things. This meant that instead of moving, the stepper oscillated between two locations while the rest of the time, the potential difference (voltage) over the coil was zero (ie both off or both on). What I realised from testing with the help of the LEDs connected and using a slower clock speed was that I had one coil with both sides on logical 1 and the other coil on logical 0 most of the time hence why it was not working. So once I swapped the two middle columns of the logical states in the table above, it all magically started working. This was something I had not read in any of the tutorials online or in text books to be careful of so I'm quite happy that I managed to solve this for myself.

So here is my code:
 #include <avr/io.h>  
 #include <util/delay.h>        // for _delay_ms()  
   
 int main(void)  
 {  
   DDRC |= 0x0F;  
        
      uint8_t curLED = 1;  
      while (1) {  
           PORTC = curLED;  
           _delay_ms(7); // 18 for full steps, 7 for half steps  
             
           /** Full Steps **  
           if (curLED == 1) {  
                curLED = 4;  
           }  
           else if (curLED == 4) {       
                curLED = 2;  
           }  
           else if (curLED == 2) {  
                curLED = 8;  
           }  
           else {  
                curLED = 1;  
           }  
           **/  
           /** Half Step **  
           if (curLED == 1) {  
                curLED = 5;  
           }  
           else if (curLED == 5) {  
                curLED = 4;  
           }  
           else if (curLED == 4) {  
                curLED = 6;  
           }  
           else if (curLED == 6) {  
                curLED = 2;  
           }  
           else if (curLED == 2) {  
                curLED = 10;  
           }  
           else if (curLED == 10) {  
                curLED = 8;  
           }  
           else if (curLED == 8) {  
                curLED = 9;  
           }  
           else {  
                curLED = 1;  
           }  
           */  
   }  
   return 1;  
 }  

(Note to self, using http://codeformatter.blogspot.com/ with settings 5 spaces per tab, no line numbering, don't remove blank lines, yes to stylesheet, auto height and no to alternative background)

Its fairly rudimentary at the moment and needs tidying up but it shows the gist. I used decimals as it was easier to test and write down than using binary numbers which I had used in my demo which wasn't working. For those interested, binary in GCC and Atmel Studio can be written down using 0b as a prefix to the binary string. The code above won't work straight from copying as I have commented out the method for changing between full steps and half steps. The other thing to note is that my chip is running at 4Mhz so the time would need to be changed if running at a slower speed.

I think that is all about getting the stepper working. Tomorrow I'll either fix it up for use with my demo program which turns certain amounts and then gives control to the buttons, or I'll have a go with serial communication to the LCD screen. I might if I have enough time, have a look at both.

Just to finish off, I was looking around Australian Robotics this afternoon and found there is a ball bearing on there which is 5mm thick with an ID of 5mm and OD of 16mm. This could potentially work for wheels on the carriage but after realising that the motor shaft is also 5mm diameter and is quite large realistically, I think a smaller shaft diameter would make more sense. The same website also has a coupler for converting the 5mm diameter shaft of the motor to 8mm which would work well for M8 threaded rod or an 8mm ball screw.

I'll should have enough stuff to post again by tomorrow night or the night after as will be at home working on it for the next few days. Should be good.