Maker Pro
Maker Pro

Microcontroller controlled by pushbutton for LED flashlight

The simulator is usually the way to go on the low-pin-count chips, but there is also a hardware solution. You can get a "debug header" which contains a special chip with extra pins for in-circuit real-time debugging. If you are using DIPs, you can plug these headers right into a DIP socket placed where the chip would go.

The chips with more pins (all 18 pin ones and any with 28 pins or more) have the in-circuit debug capability built in using the same two pins as the programmer.

Bob
 

hevans1944

Hop - AC8NS
Last night I ordered ten more PIC10F206 and ten PIC10LF320, both in PDIP packages, from Digi-Key via Priority US Mail. They should arrive here next Monday. In the meantime, I discovered the software simulator for the PIC10F206 in MPLAB X and took it out for a spin. Another learning curve to climb, but this should help. I will hold off mounting my two remaining '206 chips and play with the PDIP versions next week... at least until Hamvention® which begins next Friday. I have volunteered to help administer amateur radio license exams all day on Friday and will try to visit the exhibits on Saturday and Sunday if it isn't too hot inside. At the very least I can use the walking around exercise to visit the flea market outside. Maybe there will some vacuum variable capacitors for sale...

Hop
 

hevans1944

Hop - AC8NS
@BobK: I was aware of the in-circuit debug limitations (this baseline series doesn't have enough memory to support a debug executive) of the PIC10F200/2/4/6 series, but I am not ready to invest more money for a header board that will emulate this series and have limited usefulness for more sophisticated PIC products. The AC162059, for example, does not work with the PIC10LF320/322 series that Adam has chosen to use. That series requires the $50.00 AC244045 header for debug capability. Both headers will also need a $16.95 AC164110 RJ-11 to ICSP Adapter to connect to the PICkit 3.

The only reason I ordered PDIP versions of both PICs is to simplify solderless breadboard development and test. These came in today via USPS Priority Mail from Digi-Key, but tomorrow being Mother's Day, I probably won't be able to try them out until Monday.

The final "product" for @TenderTendon will be the SOT-23 version. Not to put down Adam, who is doing better job at programming than I am, but I would like to see if I can get the original PIC10F200 to work with acceptably low current and a one to ten microfarad capacitor. That isn't too likely as the PIC10LF320 uses an order of magnitude less current, plus is "easier" to write programs to. I still have two PIC10F206 chips left that I haven't soldered to an 8-pin DIP carrier, plus the original PIC10F200 that Jeff soldered to his prototype board, and would like to continue working with those components.

The PIC10LF320 has a maximum Vdd of 3.2 V, so I need to go back to using a pair of AA-cells in series to power it, if I ever get a program that works; mine or Adam's makes no difference. However this unfolds, Adam has a nice PCB layout that Jeff can mill a working flashlight-sized board from. It does require some more hand-work than a manufactured board because of the vias, but as soon as Jeff has a working board he can have "real" ones made with plated-through vias, back-filled with solder to carry his five ampere LED current.

I don't mind not having in-circuit debugging or in-circuit emulation capability for these baseline processors. Back in the day, I shunned the Intel ICE product and simply used I/O ports and program break-points for troubleshooting, re-programming EPROMs for the target CPU as "bugs" and errors in logic were discovered and eliminated. A real PITA to have to have a stack of erased EPROMs on hand (and more cooking in the UV bulk eraser), but the Flash memory in these PICs makes that a thing of the past. So, for now I will use the MPLAB X software emulator, and download code to the target PIC only when I feel it is necessary to run on real hardware to test timing and current burden.

If I do get bit by the PIC bug and move on to more powerful PICs and <gasp!> high-level languages, perhaps I will purchase the $500 MPLAB REAL ICE In-Circuit Emulator and maybe hire a software weenie to design application software... all that is assuming I can find a real customer to carry the overhead.:D

Hop
 
I agree that hardware debug is rarely needed, and it presents a lot of problems of it's own, such as stopping at certain points in a program can cause hardware smoke!

Bob
 

hevans1944

Hop - AC8NS
The worst problem I found was the problematic timing with ICE versus the real deal. But as you said, stopping with a high-current load enabled does indeed release the "magic smoke" unless the hardware is specifically designed for 100% duty cycle under full load conditions. We didn't do any PWM back in the 1980s, but there were often solenoids that would overheat if left on too long. Every project is different and requires analysis and "what if" conjectures to avoid pitfalls, but experience is the best teacher. Like, "Well, I'll never do THAT again!"

So it's Monday and I am off to play with the new PDIP toys and to see if I can make headway with the software emulator. This is beginning to feel like fun again.

Hop
 

hevans1944

Hop - AC8NS
I thought I would bump this thread to let everyone know where I am with programming the PIC10F206. I think I mentioned in another thread that I finally realized that I had to disable the comparator to use its two input pins for digital I/O. So I now have a simple program that reads a push-button switch and lights (or not) an LED if the switch is pressed (or not).

To protect the breadboard circuitry from accidental short-circuits, I currently have a 390 Ω 1/4 watt resistor in series with the output of a 7805 three-terminal voltage regulator, powered with a Radio Shack AC Adapter (AD-452) providing 9 VDC at up to 400 mA. No more D-cell batteries! It is bypassed on the prototyping board with a non-polarized 0.1 μF capacitor This resistor will later be increased to 330 Ω when it is mounted across the LED controller in Jeff's flashlights to provide a current path to re-charge an energy storage capacitor which will power the PIC when the flashlight LED is on. Well, that's been the plan all along, but I don't know yet if I can make it work with this PIC.

The PIC is drawing 0.58 mA at 4.98 VDC, doing nothing much except executing a loop testing the switch state. The switch has a 10 kΩ pull-up resistor, but my next iteration will be to enable the internal weak pull-ups and see how that works. This is clearly too much current to power the PIC for 100 msec with any reasonably sized energy storage capacitor. Moreover, there is only about 12 mA available through the 330 Ω resistor from a 4 V battery to recharge the capacitor in one millisecond. Do the math: dQ/dt = I = C dV/dt = 0.012 A. So, if the charge is allowed to drop from, say, 4 V to 2 V (minimum needed to maintain PIC RAM) then dV/dt rate to re-charge is 2 V/msec = 2000 V/sec and C = 0.012 / 2000 = 6 μF.

It would of course be better if the voltage didn't drop so much over the 100 msec the capacitor is NOT being re-charged. But, if we did use a 6 μF capacitor, and re-charged it to 4 V every 100 msec, then the current during discharge could be C dv/dt = 6 μF x 20 V/sec = 120 μA. IMO, that's too much current, and requires too large a capacitor. Getting the average current down to 20 μA (a factor of six smaller) would allow the energy storage capacitor to be only 1 μF. To get the average current that low, the PIC must spend almost all of its time in sleep mode, processing "stuff" very quickly and returning to sleep during the one millisecond it has available to "do things".

Pressing the switch on my breadboard lights the LED, and current to the PIC increases from about 0.58 mA to 2 mA. There is a red LED connected between Vdd and the PIC output port through a 3300 Ω 1/8 watt carbon-film resistor. The LED has 3.17 VDC at its cathode when illuminated and 4.98 VDC at its anode. The PIC output port switches between 4.98 VDC, when it is set, and 0.03 VDC, when it is cleared. So, the current-limiting resistor has about 3.14 VDC across it when the port output is low and the LED is illuminated. This works out to 3.14 / 3300 = 0.95 mA, which when added to the 0.58 mA drawn when the LED is off, adds up to only 1.53 mA. However, pressing the switch grounds the 10 kΩ pull-up resistor, adding another 0.5 mA to the total draw of 2.0 mA. I guess Ohm's Law still works.

So the next baby-steps involve learning how to put this puppy to sleep and wake it up to do something useful. There is a Microchip application note that sort of explains how to do this, but it is missing the code examples referenced in the text, so I will have to figure that out myself... which is the whole point of this exercise. I think I will use the input Change-On-Port Reset condition to wake up the PIC. Pressing the push-button switch will light the LED and put the PIC to sleep. Releasing the push-button switch will extinguish the LED... and put the PIC to sleep. So, depending on how often I press and release the button, most of the time the PIC will be asleep and I can measure how much current that uses. If the LED follows my button pushes, I will know my code is working.

Hop
 

Attachments

  • TB082 Understanding Reset Events On The PIC10F20X 91082A.pdf
    104.3 KB · Views: 124

hevans1944

Hop - AC8NS
Today was interesting. I converted my simple "button-push to light an LED" program to put the PIC10F206 to sleep between presses and releases. Took all day to figure that out, and I would still be struggling with it were it not for a program fragment and an explanation I found on the web here. It turns out you need to insert a MOVFW GPIO instruction immediately before the SLEEP instruction. This read of the I/O pins apparently clears the awaken-on-pin-change bit in the STATUS word. Below is my code that uses awaken-on-pin-change to sense the state of a push-button switch and control an LED accordingly. Note the LED is connected between Vcc and GP0, configured as an output. So GP0=0 turns the LED on.

I have a sensitive digital current meter connected in series with Vcc to measure the PIC current. In the quiescent state (sleeping) the PIC draws 0.01 μA, which is at the limit of sensitivity for my BK Precision 2890A multimeter. When I press and hold the button, the PIC wakes up momentarily to set GP0=0 and light the LED. I can see this happening because there is a short string of 1 MHz clock pulses on GP2 that occur and then vanish each time I press or release the push-button switch.
Code:
;///////////////////////////////////////////////////////////////////////////////
;/                     Program to test PIC10F206 I/O Ports                     /
;/                                                                             /
;/ This code is being developed and tested on a PIC10F206 but will be ported to/
;/ the PIC10F200. So, none of the extra features of the PIC10F206 are used.    /                     
;/                                                                             /
;/ PIC10F200 PIC10F206 Pin Definitions for Flashlight Project. The pinouts are /
;/ subject to change, depending on actual PCB layout considerations.           /                                                                                                 /
;/ PIN #    Name                Function                                       /
;/   1      GP0/ICSPDAT         OUTPUT: LED or MOSFET gate input               /
;/   2      Vss                 Power Supply Common                            /
;/   3      GP1/ICSPCLK         INPUT: N.O Push button switch, internal pull-up/
;/   4      GP2/TOCKI/FOSC4     OUTPUT: FOSC/4 oscillator signal               /
;/   5      Vdd                 Power Supply +2.5 to +5.5 VDC                  /
;/   6      GP3/MCLR/Vpp        INPUT: Active-low MCLR, internal pull-up       /
;/                                                                             /
;///////////////////////////////////////////////////////////////////////////////

    #include p10f206.inc

    __CONFIG _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC

    CBLOCK  0x10                ;RAM (register memory) locations start here
            osc_cal_store       ;a place to store oscillator calibration byte
            temp11              ;reserve some variable storage in case it is
            temp12              ;it is needed later... this is all the storage
            temp13              ;available in common to BOTH the 10F200 and
            temp14              ;the 10F206, so it must be used wisely.
            temp15
            temp16
            temp17
            temp18
     endc

osc_cal     EQU 0x18            ;Previously read value, before programming PIC

;///////////////////////////////////////////////////////////////////////////////
;/                                                                             /
;/ PIC RESET                                                                   /
;/                                                                             /
;/ When the PIC is RESET the Program Counter (PCL) is loaded with 0xff or 0x1ff/
;/ to execute code at the highest location in program memory. This should be   /
;/ "MOVLW xx" where xx is the oscillator calibration byte. The program then    /
;/ rolls over to address 0x00 where the program may then copy WREG contents    /
;/ (loaded by MOVLW xx insruction) into the OSCCAL register.                                                   /
;/                                                                             /
;///////////////////////////////////////////////////////////////////////////////

  ;Using the MPLAB X IDE, you MUST manually read the factory-set value from 0x1ff
  ;in program memory and EQUate it to "osc_cal" before programming the PIC,
  ;then move the EQU value above into WREG. This is not needed if the "MOVLW xx"
  ;instruction in high program memory, containing valid callibration data, was
  ;executed upon PIC start-up reset, but the PICkit 3 erases that location before
  ;programming the PIC!

           org     0x0         ;reset vectors to 0x1ff and rolls over to here


;/INSERT MORE CODE HERE LATER TO TEST FOR OTHER CAUSES OF RESET SUCH AS WDT
                 
           iorlw   b'00000001' ;set FOSC4 bit in OSCCAL to output FOSC/4 on GP2
           movwf   OSCCAL      ;move the callibration bits from WREG into OSCCAL
     
           movlw   b'00000111'
                                ;bit 7=0 enable wake-up on GPIO pin change
                                ;bit 6=0 enable weak pull-ups
                                ;bit 5=0 disable TOCKI input function
                                ;bit 4=0 increment Timer0 on low-tohigh transition on TOCKI pin
                                ;bit 3=0 assign pre-scaler to TIMER0
                                ;bit 2=1 set pre-scaler 1:256 rate (longest timeout)
                                ;bit 1=1 set pre-scaler 1:256 rate
                                ;bit 0-1 set pre-scaler 1:356 rate
           OPTION
           movlw    b'11110111' ;0xf7
           movwf    CMCON0     ;turn off analog comparator
           clrwdt              ;reset watchdog timer

;///////////////////////////////////////////////////////////////////////////////
;/                                                                             /
;/         Now that everything is initialized, begin the main program loop     /
;/                                                                             /
;///////////////////////////////////////////////////////////////////////////////

            clrf    GPIO        ;pre-condition output latches to zero
            movlw   b'00001010' ;GP1, GP3 as input; GP0, GP2 as output
            tris    GPIO

test_state:

           btfss   GPIO, GP1           ;GOTO led_on if GP1=0 switch is pressed
           goto    led_on
           bsf     GPIO, GP0        ;turn off LED (GP0=1) if switch not pressed
           movfw   GPIO
           sleep
      
led_on:

           bcf     GPIO, GP0           ;turn on LED GP0=0 if switch pressed
           movfw   GPIO        ;read ports before sleep
           sleep
           org     0x1ff
           movlw   0x18

         end
Please note this is a "work in progress" not a finished product yet. However, putting the PIC to sleep and then awakening it with a button push is encouraging (at least to me!). I am concerned that even with the LED out of the circuit (it eventually gets replaced with the gate of power MOSFET), the PIC draws 222 μA from the "weak" pull-up resistor when the switch is closed. That is unacceptable for the flashlight project.

Perhaps I can devise a work-around that doesn't require an active "weak" pull-up for the switch all the time.

Next goal: enable the WDT and see what kind of delays between "sleeps" I can get!

Hop
 

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
Might it be better to only turn on the weak pull up just before reading the pin?

Leave it high impedance the rest of the time, unless asleep.
 

hevans1944

Hop - AC8NS
Might it be better to only turn on the weak pull up just before reading the pin?

Leave it high impedance the rest of the time, unless asleep.
Exactly my thought, too. It won't be easy to code this because the switch performs multiple functions and I must periodically check its state to determine how to control the MOSFET. Overall, if the flashlight is off, I can use the awaken-on-pin-change to turn it on for the first 100 milliseconds, enabling the WDT to time this and immediately going back to sleep. Therefore, when the flashlight is off, the PIC, although fully powered, is asleep consuming almost no current... just the way you want any flashlight to behave, ideally zero power consumption when off. Note: the weak pull-ups draw no current when the flashlight is off and the switch is not pressed.

It is when the flashlight is on that the "fun" begins! It, first of all, needs to be turned off every one hundred milliseconds to allow the energy storage capacitor to re-charge. How long to allow for re-charge is TBD right now, but initially @KrisBlueNZ thought a one millisecond charge every hundred milliseconds would be sufficient, and @TenderTendon (Jeff) was pretty sure that a one millisecond "blink" would not be visually perceptible to the user because of persistence of vision effect. I still don't know what effect a one millisecond interruption will have on the LED controller at the other end of the flashlight. The controller is "programmed" by the user pushing and releasing the switch multiple times (to turn on the MOSFET and LED controller) in a specific pattern, similar to the way you would do to send flashing light "Morse Code" with an ordinary flashlight. I am thinking that a half-second on with a half-second off (or longer) sequence might be acceptable to the LED controller, but who knows what it will "think" if those longish pulses are interrupted for one millisecond every one hundred milliseconds?

Since making those flashlights is a business for Jeff, I asked him to hold off on sending me an LED controller to "play" with until I felt comfortable programming the PIC. I never imagined it would take more than two months to get to where I am today, so he's probably given up on me by now. Plus, if @Arouse1973 (Adam) has managed to get his PIC programmed with sufficiently low current draw during the sleep intervals to allow the energy storage capacitor to re-charge, it is a moot point.

Well, it's not moot to me. I need to learn how this "sleep" technology actually works to make real-world devices, not just fancy flashlights. Actually, I stumbled across sleep technology many years ago when Texas Instruments launched their MSP430 series of low-power microprocessors. I even have a few USB modules (acquired as free samples) with MSP430 processors and other things on them that I could try to program. But I haven't followed up on that yet. The development chain for TI products is significantly more expensive than what Microchip requires... at least it was the last time I looked. YMMV.

Whether a one millisecond re-charge every one hundred milliseconds is sufficient or not is determined by how much current the PIC consumes when it is "awake," presumably doing useful things, versus the current consumed while it is asleep. At one microsecond per instruction cycle, the PIC can execute a thousand instructions in one millisecond (one thousand microseconds) if we ignore that some instructions (like program branches, calls, and returns) take two cycles. So, during that millisecond, I need to re-enable the pull-ups, allow the switch stray capacitance to charge up, read the switch state and store it in RAM for later processing, determine that sufficient time has elapsed to re-charge the energy storage capacitor, decide whether the flashlight is still on for the next one hundred milliseconds and then go back to sleep, awaiting either another WDT interrupt or (if the flashlight is now off with weak pull-ups enabled) another switch transition to the on state has been made.

I am still not clear in my head how the logic of this will play out. I do know I cannot be reading that switch all the time in order to make decisions on whether the flashlight LED is on or not. Perhaps storing the state after a switch transition from off to on, and then looking at it again on the next WDT timeout will be sufficient. That means the user cannot "flash" the flashlight on and off more often than once every hundred milliseconds, but that could be acceptable. The WDT operates asynchronously (and not very accurately) with the PIC clock oscillator, which is turned off during sleep, to time those one hundred millisecond re-charge intervals. The WDT time interval is also very coarse, but that probably isn't important for this Human-Machine Interface (HMI) application. Plus or minus a few milliseconds error in timing the off interruptions is not going to be important. Presumably there will be sufficient current to run the PIC after it wakes up to allow for more precise timing during the re-charge interval, although I do not intend to string out a thousand NOPs to get a one millisecond time interval. What I need to discover next is the current burden the WDT places on the PIC. This will probably be the main source of discharge current for the energy storage capacitor while the PIC is asleep.

Hop
 
Might it be better to only turn on the weak pull up just before reading the pin?

Leave it high impedance the rest of the time, unless asleep.

Some pics allow the port to be in a disconnect mode but not sure about this PIC.

If not I think this could actually make things worse, the pin could float and be in an indeterminate state drawing more current. It is better to either make it an A/D if possible or an output low, so if the switch was pressed you don't current limit the port pin.
Adam.
 

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
If not I think this could actually make things worse

Yeah, that could be an issue, but the input capacitance actually works for you here. The disconnected input will tend to remain in the last state it was for some time. You see this happening with a mosfet that will remain on (or off) if you disconnect the gate.

In this case the charge on the gate capacitance will be topped up periodically when the microcontroller turns on the weak pull up before checking the input state. In some respects it's a lot like DRAM (except the capacitance of the input is several orders of magnitude greater than that of a DRAM cell, if I remember correctly)
 
Yeah, that could be an issue, but the input capacitance actually works for you here. The disconnected input will tend to remain in the last state it was for some time. You see this happening with a mosfet that will remain on (or off) if you disconnect the gate.

In this case the charge on the gate capacitance will be topped up periodically when the microcontroller turns on the weak pull up before checking the input state. In some respects it's a lot like DRAM (except the capacitance of the input is several orders of magnitude greater than that of a DRAM cell, if I remember correctly)

I agree to some respect but what's the quality of the capacitor? also I have experienced PCB contamination that you can't even see put pay to this. I like the idea but personally it's a no no from me. FWIW
Thanks
Adam
 

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
The quality of the capacitor is very good. The issue is leakage through the protection network.

What you are trading off is the cost of the current through the weak pull up vs the current through the input gate of the input is biased at some point where both of the complimentary mosfets are partially on.

Another solution is to make the pin an output and force it low when you're not reading from it. This would have no impact on current consumption.

The routine might go:

Wake up.
Turn off LED.
Change switch pin to input with weak pull up.
Read switch status.
Change switch pin to low output.
(Switch logic)
(Wait for charge completion)
Turn on LED if required.
Go back to sleep.
Repeat.

Note that you need a short pause after setting the weak pull up to ensure it has time to pull the input high if the switch is open.

The issue for Bob is to determine the most power efficient way to sleep. The watchdog timer adds to the power required but I suspect it's lower than running a delay loop. :)
 

hevans1944

Hop - AC8NS
Some pics allow the port to be in a disconnect mode but not sure about this PIC.

If not I think this could actually make things worse, the pin could float and be in an indeterminate state drawing more current. It is better to either make it an A/D if possible or an output low, so if the switch was pressed you don't current limit the port pin.
Adam.
AFAIK, the GPIO pins on the PIC10F20x chips are either inputs, that are isolated (tri-stated) from the GPIO register when the TRIS instruction writes a "1" to that bit, or they are outputs that are in a low-impedance state, whether sourcing current as logical "1" or sinking current as logical "0". So, if a GPIO pin is going to be used as an input, it should either be pulled up with the internal "weak" pull-ups or connected externally to an appropriate impedance to either pull it up or pull it down. In any case, as you noted, it should not just be left to hang in the breeze. You could use a high-value external pull-down to establish logic "0" with a normally-open switch connected to Vcc to assert a logic "1" level when it is pressed, or use a high-value external pull-up to establish logic "1" with a normally-open switch connected to ground (Vss) Either way, pull up or pull down, current increases when the switch is pressed.

Suppose you choose to pull down the input to logic "0" with a passive resistor, and allow the switch actuation to apply Vcc to assert a logic "1". If you derive Vcc for the switch from an output port set to logic "1" you can "disconnect the switch" just by changing the output port to logic "0". Pressing the switch will have no effect on the input or the current drawn by the PIC.

The same principle applies if the switch is connected between the input and ground (Vss), except now the pull-up resistor is connected to an output port. If the output port is "1" the pull-up behaves normally, pulling the input port to logic "1" until the switch is actuated to drive the input to logic "0". If the output port is "0" the input may be "pulled down" to logic "0" (depending on the value of the pull-up resistor) but it certainly isn't floating. In either case, you ignore the input when the output port is at logic "0" and no increase in current occurs when the switch is actuated.

For Jeff's flashlight, the push-button switch input to the PIC has to be pulled up externally though a resistor connected to an unused output port. Fortunately there is one available, GP2. Your PCB circuit board would have to be modified to include a 10 kΩ resistor chip and the traces to connect it between GP2 and GP1.

The problem is the user can press the switch at any time. If this occurs while the flashlight is on and the PIC is asleep, current draw skyrockets if the pull-up is connected to Vcc. Other than the solution offered above, I also contemplated using one of the pins of the comparator in the PIC10F206 as a high-impedance switch input, maybe with an external resistor high enough in value to limit the current burden when the switch is pressed to a micro-ampere or so. But even if that worked, I am reluctant to do so because it would mean the PIC10F200 would have to be replaced with a PIC10F206. I am stubborn enough to want to see if I can do this with the PIC10F200.

Adam, you have already upgraded to a saner configuration, the PIC10F320, and back in Dayton I have ten of the low-power versions, the PIC10LF320, to play with. I like that version because you can dial down the clock oscillator in software to lower current requirements, albeit sacrificing execution speed. Plus, it has a 4-channel, 10-bit A/D converter, not applicable to the flashlight project, but certainly nice to have for other projects requiring low-resolution analog signal processing. The only downside I see right now is the maximum Vcc is 4.0 V so I will have to be more careful with the power supply, lest I let out the magic smoke. Not a problem with Jeff's flashlight of course because his battery only produces 4.0 volts.

Since I have the prototype breadboard up and running, I might just try an external pull-up for the switch driven from GP2. I hate giving up the FOSC/4 "heart-beat" signal on GP2 that I can see on the oscilloscope to re-assure me the PIC is running. But now that I have sleep working, that mostly goes away... just a few dozen clock pulses appear when I press or release the switch. So I guess I can do without it. More on that later.

Below is a picture of the prototyping breadboard, to the left of the BK multimeter, with me pressing the switch to light the LED and showing the current, 1121.5 μA, drawn by the PIC, the LED, and the "weak" pull-up resistor. The PIC was actually in "sleep" mode when this picture was taken. The breadboard above the multimeter is used to hold a three-terminal 7805 voltage regulator in the top right corner; a "power on" LED in the lower right; three PIC10F206 chips in the SOT-23 package, soldered to DIP headers; and a PIC10F206 in a PDIP package. The breadboard is just a convenient "place holder" for the chips, all of which I thought were "DOA" a few weeks ago... until I finally figured out I had to turn the comparator off to use the I/O ports assigned by default to the comparator inputs. One of the SOT-23 chips may actually be dead as I distinctly remember smoke coming up from the breadboard on the left when I was using this in Dayton last April, rather than here in Virginia Beach.

upload_2015-6-19_11-32-31.jpeg

Hop
 
Looks good Hop, I admire your determination. If I had to start from scratch like you (not that I know that much) I would have given up I think and gone back to learning quantum electro dynamics, which I find easier. :)
Adam
 

