' VOLTAGE MONITOR is an unusual circuit in that the monitoring is done backwards!
' There are situations when you want to monitor your own battery voltage and
' shut down the circuit at a critical voltage. The program gives you a 3 digit
' output from "430" (+4.30 volts) to "600" (+6.00 volts) which makes it easy to
' act on just about any voltage. The beauty of the program is in its ability to
' accurately calculate an offset for a voltage reference since they are all
' different when you look at the exact reference voltage, (eg. a 3.3v regulator
' can be as low as 3.247 volts which would throw off your reading significantly).
' The only critical part of this circuit is during the actual programming. You
' must ensure you are powering the circuit with exactly 5.00 volts! After that,
' it is fully calibrated to read any voltage at any time. Accuracy AND display
' resolution down to 1/100 volt!
' The conventional method for doing this trick would require using the 1 and only
' Vref pin (GPIO.1) on the 12F675 and another GPIO pin for the ADC reading.
' That's too many pins, plus, you can't IN CIRCUIT PROGRAM if you have a voltage
' constantly going to GPIO.1's "CLOCK" pin. You would have to disconnect this
' voltage source every time you dump a new program with this routine attached.
' Obviously, this is not a good way to go.
' The other method would be to power the chip with an LDO (Low Drop Out) regulator.
' A great Vreg is the LM1117 at 3.3v that will stay regulated down to 4.37 volts
' of course "brown-out" is to be disabled and you need to use two 1% resistors to
' form an accurate voltage divider for the input. Remember that the voltage
' reference chip (LM1117) would be powering the chip so that means that the 1024
' steps of the 10-bit ADC can not go above 3.3 volts. Because the +5v battery is
' over this ADC ceiling of 3.3 volts, you have to give the ADC input something
' less via the divider network. This is still not a great way to monitor voltage.
' Here's a better way to monitor your own voltage using only an inexpensive LDO
' 3.3 volt regulator (LM-1117), only one pin (any of the 6 available), and a few
' lines of code. Of course you must have a PIC with EEPROM. This routine was
' written specifically for the 12F675 since there are so few pins to work with.
' First set the ADCON0 to use Vdd for the 'reference'. And yes, it'll be changing
' all the time which in turn, changes the 10-bit scale. Hang-on... it gets real
' simple, real fast. This is where things go backwards. The uP reads the +3.3v
' all the time and never changes, however the ADC result will change because the
' ratio of the ADC ladder is changing due to Vdd changing! This is what's backwards.
' There are three "knowns" or "givens" so we can easily solve for the fourth.
' The three "givens" are: "REFERENCE" at 3.3 volts, "RESOLUTION" at 1024 and the
' "ADC" reading. All we need to do is solve for the 4th or "X". The trick is to
' use a little high school math to simply "Solve for X". This is not complicated1
' ADC Resolution "X"
' -------------- : ------------------
' ADC Result Voltage Reference
' Do the typical "cross multiply" to get a one line formula of:
' (Resolution) x (Voltage Reference) = (ADC Result_x)
' Now to plug in some numbers and divide by the "X":
' (This example of all four sections filled in equates to a +5.00 volt battery)
' 1024 "X"
' ------ : ------
' 665 3.3 (665 is an ADC result of an exact 5 volt power supply)
' Now we have 665_x = 3325. Now solve for X by dividing 3325 by 665 = +5.00v
' Since the RESOLUTION and VOLTAGE REFERENCE don't change we have a constant of
' 3325 and only need one line of code after the ADC finishes, but we're also
' dealing with a decimal point which we can't work with. The section below
' labeled "Calculate" does repetitive division using the "//" (modulus) function.
' It doesn't give you the digits to the right of the decimal, rather, you get
' what's left over from the first division as a whole number. You then do it
' again and again to get three whole numbers. I've multiplied the first digit by
' 100 to make room for two "place settings" for simple addition at the end of a
' "tens" digit (the second division) and lastly, the third digit being the "units"
' We jus add 'em right up. If the number is +4.27 volts, the three digits would
' be "400" + "20" "7". Your program just looks for the three digits to manipulate
' when to act on any voltage. Simple!
' This program will create an "offset" to compensate for one of the "knowns" that
' really IS NOT a great known... the voltage regulator! It can vary significantly
' since the spec is quite loose for our purposes, however, it will not vary once
' you have it in circuit. The problem is you can't rely on the rated 3.3 volt
' value. This is why we will run the calibration step in the middle of the program
' on the VERY FIRST run through. It will create an offset and store it in memory
' for any subsequent cold start. Because the actual programming is critical on
' this calibration step, you MUST verify you have a very solid +5.00 volts on the
' chip. In effect, the program assumess it's getting 5 volts during the routine.
' That's about it... the last few notes are for connections to the chip, etc. If
' you have any feedback or questions, please email to Frank Miller at
' [email protected]
' NOTE: Before dumping the program to the 12F675, make sure you have EXACTLY +5v
' on the board since the calibration step is run first to correct the variance
' on the 3.3 volt regulator. This "offset" value is subsequently put into EEPROM
' for read-back on any future power-up, maintaining accurate voltage readings.
' If you notice your voltage readout is off a 'tad' from your volt meter reading
' it means your programming voltage was off by that same amount.
' LCD is SEETRON (Scott Edwards 4-Line LCD Serial LCD backpack) and powered
' from the Epic programmer. (It's ok... not much of a load!) You can't easily
' use the incoming 5v supply to power the LCD because when the supply
' volts drop below 4.6v, the LCD gets goofy.
' CONNECTIONS TO IC PINS:
' Pin 2: LCD serial backpack
' Pin 3: LM-1117 Low Drop Out voltage regulator
' For demonstration purposes, you'll notice that the progam is using 462 bytes
' of space, almost half of the 1000 total, however, in use there is no need for
' knowing this info, so the program space drops dramatically in half.
Code:
'**************************************************************** '* Name : 12F675 One Pin Voltage Monitor.BAS * '* Author : Frank Miller "Pulsar" * '* Email : [email protected] * '* Date : 7/30/2004 * '* Version : 1.0 * '**************************************************************** '------------------------------------------------------------------------------- VARIABLES: Sample var word ' ADC voltage reading (Pin 3 set by ADCON0) Group var word ' Collection of 20 ADC readings to average Base var word ' Sample voltage reading x 5 volts Volts var WORD ' Manipulated as a 2 digit reading (46 = +4.6v) Volts_1 var word ' 100's (1st voltage digit) Volts_2 var word ' 10's (2nd voltage digit) Volts_3 var word ' 1's (3rd voltage digit) Remain var word ' Remainder used loop_cnt var byte ' Used in ADC routine to capture 20 readings LCD var GPIO.5 ' 4-Line "Scott Edwards LCD" backpack on pin 2 TRISIO = %010000 ' LCD (pin 1 = gpio.5) and Vref (pin 3 = gpio.4) eeprom 0, [0, 0] ' Program forces first 2 memory locations to "0" LCD_SETUP: ' Print labels once for a flicker-free display SEROUT LCD, 4, [12, 14] ' 4 = baud, 12 = clear screen, 14 = backlight on serout LCD, 4, [16, 144, " BASE = "] ' 16 = put cursor at "144" location serout LCD, 4, [16, 164, "SAMPLE = "] ' 20 characters per line serout LCD, 4, [16, 184, " VOLTS = "] ' 4th line would start at "204" '--------------------------------------------------------------------------- ANSEL = %00110010 ' Analog Select Register (page 42) ' MSB 0 = n/a "0" ' 0 = FRC select (bit 3) "011" ' 1 = FRC select (bit 2) ' 1 = FRC select (bit 1) ' 0 = analog input select (bit 4 of 4) "0010" ' 0 = analog input select (bit 3 of 4) ' 1 = analog input select (bit 2 of 4) ' 0 = analog input select (bit 1 of 4) '--------------------------------------------------------------------------- ADCON0 = %10001101 ' ADC input on GPIO.4/AN3/pin3 (page 41) ' MSB 1 = Right Justify "1" ' 0 = Vdd as voltage reference "0" ' 0 = n/a "00" ' 0 = n/a ' 1 = select channel 03 (bit 2 of 2) "11" ' 1 = select channel 03 (bit 1 of 2) ' 0 = conversion status (see routine) "0" ' LSB 1 = A/D converter module is on "1" '------------------------------------------------------------------------------- ADC: Let Sample = 0 ' Clear any prior values Let Group = 0 for loop_cnt = 1 to 20 ' Take 20 readings for better accuracy ADCON0.1 = 1 ' Setup for manual ADC technique NOT_DONE: if ADCON0.1 = 1 then not_done ' Waiting for completion of cycle pause 10 ' Give the reading a little settling time sample.highbyte = ADRESH Sample.lowbyte = ADRESL pause 10 let Group = Group + Sample ' Collecting 20 samples next loop_cnt ' Continue back up for another reading let sample = Group/20 ' Accurate averaged reading to work with '------------------------------------------------------------------------------- CHECK_CALIBRATION: ' Check for a stored value for BASE Read 0, base.byte0 ' Read EEPROM memory locations 0 & 1 to form read 1, base.byte1 ' a 16-bit word from 2 bytes for "BASE" value if base = 0 then ' If nothing there, do the calibration Base = sample * 5 ' Sample x 5! Set power supply exactly to 5v! Write 0, BASE.byte0 ' Put lower BASE value into EEPROM address 0 write 1, base.byte1 ' Put higher BASE value into EEPROM address 1 endif ' End of capturing the BASE value '------------------------------------------------------------------------------- CALCULATE: Let Volts_1 = Base / sample ' This is the FIRST of three digits Let Volts_1 = Volts_1 * 100 ' Make a place holder for 2nd & 3rd digits Let remain = base // sample * 10 ' Get the modulus (//) and multiply x 10 '------------------------------- Let Volts_2 = Remain / sample ' This is the SECOND of three digits Let Volts_2 = Volts_2 * 10 ' Make a place holder for 2nd & 3rd digits let remain = remain // sample * 10' Get the modulus (//) and multiply x 10 '------------------------------- Let Volts_3 = remain / Sample ' This is the THIRD of three digits Let Volts=Volts_1+Volts_2+volts_3 ' 3-digit number with 1/100 volt accuracy DISPLAY: serout LCD, 4, [16, 153, #base] serout LCD, 4, [16, 173, #Sample] serout LCD, 4, [16, 193, #volts] goto adc
Re: CAN header and EXT asm question
Interface board with SPI controlled MCP 2515 and line driver to use with non CAN enabled PIC's
retepsnikrep Yesterday, 08:34https://www.aliexpress.com/item/1005006850683509.html
Line driver to use with CAN enabled PIC's....