~crm/pic_therm

b10502a0b8651c8d6524d42f48760de0b80a8dd7 — Christos Margiolis 2 years ago
initial commit
A  => LICENSE +20 -0
@@ 1,20 @@
MIT License

(c) 2022-Present Christos Margiolis <christos@margiolis.net>

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the “Software”), to deal in
the Software without restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the Software is furnished to do so, 
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

A  => README +2 -0
@@ 1,2 @@
Temperature and humidity measurement using PIC16F877A and BME280.
https://margiolis.net/articles/thermometer-using-pic16f877a-and-bme280.html

A  => doc/bme280_datasheet.pdf +0 -0
A  => doc/lcd_datasheet.pdf +0 -0
A  => doc/pic16f87xa_datasheet.pdf +0 -0
A  => schem/fp-info-cache +1 -0
@@ 1,1 @@
0

A  => schem/layout.kicad_wks +18 -0
@@ 1,18 @@
(page_layout
  (setup (textsize 1.5 1.5)(linewidth 0.15)(textlinewidth 0.15)
  (left_margin 10)(right_margin 10)(top_margin 10)(bottom_margin 10))
  (rect (name rect1:Rect) (start 0 0 ltcorner) (end 0 0) (repeat 2) (incrx 2) (incry 2))
  (line (name segm1:Line) (start 50 2 ltcorner) (end 50 0 ltcorner) (repeat 30) (incrx 50))
  (tbtext 1 (name text1:Text) (pos 25 1 ltcorner) (font (size 1.3 1.3)) (repeat 100) (incrx 50))
  (line (name segm2:Line) (start 50 2 lbcorner) (end 50 0 lbcorner) (repeat 30) (incrx 50))
  (tbtext 1 (name text2:Text) (pos 25 1 lbcorner) (font (size 1.3 1.3)) (repeat 100) (incrx 50))
  (line (name segm3:Line) (start 0 50 ltcorner) (end 2 50 ltcorner) (repeat 30) (incry 50))
  (tbtext A (name text3:Text) (pos 1 25 ltcorner) (font (size 1.3 1.3)) (justify center) (repeat 100) (incry 50))
  (line (name segm4:Line) (start 0 50 rtcorner) (end 2 50 rtcorner) (repeat 30) (incry 50))
  (tbtext A (name text4:Text) (pos 1 25 rtcorner) (font (size 1.3 1.3)) (justify center) (repeat 100) (incry 50))
  (tbtext %Y (name text5:Text) (pos 109 20) (font bold))
  (tbtext %C0 (name text6:Text) (pos 109 23))
  (tbtext %C1 (name text7:Text) (pos 109 26))
  (tbtext %C2 (name text8:Text) (pos 109 29))
  (tbtext %C3 (name text9:Text) (pos 109 32))
)

A  => schem/pic-cache.lib +277 -0
@@ 1,277 @@
EESchema-LIBRARY Version 2.4
#encoding utf-8
#
# Device_C_Small
#
DEF Device_C_Small C 0 10 N N 1 F N
F0 "C" 10 70 50 H V L CNN
F1 "Device_C_Small" 10 -80 50 H V L CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
 C_*
$ENDFPLIST
DRAW
P 2 0 1 13 -60 -20 60 -20 N
P 2 0 1 12 -60 20 60 20 N
X ~ 1 0 100 80 D 50 50 1 1 P
X ~ 2 0 -100 80 U 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Device_Crystal
#
DEF Device_Crystal Y 0 40 N N 1 F N
F0 "Y" 0 150 50 H V C CNN
F1 "Device_Crystal" 0 -150 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
 Crystal*
$ENDFPLIST
DRAW
S -45 100 45 -100 0 1 12 N
P 2 0 1 0 -100 0 -75 0 N
P 2 0 1 20 -75 -50 -75 50 N
P 2 0 1 20 75 -50 75 50 N
P 2 0 1 0 100 0 75 0 N
X 1 1 -150 0 50 R 50 50 1 1 P
X 2 2 150 0 50 L 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Device_LED
#
DEF Device_LED D 0 40 N N 1 F N
F0 "D" 0 100 50 H V C CNN
F1 "Device_LED" 0 -100 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
 LED*
 LED_SMD:*
 LED_THT:*
$ENDFPLIST
DRAW
P 2 0 1 10 -50 -50 -50 50 N
P 2 0 1 0 -50 0 50 0 N
P 4 0 1 10 50 -50 50 50 -50 0 50 -50 N
P 5 0 1 0 -120 -30 -180 -90 -150 -90 -180 -90 -180 -60 N
P 5 0 1 0 -70 -30 -130 -90 -100 -90 -130 -90 -130 -60 N
X K 1 -150 0 100 R 50 50 1 1 P
X A 2 150 0 100 L 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Device_R_POT_US
#
DEF Device_R_POT_US RV 0 40 Y N 1 F N
F0 "RV" -175 0 50 V V C CNN
F1 "Device_R_POT_US" -100 0 50 V V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
 Potentiometer*
$ENDFPLIST
DRAW
P 2 0 1 0 0 -90 0 -100 N
P 2 0 1 0 0 100 0 90 N
P 2 0 1 0 100 0 60 0 N
P 4 0 1 0 45 0 90 20 90 -20 45 0 F
P 5 0 1 0 0 -30 40 -45 0 -60 -40 -75 0 -90 N
P 5 0 1 0 0 30 40 15 0 0 -40 -15 0 -30 N
P 5 0 1 0 0 90 40 75 0 60 -40 45 0 30 N
X 1 1 0 150 50 D 50 50 1 1 P
X 2 2 150 0 50 L 50 50 1 1 P
X 3 3 0 -150 50 U 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Device_R_US
#
DEF Device_R_US R 0 0 N Y 1 F N
F0 "R" 100 0 50 V V C CNN
F1 "Device_R_US" -100 0 50 V V C CNN
F2 "" 40 -10 50 V I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
 R_*
$ENDFPLIST
DRAW
P 2 0 1 0 0 -90 0 -100 N
P 2 0 1 0 0 90 0 100 N
P 5 0 1 0 0 -30 40 -45 0 -60 -40 -75 0 -90 N
P 5 0 1 0 0 30 40 15 0 0 -40 -15 0 -30 N
P 5 0 1 0 0 90 40 75 0 60 -40 45 0 30 N
X ~ 1 0 150 50 D 50 50 1 1 P
X ~ 2 0 -150 50 U 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Display_Character_NHD-0420H1Z
#
DEF Display_Character_NHD-0420H1Z U 0 20 Y Y 1 F N
F0 "U" -250 750 50 H V C CNN
F1 "Display_Character_NHD-0420H1Z" 200 750 50 H V L CNN
F2 "Display:NHD-0420H1Z" 0 -900 50 H I C CNN
F3 "" 100 -100 50 H I C CNN
$FPLIST
 NHD*0420H1Z*
$ENDFPLIST
DRAW
S -300 700 300 -700 0 1 10 f
X VSS 1 0 -800 100 U 50 50 1 1 W
X DB3 10 -400 -200 100 R 50 50 1 1 B
X DB4 11 -400 -300 100 R 50 50 1 1 B
X DB5 12 -400 -400 100 R 50 50 1 1 B
X DB6 13 -400 -500 100 R 50 50 1 1 B
X DB7 14 -400 -600 100 R 50 50 1 1 B
X A 15 400 -300 100 L 50 50 1 1 P
X K 16 400 -200 100 L 50 50 1 1 P
X VDD 2 0 800 100 D 50 50 1 1 W
X VO 3 100 800 100 D 50 50 1 1 W
X RS 4 -400 600 100 R 50 50 1 1 I
X R/W 5 -400 500 100 R 50 50 1 1 I
X E 6 -400 400 100 R 50 50 1 1 I
X DB0 7 -400 100 100 R 50 50 1 1 B
X DB1 8 -400 0 100 R 50 50 1 1 B
X DB2 9 -400 -100 100 R 50 50 1 1 B
ENDDRAW
ENDDEF
#
# MCU_Microchip_PIC16_PIC16F877A-IP
#
DEF MCU_Microchip_PIC16_PIC16F877A-IP U 0 40 Y Y 1 F N
F0 "U" 200 1400 50 H V L CNN
F1 "MCU_Microchip_PIC16_PIC16F877A-IP" 200 1300 50 H V L CNN
F2 "" 0 0 50 H I C CIN
F3 "" 0 0 50 H I C CNN
ALIAS PIC16F877A-IP
$FPLIST
 DIP*
 PDIP*
