TERM PROJECT PROJECT TITLE: Microcontroller Based Automatic Railway Gate Control System
Department of Mechanical Engineering SUBMITTED BY Mansura Islam Linda (0810108) Seikh Hayatul Haque (010116) Kawsar Alam (0810124)
Group : B 28
Bangladesh University of Engineering and Technology December-2011
A project paper For Microcontroller Based Automatic Railway Gate Control System
BY Mansura Islam Linda(0810108) Seikh Hayatul Haque (0810116) Kawsar Alam (0810124)
Supervised by Mr. Reaz Mohiuddin, Asst.Professor Mr. Kazi Arafat Rahman , Lecturer Mr. Adnan Morshed, Lecturer Mr. Aminul Islam Khan, Lecturer
ME 362 (Instrumentation and Measurement Sessional)
All praise be upon almighty Allah . We express our humble gratitude to our course teacher Mr. Reaz Mohiuddin, Mr. Kazi Arafat Rahman , Mr. Adnan Morshed and Mr. Aminul Islam Khan .We are doing something like this for the very first time in our life . So ,Without their proper help, advice, smart idea and strong guidance, it was tough for us to complete the project. Special thanks for Mr. Masudur Rahman, assistant Instrumentation Engineer for his integrity and helpfulness.
We are very much grateful for the outstanding technical support from the Carpentry shop. Everybody out there has been a big help . I want to take this opportunity to express my sincere gratitude to my fellow batch mate Fahimul Islam and Farrukh Ahmed Parag for their support without which this project would have been a mere dream . Finally, we express our gratitude to Dr. Taher Ali sir, who made a notable contribution to set up Instrumentation and Measurement sessional Lab. From this lab we have enjoyed the uncomparable feeling of creation . It is really wonderful when things just work ! ACKNOWLEDGEMENT
The purpose of this project is to design a simple system to control an unmanned railway gate over a level crossing. When there is an incoming train on the verge of arriving at the level crossing, an alarm will go on as well as turning the RED SIGNAL Lights on too. The gate/barrier will be automatically closed. The system will be restore to its initial condition (Alarm OFF, RED SIGNAL Lights OFF, GREEN SIGNAL light on, Gate Open) after the train leaves the crossing. In our project, we developed a working algorithm to achieve this target and a simplified model is assembled to illustrate the operation and control.
INTRODUCTION:
Microcontroller Unit ATMEGA32 LEDs AND Light Dependent Resistors(LDR) DC Stepper Gear Motor (5 wire uni-polar type) L293D (motor driver) Resistances for proper biasing, control and safety measure 7805 Capacitors(1F 250v, 0.1F, 1000F) Breadboard Cables Toy Train Ply wood
The AVR core combines a rich instruction set with 32 general purpose working registers. All the 32 registers are directly connected to the Arithmetic Logic Unit (ALU), allowing two independent registers to be accessed in one single instruction executed in one clock cycle. The resulting architecture is more code efficient while achieving throughputs up to ten times faster than conventional CISC microcontrollers. The ATmega32 provides the following features: 32K bytes of In-System Programmable Flash Program memory with Read-While-Write capabilities, 1024 bytes EEPROM, 2K byte SRAM, 32 general purpose I/O lines, 32 general purpose working registers, a JTAG interface for Boundary-scan, On-chip Debugging support and programming, three flexible Timer/Counters with compare modes, Internal and External Interrupts, a serial programmable USART, a byte oriented Two-wire Serial Interface, an 8- channel, 10-bit ADC with optional differential input stage with programmable gain (TQFP package only), a programmable Watchdog Timer with Internal Oscillator, an SPI serial port, and six software selectable power saving modes. The Idle mode stops the CPU while allowing the USART, Two-wire interface, A/D Converter, SRAM, Timer/Counters, SPI port, and interrupt system to continue functioning. The Power-down mode saves the register contents but freezes the Oscillator, disabling all other chip functions until the next External Interrupt or Hardware Reset. In Power-save mode, the Asynchronous Timer continues to run, allowing the user to maintain a timer base while the rest of the device is sleeping. The ADC Noise Reduction mode stops the CPU and all I/O modules except Asynchronous Timer and ADC, to minimize switching noise during ADC conversions. In Standby mode, the crystal/resonator Oscillator is running while the rest of the device is sleeping. This allows very fast start-up combined with low-power consumption. In Extended Standby mode, both the main Oscillator and the Asynchronous Timer continue to run. The device is manufactured using Atmels high density nonvolatile memory technology. The On-chip ISP Flash allows the program memory to be reprogrammed in-system through an SPI serial interface, by a conventional nonvolatile memory programmer, or by an On-chip Boot program running on the AVR core. The boot program can use any interface to download the application program in the Application Flash memory. Software in the Boot Flash section will continue to run while the Application Flash section is updated, providing true Read-While-Write operation. By combining an 8-bit RISC CPU with In-System Self-Programmable Flash on a monolithic chip, the Atmel ATmega32 is a powerful microcontroller that provides a highly-flexible and cost- effective solution to many embedded control applications. The ATmega32 AVR is supported with a full suite of program and system development tools including: C compilers, macro assemblers, program debugger/simulators, in-circuit emulators, and evaluation kits.
Here is the pin configuration of ATMEGA32 :-
As we can see now it is easy to control the motor by changing polarity. But changing the polarity is not as easy as it seemed to be. So we used motor controller to control it. Below there is a schematic to control a single motor.
Motor Controllers (L293D):
When we switch S1 and s4, motor will start rotating; while for switching s2 and s3 motor will be controlled in reverse direction. This diagram is also termed as H-Bridge. This bridge is used for the L293D chip which was used for motor controlling.
For this layout of connection motor will rotate according to the table. Here 1 and 0 denotes high<non-zero voltage> and low<zero voltage> respectively.
For this layout of connection motor will rotate according to the table. Here 1 and 0 denotes high<non-zero voltage> and low<zero voltage> respectively.
PROTEUS CIRCUIT DIAGRAM:
PROTEUS CIRCUIT DIAGRAM:
BLOCK DIAGRAM:
YES YES NO NO NO NO NO NO START INITIALIZE LCD, SENSORS, MOTORS, LIGHTS. SENSOR 2 SENSOR CROSSED?
MOTOR CCW ROTATED, GATE CLOSED SENSOR 1 SENSOR CROSSED?
In the ready state, the MCU (Microcontroller Unit) continuously checks the status of Sensor-1 (SEN1) and Sensor-2 (SEN2). In simple words, when MCU gets an interrupt at any of them, it closes the gate and checks the other Sensor to determine the leaving moment of the train and then it opens the gate to return to ready state. In the above block diagram, we explained the events that occur after getting an interrupt at SEN1. The events for SEN2 might be realized in exactly same manner. After the cycle completes, the system returns to ready state as indicated with a START label in above diagram. Now we explain the logic described in above model. The MCU continuously checks SEN1 as long as the value stays zero. When (SEN=1), MCU starts closing the gate barrier of the railway level crossing by controlling a DC Stepper Gear Motor. There is a local variable SAFETY_FACTOR which initialized as zero at first. It is used to measure the time to pass the train through SEN1 completely in second. But when at first SEN1=1 motors starts running and a small time is needed for closing the barrier completely. By simple hand YES YES MOTOR CW, GATE OPEN MOTOR CW, GATE OPEN YES EXPLANATION : calculation the gate opening and closing time is adjusted to 1 second. So SAFETY_FACTOR starts to count directly from 1 second so that the total time needed to pass the train SEN1 is found correctly. So while the train passes the sensor (so SEN1 stays one), the MCU keeps increasing a local variable SAFETY_FACTOR. When SEN1 becomes zero, it can be realized that the train has already passed SEN1. So MCU starts monitoring the status of SEN2 as shown on the diagram. If the value at SEN2 is one, that means train reached SEN2. Else, it means train has not passed all the way to the leaving sensor yet. So MCU does busy waiting as long as SEN2 is zero. When SEN2 becomes one, we know that train reached SEN2. So assuming the train speed is somewhat constant, we start decreasing SAFETY_FACTOR until it becomes zero. So then it is assumed that the train has left the sensor 2 unless its speed decreased in the mean time. But if the train speed has been decreased in this time then SAFETY_FACTOR becomes zero but train has not passed SEN2 yet. So we make a further check of the SEN2 state, If it is one, then it is obvious that train speed is not constant. So we keep waiting until it becomes zero to indicate confirmation of train leaving. At its zero event, we finally restore the gate position (open gate) using stepper motor and get back to ready state. There are two emergency cases. Firstly, if any vehicle get struck in the middle of the rail line a signal is passed to the train driver. Secondly, if the gate fails to close a signal is passed to the driver so that he could take precautionary measures.
Stepper motor:
The stepper motor is a DC motor, which has several coils. In our design, we used a Stepper Gear Motor. One end of the coils is shorted and kept at Vdc = 12V. The other ends of the coils are energized sequentially and hence the motor starts rotating. The sequence and internal delay between applying the energy dictates the speed and direction of rotation. The pulses on the coils are given via MOSFET Switching. So if we give zero volts at a coil end, it is energized as other end is at 12Vdc. This motor has gear system so that the rotor will not rotate by any mechanical force, until the gate pulses are given in the coils. We used half step rotation logic on the coils. Table: Truth table to rotate the rotor of the stepper motor in half step: coil 4(C4) coil 3(C3) coil 2(C2) coil 1(C1) BYTE Value 1 0 0 1 9 1 0 0 0 8 1 1 0 0 12 0 1 0 0 4 0 1 1 0 6 0 0 1 0 2 0 0 1 1 3 0 0 0 1 1
Stepper motor calculation: C1 C2 +V C3 C4
Step size of stepper motor = 7.5 degrees/step. Rotation of the stepper motor needed = 90 degree Total step requiRED SIGNAL if half step is used = 90 / 7.5 * 2 = 24 If 1 second time is requiRED SIGNAL to close/open the gate delay between 2 half steps = (1/24)*1000 = 42 ms
In our scheme, two infrared sensors were used to detect the presence of train. But weight sensor would give better accuracy for the detection purpose. In that case, four weight sensors will be used in the whole scheme. Two of them will lie at very far from the level crossing to sense the approach of a train, and the other two will be just by the side the crossing to get a better accuracy to get leaving edge of the train.
We assumed the train enters and leaves at almost constant speed. If the train stops in the region of SEN1, then the delay COUNT will increase higher than needed and so the gate will be opened at a delayed time. Although that is not a usual case, still this is a limitation of our design.
LIMITATIONS AND DISCUSSIONS: The motor we used is a DC Stepper Gear type which has a static rotor so that we can hold the Barrier in a vertical plane. If we want to use a gate which will lie beside the railway line and slide horizontally to block the traffic, then any kind of bidirectional motor will be sufficient. But to use a Boom Barrier (on a vertical arc movement), DC Stepper Gear motor must be used as we have done.
// DC Stepper Gear Motor Driving Function // Input Argument 'flag' controls direction of rotation void MotorRun(int flag) { unsigned char i; // forward run signal sequence unsigned char cw[] = {9,8,12,4,6,2,3,1}; for(i=0;i<=7;i++) { if (flag) { // forward run PORTC = cw[i%8]; delay_ms(42); } else { // reverse run PORTC = cw[7-(i%8)]; delay_ms(42); } } }
void main(void) { //local variables int k; int Safety_factor; int emergency;
//status pin output DDRA=0xFF; PORTA=0x00; //sensor input DDRB=0x00; PORTB=0x00; //stepper motor output DDRC=0xFF; PORTC=0x00; // LCD OUTPUT DDRD=0xFF; PORTD=0x00; lcd_init(LCDwidth); lcd_clear(); while (1) { PORTA.0 = 1; // TURN ON GREEN SIGNAL PORTC = 0x00; // MOTOR OFF Safety_factor = 0; // current count is zero
if(PINB.1==1) // train approaches from S1? { //LCD signal for train engine lcd_clear(); sprintf(Buffer1,"RailGate Closing"); lcd_gotoxy(0,0); lcd_puts(Buffer1); sprintf(Buffer2,"Infront"); lcd_gotoxy(4,1); lcd_puts(Buffer2);
PORTA.0 = 0; // turn OFF GREEN SIGNAL PORTA.1 = 1; // TURN ON YELLOW SIGNAL PORTA.7 = 1; // TURN BUZZER ON delay_ms(2000); PORTA.1 = 0; // TURN OFF YELLOW SIGNAL PORTA.2 = 1; // TURN ON RED SIGNAL
// gate is closing now. for (k=0;k<3;k++) { MotorRun(1); // motor forward run }
PORTC = 0x00; // ULN SIGNALS ARE ZERO Safety_factor = 2; // initialize the count to 2
emergency = 1000;
while(emergency ==1000) { if(PINB.6 == 1) { PORTA.6 = 1; lcd_clear(); sprintf(Buffer1,"EMERGENCY!!"); lcd_gotoxy(4,0); lcd_puts(Buffer1); sprintf(Buffer2,"SLOW DOWN"); lcd_gotoxy(4,1); lcd_puts(Buffer2); break; } delay_ms(1); emergency--; } if(PINB.1==1) // train tail entering? { while(PINB.1==1) // yes then check again { Safety_factor++; // count upward delay_ms(500); // now wait for 1 sec... delay_ms(500); // and then check again } }
if(PINB.2==0) // train reached S2? { while(PINB.2==0) // no, then keep waiting { ; // until train reaches S2 } } // above loop is broken, so train reached S2
while(Safety_factor>0) // is count nonzero? { delay_ms(500); // then wait for 1 second delay_ms(500); // and then decrease the COUNT Safety_factor--; // count and loop again } // count is zero now, so train has possibly passed S2 if(PINB.2==1) // but check again { while(PINB.2==1) // is train tail on S2? { ; // keep polling } } PORTA.2 = 0; // TURN OFF RED SIGNAL PORTA.1 = 1; // TURN ON YELLOW SIGNAL
// now the train tail surely passed S2, so... for (k=0;k<3;k++) { MotorRun(0); // motor reverse run } PORTC = 0x00; // motor off //LCD signal for train engine lcd_clear(); sprintf(Buffer1,"RailGate crossed"); lcd_gotoxy(0,0); lcd_puts(Buffer1); PORTA.6 = 0; delay_ms(1000); PORTA.7 = 0; // TURN BUZZER OFF PORTA.1 = 0; // TURN OFF YELLOW SIGNAL PORTA.0 = 1; // turn ON GREEN SIGNAL lcd_clear(); }
// Now, as we reach this line of the code, it // means S1 is not sensing any incoming train // so check for train from the opposite direction
else if(PINB.2==1) // train approaches from S2? { //LCD signal for train engine lcd_clear(); sprintf(Buffer1,"RailGate Closing"); lcd_gotoxy(0,0); lcd_puts(Buffer1); sprintf(Buffer2,"Infront"); lcd_gotoxy(4,1); lcd_puts(Buffer2);
PORTA.0 = 0; // turn OFF GREEN SIGNAL PORTA.1 = 1; // TURN ON YELLOW SIGNAL PORTA.7 = 1; // TURN BUZZER ON delay_ms(2000); PORTA.1 = 0; // TURN OFF YELLOW SIGNAL PORTA.2 = 1; // TURN ON RED SIGNAL
for (k=0;k<3;k++) { MotorRun(1); // motor forward run }
PORTC = 0x00; // ULN signal zero Safety_factor = 2; // initialize the count to 2
if(PINB.2==1) // train tail entering? { while(PINB.2==1) // yes then check again { Safety_factor++; // count upward delay_ms(500); // now wait for 1 sec... delay_ms(500); // and then check again } }
if(PINB.1==0) // train reached S1? { while(PINB.1==0) // no, then keep waiting { ; // until train reaches S1 } } // above loop is broken, so train reached S1
while(Safety_factor>0) // is count nonzero? { delay_ms(500); // then wait for 1 second delay_ms(500); // and then decrease the Safety_factor--; // count and loop again } // count is zero now, so train has possibly passed S1 if(PINB.1==1) // but check again { while(PINB.1==1) // is train tail on S2? { ; // keep polling } } // now the train tail surely passed S2, so... PORTA.2 = 0; // TURN OFF RED SIGNAL PORTA.1 = 1; // TURN ON YELLOW SIGNAL
for (k=0;k<3;k++) { MotorRun(0); // motor reverse run } PORTC = 0x00; // ULN signal zero lcd_clear(); sprintf(Buffer1,"RAILGAT E CROSSED"); lcd_gotoxy(0,0); lcd_puts(Buffer1); PORTA.6 = 0; delay_ms(1000); PORTA.7 = 0; // TURN BUZZER OFF PORTA.1 = 0; // TURN OFF YELLOW SIGNAL PORTA.0 = 1; // turn ON GREEN SIGNAL lcd_clear(); } } }