REM IgnCapCoil.bas written by Louis Dudzik Feb 12 '04 DECLARE SUB FourBIT (x1%, y1%, x2%, y2%, FileNAME$) SCREEN 12 5 CLS 0 PRINT "This program analyzes a capacitor-driven ignition-coil-circuit. It is a" PRINT "special case of a general RLC series circuit. Specifically, the capacitor" PRINT "has an initial voltage on it, but there is no initial current in the circuit." PRINT "Given R, L, C, and the initial voltage on the capacitor, the program plots" PRINT "the current as a function of time, and the capacitor's voltage as a" PRINT "function of time." PRINT " The program first determines the damping of the circuit. It can be" PRINT "underdamped, overdamped, or critically damped. Depending on the " PRINT "damping, the program selects the appropriate equations to use." PRINT "The current is plotted as a thin, solid line." PRINT "The capacitor voltage is plotted as a dotted line." PRINT "The X axis is time in seconds." PRINT "The Y axis is both current in Amps and voltage in Volts." PRINT " Note: there is no checking of out-of-range variables, so overflow" PRINT "errors may result if input values are not selected carefully." PRINT "Printing: This progam can generate a bitmap file of the screen. The files" PRINT "will appear in the same folder as this program file resides. If it will be " PRINT "printed out, it is recommended the file be opened in MSPaint and edited." PRINT "If converting to black and white, first save as 24bit BMP then " PRINT "invert colors and convert to black and white. It's all done in MSPaint." PRINT " Seven different time scales can be chosen from." PRINT "0 to .001 sec." PRINT "0 to .01 sec." PRINT "0 to .1 sec." PRINT "0 to 1 sec." PRINT "0 to 10 sec." PRINT "0 to 100 sec." PRINT "0 to 1000 sec." INPUT "Enter the number of seconds for the x axis (default is .1)"; tScale REM "tScale" is the range of the x axis in seconds IF tScale < 0 THEN GOTO 5 IF tScale = 0 THEN REM default case tScale = .1 GOTO 8 END IF IF tScale < .0011 THEN tScale = .001 GOTO 8 END IF IF tScale < .011 THEN tScale = .01 GOTO 8 END IF IF tScale < .11 THEN tScale = .1 GOTO 8 END IF IF tScale < 1.1 THEN tScale = 1 GOTO 8 END IF IF tScale < 11 THEN tScale = 10 GOTO 8 END IF IF tScale < 110 THEN tScale = 100 GOTO 8 END IF tScale = 1000 8 CLS 0 REM the graphics port is set to leave room to the left and bottom for scale indicators REM Vertically, 0-368 gives 23 spaces, but 1/2 is wasted on top and 1/2 is wasted on bottom REM to leave room for the scale numbers so the center of the number lines up with the graph lines. REM The graph is broken into 22 useable spaces vertically with a 1/2 unused on top, REM and 1/2 unused on bottom for a total of 23, and the scale gets 22 numbers. REM It has to be that way in order for the vertical scale numbers to line up. REM Vertically, one line of text takes 16 vertical pixels. 368/23 = 16 REM if more vertical space is needed at the bottom for text, the graph loses 16 pixels per line. VIEW (39, 0)-(639, 368) REM graphics port scale will be 0 to "tScale" seconds by -7 to +15 amps/volts. REM (15.5 and -7.5 in order to center the scale with the scale numbers) REM tScale is either .001, .01, .1, 1, 10, 100, or 1000. WINDOW (0, 15.5)-(tScale, -7.5) REM show the scale numbers of the y axis as 15 to -7 REM note: using "PRINT USING" command to force the formatting. REM without it, extra spaces get printed. LOCATE 1, 1 FOR y = 15 TO -7 STEP -1 PRINT USING "####"; y NEXT y REM print the x axis time-scale values LOCATE 24, 1 IF tScale = .001 THEN PRINT " 0sec .0001 .0002 .0003 .0004 .0005 .0006 .0007 .0008 .0009 .001" IF tScale = .01 THEN PRINT " 0sec .001 .002 .003 .004 .005 .006 .007 .008 .009 .01" IF tScale = .1 THEN PRINT " 0sec .01 .02 .03 .04 .05 .06 .07 .08 .09 .1" IF tScale = 1 THEN PRINT " 0sec .1 .2 .3 .4 .5 .6 .7 .8 .9 1" IF tScale = 10 THEN PRINT " 0sec 1 2 3 4 5 6 7 8 9 10" IF tScale = 100 THEN PRINT " 0sec 10 20 30 40 50 60 70 80 90 100" IF tScale = 1000 THEN PRINT " 0sec 100 200 300 400 500 600 700 800 900 1000" 10 VIEW PRINT 25 TO 30 CLS CLS 2 REM -------------Sets up the graph underlay------------------------------------------------------ COLOR 8 FOR y = -7 TO 15 LINE (0, y)-(tScale, y) NEXT y FOR x = 0 TO tScale + tScale / 100 STEP tScale / 100 REM The x loop goes to "tScale + tScale/100" to put one extra step in the loop. REM Due to rounding errors, the last step in the loop was not being performed. REM This is because the STEP calculation was not exactly tScale /100 LINE (x, -7)-(x, 15) NEXT x COLOR 15 LINE (0, 15)-(0, -7) LINE (0, 0)-(tScale, 0) LINE (0, -23 / 368)-(tScale, -23 / 368) FOR x = 0 TO tScale + tScale / 10 STEP tScale / 10 REM one extra step is put into the loop. see rem notes above. LINE (x, -7)-(x, 15) LINE (x + tScale / 600, -7)-(x + tScale / 600, 15) NEXT x REM--------------------------------------------------------------------------------------------- REM This initializes the color for the plot. REM each successive plot changes color. GrphColor = 8 REM command section------------------------------------------------------------------------------- 20 VIEW PRINT 27 TO 30 LOCATE 28, 1 COLOR 15 PRINT "Enter 475 to generate a bitmap (BMP) of the screen." PRINT "Enter 1 to clear screen. 2 to exit. Enter 3 to change time scale (start)." INPUT "Or just enter 0 to continue."; command% CLS 2 IF command% = 2 THEN SYSTEM IF command% = 1 THEN GOTO 10 IF command% = 3 THEN REM this next line is needed to expand the text port before starting over VIEW PRINT 1 TO 30 GOTO 5 END IF IF command% = 475 THEN 'this increments a new bitmap name-number every time a bitmap is generated (up to 9999) BMPnumber% = BMPnumber% + 1 'this makes the new bitmap name based on the new number BMPname$ = "IGCC" + STR$(BMPnumber%) PRINT "A bitmap of this screen called "; BMPname$; ".BMP is being generated. Please wait. " 'the previously set VIEW and WINDOW commands have to be cleared for the sub to work. VIEW WINDOW FourBIT 0, 0, 639, 479, BMPname$ 'must now reinstate the VIEW and WINDOW VIEW (39, 0)-(639, 368) WINDOW (0, 15.5)-(tScale, -7.5) CLS 2 PRINT "Image file "; BMPname$; " is saved in the folder in which this program resides." GOTO 20 END IF REM--------------------------------------------------------------------- REM input section--------------------------------------------------------------------------------- REM all equation variables should be double-length floating point. They end in # INPUT "Enter DC resistance of coil (plus ballast if any) in Ohms "; R# INPUT "Enter the inductance of the coil in milli-Henrys "; ML# REM convert to henrys L# = ML# / 1000 INPUT "Enter the capacitance of the capacitor in Farads "; C# INPUT "Enter the initial voltage on the capacitor in Volts "; V# REM --------------------------------------------------------------------------------------------- REM clear text window CLS 2 REM Redraw X axis LINE (0, 0)-(tScale, 0) REM change plot color for new plot GrphColor = GrphColor + 1 IF GrphColor = 15 THEN GrphColor = 9 COLOR GrphColor VIEW PRINT 25 TO 27 CLS 2 PRINT "The line plot is current. The dotted plot is capacitor voltage." REM reprint input values in same color REM to print neatly, they should be converted to single length. They end in ! R! = R# ML! = ML# C! = C# V! = V# PRINT R!; "ohms "; ML!; "mHenrys "; C!; "farads "; V!; "volts "; REM determine damping type alpha# = R# / (2 * L#) alphaSQ# = alpha# ^ 2 omegaSQ# = 1 / (L# * C#) IF omegaSQ# < alphaSQ# THEN GOTO 100 IF omegaSQ# > alphaSQ# THEN GOTO 200 IF omegaSQ# = alphaSQ# THEN GOTO 300 GOTO 20 100 REM---------------------------------------overdamp------------------------------------ PRINT " Overdamped." s1# = -1 * alpha# + SQR(alphaSQ# - omegaSQ#) s2# = -1 * alpha# - SQR(alphaSQ# - omegaSQ#) a1# = V# / (L# * (s2# - s1#)) a2# = (-1 * V#) / (L# * (s2# - s1#)) REM move current graphic cursor to origin PSET (0, 0) REM plot i(t) (solid line) REM t is in seconds FOR t = 0 TO tScale STEP tScale / 620 i# = a1# * (EXP(s1# * t)) + a2# * (EXP(s2# * t)) i# = -1 * i# LINE STEP(0, 0)-(t, i#) NEXT t REM plot capacitor v(t) dotted line FOR t = 0 TO tScale STEP tScale / 6200 vc# = -1 * R# * a1# * (EXP(s1# * t)) - R# * a2# * (EXP(s2# * t)) - L# * s1# * a1# * (EXP(s1# * t)) - L# * s2# * a2# * (EXP(s2# * t)) REM This checks for distance between points on the plot. It skips the point if the previous point was too close. IF ABS(vcPrevious# - vc#) < .25 AND ABS(t - tPrevious) < tScale / 130 THEN GOTO 110 REM draw a circle and fill it radius = tScale / 600 CIRCLE (t, vc#), radius PAINT (t, vc#) REM save coordinates of plotted point vcPrevious# = vc# tPrevious = t 110 NEXT t GOTO 20 200 REM-----------------------------------underdamp--------------------------------------- PRINT " Underdamped." omegaD# = SQR(omegaSQ# - alphaSQ#) b2# = -1 * V# / (L# * omegaD#) REM move current graphic cursor to origin PSET (0, 0) REM plot i(t) (solid line) REM t is in seconds FOR t = 0 TO tScale STEP tScale / 620 i# = b2# * EXP(-1 * alpha# * t) * SIN(omegaD# * t) i# = -1 * i# LINE STEP(0, 0)-(t, i#) NEXT t REM plot capacitor v(t) dotted line FOR t = 0 TO tScale STEP tScale / 6200 vc# = -1 * L# * omegaD# * b2# * (EXP(-1 * alpha# * t)) * COS(omegaD# * t) + L# * alpha# * b2# * (EXP(-1 * alpha# * t)) * SIN(omegaD# * t) - R# * b2# * (EXP(-1 * alpha# * t)) * SIN(omegaD# * t) REM This checks for distance between points on the plot. It skips the point if the previous point was too close. IF ABS(vcPrevious# - vc#) < .25 AND ABS(t - tPrevious) < tScale / 130 THEN GOTO 210 REM draw a circle and fill it radius = tScale / 600 CIRCLE (t, vc#), radius PAINT (t, vc#) REM save coordinates of plotted point vcPrevious# = vc# tPrevious = t 210 NEXT t GOTO 20 300 REM-----------------------------------------critically damp---------------------------------- PRINT " Critically damped." d1# = -1 * V# / L# REM move current graphic cursor to origin PSET (0, 0) REM plot i(t) (solid line) REM t is in seconds FOR t = 0 TO tScale STEP tScale / 620 i# = d1# * t * EXP(-1 * alpha# * t) i# = -1 * i# LINE STEP(0, 0)-(t, i#) NEXT t REM plot capacitor v(t) dotted line FOR t = 0 TO tScale STEP tScale / 6200 vc# = -1 * L# * d1# * (EXP(-1 * alpha# * t)) + alpha# * L# * d1# * t * (EXP(-1 * alpha# * t)) - R# * d1# * t * (EXP(-1 * alpha# * t)) REM This checks for distance between points on the plot. It skips the point if the previous point was too close. IF ABS(vcPrevious# - vc#) < .25 AND ABS(t - tPrevious) < tScale / 130 THEN GOTO 310 REM draw a circle and fill it radius = tScale / 600 CIRCLE (t, vc#), radius PAINT (t, vc#) REM save coordinates of plotted point vcPrevious# = vc# tPrevious = t 310 NEXT t GOTO 20 '------------------------this is the screen 12 bitmap generator--------------- SUB FourBIT (x1%, y1%, x2%, y2%, FileNAME$) DIM FileCOLORS%(1 TO 48) DIM Colors4%(15) IF INSTR(FileNAME$, ".BMP") = 0 THEN FileNAME$ = RTRIM$(LEFT$(FileNAME$, 8)) + ".BMP" END IF FOR x = x1% TO x2% FOR y = y1% TO y2% Colors4%(POINT(x, y)) = 1 NEXT y NEXT x FOR n = 0 TO 15 IF Colors4%(n) = 1 THEN SigCOLORS& = SigCOLORS& + 1 NEXT n FileTYPE$ = "BM" Reserved1% = 0 Reserved2% = 0 OffsetBITS& = 118 InfoHEADER& = 40 PictureWIDTH& = x2% - x1% + 1 PictureDEPTH& = y2% - y1% + 1 NumPLANES% = 1 BPP% = 4 Compression& = 0 WidthPELS& = 3780 DepthPELS& = 3780 NumCOLORS& = 16 IF PictureWIDTH& MOD 8 <> 0 THEN ZeroPAD$ = SPACE$((8 - PictureWIDTH& MOD 8) \ 2) END IF ImageSIZE& = (((ImageWIDTH& + LEN(ZeroPAD$)) * ImageDEPTH&) + .1) / 2 FileSIZE& = ImageSIZE& + OffsetBITS& Colr = 0 FOR n = 1 TO 48 STEP 3 OUT &H3C7, Colr FileCOLORS%(n) = INP(&H3C9) FileCOLORS%(n + 1) = INP(&H3C9) FileCOLORS%(n + 2) = INP(&H3C9) Colr = Colr + 1 NEXT n OPEN FileNAME$ FOR BINARY AS #1 PUT #1, , FileTYPE$ PUT #1, , FileSIZE& PUT #1, , Reserved1% 'should be zero PUT #1, , Reserved2% 'should be zero PUT #1, , OffsetBITS& PUT #1, , InfoHEADER& PUT #1, , PictureWIDTH& PUT #1, , PictureDEPTH& PUT #1, , NumPLANES% PUT #1, , BPP% PUT #1, , Compression& PUT #1, , ImageSIZE& PUT #1, , WidthPELS& PUT #1, , DepthPELS& PUT #1, , NumCOLORS& PUT #1, , SigCOLORS& u$ = " " FOR n% = 1 TO 46 STEP 3 Colr$ = CHR$(FileCOLORS%(n% + 2) * 4) PUT #1, , Colr$ Colr$ = CHR$(FileCOLORS%(n% + 1) * 4) PUT #1, , Colr$ Colr$ = CHR$(FileCOLORS%(n%) * 4) PUT #1, , Colr$ PUT #1, , u$ 'Unused byte NEXT n% FOR y = y2% TO y1% STEP -1 FOR x = x1% TO x2% STEP 2 HiX = POINT(x, y) LoX = POINT(x + 1, y) HiNIBBLE$ = HEX$(HiX) LoNIBBLE$ = HEX$(LoX) HexVAL$ = "&H" + HiNIBBLE$ + LoNIBBLE$ a$ = CHR$(VAL(HexVAL$)) PUT #1, , a$ NEXT x PUT #1, , ZeroPAD$ NEXT y CLOSE #1 END SUB