Please help my son! 16F628A timer circuit/program

Thread Starter

Tigthwad

Joined Oct 27, 2009
31
When does LED1 get turned off?

After pressing SW1 and turning on LED2 and waiting for 3 seconds, why would you need to turn on LED2 again when you activate the relay? Is this a typo?
In this case LED1 indicates the timing sequence has started. LED2 indicates power and then is blinked to indicate the timer is running in the 55 second loop. Mostly this is for visual troubleshooting. A Third LED might be utilized to avoid confusion going forward.
 

Thread Starter

Tigthwad

Joined Oct 27, 2009
31
Try this, it is something that your son can understand and maybe improve also ;) The other suggestions are indeed correct. But way over anything what is expected from a 12 year old boy. This may perhaps be cheating. But as I see it. If your son understand this. He has also learned something. Remember this is your sons science fair, not yours ;)
Rich (BB code):
/************************
* Description: LED Test with buttons
* Turn on LED for x seconds
* Pin Assignments:
*   RB0 = Switch 1
*    RB1 = Switch 2
*    RB2 = LED1
*    RB3 = LED2
*    RB4 = Relay connection
 **************************/
#define _XTAL_FREQ 4000000
#include<xc.h>
#define LED_ON      1       // LED is connected cathode to ground
#define LED_OFF     0
#define RELAY_ON    1       //RELAY is connected to ground
#define RELAY_OFF   0       //RELAY not connect to ground
#define BUTTON_ON   0       // Button input is low when button pressed
#define BUTTON_OFF  1       // (this is how a pull-up resistor button works)
#define I_O_OUT     0       // standard TRIS definitions
#define I_O_IN      1       // zero is 0ut, one is 1n
#define SW_A        RB0     // switch A is on PORTB.0
#define SW_B        RB1
#define SW_A_TRIS   TRISB0  // switch B is on PORTB.1
#define SW_B_TRIS   TRISB1
#define LED_A       RB2     // LED A is on PORTB.2
#define LED_B       RB3     // LED B is on PORTB.3
#define RELAY       RB4     // RELAY is connected to ground
#define LED_A_TRIS  TRISB2
#define LED_B_TRIS  TRISB3
#define RELAY TRISB4
__CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & BOREN_OFF & LVP_OFF & CPD_OFF & CP_OFF);
unsigned char i;
unsigned char flag;
void main(void)
{
  CMCON=0x07;
  flag=0;
  SW_A_TRIS  = I_O_IN;    // set up I/O pin directions
  SW_B_TRIS  = I_O_IN;
  LED_A_TRIS = I_O_OUT;
  LED_B_TRIS = I_O_OUT;
  LED_A=LED_ON;
  LED_B=LED_OFF;
OSCF=1;
/*bit 3 OSCF: INTOSC Oscillator Frequency bit
1 = 4 MHz typical
0 = 48 kHz typical
*/
  // now loop forever to sense buttons
  while(1)
  {
      while(SW_A==1);
      LED_B=LED_ON;
      for(i=0;i<40;i++)
        {
          if (SW_B==0)
          {
              LED_B=LED_OFF;
              flag=1;
              break;
          }
          __delay_ms(75);
          LED_B=!LED_B;
         }
       if(flag==0)
       {
          LED_B=LED_ON;
          RELAY=RELAY_ON;
          for(i=0;i<55;i++)
          {
              __delay_ms(1000);
          }
          RELAY=RELAY_OFF;            
       } 
       LED_B=0; 
       flag=0;
  }
}//end main
I will give this a try, thanks!

He does have to understand how to program it, he can't just copy what someone else has done. It will be much easier to explain the parts to him and let him combine for the finished result himself. Knowing the program works will go a long way towards feeling confident he can do it himself.

I appreciate all the help thus far, the stress level over this project has gone way down!
 

takao21203

Joined Apr 28, 2012
3,702
Blinking LEDs and delays are just some very basics. It is true these things have to be mastered and understood properly.

But it is not that interesting as such.

Get some other PICs!

The 16f59 is good since it is easy to use and cheap and has a lot of I/O.

Build a LED matrix and things like that.

Why not try these new 16f14xx USB PICs.

