pic16f877a and mikroc problem

Thread Starter

wali78

Joined Dec 29, 2014
28
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;


}
}
}
 

absf

Joined Dec 29, 2010
1,968
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
 

Thread Starter

wali78

Joined Dec 29, 2014
28
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
}
 

Thread Starter

wali78

Joined Dec 29, 2014
28
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;


}
}
}
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
}
 

JohnInTX

Joined Jun 26, 2012
4,787
below is the code in MikroC, it doesn't work correctly.
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:
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;

      } //for
} //main
Good luck!
 
Last edited:

Thread Starter

wali78

Joined Dec 29, 2014
28
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:
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;

      } //for
} //main
Good luck!
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.
 

John P

Joined Oct 14, 2008
2,026
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:
unsigned char portb_shadow;

bit_set(portb_shadow, 0);
portb = portb_shadow;
 

ErnieM

Joined Apr 24, 2011
8,377
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.
What do you mean you "tried it" and "it works" without connecting what where? What is the mystery "device"?

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.
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.

anyhow, I'm very sure of the schematic, where the system works before.
If it worked you wouldn't be asking for help.

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

Thread Starter

wali78

Joined Dec 29, 2014
28
What do you mean you "tried it" and "it works" without connecting what where? What is the mystery "device"?
I meant that I did the PCB and powered it up and it works but after I connected it to device (DISHWASHER) it doesn't work in the sequence I wrote in the code.

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.
I did it, but I don't see any files in the folder. (pdf, jpg etc...)

If it worked you wouldn't be asking for help.
yes, but after I connected it to device (DISHWASHER) it doesn't work in the sequence I wrote in the code.

We can't help until we know what you are doing.
DISHWASHER timer
 

Thread Starter

wali78

Joined Dec 29, 2014
28
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:
unsigned char portb_shadow;

bit_set(portb_shadow, 0);
portb = portb_shadow;
I'll try this, thank you.
 

Thread Starter

wali78

Joined Dec 29, 2014
28
I'll try this, thank you.
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.
 

Attachments

JohnInTX

Joined Jun 26, 2012
4,787
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:
// Example of shadowing PORTB. An image of the port is maintained in RAM.
// Changes to the port are done by first modifying the image then writing
// the whole byte to the PORT and avoiding r-m-w problems.

unsigned char PORTBimage;

void main()
{
     TRISB=0b00000000;
     PORTB=0;
     PORTBimage = 0; // must start the same
     for(;;){

      //RB1_bit=1;
      PORTBimage.B1 = 1; // set bit in shadow register
      PORTB = PORTBimage;  // write it to the port
      Delay_ms(5000);
  
      //RB1_bit=0;
      PORTBimage.B1 = 0; // set bit in shadow register
      PORTB = PORTBimage;  // write the new pattern to the port
      Delay_ms(2000);
  
      //RB7_bit=1;
      PORTBimage.B7 = 1;
      PORTB = PORTBimage;

    } //for
} //main
Good luck!
 
Last edited:

Thread Starter

wali78

Joined Dec 29, 2014
28
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
 

JohnInTX

Joined Jun 26, 2012
4,787
I mean the problem now is in the sequence.
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:

Thread Starter

wali78

Joined Dec 29, 2014
28
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.
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:)
 

Thread Starter

wali78

Joined Dec 29, 2014
28
I'll try this, thank you.
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:)
 

JohnInTX

Joined Jun 26, 2012
4,787
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:)
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?
 

Thread Starter

wali78

Joined Dec 29, 2014
28
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?
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:
// Example of shadowing PORTB. An image of the port is maintained in RAM.
// Changes to the port are done by first modifying the image then writing
// the whole byte to the PORT and avoiding r-m-w problems.

unsigned char PORTBimage;