$ENDFPLIST
DRAW
S -750 1250 750 -1350 0 1 10 f
X ~MCLR~/Vpp 1 -900 1100 150 R 50 50 1 1 I
X RE2/~CS~/AN7 10 -900 -700 150 R 50 50 1 1 B
X VDD 11 0 1400 150 D 50 50 1 1 W
X VSS 12 0 -1500 150 U 50 50 1 1 W
X OSC1/CLKI 13 -900 800 150 R 50 50 1 1 I
X OSC2/CLKO 14 -900 600 150 R 50 50 1 1 O
X T1OSO/T1CKI/RC0 15 900 -500 150 L 50 50 1 1 B
X T1OSI/CCP2/RC1 16 900 -600 150 L 50 50 1 1 B
X CCP1/RC2 17 900 -700 150 L 50 50 1 1 B
X SCK/SCL/RC3 18 900 -800 150 L 50 50 1 1 B
X RD0/PSP0 19 -900 400 150 R 50 50 1 1 B
X AN0/RA0 2 900 1100 150 L 50 50 1 1 B
X RD1/PSP1 20 -900 300 150 R 50 50 1 1 B
X RD2/PSP2 21 -900 200 150 R 50 50 1 1 B
X RD3/PSP3 22 -900 100 150 R 50 50 1 1 B
X SDI/SDA/RC4 23 900 -900 150 L 50 50 1 1 B
X SDO/RC5 24 900 -1000 150 L 50 50 1 1 B
X CK/TX/RC6 25 900 -1100 150 L 50 50 1 1 B
X DT/RX/RC7 26 900 -1200 150 L 50 50 1 1 B
X RD4/PSP4 27 -900 0 150 R 50 50 1 1 B
X RD5/PSP5 28 -900 -100 150 R 50 50 1 1 B
X RD6/PSP6 29 -900 -200 150 R 50 50 1 1 B
X AN1/RA1 3 900 1000 150 L 50 50 1 1 B
X RD7/PSP7 30 -900 -300 150 R 50 50 1 1 B
X VSS 31 100 -1500 150 U 50 50 1 1 W
X VDD 32 100 1400 150 D 50 50 1 1 W
X INT/RB0 33 900 400 150 L 50 50 1 1 B
X RB1 34 900 300 150 L 50 50 1 1 B
X RB2 35 900 200 150 L 50 50 1 1 B
X PGM/RB3 36 900 100 150 L 50 50 1 1 B
X RB4 37 900 0 150 L 50 50 1 1 B
X RB5 38 900 -100 150 L 50 50 1 1 B
X PGC/RB6 39 900 -200 150 L 50 50 1 1 B
X CVref/Vref-/AN2/RA2 4 900 900 150 L 50 50 1 1 B
X PGD/RB7 40 900 -300 150 L 50 50 1 1 B
X Vref+/AN3/RA3 5 900 800 150 L 50 50 1 1 B
X C1OUT/T0CKI/RA4 6 900 700 150 L 50 50 1 1 B
X ~SS~/C2OUT/AN4/RA5 7 900 600 150 L 50 50 1 1 B
X RE0/~RD~/AN5 8 -900 -500 150 R 50 50 1 1 B
X RE1/~WR~/AN6 9 -900 -600 150 R 50 50 1 1 B
ENDDRAW
ENDDEF
#
# Sensor_BME280
#
DEF Sensor_BME280 U 0 20 Y Y 1 F N
F0 "U" -350 450 50 H V C CNN
F1 "Sensor_BME280" 300 450 50 H V C CNN
F2 "Package_LGA:Bosch_LGA-8_2.5x2.5mm_P0.65mm_ClockwisePinNumbering" 1500 -450 50 H I C CNN
F3 "" 0 -200 50 H I C CNN
$FPLIST
 *LGA*2.5x2.5mm*P0.65mm*Clockwise*
$ENDFPLIST
DRAW
S -400 400 400 -400 0 1 10 f
X GND 1 -100 -600 200 U 50 50 1 1 W
X CSB 2 600 -300 200 L 50 50 1 1 I
X SDI 3 600 -100 200 L 50 50 1 1 B
X SCK 4 600 100 200 L 50 50 1 1 I
X SDO 5 600 300 200 L 50 50 1 1 B
X VDDIO 6 -100 600 200 D 50 50 1 1 W
X GND 7 100 -600 200 U 50 50 1 1 W
X VDD 8 100 600 200 D 50 50 1 1 W
ENDDRAW
ENDDEF
#
# Simulation_SPICE_VDC
#
DEF Simulation_SPICE_VDC V 0 1 N Y 1 F N
F0 "V" 100 100 50 H V L CNN
F1 "Simulation_SPICE_VDC" 100 0 50 H V L CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
F4 "Y" 0 0 50 H I L CNN "Spice_Netlist_Enabled"
F5 "V" 0 0 50 H I L CNN "Spice_Primitive"
F6 "dc(1)" 100 -100 50 H V L CNN "Spice_Model"
DRAW
C 0 0 100 0 1 10 f
T 0 0 75 50 0 0 0 + Normal 0 C C
P 2 0 0 0 -50 10 50 10 N
P 2 0 0 0 -30 -10 -50 -10 N
P 2 0 0 0 10 -10 -10 -10 N
P 2 0 0 0 50 -10 30 -10 N
X ~ 1 0 200 100 D 50 50 1 1 P
X ~ 2 0 -200 100 U 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Switch_SW_Push
#
DEF Switch_SW_Push SW 0 40 N N 1 F N
F0 "SW" 50 100 50 H V L CNN
F1 "Switch_SW_Push" 0 -60 50 H V C CNN
F2 "" 0 200 50 H I C CNN
F3 "" 0 200 50 H I C CNN
DRAW
C -80 0 20 0 1 0 N
C 80 0 20 0 1 0 N
P 2 0 1 0 0 50 0 120 N
P 2 0 1 0 100 50 -100 50 N
X 1 1 -200 0 100 R 50 50 0 1 P
X 2 2 200 0 100 L 50 50 0 1 P
ENDDRAW
ENDDEF
#
# power_GNDREF
#
DEF power_GNDREF #PWR 0 0 Y Y 1 F P
F0 "#PWR" 0 -250 50 H I C CNN
F1 "power_GNDREF" 0 -150 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
DRAW
P 2 0 1 0 -25 -75 25 -75 N
P 2 0 1 0 -5 -100 5 -100 N
P 2 0 1 0 0 -50 0 0 N
P 2 0 1 0 50 -50 -50 -50 N
X GNDREF 1 0 0 0 D 50 50 1 1 W N
ENDDRAW
ENDDEF
#
#End Library

A  => schem/pic.pdf +0 -0
A  => schem/pic.pro +248 -0
@@ 1,248 @@
update=Wed Feb  2 15:50:17 2022
version=1
last_client=kicad
[general]
version=1
RootSch=
BoardNm=
[cvpcb]
version=1
NetIExt=net
[eeschema]
version=1
LibDir=
[eeschema/libraries]
[schematic_editor]
version=1
PageLayoutDescrFile=layout.kicad_wks
PlotDirectoryName=../doc/
SubpartIdSeparator=0
SubpartFirstId=65
NetFmtName=Pcbnew
SpiceAjustPassiveValues=0
LabSize=50
ERC_TestSimilarLabels=1
[pcbnew]
version=1
PageLayoutDescrFile=
LastNetListRead=pic.net
CopperLayerCount=2
BoardThickness=1.6
AllowMicroVias=0
AllowBlindVias=0
RequireCourtyardDefinitions=0
ProhibitOverlappingCourtyards=1
MinTrackWidth=0.2
MinViaDiameter=0.4
MinViaDrill=0.3
MinMicroViaDiameter=0.2
MinMicroViaDrill=0.09999999999999999
MinHoleToHole=0.25
TrackWidth1=0.25
ViaDiameter1=0.8
ViaDrill1=0.4
dPairWidth1=0.2
dPairGap1=0.25
dPairViaGap1=0.25
SilkLineWidth=0.12
SilkTextSizeV=1
SilkTextSizeH=1
SilkTextSizeThickness=0.15
SilkTextItalic=0
SilkTextUpright=1
CopperLineWidth=0.2
CopperTextSizeV=1.5
CopperTextSizeH=1.5
CopperTextThickness=0.3
CopperTextItalic=0
CopperTextUpright=1
EdgeCutLineWidth=0.05
CourtyardLineWidth=0.05
OthersLineWidth=0.15
OthersTextSizeV=1
OthersTextSizeH=1
OthersTextSizeThickness=0.15
OthersTextItalic=0
OthersTextUpright=1
SolderMaskClearance=0
SolderMaskMinWidth=0
SolderPasteClearance=0
SolderPasteRatio=0
[pcbnew/Layer.F.Cu]
Name=F.Cu
Type=0
Enabled=1
[pcbnew/Layer.In1.Cu]
Name=In1.Cu
Type=0
Enabled=0
[pcbnew/Layer.In2.Cu]
Name=In2.Cu
Type=0
Enabled=0
[pcbnew/Layer.In3.Cu]
Name=In3.Cu
Type=0
Enabled=0
[pcbnew/Layer.In4.Cu]
Name=In4.Cu
Type=0
Enabled=0
[pcbnew/Layer.In5.Cu]
Name=In5.Cu
Type=0
Enabled=0
[pcbnew/Layer.In6.Cu]
Name=In6.Cu
Type=0
Enabled=0
[pcbnew/Layer.In7.Cu]
Name=In7.Cu
Type=0
Enabled=0
[pcbnew/Layer.In8.Cu]
Name=In8.Cu
Type=0
Enabled=0
[pcbnew/Layer.In9.Cu]
Name=In9.Cu
Type=0
Enabled=0
[pcbnew/Layer.In10.Cu]
Name=In10.Cu
Type=0
Enabled=0
[pcbnew/Layer.In11.Cu]
Name=In11.Cu
Type=0
Enabled=0
[pcbnew/Layer.In12.Cu]
Name=In12.Cu
Type=0
Enabled=0
[pcbnew/Layer.In13.Cu]
Name=In13.Cu
Type=0
Enabled=0
[pcbnew/Layer.In14.Cu]
Name=In14.Cu
Type=0
Enabled=0
[pcbnew/Layer.In15.Cu]
Name=In15.Cu
Type=0
Enabled=0
[pcbnew/Layer.In16.Cu]
Name=In16.Cu
Type=0
Enabled=0
[pcbnew/Layer.In17.Cu]
Name=In17.Cu
Type=0
Enabled=0
[pcbnew/Layer.In18.Cu]
Name=In18.Cu
Type=0
Enabled=0
[pcbnew/Layer.In19.Cu]
Name=In19.Cu
Type=0
Enabled=0
[pcbnew/Layer.In20.Cu]
Name=In20.Cu
Type=0
Enabled=0
[pcbnew/Layer.In21.Cu]
Name=In21.Cu
Type=0
Enabled=0
[pcbnew/Layer.In22.Cu]
Name=In22.Cu
Type=0
Enabled=0
[pcbnew/Layer.In23.Cu]
Name=In23.Cu
Type=0
Enabled=0
[pcbnew/Layer.In24.Cu]
Name=In24.Cu
Type=0
Enabled=0
[pcbnew/Layer.In25.Cu]
Name=In25.Cu
Type=0
Enabled=0
[pcbnew/Layer.In26.Cu]
Name=In26.Cu
Type=0
Enabled=0
[pcbnew/Layer.In27.Cu]
Name=In27.Cu
Type=0
Enabled=0
[pcbnew/Layer.In28.Cu]
Name=In28.Cu
Type=0
Enabled=0
[pcbnew/Layer.In29.Cu]
Name=In29.Cu
Type=0
Enabled=0
[pcbnew/Layer.In30.Cu]
Name=In30.Cu
Type=0
Enabled=0
[pcbnew/Layer.B.Cu]
Name=B.Cu
Type=0
Enabled=1
[pcbnew/Layer.B.Adhes]
Enabled=1
[pcbnew/Layer.F.Adhes]
Enabled=1
[pcbnew/Layer.B.Paste]
Enabled=1
[pcbnew/Layer.F.Paste]
Enabled=1
[pcbnew/Layer.B.SilkS]
Enabled=1
[pcbnew/Layer.F.SilkS]
Enabled=1
[pcbnew/Layer.B.Mask]
Enabled=1
[pcbnew/Layer.F.Mask]
Enabled=1
[pcbnew/Layer.Dwgs.User]
Enabled=1
[pcbnew/Layer.Cmts.User]
Enabled=1
[pcbnew/Layer.Eco1.User]
Enabled=1
[pcbnew/Layer.Eco2.User]
Enabled=1
[pcbnew/Layer.Edge.Cuts]
Enabled=1
[pcbnew/Layer.Margin]
Enabled=1
[pcbnew/Layer.B.CrtYd]
Enabled=1
[pcbnew/Layer.F.CrtYd]
Enabled=1
[pcbnew/Layer.B.Fab]
Enabled=1
[pcbnew/Layer.F.Fab]
Enabled=1
[pcbnew/Layer.Rescue]
Enabled=1
[pcbnew/Netclasses]
[pcbnew/Netclasses/Default]
Name=Default
Clearance=0.2
TrackWidth=0.25
ViaDiameter=0.8
ViaDrill=0.4
uViaDiameter=0.3
uViaDrill=0.1
dPairWidth=0.2
dPairGap=0.25
dPairViaGap=0.25