A challenge for a 12 year old would be to make a 16F USB PIC and a 16f59 communicate with each other.

The new trend is PIC32, they also start at only 2 dollar, but are far more powerful. But, they need extra components and configuration is not that easy.

It helps to gain experience on the older simpler PICs at first.

I used the 16f54, 16f57 and 16f59 (which I favour) to research many things such as LED driving, key debouncing, random numer generators. And I don't build just trivial circuits.

Maybe order 25 pcs. 16f59 from Microchip (not that expensive), a few 16F14xx USB PICs, so your son can do whatever experiment and circuits he likes.

16f628 is a very small chip, and only has very few I/O lines.
 

Thread Starter

Tigthwad

Joined Oct 27, 2009
31
Blinking LEDs and delays are just some very basics. It is true these things have to be mastered and understood properly.

But it is not that interesting as such.

Get some other PICs!

The 16f59 is good since it is easy to use and cheap and has a lot of I/O.

Build a LED matrix and things like that.

Why not try these new 16f14xx USB PICs.

A challenge for a 12 year old would be to make a 16F USB PIC and a 16f59 communicate with each other.

The new trend is PIC32, they also start at only 2 dollar, but are far more powerful. But, they need extra components and configuration is not that easy.

It helps to gain experience on the older simpler PICs at first.

I used the 16f54, 16f57 and 16f59 (which I favour) to research many things such as LED driving, key debouncing, random numer generators. And I don't build just trivial circuits.

Maybe order 25 pcs. 16f59 from Microchip (not that expensive), a few 16F14xx USB PICs, so your son can do whatever experiment and circuits he likes.

16f628 is a very small chip, and only has very few I/O lines.
At this point he needs to walk before he can run. I had the 16F628A on hand and they are good enough for this project. If his interest can be captured with this project I can see him moving to other projects...LCD displays etc.

At 12 he is still fairly impressed with lighting an LED. LED matrixing will interest him as well.

Another question has come up...

We are unable to use the __CONFIG() or __delay_ms() commands. Both get underlined in red and the project won't build. I am worried there is an issue with the XC8 setup but don't know where to look. I tried on two computers with the same result however. Any ideas? I can set the config via #pragma so I can get past the older __CONFIG() setting but the __delay_ms() still doesn't work...
 

t06afre

Joined May 11, 2009
5,934
We are unable to use the __CONFIG() or __delay_ms() commands. Both get underlined in red and the project won't build. I am worried there is an issue with the XC8 setup but don't know where to look. I tried on two computers with the same result however. Any ideas? I can set the config via #pragma so I can get past the older __CONFIG() setting but the __delay_ms() still doesn't work...
I did use the XC8 compiler, version 1.00 and MPLABX then testing your code. It compiled just fine. The __delay_ms function is marked red but just ignore that. To be sure I simulated the code a few seconds ago. And all worked well. Just to be sure can you create a new new project in a new folder. Using my code draft.
 

takao21203

Joined Apr 28, 2012
3,702
When I was 13 or 14, I wasn't the brightest with electronics.

For instance I had a 2n3055 suspended in oil for cooling (as linear voltage regulator). I ruined my SEGA master system by wiring up a linear regulator chip, and making a short. And things like that.

Somehow shortly after that I did not put much efforts into it anymore. Only in 2004 I started again, when I bought a PIC microcontroller kit. Since then I have built up a reasonable pile of parts and have constructed 100s of circuits.
 

Thread Starter

Tigthwad

Joined Oct 27, 2009
31
I did use the XC8 compiler, version 1.00 and MPLABX then testing your code. It compiled just fine. The __delay_ms function is marked red but just ignore that. To be sure I simulated the code a few seconds ago. And all worked well. Just to be sure can you create a new new project in a new folder. Using my code draft.

I was able to build it...found a typo that was the true problem.

I haven't run the code in the circuit yet but I have some questions as I try to understand what it is doing

This line:
Rich (BB code):
while(SW_A==1);
I can see it is evaluating that switch A is = to 1 (switch active). It appears that is all it does however...so what is it doing?

In our project we are using a momentary switch to kick off the sequence of that will activate the relay.

