ADC Hex converision questions......
Hello!
Im havin fun which is the important part!
Anyway.
The ADC0831 code is the heart of my current hack. I have modified it and added buzzers lights relays warnings and an LCD. It pretty cool. Of course I want to apply my new found Voltage monitor to a 12vdc system. I knew Id have to tackle the conversion issue since I will be using 5Vref. So off I went with my 8th grade math skillz, parallax basic stamp forum and google.
The stock code can be found on pages 156 -157 in Stamp works. Please note the $139c value for Cnts2Mv. The comment says that 5000 / 255 = 19.6. Awesome. I don't know Hex from a hole in the wall so I figured all of this was true. Using this information I came up with $1388 for the hex value. Curious, I plugged it in and now my display reads 4980. Hmmmm. Off to study Hex for a few hours......... I stumbled upon some awesome code while perusing the forums from Tracy Allen and hacked it up to help me solve the problem. Here it is...
After hours with various beans and pieces of paper I discovered that If I add 20 to my targetV variable (now MultV) I get the desired output for finding the HEX value.
I have figured out what the Hex conversion for 12v is. I think its $2f10. Why is the question. Why do I have to add 20 to the HEX value to get my targeted number.
Here is the Actual code Im using. Its original skeleton is the code from the book.
My code works so far but why? lolz. you guys are great!
Im havin fun which is the important part!
Anyway.
The ADC0831 code is the heart of my current hack. I have modified it and added buzzers lights relays warnings and an LCD. It pretty cool. Of course I want to apply my new found Voltage monitor to a 12vdc system. I knew Id have to tackle the conversion issue since I will be using 5Vref. So off I went with my 8th grade math skillz, parallax basic stamp forum and google.
The stock code can be found on pages 156 -157 in Stamp works. Please note the $139c value for Cnts2Mv. The comment says that 5000 / 255 = 19.6. Awesome. I don't know Hex from a hole in the wall so I figured all of this was true. Using this information I came up with $1388 for the hex value. Curious, I plugged it in and now my display reads 4980. Hmmmm. Off to study Hex for a few hours......... I stumbled upon some awesome code while perusing the forums from Tracy Allen and hacked it up to help me solve the problem. Here it is...
'{$STAMP BS2sx}
'{$PBASIC 2.5}
' ----------[ revision history ]------------------------------------------------
' Tracy Allen, [URL="http://www.emesystems.com"]www.emesystems.com[/URL] when?
' Randy Cookson Hacked it up on July 2, 2014
' This awsome Tracy Allen code was hacked up and reconfigured to find the HEX
' value for the conversion of the 255 bit result from the ADC0831 reading 5Vref to show the 12vdc scale on the debug
' and LCD. I got close. I have no Idea why the 0831 code used 5020 or #139c to
' get the terminal to show 5000 which is actully = $1388 Where did the 20 Hex points come from?
idx VAR Byte
precision VAR Word
Hexcnt VAR Word
hexnum VAR Word
MultV VAR Word
bitV VAR Word
targetV VAR Word
targetHEX VAR Word
result VAR Word
com VAR Byte
main:
DEBUG CLS
DEBUG "First enter number of decimal places desired: "
DEBUGIN DEC precision
DEBUG CR
DEBUG CLS, "Enter highest bit division # ie. 8 bit would be 255 "
DEBUGIN SNUM bitV ' retrieve number in any format
DEBUG CLS, CRSRXY, 6,0, "Decimal bit value:... ", DEC bitv
DEBUG CRSRXY, 0,2, "Enter desired display result. ie. 5000 "
DEBUGIN SDEC targetV
DEBUG CRSRXY,0,2,CLREOL
DEBUG CRSRXY, 6,1, "Target Value entered is:.. ", DEC targetV ,CR
MultV = targetV + 20 '<<<<<<<< CRITICAL WTF CODE HERE
DEBUG CRSRXY, 6,2,DEC targetV," / ",DEC bitV," = ", DEC targetV/bitV,"."
' main digit kicker outer...
FOR idx=1 TO precision-1
targetV=targetV//bitV*10
DEBUG DEC1 targetV/bitV
NEXT
DEBUG DEC1 (targetV//bitV*10+5/bitV),CR,CR ' round off final digit
DEBUG CRSRXY, 0,8, HEX MultV
After hours with various beans and pieces of paper I discovered that If I add 20 to my targetV variable (now MultV) I get the desired output for finding the HEX value.
I have figured out what the Hex conversion for 12v is. I think its $2f10. Why is the question. Why do I have to add 20 to the HEX value to get my targeted number.
Here is the Actual code Im using. Its original skeleton is the code from the book.
' {$STAMP BS2sx}
' {$PBASIC 2.5}
'
' =========================================================================
' -----[ Program Description ]---------------------------------------------
'
'Battery monitory with LCD display.
'--------[0831 pinout to stamp---------------------------------------------
' 0831 pin 1 CS MCU 0
' 0831 pin 2 Vin+ wiper 10k pot with 220 Resistor (pot = VDD / VSS)
' 0831 pin 3 Vin- VSS (GND)
' 0831 pin 4 GND VSS (GND)
' 0831 PIN 5 Vref VDD +5VDC (this will be from Vref chip)
' 0831 pin 6 DO MCU 2
' 0831 PIN 7 CLK MCU 1
' 0831 PIN 8 VCC VCC +5VDC
' -----[ I/O Definitions ]-------------------------------------------------
CS PIN 0 ' chip select (ADC0831.1)
Clock PIN 1 ' clock (ADC0831.7)
DataIn PIN 2 ' data (ADC0831.6)
' -----[ Constants ]-------------------------------------------------------
BAUD CON $406e 'Set Baud rate to 19200 inverted BS2 = $4020 BS2sx = $406e
CLR CON 012 'LCD Clear Screen instruction
LINE1 CON 001 'Cursor Home Position
TX CON 9
Spkr PIN 4
freq CON 1500
freqtime CON 200
BatFull CON 12000
BatRecover CON 11900
BatLow CON 11800
BatCrit CON 11700
BatDead CON 11500
Bat_Good_led CON 10
Alarm1 CON 12
Alarm2 CON 11
SysPower CON 5
Sdelay CON 10
Cnts2Mv CON $2f10 ' x 19.6 ((Actually this hex is 5020 dec)
' (TO millivolts) $139c is the original value.
' -----[ Variables ]-------------------------------------------------------
LCDVolts VAR Word
result VAR Byte ' result of conversion
mVolts VAR Word ' millivolts
' -----[LCD initialize]----------------------------------------------------
Initialize:
PAUSE 2000
Recover:
LOW Alarm1
LOW Alarm2
FREQOUT Spkr, freqtime, freq
HIGH tx
PAUSE 200
SEROUT TX,BAUD,[003] 'RESTORE DISPLAY
SEROUT TX,BAUD,[015,040] 'Set Contrast
SEROUT TX,BAUD,[020] 'Turn Scroll Off
SEROUT TX,BAUD,[024] 'Turn Wrap Off
SEROUT TX,BAUD,[004] 'Turn Cursor Off
SEROUT TX,BAUD,[CLR] 'Clear Screen
SEROUT TX,BAUD,[LINE1] 'Goto Home Position
SEROUT TX,BAUD,[" Power Monitor"] 'Display Text
SEROUT TX,BAUD,[017,000,001] 'Position Cursor at Col 1 of Line 2 on LCD
SEROUT TX,BAUD,[" Running"] 'Display Text
PAUSE 1000 'Pause
SEROUT TX,BAUD,[CLR] 'Clear Screen
' -----[ Initialization ]--------------------------------------------------
Reset:
DEBUG CLS, ' create report screen
"ADC.... ", CR,
"volts... "
' -----[ Program Code ]----------------------------------------------------
Main:
HIGH Bat_Good_led
LOW Alarm1
LOW Alarm2
HIGH SysPower ' connecy or disconnect all loads
DO
GOSUB Read_0831 ' read the ADC
mVolts = result */ Cnts2Mv ' convert to millivolts
DEBUG HOME, ' report
CRSRXY, 9, 0, DEC result, CLREOL,
CRSRXY, 9, 1, DEC mVolts
SEROUT TX,BAUD,[020] 'Turn Scroll Off
SEROUT TX,BAUD,[024] 'Turn Wrap Off
SEROUT TX,BAUD,[004] 'Turn Cursor Off
SEROUT TX,BAUD,[LINE1] 'Goto Home Position
SEROUT TX,BAUD,["Millivolts ",DEC5 mVolts]
SEROUT TX,BAUD,[017,000,001]
SEROUT TX,BAUD,["Sys. Oporational"]
IF mVolts < BatLow THEN
GOTO Low_Battery:
ELSEIF mVolts < BatCrit THEN
GOTO Bat_Critical:
ELSEIF mVolts < BatDead THEN
GOTO Emergency_stop:
ENDIF
LOOP
'-------------------------- [Sub routine]-------------------------------------------
Read_0831:
LOW CS ' enable ADC
SHIFTIN DataIn, Clock, MSBPOST, [result\9] ' read ADC
HIGH CS ' disable ADC
RETURN
'-------------------------- [Sub routine]--------------------------------------------
Low_Battery:
LOW Bat_Good_led
DO
PWM Alarm1,255,100
GOSUB Read_0831 ' read the ADC
mVolts = result */ Cnts2Mv ' convert to millivolts
DEBUG HOME, ' report
CRSRXY, 9, 0, DEC result, CLREOL,
CRSRXY, 9, 1, DEC mVolts DIG 3,
".", DEC3 mVolts
SEROUT TX,BAUD,[020] 'Turn Scroll Off
SEROUT TX,BAUD,[024] 'Turn Wrap Off
SEROUT TX,BAUD,[004] 'Turn Cursor Off
SEROUT TX,BAUD,[LINE1] 'Goto Home Position
SEROUT TX,BAUD, ["Millivolts ", DEC5 mVolts]
SEROUT TX,BAUD,[017,000,001]
SEROUT TX,BAUD, [" Low Battery "]
IF mVolts < BatCrit THEN
GOTO Bat_Critical:
ELSEIF mVolts < BatDead THEN
GOTO Emergency_stop:
ELSEIF mVolts > BatRecover THEN
GOTO Main:
ENDIF
LOOP
'-------------------------- [Sub routine]-------------------------------------------
Bat_Critical:
DO
PWM Alarm2,200,200
PWM Alarm1,255,200
GOSUB Read_0831 ' read the ADC
mVolts = result */ Cnts2Mv ' convert to millivolts
DEBUG HOME, ' report
CRSRXY, 9, 0, DEC result, CLREOL,
CRSRXY, 9, 1, DEC mVolts DIG 3,
".", DEC3 mVolts
SEROUT TX,BAUD,[020] 'Turn Scroll Off
SEROUT TX,BAUD,[024] 'Turn Wrap Off
SEROUT TX,BAUD,[004] 'Turn Cursor Off
SEROUT TX,BAUD,[LINE1] 'Goto Home Position
SEROUT TX, BAUD, ["Millivolts ", DEC5 mVolts]
SEROUT TX,BAUD,[017,000,001]
SEROUT TX, BAUD, ["Battery Critical"]
IF mVolts > BatLow THEN
GOTO Low_Battery:
ELSEIF mVolts < BatDead THEN
GOTO Emergency_stop:
ENDIF
LOOP
Emergency_stop:
SEROUT TX,BAUD,[003] 'Hide display
SEROUT TX,BAUD,[015,040]
SEROUT TX,BAUD,[020] 'Turn Scroll Off
SEROUT TX,BAUD,[024] 'Turn Wrap Off
SEROUT TX,BAUD,[004] 'Turn Cursor Off
SEROUT TX,BAUD,[CLR] 'Clear Screen
SEROUT TX,BAUD,[LINE1] 'Goto Home Position
SEROUT TX,BAUD,[" Battery at "] 'Display Text
SEROUT TX,BAUD,[017,000,001] 'Position Cursor at Col 1 of Line 2 on LCD
SEROUT TX,BAUD,[" unsafe level"] 'Display Text
PAUSE 1000 'Pause
SEROUT TX,BAUD,[CLR] 'Clear Screen
SEROUT TX,BAUD,[" Battery at "] 'Display Text
SEROUT TX,BAUD,[017,000,001] 'Position Cursor at Col 1 of Line 2 on LCD
SEROUT TX,BAUD,[" unsafe level"] 'Display Text
PAUSE 1000
SEROUT TX,BAUD,[020] 'Turn Scroll Off
SEROUT TX,BAUD,[024] 'Turn Wrap Off
SEROUT TX,BAUD,[004] 'Turn Cursor Off
SEROUT TX,BAUD,[LINE1] 'Goto Home Position
SEROUT TX, BAUD, [" Shutting down"]
PAUSE 1000
FREQOUT Spkr,1500,1500
LOW SysPower
DO
HIGH Alarm2
GOSUB Read_0831 ' read the ADC
mVolts = result */ Cnts2Mv ' convert to millivolts
DEBUG HOME, ' report
CRSRXY, 9, 0, DEC result, CLREOL,
CRSRXY, 9, 1, DEC mVolts DIG 3,
".", DEC3 mVolts
SEROUT TX,BAUD,[020] 'Turn Scroll Off
SEROUT TX,BAUD,[024] 'Turn Wrap Off
SEROUT TX,BAUD,[004] 'Turn Cursor Off
SEROUT TX,BAUD,[LINE1] 'Goto Home Position
SEROUT TX, BAUD, ["Millivolts ", DEC5 mVolts]
SEROUT TX,BAUD,[017,000,001]
SEROUT TX,BAUD,[" Standby mode..."]
LOW Alarm2
PAUSE 3000 'charge stand by MODIFY FOR LONGER DELAY BASED ON CSD.
SEROUT TX,BAUD,[003]
IF mVolts > BatRecover THEN
PAUSE 2500
SEROUT TX,BAUD,[017,000,001]
SEROUT TX,BAUD,[" 12 Vdc detected!"]
PAUSE 2500
LOW Alarm2
GOTO Recover:
ENDIF
LOOP
My code works so far but why? lolz. you guys are great!
Comments
Page 158 of StampWorks it says:
Dividing five (volts) by 255, we find that each bit in the result is equal to 19.6 millivolts.
For display purposes, the result is converted to millivolts by multiplying by 19.6 (result */ $139C).
On page 160, its also says:
With a Vref of 2.55 volts, the voltage per bit is 0.01 volts, nearly twice as when 5.00 volts was used, for Vref, and the conversion to millivolts is simplified.
...
Before running the program modify the Cnts2Mv constant to reflect the Vref change.
With each bit equal to 0.01 volts (1/100) we can multiply by 10 to covert to millivolts (1/1000).
Cnts2Mv CON $0A00 ' x 10 (to millivolts)
Refer to Page 85 of What's a Microcontroller? V3.0 for an explanation of the */ operator.
Step 2 says take the fractional value that you want to use and multiply it by 256.
Here's the math:
Reference Voltage / # of bits for the ADC = Volts per bit
The ADC0831 is 8-bit so it outputs a value from 0 to 255 (2^8 = 256).
Vref = 5V
5V / 255 = 0.019607843 which rounds up to 0.01961 volts per bit or 19.61 mV per bit.
19.61 x 256 = 5020.16 which rounds up to 5020 which is $139C, for mV per bit.
Vref = 2.55V
2.55V / 255 = 0.01 V / Bit = 10 mV per bit
10 x 256 = 2560 = $0A00, for mV per bit
Hexadecimal is Base-16 so the digits range from 0 to F.
0-9, A = 10, B = 11, C = 12, D = 13, E = 14, F = 15
$139C = 1(16^3) + 3(16^2) + 9(16^1) + C=12(16^0) = 1(4096) + 3(256) + 9(16) + 12(1) = 4096 + 768 + 144 +12 = 5020
Remember from algebra, that anything raised to the 0 power is 1 (by definition).
$0A000 = 0(16^3) + A=10(16^2) + 0(16^1) + 0(16^0=1) = 0 +10(256) + 0 + 0 = 2560
The Windows calculator has a built in converter so click View - Programmer. Click View - Standard to return to the regular calculator mode.
Some scientific calculators also have Hex - Dec and vice-versa conversion.
I noticed that your program using GOTOs within a DO-LOOP which is very bad practice. Instead you should use what's called a State Machine.
The State changes with conditions and code is executed or skipped depending on the current State.
Anything connected to an I/O pin should be a PIN and not a CON variable.
You have a lot of LCD code so put as much of it as you can in a subroutine or a set of subroutines.
Do you have a schematic of your circuit?
I don't see any reason why you need to use hexadecimal in your code at all.
Your code is really hard to read. I think the BS2 editor will automatically indent the code for you. Please do this in the future. It will make reading your code much easier. Thanks for using code tags.
As Genetix points out your code has structural issues but then most us on the forum had structural issues with our code at one time. I hope you don't get discouraged when one of us says "you're doing it wrong". I personally learn the most from "you're doing it wrong type posts" (when directed at myself).
What are SysPower, Alarm1, and Alarm2 and better explain what should happen when each state changes.
Why do you first HIGH and LOW the Alarms and then later use PWM?
I see you have a short and long speaker tone that I adjusted since the BS2SX is not the same speed as the BS2.
' {$STAMP BS2sx} ' {$PBASIC 2.5} ' ' ========================================================================= ' -----[ Program Description ]--------------------------------------------- ' ' Battery monitory with LCD display. '--------[0831 pinout to stamp--------------------------------------------- ' 0831 pin 1 CS MCU 0 ' 0831 pin 2 Vin+ wiper 10k pot with 220 Resistor (pot = VDD / VSS) ' 0831 pin 3 Vin- VSS (GND) ' 0831 pin 4 GND VSS (GND) ' 0831 PIN 5 Vref VDD +5VDC (this will be from Vref chip) ' 0831 pin 6 DO MCU 2 ' 0831 PIN 7 CLK MCU 1 ' 0831 PIN 8 VCC VCC +5VDC ' -----[ I/O Definitions ]------------------------------------------------- ' ADC0831 Pins CS PIN 0 ' chip select (ADC0831.1) Clock PIN 1 ' clock (ADC0831.7) DataIn PIN 2 ' data (ADC0831.6) ' User Interface LCD_TX PIN 9 ' (Changed from CON to PIN) [LCD] Spkr PIN 4 ' (Changed from CON to PIN) [Speaker] SysPower PIN 5 ' (Changed from CON to PIN) [On or Off] Bat_Good_LED PIN 10 ' (Changed from CON to PIN) [Good Battery] ' Alarms Alarm2 PIN 11 ' (Changed from CON to PIN) [Standby - Battery too low] Alarm1 PIN 12 ' (Changed from CON to PIN) [Low Battery] ' -----[ Constants ]------------------------------------------------------- BAUD CON $406E 'Set Baud rate to 19200 inverted (BS2SX) ' BS2 = $4020 (16416) BS2sx = $406e (16494) [32 - 19200, True, BS2] ' BS2 = INT(1,000,000 / baud rate) - 20, Bits 0-11 ' BS2SX = INT (2,500,000 / baud rate) - 20 ' Bit 13 - Set data bits and parity, 8N = 0, 7E = 8192 ' Bit 14 - Select polarity, True (noninverted) = 0, Inverted = 16384 ' Bit 15 - Select driven or open output, Driven = 0, Open = 32768 ' 16416 - 16384 = 32 (BS2) ' (1,000,000 / 19,200) - 20 = 52.08333 - 20 = 32 [BS2] ' 16494 - 16384 = 110 (BS2SX) ' (2,500,000 / 19,200) - 20 = 130.208333 - 20 = 110 [BS2SX] ' LCD Constants CLR CON 012 'LCD Clear Screen instruction (Form Feed) LINE1 CON 001 'Cursor Home Position HideDisplay CON 003 'Hide display RestoreDisplay CON 003 'RESTORE DISPLAY CursorOff CON 004 'Turn Cursor Off ScrollOff CON 020 'Turn Scroll Off WrapOff CON 024 'Turn Wrap Off ' SEROUT TX, BAUD, [015,040] 'Set Contrast ' SEROUT TX, BAUD, [017,000,001] 'Position Cursor at Col 1 of Line 2 on LCD ' Speaker Constants (Converted from BS2 to BS2SX) Freq CON 1500 * 0.4 ' Frequency (2.5 Hz - BS2SX, Hz - BS2) [1 / 2.5 = 0.4] FreqTime1 CON 200 * 2.5 ' Duration (0.4 ms - BS2SX, ms - BS2) [1 / 0.4 = 2.5] FreqTime2 CON 1500 * 2.5 ' Duration (0.4 ms - BS2SX, ms - BS2) [1 / 0.4 = 2.5] ' Battery Constants (mV???) BatFull CON 12000 BatRecover CON 11900 BatLow CON 11800 BatCrit CON 11700 BatDead CON 11500 ' Voltage Constants Cnts2Mv CON $2f10 ' x 19.6 ((Actually this hex is 5020 dec) ' (TO millivolts) $139c is the original value. ' $2F10 = 12048 ' Unknown or unused Constants Sdelay CON 10 ' What is this??? ' -----[ Variables ]------------------------------------------------------- LCDVolts VAR Word result VAR Byte ' result of conversion mVolts VAR Word ' millivolts batState VAR NIB ' Added (0 = Full, 1 = Low, 2 = Critical, 3 = Dead) ' -----[LCD initialize]---------------------------------------------------- Initialize: PAUSE 2000 ' Allow PC Serial Ports to stabilize GOSUB System_Good ' Added HIGH LCD_TX ' Set pin high to be a serial port PAUSE 200 ' Pause for Serial LCD to initialize SEROUT LCD_TX, BAUD, [003] 'RESTORE DISPLAY SEROUT LCD_TX, BAUD, [015,040] 'Set Contrast SEROUT LCD_TX, BAUD, [ScrollOff] 'Turn Scroll Off SEROUT LCD_TX, BAUD, [WrapOff] 'Turn Wrap Off SEROUT LCD_TX, BAUD, [CursorOff] 'Turn Cursor Off SEROUT LCD_TX, BAUD, [CLR] 'Clear Screen 'PAUSE 5 ' Give the Serial LCD time to clear the display. SEROUT LCD_TX, BAUD, [LINE1] 'Goto Home Position SEROUT LCD_TX, BAUD, [" Power Monitor"] 'Display Text SEROUT LCD_TX, BAUD, [017,000,001] 'Position Cursor at Col 1 of Line 2 on LCD ' 17 - Backlight on, 18 - off SEROUT LCD_TX, BAUD, [" Running"] 'Display Text PAUSE 1000 'Pause for 1 second SEROUT TX, BAUD, [CLR] 'Clear Screen ' -----[ Initialization ]-------------------------------------------------- DEBUG CLS, ' create report screen "ADC.... ", CR, "volts... " HIGH Bat_Good_LED ' Turn on Battery Good LED HIGH SysPower ' connect or disconnect all loads ' -----[ Program Code ]---------------------------------------------------- DO ' Main Loop GOSUB Read_0831 ' read the ADC mVolts = (result */ Cnts2Mv) ' convert to millivolts DEBUG HOME, ' report CRSRXY, 9, 0, DEC result, CLREOL, CRSRXY, 9, 1, DEC mVolts IF (mVolts > BatFull) THEN ' Battery is good IF (batState = 0) THEN ' Battery is already good GOSUB Prep_LCD ' Moved these 4 lines to a subroutine SEROUT LCD_TX, BAUD, ["Millivolts ",DEC5 mVolts] SEROUT LCD_TX, BAUD, [017,000,001] SEROUT LCD_TX, BAUD, ["Sys. Oporational"] ELSE ' Battery has recovered batState = 0 GOSUB Bat_Recover ENDIF ' End of inner IF Statement ELSEIF (mVolts < BatLow) THEN ' Changed from IF to ELSEIF GOSUB Low_Battery: ' Changed from GOTO to GOSUB ELSEIF (mVolts < BatCrit) THEN GOSUB Bat_Critical: ' Changed from GOTO to GOSUB ELSEIF (mVolts < BatDead) THEN GOSUB Emergency_stop: ' Changed from GOTO TO GOSUB ENDIF ' End of outer IF statement LOOP ' Loop again '-------------------------- [Sub routine]------------------------------------------- Read_0831: LOW CS ' enable ADC SHIFTIN DataIn, Clock, MSBPOST, [result\9] ' read ADC HIGH CS ' disable ADC RETURN '-------------------------- [Sub routine]------------------------------------------- Prep_LCD: ' Prepare LCD to display a message (Added) SEROUT LCD_TX, BAUD, [ScrollOff] 'Turn Scroll Off SEROUT LCD_TX, BAUD, [WrapOff] 'Turn Wrap Off SEROUT LCD_TX, BAUD, [CursorOff] 'Turn Cursor Off SEROUT LCD_TX, BAUD, [LINE1] 'Goto Home Position '-------------------------- [Sub routine]-------------------------------------------- Low_Battery: batState = 1 ' Low Battery LOW Bat_Good_LED ' Turn off Battery Good LED PWM Alarm1, 255, 100 ' Duty = 255, Cycles = 100 (0.4 ms - BS2SX, ms - BS2) ' 100 x 0.4 = 40 ms (BS2SX) GOSUB Prep_LCD ' Moved these 4 lines to a subroutine SEROUT LCD_TX, BAUD, ["Millivolts ", DEC5 mVolts] SEROUT LCD_TX, BAUD, [017,000,001] SEROUT LCD_TX, BAUD, [" Low Battery "] RETURN ' Added '-------------------------- [Sub routine]------------------------------------------- Bat_Critical: batState = 2 PWM Alarm2, 200, 200 ' Duty = 200, Cycles = 200 PWM Alarm1, 255, 200 ' Duty = 200, Cycles = 200 ' 200 x 0.4 = 80 ms (BS2SX) GOSUB Prep_LCD ' Moved these 4 lines to a subroutine SEROUT LCD_TX, BAUD , ["Millivolts ", DEC5 mVolts] SEROUT LCD_TX, BAUD , [017,000,001] SEROUT LCD_TX, BAUD , ["Battery Critical"] RETURN ' Added '-------------------------- [Sub routine]------------------------------------------- Emergency_stop: batState = 3 SEROUT TX, BAUD, [003] 'Hide display SEROUT TX, BAUD, [015,040] 'Set Contrast SEROUT TX, BAUD, [ScrollOff] 'Turn Scroll Off SEROUT TX, BAUD, [WrapOff] 'Turn Wrap Off SEROUT TX, BAUD, [CursorOff] 'Turn Cursor Off SEROUT TX, BAUD, [CLR] 'Clear Screen SEROUT TX, BAUD, [LINE1] 'Goto Home Position SEROUT TX, BAUD, [" Battery at "] 'Display Text SEROUT TX, BAUD, [017,000,001] 'Position Cursor at Col 1 of Line 2 on LCD SEROUT TX, BAUD, [" unsafe level"] 'Display Text PAUSE 1000 'Pause SEROUT TX, BAUD, [CLR] 'Clear Screen SEROUT TX, BAUD, [LINE1] 'Goto Home Position SEROUT TX, BAUD, [" Battery at "] 'Display Text SEROUT TX, BAUD, [017,000,001] 'Position Cursor at Col 1 of Line 2 on LCD SEROUT TX, BAUD, [" unsafe level"] 'Display Text PAUSE 1000 GOSUB Prep_LCD ' Moved these 4 lines to a subroutine SEROUT TX, BAUD, [" Shutting down"] PAUSE 1000 FREQOUT Spkr, FreqTime2, Freq ' Changed from 1500 to FreqTime2 and from 1500 to Freq LOW SysPower HIGH Alarm2 ' Turn on Alarm GOSUB Prep_LCD ' Moved these 4 lines to a subroutine SEROUT TX, BAUD, ["Millivolts ", DEC5 mVolts] SEROUT TX, BAUD, [017,000,001] SEROUT TX, BAUD, [" Standby mode..."] LOW Alarm2 ' Turn off Alarm PAUSE 3000 'charge stand by MODIFY FOR LONGER DELAY BASED ON LCD. '-------------------------- [Sub routine]------------------------------------------- Bat_Recover: ' Battery recovered from being Critical ' SEROUT TX, BAUD, [003] ' PAUSE 2500 SEROUT TX, BAUD, [017,000,001] SEROUT TX, BAUD, [" 12 Vdc detected!"] ' PAUSE 2500 LOW Alarm2 ' Turn off Alarm RETURN ' Added '-------------------------- [Sub routine]------------------------------------------- System_Good: ' Let user know that system if fully functional (Added) LOW Alarm1 ' Turn off Alarms LOW Alarm2 FREQOUT Spkr, FreqTime1, Freq RETURN