A  => schem/pic.sch +473 -0
@@ 1,473 @@
EESchema Schematic File Version 4
EELAYER 30 0
EELAYER END
$Descr A4 11693 8268
encoding utf-8
Sheet 1 1
Title ""
Date ""
Rev ""
Comp ""
Comment1 ""
Comment2 ""
Comment3 ""
Comment4 ""
$EndDescr
$Comp
L Device:R_US R1
U 1 1 61EA1FDB
P 5300 3000
F 0 "R1" H 5368 3046 50  0000 L CNN
F 1 "10kΩ" H 5368 2955 50  0000 L CNN
F 2 "" V 5340 2990 50  0001 C CNN
F 3 "~" H 5300 3000 50  0001 C CNN
	1    5300 3000
	0    -1   -1   0   
$EndComp
$Comp
L power:GNDREF #GND0101
U 1 1 61EB279A
P 5450 2150
F 0 "#GND0101" H 5538 2113 50  0000 L CNN
F 1 "GNDREF" H 5455 1977 50  0001 C CNN
F 2 "" H 5450 2150 50  0001 C CNN
F 3 "" H 5450 2150 50  0001 C CNN
	1    5450 2150
	-1   0    0    1   
$EndComp
$Comp
L Device:R_US R2
U 1 1 61ECA8DC
P 4100 5950
F 0 "R2" H 4168 5996 50  0000 L CNN
F 1 "330Ω" H 4168 5905 50  0000 L CNN
F 2 "" V 4140 5940 50  0001 C CNN
F 3 "~" H 4100 5950 50  0001 C CNN
	1    4100 5950
	1    0    0    -1  
$EndComp
$Comp
L MCU_Microchip_PIC16:PIC16F877A-IP PIC16F877A-IP1
U 1 1 61E8B28E
P 6550 4100
F 0 "PIC16F877A-IP1" H 6550 5589 50  0000 C CNN
F 1 "PIC16F877A-IP" H 6550 5590 50  0001 C CNN
F 2 "" H 6550 4100 50  0001 C CIN
F 3 "http://ww1.microchip.com/downloads/en/DeviceDoc/39582b.pdf" H 6550 4100 50  0001 C CNN
	1    6550 4100
	1    0    0    -1  
$EndComp
$Comp
L Simulation_SPICE:VDC V1
U 1 1 61F2BB51
P 6000 1550
F 0 "V1" H 6130 1596 50  0001 L CNN
F 1 "5V" H 5870 1550 50  0000 R CNN
F 2 "" H 6000 1550 50  0001 C CNN
F 3 "~" H 6000 1550 50  0001 C CNN
F 4 "Y" H 6000 1550 50  0001 L CNN "Spice_Netlist_Enabled"
F 5 "V" H 6000 1550 50  0001 L CNN "Spice_Primitive"
F 6 "dc(1)" H 6130 1459 50  0001 L CNN "Spice_Model"
	1    6000 1550
	-1   0    0    1   
$EndComp
$Comp
L power:GNDREF #GND0102
U 1 1 61F5552B
P 6550 6300
F 0 "#GND0102" H 6638 6263 50  0000 L CNN
F 1 "GNDREF" H 6555 6127 50  0001 C CNN
F 2 "" H 6550 6300 50  0001 C CNN
F 3 "" H 6550 6300 50  0001 C CNN
	1    6550 6300
	1    0    0    -1  
$EndComp
Wire Wire Line
	5450 3000 5650 3000
Wire Wire Line
	6000 2450 6550 2450
Wire Wire Line
	6550 2450 6550 2700
Wire Wire Line
	5150 3000 4900 3000
$Comp
L Switch:SW_Push RSTB1
U 1 1 61FC0519
P 5150 2500
F 0 "RSTB1" H 5150 2693 50  0000 C CNN
F 1 "SW_Push" H 5150 2694 50  0001 C CNN
F 2 "" H 5150 2700 50  0001 C CNN
F 3 "~" H 5150 2700 50  0001 C CNN
	1    5150 2500
	1    0    0    -1  
$EndComp
Wire Wire Line
	4900 2500 4950 2500
Wire Wire Line
	4900 2500 4900 2650
Wire Wire Line
	5450 2150 5450 2500
Wire Wire Line
	4900 2650 5850 2650
Wire Wire Line
	5850 2650 5850 2450
Wire Wire Line
	5850 2450 6000 2450
Connection ~ 4900 2650
Wire Wire Line
	4900 2650 4900 3000
Connection ~ 6000 2450
Wire Wire Line
	6650 2450 6550 2450
Connection ~ 6550 2450
$Comp
L Sensor:BME280 BME280
U 1 1 61E953D6
P 8750 2600
F 0 "BME280" H 8321 2646 50  0000 R CNN
F 1 "BME280" H 8321 2555 50  0001 R CNN
F 2 "Package_LGA:Bosch_LGA-8_2.5x2.5mm_P0.65mm_ClockwisePinNumbering" H 10250 2150 50  0001 C CNN
F 3 "https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280-DS002.pdf" H 8750 2400 50  0001 C CNN
	1    8750 2600
	-1   0    0    -1  
$EndComp
Wire Wire Line
	6650 2700 6650 2450
$Comp
L Display_Character:NHD-0420H1Z LCD1
U 1 1 61E937A6
P 4400 5200
F 0 "LCD1" V 4400 4356 50  0000 R CNN
F 1 "NHD-0420H1Z" H 4400 4220 50  0001 C CNN
F 2 "Display:NHD-0420H1Z" H 4400 4300 50  0001 C CNN
F 3 "http://www.newhavendisplay.com/specs/NHD-0420H1Z-FSW-GBW-33V3.pdf" H 4500 5100 50  0001 C CNN
	1    4400 5200
	0    1    1    0   
$EndComp
Wire Wire Line
	3600 5200 3550 5200
Wire Wire Line
	4100 5600 4100 5800
Wire Wire Line
	4100 6250 4100 6100
Connection ~ 6000 1950
Wire Wire Line
	6000 1950 6000 2450
Wire Wire Line
	6550 5600 6550 5700
Connection ~ 6550 5700
Wire Wire Line
	5200 5200 5300 5200
Connection ~ 4100 6250
Wire Wire Line
	4200 5600 4200 5700
Wire Wire Line
	4200 5700 5050 5700
Wire Wire Line
	4100 6250 5050 6250
Connection ~ 5050 5700
Wire Wire Line
	5050 5700 6550 5700
Connection ~ 5050 6250
Wire Wire Line
	5050 6250 5300 6250
Wire Wire Line
	3550 6150 6550 6150
Wire Wire Line
	3550 5200 3550 6150
Connection ~ 6550 6150
Wire Wire Line
	6550 6150 6550 6300
Wire Wire Line
	6000 1750 6000 1950