The next question is:

Rich (BB code):
      for(i=0;i<40;i++)
        {
          if (SW_B==0)
          {
              LED_B=LED_OFF;
              flag=1;
              break;
          }
          __delay_ms(75);
          LED_B=!LED_B;
         }
This part looks like a short timer that check if Switch B is pressed and if not will flash LED_B at a rate of 13 times a second for a total of 1/2 second?

And in this part:
Rich (BB code):
       if(flag==0)
       {
          LED_B=LED_ON;
          RELAY=RELAY_ON;
          for(i=0;i<55;i++)
          {
              __delay_ms(1000);
              LED_B=!LED_B;
          }
          RELAY=RELAY_OFF;
       }
I added the LED_B on/off sequence. Looks like it will spend 1 second in each state.

How is this delay sequence less power consumptive than what I wrote? It appears to be more accurately using the clock but I haven't tested the actual time vs the programmed time.
 

t06afre

Joined May 11, 2009
5,934
I haven't run the code in the circuit yet but I have some questions as I try to understand what it is doing

This line:
Rich (BB code):
while(SW_A==1);
I can see it is evaluating that switch A is = to 1 (switch active). It appears that is all it does however...so what is it doing?
Look at the PDF in post #20. This is one of (many) correct way(s) to connect a switch to a input. Then the switch is not active. The port will have a high input signal. Then active the port will see a low signal.
Rich (BB code):
while(SW_A==1);
Is a loop what does nothing else than looping as long as the SW_A input is high. It will break out of doing this the moment the switch is active.
The next question is:

Rich (BB code):
      for(i=0;i<40;i++)
        {
          if (SW_B==0)
          {
              LED_B=LED_OFF;
              flag=1;
              break;
          }
          __delay_ms(75);
          LED_B=!LED_B;
         }
This part looks like a short timer that check if Switch B is pressed and if not will flash LED_B at a rate of 13 times a second for a total of 1/2 second?.
This part is the 3 seconds delay you have to cancel. I added a rapid blinking of LED 2 to spice up the project:p. What is do is to execute a 75 msec delay 40 times (3/0.075=40) Between each 75msec it will check if switch B is pressed and also flip LED_B. If SW_B pressed. It will break out the loop, and at the same time setting the flag variable. This will tell us that the for loop was stopped. Outside the the latter loop we check the flag variable. If it is 0 (SW_2 not pressed) we go on with 55sec on time for the relay. Regarding the relay. A PIC port will not be able to drive a relay coil directly. You can let the port control a transistor that in turn control the relay coil
 

t06afre

Joined May 11, 2009
5,934
One more thing. In your program your have this
Rich (BB code):
#define RELAY RB4 // RELAY is connected to ground
#define LED_A_TRIS TRISB2
#define LED_B_TRIS TRISB3
#define RELAY TRISB4
Relay is defined and then redefined. This make RB4 an input pin. Also did a full simulation. The timing error using exact 4MHz is in the msec range. The typical error on the internal oscillator is about 1%. Hence I think using the __delay_ms functions like I did in my code draft and internal oscillator. Will give more than good enough accuracy for this setup
 
Last edited:

thatoneguy

Joined Feb 19, 2009
6,359
Adding:

Rich (BB code):
#pragma config MCLRE = OFF, WDTE = OFF, CP = OFF, LVP = OFF, FOSC = INTOSCIO
Did the trick. I wish I understood what it all meant...I get the Code Protection and Watchdog(kinda) and LVP part but I am not firm on the MCLRE and FOSC parts...especially the FOSC as I know I need that later for the delay routine
MCLRE=OFF -> Memory CLeaR Enable = Disabled, MCLR pin acts as General Purpose I/O Port (GPIO). MCLRE=ON Allows MCLR pin to act as master reset.
WDTE=OFF -> WatchDog Timer Enable, reboots controller if code locks up, requires extra instructions to continually reset WDT (WatchDogTimer)
CP=OFF -> Code Protection (encryption so a user cannot reverse engineer your code), disabled.
LVP=OFF -> Low Voltage Programming Disabled. Only high voltage on MCLR pin puts uC in programming mode, so a low signal on PGC and PGD doesn't put uC into Programming mode at unintended times.
FOSC=INTOSCIO -> Normal Clock Lines (CLKOUT and CLKIN) on uC Can be used as GPIO pins, Internal Oscillator enabled to clock the processor.