hevans1944

Hop - AC8NS
Well, it just keeps on getting better... I re-discovered recently that, whenever the PIC awakes from sleep, it sets a bunch of bits in various registers to logic "1" state. Included in the list is the 4-bit TRIS register associated with the I/O ports, and the OPTION register and CMCON0 register associated with the comparator on the 10F206. The I/O port latches are not affected, but the effect of setting the TRIS bits to all ones is to tri-state all the ports, which produces "glitches" on those ports that are used as outputs. I didn't notice this until I started playing around with sleep mode and awakening from sleep with both WDT timeout and wake-up-on-change port transitions. The code I posted in reply #328 works just fine to awaken the PIC from sleep whenever the push-button state changes, but it doesn't have the WDT enabled. After enabling the WDT timer, I needed a persistent way to determine why the PIC woke up and branch accordingly. It was somewhere in this learning phase where I discovered the side effects of the TRIS register resetting all the outputs to tri-state inputs. Long story shortened: (1) You have to skip around the Power On Reset initialization by inspecting bits in the STATUS register first, and (2) You cannot avoid "glitches" in the ports used as outputs upon awakening from sleep until your code gets around to making the TRIS register "right" again. Learn to live with it.
 

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
I agree, the wakeup stuff is a tricky area. I've not done a lot in this area, but I did read something which detailed someone's adventures in this area. From memory I think it was "The evil genius' guide to microcontrollers" or something like that.
 

