PIC16F877A interface sensor and motor with MicroC code.

Status
Not open for further replies.

Ishah

Member level 1
Joined
Mar 13, 2013
Messages
33
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Visit site
Activity points
1,502
Hi everyone,

I need your help to fix my code. I want to make project security sliding door. When the user push one button the motor will run,at the same time when the user push the button again,the motor will stop. Another case, while the motor is running,the sensor triggered and the motor will stop.

Here is my Proteus circuit and my code. I am lack of programming, but I try to learn it seem it look messy. Can anyone give some example?

My problem is the motor automatically run,stop,run without selecting any button.

Code:
/*
    Project Title: Controlled Motor by switches and sensor

*/

void main()
{
  TRISA=0XFF; //Configure all bit of PORTA as input
  TRISB=0XFF; //Configure all bit of PORTB as input
  TRISD=0X00; //Configure all bit of PORTD as output
  PORTA=0X00;       // Clear bits to zero
  PORTB=0X00;       // Clear bits to zero
  PORTD=0X00;       // Clear bits to zero

  CMCON=0X07; //      or CMCON register = 0X00000111

  ADCON1=0X07; //     Configure ADCON1, or ADCON1=0X06;

do
{
    if(PORTB.F0 == 1)   //If the switch is pressed
       {
          PORTD.F0 = 0;   // Motor 1 clockwise
          PORTD.F1 = 1;
          PORTD.F2 = 0;   // Motor 2 clockwise
          PORTD.F3 = 1;
          Delay_ms(1000);         // Delay 100 ms
       }
    else
    if (PORTB.F1 == 1)   //If the switch is pressed
       {
          if(PORTB.F1 == 1)   //If the switch is pressed

          PORTD.F0 = 1;   // Motor 1 anti-clockwise
          PORTD.F1 = 0;
          PORTD.F2 = 1;   // Motor 2 anti-clockwise
          PORTD.F3 = 0;
          Delay_ms(1000);         // Delay 100 ms
       }
    else
       {
          PORTD.F0 = 1;   // Motor stop
          PORTD.F1 = 1;
          PORTD.F2 = 1;   // Motor stop
          PORTD.F3 = 1;
          Delay_ms(500);         // Delay 1000 ms
       }
       
    if(PORTA.F0 == 1)   //If the sensor triggered
       {
          PORTD.F0 = 0;   // Motor 1 stop
          PORTD.F1 = 0;
          PORTD.F2 = 0;   // Motor 2 stop
          PORTD.F3 = 0;
          Delay_ms(500);         // Delay 100 ms
       }
    else
    if(PORTA.F1 == 1)   //If the sensor triggered
       {
          PORTD.F0 = 0;   // Motor 1 stop
          PORTD.F1 = 0;
          PORTD.F2 = 0;   // Motor 2 stop
          PORTD.F3 = 0;
          Delay_ms(500);         // Delay 100 ms
       }
    else
       {
          PORTD.F0 = 1;   // Motor 1 keep run
          PORTD.F1 = 1;
          PORTD.F2 = 1;   // Motor 2 keep run
          PORTD.F3 = 1;
          Delay_ms(500);         // Delay 100 ms
       }
 }
while(1);
}
Then if I make some changes
Code:
 ADCON1=0X07; //     Configure ADCON1, or ADCON1=0X06;

while(1);
{
    if(PORTB.F0 == 1)   //If the switch is pressed .................................  

......................................
......................................              
 Delay_ms(500);         // Delay 100 ms
       }
 }

}
The motor static.

Here are the result:
For simulation, I used the switches as sensor.

 

Hi, from what I can see, it appears the code is okay. However, I'll recommend you take another look at your circuit connection for PORTB.

From what I can understand looking at the code, the idle state for the PORTB input pins is supposed to be a LOW (0), and when the switch is pressed, it goes HIGH.
But from your circuit connection RB0, RB1 and RB2 are idle HIGH through their individual 10k resistors connecting them to the 5V rail. Therefore, your circuit will definitely keep running as if all three switches are simultaneously pressed, and that might explain why your circuit responds without the switch being pressed.

