Stepper Motor
Stepper Motor
Stepper Motor
INIT
Learning new stuff is fun, but can be a bit frustrating. So, you want to write a device driver. The name itself is high-tech! You have some skills in the C programming language and want to explore the same. Also, you've written a few normal programs to run as processes in user space, and now you want to enter kernel space - where the real action takes place. Why Linux device drivers? The answer is,
For fun For profit (Linux is HOT right now, especially embedded Linux) Because you can! The source is with you.
Although it is possible to learn device driver coding by reading some books and PDFs written by the masters, this is a complicated and time-consuming approach. We will take the quick and easy approach, which is:
Find some pre-written, working code Understand how this code works Modify it to suit our needs
A typical full step rotation is 1.8 degrees, or 200 steps per rotation (360 degrees). By changing the time delay between successive steps, the speed of the motor can be regulated, and by counting the number of steps, the rotation angle can be controlled.
Bit Pattern for Full Step Mode Green Blue Orange Red Hex Output Value Step 0 1 Step 1 1 Step 2 0 Step 3 0 0 0 1 1 1 0 0 1 0 1 1 0 A 9 5 6
Hardware ideas
The circuit diagram for the drive is shown below.
The circuit consists of four TIP122 power transistors (T1, T2, T3 and T4), 220 resistors (R1, R2, R3 and R4), 3.3K resistors (R5, R6, R7 and R8), 1N4148 freewheeling diodes (D1, D2, D3 and D4), and one LM7407 buffer chip (IC1). The 7407 buffer used here is a hex-type opencollector high-voltage buffer. The 3.3K resistors are the pull-up resistors for the open-collector buffer. The input for this buffer comes from the parallel port. The output of the buffer is of higher current capacity than the parallel port output, which is necessary for triggering the transistor; it also isolates the circuit from the PC parallel port and hence provides extra protection against potentially dangerous feedback voltages that may occur if the circuit fails. The diode connected across the supply and the collector is used as a freewheeling diode and also to protect the transistor from the back EMF of the motor inductance. During normal operation, the output pattern from the PC drives the buffer, and corresponding transistors are switched on. This leads to the conduction of current through those coils of the stepper motor which are connected to the energized transistor. This makes the motor move forward one step. The next pulse will trigger a new combination of transistors, and hence a new set of coils, leading to the motor moving another step. The scheme of excitation that we have used here has already been shown above.
The PC parallel port is a 25 pin D-shaped female connector in the back of the computer. It is normally used for connecting computer to printer, but many other types of hardware for that port are available.
The original IBM PC's Parallel Printer Port had a total of 12 digital outputs and 5 digital inputs accessed via 3 consecutive 8-bit ports in the processor's I/O space. 1. 8 output pins accessed via the DATA Port 2. 5 input pins (one inverted) accessed via the STATUS Port 3. 4 output pins (three inverted) accessed via the CONTROL Port 4. The remaining 8 pins are grounded To read a byte (8 bits) coming into a port, call inb (port); to output a byte, call outb (value, port) (please note the order of the parameters). The data outputs are provided by an 74LS374 totem-pole TTL integrated circuit, which can source (+) 2.6 mA and sink (-) 24 mA. The best option for preventing damage to the port is to use optocouplers; by doing so, the port is completely electrically isolated from external hardware devices.
What is a module?
Modules are pieces of code that can be loaded into and unloaded from a running kernel upon demand. They extend the functionality of the kernel without the need to reboot the system. Device drivers are a class of modules which allows the kernel to control hardware connected to the system. In this article, I have written a simple device driver to control a stepper motor drive; now it is time to log on to your console and start coding your very first module.
Let's have an unusual start! You have written so many "Hello, World" programs. So this time something different - "No gates, No windows, it's open". You will get these words printed on your console when you insert your first module.
/*mymodule.c - The simplest kernel module.*/ #include <linux/module.h> /* Needed by all modules */ #include <linux/kernel.h> /* Needed for KERN_ALERT */ int init_module(void) { printk("<1>No gates, No windows, it's open\n"); return 0;/* A non-0 return means init_module failed; module can't be loaded.*/ } void cleanup_module(void) { printk("Goodbye\n"); }
The "start" function in a kernel module is init_module () which is called when the module is insmoded into the kernel, and the "end" (cleanup) function cleanup_module() is called just before it is rmmoded.
CFLAGS := -O2 -DMODULE -D__KERNEL__ ${WARN} -I${INCLUDE} all : stepper.o #${TARGET}.o : ${TARGET}.c clean: rm -rf *.o
You can learn more about make utility by reading "man make".
A device driver has two sides. One side talks to the rest of the kernel and to the hardware, and the other side talks to the user. To talk to the kernel, the driver registers with subsystems to respond to events. Such an event might be the opening of a file, writing some useful data, the plugging in of a pendrive (USB device), etc. Since Linux is a type of UNIX, and in UNIX everything is a file, users talk with device drivers through device files, which are like a digital representation of a hardware device. A stepper is a character device, and thus the user talks to it through a character device file. The other common type of device file is block. We will only discuss character device files in this article. The user controls the stepper motor through the /dev/stepper device file When the user opens /dev/stepper, the kernel calls stepper's open routine When the user closes /dev/stepper, the kernel calls stepper's release routine When the user reads or writes from or to /dev/stepper - I think you got the idea...
#define LPT_BASE 0x378 #define DEVICE_NAME "stepper" static int Major,i,j,k; static int Device_Open = 0;
//static int pattern[2][8][8] = { // {{0xA,0x9,0x5,0x6},{0xA,0x8,0x9,0x1,0x5,0x4,0x6,0x2}}, // {{0x6,0x5,0x9,0xA},{0x2,0x6,0x4,0x5,0x1,0x9,0x8,0xA}} //}; static int pattern[2][8][8] = { {{0xA,0x9,0x5,0x6,0xA,0x9,0x5,0x6},{0xA,0x8,0x9,0x1,0x5,0x4,0x6,0x2}}, {{0x6,0x5,0x9,0xA,0x6,0x5,0x9,0xA},{0x2,0x6,0x4,0x5,0x1,0x9,0x8,0xA}} }; int step() { if(k<8) // // // // // // // } else { k=0; printk("%d\n",pattern[i][j][k]); /*#####*/ k++; /*#####*/
} return 0;
static int stepper_open(struct inode *inode,struct file *filp) { static int counter = 0; if(Device_Open) return -EBUSY; printk("Opening in WR mode...\n"); Device_Open++; MOD_INC_USE_COUNT; return 0; } static int stepper_release(struct inode *inode,struct file *filp) { printk("Clossing...\n"); Device_Open --; MOD_DEC_USE_COUNT; return 0; } static int stepper_write(struct file *file, const char *buffer, size_t len, loff_t *offset) { char *data; char cmd; get_user(data,buffer); switch (cmd=data) { case 'H': printk("Reffer README file\n");
// // // }
break; case 'h': printk("Half-Step mode initialized\n"); j=0; break; case 'f': printk("Full-Step mode initialized\n"); j=1; break; case 'F': i=0; step(); break; case 'R': i=1; step(); break; default: printk("Give 'H' for Help\n"); break; } return 1;
static struct file_operations fops={ open:stepper_open, write:stepper_write, release:stepper_release, }; int init_module(void) { Major = register_chrdev(0, DEVICE_NAME, &fops); if (Major < 0) { printk("<1>Registering the character device failed with %d \n",Major); return Major; } printk("<1>Registered, got Major no= %d\n",Major); return 0; } void cleanup_module(void) { printk("<1>Unregistered\n"); unregister_chrdev(Major,DEVICE_NAME); }
Driver initialization
1. The init_module() function is called on the driver's initialization 2. The cleanup_module () function is called when the driver is removed from the system
3. The init function will register hooks that will get the driver's code called when the appropriate event happens 4. There are various hooks that can be registered: file operations, PCI operations, USB operations, network operations. Ours is a file operation. 5. The driver registers a character device tied to a given major number and a user can create access points corresponding to this major number.The following command will do it for you:
mknod /dev/stepper c 254 0
H ----------- Help h ----------- Half-step mode f ----------- Full-step mode F ----------- Rotate one step clockwise R ----------- Rotate one step anti-clockwise
File operations
The driver makes use of the following device file operations: 1. open for allocating resources 2. release for releasing resources 3. write the required pattern to the parallel port. 4. there is no reading in our program, but if you want, you can read the current pattern at the parallel port. If you write 'F' once to "/dev/stepper", the motor will rotate through its minimum step-angle. If you keep on writing 'F' to "/dev/stepper", it will rotate continuously. The "write" system call will do this for you.
#include "header.h" main () {
char t,buf[6] = {'h','f','F','R','H','q'}; int fd,rt,i,j; size_t count; printf("Select Mode \n(1) [Half-step clockwise]\n(2) [Half-step anti-clockwise]\n(3) [Full-step clockwise]\n(4) [Full-step anti-clockwise] "); t=getchar(); if(t=='1') {i=0; j=2;} else if(t=='2') {i=0; j=3;} else if(t=='3') {i=1; j=2;} else {i=1; j=3;} fd=open("stepper",O_WRONLY); rt=write(fd,&buf[i],count); for(i=0;i<1000;i++) { rt=write(fd,&buf[j],count); usleep (100000); } close(fd); }
Also, if you are familiar with shell scripting, you can do the same by writing a simple shell script. Now you can start talking to the device /dev/stepper. It will be really interesting if you talk in Linux's language - I mean a shell script. Just use simple echo commands as given below:
echo H > /dev/stepper
Do you think that Morpheus is talking to you? Your kernel is replying to your commands. How's that! Now, you too can feel like you are The One.
Conclusion
I hope I have given you some basics of device driver coding and perhaps a "small step toward Robotics". Here is a detailed schematic of a stepper-controlled robotic arm; feel free to try it out. One can connect three stepper motors simultaneously to the PC parallel port and can achieve step-wise mobility; this allows anyone to start thinking of complex innovative mobility with multi-threaded programming in Linux. You can also add C functions to our module to enhance its functionality... the possibilities are endless!
STEPPER MOTOR DRIVER CIRCUIT USING MICROCONTROLLER: In this demo we are using 6v/2amps 1.8degree stepper motor. In this circuit CD4050 hex buffer using to connect to the microcontroller. The output of cd4050 is connected to the TIP122 of the BASE. The Emitter and collector are connected to 1N4007 diode the collector of tip122 is connected to the stepper motor coil. In this demo we are using Uni-polar Stepper motor using 6wires, the color coding of the stepper motors are Black coil 1, Red coil 2, Green coil 3, Yellow coil 4 and 2 white are connected to give 6V input supply voltage.
27 28 29 30 31 32 33 34
while(1) { rotate();
} }