Wire Wire Line
	6550 5700 6550 6150
Wire Wire Line
	6650 5600 6650 5700
Wire Wire Line
	6650 5700 6550 5700
Wire Wire Line
	8650 6150 6550 6150
Wire Wire Line
	8650 1950 6000 1950
Wire Wire Line
	7450 4900 7550 4900
Wire Wire Line
	7550 4900 7550 2500
Wire Wire Line
	7550 2500 8150 2500
Wire Wire Line
	7450 5000 7650 5000
Wire Wire Line
	7650 5000 7650 2700
Wire Wire Line
	7650 2700 8150 2700
Wire Wire Line
	7450 5100 7750 5100
Wire Wire Line
	7750 5100 7750 2300
Wire Wire Line
	7750 2300 8150 2300
Wire Wire Line
	8650 3200 8650 3350
$Comp
L Device:LED LED1
U 1 1 61E8F822
P 8400 3950
F 0 "LED1" H 8393 4075 50  0000 C CNN
F 1 "LED" H 8393 4076 50  0001 C CNN
F 2 "" H 8400 3950 50  0001 C CNN
F 3 "~" H 8400 3950 50  0001 C CNN
	1    8400 3950
	-1   0    0    1   
$EndComp
$Comp
L Device:R_US R3
U 1 1 61F053CB
P 8000 3950
F 0 "R3" H 8068 3996 50  0000 L CNN
F 1 "330Ω" H 8068 3905 50  0000 L CNN
F 2 "" V 8040 3940 50  0001 C CNN
F 3 "~" H 8000 3950 50  0001 C CNN
	1    8000 3950
	0    -1   -1   0   
$EndComp
Wire Wire Line
	8650 2000 8650 1950
$Comp
L Switch:SW_Push BTN1
U 1 1 620E2C06
P 8050 3550
F 0 "BTN1" H 8050 3743 50  0000 C CNN
F 1 "SW_Push" H 8050 3744 50  0001 C CNN
F 2 "" H 8050 3750 50  0001 C CNN
F 3 "~" H 8050 3750 50  0001 C CNN
	1    8050 3550
	1    0    0    -1  
$EndComp
Wire Wire Line
	3400 1950 3400 6250
Wire Wire Line
	5450 2500 5350 2500
$Comp
L Device:C_Small C1
U 1 1 61E97CC0
P 4200 2650
F 0 "C1" H 4292 2696 50  0000 L CNN
F 1 "22pF" H 4292 2605 50  0000 L CNN
F 2 "" H 4200 2650 50  0001 C CNN
F 3 "~" H 4200 2650 50  0001 C CNN
	1    4200 2650
	1    0    0    1   
$EndComp
$Comp
L Device:C_Small C2
U 1 1 61ECA409
P 4200 3350
F 0 "C2" H 4292 3396 50  0000 L CNN
F 1 "22pF" H 4292 3305 50  0000 L CNN
F 2 "" H 4200 3350 50  0001 C CNN
F 3 "~" H 4200 3350 50  0001 C CNN
	1    4200 3350
	-1   0    0    1   
$EndComp
$Comp
L Device:Crystal OSC1
U 1 1 61EB43E4
P 4200 3000
F 0 "OSC1" H 4200 3268 50  0000 C CNN
F 1 "16MHz" H 4200 3177 50  0000 C CNN
F 2 "" H 4200 3000 50  0001 C CNN
F 3 "~" H 4200 3000 50  0001 C CNN
	1    4200 3000
	0    -1   -1   0   
$EndComp
$Comp
L power:GNDREF #GND0103
U 1 1 61EE8AF0
P 3800 3000
F 0 "#GND0103" H 3888 2963 50  0000 L CNN
F 1 "GNDREF" H 3805 2827 50  0001 C CNN
F 2 "" H 3800 3000 50  0001 C CNN
F 3 "" H 3800 3000 50  0001 C CNN
	1    3800 3000
	0    1    1    0   
$EndComp
Wire Wire Line
	3800 3000 3850 3000
Wire Wire Line
	3850 3000 3850 2500
Wire Wire Line
	3850 2500 4200 2500
Wire Wire Line
	4200 2500 4200 2550
Wire Wire Line
	4200 3450 4200 3500
Wire Wire Line
	4200 3500 3850 3500
Wire Wire Line
	3850 3500 3850 3000
Connection ~ 3850 3000
Wire Wire Line
	4200 3150 4200 3250
Wire Wire Line
	4200 2850 4200 2750
Wire Wire Line
	3400 1950 6000 1950
Wire Wire Line
	3400 6250 4100 6250
Wire Wire Line
	5300 6250 5300 5200
Wire Wire Line
	8850 3200 8850 3350
Wire Wire Line
	8850 3350 8650 3350
Connection ~ 8650 3350
Wire Wire Line
	8850 2000 8850 1950
Wire Wire Line
	8850 1950 8650 1950
Connection ~ 8650 1950
Wire Wire Line
	5050 6100 5050 6250
Wire Wire Line
	5200 5950 5200 5300
Wire Wire Line
	5050 5800 5050 5700
$Comp
L Device:R_POT_US POT1
U 1 1 6208C3F4
P 5050 5950
F 0 "POT1" H 4983 5996 50  0000 R CNN
F 1 "10kΩ" H 4983 5905 50  0000 R CNN
F 2 "" H 5050 5950 50  0001 C CNN
F 3 "~" H 5050 5950 50  0001 C CNN
	1    5050 5950
	1    0    0    -1  
$EndComp
Wire Wire Line
	4200 3250 4650 3250
Wire Wire Line
	4650 3250 4650 3500
Wire Wire Line
	4650 3500 5650 3500
Connection ~ 4200 3250
Wire Wire Line
	4200 2750 4750 2750
Wire Wire Line
	4750 2750 4750 3300
Wire Wire Line
	4750 3300 5650 3300
Connection ~ 4200 2750
Wire Wire Line
	7450 3700 7850 3700
Wire Wire Line
	7850 3700 7850 3550
Wire Wire Line
	8650 3350 8650 3550
Connection ~ 8650 3550
Wire Wire Line
	8650 3550 8650 3950
Wire Wire Line
	7450 3800 7850 3800
Wire Wire Line
	7850 3800 7850 3950
Wire Wire Line
	8550 3950 8650 3950
Connection ~ 8650 3950
Wire Wire Line
	8650 3950 8650 6150
Wire Wire Line
	8600 3550 8650 3550
$Comp
L Device:R_US R4
U 1 1 62134942
P 8450 3550
F 0 "R4" H 8518 3596 50  0000 L CNN
F 1 "10kΩ" H 8518 3505 50  0000 L CNN
F 2 "" V 8490 3540 50  0001 C CNN
F 3 "~" H 8450 3550 50  0001 C CNN
	1    8450 3550
	0    -1   -1   0   
$EndComp
Wire Wire Line
	8150 3950 8250 3950
Wire Wire Line
	8250 3550 8300 3550
Wire Wire Line
	4500 4800 4500 3700
Wire Wire Line
	4500 3700 5650 3700
Wire Wire Line
	4400 4800 4400 3800
Wire Wire Line
	4400 3800 5650 3800
Wire Wire Line
	4300 4800 4300 3900
Wire Wire Line
	4300 3900 5650 3900
Wire Wire Line
	4200 4800 4200 4000
Wire Wire Line
	4200 4000 5650 4000
Wire Wire Line
	4100 4800 4100 4100
Wire Wire Line
	4100 4100 5650 4100
Wire Wire Line
	4000 4800 4000 4200
Wire Wire Line
	4000 4200 5650 4200
Wire Wire Line
	3900 4800 3900 4300
Wire Wire Line
	3900 4300 5650 4300
Wire Wire Line
	3800 4800 3800 4400
Wire Wire Line
	3800 4400 5650 4400
Wire Wire Line
	5000 4800 5000 4750
Wire Wire Line
	5000 4750 5400 4750
Wire Wire Line
	5400 4750 5400 6000
Wire Wire Line
	5400 6000 8050 6000
Wire Wire Line
	8050 6000 8050 4600
Wire Wire Line
	8050 4600 7450 4600
Wire Wire Line
	4900 4800 4900 4650
Wire Wire Line
	4900 4650 5500 4650
Wire Wire Line
	5500 4650 5500 5900
Wire Wire Line
	5500 5900 7950 5900
Wire Wire Line
	7950 5900 7950 4700
Wire Wire Line
	7950 4700 7450 4700
Wire Wire Line
	4800 4800 4800 4550
Wire Wire Line
	4800 4550 5600 4550
Wire Wire Line
	5600 4550 5600 5800
Wire Wire Line
	5600 5800 7850 5800
Wire Wire Line
	7850 5800 7850 4800
Wire Wire Line
	7850 4800 7450 4800
Entry Bus Bus
	2200 2000 2300 2100
Entry Bus Bus
	2200 2000 2300 2100
Entry Bus Bus
	2200 2000 2300 2100
Entry Bus Bus
	2200 2000 2300 2100
$EndSCHEMATC

A  => schem/pic.sch-bak +473 -0
@@ 1,473 @@
EESchema Schematic File Version 4
EELAYER 30 0
EELAYER END
$Descr A4 11693 8268
encoding utf-8
Sheet 1 1
Title ""
Date ""
Rev ""
Comp ""
Comment1 ""
Comment2 ""
Comment3 ""
Comment4 ""
$EndDescr
$Comp
L Device:R_US R1
U 1 1 61EA1FDB
P 5300 3000
F 0 "R1" H 5368 3046 50  0000 L CNN
F 1 "10kΩ" H 5368 2955 50  0000 L CNN
F 2 "" V 5340 2990 50  0001 C CNN
F 3 "~" H 5300 3000 50  0001 C CNN
	1    5300 3000
	0    -1   -1   0   
