pic16f877a and mikroc problem

Discussion in 'Embedded Systems and Microcontrollers' started by wali78, Jan 2, 2015.

  1. wali78

    Thread Starter New Member

    Dec 29, 2014
    28
    0
    Hi, it would be nice if somebody can help me in my project, I try to control 6 relays with different times and repeating some operations, below is the code in MikroC, it doesn't work correctly. I hope to find a solution here.

    void main() {

    TRISB=0b00000000;
    PORTB=0; {
    for(;;){

    RB1_bit=1;
    Delay_ms(5000);
    RB1_bit=0;
    delay_ms(2000);

    RB2_bit=1;
    delay_ms(5000);
    RB2_bit=0;
    delay_ms(2000);

    RB3_bit=1;
    delay_ms(5000);
    RB3_bit=0;
    delay_ms(2000);


    RB1_bit=1;
    Delay_ms(5000);
    RB1_bit=0;
    delay_ms(2000);

    RB5_bit=1;
    Delay_ms(5000);
    RB5_bit=0;
    delay_ms(2000);

    RB2_bit=1;
    delay_ms(5000);
    RB2_bit=0;
    delay_ms(2000);

    RB3_bit=1;
    delay_ms(5000);
    RB3_bit=0;
    delay_ms(2000);


    RB1_bit=1;
    delay_ms(5000);
    RB1_bit=0;
    delay_ms(2000);

    RB4_bit=1;
    delay_ms(2000);
    RB4_bit=0;
    delay_ms(2000);

    RB5_bit=1;
    Delay_ms(5000);
    RB5_bit=0;
    delay_ms(2000);

    RB2_bit=1;
    Delay_ms(5000);
    RB2_bit=0;
    delay_ms(2000);

    RB3_bit=1;
    delay_ms(5000);
    RB3_bit=0;
    delay_ms(2000);

    RB5_bit=1;
    delay_ms(5000);
    RB5_bit=0;
    delay_ms(2000);

    RB7_bit=1;


    }
    }
    }
     
  2. absf

    Senior Member

    Dec 29, 2010
    1,493
    372
    Are you wanting all the 6 relays to ON/OFF at the same time with different timing?

    OR you want to do it one pattern at a time?

    Allen
     
  3. wali78

    Thread Starter New Member

    Dec 29, 2014
    28
    0
    Many thanks for the quick response, I want to tun on/off the relays as follow:
    Ex.
    {
    Relay 1 ON/OFF (delay time)
    after that
    Relay 2 ON/OFF (delay time)
    after that
    Relay 3 ON/OFF (delay time)

    And then,
    Relay 1 ON/OFF
    after that
    Relay 5 ON/OFF (delay time)
    after that
    Relay 2 ON/OFF (delay time)
    after that
    Relay 3 ON/OFF (delay time)

    And then,
    Relay 1 ON/OFF (delay time)
    after that
    Relay 5 ON/OFF (delay time)
    after that
    Relay 4 On/OFF (delay time)
    Relay 2 ON/OFF (delay time)
    after that
    Relay 3 ON/OFF (delay time)

    And then,
    Relay 5 ON/OFF (delay time)

    And then,
    LED 7 ON
    }
     
  4. wali78

    Thread Starter New Member

    Dec 29, 2014
    28
    0
    I want to tun on/off the relays as follow:
    Ex.
    {
    Relay 1 ON/OFF (delay time)
    after that
    Relay 2 ON/OFF (delay time)
    after that
    Relay 3 ON/OFF (delay time)

    And then,
    Relay 1 ON/OFF
    after that
    Relay 5 ON/OFF (delay time)
    after that
    Relay 2 ON/OFF (delay time)
    after that
    Relay 3 ON/OFF (delay time)

    And then,
    Relay 1 ON/OFF (delay time)
    after that
    Relay 5 ON/OFF (delay time)
    after that
    Relay 4 On/OFF (delay time)
    Relay 2 ON/OFF (delay time)
    after that
    Relay 3 ON/OFF (delay time)

    And then,
    Relay 5 ON/OFF (delay time)

    And then,
    LED 7 ON
    }
     
  5. JohnInTX

    Moderator

    Jun 26, 2012
    2,347
    1,029
    What do you mean it doesn't work correctly? Do you mean it doesn't compile correctly? Delay_ms() is valid but delay_ms() is not if case-sensitivity is turned on. You should fix the function calls as I did then turn case-sensitivity ON and leave it on. (Tools->Options->Output->Output Settings - check the case-sensitivity box).
    I removed the extra bracket after PORTB=0; to clean things up.
    But, if your code compiled with no errors it should have worked OK.

    The code below compiles and simulates OK in MPSIM so not sure what your problem is.
    If you are running on hardware, be sure to have the configuration bits set for the oscillator type and frequency, watchdog timer OFF etc.

    If you are simulating, be aware that delays will take MUCH longer to execute in the sim than on the hardware. That can make it look like it locked up.
    Try commenting out all but one LED flashing. Get that working then add the rest.
    Code (Text):
    1. void main()
    2. {
    3.      TRISB=0b00000000;
    4.      PORTB=0;
    5.      for(;;){
    6.  
    7.       RB1_bit=1;
    8.       Delay_ms(5000);
    9.       RB1_bit=0;
    10.       Delay_ms(2000);
    11.  
    12.       RB2_bit=1;
    13.       Delay_ms(5000);
    14.       RB2_bit=0;
    15.       Delay_ms(2000);
    16.  
    17.       RB3_bit=1;
    18.       Delay_ms(5000);
    19.       RB3_bit=0;
    20.       Delay_ms(2000);
    21.  
    22.  
    23.       RB1_bit=1;
    24.       Delay_ms(5000);
    25.       RB1_bit=0;
    26.       Delay_ms(2000);
    27.  
    28.       RB5_bit=1;
    29.       Delay_ms(5000);
    30.       RB5_bit=0;
    31.       Delay_ms(2000);
    32.  
    33.       RB2_bit=1;
    34.       Delay_ms(5000);
    35.       RB2_bit=0;
    36.       Delay_ms(2000);
    37.  
    38.       RB3_bit=1;
    39.       Delay_ms(5000);
    40.       RB3_bit=0;
    41.       Delay_ms(2000);
    42.  
    43.  
    44.       RB1_bit=1;
    45.       Delay_ms(5000);
    46.       RB1_bit=0;
    47.       Delay_ms(2000);
    48.  
    49.       RB4_bit=1;
    50.       Delay_ms(2000);
    51.       RB4_bit=0;
    52.       Delay_ms(2000);
    53.  
    54.       RB5_bit=1;
    55.       Delay_ms(5000);
    56.       RB5_bit=0;
    57.       Delay_ms(2000);
    58.  
    59.       RB2_bit=1;
    60.       Delay_ms(5000);
    61.       RB2_bit=0;
    62.       Delay_ms(2000);
    63.  
    64.       RB3_bit=1;
    65.       Delay_ms(5000);
    66.       RB3_bit=0;
    67.       Delay_ms(2000);
    68.  
    69.       RB5_bit=1;
    70.       Delay_ms(5000);
    71.       RB5_bit=0;
    72.       Delay_ms(2000);
    73.  
    74.       RB7_bit=1;
    75.  
    76.       } //for
    77. } //main
    Good luck!
     
    Last edited: Jan 3, 2015
  6. wali78

    Thread Starter New Member

    Dec 29, 2014
    28
    0
    Many thanks for your interest and your effort, I rebuilt the project and tried it, the result is; it works. but when I connected it to the device I wanted to control it according to this code; it goes snafu. it doesn't goes in the sequence which is programmed for.
    I connected these PCBs with 2 separate power sources; one for the PIC and one for the relays and its IC.

    PS. I'm trying to attach a photo for the schematic but I don't know how! when I click on Upload a file I find nothing in the folder.
    anyhow, I'm very sure of the schematic, where the system works before.

    Pls advice.

    Regards.
     
  7. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,810
    834
    Have you connected the grounds of the two power supplies together? Can you provide a schematic?
     
  8. John P

    AAC Fanatic!

    Oct 14, 2008
    1,634
    224
    Use CODE tags please!

    As I said just a few days ago in another thread:

    I've had enough problems with PIC processor outputs that I just force myself to be defensive and use "shadow ports" and live with the extra time, code space and memory use that it involves. The trouble is Microchip's worst idea ever, the read-modify-write operation. It means that changing a single bit of a port may unpredictably change other pins. Not saying that's the problem here, but I'd avoid having to worry. When I write the code, every action on a port pin looks like this, and note also the text written with CODE tags (but setting or clearing bits may be different with your compiler):
    Code (Text):
    1.  
    2. unsigned char portb_shadow;
    3.  
    4. bit_set(portb_shadow, 0);
    5. portb = portb_shadow;
    6.  
     
    absf and JohnInTX like this.
  9. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,606
    What do you mean you "tried it" and "it works" without connecting what where? What is the mystery "device"?

    The "Upload a File" button opens a window to files on your computer. If you browse to the folder where your file is but it does not appear then you need to change the file type to something acceptable. gif, bmp and jpg are always acceptable, as is pdf. Don't upload files from any schematic program as not everyone has every program to view these.

    As a last resort do a "Print Screen" capture and paste into MS Paint, save and upload that.

    If it worked you wouldn't be asking for help.

    We can't help until we know what you are doing.
     
  10. wali78

    Thread Starter New Member

    Dec 29, 2014
    28
    0
    DISHWASHER timer
     
  11. wali78

    Thread Starter New Member

    Dec 29, 2014
    28
    0
    No. the problem is that the sequence is not as wrote in the code.
    thanks a lot
     
  12. wali78

    Thread Starter New Member

    Dec 29, 2014
    28
    0
    I'll try this, thank you.
     
  13. wali78

    Thread Starter New Member

    Dec 29, 2014
    28
    0
    I appreciate your effort, I don't know how to use this code where I'm new in this topic.
    is it possible to write an example which can help me?
    I want to control 6 relays with different times and repeating some operations.
    here it is the sequence I want
    Relay: 1, 2, 3 then 1, 5, 2, 3 then 1, 4, 5, 2, 3 then 5 and then 7

    I use MikroC.
     
  14. JohnInTX

    Moderator

    Jun 26, 2012
    2,347
    1,029
    Your circuit is in error. The ULN2003 is a SINKING driver. You have it wired as if it sources current. To fix it:
    1) Connect the common relay coil wires and pin 9 to +12V.
    2) Connect pin 8 (E) of the ULN2003 to ground via direct connection to the power supply ground. Don't share this ground wire with the PIC ground. The drivers sink to ground via this pin when turned on, energizing the coils.
    3) Each of the other relay coil wires go to individual outputs of the ULN2003 as you have them.
    That should fix your coil driving problem.

    The LEDs D1-D5 should have indicated the proper sequence. Do they? If not, is the PIC running?

    I see no oscillator hookup on the schematic and the 877A does not have an internal oscillator. You have to provide one AND program the configuration bits in MikroC (Project->Edit Project). For the 877A you have a choice of crystal or external oscillators. Pick the one you are going to use. I would turn on the Power-Up Timer as well. Be sure to select the correct oscillator frequency so that your delays are computed correctly.

    When you get some action on the LEDs the relays should follow.

    When you get that far, consider shadowing the ports. Here's a simplified version of your program showing how to do that. It compiles and simulates OK on MikroC.

    Code (Text):
    1. // Example of shadowing PORTB. An image of the port is maintained in RAM.
    2. // Changes to the port are done by first modifying the image then writing
    3. // the whole byte to the PORT and avoiding r-m-w problems.
    4.  
    5. unsigned char PORTBimage;
    6.  
    7. void main()
    8. {
    9.      TRISB=0b00000000;
    10.      PORTB=0;
    11.      PORTBimage = 0; // must start the same
    12.      for(;;){
    13.  
    14.       //RB1_bit=1;
    15.       PORTBimage.B1 = 1; // set bit in shadow register
    16.       PORTB = PORTBimage;  // write it to the port
    17.       Delay_ms(5000);
    18.  
    19.       //RB1_bit=0;
    20.       PORTBimage.B1 = 0; // set bit in shadow register
    21.       PORTB = PORTBimage;  // write the new pattern to the port
    22.       Delay_ms(2000);
    23.  
    24.       //RB7_bit=1;
    25.       PORTBimage.B7 = 1;
    26.       PORTB = PORTBimage;
    27.  
    28.     } //for
    29. } //main
    Good luck!
     
    Last edited: Jan 7, 2015
  15. wali78

    Thread Starter New Member

    Dec 29, 2014
    28
    0
    At first, I would like to thank you and thank everybody here try to help, highly appreciated; regarding to the schematic(but it has drown in Proteus so that you don't see pins 11, 12, 13, 14, 31, 32 of PIC also pins 8, 9 of ULN2003); I'm with you in every advise you said and already everything is connected with its necessary component as it should be;

    1) PIC pins 11, 12 to VCC & VSS, 13, 14 to CRYSTAL (4Mhz), 31, 32 are VCC & VSS (connected internally); Oscillator is 4 Mhz in MikroC, Proteus and WinPic800.
    2) ULN2003A has a separate power source, 9 to 12vdc and connected to the common of the coils of the relays, and 8 to GND .

    I mentioned before that the circuit worked in sequence twice (LEDs & Relays) but it didn't work in the sequence again (LEDs light & Relays); I mean the problem now is in the sequence.

    I'm not sure, but I think the problem is in the code. I'll try the new way you sent and let you know what happened.

    Many thanks
     
  16. JohnInTX

    Moderator

    Jun 26, 2012
    2,347
    1,029
    OK. That clears things up a bit..
    Your code and the short version I posted both run OK in the sim, over and over. Shadowing the ports will fix it IF the rest of the hardware is properly implemented. Keep in mind that the DONE LED is only turned on once. You should turn it off when restarting the cycle.
    Be sure that you have the power lines to the PIC decoupled (capacitors between Vdd and Vss) and use separate wires directly from the power supply to power the relays (don't share grounds between the ULN2003 and the PIC).
    Let us know how its working from there.
     
    Last edited: Jan 7, 2015
  17. wali78

    Thread Starter New Member

    Dec 29, 2014
    28
    0
    I would like to inform you that this code worked very well and the dishwasher is working now;
    Thank you and many thanks for everyone gave an advice to me, thank you all very a lot.
    the next step is replacing the leds indicators with LCD:)
     
  18. wali78

    Thread Starter New Member

    Dec 29, 2014
    28
    0
    I would like to inform you that this way worked very well (with the help of JohnInTX ) and the dishwasher is working now;
    Thank you and many thanks for everyone gave an advice to me, thank you all a lot.
    the next step is replacing the leds indicators with LCD:)
     
  19. JohnInTX

    Moderator

    Jun 26, 2012
    2,347
    1,029
    JohnP was the first to suggest shadowing but I would have as well as a next step. Lesson here for all readers is to ALWAYS shadow the ports on midrange/baseline PICs.

    What are you going to use for the LCD?
     
  20. wali78

    Thread Starter New Member

    Dec 29, 2014
    28
    0
    I would like to thank you for your help; highly appreciated. I mentioned before that the dishwasher is working; but I want to add 2 buttons as follow:
    1- BUTTON 1 to start some steps of the system and wait until I press BUTTON 2.
    2- BUTTON 2 to start the remaining steps.
    I don't know how to write the button's code in shadowing!

    Please have a look at the code:

    Code ( (Unknown Language)):
    1.  
    2. // Example of shadowing PORTB. An image of the port is maintained in RAM.
    3. // Changes to the port are done by first modifying the image then writing
    4. // the whole byte to the PORT and avoiding r-m-w problems.
    5.  
    6. unsigned char PORTBimage;
    7.  
    8. void main()
    9. {
    10.      TRISB=0b00000000;
    11.      PORTB=0;
    12.      PORTBimage = 0; // must start the same
    13.  
    14.        [B][I][COLOR=#ff0000] BUTTON 1[/COLOR][/I][/B]
    15.  
    16.       //RB1_bit=1;
    17.       PORTBimage.B1 = 1; // set bit in shadow register
    18.       PORTB = PORTBimage;  // write the new pattern to the port
    19.       Delay_ms(32000);
    20.  
    21.       PORTBimage.B1 = 0; // set bit in shadow register
    22.       PORTB = PORTBimage;  // write it to the port
    23.       Delay_ms(2000);
    24.  
    25.       //RB2_bit=1;
    26.       PORTBimage.B2 = 1; // set bit in shadow register
    27.       PORTB = PORTBimage;  // write the new pattern to the port
    28.       Delay_ms(240000);
    29.  
    30.       PORTBimage.B2 = 0; // set bit in shadow register
    31.       PORTB = PORTBimage;  // write it to the port
    32.       Delay_ms(2000);
    33.  
    34.       //RB3_bit=1;
    35.       PORTBimage.B3 = 1; // set bit in shadow register
    36.       PORTB = PORTBimage;  // write the new pattern to the port
    37.       Delay_ms(30000);
    38.  
    39.        PORTBimage.B3 = 0; // set bit in shadow register
    40.       PORTB = PORTBimage;  // write it to the port
    41.       Delay_ms(60000);
    42. //////////////////////////////////////////////////////////////////////////////////////////////////
    43.    
    44.       [COLOR=#ff0000][B][I]BUTTON 2[/I][/B][/COLOR]
    45.  
    46.       //RB1_bit=1;
    47.       PORTBimage.B1 = 1; // set bit in shadow register
    48.       PORTB = PORTBimage;  // write the new pattern to the port
    49.       Delay_ms(32000);
    50.  
    51.       PORTBimage.B1 = 0; // set bit in shadow register
    52.       PORTB = PORTBimage;  // write it to the port
    53.       Delay_ms(2000);
    54.  
    55.       //RB5_bit=1;
    56.       PORTBimage.B5 = 1; // set bit in shadow register
    57.       PORTB = PORTBimage;  // write the new pattern to the port
    58.       Delay_ms(600000);
    59.  
    60.       PORTBimage.B5 = 0; // set bit in shadow register
    61.       PORTB = PORTBimage;  // write it to the port
    62.       Delay_ms(2000);
    63.  
    64.       //RB2_bit=1;
    65.       PORTBimage.B2 = 1; // set bit in shadow register
    66.       PORTB = PORTBimage;  // write the new pattern to the port
    67.       Delay_ms(420000);
    68.  
    69.       PORTBimage.B2 = 0; // set bit in shadow register
    70.       PORTB = PORTBimage;  // write it to the port
    71.       Delay_ms(2000);
    72.  
    73.       //RB3_bit=1;
    74.       PORTBimage.B3 = 1; // set bit in shadow register
    75.       PORTB = PORTBimage;  // write the new pattern to the port
    76.       Delay_ms(30000);
    77.  
    78.       PORTBimage.B3 = 0; // set bit in shadow register
    79.       PORTB = PORTBimage;  // write it to the port
    80.       Delay_ms(2000);
    81.  
    82.       //RB1_bit=1;
    83.       PORTBimage.B1 = 1; // set bit in shadow register
    84.       PORTB = PORTBimage;  // write the new pattern to the port
    85.       Delay_ms(32000);
    86.  
    87.       PORTBimage.B1 = 0; // set bit in shadow register
    88.       PORTB = PORTBimage;  // write it to the port
    89.       Delay_ms(2000);
    90.  
    91.       //RB4_bit=1;
    92.       PORTBimage.B4 = 1; // set bit in shadow register
    93.       PORTB = PORTBimage;  // write the new pattern to the port
    94.       Delay_ms(3000);
    95.  
    96.        PORTBimage.B4 = 0; // set bit in shadow register
    97.       PORTB = PORTBimage;  // write it to the port
    98.       Delay_ms(2000);
    99.  
    100.       //RB5_bit=1;
    101.       PORTBimage.B5 = 1; // set bit in shadow register
    102.       PORTB = PORTBimage;  // write the new pattern to the port
    103.       Delay_ms(600000);
    104.  
    105.       PORTBimage.B5 = 0; // set bit in shadow register
    106.       PORTB = PORTBimage;  // write it to the port
    107.       Delay_ms(2000);
    108.  
    109.       //RB2_bit=1;
    110.       PORTBimage.B2 = 1; // set bit in shadow register
    111.       PORTB = PORTBimage;  // write the new pattern to the port
    112.       Delay_ms(420000);
    113.  
    114.        PORTBimage.B2 = 0; // set bit in shadow register
    115.       PORTB = PORTBimage;  // write it to the port
    116.       Delay_ms(2000);
    117.  
    118.  
    119.  
    120.       //RB5_bit=1;
    121.       PORTBimage.B5 = 1; // set bit in shadow register
    122.       PORTB = PORTBimage;  // write the new pattern to the port
    123.       Delay_ms(300000);
    124.    
    125.       PORTBimage.B5 = 0; // set bit in shadow register
    126.       PORTB = PORTBimage;  // write it to the port
    127.       Delay_ms(2000);
    128.  
    129.       //RB3_bit=1;
    130.       PORTBimage.B3 = 1; // set bit in shadow register
    131.       PORTB = PORTBimage;  // write the new pattern to the port
    132.       Delay_ms(30000);
    133.  
    134.        PORTBimage.B3 = 0; // set bit in shadow register
    135.       PORTB = PORTBimage;  // write it to the port
    136.       Delay_ms(2000);
    137.  
    138.       //RB7_bit=1;
    139.       PORTBimage.B7 = 1;
    140.       PORTB = PORTBimage;
    141.  
    142.     } //for
    143. //main
    144.  
    Moderators note: Please use code tags for pieces of code
     
    Last edited by a moderator: Jan 16, 2015
Loading...