In this article I will describe the functionality of this product and will attach a schematic with circuit descriptions, the Bill of Material and the PCB layout for building this product. I will then list the PICBASIC PRO™ Compiler code that was developed for it to work. At the end of this article, I will describe a Visual Basic application I coded for a WINDOWS PC that serves as a GUI based HMI for use with the Ultrasonic Ranger (via its USB interface) to upload data from the unit's EEPROM to the PC and to monitor and reset the date, time and alarm settings in the RTC of the unit.
FUNCTIONALITY
This product performs the following functions:
0) SLEEP MODE: The unit remains in a very low power consumption sleep mode between measurements to reduce the current load on the power supply, which is a 9vdc battery. The power switch is normally left in the on position so that a user can operate it at any time by actuating a red button to wake up the unit. The design of the unit and the code has reduced the power consumption to the point that it will operate for many weeks before discharging a 250 mAH, NiMH 9vdc battery.
1) RANGING: Upon depression of a red button on the unit, an interrupt is generated that causes the embedded microcontroller to awaken from sleep mode and to then command the ultrasonic ranging sensor (a SRF02 from Devantech) to transmit a series of ultrasonic pulses. The reflected pulses from the nearest object that lies within the direction beam of the sensor are used to calculate a time delay between the time of transmit and the reception of the reflected signals. The measured time delays for the multiple pulses are averaged to one value. This average time delay value can be used as the reported measurement in microsecs or the SRF02 can be commanded by the microcontroller to convert all time delay measurements into a range value in inches or cm before reporting. The measurement is reported in the commanded units to the microcontroller via an I2C bus. The implementation in this article uses range measurements in inches.
2) REAL TIME CLOCK: The unit contains a real-time clock (a DS1337 RTC chip with I2C Serial bus) that is programmed by the embedded microcontroller on power up with a pre-established clock time. Since the DS1337 has the ability to also be
programmed with an alarm time, the unit is also programmed at powerup to waken from sleep by an interrup from the DS1337 at the alarm time and make and report a range measurment. Default programming makes this alarm occur at midnight ccording to the firmware code described in this article. This can be changed to any alarm time by modifying the initialization portion of the code that is executed on powerup. In normal manual button depression operation, the microcontroller time tags the range measurements with the current time from the RTC at time of measurement.
3) DISPLAY: During initialization after powerup, a 2x8 character LCD displays the date and alarm setting time from the RTC as a check on the RTC's settings during initialization. It then clears the display and then displays the time and a current range measurement at time of initialization. Once initialization is completed, the unit goes into a deep sleep mode until the red button is pressed for a manual measurement or until the alarm time is reached requiring another measurement. The unit remains in deep sleep mode in between measurments.
4) DATA LOGGING: Each measurement and the time stamp for the measurement is stored in EEPROM as a 3 byte word for use in later data recovery. Usage of the EEPROM mapping by the code stores 68 sequential and unique range measurements that are time stamped. If the unit is used over a period of time and makes more than 68 measurements before the unit is interfaced with a computer via the USB and re-initialized, it will commence overwriting earlier measurements.
5) DATA RECOVERY: An external USB interface is provided to the unit. By connecting via the USB interface to a computer that contains some custom Visual Basic programming that is available for the product, any stored measurement data in EEPROM will be downloaded to the computer for further analysis and display in an EXCEL spreaqsheet. After completion of the recovery of the data log from the unit, the code then enables the computer user to reprogram the date, time and alarm settings of the RTC chip if desired. The EEPROM is erased and initialized for another data logging epoch. When the USB connection is terminated, the unit goes back into deep sleep awaiting the next measurement interrupt.
6) POWER SUPPLY: As mentioned earlier, the power supply for the unit is a snap-in, 9vdc battery. For maximum operating time, it is recommended that a NiMH, 9vdc battery be used since it can be re-charged when required. However, it will operate
for a relatively long period of time on even a non-rechargeable 9Vdc battery of low capacity as long as infrequent measurements are made.
SCHEMATIC
A copy of the schematic for the electronic circuits used in this product is attached. It consists of a labeled BATTERY/POWER REGULATOR CIRCUIT, a MICROCONTROLLER CIRCUIT, and 6 sub-circuits within the over-all MICROCONTROLLER CIRCUIT:
a. BATTERY AND POWer REGULATOR CIRCUIT: This labeled circuit, provides a regulated 5.0 vdc or 3.5 vdc output (depending on the voltage regulator chip used) for the Vdd supply to the LCD and a Vcc supply of 4.83 or 3.33 vdc (depending on the voltage regulator chip used) to the embedded controller and the rest of the circuits. The Vcc supply is derived from a Shotkky Diode in series with the Vdd supply output which also serves the purpose of isolating the battery from any voltage that may be applied to the microcontroller via the ICSP / PICkit2™
interface that is provisioned in the circuit board for field programming of the microcontroller chip.
b. MICROCONTROLLER CIRCUIT: This circuit provides for all connections to the microcontroller, including the following sub-circuits: a 2x8 pin header for internal connection to the 2 line x 8 character LCD display, a 1x6 header that connects
to the board level ICSP / PICkit2™ interface, a 1x5 pin header that connects to the internal SRF02 ultrasonic ranger sensor module, the labeled external USB interface, an internal DS1307 or DS1337 RTC labeled circuit, and an externally visible RED/GREEN LED. The LED is used by the microcontroller to flash RED 5 times when the batter voltage is detected by an HLVD routine in the code to be below 4.33 volts as a warning that the battery needs replacement or re-charging (see a separate
article on this subject at http://www.picbasic.co.uk/forum/cont...oltage-monitor) . There is also
provision of an optional circuit for mounting of a back-up Lithium Ion battery for the RTC chip that is separated from the normal 9vdc NiMH battery by diodes.
PCB LAYOUT
A PCB layout for the custom circuit board required for this product is attached. It is designed as an 8.6 square inch, 2-layer PCB.
BILL OF MATERIAL (BOM)
A BOM for this product is attached that lists the components that were used in the prototype of this product. Suggested sources and prices are included on this BOM.
PHOTOS OF FINISHED PRODUCT PROTOTYPE
A photo showing various views of the prototype of this product attached to this article, which includes labels identifying some of the features and user interfaces. Click your mouse on the photo to enlarge it for easier reading.
PICBasic PRO CODE
A complete listing of the code developed for this product is provided below. This code requires 10,248 bytes of program memory and is compatible with PICBasic Pro Compiler version 2.6. Portions of the code related to RTC operation were adapted
from code written by Tonigalea (see URL at http://www.picbasic.co.uk/forum/show...ghlight-DS1337), but modified to run on an EasyPic6 with 18F4550 MCU and a DS1337 RTC. The USB interface portions of the code were adapted from the USBdemo DTHID.pbp version 2.0 dated 11/9/2009 authored by Steve Monfette and Darrel Taylor. This code was developed and debugged on an EasyPic6 Development Board with an 18F4550 microcontroller chip installed before burning to the product's custom PCB.
Code:
'STATUS: Compiles & assembles OK with CPU clock @ 48 MHz or 16 MHz.
' USBRx window reads continously until VB6 TriggerRX button click.
' Still debugging HMI time/date/alarm correction/reset code.
'***********************************************************************
'* Name : URcode_USBversion.pbp *
'* Author : John R. Ellis *
'* Started : 03/22/2010 *
'* Version : 1.5 *
'* Notes : 1) This code was designed/devloped on an EasyPic6 board. *
'* : 2) Portions of Program extracted from: *
'* USBdemo_DTHID Steve Monfette/Darrel Taylor *
'* (see reference below) * *
'* Compiler: PICBASIC PRO Compiler 2.60 from microEngineering Labs *
'* Device : 18F2550/4550 w/ serial 2x16 LCD as installed on Proto- *
'* Board connected via Port Extension to an EasyPic6. *
'* Memory : 10,248 bytes of Program Memory required. *
'***********************************************************************
'* Ref 1): : RTC portions of this code are adapted from code written *
'* : by Tonigalea (see URL ref below), but modified to run *
'* : on an EasyPic6 with 18F4550 MCU and a DS1337 RTC: *
'*http://www.picbasic.co.uk/forum/showthread.php?t=662&highlight=DS1337* *
'***********************************************************************
'* Portions of this code are adapted from code from this reference: *
'* Ref 2): Name : USBdemo_DTHID.pbp *
'* Author : Steve Monfette/Darrel Taylor *
'* Date : 11/9/2009 *
'* Version : 2.0 *
'* Notes : This is an adaptation of mister-e's USBdemo *
'* : for DT_HIDMeant to work with mister-e's GUI *
'***********************************************************************
' -----------------------[ Program Description ]--------------------------
' PICBASIC PRO program to demonstrate operation of an LCD in 4-bit mode *
' 1) Initializes 2x16 LCD display with EasyPic6. *
' 2) Initializes DS1337 Real-time-clock. *
' 3) Takes range measurement from SRF02 Ultrasonic sensor upon *
' programmed interrupt time from DS1337 RTC & displays results *
' on 2x16 display. *
' 4) Also displays time/date at time of measurment. *
' 5) Also logs date-stamped measurement in EEPROM *
' 6) When USB connection is detected, transfers log data to host PC *
' & receives time/date corrections when sent from PC host. *
' *
'*************************************************************************
' -----------------------[ Revision History ]-----------------------------
' Version 1.0 Started on 03/22/10
' Version 1.5 Fully functional TX mode completed (06/01/10)
' ------------[ NOTES for use with EasyPic6 development board ]-----------
' Make sure that SW6.8 on the EasyPic6 is set to ON position before
' powerup for LCD's requiring backlight.
'For use with 2x16 LCD:
' - Turn on Port Expander switches SW6.1, SW6.2, SW6.3, SW6.4 & SW6.5.
' - Turn on COG LCD 2x16 switches SW10.1, SW10.2, SW10.3, SW10.4,
' SW10.5 & SW10.6.
'For interface to DS1337 RTC:
' - To provide battery backup, place a Shottky diode between the
' + battery terminal and Vcc (pin-8) of the DS1337.
' - I2C communication lines should be connected to 4.7K pull-ups.
' - INTA & INTB lines should be connected to pull-up resistsors.
' - Turn off LEDs connected to I2C communication lines.
'-----------------PDIP 18F2550/4550 Port/PIN Connections ]----------------
'I/O pin connections to the 18F4550 MCU are as follows:
'PORTA.0 (02) connected to LCD D4.
'PORTA.1 (03) connected to LCD D5.
'PORTA.2 (04) connected to LCD D6.
'PORTA.3 (05) connected to LCD D7.
'PORTA.4 (06) connected to LCD RS.
'PORTA.5 (07) connected to LCD E.
'PORTB.0 (21) connected as I2C SDA output to DS1337.
'PORTB.1 (22) connected as I2C SCL output to DS1337.
'PORTB.2 (23) connected as INT2 interrupt from pin-3 (_INTA) of DS1337 RTC.
' Also senses pushbutton for manual range measurement.
'PORTB.3 (24) connected as input from SQW/_INTB pin-7 of DS1337 RTC.
'PORTB.4 (25) RB4 connected to Green LED to indicate USB connected & power on.
'PORTB.5 (26) RB5 not connected...used during test as mainloop heartbeat LED
'PORTB.6 (27) connected as PGC for ICSP connection.
'PORTB.7 (28) connected as PGD for ICSP connection.
'PORTC.0 (11) RC0 connected to control external power to Ultrasonic sensors.
'PORTC.1 (12) RC1 connected as an output to a Red LED for battery low.
'PORTC.2 (13) RC2 connected to LCD R/W.
'PORTC.3 (14) RC3/Vbus connected to 470 pf capacitor for USB
'PORTC.4 (15) normally connected as USB D-.
'PORTC.5 (16) normally connected as USB D+.
'PORTC.6 (17) normally connected as RS232 TX.
'PORTC.7 (18) normally connected as RS232 RX.
'--------------[ Define EEPROM usage ]-----------------------------------
'09 = day_cnt ' Most recent day_cnt value
'10 = J ' Index for counting EEPROM logging address
'11 = hr ' Hour time from RTC after setting RTC
'12 = MINs ' Minutes time from RTC after setting RTC
'13 = sec ' Seconds time from RTC after setting RTC
'14 = A1hr ' Alarm1 hour time from RTC after setting RTC
'15 = A1MINs ' Alarm1 minutes time from RTC after setting RTC
'16+J = stamp ' Log Day of month date-stamp for day's range measurement
'17+J = rng0 ' Log of LSB of range for day's measurement
'18+J = rng1 ' Log of MSB of range for day's measurement
'223 ' Last legitimate entry of a log entry
'224 = ResetClk ' Record microcontroller clock Reset Flag from PC
'225 = corHr ' Corrected Hr from PC
'226 = corMINs ' Corrected MINs from PC
'227 = corSecs ' Corrected Secs from PC
'228 = corMon ' Corrected month (Mon) from PC
'229 = corDate ' Corrected Date in Month from PC
'230 = corYr ' Corrected Yr from PC
'240 = ID(0) ' LSB of device ID
'241 = ID(1) ' MSB of device ID
'242 = mon ' Month from clock
'243 = date ' Date in month from clock
'244 = yr ' Year from clock
'245 = hr ' Current hour of day from clock
'246 = MINs ' Current minute from clock
'247 = sec ' Current second from clock
'248 = rng0 ' LSB of last ultrasonic ranger measurement
'249 = rng1 ' MSB of last ultrasonic ranger measurement
'250 = ResetClk ' Record microcontroller clock Reset Flag from PC
'INCLUDE "CodeSize.pbp" 'FOR TEST ONLY...comment out otherwise
DEFINE Measure 1
;@ StartSize(LookUp) 'FOR TEST ONLY...comment out otherwise
Pause 10 ' This statement is placed at beginning of code for ICD use
Disable Debug
;-- if you un-comment these, you must comment the ones in the .inc file --
ASM ; 18F2550/4550, 8mhz crystal
__CONFIG _CONFIG1L, _PLLDIV_2_1L & _CPUDIV_OSC4_PLL6_1L & _USBDIV_2_1L
__CONFIG _CONFIG1H, _FOSC_HSPLL_HS_1H
__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_OFF_2L & _VREGEN_ON_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_512_2H
__CONFIG _CONFIG3H, _PBADEN_OFF_3H
__CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
ENDASM
'--------------[ Define Hardware / Set Registers ]------------------------
DEFINE OSC 16 ' CPU oscillator set at 16 MHz for compiler read
DEFINE I2C_SLOW 1 ' Set i2c to the standard speed
DEFINE I2C_HOLD 1 ' Enable recieving i2c device to pause communication
Include "Modedefs.Bas" ' Mode definitions for Debug,Serin/out,
' Shiftin/out, Xin/out.
INCLUDE "ALLDIGITAL.pbp" ' Sets all registers for digital ops.
' User must make sure AllDigital.pbp file
' is in same or higher directory location as
' this source code before compiling.
'DEFINE SHOWDIGITAL 1 ' When uncommented will show analog settings
' in Assembler Results window.
INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP high priority interrupts
' Allows re-entry to PBP from a High Priority
' ASM interrupt. Must have DT_INTS-18.bas
' loaded first.
'OSCCON.7 = 0 ' Clear IDLEN bit to allow SLEEP mode
' According to data sheet, must clear CONFIG2H.0 (WDTEN bit)
' in order to use WDTCON. Not clear from Data sheet how to reach
' WDTEN bit with with config fuses??
'WDTCON.0 = 1 ' Set SWDTEN bit to turn on WDT
TRISA = 0 ' PortA output connections are used for LCD interface
TRISB = %00001100 ' RB2 & RB3 set as RTC Alarm1 & Alarm2 inputs
' PORTB.2 is also an input from switch grounding
' PortB.5 is used for a mainloop Heartbeat LED output
TRISC.2 = 0 ' PortC.2 is used for the LCD R/W connection
CLEAR
;--- Setup Interrupts ----------------------------------------------------
OldBits VAR Byte
NewBits VAR byte
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
;INT_Handler USB_ACTV_INT, _ACTVIFhandler, ASM, no ; first in list
INT_Handler USB_Handler
INT_Handler INT2_INT, _Range, PBP, yes
INT_Handler HLVD_INT, _LowVolt, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
endasm
'ENABLE DEBUG ; Uncomment for DEBUGGING
' Per DT, DT_INTS already takes care of setting INTCON and RCON registers
' but this doesn't work unles INTCON2 set per below:
INTCON2 = %10000000 ' Set INT2 for falling edge (Bit4-low)
' on RTC's interrupt.
' Disable all PortB pull-ups (Bit7-high)
RTC_INT_FLG VAR INTCON3.1 'INT2 interrupt flag from RTC..DT_INTS handles
;--- Setup USB -----------------------------------------------------------
INCLUDE "DT_HID260.pbp"
DEFINE USB_VENDORID 6017
DEFINE USB_PRODUCTID 2000
DEFINE USB_VERSION 1
DEFINE USB_VENDORNAME "LodeStar Assoc. Inc."
DEFINE USB_PRODUCTNAME "FillMonitor"
DEFINE USB_SERIAL "002"
DEFINE USB_INSIZE 16 ; IN report is PIC to PC (8,16,32,64)
DEFINE USB_OUTSIZE 16 ; OUT report is PC to PIC
DEFINE USB_POLLIN 10 ; Polling times in mS, MIN=1 MAX=10
DEFINE USB_POLLOUT 10
; --- Each USB status LED is optional, comment them if not used ----------
; -- They can be assigned to any pin, and no further action is required --
DEFINE USB_LEDPOLARITY 1 ; LED ON State [0 or 1] (default = 1)
DEFINE USB_PLUGGEDLED PORTB,4 ; LED indicates if USB is connected
;DEFINE USB_TXLED PORTB,6 ; " " data being sent to PC
;DEFINE USB_RXLED PORTB,5 ; " " data being received from PC
'--- Variables & Aliases -------------------------------------------------
BATTLOW VAR BIT ' Flag that is set when battery is low
corHr VAR BYTE ' Corrected Hr from PC
corMINs VAR BYTE ' Corrected MINs from PC
corSecs VAR BYTE ' Corrected Secs from PC
corMon VAR BYTE ' Corrected month (Mon) from PC
corDate VAR Byte ' Corrected Date in Month from PC
corYr VAR BYTe ' Corrected Yr from PC
corA1hr VAR Byte ' Corrected Alarm1 hour from PC
corA1MINs VAR byte ' Corrected Alarm1 minutes from PC
corA1sec VAR byte ' Corrected Alarm1 seconds from PC
day_cnt VAR BYTE ' Counter for day number during monthly epoch
deviceID1 VAR BYTE ' Serial # of MCU (MSB)
deviceID2 VAR BYTE ' Serial # of MCU (LSB)
empty VAR BYTE ' Used as variable when empty buffer needed
stamp VAR Byte ' Stored Date stamp of measurment
ext_pwr VAR PORTC.0 ' Alias to control power to Ultrasonic sensors
I VAR Byte ' Index for loop counters
ID VAR BYTE(8) ' DeviceID array
J VAR BYTE ' EEPROM address index for storing measurements
LED_RED VAr PortC.1 ' Red LED used to indicate battery is low
LED_GRN VAR PortB.4 ' Green LED used to indicate Routine entries
LCD_Flag VAR Bit ' Flag when set indicates LCD is installed/used
New_PORTB2 VAR BYTE ' Used to poll PORTB.2 to sense incoming USB data
Old_PORTB2 VAR BYTE ' when New_PORTB2 <> Old_PORTB2.
ReportID VAR Byte ' Report ID for USB message
ResetClk VAR BIT ' Reset flag if set resets microcontroller clock
rng0 VAR w0.Byte0 ' LSB of range measurement when right justified
rng1 VAR w0.byte1 ' MSB of range measurement when right justified
SCL VAR PORTB.1 ' I2C clock pin
SDA VAR PORTB.0 ' I2C data pin
Spare_1 VAR PORTB.7 ' PGD for ICSP & Spare I/O for normal ops
Spare_2 VAR PORTB.6 ' PGC for ICSP & Spare I/O for normal op
X VAR WORD ' Used as a loop index during Main for USB
w0 var word ' W0 is the word value of the range measurement
' Constants
'==========
RTCdevice CON $D0 ' Device write address = %11010000 for DS1337 RTC
srfdevice CON $E0 ' Device address for SRF02 ultrasonic RangeFinder
ENABLE DEBUG
;--- Initialize ----------------------------------------------------------
' Set FLAGS for current configuration
BATTLOW = 1 ' Test Low Battery Flag = 0
LCD_Flag = 1 ' Set for LCD installed/used; cleared otherwise
'CCPR1L = 0 ' Not used
'CCPR2L = 0 ' Not used
'CCP1CON = %00001100 ' CCP1, PWM mode...not used
'CCP2CON = %00001100 ' CCP2, PWM mode...not used
PR2 = 249 ' 0-1000 duty range
T2CON = %00000101 ' TMR2 on, prescaler 1:4
TRISB = 0
'OUTPUT PORTC.1 ' For slider bar only..not used in this app
'OUTPUT PORTC.2 ' For slider bar only..not used in this app
' A/D converters not used for this application
'DEFINE ADC_BITS 8 ; Number of bits in ADCIN result 'Not used
'ADCON2.7 = 0 ; left justify(Change this if ADFM in diff register)
'ADCON1 = %1101 ; AN0/AN1 Analog
' Read MCU Serial Number from device ID Locations
TBLPTRU=$20 ' Address $200000
TBLPTRH=$00
TBLPTRL=$00
For i = 0 To 7
@ TBLRD*+ ; Get value and increment the address
ID(i) = TABLAT ; Store the byte as ID(i)
Next
deviceID1 = ID(0) ' MSB of MCU Device Serial Number
deviceID2 = ID(1) ' LSB of MCU Device Serial Number
deviceID1 = 0
deviceID2 = 2
WRITE 240, ID(0) ' Write fixed values to EEPROM
WRITE 241, ID(1)
'Initialize epoch indexes at time of powerup/reset
day_cnt = 0
WRITE 9, day_cnt ' Store new epoch initialized day_count
Pause 10
J = 16 ' Initialize EEPROM logging index @ start address
WRITE 10,J ' Store new epoch initialized J index
Pause 10
'Initialize LEDs to off
LOW LED_GRN
LOW LED_RED
'*******************SETUP FOR USING DS1337 Real Time Clock**************
' Setup Hardware for uart
DEFINE HSER_BAUD 115200
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 24h
DEFINE HSER_CLROERR 1
' Aliased Variables for CLock
Alarm1 VAR PORTB.2 ' Alarm1 input from DS1337 INTA (pin-3)
'Alarm2 VAR PORTB.3 ' Alarm2 input from DS1337 INTB (pin-7)
'SCL VAR PORTB.1 ' I2C clock pin..previously set
'SDA VAR PORTB.0 ' I2C data pin..previously sset
'RTCdevice CON %11010000 ' RTC device write address..already set
' This is a list of allowable clock contrl settings, one which
' must be setup in the SetTimeAndDate subroutine for intended use.
'contrl CON %00000000 ' Starts oscillar, sets the SQW/OUT to
' 1Hz pulse, no Alarm interrupt enabled.
' WORKS as intended!!
'contrl CON %00000001 ' Starts oscillator, sets the SQW/OUT to
' 1 HZ pulse, & enables INTA interrupt from
' A1F. WORKS as intended!!
'(see data sheet pg 10)
'contrl CON %00000010 ' Starts oscillator, sets the SQW/OUT to
' 1 HZ pulse, enables INTA interrupt from
' A2F. WORKS AS intended!!
'contrl CON %00000011 ' Starts the oscillator, sets the SQW/OUT
' to 1 Hz, enables INTA interrupt from A1F
' or from A2F. WORKS as intended!!
'contrl CON %000xx100 ' Starts oscillator, no interrupts enabled.
' WORKS as intended!
'contrl CON %00000101 ' Starts oscillator, enables INTA interrupt
' from A1F, INTA/SQW off. WORKS OK!
'contrl CON %00000110 ' Starts oscillator, enables INTB interrupt
' from A2F. WORKS OK!
'contrl CON %00000111 ' Starts oscillator, enables INTA interrupt
' from A1F or INTB from A2F. WORKS OK!
' Both interrupts staggered 30 secs apart.
'contrl CON %00011111 ' Starts oscillator, enables INTA interrupt
' from A1F or INTB from A2F. WORKS OK!
'contrl CON %00011001 ' Sets RS1 & RS2,
' clears INTCN to enable INTA interrupt
' from A1F with 3.2768kHz on SQW output.
' SQW output WORKS OK but INTA doesn't!
'contrl CON %00011010 ' Sets RS1 & RS2,
' clears INTCN to enable INTA interrupt
' from A2F with 3.2768kHz on SQW. WORKS OK!
' RTC Address definitions
SecReg CON $00 ' seconds address (00 - 59)
' Must set MSB of SecReg to a 0 to enable RTC
MinReg CON $01 ' minutes address (00 - 59)
HrReg CON $02 ' hours address (01 - 12) or (00 - 23)
DayReg CON $03 ' day address (1 - 7)
DateReg CON $04 ' date address (01 - 28/29, 30, 31)
MonReg CON $05 ' month address (01 - 12)
YearReg CON $06 ' year address (00 - 99)
' Alarm 1 Address definitions
Alm1sec CON $07 ' Alarm 1 seconds address (00 - 59)
Alm1min CON $08 ' Alarm 1 minutes address (00 - 59)
Alm1hr CON $09 ' Alarm 1 hours address (01 - 12) or (00 - 23)
Alm1Day CON $0A ' Alarm 1 day address (1 - 7)
' Alarm 2 Address definitions..not used in this application
'Alm2min CON $0B ' Alarm 2 minutes address (00 - 59)
'Alm2hr CON $0C ' Alarm 2 hours address (01 - 12) or (00 - 23)
'Alm2Day CON $0D ' Alarm 2 day address (1 - 7)
' Alias of Clock register addresses
ContReg CON $0E ' CONTROL register address
StatusReg CON $0F ' STATUS register address
' Clock Variables
sec VAR BYTE ' seconds
MINs VAR BYTE ' minutes
hr VAR BYTE ' hours
day VAR BYTE ' day of week (Sunday = 7)
date VAR BYTE ' date in month
mon VAR BYTE ' month
yr VAR BYTE ' year
' ALARM1 VARIABLES
A1sec VAR BYTE ' seconds
A1MINs VAR BYTE ' minutes
A1hr VAR BYTE ' hours
A1day VAR BYTE ' day
' ALARM2 VARIABLES..not used in this application
'A2MINs VAR BYTE ' minutes
'A2hr VAR BYTE ' hours
'A2day VAR BYTE ' day
GOTO JumpPoint ' Jump over all subroutines so they don't execute on powerup
' ----------------------[ START SUBROUTINES ]--------------------------
InitializeDisplay: ' Subroutine to initialize 2X16 LCD display
'=================
' Blink LED_GRN 3X to indicate entered IntializeDisplay
For i = 0 to 2
HIGH LED_GRN
Pause 500
LOW LED_GRN
PAUSE 500
Next
'-----SETUP FOR USING 2x16 LCD THAT IS INSTALLED IN EASYPIC6--------
' LCD DEFINES FOR USING 2x16 LCD with PortA in EASYPIC6
DEFINE LCD_DREG PORTA ' Use PORTA for LCD Data
DEFINE LCD_DBIT 0 ' Use lower(4) 4 bits of PORTA
' PORTA.0 thru PORTA.3 connect to
' LCD DB4 thru LCD DB-7 respectively
DEFINE LCD_RSREG PORTA ' PORTA for RegisterSelect (RS) bit
DEFINE LCD_RSBIT 4 ' PORTA.4 pin for LCD's RS line
DEFINE LCD_RWREG PORTC ' LCD read/write port
DEFINE LCD_RWBIT 2 ' LCD read/write bit
DEFINE LCD_EREG PORTA ' PORTA for Enable (E) bit
DEFINE LCD_EBIT 5 ' PORTA.5 pin for LCD's E line
DEFINE LCD_BITS 4 ' Using 4-bit bus
DEFINE LCD_LINES 2 ' Using 2 line Display
DEFINE LCD_COMMANDUS 1500' Command Delay (uS)
DEFINE LCD_DATAUS 44 ' Data Delay (uS)
' DEFINE LCD Control Constants
Line1 CON 128 ' Point to beginning of line 1 ($80)
Line2 CON 192 ' Point to beginning of line 2 ($C0)
' Test the LCD during initialization
LCDOut $fe,1:FLAGS=0:Pause 250 ' Clear Display
LCDOut $fe,Line1,"LCD TEST " ' Display on 1st line
LCDOut $fe,Line2,"Power On!!" ' Display on 2nd line
PAUSE 2000
Return
SetTimeAndDate: ' Subroutine to set current time, date and alarms
'==============
' Blink LED_GRN 2X times to indicate entered SetTimeAndDate
For i = 0 to 1
HIGH LED_GRN
Pause 500
LOW LED_GRN
PAUSE 500
Next
HIGH ext_pwr ' Temporarily turn on power to SRF02 for I2C bus use
PAUSE 70 ' Delay to let I2C bus stabilize after SRF02 turn on
' Initialize the display & clock
' Initialize clock variables to 0
yr=0:date =0:mon =0:day=0:hr=0:MINs=0:sec=0
A1sec=0:A1MINs=0:A1hr=0:A1Day=0
'A2MINs=0:A2hr=0:A2day=0
' The BCD constants below set the RTC to: 13:00:00 on 07-31-2010
hr=$13
MINs=$00
sec=$00
day=$06
mon=$07
date=$31
yr=$10
' Per MAXIM TechSupport, proper sequencing requires setting
' INTCN = 1, & A2IE=A1IE=0 before setting alarms.
I2CWrite SDA, SCL, RTCdevice, ContReg,[%00000101]
PAUSE 10
'Define ALARM1 FOR 00:00:00 & to alarm when MINs match (1/hr).
' This requires A1M1=A1M2=0 and A1M3=A1M4=1
' ($80+$A1xxx or 128d+A1xxx sets bit 7 as A1Mx = 1)
A1hr = %10000000 '$80+$00 = %10000000, for A1M3 = 1
'Bit6 must be 0 for 24 hour clock
A1MINs = %00000000 '$00 = %00000000, for A1M2 = 0
A1sec = %00000000 '$00 = %00000000, for A1M1 = 0
A1day = %10000001 '$80+$01 = %10000001, for A1M4 = 1
'DY/_DT Bit6 = 0 for using Day of month alarm
'Define ALARM2 FOR 14:01:00 & to alarm once per minute (00 secs)
'Disabled in this application
' This requires A2M2 = A2M3 = A2M4 = 1
' (A2xxx + $80 or A2xxx + 128d sets bit 7 as A2Mx = 1)
'A2hr = $14 + $80 '$14 + $80 = %10010100, for A2M3 = 1
'Bit6 must be 0 for 24 hour clock
'A2MINs = $01 + $80 '$01 + $80 = %10000001, for A2M2 = 1
'A2day = $07 + $80 '$07 + $80 = $10000111, for A2M4 = 1
'DY/_DT Bit6 = 0 for using Day of month alarm
' Per MAXIM TechSupport, reset control register for desired Alarm
' after setting alarms.
I2CWrite SDA, SCL, RTCdevice, ContReg,[%00000101]
PAUSE 10
'Set the main Time
I2CWrite SDA, SCL, RTCdevice, SecReg,[sec,MINs,hr,day,date,mon,yr]
PAUSE 10
' Write date/time setting to EEPROM
WRITE 242, Mon
WRITE 243, Date
WRITE 244, Yr
WRITE 245, hr
WRITE 246, MINs
Write 247, sec
'Set the Alarm1 Time
I2CWrite SDA, SCL, RTCdevice, Alm1sec,[A1sec,A1MINs,A1hr,A1day]
PAUSE 10
'Set the Alarm2 Time ' Alarm2 disabled for this application
'I2CWrite SDA, SCL, RTCdevice, Alm2min,[A2MINs,A2hr,A2day]
'PAUSE 10
IF LCD_Flag = 1 Then ' This code block FOR TESTING ONLY
'Test to see if Time set correctly by displaying on LCD
I2CREAD SDA, SCL, RTCdevice, SecReg,[sec,MINs,hr,day,date,mon,yr]
LCDOut $fe,1 ' Clear Display
LCDOUT $fe,Line1,"SetTime"
LCDOUT $FE,LINE2,hex2 hr,":",hex2 MINs,":",hex2 sec
Pause 2000 ' Delay so user can view display
'Test if Alarm1 set correctly by displaying stored Alarm1 time
I2CREAD SDA,SCL,RTCdevice,Alm1sec,[A1sec,A1MINs,A1hr,A1day]
LCDOut $fe,1 ' Clear Display
LCDOUT $fe,Line1,"SetAlm1"
LCDOut $FE,line2,hex2 A1hr,":",hex2 A1MINs,":",hex2 A1sec
PAUSE 2000 ' Delay so user can view display
ENDIF
' Clear STATUS and set CONTROL registers
I2CWrite SDA, SCL, RTCdevice, StatusReg,[$00]
PAUSE 10
I2CWrite SDA, SCL, RTCdevice, ContReg,[%00000101]
' Starts oscillator, no interrupts enabled.
' WORKS as intended!!
Pause 10
LOW ext_pwr ' Turn off power to the SRF02 at end of I2C use.
' This statement will distort the I2C bus & ext_pwr must be set
' HIGH again before any attempts are made to use the I2C bus.
Return
DisplayDateTime ' Subroutine to display date/time on LCD
'==============
LCDOut $fe,1 ' Clear Display
HIGH ext_pwr ' Temporarily turn on SRF02 power for I2C bus use
PAUSE 70 ' Delay to let I2C bus stabilize after SRF02 turn on
I2CREAD SDA, SCL, RTCdevice, SecReg,[sec,MINs,hr,day,date,mon,yr]
LCDOUT $fe,Line1,Hex2 mon,"/",hex2 date,"/", hex2 yr
LCDOUT $fe,Line2,hex2 hr,":",hex2 MINs,":",hex2 sec
LOW ext_pwr ' Turn off power to SRF02 until I2C bus is needed
Pause 2000
LCDOut $fe,1 ' Clear Display
Return
' ----------------------[ END OF SUBROUTINES ]--------------------------
JumpPoint:
' This block FOR TEST ONLY...comment out for ops.
'rng0 = 8 ' Initializes for data set
'date = 0
'For X = 16 To 220 Step 3 ' Write 45 ea 3 byte data sets to EEPROM
' Max EEPROM index is $DC or dec 220
'date = date +1
'rng0 = rng0+1
'rng1 = 0
'WRITE x, date ' Log Day of month date-stamp
'WRITE x+1, rng0 ' Log LSB of range for day's measurement
'WRITE X+2, rng1 ' Log MSB of range for day's measurement
'NEXT
'Setup for starting Main Program
' Initialize LCD if installed before starting main loop?
IF LCD_Flag = 1 Then GOSUB InitializeDisplay
GOSUB SetTimeAndDate ' Set RTC time/date before starting mainloop
' Also turns SRF02 power off to save battery
' until I2C bus is needed again.
' This block is required if MCU has undergone a POR
' Read last date/time stored in EEPROM in case of POR or MCU reset
'Read 242, Mon
'Read 243, Date
'Read 244, Yr
'Read 245, hr
'Read 246, MINs
'Read 247, sec
'Write reset date/time to RTC
'I2CWRITE SDA, SCL, RTCdevice, SecReg,[sec,MINs,hr,day,date,mon,yr]
'PAUSE 10
IF LCD_Flag = 1 Then ' This code block FOR TESTING ONLY
' Comment out for ops.
LCDOut $fe,1' Clear Display
LCDOUT $fe,Line1,"Entered"
LCDOUT $fe,Line2,"JumpPoint"
' Display Date/Time on LCD
GOSUB DisplayDateTime
ENDIF
' HIGH again before any attempts are made to use the I2C bus..
' Enable the interrupts that are to be active during main loop.
@ INT_ENABLE INT2_INT ; enable external (INT) interrupts
ENABLE DEBUG
'--------------------[ Begin Main Program Loop ]-------------------------
;@ StartSize(MainLoop) ; FOR TEST ONLY
Main:
GOSUB DisplayDateTime
' Store current date/time in EEPROM
WRITE 242, Mon
WRITE 243, Date
WRITE 244, Yr
WRITE 245, hr
WRITE 246, MINs
Write 247, sec
' BufferOut (PIC to PC) Data Structure
' BufferOut(0) = 0, must always be zero as valid Report ID
' BufferOut(1) = DeviceID1 or MSB of Device Serial Number
' BufferOut(2) = DeviceID2 or LSB of Device Serial Number
' BufferOut(3) = mon
' BufferOut(4) = date
' BufferOut(5) = yr
' BufferOut(6) = hr (Pic hours time)
' BufferOut(7) = MINs (Pic minutes time)
' BufferOut(8) = sec (Pic seconds time)
' BufferOut(9) = stamp
' BufferOut(10) = rng0
' BufferOut(11) = rng1
' BufferOut(12) = BATTLOW (Low Battery Flag)
' BufferOut(13) = n/a ..0
' BufferOut(14) = n/a ..0
' BufferOut(15) = n/a ..0
' BufferOut(15) must be zero for sending data buffers (1) thru (12)
' ...else must send a text string with Buffer(15) = 1
'FOR X = 0 to 5 ' Send data set about one/sec
@ ON_USBRX_GOSUB _HandleRX
'NEXT X
IF J > 222 THEN ' If reached maximum EEPROM usage location...
J = 16 ' ..reset pointer to start of range data
Endif
READ j, stamp ' Read date stamp of measurment
READ J+1, rng0 ' Read range measurement from EEPROM
READ J+2, rng1
Pause 10
J = J + 3
' Send Data to PC
' Send device ID to PC
' Send current Date/Time to PC
' Send each EEPROM stored range measurement to PC
' Send current BATTLOW indicator to PC
ARRAYWRITE USBTXBuffer,[0,deviceID1,deviceID2,mon,date,yr, _
hr,MINs,sec,A1hr,A1mins,A1sec,BATTLOW,stamp,0,0]
GOSUB SendIfReady
' Place code here to put MCU and Ultrasonic Ranger in SLEEP mode.
' while waiting for clock or USB interrupt to wakeup from SLEEP mode.
' If USB is un-plugged, put MCU in deep sleep to save power.
' If the USB is still Plugged, no sense putting PIC to sleep because it
' will just wake up again in 1ms or less.
' The ACTVIE enable bit is already enabled by DT_HID.
' You don't need to do anything with it before going to sleep.
'IF !Plugged THEN ' Go into deep sleep
'UCON.1 = 0 ' Clear the SUSPEND bit on the USB module
'ENDIF
' Perform following steps to save power during Sleep mode
CVRCON = %00000000 ' Set Voltage Reference for min. power consumption
' Disable CVref during Sleep to save power
'ADCON1= %00000000 ' Set PortA to Analog I/O to save power during Sleep.
' Above statement cannot be left to operate for some
' reason or else Alarm1 interrupt occurs continuously.
CMCON = %00000111 ' Disable comparators
HLVDCON = %00000000' Disable HLDV register
TRISB = %11111111 ' Set all PORTB pins to inputs
TRISC = %11111111 ' Set all PORTC pins to inputs
PortA = %11111111 ' Set TOCK1, MCLR & all PortA pins High before Sleep
' to save power
PortB = %11111111 ' Set all Port B & C pins High to save power
PortC = %11111111
Disable DEBUG
@ SLEEP
@ NOP
' Microcontroller is in Sleep State awaiting next interrupt from RTC or USB
GOTO Main
;@ EndSize(MainLoop) ; FOR TEST ONLY
;--- Send Data if Plugged and ready, otherwise discard -------------------
SendIfReady:
IF Plugged AND TX_READY THEN DoUSBOut
RETURN
;--- Wait till Ready to send or until unplugged --------------------------
WaitToSend:
WHILE Plugged and !TX_READY : WEND
IF TX_READY THEN GOSUB DoUSBOut
RETURN
;---- Receive incoming data...PORTB LEDS & corrected time/date -----------
HandleRX:
;@ INT_DISABLE INT2_INT ; disable external (INT) interrupts
IF LCD_Flag = 1 Then ' This code block for testing only
LCDOut $fe,1' Clear Display
LCDOUT $fe,Line1,"Entered"
LCDOUT $fe,Line2,"HandleRX"
Pause 1000 ' Delay for user to view LCD
ENDIF
' BufferIn (PC to PIC) Structure
'BufferIn(0) = ReportID => always 0
'BufferIn(1) is sent by PC as PORTB settings but used as a Flag
'ResetClk = BufferIn(1) ' PORTB is Reset flag..if set restarts MCU clock
'corHr = BufferIn(2) ' Corrected Hr setting from PC
'corMINs = BufferIn(3) ' Corrected MINs setting from PC
'corSecs = BufferIn(4) ' Corrected Secs setting from PC
'corMon = BufferIn(5) ' Corrected Mon setting from PC
'corDate = BufferIn(6) ' Corrected Date from PC
'corYr = BufferIn(7) ' Corrected Yr from PC
'corA1hr = BufferIn(8) ' Corrected Alarm1 hour from PC
'corA1MINs = BufferIn(9)' Corrected Alarm1 minutes from PC
'corA1sec = BufferIn(10)' Corrected Alarm1 seconds from PC
' Receive ResetClk and corrected FMReset flag/time/date from PC
ARRAYREAD USBRXBuffer,[ReportID,ResetClk,corHr,corMINs,corSecs,corMon, _
corDate,corYr,corA1hr,corA1MINs,corA1sec,empty,empty,empty,empty,empty]
IF ReportID = 0 Then ' Check for valid RX report
IF ResetClk = 1 Then ' Check if time correction sent
' Convert Decimal -> Hex coded time data
mon = (corMon DIG 1) * $10 + (corMon DIG 0)
date = (corDate DIG 1) * $10 + (corDate DIG 0)
yr = (corYr DIG 1) * $10 + (corYr DIG 0)
hr = (corHR DIG 1) * $10 + (corHR DIG 0)
MINs = (corMINs DIG 1) * $10 + (corMINs DIG 0)
sec = (corSecs DIG 1) * $10 + (corSecs DIG 0)
A1hr = A1hr + $80 ' Set Alarm1 to interrupt every 24 hours
A1hr = (corA1hr DIG 1) * $10 + (corA1hr DIG 0)
A1MINs = (corA1MINs DIG 1) * $10 + (corA1MINs DIG 0)
A1sec = (corA1sec DIG 1) * $10 + (corA1sec DIG 0)
Write 224,ResetClk ' Record Reset flag state in EEPROM
WRITE 225,mon ' Update PIC date/time from PC corrections
WRITE 226,date
WRITE 227,yr
WRITE 228,hr
Write 229,MINs
Write 230,sec
WRITE 231,empty
'Set the corrected time/date
I2CWrite SDA, SCL, RTCdevice, SecReg,[sec,MINs,hr,day, _
date,mon,yr]
PAUSE 10
'Set the Alarm1 Time (1 x every 24 hours)
I2CWrite SDA, SCL, RTCdevice, Alm1sec,[A1sec,A1MINs,A1hr]
PAUSE 10
LCDOut $fe,1' Clear Display
LCDOUT $fe,Line1,"SetAlm1"
LCDOut $FE,line2,hex2 A1hr,":",hex2 A1MINs,":",hex2 A1sec
PAUSE 2000 ' Delay so user can view display
ENDIF
Endif
' Read back time setting for verification
I2CREAD SDA, SCL, RTCdevice, SecReg,[sec,MINs,hr,day,date,mon,yr]
LOW ext_pwr ' Turn off power to the SRF02 at end of display.
' This statement will distort the I2C bus and ext_pwr
' must be set HIGH again before any attempts are made to
' use the I2C bus.
' Send RTC corrected time to PC as verification of corrections
ARRAYWRITE USBTXBuffer,[0,deviceID1,deviceID2,mon,date,yr, _
hr,MINs,sec,A1hr,A1Mins,A1sec,BATTLOW,stamp,0,0]
'hr,MINs,sec,A1hr,A1MIns,A1sec,BATTLOW,stamp,rng0,0]
GOSUB SendIfReady
' If ResetClk = 1, put code here to reset EEPROM memory index to J=16
' for new logging epoch .
;@ INT_ENABLE INT2_INT ;re-enable external (INT) interrupts
return
'---------------------[ACTVIF - interrupt handler]------------------------
ACTVIFhandler:
IF UCON.1 THEN UCON.1 = 0 ' Clear the SUSPEND bit to wakeup USB module
@ INT_RETURN
'--------------------[ Range - interrupt handler ]------------------------
Range:
Enable Debug
IF LCD_Flag = 1 Then ' This code block FOR TESTING ONLY
LCDOut $fe,1' Clear Display
LCDOUT $fe,Line1," Entered"
LCDOUT $fe,Line2," Range:"
ENDIF
' Reset registers from SLEEP power save state to operational state
TRISA = 0 ' PortA output connections are used for LCD interface
TRISB = %00001100 ' RB2 & RB3 set as RTC Alarm1 (Alm1) & Alarm2 inputs
' PORTB.2 is an Alm1 interrupt or SW1 grounding input
' PORTB.4 is used during test as a Green LED heartbeat
' and as a USB connected indicator during ops
TRISC.1 = 0 ' PORTC.1 used during test as a RED LED output
TRISC.2 = 0 ' PortC.2 is used for the LCD R/W connection
ADCON1= %11111111 ' Set PortA to Digital I/O after SLEEP mode.
' Blink LED_GRN 1X to indicate entered Range ISR
HIGH LED_GRN
Pause 500
LOW LED_GRN
PAUSE 500
' Test for low battery condition that causes Vdd to go below 3.3 vdc
' Setup registers for HLVD module to support low voltage interrupt
' Step 1-Disable the module by clearing HLVDCON.4
HLVDCON.4 = 0 ' Implement Step 1
' Step2 HLVD3:HLVDL0=1000 'Set the trip point at Vdd=3.39 vdc
' Step3 HLVDCON.7=0 'Set VDIRMAG=0 to detect low voltage transition
' Step4 HLVDCON.4=1 'Enable the HLVD module
HLVDCON = %00011000 'Implements Steps 2-4
' Clear the HLVDIF interrupt flag (PIR2<2>)
PIR2.2 = 0
' Setup the interrupt and an ISR in your code and enable the interrupt
' where you want to test for low voltage
@ INT_ENABLE HLVD_INT ; enable HLVD interrupt
' If low voltage exists a HLVD interrupt will take place here and
' the ISR will blink the low voltage warning LED 5x.
HIGH ext_pwr ' Temporarily turn on power to SRF02 for I2C bus use
PAUSE 70 ' Delay to let I2C bus stabilize after SRF02 turn on
'DEFINE WRITE_USED 1 'Required if only writing WORD variables in v2.6
' Update day counter and address offset for day's measurements
READ 9,day_cnt ' Test if EEPROM data has been captured
' & cleared by PC & new monthly epoch
' started.
day_cnt = day_cnt + 1 ' Increment day counter
Write 9,day_cnt 'Update contents of day_count memory address
Pause 10
If J >= $DF Then ' Max logging EEPROM memory address is 223
J = 16 ' If allocated EEPROM already used, start over
ENDIF
' Make SRF02 Range Measurement
I2CWRITE SDA,SCL,$E0,0,[80]' Request start of ranging in inches
pause 100 ' Wait for ranging to finish
I2CREAD SDA,SCL,$E0,2,[rng1,rng0] ' Get ranging results
WRITE 240,Word w0 ' Write range to EEPROM
' Display time & range measurement on LCD display in inches
IF LCD_Flag = 1 Then ' This code block for testing only
LCDOut $FE,1:FLAGS=0:Pause 250 ' Clear Display
I2CREAD SDA, SCL, RTCdevice, SecReg,[sec,MINs,hr,day,date,mon,yr]
LCDOUT $fe,1
LCDOUT $fe,Line1,Hex2 mon,"/",hex2 date,"/",hex2 yr
LCDOUT $fe,Line2,hex2 hr,":",hex2 MINs,":",hex2 sec
Pause 200 ' Allow Time for user to view
LCDOUT $FE,1
LCDOut $FE,Line1,"Range:" ' Display on 1st line
LCDOut $FE,Line2,#w0," in." ' Display on 2nd line
ENDIF
PAUSE 3000 ' Allow Time for user to view
' Clear STATUS register & Alarm flags..ready for next interrupt
I2CWrite SDA, SCL, rtcdevice, StatusReg,[$00]
LOW ext_pwr ' Turn off power to the SRF02 at end of display.
' This statement will distort the I2C bus and ext_pwr
' must be set HIGH again before any attempts are made to
' use the I2C bus.
' Store range as date-stamped value in EEPROM
WRITE J+1,WORD w0 'Store day's range in EEPROM
PAUSE 10
Write J,date ' with day of month date-stamp
PAUSE 10
' Step pointer to next logging address in EEPROM
J = J + 3
WRITE 10,J 'Update contents of J index EEPROM memory address
Pause 10
PAUSE 470 ' Delay to permit I2C bus to stabilize after SRF02 off
@ INT_DISABLE HLVD_INT
Disable debug
' Resume Main Program
@ INT_RETURN
LowVolt:
BATTLOW = 1 ' Set low battery warning flag
' Blink LED_RED 5X to indicate Low Battery voltage detected
For i = 0 to 4
HIGH LED_RED
Pause 500
LOW LED_RED
PAUSE 500
Next
' Resume Main Program
@ INT_RETURN
End ' Safety measure to insure program stops if reaches here
;@ EndSize(LookUp) ; FOR TEST ONLY
;@ LibrarySize ; FOR TEST ONLY
;@ UserSize ; FOR TEST ONLY
;@ TotalSize ; FOR TEST ONLY
'------------------{ End of Interrupt Handlers }-------------------------
I also developed a Visual Basic coded application to run on a PC so that the user could interface the PC to the unit via its USB interface in order to upload data from the unit's EEPROM and to monitor/reset the time, date, and alarm settings of the RTC in the unit. A screen snapshot of this application is shown in an attachement. I consider the rights to this code to be copy righted to our Company, so I am not including the code in this article. However, anyone who is interested in getting the code for this interface can contact me by a Forum Personal Message and I will then collaborate with you by email to possibly issue you a license for use of the code.
If you have any questions regarding this project, contact me with a message via the Forum Private Messages feature.
/s/ John Ellis


Menu
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
one last update:
jackberg1 - 1st November 2025, 17:11added an PGM Sw on RA3
to edit the baud rate:
turn off the LCD display, press & hold the PGM sw, turn on the LCD
line 1 will show "Press to Select" , line 2 : "Baud Rate:"...