Two ways to go about correcting this:
1. Change the connection to idle LOW for the PORTB pins (You'll have to come up with a different connection)
2. (Recommended) Change your code to idle HIGH while you retain the existing connection -- something like:

Code:
/*
    Project Title: Controlled Motor by switches and sensor

*/

void main()
{
  TRISA=0XFF; //Configure all bit of PORTA as input
  TRISB=0XFF; //Configure all bit of PORTB as input
  TRISD=0X00; //Configure all bit of PORTD as output
  PORTA=0X00;       // Clear bits to zero
  PORTB=0X00;       // Clear bits to zero
  PORTD=0X00;       // Clear bits to zero

  CMCON=0X07; //      or CMCON register = 0X00000111

  ADCON1=0X07; //     Configure ADCON1, or ADCON1=0X06;

do
{
    if([COLOR="#FF0000"]PORTB.F0 == 0[/COLOR])   //If the switch is pressed
       {
          PORTD.F0 = 0;   // Motor 1 clockwise
          PORTD.F1 = 1;
          PORTD.F2 = 0;   // Motor 2 clockwise
          PORTD.F3 = 1;
          Delay_ms(1000);         // Delay 100 ms
       }
    else
    if ([COLOR="#FF0000"]PORTB.F1 == 0[/COLOR])   //If the switch is pressed
       {
          if(PORTB.F1 == 1)   //If the switch is pressed

          PORTD.F0 = 1;   // Motor 1 anti-clockwise
          PORTD.F1 = 0;
          PORTD.F2 = 1;   // Motor 2 anti-clockwise
          PORTD.F3 = 0;
          Delay_ms(1000);         // Delay 100 ms
       }
    else
       {
          PORTD.F0 = 1;   // Motor stop
          PORTD.F1 = 1;
          PORTD.F2 = 1;   // Motor stop
          PORTD.F3 = 1;
          Delay_ms(500);         // Delay 1000 ms
       }
       
    if(PORTA.F0 == 1)   //If the sensor triggered
       {
          PORTD.F0 = 0;   // Motor 1 stop
          PORTD.F1 = 0;
          PORTD.F2 = 0;   // Motor 2 stop
          PORTD.F3 = 0;
          Delay_ms(500);         // Delay 100 ms
       }
    else
    if(PORTA.F1 == 1)   //If the sensor triggered
       {
          PORTD.F0 = 0;   // Motor 1 stop
          PORTD.F1 = 0;
          PORTD.F2 = 0;   // Motor 2 stop
          PORTD.F3 = 0;
          Delay_ms(500);         // Delay 100 ms
       }
    else
       {
          PORTD.F0 = 1;   // Motor 1 keep run
          PORTD.F1 = 1;
          PORTD.F2 = 1;   // Motor 2 keep run
          PORTD.F3 = 1;
          Delay_ms(500);         // Delay 100 ms
       }
 }
while(1);
}


ADCON1=0X07; //     Configure ADCON1, or ADCON1=0X06;

while(1);
{
    if([COLOR="#FF0000"]PORTB.F0 == 0[/COLOR])   //If the switch is pressed .................................  

......................................
......................................              
 Delay_ms(500);         // Delay 100 ms
       }
 }

}
 

Hi Ibkay and jayanth,
Thanks for your feedback.