void main()
{
     TRISB=0b00000000;
     PORTB=0;
     PORTBimage = 0; // must start the same

       [B][I][COLOR=#ff0000] BUTTON 1[/COLOR][/I][/B]

      //RB1_bit=1;
      PORTBimage.B1 = 1; // set bit in shadow register
      PORTB = PORTBimage;  // write the new pattern to the port
      Delay_ms(32000);

      PORTBimage.B1 = 0; // set bit in shadow register
      PORTB = PORTBimage;  // write it to the port
      Delay_ms(2000);

      //RB2_bit=1;
      PORTBimage.B2 = 1; // set bit in shadow register
      PORTB = PORTBimage;  // write the new pattern to the port
      Delay_ms(240000);

      PORTBimage.B2 = 0; // set bit in shadow register
      PORTB = PORTBimage;  // write it to the port
      Delay_ms(2000);

      //RB3_bit=1;
      PORTBimage.B3 = 1; // set bit in shadow register
      PORTB = PORTBimage;  // write the new pattern to the port
      Delay_ms(30000);

       PORTBimage.B3 = 0; // set bit in shadow register
      PORTB = PORTBimage;  // write it to the port
      Delay_ms(60000);
//////////////////////////////////////////////////////////////////////////////////////////////////
   
      [COLOR=#ff0000][B][I]BUTTON 2[/I][/B][/COLOR]

      //RB1_bit=1;
      PORTBimage.B1 = 1; // set bit in shadow register
      PORTB = PORTBimage;  // write the new pattern to the port
      Delay_ms(32000);

      PORTBimage.B1 = 0; // set bit in shadow register
      PORTB = PORTBimage;  // write it to the port
      Delay_ms(2000);

      //RB5_bit=1;
      PORTBimage.B5 = 1; // set bit in shadow register
      PORTB = PORTBimage;  // write the new pattern to the port
      Delay_ms(600000);

      PORTBimage.B5 = 0; // set bit in shadow register
      PORTB = PORTBimage;  // write it to the port
      Delay_ms(2000);

      //RB2_bit=1;
      PORTBimage.B2 = 1; // set bit in shadow register
      PORTB = PORTBimage;  // write the new pattern to the port
      Delay_ms(420000);

      PORTBimage.B2 = 0; // set bit in shadow register
      PORTB = PORTBimage;  // write it to the port
      Delay_ms(2000);

      //RB3_bit=1;
      PORTBimage.B3 = 1; // set bit in shadow register
      PORTB = PORTBimage;  // write the new pattern to the port
      Delay_ms(30000);

      PORTBimage.B3 = 0; // set bit in shadow register
      PORTB = PORTBimage;  // write it to the port
      Delay_ms(2000);

      //RB1_bit=1;
      PORTBimage.B1 = 1; // set bit in shadow register
      PORTB = PORTBimage;  // write the new pattern to the port
      Delay_ms(32000);

      PORTBimage.B1 = 0; // set bit in shadow register
      PORTB = PORTBimage;  // write it to the port
      Delay_ms(2000);

      //RB4_bit=1;
      PORTBimage.B4 = 1; // set bit in shadow register
      PORTB = PORTBimage;  // write the new pattern to the port
      Delay_ms(3000);

       PORTBimage.B4 = 0; // set bit in shadow register
      PORTB = PORTBimage;  // write it to the port
      Delay_ms(2000);

      //RB5_bit=1;
      PORTBimage.B5 = 1; // set bit in shadow register
      PORTB = PORTBimage;  // write the new pattern to the port
      Delay_ms(600000);

      PORTBimage.B5 = 0; // set bit in shadow register
      PORTB = PORTBimage;  // write it to the port
      Delay_ms(2000);

      //RB2_bit=1;
      PORTBimage.B2 = 1; // set bit in shadow register
      PORTB = PORTBimage;  // write the new pattern to the port
      Delay_ms(420000);

       PORTBimage.B2 = 0; // set bit in shadow register
      PORTB = PORTBimage;  // write it to the port
      Delay_ms(2000);



      //RB5_bit=1;
      PORTBimage.B5 = 1; // set bit in shadow register
      PORTB = PORTBimage;  // write the new pattern to the port
      Delay_ms(300000);
   
      PORTBimage.B5 = 0; // set bit in shadow register
      PORTB = PORTBimage;  // write it to the port
      Delay_ms(2000);

      //RB3_bit=1;
      PORTBimage.B3 = 1; // set bit in shadow register
      PORTB = PORTBimage;  // write the new pattern to the port
      Delay_ms(30000);

       PORTBimage.B3 = 0; // set bit in shadow register
      PORTB = PORTBimage;  // write it to the port
      Delay_ms(2000);

      //RB7_bit=1;
      PORTBimage.B7 = 1;
      PORTB = PORTBimage;

    } //for
//main
Moderators note: Please use code tags for pieces of code
 
Last edited by a moderator:
Top