$EndComp
$Comp
L power:GNDREF GND
U 1 1 61EB279A
P 5450 2150
F 0 "GND" H 5538 2113 50  0000 L CNN
F 1 "GNDREF" H 5455 1977 50  0001 C CNN
F 2 "" H 5450 2150 50  0001 C CNN
F 3 "" H 5450 2150 50  0001 C CNN
	1    5450 2150
	-1   0    0    1   
$EndComp
$Comp
L Device:R_US R2
U 1 1 61ECA8DC
P 4100 5950
F 0 "R2" H 4168 5996 50  0000 L CNN
F 1 "330Ω" H 4168 5905 50  0000 L CNN
F 2 "" V 4140 5940 50  0001 C CNN
F 3 "~" H 4100 5950 50  0001 C CNN
	1    4100 5950
	1    0    0    -1  
$EndComp
$Comp
L MCU_Microchip_PIC16:PIC16F877A-IP PIC16F877A-IP1
U 1 1 61E8B28E
P 6550 4100
F 0 "PIC16F877A-IP1" H 6550 5589 50  0000 C CNN
F 1 "PIC16F877A-IP" H 6550 5590 50  0001 C CNN
F 2 "" H 6550 4100 50  0001 C CIN
F 3 "http://ww1.microchip.com/downloads/en/DeviceDoc/39582b.pdf" H 6550 4100 50  0001 C CNN
	1    6550 4100
	1    0    0    -1  
$EndComp
$Comp
L Simulation_SPICE:VDC V1
U 1 1 61F2BB51
P 6000 1550
F 0 "V1" H 6130 1596 50  0001 L CNN
F 1 "5V" H 5870 1550 50  0000 R CNN
F 2 "" H 6000 1550 50  0001 C CNN
F 3 "~" H 6000 1550 50  0001 C CNN
F 4 "Y" H 6000 1550 50  0001 L CNN "Spice_Netlist_Enabled"
F 5 "V" H 6000 1550 50  0001 L CNN "Spice_Primitive"
F 6 "dc(1)" H 6130 1459 50  0001 L CNN "Spice_Model"
	1    6000 1550
	-1   0    0    1   
$EndComp
$Comp
L power:GNDREF GND
U 1 1 61F5552B
P 6550 6300
F 0 "GND" H 6638 6263 50  0000 L CNN
F 1 "GNDREF" H 6555 6127 50  0001 C CNN
F 2 "" H 6550 6300 50  0001 C CNN
F 3 "" H 6550 6300 50  0001 C CNN
	1    6550 6300
	1    0    0    -1  
$EndComp
Wire Wire Line
	5450 3000 5650 3000
Wire Wire Line
	6000 2450 6550 2450
Wire Wire Line
	6550 2450 6550 2700
Wire Wire Line
	5150 3000 4900 3000
$Comp
L Switch:SW_Push RSTB1
U 1 1 61FC0519
P 5150 2500
F 0 "RSTB1" H 5150 2693 50  0000 C CNN
F 1 "SW_Push" H 5150 2694 50  0001 C CNN
F 2 "" H 5150 2700 50  0001 C CNN
F 3 "~" H 5150 2700 50  0001 C CNN
	1    5150 2500
	1    0    0    -1  
$EndComp
Wire Wire Line
	4900 2500 4950 2500
Wire Wire Line
	4900 2500 4900 2650
Wire Wire Line
	5450 2150 5450 2500
Wire Wire Line
	4900 2650 5850 2650
Wire Wire Line
	5850 2650 5850 2450
Wire Wire Line
	5850 2450 6000 2450
Connection ~ 4900 2650
Wire Wire Line
	4900 2650 4900 3000
Connection ~ 6000 2450
Wire Wire Line
	6650 2450 6550 2450
Connection ~ 6550 2450
$Comp
L Sensor:BME280 BME280
U 1 1 61E953D6
P 8750 2600
F 0 "BME280" H 8321 2646 50  0000 R CNN
F 1 "BME280" H 8321 2555 50  0001 R CNN
F 2 "Package_LGA:Bosch_LGA-8_2.5x2.5mm_P0.65mm_ClockwisePinNumbering" H 10250 2150 50  0001 C CNN
F 3 "https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280-DS002.pdf" H 8750 2400 50  0001 C CNN
	1    8750 2600
	-1   0    0    -1  
$EndComp
Wire Wire Line
	6650 2700 6650 2450
$Comp
L Display_Character:NHD-0420H1Z LCD
U 1 1 61E937A6
P 4400 5200
F 0 "LCD" V 4400 4356 50  0000 R CNN
F 1 "NHD-0420H1Z" H 4400 4220 50  0001 C CNN
F 2 "Display:NHD-0420H1Z" H 4400 4300 50  0001 C CNN
F 3 "http://www.newhavendisplay.com/specs/NHD-0420H1Z-FSW-GBW-33V3.pdf" H 4500 5100 50  0001 C CNN
	1    4400 5200
	0    1    1    0   
$EndComp
Wire Wire Line
	3600 5200 3550 5200
Wire Wire Line
	4100 5600 4100 5800
Wire Wire Line
	4100 6250 4100 6100
Connection ~ 6000 1950
Wire Wire Line
	6000 1950 6000 2450
Wire Wire Line
	6550 5600 6550 5700
Connection ~ 6550 5700
Wire Wire Line
	5200 5200 5300 5200
Connection ~ 4100 6250
Wire Wire Line
	4200 5600 4200 5700
Wire Wire Line
	4200 5700 5050 5700
Wire Wire Line
	4100 6250 5050 6250
Connection ~ 5050 5700
Wire Wire Line
	5050 5700 6550 5700
Connection ~ 5050 6250
Wire Wire Line
	5050 6250 5300 6250
Wire Wire Line
	3550 6150 6550 6150
Wire Wire Line
	3550 5200 3550 6150
Connection ~ 6550 6150
Wire Wire Line
	6550 6150 6550 6300
Wire Wire Line
	6000 1750 6000 1950
Wire Wire Line
	6550 5700 6550 6150
Wire Wire Line
	6650 5600 6650 5700
Wire Wire Line
	6650 5700 6550 5700
Wire Wire Line
	8650 6150 6550 6150
Wire Wire Line
	8650 1950 6000 1950
Wire Wire Line
	7450 4900 7550 4900
Wire Wire Line
	7550 4900 7550 2500
Wire Wire Line
	7550 2500 8150 2500
Wire Wire Line
	7450 5000 7650 5000
Wire Wire Line
	7650 5000 7650 2700
Wire Wire Line
	7650 2700 8150 2700
Wire Wire Line
	7450 5100 7750 5100
Wire Wire Line
	7750 5100 7750 2300
Wire Wire Line
	7750 2300 8150 2300
Wire Wire Line
	8650 3200 8650 3350
$Comp
L Device:LED LED1
U 1 1 61E8F822
P 8400 3950
F 0 "LED1" H 8393 4075 50  0000 C CNN
F 1 "LED" H 8393 4076 50  0001 C CNN
F 2 "" H 8400 3950 50  0001 C CNN
F 3 "~" H 8400 3950 50  0001 C CNN
	1    8400 3950
	-1   0    0    1   
$EndComp
$Comp
L Device:R_US R3
U 1 1 61F053CB
P 8000 3950
F 0 "R3" H 8068 3996 50  0000 L CNN
F 1 "330Ω" H 8068 3905 50  0000 L CNN
F 2 "" V 8040 3940 50  0001 C CNN
F 3 "~" H 8000 3950 50  0001 C CNN
	1    8000 3950
	0    -1   -1   0   
$EndComp
Wire Wire Line
	8650 2000 8650 1950
$Comp
L Switch:SW_Push BTN1
U 1 1 620E2C06
P 8050 3550
F 0 "BTN1" H 8050 3743 50  0000 C CNN
F 1 "SW_Push" H 8050 3744 50  0001 C CNN
F 2 "" H 8050 3750 50  0001 C CNN
F 3 "~" H 8050 3750 50  0001 C CNN
	1    8050 3550
	1    0    0    -1  
$EndComp
Wire Wire Line
	3400 1950 3400 6250
Wire Wire Line
	5450 2500 5350 2500
$Comp
L Device:C_Small C1
U 1 1 61E97CC0
P 4200 2650
F 0 "C1" H 4292 2696 50  0000 L CNN
F 1 "22pF" H 4292 2605 50  0000 L CNN
F 2 "" H 4200 2650 50  0001 C CNN
F 3 "~" H 4200 2650 50  0001 C CNN
	1    4200 2650
	1    0    0    1   
$EndComp
$Comp
L Device:C_Small C2
U 1 1 61ECA409
P 4200 3350
F 0 "C2" H 4292 3396 50  0000 L CNN
F 1 "22pF" H 4292 3305 50  0000 L CNN
F 2 "" H 4200 3350 50  0001 C CNN
F 3 "~" H 4200 3350 50  0001 C CNN
	1    4200 3350
	-1   0    0    1   
$EndComp
$Comp
L Device:Crystal OSC1
U 1 1 61EB43E4
P 4200 3000
F 0 "OSC1" H 4200 3268 50  0000 C CNN
F 1 "16MHz" H 4200 3177 50  0000 C CNN
F 2 "" H 4200 3000 50  0001 C CNN
F 3 "~" H 4200 3000 50  0001 C CNN
	1    4200 3000
	0    -1   -1   0   