Two ways to go about correcting this:
1. Change the connection to idle LOW for the PORTB pins (You'll have to come up with a different connection)
2. (Recommended) Change your code to idle HIGH while you retain the existing connection

I already follow the suggestion of 2nd option and change my code to:

Code:
/*
    Project Title: Controlled Motor by switches and sensor

*/

void main()
{
  TRISA=0XFF; //Configure all bit of PORTA as input
  TRISB=0XFF; //Configure all bit of PORTB as input
  TRISD=0X00; //Configure all bit of PORTD as output
  PORTA=0X00;       // Clear bits to zero
  PORTB=0X00;       // Clear bits to zero
  PORTD=0X00;       // Clear bits to zero

  CMCON=0X07; //      or CMCON register = 0X00000111
  ADCON1=0X07; //     Configure ADCON1, or ADCON1=0X06;

do
{
    if(PORTB.F0 == 0)   //If the switch is pressed
       {
          PORTD.F0 = 0;   // Motor 1 clockwise
          PORTD.F1 = 1;
          PORTD.F2 = 0;   // Motor 2 clockwise
          PORTD.F3 = 1;
          Delay_ms(500);         // Delay 500 ms
       }
    else
    if (PORTB.F1 == 0)   //If the switch is pressed
       {
          if(PORTB.F1 == 0)   //If the switch is pressed

          PORTD.F0 = 1;   // Motor 1 anti-clockwise
          PORTD.F1 = 0;
          PORTD.F2 = 1;   // Motor 2 anti-clockwise
          PORTD.F3 = 0;
          Delay_ms(500);         // Delay 500 ms
       }
    else
       {
          PORTD.F0 = 1;   // Motor stop
          PORTD.F1 = 1;
          PORTD.F2 = 1;   // Motor stop
          PORTD.F3 = 1;
          Delay_ms(500);         // Delay 500 ms
       }
       
    if(PORTA.F0 == 1)   //If the sensor triggered
       {
          PORTD.F0 = 0;   // Motor 1 stop
          PORTD.F1 = 0;
          PORTD.F2 = 0;   // Motor 2 stop
          PORTD.F3 = 0;
          Delay_ms(500);         // Delay 500 ms
       }
    else
    if(PORTA.F1 == 1)   //If the sensor triggered
       {
          PORTD.F0 = 0;   // Motor 1 stop
          PORTD.F1 = 0;
          PORTD.F2 = 0;   // Motor 2 stop
          PORTD.F3 = 0;
          Delay_ms(500);         // Delay 500 ms
       }
    else
       {
          PORTD.F0 = 1;   // Motor 1 keep run
          PORTD.F1 = 1;
          PORTD.F2 = 1;   // Motor 2 keep run
          PORTD.F3 = 1;
          Delay_ms(500);         // Delay 500 ms
       }
 }
while (1);
}

The problem now is when I push the button, the motor run but in a few second it stop and run again. Seem my stop button does not needed in circuit.

and I think, this is what Jaya mentioned on
With changes mentioned by Ibkay add 50 ms debounce delays for the switches.

In the other hand, the sensor also not functioning as what I want.



Please Help.
 

Code for button 3 and sensor 3 is missing.

You want motor to stop when any sensor input becomes high? How should the 3 buttons control the motor?



Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#define SENSORPORT PORTA
#define SWITCHPORT PORTB
#define MOTORPORT PORTD
 
unsigned short toggle = 0;
 
void main(){
 
    TRISA = 0XFF; //Configure all bit of PORTA as input
    TRISB = 0XFF; //Configure all bit of PORTB as input
    TRISD = 0X00; //Configure all bit of PORTD as output
    PORTA = 0X00; //Clear bits to zero
    PORTB = 0X00; //Clear bits to zero
    PORTD = 0X00; //Clear bits to zero
 
    CMCON=0X07;   //or CMCON register = 0X00000111
    ADCON1=0X07;  //Configure ADCON1, or ADCON1=0X06;
 
    while(1){
    
        if((SENSORPORT & 0x07) == 0x00){
    
            if(((SWITCHPORT & 0x07) == 0x06) ){ //SW1 pressed
                Delay_ms(50);
                if((SWITCHPORT & 0x07) == 0x06){
 
                    MOTORPORT = (MOTORPORT & 0xF0) | 0x0A;  //Motor 1 & 2 CW
 
                }
                }
            else if(((SWITCHPORT & 0x07) == 0x05)){ //SW2 pressed
                Delay_ms(50);
                if((SWITCHPORT & 0x07) == 0x05){
 
                    MOTORPORT = (MOTORPORT & 0xF0) | 0x05;  //Motor 1 & 2 CCW
 
                }
                }
            else if(((SWITCHPORT & 0x07) == 0x03)){ //SW3 pressed
                Delay_ms(50);
                if((SWITCHPORT & 0x07) == 0x03){
 
                    MOTORPORT = (MOTORPORT & 0xF0);     //Motor 1 & 2 Stop
 
                }
                }
 
        }
        else if(((SENSORPORT & 0x07) == 0x01) || ((SENSORPORT & 0x07) == 0x02) || ((SENSORPORT & 0x07) == 0x04))){
                MOTORPORT = (MOTORPORT & 0xF0);
        }   
    }
}

 
Last edited:

Hi Jaya,

Thanks for the code, the motor run and it stop when sensor triggered.



Actually, here is the operation I want to do. I attached the physical model of my project.




I think I should change the code right?
 

Your image and expanation was not helpful. PBx are buttons in image? Just explain the working of 3 buttons ins your circuit. Earlier you said
When the user push one button the motor will run,at the same time when the user push the button again,the motor will stop.

You want 3 buttons or 2 buttons?

If three buttons - 1st button starts or stops the motors, 2nd button will turn motors CW, 3rd button turn the motors CCW.
If 2 buttons - 1st button starts or stops motors, 2nd button change direction to CW or CCW.

2 buttons is enough. Decide and mention the working you need that is 3 buttons or 2 buttons. Also mention the working of each button.

Connect all the 3 sensor outputs to the same input pin preferably RB0/INT0 pin and use INT0 interrupt to detect sensor o/p.

If needed you can use 3 input OR gate and connect sensor outputs to OR gate inputs and connect OR gate output to RB0/INT0 pin.

Redesign the hardware and software.

Zip and post Proteus .dsn file. I don't have time and patience to draw your circuit. The last operation being performed before sensor ia activated should be stored in memory and after sensor output clears the previous operation should be continued i.e., if door was closing and sensor made it to stop then after sensor output clears the closing of door should be continued.
 
Last edited:

Door Control attached. It used ADC for buttons and external interrupt on rising edge to detect sensors outputs. One button is used to turn ON/OFF motors and another to change direction of motors.


Edit: rev1 file attached. Changed code for button so that button press is registered only if button is released after pressing.
 

Attachments

  • Door Control.rar
    46.7 KB · Views: 70
  • Door Control rev1.rar
    53.3 KB · Views: 73
Last edited:

Fixed a minor bug. After interrupt was cleared the previous operation was not continuing.