Hope that clears things up for you. The \(\small{\mathsf{\overline{MCLR}}}\) (Active Low) MCLR/Reset is active Low, hence the line over it. So disabling the enable disables the reset on that pin, only a power cycle resets the uC, though you get an extra I/O pin from the deal, important on low pin count devices, but one needs to be careful using the pin, see app notes.
 

Thread Starter

Tigthwad

Joined Oct 27, 2009
31
One more thing. In your program your have this
Rich (BB code):
#define RELAY RB4 // RELAY is connected to ground
#define LED_A_TRIS TRISB2
#define LED_B_TRIS TRISB3
#define RELAY TRISB4
Relay is defined and then redefined. This make RB4 an input pin. Also did a full simulation. The timing error using exact 4MHz is in the msec range. The typical error on the internal oscillator is about 1%. Hence I think using the __delay_ms functions like I did in my code draft and internal oscillator. Will give more than good enough accuracy for this setup
Funny thing...that bit of code had a typo and should have been:
Rich (BB code):
#define RELAY RB4 // RELAY is connected to ground
#define LED_A_TRIS TRISB2
#define LED_B_TRIS TRISB3
#define RELAY_TRIS TRISB4
Regarding driving a relay...we did that last night without issue. It was a 5V reed relay we got from Radio Shack. We might need to look into the transistor as well.

How do you do a simulation? I haven't learned this functionality yet and I have to use the actual device (breadboarded at this point) for testing. Knowing how to simulate would be helpful!


For those wondering if my son would catch the bug....he was asking how to drive an LCD display to say something like "I'm finished, how did I do?" at the end. I let him know he needed to get HIS code working first...(plus that gives me time to figure out how to get to that step!)
 

Thread Starter

Tigthwad

Joined Oct 27, 2009
31
MCLRE=OFF -> Memory CLeaR Enable = Disabled, MCLR pin acts as General Purpose I/O Port (GPIO). MCLRE=ON Allows MCLR pin to act as master reset.
WDTE=OFF -> WatchDog Timer Enable, reboots controller if code locks up, requires extra instructions to continually reset WDT (WatchDogTimer)
CP=OFF -> Code Protection (encryption so a user cannot reverse engineer your code), disabled.
LVP=OFF -> Low Voltage Programming Disabled. Only high voltage on MCLR pin puts uC in programming mode, so a low signal on PGC and PGD doesn't put uC into Programming mode at unintended times.
FOSC=INTOSCIO -> Normal Clock Lines (CLKOUT and CLKIN) on uC Can be used as GPIO pins, Internal Oscillator enabled to clock the processor.

Hope that clears things up for you. The \(\small{\mathsf{\overline{MCLR}}}\) (Active Low) MCLR/Reset is active Low, hence the line over it. So disabling the enable disables the reset on that pin, only a power cycle resets the uC, though you get an extra I/O pin from the deal, important on low pin count devices, but one needs to be careful using the pin, see app notes.
Thanks, that helps a lot! the I/O pin count may become important if/when he wants to try LCD output.
 

t06afre

Joined May 11, 2009
5,934
Funny thing...that bit of code had a typo and should have been:
Rich (BB code):
#define RELAY RB4 // RELAY is connected to ground
#define LED_A_TRIS TRISB2
#define LED_B_TRIS TRISB3
#define RELAY_TRIS TRISB4
Regarding driving a relay...we did that last night without issue. It was a 5V reed relay we got from Radio Shack. We might need to look into the transistor as well.

How do you do a simulation? I haven't learned this functionality yet and I have to use the actual device (breadboarded at this point) for testing. Knowing how to simulate would be helpful!
I use a dedicated simulator and also the simulator in MPLAB. I have not jumped on the MPLAX train yet. But take a look here http://microchip.wikidot.com/mplab:_start in the debugging section look for the stop watch function
Regarding the relay if it is the Model: 275-232 relay. It look to me that the coil has resistance equal to 250 ohm. And then it should be OK to not use transistor. The max current from any pin in your chip is 25mA. And the relay will draw 20mA. You can check the coil resistance with a multimeter
 