$EndComp
$Comp
L power:GNDREF GND
U 1 1 61EE8AF0
P 3800 3000
F 0 "GND" H 3888 2963 50  0000 L CNN
F 1 "GNDREF" H 3805 2827 50  0001 C CNN
F 2 "" H 3800 3000 50  0001 C CNN
F 3 "" H 3800 3000 50  0001 C CNN
	1    3800 3000
	0    1    1    0   
$EndComp
Wire Wire Line
	3800 3000 3850 3000
Wire Wire Line
	3850 3000 3850 2500
Wire Wire Line
	3850 2500 4200 2500
Wire Wire Line
	4200 2500 4200 2550
Wire Wire Line
	4200 3450 4200 3500
Wire Wire Line
	4200 3500 3850 3500
Wire Wire Line
	3850 3500 3850 3000
Connection ~ 3850 3000
Wire Wire Line
	4200 3150 4200 3250
Wire Wire Line
	4200 2850 4200 2750
Wire Wire Line
	3400 1950 6000 1950
Wire Wire Line
	3400 6250 4100 6250
Wire Wire Line
	5300 6250 5300 5200
Wire Wire Line
	8850 3200 8850 3350
Wire Wire Line
	8850 3350 8650 3350
Connection ~ 8650 3350
Wire Wire Line
	8850 2000 8850 1950
Wire Wire Line
	8850 1950 8650 1950
Connection ~ 8650 1950
Wire Wire Line
	5050 6100 5050 6250
Wire Wire Line
	5200 5950 5200 5300
Wire Wire Line
	5050 5800 5050 5700
$Comp
L Device:R_POT_US POT1
U 1 1 6208C3F4
P 5050 5950
F 0 "POT1" H 4983 5996 50  0000 R CNN
F 1 "10kΩ" H 4983 5905 50  0000 R CNN
F 2 "" H 5050 5950 50  0001 C CNN
F 3 "~" H 5050 5950 50  0001 C CNN
	1    5050 5950
	1    0    0    -1  
$EndComp
Wire Wire Line
	4200 3250 4650 3250
Wire Wire Line
	4650 3250 4650 3500
Wire Wire Line
	4650 3500 5650 3500
Connection ~ 4200 3250
Wire Wire Line
	4200 2750 4750 2750
Wire Wire Line
	4750 2750 4750 3300
Wire Wire Line
	4750 3300 5650 3300
Connection ~ 4200 2750
Wire Wire Line
	7450 3700 7850 3700
Wire Wire Line
	7850 3700 7850 3550
Wire Wire Line
	8650 3350 8650 3550
Connection ~ 8650 3550
Wire Wire Line
	8650 3550 8650 3950
Wire Wire Line
	7450 3800 7850 3800
Wire Wire Line
	7850 3800 7850 3950
Wire Wire Line
	8550 3950 8650 3950
Connection ~ 8650 3950
Wire Wire Line
	8650 3950 8650 6150
Wire Wire Line
	8600 3550 8650 3550
$Comp
L Device:R_US R4
U 1 1 62134942
P 8450 3550
F 0 "R4" H 8518 3596 50  0000 L CNN
F 1 "10kΩ" H 8518 3505 50  0000 L CNN
F 2 "" V 8490 3540 50  0001 C CNN
F 3 "~" H 8450 3550 50  0001 C CNN
	1    8450 3550
	0    -1   -1   0   
$EndComp
Wire Wire Line
	8150 3950 8250 3950
Wire Wire Line
	8250 3550 8300 3550
Wire Wire Line
	4500 4800 4500 3700
Wire Wire Line
	4500 3700 5650 3700
Wire Wire Line
	4400 4800 4400 3800
Wire Wire Line
	4400 3800 5650 3800
Wire Wire Line
	4300 4800 4300 3900
Wire Wire Line
	4300 3900 5650 3900
Wire Wire Line
	4200 4800 4200 4000
Wire Wire Line
	4200 4000 5650 4000
Wire Wire Line
	4100 4800 4100 4100
Wire Wire Line
	4100 4100 5650 4100
Wire Wire Line
	4000 4800 4000 4200
Wire Wire Line
	4000 4200 5650 4200
Wire Wire Line
	3900 4800 3900 4300
Wire Wire Line
	3900 4300 5650 4300
Wire Wire Line
	3800 4800 3800 4400
Wire Wire Line
	3800 4400 5650 4400
Wire Wire Line
	5000 4800 5000 4750
Wire Wire Line
	5000 4750 5400 4750
Wire Wire Line
	5400 4750 5400 6000
Wire Wire Line
	5400 6000 8050 6000
Wire Wire Line
	8050 6000 8050 4600
Wire Wire Line
	8050 4600 7450 4600
Wire Wire Line
	4900 4800 4900 4650
Wire Wire Line
	4900 4650 5500 4650
Wire Wire Line
	5500 4650 5500 5900
Wire Wire Line
	5500 5900 7950 5900
Wire Wire Line
	7950 5900 7950 4700
Wire Wire Line
	7950 4700 7450 4700
Wire Wire Line
	4800 4800 4800 4550
Wire Wire Line
	4800 4550 5600 4550
Wire Wire Line
	5600 4550 5600 5800
Wire Wire Line
	5600 5800 7850 5800
Wire Wire Line
	7850 5800 7850 4800
Wire Wire Line
	7850 4800 7450 4800
Entry Bus Bus
	2200 2000 2300 2100
Entry Bus Bus
	2200 2000 2300 2100
Entry Bus Bus
	2200 2000 2300 2100
Entry Bus Bus
	2200 2000 2300 2100
$EndSCHEMATC

A  => src/Makefile +40 -0
@@ 1,40 @@
.POSIX:

BIN = prog
CC = sdcc
CPPFLAGS =
CFLAGS = --use-non-free -mpic14 -p16f877a ${CPPFLAGS}
PIC = PIC16F877A

SRC = main.c \
      tmr0.c \
      lcd.c \
      i2c.c \
      bme280.c \
      util.c

OBJ = ${SRC:.c=.o}

all: options ${BIN}

options:
	@echo ${BIN} build options:
	@echo "CC	= ${CC}"
	@echo "CFLAGS	= ${CFLAGS}"

${BIN}: ${OBJ}
	${CC} ${OBJ} ${CFLAGS} -o $@

.c.o:
	${CC} -c ${CFLAGS} $<

flash: all
	pk2cmd -P ${PIC} -X -M -F ${BIN}.hex

erase: all
	pk2cmd -P ${PIC} -E -F ${BIN}.hex

clean:
	rm -f *.hex *.asm *.cod *.hex *.lst *.o *.core

.PHONY: all options clean erase flash

A  => src/bme280.c +210 -0
@@ 1,210 @@
#include "bme280.h"
#include "i2c.h"
#include "tmr0.h"

#define MODE_WRITE 0
#define MODE_READ 1

#define BME280_DELAY		100

#define BME280_SAMPLE_SKIP	0x00
#define BME280_SAMPLE_X1	0x01
#define BME280_FILTER_OFF	0x00
#define BME280_STANDBY_0_5	0x00
#define BME280_MODE_NORMAL	0x03
#define BME280_RESET_POWERON	0xb6

#define BME280_ADDR		0xee
#define BME280_CHIPID		0x60

#define BME280_REG_DIG_T1	0x88
#define BME280_REG_DIG_T2	0x8a
#define BME280_REG_DIG_T3	0x8c

#define BME280_REG_DIG_H1	0xa1
#define BME280_REG_DIG_H2	0xe1
#define BME280_REG_DIG_H3	0xe3
#define BME280_REG_DIG_H4	0xe4
#define BME280_REG_DIG_H5	0xe5
#define BME280_REG_DIG_H6	0xe7

#define BME280_REG_CHIPID	0xd0
#define BME280_REG_SOFTRESET	0xe0

#define BME280_REG_CTLHUM	0xf2
#define BME280_REG_STATUS	0xf3
#define BME280_REG_CTL		0xf4
#define BME280_REG_CONFIG	0xf5
#define BME280_REG_PRESS_MSB	0xf7

struct bme280_calib {
	uint16_t	dig_t1;
	int16_t		dig_t2;
	int16_t 	dig_t3;
	/* Pressure fields are not used to preserve space. */
	uint8_t 	dig_h1;
	int16_t 	dig_h2;
	uint8_t 	dig_h3;
	int16_t 	dig_h4;
	int16_t 	dig_h5;
	int8_t  	dig_h6;
};

static void	bme280_write(uint8_t, uint8_t);
static uint8_t	bme280_read8(uint8_t);
static uint16_t	bme280_read16(uint8_t);
static void	bme280_update(void);

static struct bme280_calib cal;
static int32_t adc_t, adc_h, t_fine;

static void
bme280_write(uint8_t reg, uint8_t dat)
{
	i2c_start();
	i2c_write(BME280_ADDR | MODE_WRITE);
	i2c_write(reg);
	i2c_write(dat);
	i2c_stop();
}

static uint8_t
bme280_read8(uint8_t reg)
{
	uint8_t c;

	i2c_start();
	i2c_write(BME280_ADDR | MODE_WRITE);
	i2c_write(reg);
	i2c_restart();
	i2c_write(BME280_ADDR | MODE_READ);
	c = i2c_read(0);
	i2c_stop();
	return (c);
}

static uint16_t
bme280_read16(uint8_t reg)
{
	uint16_t c;

	i2c_start();
	i2c_write(BME280_ADDR | MODE_WRITE);
	i2c_write(reg);
	i2c_restart();
	i2c_write(BME280_ADDR | MODE_READ);
	c = i2c_read(1);
	c |= i2c_read(0) << 8;
	i2c_stop();
	return (c);
}