- - - Updated - - -

Replace s1, s2, s3, connected to R4, R5, R6 in your circuit with output pins. You have used input pins for them. You have to use one input pin and one output pin which make a pair for connection.
 

Attachments

  • Door Control Working.rar
    44.1 KB · Views: 116
  • dc.png
    68.4 KB · Views: 126

Hi Jaya,

sorry for late feedback. I need to understand your code given since I am lack of it.

I already draw a new model view, schematic and code.

After edit my code, the simulation using ISIS proteus, the motor run without selected any button. Still have the problems.

Code:
//define motor1 ports
sbit motor1a at RD0_bit;
sbit motor1b at RD1_bit;


//define motor2 ports
sbit motor2a at RD2_bit;
sbit motor2b at RD3_bit;

//define sensor ports
#define SENSOR PORTA


//define switches ports
#define PB1 PORTB.F0
#define PB2 PORTB.F1
#define PB3 PORTB.F2
#define PB4 PORTB.F3

unsigned short toggle = 0;

void main(){

    TRISA = 0XFF; //Configure all bit of PORTA as input
    TRISB = 0XFF; //Configure all bit of PORTB as input
    TRISD = 0X00; //Configure all bit of PORTD as output
    PORTA = 0X00; //Clear bits to zero
    PORTB = 0X00; //Clear bits to zero
    PORTD = 0X00; //Clear bits to zero

    CMCON=0X07;   //or CMCON register = 0X00000111
    ADCON1=0X07;  //Configure ADCON1, or ADCON1=0X06;

    while(1){

        if((SENSOR & 0x07) == 0x00)
        {

            if(PB1 == 1)   //If the push button 1 is pressed
            {
             Delay_ms(50);         // Delay 100 ms
             if(PB1 == 1)
                 {
                    motor1a = 1;   // Motor 1 clockwise
                    motor1b = 0;
                    motor2a = 1;   // Motor 2 clockwise
                    motor2b = 0;
                 }
             }
            else
            if (PB2 == 1)   //If the push button 2 is pressed
            {
              Delay_ms(50);         // Delay 100 ms
              if(PB2 == 1)
                 {
                    if(PB2 == 1)

                    motor1a = 0;   // Motor 1 counter clockwise
                    motor1b = 1;
                    motor2a = 0;   // Motor 2  counter clockwise
                    motor2b = 1;
                 }
             }
            else
            if (PB3 == 1)   //If the push button 3 is pressed
            {
              Delay_ms(50);         // Delay 100 ms
              if(PB3 == 1)
                 {
                    motor1a = 1;   // Motor 1 clockwise
                    motor1b = 0;
                    motor2a = 1;   // Motor 2 clockwise
                    motor2b = 0;
                 }
            }
            else
            if (PB4 == 1)   //If the push button 4 is pressed
            {
              Delay_ms(50);         // Delay 100 ms
              if(PB4 == 1)
                 {
                    motor1a = 0;   // Motor 1 counter clockwise
                    motor1b = 1;
                    motor2a = 0;   // Motor 2 counter clockwise
                    motor2b = 1;
                 }
             }
        }
        else if(((SENSOR & 0x07) == 0x01) || ((SENSOR & 0x07) == 0x02) || ((SENSOR & 0x07) == 0x04))
        {
                motor1a = 0;   // Motor 1 stop
                motor1b = 0;
                motor2a = 0;   // Motor 2 stop
                motor2b = 0;
        }
      }
}



Here is my new schematic image.Already replace the input pin.
Did I still need to draw 74HC4075 and 74HC10 ?In my circuit I drew both.

Replace s1, s2, s3, connected to R4, R5, R6 in your circuit with output pins. You have used input pins for them. You have to use one input pin and one output pin which make a pair for connection.




The zip file.

- - - Updated - - -


I want to ask can the button used in twice function ? For the example: PB2 push, motor 1 and motor 2 run. Next PB2 push, only motor 1 run ?





System Operation
Here are 3 boxes of cabinet. Box 1 is fixed box while another 2 boxes is moveable box. The user can select either PB1 or PB3 “Right Button” or PB2 OR PB 4 “Left Button” at any box. For example; if the users select the PB2 of box 2, both motor (M1 and M2) will run to left side until the motor 1 detect the proximity sensor and motor 2 reached a limit switch. When the user step in the aisle between the box 2 and box 1, the both motor will stop since the PIR sensor will automatically detect the user. So, automatically whole the system operation will stop and all illuminated push button will blink. When the sensors clear the interrupt (no obstacle), the user can continue the current operation by select either “Right Button” or “Left Button” at any box again. IR sensor used to detect user and Proximity sensor used to keep the safe distance between tow boxes.



Thanks Jaya.
 

Attachments

  • design new.zip
    169.1 KB · Views: 77

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…