Thread Starter

Tigthwad

Joined Oct 27, 2009
31
I use a dedicated simulator and also the simulator in MPLAB. I have not jumped on the MPLAX train yet. But take a look here http://microchip.wikidot.com/mplab:_start in the debugging section look for the stop watch function
Regarding the relay if it is the Model: 275-232 relay. It look to me that the coil has resistance equal to 250 ohm. And then it should be OK to not use transistor. The max current from any pin in your chip is 25mA. And the relay will draw 20mA. You can check the coil resistance with a multimeter
I tried the debugger but it requires a debug header and I didn't know what that was or how to make it. I would love to be able to step through the program as I think that is a great learning tool as well.
 

Thread Starter

Tigthwad

Joined Oct 27, 2009
31
Ok, so another question has come up from investigating the use of a transistor to activate the relay.

We were planning to use a 7805 to turn a 9V battery to the 5V the chip uses. All well and good there but the transistor 2n3906 I was looking at has 12v as the norm...will it work with 5v? I assume it is better to use 5v than 9v but obviously both would be available in the circuit.

 

t06afre

Joined May 11, 2009
5,934
I tried the debugger but it requires a debug header and I didn't know what that was or how to make it. I would love to be able to step through the program as I think that is a great learning tool as well.
You can use the MPLABX simulator. I think it is named that. The MPLABX system is still kind of in beta. The documentation is still at the best poor. That is the reason that I still stick with the MPLAB system. It is better with the devil you know:p
The good thing is that XC8 compiler works nice in MPLAB. You will have to build a new MPLAB project. Take you about 10 seconds. But the code will work as is in MPLAB.
 

t06afre

Joined May 11, 2009
5,934
Ok, so another question has come up from investigating the use of a transistor to activate the relay.

We were planning to use a 7805 to turn a 9V battery to the 5V the chip uses. All well and good there but the transistor 2n3906 I was looking at has 12v as the norm...will it work with 5v? I assume it is better to use 5v than 9v but obviously both would be available in the circuit.

Do you have some old 5 to 4.5 volt cell phone charger. That will work nice with this project. Much better than a 9 volt battery, as the drain out very fast. If you have to use battery. I would have used a 3 cell 1.5 volt battery compartment. I am sure Radioshack has something like it. The 16F628 can work with voltages from 2 to 5.5 volt. And 4.5 volt will work fine in this project. And no voltage regulator will be needed
 

thatoneguy

Joined Feb 19, 2009
6,359
Here is a commonly used Relay Driver circuit.

The relay is on when the input is low, as shown by the inputs on left in green. Voltage through relay (R2 simulating coil) is Blue Trace. I just put a square wave for testing purposes to show function. In use, Remove Left Voltage Source and use only MCU_INPUT and connect MCU_GND to 9V_GND.

The diode is not needed with the resistor (say, for an LED in Drain circuit), but if using an inductive load, namely a relay coil, the diode must be in the circuit, preferably a fast Schottky or similar, 1N5819 or equiv. though a standard diode will work as well. R1 is required to fully turn off MOSFET when the uC input goes low or High-Z.

2N7002 is a higher capacity version of the 2N7000 N-MOSFET, either can be used for this purpose. They come in a TO-92 case, same as small signal bipolar transistors, so easy to place.


 

Attachments

Last edited:

Thread Starter

Tigthwad

Joined Oct 27, 2009
31
Do you have some old 5 to 4.5 volt cell phone charger. That will work nice with this project. Much better than a 9 volt battery, as the drain out very fast. If you have to use battery. I would have used a 3 cell 1.5 volt battery compartment. I am sure Radioshack has something like it. The 16F628 can work with voltages from 2 to 5.5 volt. And 4.5 volt will work fine in this project. And no voltage regulator will be needed
Good idea on the 3 cell pack, that is what we will do (knowing we don't need the 2n3902 at this time).

We are using a 5v cell phone charge cord for testing...it does work well...I never throw those away!
 
Top