static void
bme280_update(void)
{
	union {
		uint8_t a[4];
		uint32_t v;
	} r;

	i2c_start();
	i2c_write(BME280_ADDR | MODE_WRITE);
	i2c_write(BME280_REG_PRESS_MSB);
	i2c_restart();
	i2c_write(BME280_ADDR | MODE_READ);

	/* Ignore pressure */
	(void)i2c_read(1);
	(void)i2c_read(1);
	(void)i2c_read(1);

	r.a[3] = 0x00;
	r.a[2] = i2c_read(1);
	r.a[1] = i2c_read(1);
	r.a[0] = i2c_read(1);
	adc_t = (r.v >> 4) & 0xfffff;

	r.a[2] = 0x00;
	r.a[1] = i2c_read(1);
	r.a[0] = i2c_read(0);
	adc_h = r.v & 0xffff;

	i2c_stop();
}

int
bme280_init(void)
{
	if (bme280_read8(BME280_REG_CHIPID) != BME280_CHIPID)
		return (-1);
	bme280_write(BME280_REG_SOFTRESET, BME280_RESET_POWERON);
	tmr0_delay_ms(BME280_DELAY);
	while ((bme280_read8(BME280_REG_STATUS) & 0x01) == 0x01)
		tmr0_delay_ms(BME280_DELAY);

	cal.dig_t1 = bme280_read16(BME280_REG_DIG_T1);
	cal.dig_t2 = bme280_read16(BME280_REG_DIG_T2);
	cal.dig_t3 = bme280_read16(BME280_REG_DIG_T3);

	cal.dig_h1 = bme280_read8(BME280_REG_DIG_H1);
	cal.dig_h2 = bme280_read16(BME280_REG_DIG_H2);
	cal.dig_h3 = bme280_read8(BME280_REG_DIG_H3);
	cal.dig_h4 = ((uint16_t)bme280_read8(BME280_REG_DIG_H4) << 4) |
	    (bme280_read8(BME280_REG_DIG_H4 + 1) & 0x0f);
	if (cal.dig_h4 & 0x0800)	/* H4 < 0 */
		cal.dig_h4 |= 0xf000;
	cal.dig_h5 = ((uint16_t)bme280_read8(BME280_REG_DIG_H5 + 1) << 4) |
	    (bme280_read8(BME280_REG_DIG_H5) >> 4);
	if (cal.dig_h5 & 0x0800)	/* H5 < 0 */
		cal.dig_h5 |= 0xf000;
	cal.dig_h6 = bme280_read8(BME280_REG_DIG_H6);

	bme280_write(BME280_REG_CTLHUM, BME280_SAMPLE_X1);
	bme280_write(BME280_REG_CONFIG, ((BME280_STANDBY_0_5 << 5) |
	    (BME280_FILTER_OFF << 2)) & 0xfc);
	bme280_write(BME280_REG_CTL, ((BME280_SAMPLE_X1 << 5) |
	    (BME280_SAMPLE_SKIP << 2)) | BME280_MODE_NORMAL);

	tmr0_delay_ms(BME280_DELAY);

	return (0);
}

/* Black magic taken (stolen) from BME280's datasheet. */
int32_t
bme280_read_temp(void)
{
	int32_t v1, v2;

	bme280_update();
	v1 = ((((adc_t >> 3) - ((int32_t)cal.dig_t1 << 1))) *
	    ((int32_t)cal.dig_t2)) >> 11;
	v2 = (((((adc_t >> 4) - ((int32_t)cal.dig_t1)) *
	    ((adc_t >> 4) - ((int32_t)cal.dig_t1))) >> 12) *
	    ((int32_t)cal.dig_t3)) >> 14;

	t_fine = v1 + v2;

	return ((t_fine * 5 + 128) / 256);
}

uint32_t
bme280_read_humid(void)
{
	int32_t v = 0;

	bme280_update();
	v = (t_fine - ((int32_t)76800));
 
	v = (((((adc_h << 14) - (((int32_t)cal.dig_h4) << 20) -
	    (((int32_t)cal.dig_h5) * v)) + ((int32_t)16384)) >> 15) *
	    (((((((v * ((int32_t)cal.dig_h6)) >> 10) *
	    (((v * ((int32_t)cal.dig_h3)) >> 11) + ((int32_t)32768))) >> 10) +
	    ((int32_t)2097152)) * ((int32_t)cal.dig_h2) + 8192) >> 14));

	v = (v - (((((v >> 15) * (v >> 15)) >> 7) * ((int32_t)cal.dig_h1)) >> 4));
	v = (v < 0 ? 0 : v);
	v = (v > 419430400 ? 419430400 : v);
   
	return ((uint32_t)(v >> 12));
}

A  => src/bme280.h +10 -0
@@ 1,10 @@
#ifndef _BME280_H_
#define _BME280_H_

#include <stdint.h>

int		bme280_init(void);
int32_t		bme280_read_temp(void);
uint32_t	bme280_read_humid(void);

#endif /* _BME280_H_ */

A  => src/extern.h +25 -0
@@ 1,25 @@
#ifndef _EXTERN_H_
#define _EXTERN_H_

#define NO_BIT_DEFINES
#include <pic14regs.h>
#include <stdint.h>

/* MCU related constants */
#define _XTAL_FREQ 16000000	/* Crystal oscillator running at 16MHz */

#define BTN_PORT PORTBbits.RB0
#define BTN_TRIS TRISBbits.TRISB0
#define BTN_DEBOUNCE_TIME_MS 20

#define LED_PORT PORTBbits.RB1
#define LED_TRIS TRISBbits.TRISB1

#define OUTPUT 0
#define INPUT 1

/* Non MCU related constants */
#define NULL ((void *)0)
#define BUFSIZ (3 * sizeof(uint32_t))

#endif /* _EXTERN_H_ */

A  => src/i2c.c +67 -0
@@ 1,67 @@
#include "extern.h"
#include "i2c.h"

#define I2C_SCL TRISCbits.TRISC3
#define I2C_SDA TRISCbits.TRISC4

void
i2c_init(uint8_t mode, uint8_t slew, uint32_t freq)
{
	I2C_SCL = INPUT;
	I2C_SDA = INPUT;
	SSPCON = mode | 0x20; /* MCU as master */
	SSPCON2 = 0;
	SSPADD = (_XTAL_FREQ / (4 * freq)) - 1; /* Bus clock speed */
	SSPSTAT &= 0x3f;
	SSPSTAT = slew;
}

void
i2c_hold(void)
{
	while ((SSPSTATbits.R_W) || (SSPCON2 & 0x1f))
		;	/* nothing */
}

void
i2c_start(void)
{
	i2c_hold();
	SSPCON2bits.SEN = 1;
}

void
i2c_stop(void)
{
	i2c_hold();
	SSPCON2bits.PEN = 1;
}

void
i2c_restart(void)
{
	i2c_hold();
	SSPCON2bits.RSEN = 1;
}

void
i2c_write(uint8_t c)
{
	SSPBUF = c;
	i2c_hold();
}

uint8_t
i2c_read(uint8_t ack)
{
	uint8_t c;

	SSPCON2bits.RCEN = 1;
	while (SSPSTATbits.BF == 0)
		;	/* nothing */
	c = SSPBUF;
	i2c_hold();
	SSPCON2bits.ACKDT = ack ? 0 : 1;
	SSPCON2bits.ACKEN = 1;
	return (c);
}

A  => src/i2c.h +19 -0
@@ 1,19 @@
#ifndef _I2C_H_
#define _I2C_H_

#include <stdint.h>

#define I2C_MASTER 0x08
#define I2C_SLEW_OFF 0x80
#define I2C_SLEW_ON 0x00
#define I2C_CLK_1MHZ 1000000

void	i2c_init(uint8_t, uint8_t, uint32_t);
void	i2c_hold(void);
void	i2c_start(void);
void	i2c_stop(void);
void	i2c_restart(void);
void	i2c_write(uint8_t);
uint8_t	i2c_read(uint8_t);

#endif /* _I2C_H_ */

A  => src/lcd.c +50 -0
@@ 1,50 @@
#include "extern.h"
#include "lcd.h"
#include "tmr0.h"

#define LCD_RS PORTCbits.RC0	/* Instruction reg: 0, Data reg: 1 */
#define LCD_RW PORTCbits.RC1	/* Write: 0, Read: 1 */
#define LCD_EN PORTCbits.RC2	/* Enable read/write */
#define LCD_RS_TRIS TRISCbits.TRISC0
#define LCD_RW_TRIS TRISCbits.TRISC1
#define LCD_EN_TRIS TRISCbits.TRISC2
#define LCD_PORT_DATA PORTD
#define LCD_TRIS_DATA TRISD

void
lcd_init(void)
{
	LCD_RS_TRIS = OUTPUT;
	LCD_RW_TRIS = OUTPUT;
	LCD_EN_TRIS = OUTPUT;
	LCD_PORT_DATA = OUTPUT;
	LCD_TRIS_DATA = OUTPUT;
	LCD_RS = 0;
	LCD_RW = 0;
	LCD_EN = 0;
	
	lcd_cmd(LCD_MODE);
	tmr0_delay_ms(LCD_DELAY_STARTUP);
	lcd_cmd(LCD_CURS_ROW1);
	lcd_cmd(LCD_CURS_OFF);
	lcd_cmd(LCD_CURS_INC);
	lcd_cmd(LCD_CLEAR);
}

