dinsdag 30 juli 2013

Temperature display with 7 segment and PIR sensor and PIC18F14K22


I like leds so i decided to make a temperature monitor with 7 segment display running on a single CR2032 battery.

Since the battery consumption is too high to let it run continuously i planned
to make the microcontroller sleep and wake up when a person approaches by using a PIR with low power consumption.

Update 5/8/13 Added battery voltage monitor when Board is powered.

at 2.5v the DS18B20 is still performing great




    Here are the specs:
  • PIC18F14K22 20 pin PIC microcontroller
  • 4 digit 7 segment display Common cathode
  • Panasonic PIR only using 170 uA in idle.
  • DS18B20 temperature sensor in 1-wire mode.
  • CR2032 to power the project.
  • Small piezo speaker so i can use this project for other purposes.
  • ICSP connector onboard for easy uploading new firmware.
The total current draw while sleeping is ~170uA this means it should run about a month on 1 battery.



Lets look at the schematic below:

For a brighter display you can go as low as 470 ohm for the anode resistors without surpassing
the total current of the max pic output current. I used 1k because i will be using it inside in low
light conditions.

Download Hexfile for Temperature monitor for PIC18F14K22

UPDATED Hexfile with voltage monitor at startup

The PIR is optional ,the pic can be awakened by pushing the button as well.
Here is the PCB layout:


Below is the PCB with only a few smd resistors soldered.

 
Here is the interrupt showing the Display multiplex routine:
char mask,dat,curdig=0;

void interrupt()                  // ISR Only Takes 17 usecs in ASM
 {
  if(INTCON.TMR0IF ) // TMR0 Interrupt?  4Mhz/4/8/256 = 488hz ~2mS
    {
    // Multiplexing code
      asm clrf FSR2H
      asm incf FSR2H                  // point to 0x100
      asm movff _curdig,FSR2L         // point to 0x10x current digit data
      asm movff INDF2,_dat            // save digit data
      
      asm bsf FSR2L,5                 // point to 0x12x current mask data
      asm movff INDF2,_mask           // Get current common mask
      asm movlw 0x0F
      asm ANDWF COM7SEG,0
      asm iorwf _mask,0
      asm movwf COM7SEG
      asm movff _dat,PORT7SEG         // PUT digit data on port

      curdig++;                      // value 0 - 3   (0=left digit)
      curdig&=0x03;

     INTCON.TMR0IF = 0;    // clear T0 Int flag
    }
  if(INTCON3.INT2IF) // Hardware interrupt INT0 ?
    {                                               // wake up from sleep
      INTCON3.INT2IF = 0;    // clear INT0 flag
    }
  if(INTCON3.INT1IF) // Hardware interrupt INT1 ?  Button
    {                                               // wake up from sleep
      INTCON3.INT1IF = 0;    // clear INT1 flag
    }
 }