hevans1944

Hop - AC8NS
Most of my problems had to do with initializing memory variables just once instead of after every reset occurred. I finally got a clue on this when I belatedly realized everything I needed to know was coded into the bits of the STATUS register. Once I was able to distinguish the different modes of reset it was pretty trivial to initialize memory variables for Power On Reset (only) and then skip over that initialization on subsequent resets.

So now the Flashlight Project sees a light at the end of the tunnel. I have the PIC10F206 performing a WDT reset every 135 ms, enabling an active pull-up for the push-button switch for about 15 μs (long enough to read the switch state) and overall drawing just under 10 μA of current. Next step is to create a software timer to crank out a millisecond or so delay between WDT resets and see if that is enough to re-charge the energy storage capacitor. My "gut" feeling is it is not and I will need to get the current burden down to less than a micro-ampere by using a low-power version of the PIC10F series.

I haven't timed how long the PIC stays awake after a WDT timeout, but it is surely less than one millisecond. Adding code to implement a one millisecond delay before going back to sleep will increase the current burden, but fortunately this occurs when there is power available through the 330 Ω resistor to power both the PIC and re-charge the energy storage capacitor. It may not be a problem. I think I will (crudely) implement the millisecond delay through nested counter loops. I suppose TIMER0 could be activated for this purpose, but I don't want to farkle with that just yet because it would require switching the prescaler back and forth between the WDT and TIMER0. It seems unbelievable to me, but it appears there is no way that I can see to determine when TIMER0 "rolls over" other than to continuously poll the timer register!
 
Top