void
lcd_data(uint8_t c, uint8_t rs)
{
	LCD_RS = rs;
	LCD_RW = 0;
	LCD_PORT_DATA = c;
	LCD_EN = 1;
	tmr0_delay_ms(LCD_DELAY_CMD);
	LCD_EN = 0;
}

void
lcd_puts(const char *str)
{
	while (*str != '\0')
		lcd_putc(*str++);
}

A  => src/lcd.h +26 -0
@@ 1,26 @@
#ifndef _LCD_H_
#define _LCD_H_

#include <stdint.h>

#define LCD_DELAY_STARTUP 15
#define LCD_DELAY_CMD 2
#define LCD_SEL_INST 0		/* Instruction register for RS */
#define LCD_SEL_DATA 1		/* Data register for RS */
#define LCD_CLEAR 0x01		/* Clear screen */
#define LCD_CURS_ROW1 0x02	/* Set cursor on (0, 0) */
#define LCD_CURS_ROW2 0xc0	/* Set cursor on (1, 0) */
#define LCD_CURS_INC 0x06	/* Auto-increment cursor */
#define LCD_CURS_OFF 0x0c	/* Hide cursor */
#define LCD_MODE 0x38		/* 8-bit, 16x2 */
//TODO: backlight

/* Function macros */
#define lcd_putc(c) lcd_data(c, LCD_SEL_DATA)
#define lcd_cmd(cmd) lcd_data(cmd, LCD_SEL_INST)

void	lcd_init(void);
void	lcd_data(uint8_t, uint8_t);
void	lcd_puts(const char *);

#endif /* _LCD_H_ */

A  => src/main.c +137 -0
@@ 1,137 @@
#include "extern.h"
#include "bme280.h"
#include "i2c.h"
#include "lcd.h"
#include "tmr0.h"
#include "util.h"

static __code uint16_t __at (_CONFIG) __configword =
    _FOSC_HS & _WDTE_OFF & _PWRTE_ON & _LVP_OFF & _WRT_OFF & _BOREN_ON &
    _CPD_OFF & _CP_OFF;

/*
 * TODO: turn off unneeded modules (e.g tmr1..) to minimize consumption.
 */

static void	ctx_main(void);
static void	ctx_uptime_maxtp(void);
static void	print_tp(int32_t);
static void	led_blink(void);
static void	button_debounce(void);

static uint32_t	timecnt = 0;	/* Seconds passed since start */
static int	f_ctx = 0;	/* Change context */
static uint32_t	humid;		/* Current humidity */
static int32_t	tp;		/* Current temperature */
static int32_t	maxtp = -99999;	/* Max temperature */
static char	buf[BUFSIZ+1] = {0}; /* Generic buffer */

#define LCD_PUTS_INT(buf, v) do {		\
	memset(buf, 0, sizeof(buf));		\
	lcd_puts(itoa(&buf[sizeof(buf)-1], v));	\
} while (0)

static void
ctx_main(void)
{
	/*lcd_cmd(LCD_CURS_ROW1);*/
	/*lcd_puts("ID: 19390133");*/

	lcd_cmd(LCD_CURS_ROW1);
	lcd_puts("Temp: ");
	print_tp(tp);

	lcd_cmd(LCD_CURS_ROW2);
	lcd_puts("Humid: ");
	LCD_PUTS_INT(buf, humid / 1024);
	lcd_putc('.');
	LCD_PUTS_INT(buf, ((humid * 100) / 1024) % 100);
	lcd_putc('%');
}

static void
ctx_uptime_maxtp(void)
{
	lcd_cmd(LCD_CURS_ROW1);
	lcd_puts("T: ");
	LCD_PUTS_INT(buf, timecnt);

	lcd_cmd(LCD_CURS_ROW2);
	lcd_puts("Max: ");
	print_tp(maxtp);
}

static void
print_tp(int32_t tp)
{
	if (tp < 0) {
		tp = -tp;
		lcd_putc('-');
	}
	LCD_PUTS_INT(buf, tp / 100);
	lcd_putc('.');
	LCD_PUTS_INT(buf, tp % 100);
	lcd_puts("\337C   ");
}

#undef LCD_PUTS_INT

static void
led_blink(void)
{
	LED_PORT ^= 1;
	/*
	 * Increment here since this function is called every 1 sec.
	 * No need to create another timer callback.
	 */
	timecnt++;
}

static void
button_debounce(void)
{
	static uint8_t cnt = 0;

	/* Button is pressed */
	if (BTN_PORT == 0) {
		if (cnt == 0) {
			/* Actual button functionality goes here. */
			f_ctx = 1;
			cnt++;
		}
		cnt = BTN_DEBOUNCE_TIME_MS;
	} else if (cnt != 0) {
		f_ctx = 0;
		cnt--;
	}
}

void
main(void)
{
	tmr0_init();
	tmr0_set_event(&led_blink, 1000);
	tmr0_set_event(&button_debounce, 1);
	lcd_init();
	i2c_init(I2C_MASTER, I2C_SLEW_OFF, I2C_CLK_1MHZ);
	if (bme280_init() < 0) {
		lcd_puts("BME280 error");
		for (;;); /* Hang */
	}

	BTN_TRIS = INPUT;
	LED_PORT = 1; /* LED on */
	LED_TRIS = OUTPUT;

	for (;;) {
		if ((tp = bme280_read_temp()) > maxtp)
			maxtp = tp;
		humid = bme280_read_humid();
		lcd_cmd(LCD_CLEAR);
		if (!f_ctx)
			ctx_main();
		else
			ctx_uptime_maxtp();
		tmr0_delay_ms(1000);
	}
}

A  => src/tmr0.c +76 -0
@@ 1,76 @@
#include "tmr0.h"
#include "util.h"

#define TMR0_REQ_MAX 2

struct timer_req {
	ev_handler handler;	/* ISR callback */
	uint16_t rate;		/* Interval */
	uint16_t cnt;		/* Current time */
};

static void tmr0_isr(void) __interrupt;

static struct timer_req	reqs[TMR0_REQ_MAX];

static void
tmr0_isr(void) __interrupt
{
	struct timer_req *r;
	uint8_t i;

	if (INTCONbits.TMR0IF != 1)
		return;
	for (i = 0; i < TMR0_REQ_MAX; i++) {
		r = &reqs[i];
		if (r->handler == NULL)
			continue;
		if (++r->cnt == r->rate) {
			r->handler();
			r->cnt = 0;
		}
	}
	TMR0 = TMR0_DELAY;
	INTCONbits.TMR0IF = 0; /* Clear interrupt flags */
}

void
tmr0_init(void)
{
	memset(reqs, 0, sizeof(reqs));
	OPTION_REG = 0;
	OPTION_REG |= TMR0_CLK0 | TMR0_PRESCALAR_256;
	TMR0 = TMR0_DELAY;
	INTCONbits.TMR0IE = 1;	/* TMR0 Interrupt Enable */
	INTCONbits.GIE = 1;	/* Global Interrupt Enable */
	INTCONbits.PEIE = 1;	/* Peripheral Interrupt Enable */
}

void
tmr0_delay_ms(uint16_t t)
{
	while (t--) {
		while (INTCONbits.TMR0IF == 0)
			;	/* nothing */
		INTCONbits.TMR0IF = 0;
		TMR0 = TMR0_DELAY;
	}
}

int
tmr0_set_event(ev_handler handler, uint16_t rate)
{
	struct timer_req *r;
	uint8_t i;

	for (i = 0; i < TMR0_REQ_MAX; i++) {
		r = &reqs[i];
		if (r->handler != NULL)
			continue;
		r->handler = handler;
		r->rate = rate;
		r->cnt = 0;
		return (1);
	}
	return (0);
}

A  => src/tmr0.h +30 -0
@@ 1,30 @@
#ifndef _TMR0_H_
#define _TMR0_H_

#include "extern.h"

#define TMR0_CLK0 (0 << 5)		/* Use the CLK0 pin */
/*
 * Bit 3 assigns the prescalar to TMR0.
 * Bits 0-2 of OPTION_REG indicate the prescalar value. In this case,
 * 111 indicates a prescalar value of 256.
 */
#define TMR0_PRESCALAR_256 0b0111
/* 
 * We want 1ms delay @ 16Mhz with 64 prescalar, the formula is:
 *
 * 256 - ((delay * (fosc / 1000)) / (prescalar * 4)) =
 * 256 - ((1 * (16000000 / 1000)) / (256 * 4)) =
 * 256 - ((1 * 16000) / (256 * 4)) = ~240
 *
 * sdcc thinks there's an overflow here (hint: he's wrong)...
 */
#define TMR0_DELAY (256 - ((1 * (_XTAL_FREQ / 1000)) / (256 * 4)))

typedef void (*ev_handler)(void);

void	tmr0_init(void);
void	tmr0_delay_ms(uint16_t);
int	tmr0_set_event(ev_handler, uint16_t);

#endif /* _TMR0_H_ */

A  => src/util.c +27 -0
@@ 1,27 @@
#include "util.h"

/*
 * To avoid reversing the string, the caller has to provide a pointer to the
 * end of the string.
 */
char *
itoa(char *s, int n)
{
	*s = '\0';
	if (n == 0)
		*--s = '0';
	for (; n; n /= 10)
		*--s = n % 10 + '0';
	return (s);
}

void *
memset(void *dst, int v, int len)
{
	unsigned char *dst0;

	dst0 = dst;
	while (len--)
		*dst0++ = v;
	return (dst);
}

A  => src/util.h +7 -0
@@ 1,7 @@
#ifndef _UTIL_H_
#define _UTIL_H_

char	*itoa(char *, int);
void	*memset(void *, int, int);

#endif /* _UTIL_H_ */