Login| Sign Up| Help| Contact|

Patent Searching and Data


Title:
ANAEROBIC FERMENTATION METHOD AND APPARATUS
Document Type and Number:
WIPO Patent Application WO/2005/042690
Kind Code:
A2
Abstract:
A method and apparatus for monitoring a liquid undergoing anaerobic fermentation in a vessel is disclosed. The apparatus comprises an airlock containing a fluid for sealing the vessel and means (40, 42) to detect passage of bubbles through the airlock.

Inventors:
PAZIK ANDRE J (US)
KORNACKI DANIEL C (US)
Application Number:
PCT/US2004/036778
Publication Date:
May 12, 2005
Filing Date:
November 04, 2004
Export Citation:
Click for automatic bibliography generation   Help
Assignee:
PAZIK ANDRE J (US)
KORNACKI DANIEL C (US)
International Classes:
C12C13/00; C12G1/02; C12G3/00; C12L11/00; C12C; (IPC1-7): C12C/
Foreign References:
US4577186A1986-03-18
US5092181A1992-03-03
Attorney, Agent or Firm:
Maliszewski, Paul C. (PLLC 5555 Main Stree, Williamsville NY, US)
Download PDF:
Claims:
CLAIMS
1. A method for determining an amount of alcohol produced during anaerobic fermentation in a sealed anaerobic fermentation vessel containing a liquid being fermented, said vessel sealed with an airlock, the method comprising the steps of : counting bubbles which pass through said airlock to determine a volume of gas produced, said bubbles detected by an optical detector; and, determining said amount of alcohol produced based on said volume of gas produced.
2. The method recited in Claim 1 further including the step of determining the interval between bubbles so that the rate of fermentation may be determined.
3. The method recited in Claim 1 further including the step of activating an alarm when a desired amount of alcohol is produced.
4. The method recited in Claim 1 wherein said airlock is an"S"type airlock.
5. The method recited in Claim 1 further i ncluding t he s tep o f c orrecting s aid amount of alcohol produced based on an elevation of said vessel.
6. A method for measuring gas produced during anaerobic fermentation comprising the steps of : providing a vessel suitable for anaerobic fermentation; placing liquid materials subject to anaerobic fermentation within the vessel; sealing the vessel with an"S"type airlock; and, counting the bubbles which pass through the airlock to determine the volume of gas produced, said bubbles detected by an optical detector.
7. The method recited in Claim 6 further comprising the step of determining the interval between bubbles so that the rate of fermentation may be determined.
8. An apparatus for monitoring a liquid undergoing anaerobic fermentation in a vessel, comprising : an airlock containing a fluid for sealing the vessel; and, an optical detector operatively arranged to detect passage of bubbles through said airlock.
9. The apparatus recited in Claim 8 wherein said airlock is an"S"type airlock.
10. The apparatus recited in Claim 9 wherein said airlock comprises a portion with two parallel sides.
11. The apparatus recited in Claim 10 wherein said optical detector engages said portion of said airlock having two parallel sides.
12. The apparatus recited in Claim 8 further comprising means for determining the volume of gas produced based on said detected passage of bubbles.
13. The apparatus recited in Claim 12 further comprising: means to determine an amount of alcohol produced based on said amount of gas produced, said amount corrected based on an altitude of said apparatus; and, a display operatively arranged to display said amount of alcohol produced.
14. The apparatus recited in Claim 13 further comprising: an alarm operatively arranged to warn a user when a preprogrammed amount of alcohol has been produced.
15. The apparatus recited in Claim 8 further comprising: means for determining the time between bubble detections; and, means for determining the rate of gas production based on said time between bubble detections.
16. The apparatus recited in Claim 15 further comprising: an alarm operatively arranged to warn a user when no bubbles are detected for a predetermined amount of time.
17. The apparatus recited in Claim 16 wherein said predetermined amount of time is 24 hours.
18. The apparatus recited in Claim 8 further comprising: means for determining the length of time a bubble is proximate said optical detector; and, an alarm operatively arranged to warn a user when the liquid in said airlock is low, based on said length of time said bubble is proximate said optical detector.
19. The apparatus recited in Claim 13 further comprising means for computing a flow rate of alcohol produced, said flow rate corrected based on an elevation of said apparatus.
20. The apparatus recited in Claim 19 further comprising alarm means for signaling when said computed flow rate exceeds a flow rate threshold set by a user.
21. An airlock comprising: a portion having a cross section with two parallel sides.
22. The airlock recited in Claim 21 wherein said portion has a polygonal cross section.
23. The airlock recited in Claim 21 wherein said portion has a rectangular cross section.
24. The airlock recited in Claim 21 wherein said cross section of said portion further comprises two opposing, arcuate sides.
25. An apparatus for monitoring anaerobic fermentation comprising: an airlock; a bubble detector; processing means connected to said detector, said processing means operatively arranged to count a number of bubbles passing through said airlock; and, communication means connected to said processing means, said communication means operatively arranged to communicate data between said processing means and an information system.
26. The apparatus recited in Claim 25 wherein said airlock comprises a portion having two parallel sides.
27. The apparatus recited in Claim 25 wherein said processing means comprises a general purpose microprocessor programmed to count said number of bubbles passing through said airlock.
28. The apparatus recited in Claim 25 wherein said processing means is operatively arranged to determine a quantity of alcohol produced by said anaerobic fermentation.
29. The apparatus recited in Claim 25 wherein said processing means is operatively arranged to measure a period of time between said bubbles passing through said airlock.
30. The apparatus recited in Claim 25 wherein said processing means is operatively arranged to determine when said anaerobic fermentation has ended.
31. The apparatus recited in Claim 25 wherein said processing means is operatively arranged to determine if said airlock contains an inadequate amount of liquid.
32. The apparatus recited in Claim 25 wherein said data is said amount of alcohol produced.
33. The apparatus recited in Claim 25 wherein said data is an alarm status.
34. The apparatus recited in Claim 25 wherein said data is a warning that an inadequate amount of liquid is in said airlock.
35. The apparatus recited in Claim 25 wherein said data is a warning that said anaerobic fermentation has ended.
36. The apparatus recited in Claim 25 wherein said communication means is an RS232 connection.
37. The apparatus recited in Claim 25 wherein said communication means is a TCP/IP connection.
38. The apparatus recited in Claim 25 wherein said communication means is a USB connection.
39. The apparatus recited in Claim 25 wherein said information system is the Internet.
40. The apparatus recited in Claim 25 wherein said information system is a personal computer.
41. The apparatus recited in Claim 25 wherein said information system is a wireless phone system.
42. The apparatus recited in Claim 25 wherein said information system is a pager system.
43. The apparatus recited in Claim 25 wherein said information system is a personal digital assistant system.
44. The apparatus recited in Claim 25 wherein said information system is a wireless local area network.
45. The apparatus recited in Claim 25 further comprising database means to store said data.
Description:
ANAEROBIC FERMENTATION METHOD AND APPARATUS TECHNICAL FIELD The present invention relates generally to a method and apparatus useful during anaerobic fermentation, and more particularly to a method and apparatus for measuring the volume and rate of gas produced during anaerobic fermentation, this invention having particular utility during the making of alcoholic beverages.

BACKGROUND ART It is common when making alcoholic beverages in the home to place the liquid subject to fermentation into a vessel for anaerobic fermentation, the vessel being closed by a fermentation airlock. The purpose of the fermentation airlock is to prevent undesirable dust and bacteria from contaminating the material being fermented. Therefore it is common to utilize an airtrap, the gas produced by fermentation bubbling though a liquid in the airtrap, the liquid typically containing water and a sterilizing agent such as sodium or potassium metabisulfite. Differing types of fermentation locks are employed, various examples being shown in US patents 4,517, 884, 4, 842, 869, and 5,950, 524. A favorite form of airlock is the "S"type airlock, variations being shown in US patents 2,023, 153 and 4,717, 031, and German patents 412,918 and 957,563. Another prior art form of"S"type airlock is shown in Figure 1 of this application.

The airlock may be molded from a clear plastic, all airlocks being quite uniform in size. It has been observed that when using some airlocks that each bubble has substantially the same volume, i. e. , 1.7 ml. It is also known that during fermentation that equal mole volumes of CO2 and alcohol are produced.

DISCLOSURE OF INVENTION The present invention broadly comprises a method and apparatus for measuring gas produced during anaerobic fermentation. The method comprises the steps of counting bubbles which pass through said airlock to determine a volume of gas produced and determining the amount of alcohol produced based on the volume of gas produced.

The above objects, and other objects and advantages of this invention will become more apparent to those skilled in the art after a consideration of the following

detailed description taken in conjunction with the accompanying drawings in which a preferred form of this invention is illustrated.

BRIEF DESCRIPTION OF DRAWINGS It should be appreciated that, in the detailed description of the invention which follows, like reference numbers on different drawing views are intended to identify identical structural elements of the invention in the respective views.

Figure 1 illustrates a prior art"S"type airlock; Figure 2 illustrates an airlock of a first embodiment of the present invention, an airlock being provided with electrodes; Figure 3 shows a dust cap for the modified"S"type airlock, which dust cap is provided with suitable contacts for contacting the electrodes in the modified"S"type airlock; Figure 4 shows a first embodiment of the present invention with the airlock being mounted on a vessel suitable for anaerobic fermentation; Figure 5 shows a bubble interrupting the flow of current through between the electrodes, signaling a bubble event; Figure 6 shows an embodiment of the electrical circuit of the control means; Figure 7 shows an alternate embodiment of the electrical circuit of the control means; Figure 8 illustrates a second embodiment of an airlock of the present invention; Figure 9 illustrates a third embodiment of an airlock of the present invention; Figure 10 illustrates a fourth embodiment of an airlock of the present invention; Figure 11 illustrates a fifth embodiment of the present invention, comprising an optical sensor and communication means; Figure 12 illustrates an embodiment of the present invention wherein multiple control means are connected to a single communication control means; Figure 13 illustrates an alternate embodiment of the present invention wherein multiple control means are connected to a single communication control means; Figure 14 illustrates a schematic of the electrical circuit for the fifth embodiment of the present invention, comprising an optical sensor;

Figures 15 and 16 illustrate an embodiment of the present invention wherein the optical detector is arranged to mate with a portion of an airlock having two parallel sides and two arcuate sides; Figures 17 and 18 illustrate an embodiment of the present invention wherein the optical detector is arranged to mate with a portion of an airlock having a rectangular cross section; and, Figures 19 and 120 illustrate an embodiment of the present invention wherein the optical detector is arranged to mate with a portion of an airlock having a hexagonal cross section.

BEST MODE FOR CARRYING OUT THE INVENTION With reference initially to Figure 1, an airlock is illustrated, said airlock being indicated generally at 10. This airlock consists of a molded clear plastic member indicated generally at 12, the plastic member including an"S"shaped passageway which will be described later. Extending downwardly from the"S"shaped passageway is a mounting stem 14 which is inserted into the rubber bung or cork 16 of a fermenting vessel 18 so as to be an airtight fit. The airlock is provided with a dust cap 20 at its upper end.

The"S"shaped passageway includes an upwardly extending portion 22 which is in direct communication with the stem 14, the portion 22 being essentially cylindrical in cross section. A"U"shaped member 24 having a circular cross section connects the portion 22 with a downwardly extending portion 26 having upper, intermediate, and lower bulbs 26.1, 26.2, and 26.3, respectively. A further "U" shaped member 28 having a circular cross section connects the lower end of downwardly extending portion 26 with an upwardly extending portion 30 provided with upper, intermediate and lower bulbs 30.1, 30.2, and 30.3, respectively. An upwardly extending member 32 is provided with a bulb 34 at its top end, which bulb receives the dust cap 20. A clear plastic web or flashing 36 extends between the downwardly extending portion 26 and the upwardly extending portion 30, and also between the downwardly extending portion 26 and the upwardly extending portion 22 to keep the various parts in fixed relationship to each other.

After the liquid to be fermented is placed in the vessel, which liquid may be a wine must, the vessel is sealed with an airlock at the commencement of anaerobic fermentation. To this end, a sterilizing liquid is placed in the"S"shaped airlock, the

sterilizing liquid filling the"U"shaped member 28 and 1/2 of each of the lower bulbs 26.3 and 30.3, the sterilizing liquid being indicated generally at SL in Figure 2. The sterilizing liquid typically contains either sodium or potassium metabisulfite, although other sterilizing agents may be used. During anaerobic fermentation the yeast is less active than during the initial aerobic fermentation, and the CO2 produced with escape through the sterilizing liquid one bubble at a time.

With reference to Figure 2, it can be seen that the"S"type airlock of the present invention is provided with two electrodes 40,42. Electrode 40 is embedded in the flashing 36 which extends between the downwardly extending portion 26 and the upwardly extending portion 30. Additional flashing 44 is provided to one side of the upwardly extending portion 30 for the receipt of electrode 42. As can be seen from Figure 2, the electrodes have lower terminal ends that extend into the passageway 28. Normally the ends of the electrodes are covered with the sterilizing liquid, which conducts electricity. Thus, when a voltage i s applied b etween them, current flows between the electrodes. However, when a bubble passes through the tube 28, the current flow between the electrodes is interrupted. Dust cap 20, shown in Figure 3, prevents dust from settling into the airlock when it is engaged with the top of airlock 12. Conducting members 21 connect to electrodes 40 and 42.

As illustrated in Figure 4, electrodes 40 and 42 are connected to control means 60 through conducting members 21. Control means 60 comprises control buttons 65A, 65B, 65C, 65D, and 65E, and a display 70. Bottle 18 contains wine must W. Control means 60 counts the number of times the current between electrodes 40 and 42 is interrupted. Control means 60 determines the status of the fermenting liquid based on the history of bubbles detected. Control means 60 displays the status of the fermenting liquid on display 70.

The interruption of the current between the electrodes is illustrated in Figure 5.

Bubble 50, created by the production of C02 during fermentation, envelops the exposed conductive material of both electrodes. Thus, with a low voltage drop across the electrodes, the gas does not conduct electricity between the electrodes. A preferred voltage drop across the electrodes i s approximately 5 V, although other voltage drops might b e suitable. T he control means of the apparatus records each interruption in the current as a bubble event.

Figure 6 is a schematic of an embodiment of the electrical circuit of the control means. The circuit shown comprises electrodes 40 and 42, a 5 V source, resistor 85, operational amplifier (op amp) 87, positive and negative power supplies V+ and V-to power the op amp, and processor 90. Processor 90 is a conventional microprocessor, well known to those in the electronics art. The 5 V source is connected across electrodes 40 and 42 through resistor 8 5. W hen c urrent e xists b etween the e lectrodes, V ;"_ i s 0 V. (The 5 V source is shorted to ground. ) However, when a bubble interrupts the current through the electrodes, Von is no longer zero. (Ground is separated from Vin boy an open circuit.) Vin+ is connected to ground. Thus processor 90 can determine the presence of a bubble between electrodes 40 and 42 from the output of operational amplifier 87.

Figure 7 shows a second possible embodiment of control means 60. This embodiment comprises a plurality of control buttons 65A, 65B, 65C, 6 5D, 6 5E, and 6 5F, electrodes 40 and 42, a 5 V source, resistor 89, pin 88 of processor 90, audio alarm 92, and visual alarm 94. Pin 88 of processor 90 is connected to electrode 40 and to a 5 V source through resistor 89. Electrode 42 is connected to ground. When current exists between the electrodes, pin 88 is shorted to ground. When the current is interrupted by a bubble, pin 88 will be lifted to a non-zero voltage. (The voltage level will depend on the resistance value of resistor 89). In this manner, processor 90 can determine the presence of bubbles between electrodes 40 and 42.

To use the above-described device, a measure volume of a liquid subject to fermentation, such as a wine-must, is placed in a container. (This is typically done after a period of aerobic fermentation and a hydrometer measurement to determine the proportion of sugar remaining. ) The airlock of the present invention is inserted in the neck of the container.

The user programs the volume of liquid present in the container using the control buttons.

In a preferred embodiment, control means 60 are configured as follows. First, the batch size must be set. Button 65A increases the batch size by 10 liters each time it is pushed. Button 65B increases the batch size one liter each time it is pushed. Button 65C accepts the batch size when it is pushed, if the batch size is non-zero. (Buttons 65D and 65E have no function in setup mode). After the batch size is set, the user can enter a user specified time alarm, to be activated when the enter amount of time passes without a bubble being detected. Button 65A increases this alarm time by one hour each time it is pushed.

Button 65B increases this alarm time by one minute each time it is pushed. Button 65C accepts the current alarm time. (Zero may be entered if no user specified time alarm is desired. ) When the user specified alarm is set, the user can then enter an alcohol alarm level.

Button 65A increases the alcohol level alarm by one percent each time it is pushed. Button 65B increases the a lcohol 1 evel a larm b y o ne t enth o f o ne p ercent e ach t ime i t i s p ushed.

Button 65C accepts the current alcohol level. After the alcohol level alarm is set, the user can activate the 24 hour alarm. Button 65A enables the 24 hour alarm. Button B disables the 24 hour alarm. Button 65C accepts the current 24 hour alarm status. The control means then detects the bubbles of gas escaping from the airlock and displays the status of the liquid on display 70.

The status is determined based on the history of bubbles detected by control means 60. In one embodiment, airlock 12 is configured such that the escaping bubbles have a volume at room temperature and 1 atmosphere of pressure of 1.7 ml. (It is assumed that the fermentation is done at a constant temperature, thus an equal amount of gas is contained in each bubble). Thus, by counting the number of bubbles, control means 60 can determine the amount of gas to escape from the airlock. According to calculations known in the art, the amount of alcohol generated during anaerobic fermentation can be determined based on the volume Of C02 generated (assuming substantially all of the escaping gas is COa generated by fermentation) and the amount of liquid present in the container (input using the control buttons, as discussed above). Accordingly, c ontrol m eans 6 0 c an c alculate the v olume o f alcohol generated and display this amount on display 70.

In a preferred embodiment the buttons of the control means function as follows. Button 65A scrolls the display of the bubble events towards the most current event.

Button 65B scrolls the display of the bubble events towards the least recent event. Button 65C deletes the display of the displayed event if pressed alone. Button 65D caused the control means to reenter setup mode. Button 65E silences current alarms and calls up a screen to review past alarms. Display 70 is set to the most recent event when button 65E is released. When buttons 65C and 65E are pressed simultaneously, past alarms are cleared.

As discussed above, a user can preprogram a percentage of alcohol desired with the control buttons. In this case, control means 60 displays a countdown of the amount of alcohol still to be generated. Control means 60 can include an audible alarm 94 and/or

visual alarm 96 to signal a user when the desired amount of alcohol has been produced. This can be especially useful in making beverages wherein some fermentation is desired after the liquid is bottled. The alarm can be set to alert the user when a portion of the desired alcohol has been produced. The user can then transfer the beverage to individual bottles for the remaining fermentation. This is also useful for the production of a sweet beverage. The user can stop fermentation before all the sugar has been consumed by the yeast. This alarm also allows a user to add further ingredients at different stages of the fermentation, such as the addition of malo-lactic cultures, nutrients, and other ingredients known in the art. The present invention allows for greater quality control in production by determining to a greater accuracy the proper time to add additional ingredients.

Control means 60 also includes timing means to determine the amount of time between each bubble. Counting means displays the amount of time since the last bubble on display 70. Audible and/or visible alarms can be activated to alert the user after a specified time without a bubble has been reached. In one embodiment, this time period is 24 hours. In another embodiment, this time period is set by the user using the control buttons (the user specified alarm discussed above).

A potential problem with fermentations that can take a long period of time is the evaporation of the sterilizing liquid. If the sterilizing liquid evaporated to the point wherein outside air may pass into vessel 18, then the fermentation may be spoiled. The present invention warns a user when the level of the sterilizing liquid is low. Electrodes 40 and 42 are placed in member 28 such that they are exposed to air before the liquid level drops to an extent that air could reenter vessel 18, as shown in Figure 2. Control means 60 times the length of the bubbles. If the sterilizing liquid has partially evaporated, then the electrodes will be exposed to air continuously. Thus, when control means 60 detects an interruption of the current that lasts an extended period of time (in one embodiment 1 hour), it displays a low liquid level warning on display 60. Audible and/or visible alarms may also be activated. In addition, bubble detection indicator 92 is lit when a bubble is being detected (when current is not flowing between electrodes 40 and 42. ) This can also allow a user to determine there is a problem if the bubble detection indicator remains lit for an extended period of time. The low liquid level warning and bubble detection indicator allow a user to replace the lost sterilizing liquid before the fermenting liquid is spoiled.

Figures 2,4, and 5 show the present invention being practiced with an"S"type airlock. However, it should be readily apparent to one skilled in the art that other airlocks or valves may be modified to practice the present invention. Figures 8-10 illustrate several valves known in the art. Figure 8 shows a flapper check valve 110. Electrodes 140 and 142 contact conducting strip 145 on flapper 115 when the valve is closed. Thus, when the valve is closed, current flows from electrode 140 to electrode 142 through strip 145. When flapper 115 is forced open by gas pressure, the current flowing between electrode 140 and electrode 142 is interrupted. Thus, the number of times gas escapes from the valve can be counted.

The amount of gas that escapes each time is measured and programmed into control means 60. In this manner, a fermentation process can be monitored as described above. In a similar manner, Figure 9 shows a piston check valve 210 comprising electrodes 240 and 242, and valve member 215 having conducting strip 245 on a surface thereon. When the valve is closed, current flows from electrode 240 to electrode 242 through strip 245. When member 215 is forced open by gas pressure, the current flowing between electrode 240 and electrode 242 is interrupted. Figure 10 shows ball check valve 310 comprising electrodes 340 and 342 and conducting ball 345. When the valve is closed, current flows from electrode 340 to electrode 342 through conducting ball 345. When ball 345 is forced up by gas pressure, the current flowing between electrode 340 and electrode 342 is interrupted. The amount of gas released each time the valve opens is used to determine how much gas is produced during fermentation, in the manner described above. These modifications, including the use of the practicing of the present invention with other valves not shown, is intended to be within the spirit and scope of the invention as claimed. In the present specification and claims, the word "airlock"is intended to mean any airlock or valve known in the art or hereafter developed that can be modified as described herein to practice the present invention.

An embodiment of the present invention may be arranged to have the elevation of the apparatus entered using the control buttons or through the communication means described below. The processing means adjusts the calculated alcohol percentage by volume based on the altitude of the apparatus. This corrected alcohol percentage by volume is used in computing the amount of alcohol present in the solution being fermented. An embodiment of the present invention can also include a flow rate alarm, where the flow rate, for example computed in cubic centimeters of alcohol produced per hour per liter of liquid, can be

corrected based on the elevation of the apparatus. When the flow rate of alcohol exceeds a threshold in put by a user, the alarm is sounded. This may be a visual or optical alarm, as discussed above. Software that implements the above-described functions is included in the appendix.

An embodiment of the present invention including communication means 480 is shown in Figure 11. Apparatus 410 comprises control means 460, display 470, and communication control means 475. Control means 460 comprises control buttons 465A, 465B, 465C, 465D, and 465E. Apparatus 410 also includes optical sensor 450 arranged to mate with portion 428 of airlock 412. Wire 448 connects sensor 450 to control means 460.

Airlock 412 contains sterilizing liquid SL. The display and control buttons function as described above for the first embodiment. Communication control means 475 communicates with information system 490 with communication means 480. Communication means 480 may comprise a hard wire or a wireless connection, both of which are known in the art.

Information system 490 may comprise a single personal computer, a local area network, a wide area network such as the Internet, a wireless phone system, a pager system, a personal digital assistant system, or any other information system known in the art. Thus, apparatus 410 is arranged to transmit and receive messages over communication means 480 to and from information system 490. (For example, the appendix contains a software listing that, when loaded on a general purpose microprocessor, transmits messages to a digital cellular phone.) The apparatus may receive parameters for programming the apparatus from the information system. Thus, a local personal computer, a computer connected to the Internet, a personal digital assistant, or any of the other information system known in the art may be used to program the present invention. The apparatus may transmit the status of any of the above- described alarms to any of the information systems known in the art. Thus, for example, a user can be warned by cell phone, pager, or personal digital assistant that the alcohol alarm is active. The status of the fermentation may be emailed to a user, or it may be posted on a website. The communication means can receive all of the parameters used to program the control means, as discussed above, such as altitude, batch size, user specified time alarm setting (alarm activated when no bubbles are detected for specified time), alcohol level alarm (alarm activated when alcohol level reaches specified level), and enabling/disabling the 24 hour alarm. The data received by the communication means can comprise commands to clear

any specific alarm, or all alarms. The data transmitted by the communication means can comprise: alcohol level, alarm status, time since the last bubble detection, bubble count, or any other parameter stored in the control means. It should be readily apparent to one skilled in the art that other parameters may be used by the control means, and these parameters may be sent over the communication means. These modifications are within the spirit and scope of the invention as claimed. The communication means may transmit messages using RS-232 protocol, Transfer Control Protocol/Internet Protocol (TCP/IP), Universal Serial Bus (USB) protocol, or any other protocol known in the art. (For example, the software listing in the appendix, when loaded on a conventional general purpose microprocessor, sends messages using the RS-232 protocol. ) It should be readily apparent to one skilled in the art that other communication means and information systems are possible, and these modifications are within the spirit and scope of the invention as claimed.

An embodiment of the present invention may also be configured to log the data sent to and received form the control means. This allows a user to evaluate the batch either by comparison to an ideal fermentation, or comparison to other fermentation batches, for example graphically. It should be readily apparent to one skilled in the art that data from the present invention can be logged into a database program and displayed graphically, with commercially available software packages, as described above.

Figure 12 illustrates an embodiment of the present invention wherein communication control means 475 sends and receives data from multiple control means 460A, 460B, and 460C. Communication control means 475 communicates with information system 490 over communication means 480. Communication control means 475 comprises at least one port 477. As shown in Figure 12, control means 460A, 460B, and 460C are each connected to communication control means 475. The connection is made by connecting wire 478 between port 477 of communication control means 475 and port 462 of control means 460A, 460B, and 460C, respectively. Figure 13 shows another embodiment of the present invention wherein control means 460A, 460B, and 460C are daisy chained together. Control means 460A is connected to control means 460B with a wire 478 connected between port 462 of control means 460A and port 462 of control means 460B. Control means 460B is connected to control means 4 60C w ith a w ire 4 78 c onnected b etween p ort 4 62 o f c ontrol means 460B and port 462 of control means 460C. Control means 460C is connected to

communication control means 475 with a wire 478 connected between port 462 of control means 460C and port 477 of communication control means 475. As should be readily apparent to one skilled in the art, any combination of direct connections to a communication control means and daisy chaining multiple control means are possible, and these modifications are within the spirit and scope of the invention as claimed. The present invention may also be practiced as shown in Figure 11, wherein communication control means 475 is integral with control means 460. In this case, each control means 460 communicates with the information system 490 through its respective communication control means 475. It should be readily apparent to one skilled in the art that the control means 460 shown in Figures 12 and 13 may comprise optical sensors as shown in Figure 11, or may comprise two electrodes, as shown in Figure 4. Any bubble counting apparatus comprising communication means for transmitting and receiving data to and from an information system is within the spirit and scope of the invention as claimed.

Figure 14 is a schematic of an exemplary embodiment of an electrical circuit for an embodiment of the present invention comprising optical sensor 450. Sensor 450 comprises optical beam emitter 452 and optical beam detector 454. In the embodiment shown, emitter 452 is an LED and detector 454 is a phototransistor. Beam emitter 452 emits a light beam towards detector 454. The beam passes through the wall 428A of airlock portion 428. Wall 428A is normal to the line connecting emitter 452 and detector 454. Thus, the beam enters the interior of airlock portion 428 normal to the surface of wall 428A. If no bubble is present in the sterilizing liquid, the beam passes through the sterilizing liquid, through wall 428B of the airlock portion 428, and is incident on detector 454. When light is incident on phototransistor 454, current may flow through the phototransistor. This shorts connection 456 to ground. When bubble 50 passes through airlock portion 428, the edges 52 will refract the incident light that is propagating in a direction normal to walls 428A and 428B in a direction that is not normal to walls 428A and 428B. Thus, when bubble edge 52 is located between emitter 452 and detector 454, light will not be incident on detector 454. This disables current from flowing through phototransistor 454, which isolates pin 456 from ground. The 5 V source pulls pin 456 up to 5 V. When the bubble is between the emitter and detector, the beam passes through the gas mixture to the detector. This allows current to flow through the phototransistor, pulling pin 456 down to 0 V. Thus, for each bubble that passes

through airlock portion 428, the light beam will be interrupted briefly twice by each bubble edge 52, leading to two voltage pulses of 5V, compared to the normal value of OV. Pin 456 is connected to a general purpose microprocessor programmed to monitor the voltage transitions at pin 456 between 0 V and 5 V. Thus, the processor increments the bubble count by 1 for each pair of interruptions of the light beam (each pair of 5 V pulses at pin 456). Optical sensor 450 may comprise a sensor such as the Omron (g) EE-SX198, EE-SX199, EE-SX1018, EE-SX1025, EE-SX1041, EE-SX1042, E-SX1070, or EE-SX1071, available from Omron Corporation, Shiokoji Horikawa, Shimogyo-ku, Kyoto, 600-8530 Japan. The processor is programmed to use the bubble count as described above for the first embodiment. The appendix contains a software listing for a processor using the optical sensor of the present embodiment.

It should be readily apparent to one skilled in the art that any airlock may be used with the embodiment comprising an optical sensor, providing it comprises a portion with two parallel sides. For example, Figures 15 and 16 show optical sensor 450 arranged to detect bubbles passing through airlock portion 428 having two parallel sides 428A and 428B, and two arcuate sides 428C. Figures 17 and 18 show optical sensor 450 arranged to detect bubbles passing through airlock portion 428 having a rectangular cross section, with two parallel sides 428A and 428B and two parallel sides 428Dthatareperpendiculartosides 428A and 428B. Figures 19 and 20 show optical sensor 450 arranged to detect bubbles passing through airlock portion 428 having two parallel sides 428A and 428B, and sides 428E that form a hexagonal cross section. It should be readily apparent to one skilled in the art that airlocks having portions with cross sections of other shapes, with two parallel sides are possible, and these modifications are within the spirit and scope of the invention as claimed.

While a preferred form of this invention has been described above and shown in the accompanying drawings, it should be understood that applicant does not intend to be limited to the particular details described above and illustrated in the accompanying drawings, but intends to be limited only to the scope of the invention as defined by the following claims.

In this regard, the term"means for"as used in the claims is intended to include not only the designs illustrated in the drawings of this application and the equivalent designs discussed in the text, but it is also intended to cover other equivalents now known to those skilled in the art, or those equivalents which may become known to those skilled in the art in the future.

COMPUTER PROGRAM LISTING APPENDIX The computer program listing appendix is hereby expressly incorporated by reference in the present application.

Filename: Fermentometer Interface3. vbp Size: 2 kilobytes Date Created: August 20,2003 Filename: Main2. frm Size: 61 kilobytes Date Created: August 20, 2003 Filename : Modulel. bas Size: 1 kilobyte Date Created: August 20,2003 Filename: patentOl. c Size: 20 kilobytes Date Created: August 20,2003 Filename: he 1 l. h Size: 4 kilobytes Date Created: August 20,2003 Filename : const. h Size: 1 kilobyte Date Created: August 20,2003 Filename : stdio. h Size: 1 kilobyte Date Created: August 20,2003 _const. h &num -ifndef CONSTH #defing _ CONST_H &num if defined(_AVR) ## defined (_M8C) #define CONST #else #define CONST const &num endif #endif Type=Exe Object= {F9043C88-F6F2-101A-A3C9-08002B2F49FB} #1. 2#0i COMDLG32. 0CX Object= {BDC217C8-ED16-llCD-956C-OOOOC04E4COA} #1. 1#0 ; TABCTL32. 0CX Object= {3B7C8863-D78F-101B-B9B5-04021C009402} #1. 2#0 ; RICHTX32. 0CX Object= {6B7E6392-850A-101B-AFCO-4210102A8DA7} 13#0 ; COMCTL32. 0CX Object= {FAEEE763-117E-101B-8933-08002B2F4F5A} #1. 1#0 ; DBLIST32. 0CX Object= {00028C01-0000-0000-0000-000000000046} #1. 0#0 ; DBGRID32. 0CX Reference=*\G {00020430-0000-0000-COOO-000000000046} #2. 0#0#.. \WINDOWS \SYSTEM\StdOle2. Tlb#Standard OLE Types Reference=*\G {EE008642-64A8-llCE-920F-08002B369A33} #1. 0#0#.. \WINDOWS \SYSTEM\MSRD032. DLL#Microsoft Remote Data Object 1. 0 Object= {648A5603-2C6E-101B-82B6-000000000014} #1. 1#0 ; MSCOMM32. 0CX Reference=*\G {00025E01-0000-0000-C000-000000000046} #4. 0#0#.. \PROGRAM FILES\COMMON FILES\MICROSOFT SHARED\DAO\DA0350. DLL#Microsoft DAO 3. 0 Object Library Object= {20C62CAE-15DA-lOlB-B9A8-444553540000} #1. 1#0 ; MSMAPI32. 0CX Form=Main2. frm Module=Modulel ; Modulel. bas IconForm="frmMain" Startup="frmMain" ExeName32="FermentometerInterface3. exe" Command32="" Name="Projectl" HelpContextID="0" CompatibleMode="0" MajorVer=l Minorer=0 RevisionVer=0 AutoIncrementVer=0 ServerSupportFiles=0 VersionCompanyName="Preferred Company" CompilationType=0 OptimizationType=0 FavorPentiumPro (tm) =0 CodeViewDebugInfo=0 NoAliasing=0 BoundsCheck=0 OverflowCheck=0 FlPointCheck=0 FDIVCheck=0 UnroundedFP=0 StartMode=0 Unattended=0 Retained=0 ThreadPerObject=0 MaxNumberOfThreads=l Hcll. h #-ifndef HC11H #define _ HCll_H 1 #define _IO_BASE 0x1000 #define PORTA * (unsigned char volatile *) (IOBASE + 0x00) #define PIOC * (unsigned char volatile *) (_IO_BASE + 0x02) #define PORTC * (unsigned char volatile *) (_IO_BASE + 0x03) #define PORTB * (unsigned char volatile *) (IOBASE + 0x04) #define PORTCL * (unsigned char volatile *) (_IO_BASE + 0x05) #define DDRC (unsigned char volatile *) (IOBASE + 0x07) #define PORTD * (unsigne char volatile *) (_IO_BASE + 0x08) #define DDRD * (unsigne char volatile *) (IOBASE + 0x09) #define PORTE * (unsigned char volatile *) (_IO_BASE + OxOA) #define CFORC * (unsigned char volatile *) (_IO_BASE + OxOB) #define ocCmM * (unsigned char volatile *) (_IO_BASE + OxOc) #define OdD''' (unsigned char volatile *) (IOBASE + 0X0D) #define TCNT * (unsigne short volatile *) (_ IO_ BASE + OxOE) #define TIC1 * (unsigned short volatile *) (_IO_BASE + 0x10) #define TIC2 * (unsigned short volatile *) (_IO_BASE + 0x12) #define TIC3 * (unsigned short volatile *) (_IO_BASE + 0x14) #define TOC1''' (unsigned short volatile *) (_IO_BASE + 0x16) #define Toc2 * (unsigned short volatile *) (_IO_BASE + 0x18) #define Toc3 * (unsigned short volatile *) (_IO_BASE + 0x1A) #define Toc4 * (unsigned short volatile *) (_IO_BASE + Oxim) #define Toc5 * (unsigned short volatile *) (_IO_BASE + 0x1E) #define TCTL1 * (unsigne char volatile *) (_IO_BASE + 0x20) #define TCTL2 * (unsigne char volatile *) (IOBASE + 0x21) #define TMSK1 * (unsigne char volatile *) (_IO_BASE + 0x22) #define TFLG1 * (unsigned char volatile *) (_IO_BASE + 0x23) #define TMSK2 * (unsigned char volatile *) (IOBASE + 0x24) #define TFLG2''' (unsigned char volatile *) (_IO_BASE + 0x25) #define PACTL * (unsigne char volatile *) (IOBASE + 0x26) #define PACNT * (unsigne char volatile *) (_IO_BASE + 0x27) #define SPCR * (unsigne char volatile *) (_IO_BASE + 0x28) #define SPSR * (unsigne char volatile *) (_IO_BASE + 0x29) #define SPDR * (unsigned char volatile *) (_IO_BASE + Ox2A) #define BAUD''' (unsigned char volatile *) (_IO_BASE + Ox2B) #define SCCR1 * (unsigne char volatile *) (_IO_BASE + Ox2c) #define SCCR2 * (unsigne char volatile *) (_IO_BASE + Ox2D) #define SCSR * (unsigne char volatile''') (IOBASE + Ox2E) #define SCDR * (unsigne char volatile *) (_IO_BASE + Ox2F) #define ADCTL * (unsigned char volatile *) (_IO_BASE + 0x30) #define ADR1 * (unsigned char volatile *) (_IO_BASE + 0x31) #define ADR2 * (unsigned char volatile*) ( ! 0BASE + 0x32) #define ADR3 * (unsigne char volatile *) (_IO_BASE + 0x33) #define ADR4 e (unsigned char volatile *) (_IO_BASE + 0x34) #define OPTION * (unsigned char volatile *) (_IO_BASE + 0x39) #define COPRST * (unsigne char volatile *) (_IO_BASE + Ox3A) #define PPROG (unsigned char volatile *) (_IO_BASE + Ox3B) #define HPRIO (unsigned char volatile *) (_IO_BASE + Ox3c) #define INIT * (unsigned char volatile *) (_IO_BASE + Ox3D) #define TEST1 * (unsigned char volatile *) (_IO_BASE + Ox3E) #define CONFIG * (unsigned char volatile *) (_IO_BASE + Ox3F) unsigned int read_sci (void) ; unsigned char read-spi (void) ; void writeeeprom (unsigned char *addr, unsigned char c) ; void write_sci (unsigned int) ; void write spi (unsigned char) ; typedef enum { BAUD9600 = 0x30, BAUD4800 = 0x31, BAUD2400 ; = 0x32, BAUD1200 = 0x33, BAUD600 = 0x34, BAUD300 = 0x35 } BaudRate ; void setbaud (BaudRate) ; Hcll. h #ifndef INTR_ON #define INTR_ON () asm (" cli") #define INTR_OFF () asm (" sei") #endif #ifndef bit #define bit (x) (1 << (x)) #endif #ifdef _SCI #define RDRF bit (5) #define TDRE bit (7) #define T8 bit (6) #define R8 bit (7) #endif #ifdef sPI #define MSTR bit (4) #define SPE bit (6) #define SPIF bit (7) #endif #ifdef EEPROM #define EEPGM bit (O) #define EELAT bit (1) #endif #endif Attribute VB Name ="Modulel" Option Explicit Public strIn As String Public strRaw As String Public strTemp As String Public strToSend As String Public strToChange As String Public strMessage As String Public strMessageAddress As String Public strSegment (0 To 14) As String Public iResponse (0 To 14) As Integer Public I As Integer Public iCharector As Integer Public iCurrentPoll As Integer Public iChangeSend As Integer Public iResetSend As Integer Public MyTime As Single Public strEvent As String Public ReturnValue As String Public Entry As String Public Device As String Public MyWorkspace As Workspace Public MyDatabase As Database Public MyTable As Recordset Public MyFile As String Public dtLastBubble As Date Public dtNextLastBubble As Date Public dtToDisplay As Date Public iCommunication As Integer Public longRecordCount As Long patentO1. c #include <hcll. h> #include <stdio. h> #define REG-BASE Ox1000 #define LINE_1 Ox80//beginning position of LCD line 1 #define LINE_2 OxCO//beginning position of LCD line 2 #define LINE_3 Ox94//beginning position of LCD line 3 #define LINE_4 OxD4//beginning position of LCD line 4 #define LCDCMD * (unsigned char *) (_Io_BASE + OxA5FO) #define LCDDAT- (unsigned char *) (_Io_sAsE + OxA5F1) #define RDRF Ox20 f static long alcoholnow, useralarm, flowrate, flowtemp, templong, lbatl, lbatlO ; static long sys_clkl, s s_clk2, sys_clk3, flowalarm ; static long factor, interval [51] = {0} ; static int elevation, alcohol, batsizel, batsizel0, sentint, startset, iskipset, ibubbleskip ; static int iflowactive, iuserhour, iusermin, iuseractive, ialcoholone, ialcoholtenth ; static int ialcoholactive, i24houralarm, ialarmlatch, ievent, idisplay, alarmon ; static int iflowhour, iflowmin, i24occured, iuseroccur, ilowoccur, ialcoholoccur, i, j, 1, m, n, o, p, q, ichdum, s ; static char t rlEl4], rElO] =1'1','Pl,'N','N','N','N,'N', 'N', Ox7B,'\0'}, *rpomt ; static char incoming [18] = {'\0'}, num, device [2] = {'1','\0'}, testchr = {Ox7B}, *sptrn, *chdummy ; void LCD_Command (unsigned char cval) ; void LCD_busy (void) ; void cprint (char dval) ; void LCDprint (char *sptr) ; void delayl0ms (unsigned int secs) ; void intprint (void) ; void timeprint (void) ; void flowprint (void) ; void alcoholprint (void) ; void alarmprint (void) ; char sci_getch () ; void Deviceu (char *chdummy) ; #pragma interrupt_handler Ti meHandle_IsR void TimeHand1elSR () { TFLG2 = Ox80 ; ++sys_clkl ; ++sys clk2 ; ++sysc1k3 ; I #pragma interrupt-handler ScIReceive_ISR void SCIReceive_ISR () { incomming [ichdum] = sci_getch () ; ichdum++ ; if ( (incomming [ichdum-1] == testchr) l} (ichdum == 15)) { inconiming [ichdum-1] ='\0' ; chdummy = &incomming [O] ; Deviceu (chdummy) ; }} #pragma interrupt-handler Dummy_ISR void Dummy_ISR () { Page 1 patentO1. c main () { asm ("sei") ; sys_clkl =0 ; sys_clk2 =0 ; sys_clk3 =0 ; alcoholnow = 0 ; ibubbleskip = 0 ; i24houralarm = 1 ; ievent = 1 ; i24occured = 0 ; iuseroccur = 0 ; ilowoccur = 0 ; ialcoholoccur = 0 ; startset = 1 ; elevation = 0 ; iflowhour = 0 ; iflowmin = 0 ; rl [0] ='1'; rl [l]'c' ; rl [ll] testchr ; rl [12] ='\0'; PACTL = Ox80 ; TCTL2 = Ox06 ; TFLG1 = ou01 ; TMSK2 oxo ; TFLG2 = 0x80 ; DDRD= 0x20 ; BAUD = Ox30 ; SCCR1 = Ox00 ; SCCR2 = Ox2C ; asm ("cli") ; LCD_Command (Ox3C) ; LCD_Command (OxOC) ; LCD-Command (OxO6) ; LCD_Command (0x01) ; PORTD ! = 0x20 for ( ;) I While ( ( (PORTD & 0x08) 8) (startset LCD_Command (Ox01) ; LCD_Command (LINE_1) ; LCDprint ("Elevation Sea Level LCD_Command (LINE_2) ; LCDprint ("Top left add 1000's") ; LCD_Command (LINE_3) ; LCDprint ("Top right sub 1000's") ; LCD_Command (LINE_4) ; LCDprint (" Bottom left accept") ; if (elevation > 0) { LCD_Command (LINE_1) ; LCDprint ("Elevation 0, 000 feet") ; LCD_Command (Ox89) ; sentint = elevation ; intprinto ; LCDCommand (Ox89) ; LCDprint ("") ; sys_clk3 = 0 ; delayl0ms (50) ; do if (((PORTE & Ox02) == 2) && (sys_clk3 > 16)) { patentOl. c sys_clk3 = 0 ; elevation++ ; if (elevation >= 10) { elevation = 0 ; LCD_Command (LINE_1) ; LCDprint ("Elevation Sea Level") ; if (elevation > 0) { LCD_Command (LINE_1) ; LCDprint ("Elevation 0, 000 feet") ; LCD_Command (Ox89) ; sentint = elevation ; intprint () ; LCD_Command (Ox89) ; LCDprint ("") ; if ( ( (PORTE & Ox01) == 1) && (sys_clk3 > 16) && (elevation > 0)) { sys_clk3 = 0 ; elevation-- ; LCD_Command (LINE_1)- LCDprint ("Elevation Sea Level") ; if (elevation > 0) { LCD_Command (LINE_1) ; LCDprint ("Elevation 0, 000 feet") ; LCDCommand (Ox89) ; sentint = elevation ; intprint () ; LCD_Command (Ox89) ; LCDprint ("") ; } while (((poRTE & Ox04) == 0) && (sys-clk3 < 908)) ; LcD-command (LINE-l) ; LCDprint ("Batch size OOliters") ; LCD_Command (LINE_2) LCDprint (" Top left add tens") ; LCD-Command (LINE-3) ; LCDprint (" Top right add ones") ; LCD_Command (LINE_4) ; LCDprint (" Bottom left accept") ; LCD_Command (Ox8B) ; sentint = batsizel + batsizel0 * 10 ; intprint () ; sys_clk3 = 0 ; delayl0ms (50) ; do { if ( ( (PORTE & Ox01) == 1) && (sys_clk3 > 16)) { sys_clk3 = 0 ; batsizel0++ ; if (batsizel0 >= 10) { batsizel0 = 0 ; LCD_Command (Ox8B) ; sentint = batsizel + batsizel0 * 10 ; intprint () ; delaylOms (1) ; if (((PORTE & Ox02) == 2) && (sys_clk3 > 16)) { sys_cll<3 = 0 ; batsizel++ ; patentO1. c if (batsizel >= 10) { batsizel = 0 ; I LCD_Command (Ox8B) ; sentint = batsizel + batsizelO * 10 ; intprint () ; delayl0ms (1) ; if ( (batsizel + batsizelO) < 1) { batsizel = 1 ; LCD_Command (Ox8B) ; sentint = batsizel + batsizelO * 10 ; intprint () ; } While (((PORTE & Ox04) == 0) && (sys_clk3 < 908)) ; LCD-Command (LINE-l) ; LCDprint ("User Alarm OOhr OOm") ; LCD_Command (LINE_2) ; LCDprint (" Top left add hours") ; LCD-Command (LINE-3) ; LCDprint (" Top right add mins") ; LCD_Command (LINE_4) ; LCDprint (" Bottom left accept") ; LCD_Command (Ox8B) ; sentint = iuserhour ; intprint () ; LCD_Command (Ox90) ; sentint = iusermin ; intprint () ; iski pset = O ; delaylOms (50) ; while ( ( (PORTE & Ox04) == O) && (sys_ clk3 < 908)) { if ( ( (PORTE & Ox01) == && (sys-clk3 > 16)) { sys_clk3 = 0 ; iuserhour++ ; if (iuserhour >= 24) { iuserhour = 0 ; I LCD_Command (Ox8B) ; sentint = iuserhour ; intprint () ; delayl0ms (1) ; if ( ( (PORTE & OxO2) == 2) && (sys_clk3 > 16)) { sys_cll<3 = 0 ; iusermin++ ; if (iusermin >= 60) { iusermin = 0 ; LCD_Command (Ox90) ; sentint = iusermin ; intprint () ; delaylOms (l) ; LCDCommand (LINE_1) ; LCDprint ("Flow SetOO. 00CC/hr/l") ; LCD_Command (LINE_2) ; LCDprint ("Top left add std CC") ; LCD_Command (LINE_ 3) ; LCDprint ("Top right add. 01 CC") ; patentO1. c LCD_Command (LINE_4) ; LCDprint (" Bottom left accept") ; LCD_command (Ox88) ; sentint = iflowhour ; intprint () ; LCD_Command (Ox8B) ; sentint = iflowmin ; intprint () ; iskipset = 0 ; delaylOms (50) ; while (((PORTE & Ox04) == O) && (sys_clk3 < 908)) { if ( ( (PORTE & Ox01) == 1) && (sys_clk3 > 16)) { sys_clk3 = 0 ; iflowhour++ ; if (iflowhour >= 20) { iflowhour = 0 ; I LCD_Command (Ox88) ; sentint = iflowhour ; intprint () ; del ayloms (l) if ( ( (PORTE & Ox02) == 2) && (sys_clk3 > 16)) { sys_clk3 = 0 ; iflowmin++ ; if (iflowmin >= 100) { iflowmin = 0 ; I LCD_Command (Ox8B) ; sentint = iflowmin ; intprinto ; } delaylOms (1) ; Ja LCD_Command (LINE_1) ; LCDprint ("Alcohol Alarm 00. 0%") ; LCD_Command (LINE_2) ; LCDprint ("Top left add ones") ; LCD_Command (LINE_3) ; LCDprint (" Top right add tenth") ; LCD_Command (LINE_4) ; LCDprint (" Bottom left accept") ; LCD_Command (Ox8E) ; sentint = ialcoholone ; intprint () ; sentint = ialcoholtenth ; intprint () ; LCD_Command (Ox90) ; LCDprint (".") ; iskipset = 0 ; delayl0ms (50) ; while ( ( (PORTE & Ox04) 0) && (sys-clk3 <'908)) l if (((PoRTE & Ox01) == 1) && (sys_clk3 > 16)) { sys_clk3 = 0 ; ialcoholone++ ; if (ialcoholone >= 18) { ialcoholone = 0 ; LCD_Command (Ox8E) ; sentint = ialcoholone ; patentO1. c intprint () ; sentint = ialcoholtenth ; intprint () ; LCD_Command (Ox90) ; LCDprint (".") ; delaylOms (1) ; if (((PoRTE & Ox02) == 2) && (sys_clk3 > 16)) { sys_clk3 = 0 ; ialcoholtenth++ ; if (ialcoholtenth >= lo) f ialcoholtenth = 0 ; I LCD_Command (Ox8E) ; sentint = ialcoholone ; intprint () ; sentint = ialcoholtenth ; intprint () ; LCD_Command (Ox90) ; LCDprint (".") ; delaylOms (l) ; LCD_Command (LINE_1) ; LCDprint ("24HourAlarm Enabled") ; LCD_Command (LINE_2) ; LCDprint (" Top left Enable") ; LCD_Command (LINE3) ; LCDprint ("Top right Disable") ; LCD_Command (LINE_4) ; LCDprint (" Bottom left accept") ; if (i 24houralarm == O) { LCD_Command (LINE_1) ; LCDprint ("24HourAlarm Disabled") ; if (i 24houralarm == 1) { LCD-Command (LINE-l) ; LCDprint ("24HourAlarm Enabled") ; delayl0ms (50) ; while ( ( (PORTE & Ox04) == 0) && (sys_clk3 < 908)) { if ( ( (PORTE & Ox01) == 1) && (sys_cilc3 > 16)) { sys_clk3 = 0 ; LCD_Command (LINE_1) ; LCDprint ("24HourAlarm Enabled") ; i24houralarm = 1 ; delaylOms (1) ; if (((PORTE & Ox02) == 2) && (sys-clk3 > 16)) { sys_clk3 = 0 ; LCDcommand (LINEJ.) ; LCDprint ("24HourAlarm Disabled") ; i24houralarm = 0 ; delayl0ms (1) ; startset = 0 ; idisplay = 1 ; r [71 = if (elevation == 0) patentOl. c factor = 10000 ; if (elevation == 1) { factor = 9646 ; 1 if (elevation == 2) { factor = 9248 ; 1 if (elevation == 3) { factor = 8961 ; 1 if (elevation == 4) { factor = 8636 ; 1 if (elevation == 5) { factor = 8319 ; if (elevation == 6) { factor = 8014 ; 1 if (elevation =-7) factor = 7717 ; 1 if (elevation == 8) { factor = 7426 ; } if (elevation == 9) { factor = 7146 ; } iuseractive = 0 ; if ( (iuserhour > 0) II (iusermin > 0)) { iuseractive = 1 ; useralarm = ((iuserhour * 60) + iusermin) * 183108 ; useralarm = useralarm/100 ; iflowactive = 0 ; if ((iflowhour > 0) II (iflowmin > 0)) { iflowactive = 1 ; lbatl = iflowmin + (iflowhour * 100) ; lbatl = lbatl % 20000 ; lbatlO = batsizel + (batsizelO * 10) ; lbatl0 = lbatlO % 20000 ; flowalarm = 18677043/ (lbatl * lbatl0) ; flowalarm = flowalarm/100 * factor/100 ; ialcoholactive = 0 ; if ((ialcoholone > 0) (ialcoholtenth > 0)) { ialcoholactive = 1 ; alcohol ialcoholone 10 + ialcoholtenth ; I rl [2] = batsizel + batsizelO 10 + 23 ; rl [3] = iuserhour + 23 ; rl [4] = iusermin + 23 ; rl [5] = ialcoholone + 23 ; rl [6] = ialcoholtenth + 23 ; rl [7] = i24houralarm + 23 ; rl [81 = elevation + 23 ; ri'9'= iflowhour + 23 ; rl [10] = iflowmin + 23 ; delaylOms (50) ; } if (((PoRTE & Ox10) _= OxlO) && (sys_clkl > 61) && (ibubbleskip == 0)) flowrate = sys_clkl ; patentO1. c interval [0] = flowrate ; for (1=50 ; 1>0 ; 1--) { interval [1] =interval [1-1] ; ibubbleskip = 1 ; ievent = 1 ; sys_clkl = 0 ; alcoholnow++ ; r [2] ='Y' ; idisplay = 1 ; delaylOms (5) ; ibubbleskip =- (PORTE & Ox10) ; if (sys_clk2 > 30) { if (alarmon == 1) { PORTA A= 0x10 ; if (alarmon == 0) { PORTA &=-OX10 ; sys_clk2 = 0 ; if ((PoRTE & OX10) == OxlO) { PORTA ! = 0x20 ; if ((PORTE & OX10) == O) { PORTA &=-Ox2O ; if ((sys_clkl > 2636759) && (i24houralarm == 1) && (i24occured == 0)) { interval [O] =sys_clkl ; for (1=50 ; 1>0 ; 1--) { interval [l] =interval [l-1] ; } sys_clkl=O ; i24occured = 1 ; idisplay = 1 ; LCD_Command (LINE_4) ; LCDprint ("HYDROMETER CHECK") ; r [4] ='Y' ; ialarmlatch = 1 ; alarmon = 1 ; if ((sys_clk1 > useralarm) && (iuseroccur == 0) && (iuseractive LCD_Command (LINE_4) ; LCDprint ("SPECIFIED ALARM") ; | r [5] ='Y'; ialarmlatch = 1 ; alarmon = 1 ; iuseroccur = 1 ; if ((sys_cilel > flowalarm) && (ilowoccur == O) && (iflowactive == 1)) { LCD_Command (LINE_4) ; LCDprint ("USER SPECIFIED FLOW") ; r [3] ='Y ; ialarmlatch = 1 ; alarmon = 1 ; ilowoccur = 1 ; if ( (idisplay == 1) && (ialarmlatch == 0) && ( (PORTE & Ox08) == O)) { LCD-Command (LINE-l) ; LCDprint ("Interval") ; sentint = ievent ; intprint () ; patentO1. c LCDprint) ; flowrate = interval [ievent] ; timeprint () ; LCD_Command (LINE_2) ; LCDprint ("Rate") ; LCD_Command (Oxc5) ; lbatl = batsizel % 1000 ; lbatlO = batsizelO % 1000 ; flowrate = (interval [ievent] * (lbatl + (lbatlO * 10))) * 10/17 ; flowprint () ; LcD_command (LINE_3) ; LCDprint ("Alcohol change flowrate = alcoholnow/ ( ( (41000000/17) * (lbatl + (lbatlO * 10)))/factor) ; alcoholprint () ; idisplay = 0 ; if ((sys_clk3 > 31) && (ialarmlatch == O) && ( (PORTE & Ox08) == O)) { flowrate = sys_clkl ; LCD_Command (LINE_4) ; LCDprint ("since Last") ; timeprint () ; sys_clk3 = 0 ; I if ((PoRTE & OX08) == 8) { ialarmlatch = 0 ; alarmon = 0 ; alarmprint () ; ievent = 1 ; if ((PORTD & Ox10) == Ox10) { i24occured = 0 ; iuseroccur = 0 ; ilowoccur = 0 ; ialcoholoccur = 0 ; delaylOms (1) ; idisplay = 1 ; I I if ( ( (PORTE & Ox01) == 1) && (ievent > 1) && (iskipset == 0)) f ievent-- ; iskipset = 1 ; delay10ms (1) ; idisplay = 1 ; if ( ( (PORTE & Ox02) == 2) && (ievent < 50) && (iskipset == O)) { ievent++ ; if (interval [ievent] == O) { ievent-- ; iskipset = 1 ; idisplay = 1 ; delaylOms (1) ; } if ((PORTE & Ox07) == 0) { iskipset = 0 ; if (sys_clkl > 6480099) { sys_clkl = 4860074 ; if (sys_clk2 > 6480099) { sys_clk2 = 4860074 ; 1 if (sys_clk3 > 6480099) { patentO1. c sys_clk3 = 4860074 ; !' void LCD_busy () { while ((LCD_CMD & Ou80)) ; void LCD_Command (unsigned char cval) { LCD_busy () ; LCD_CMD = cval ; I void cprint (char dval) { LCD_busy () ; LCD_DAT = dval ; void LCDprint (char *sptr) { while (*sptr) { cprint (*sptr) ; ++sptr ; void delaylOms (unsigned int secs) { if (secs > O) { for (j=0 ; j<=secs ; j++) for (i=O ; i<730 ; i++) ; } void intprint () { m = sentint/10 ; n = sentint % 10 ; num = m + 48 ; *sptrn = num ; cprint (*sptrn) ; num = n + 48 ; *sptrn = num ; cprint (*sptrn) ; I void timeprint () { o = flowrate/109865 ; flowrate = flowrate % 109865 ; p = flowrate/1832 ; flowrate = flowrate % 1832 ; q = (flowrate * 100)/3052 ; sentint = o ; intprint () ; LCDprint (" :") ; sentint = p ; intprint () ; LCDprint (" :") ; sentint = q ; intprint () ; LCDprint ("") ; void flowprint () { o = 0 ; patentO1. c p =0 ; q = O ; if (flowrate >= 60) { flowtemp = flowrate * 10 ; flowrate = 109864960/flowtemp ; o = flowrate/10000 ; flowrate = flowrate % 10000 ; p = flowrate/100 ; flowrate = flowrate % 100 ; q = flowrate ; sentint = o ; intprint () ; sentint = p ; intprintQ ; LCDprint (".") ; sentint = q ; intprint () ; } LCDprint (cc/hr/l") ; voi d alcoholprint () { if (flowrate <= 200) { o = flowrate % 20000 ; o = o/10 ; p = flowrate % 10 ; LCDcommand (OxA3) ; sentint = o ; intprint () ; sentint = p ; intprint () ; LCD_Command (OXA5) ; LCDprint (".") ; LCD-Command (OxA7) ; LCDpri nt ("%") ; if ( ( ( (o * 10) + p) >= alcohol) && (ialcoholoccur 0) && (ialcoholactive 1)) { LCD-Command (LINE-4) ; LCDprint ("ALCOHOL LEVEL ALARM") ; r [6 ='Y ; ialarmlatch = 1 ; alarmon = 1 ; ialcoholoccur = 1 ; idisplay = 1 ; } else { LCD_Command (LINE_3) ; LCDprint ("CONFIRM BATCH SIZE !") ; } void alarmprintof LCD_Command (LINE_1) ; if (i24occured == 1) { LCDprint ("YES HYDROMETER CHECK") ; if (i24occured == 0) { LCDprint ("NO HYDROMETER CHECK") ; LCD_Command (LINE2) ; if (ilowoccur == 1) { LCDprint ("YES SPECIFIED FLOW") ; patentO1. c if (ilowoccur == 0) { LCDprint ("NO SPECIFIED FLOW") ; LCD_Command (LINE_3) ; if (ialcoholoccur == 1) { LCDprint ("YES ALCOHOL ALARM if (ialcoholoccur == 0) { LCDprint ("NO ALCOHOL ALARM") ; LCD_Command (LINE_4) ; if (iuseroccur == 1) { LCDprint ("YES SPECIFIED ALARM if (iuseroccur == 0) { LCDprint ("NO SPECIFIED ALARM } char sci_getch () while ( ! (SCSR & RDRF)) ; return SCDR ; void DeviceU (char *chdummy) I if (*chdummy == device [O]) { chdummy++ ; if (*chdummy =='S') { s = incomming [2]-Z3 ; iuserhour = incomming [3]-23 ; iusermin = incomming [4]-23 ; ialcoholone = incomming [5]-23 ; ialcoholtenth = incommlnqC6]-23 ; i24houralarm = incommin 7]-23 ; elevation = incomming [8-23 ; iflowhour = incommin ? E9]-23 ; iflowmin = incomming 10]-23 ; batsizel0 = s/10 ; batsizel = s % 10 ; if (elevation == O) { factor = 10000 ; I if (elevation == 1) { factor = 9646 ; if (elevation == 2) { factor = 9248 ; if (elevation == 3) { factor = 8961 ; if (elevation == 4) { factor = 8636 ; if (elevation == 5) { factor = 8319 ; 1 if (elevation == 6) { factor = 8014 ; patentOl. c if (elevation == 7) { factor = 7717 ; if (elevation == 8) { factor = 7426 ; if (elevation == 9) { factor = 7146 ; iuseractive = 0 ; if ( (iuserhour > O) 11 (iusermin > 0)) { iuseractive = 1 ; useralarm = ((iuserhour * 60) + iusermin) * 183108 ; useralarm = useralarm/100 ; } iflowactive = 0 ; if ((iflowhour > 0) 11 (iflowmin > 0)) { iflowactive = 1 ; lbatl = iflowmin + (iflowhour * 100) ; lbatl = lbatl % 20000 ; lbatlO = batsizel + (batsizelO * 10) ; lbatlO = lbatlO % 20000 ; flowalarm = 18677043/ (lbatl * lbatlO) ; flowalarm = flowalarm/100 * factor/100 ; } ialcoholactive = 0 ; if ((ialcoholone > 0) (ialcoholtenth > 0)) { ialcoholactive = 1 ; alcohol = ialcoholone * 10 + ialcoholtenth ; } rl [2] = batsizel + batsizel0 10 + 23 ; rl [3] = iuserhour + 23 ; rl [4] = iusermin + 23 ; rl [5] = ialcoholone + 23 ; rl [6] = ialcoholtenth + 23 ; rl [7] = i24houralarm + 23 ; rl [8] = elevation + 23 ; rl [9] = iflowhour + 23 ; rl [10] = iflowmin + 23 ; if (*chdummy rpoint = &rl [0] ; puts (rpoint) ; if (*chdummy =='P') { rpoint = &r [O] ; puts (rpoint) ; for (s=2 ; s<=7 ; s++) { r [s] ='N' ; } if if (*chdummy =='R') { i24occured = 0 ; iuseroccur = 0 ; ilowoccur = 0 ; ialcoholoccur = 0 ; ialarmlatch-= 0 ; alarmon = 0 ; ievent = 1 ; if (*chdummy alarmon = 0 ; ievent= 1 ; patentO1. c } ichdum = 0 ; chdummy = &incomming [O] ; while (*chdummy ! ='0') { *chdummy ='\O'; chdummy++ ; chdummy = &incomming [0] ; } extern void start () ; #pragma abs_address : Oxffd6 void (*interrupt vectors []) () = SCIReceive_ISR, Dummy_ISR, Dummy_ISR, Dummy_ISR, TimeHandle_ISR, Dummy_ISR, Dummy_ISR, Dummy_ISR, Dummy_ISR, Dummy_ISR, Dummy_ISR, Dummy_ISR, Dummy_ISR, Dummy_ISR, Dummy_ISR, Dummy_ISR, Dummy_ISR, Dummy_ISR, Dummy_ISR, Dummy_ISR, _start, } ; #pragma end-abs-address VERSION 5. 00 Object ="{648A5603-2C6E-101B-82B6-000000000014} #1. 1#0";"MSCOMM32. OCX" Object =" {20C62CAE-15DA-101B-B9A8-444553540000} #1. 1#0" ;"MSMAPI32. OCX" Begin VB. Form frmMain Caption ="Fermentometer Communication Interface" ClientHeight = 5328 ClientLeft = 456 ClientTop = 1356 ClientWidth = 8700 LinkTopic ="frmMain" PaletteMode = 1'UseZOrder ScaleHeight = 5328 ScaleWidth = 8700 Begin VB. TextBox txtFlowRate Alignment = 1'Right Justify DataField ="Now" Height = 285 Left 6120 Locked =-1'True TabIndex 53 Top = 3240 Width = 975 End Begin VB. CommandButton cmdUserFlow Caption ="Change User Flow" BeginProperty Font Name ="Arial" Size = 9 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 735 Left 7920 TabIndex 51 Top = 2040 Visible = 0'False Width, = 1335 End Begin VB. ListBox List9 BeginProperty Font Name ="Arial" Size = 12 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 600 ItemData ="Main2. frx": 0000 Left = 8520 List ="Main2. frx": 0002 Tablndex = 50 Top = 1440 Visible = 0'False Width = 735 End Begin VB. ListBox List8 BeginProperty Font Name ="Arial" Size = 12 Charset = 0 Weight 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 600 ItemData ="Main2. frx": 0004 Left = 7920 List ="Main2. frx": 0006 TabIndex 49 Top = 1440 Visible = 0'False Width = 615 End Begin VB. TextBox txtProposed BeginProperty Font Name ="Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough, 0'False EndProperty Height = 315 Index = 6 Left = 7920 Locked =-1'True TabIndex 48 Text ="Proposed Settings" Top = 960 Visible = 0'False Width = 1335 End Begin VB. TextBox txtCurrent BeginProperty Font Name"Arial" Size = 8 ; 4 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 315 Index = 6 Left = 7920 TabIndex 45 Text ="Current Settings" Top 480 Width = 1335 End Begin VB. TextBox txtLabel BeginProperty Font Name ="Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0'False<BR> <BR> <BR> <BR> Italic = 0'False Strikethrough = 0'False EndProperty Height = 315 Index = 6 Left = 7920 Locked =-1'True TabIndex 44 Text ="User Flow Alarm" Top = 0 Width = 1335 End Begin VB. ListBox List7 BeginProperty Font Name ="Arial" Size = 12 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 600 ItemData = "Main2. frx": 0008 Left = 6600 List = "Main2. frx" : 000A <BR> <BR> TabIndex = 43<BR> <BR> <BR> <BR> Top 1440 Visible = 0'False Width = 1335 End Begin VB. TextBox txtProposed BeginProperty Font Name = "Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0 'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 315 Index = 5 Left = 6600 Locked = -1 'True TabIndex = 42 Text ="Proposed Settings" Top = 960 Visible = 0'False Width = 1335 End Begin VB. TextBox txtCurrent BeginProperty Font Name = "Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0'False Italic = 0 'False Strikethrough = 0'False EndProperty Height = 315 Index = 5 Left = 6600 TabIndes = 41 Text ="Current Settings" <BR> <BR> Top = 480<BR> <BR> <BR> <BR> Width = 1335 End Begin VB. TextBox txtLabel BeginProperty Font Name ="Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 315 Index = 5 Left = 6600 Locked =-1'True TabIndex = 40 Text ="Elevation" Top = 0 Width = 1335 End Begin VB. TextBox txtAlcohol Alignment = 1'Right Justify DataField = "Now" Height = 285 <BR> <BR> Left = 6120<BR> <BR> <BR> <BR> Locked =-1'True TabIndex = 39 Top = 3600 Width = 975 End Begin VB. CommandButton cmdResetLocal Caption ="Reset Alarms This Screen" BeginProperty Font Name ="Arial" Size = 9. 6 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0 'False EndProperty <BR> <BR> Height = 852<BR> <BR> <BR> <BR> Left = 6000<BR> <BR> <BR> <BR> TabIndex = 38<BR> <BR> <BR> <BR> <BR> Top = 4320<BR> <BR> <BR> <BR> Width = 1095 End Begin VB. CommandButton cmdResetSend Caption ="Reset Alarms at Device" BeginProperty Font Name ="Arial" Size = 9. 6 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 852 Left = 4920 TabIndex 37 Top = 4320 Width = 1095 End Begin VB. TextBox txtAlcoholAlarm BackColor = &HOOOOOOFF& BeginProperty Font Name ="Arial" Size = 15. 6 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty ForeColor = &H00404000& Height = 492 Left = 0 Locked =-1'True TabIndex 36 Top = 4680 Visible = 0'False Width = 4935 End Begin VB. TextBox txtUserAlarm BackColor = &HOOOOOOFF& BeginProperty Font Name ="Arial" Size = 15. 6 Charset = 0. Weight = 400 Underline 0'False Italic = 0'False Strikethrough = 0'False EndProperty ForeColor = &H00404000& Height = 492 Left = 0 Locked =-1'True TabIndex 35 Top = 4200 Visible = 0'False Width = 4935 End Begin VB. TextBox txtHydrometer BackColor = &HOOOOOOFFt BeginProperty Font Name ="Arial" Size = 15. 6 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough 0'False EndProperty ForeColor = &H00404000& Height = 492 Left = 0 Locked =-1'True TabIndex 34 Top = 3720 Visible = 0'False Width = 4935 End Begin VB. TextBox txtFluidAlarm BackColor = &HOOOOOOFF& BeginProperty Font Name ="Arial" Size = 15. 6 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty ForeColor = &H00404000& Height = 492 Left = 0 Locked =-1'True TabIndex 33 Top = 3240 Visible = 0'False Width = 4935 End Begin VB. TextBox txtCommunicationDown BackColor = &HOOOOOOFF& BeginProperty Font Name ="Arial" Size = 15. 6 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty ForeColor = &H00404000& Height = 492 Left = 0 Locked =-1'True TabIndex 32 Top = 2760 Visible = 0'False Width 4935 End Begin VB. TextBox txtTimeSince Alignment = 1'Right Justify DataField ="Now" Height = 285 Left = 6120 Locked =-1'True TabIndex 31 Top = 3960 Width = 975 End Begin VB. TextBox txtLastInterval Alignment = 1'Right Justify DataField ="Now" Height = 285 Left = 6120 Locked =-1'True TabIndex 29 Top = 2880 Width = 975 End Begin VB. CommandButton cmdCancelProposed Caption ="Cancel Proposed Settings" BeginProperty Font Name ="Arial"<BR> <BR> <BR> <BR> Size 9 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 735 Left = 8040 TabIndex = 28 Top = 3600 Visible = 0'False Width = 1212 End Begin VB. TextBox txtProposed BeginProperty Font Name = "Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 315 Index = 4 <BR> <BR> <BR> Left = 5280<BR> <BR> <BR> <BR> <BR> Locked =-1'True TabIndex = 26 Text ="Proposed Settings" Top = 960 Visible = 0'False Width = 1335 End Begin VB. TextBox txtProposed BeginProperty Font Name = "Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 315 Index = 3 Left = 3960 Locked = -1 'True TabIndex = 25 Text ="Proposed Settings" Top = 960 Visible = 0'False Width = 1335 End Begin VB. TextBox txtProposed BeginProperty Font Name = "Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 315 Index = 2 Left 2640 Locked =-1'True TabIndex =24 Text ="Proposed Settings" Top = 960 Visible = 0'False Width = 1335 End Begin VB. TextBox txtProposed BeginProperty Font Name"Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0 'False Italic = 0 'False Strikethrough = 0 'False EndProperty Height = 315 Index-l <BR> <BR> <BR> Left = 1320<BR> <BR> <BR> <BR> <BR> Locked =-1'True TabIndex = 23 Text ="Proposed Settings" Top = 960 Visible = 0'False Width = 1335 End Begin VB. TextBox txtProposed BeginProperty Font Name ="Arial" Size = 8. 4 Charset = 0 . Weight 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 315 Index = 0 Left = 0 Locked = -1 'True TabIndex 22 Text ="Proposed Settings" Top = 960 Visible = 0'False Width = 1335 End Begin VB. TextBox txtLabel BeginProperty Font Name ="Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 315 Index = 4 <BR> <BR> Left = 5280<BR> <BR> <BR> <BR> Locked =-1'True TabIndex = 21 Text ="Hydrometer Check" Top = 0 Width = 1335 End Begin VB. TextBox txtLabel BeginProperty Font Name = "Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 315 Index = 3 <BR> <BR> Left = 3960<BR> <BR> <BR> <BR> Locked =-1'True TabIndex = 20 Text ="Alcohol Alarm" Top = 0 Width-1335 End Begin VB. TextBox txtLabel BeginProperty Font Name ="Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 315 Index = 2 <BR> <BR> Left = 2640<BR> <BR> <BR> <BR> Locked =-1'True TabIndex = 19 Text ="User Spedified" Top = 0 Width = 1335 End Begin VB. TextBox txtLabel BeginProperty Font Name = "Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 315 Index = 1 Left = 1320 Locked =-1'True TabIndex = 18 Text ="Batch Size" Top = 0 Width = 1335 End Begin VB. TextBox txtCurrent BeginProperty Font Name = "Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0'False Italic = 0 'False Strikethrough = 0 'False EndProperty Height = 315 Index = 4 Left = 5280 TabIndex = 17 Text ="Current Settings" <BR> <BR> Top = 480<BR> <BR> <BR> <BR> Width = 1335 End Begin VB. TextBox txtCurrent BeginProperty Font Name = "Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 315 Index = 3 Left = 3960 TabIndex = 16 Text ="Current Settings" <BR> <BR> Top = 480<BR> <BR> <BR> <BR> Width = 1335 End Begin VB. TextBox txtCurrent BeginProperty Font Name = "Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0'False Italic 0'False Strikethrough = 0 'False EndProperty Height = 315 Index = 2 Left = 2640 TabIndex = 15 Text ="Current Settings" <BR> <BR> Top = 480<BR> <BR> <BR> <BR> Width = 1335 End Begin VB. TextBox txtCurrent BeginProperty Font Name = "Ariat" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 315 Index = 1 Left = 1320 TabIndex = 14 Text ="Current Settings" <BR> <BR> Top'480<BR> <BR> <BR> <BR> Width = 1335 End Begin VB. TextBox txtCurrent BeginProperty Font Name = "Arial" Size = 8. 4 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 315 Index = 0 Left = 0 TabIndex = 13 Text ="Current Settings" Top = 480 Width = 1335 End Begin VB. Timer timePolling Interval = 500 Left = 7800 Top = 4440 End Begin VB. CommandButton cmdHydrometer Caption ="Turn On/Off Hydrometer Alarm" BeginProperty Font Name ="Arial" Size 9 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 735 Left = 5280 TabIndex = 12 Top = 2040 Visible = 0'False Width = 1335 End Begin VB. CommandButton cmdCancelHydrometer Caption ="Cancel Change Hydrometer" BeginProperty Font Name = "Arial" Size = 9 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 735 <BR> <BR> Left = 5280<BR> <BR> <BR> <BR> Tablndex-11 top = 2040 Visible = 0'False Width = 1335 End Begin VB. ListBox List5 BeginProperty Font Name = "Arial" Size = 12 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 600 ItemData = "Main2. frx" : 000C Left = 5280 List = "Main2. frx" : 000E TabIndex = 10 Top = 1440 Visible = 0'False Width = 1335 End Begin VB. ListBox List4 BeginProperty Font Name = "Arial" Size = 12 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 600 ItemData = "Main2. frx": 0010 Left = 3240 List = "Main2. frx": 0012 TabIndex = 9 Top = 1440 Visible = 0'False Width = 735 End Begin VB. CommandButton cmdCancelUserChange Caption ="Cancel User Change" BeginProperty Font <BR> <BR> Name ="Arial"<BR> <BR> <BR> <BR> Size 9 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 735 Left = 2640 TabIndex = 8 Top = 2040 Visible = 0'False Width = 1335 End Begin VB. CommandButton cmdUserAlarm Caption ="Change User Alarm" BeginProperty Font Name ="Arial" Size = 9 <BR> <BR> Charset = 0<BR> <BR> <BR> <BR> Weight = 400 Underline 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 735 Left = 2640 TabIndex = 7 Top = 2040 Visible = 0'False Width = 1335 End Begin VB. ListBox List3 BeginProperty Font Nme = "Arial" Size = 12 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 600 ItemData = "Main2. frx": 0014 Left = 2640 List = "Main2. frx": 0016 TabIndex = 6 Top = 1440 Visible = 0'False Width = 615 End Begin VB. ListBox List2 BeginProperty Font Name ="Arial" size = 12 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 600 <BR> <BR> ItemData ="Main2. frx": 0018<BR> <BR> <BR> <BR> Left = 1320 List = "Main2. frx": 001A TabIndex = 5 Top = 1440 Visible = 0'False Width = 1335 End Begin VB. ListBox Listl BeginProperty Font Name = "Arial" Size = 12 Charset = 0 Weight = 400 Underline 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 600 ItemDate = "Main2. frx": 001C Left = 3960 List = "Main2. frx": 001E TabIndex = 4 Top = 1440 Visible = 0'False Width = 1335 End Begin VB. CommandButton cmdAlcoholChange Caption ="Change Alcohol Alarm" BeginProperty Font Name = "Arial" Size = 9 Charset = 0 Weight = 400 Underline 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 735 Left = 3960 TabIndex = 3 Top = 2040 Visible = 0'False Width = 1335 End Begin VB. CommandButton cmdCancelAlcoholChange Caption ="Cancel Alcohol Change" BeginProperty Font Name = "Arial" Size 9 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 735 Left = 3960 TabIndex 2 Top = 2040 Visible = 0'False Width = 1335 End Begin VB. CommandButton cmdCancelBatchSize Caption ="Cancel Change Batch Size" BeginProperty Font Name'="Arial"<BR> <BR> <BR> <BR> Size 9 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 735 Left = 1320 TabIndex = 1 Top = 2040 Visible = 0'False Width = 1335 End Begin VB. CommandButton cmdBatchSize Caption ="Change Batch Size" BeginProperty Font Name = "Arial" Size 9 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 735 Left = 1320 TabIndex = 0 Top = 2040 Visible = 0'False Width = 1335 End Begin VB. CommandButton cmdChangeElevation Caption = "Change Elevation" BeginProperty Font Name = "Arial" Size = 9 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 735 Left = 6600 TabIndex 46 Top = 2040 Visible = 0'False Width = 1335 End Begin VB. CommandButton cmdCancelUserFlow Caption ="Cancel Change User Flow" BeginProperty Font Name ="Arial" Size 9 Charset 0 weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 735 Left = 7920 TabIndex = 52 Top = 2040 Visible = 0'False Width = 1335 End Begin VB. CommandButton cmdCancelElevation Caption ="Cancel Change Elevation" BeginProperty Font Name = "Arial" Size = 9 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0 'False EndProperty Height = 735 Left = 6600 TabIndex 47 Top = 2040 Visible = 0'False Width = 1335 End Begin VB. CommandButton cmdAcceptProposed Caption ="Accept Proposed Settings" BeginProperty Font Name = "Arial" Size 9 Charset = 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 735 Left = 8040 TabIndex = 27 Top = 2880 Visible = 0'False Width = 1212 End Begin VB. CommandButton cmdChangeSettings Caption ="Change Device Settings" BeginProperty Font Name ="Arial" Size = 9 Charset 0 Weight = 400 Underline = 0'False Italic = 0'False Strikethrough = 0'False EndProperty Height = 735 Left = 8040 TabIndex = 30 Top = 2880 Width = 1212 End Begin MSCommLib. MSComm MSComml Left = 7440 Top = 4440 ExtentX = 677 ExtentY 677 Version 393216 DTREnable =-1'True InBufferSize = 4096 InputLen = 12 OutBufferSize = 4096 End Begin MSMAPI. MAPIMessages MAPIMessagesl Left = 8640 Top = 4440 ExtentX = 804 ExtentY 804 Version = 393216 AddressEditFieldCount= 1 AddressModifiable= 0'False AddressResolveUI= 0'False FetchSorted = 0'False FetchUnreadOnly = 0'False End Begin MSMAPI. MAPISession MAPISessionl Left = 8160 Top = 4440 _ExtentX = 804 ExtentY 804 Version = 393216 DownloadMail =-1'True LogonUI =-1'True NewSession = 0'False End Begin VB. Label Label8 Caption ="since last" Height = 252 Left = 5280 TabIndex-61 Top = 3960 Width = 732 End Begin VB. Label Label7 Caption ="alcohol" Height = 252 Left = 5280 TabIndex 60 Top = 3600 Width = 732 End Begin VB. Label Label6 Caption ="flow rate" Height = 252 Left = 5280 TabIndex 59 Top = 3240 Width = 732 End Begin VB. Label Label5 Caption ="interval" Height = 252 Left = 5280 Tablndex 58 Top = 2880 Width = 732 End Begin VB. Label Label4 Caption ="hr : min : sec" Height = 252 Left = 7200 TabIndex 57 Top = 3960 Width = 732 End Begin VB. Label Label3 Caption- Height = 252 Left = 7200 TabIndex 56 Top = 3600 Width = 732 End Begin VB. Label Label2 Caption"CC/hr/liter" Height = 252 Left = 7200 TabIndex 55 Top = 3240 Width = 852 End Begin VB. Label Labell Caption ="hr : min : sec" Height = 252 Left = 7200 TabIndex 54 Top = 2880 Width = 732 End End Attribute VB Name ="frmMain" Attribute VB GlobalNameSpace = False Attribute VB Creatable = False Attribute VB PredeclaredId = True Attribute VBExposed = False Option Explicit Sub AddRecord () MyFile ="C : \fermentometer\fermentometer_data. mdb" Set MyWorkspace = Workspaces (0) Set MyDatabase = MyWorkspace. OpenDatabase (MyFile) If (strSegment (3) ="Y") Then Set MyTable = MyDatabase. OpenRecordset ("BubbleEvent") MyTable. AddNew MyTable ("TimeStamp") = Now MyTable. Update MyTable. Bookmark = MyTable. LastModified Call UpdateInterval MyTable. Close End If If (strSegment (4) ="Y") Then Set MyTable = MyDatabase. OpenRecordset ("UserFlowAlarm") MyTable. AddNew MyTable ("TimeStamp") = Now MyTable. Update MyTable. Bookmark = MyTable. LastModified txtFluidAlarm. Locked ="False" txtFluidAlarm. Text ="User Flow Alarm Device"& Device txtFluidAlarm. Locked ="True" txtFluidAlarm. Visible ="True" MyTable. Close strMessage ="User Flow Alarm Device"& Device Call TransmitMessage End If If (strSegment (5) ="Y") Then Set MyTable = MyDatabase. OpenRecordset ("HydrometerCheck") MyTable. AddNew MyTable ("TimeStamp") = Now MyTable. Update MyTable. Bookmark = MyTable. LastModified txtHydrometer. Locked ="False" txtHydrometer. Text ="Hydrometer Check Device"& Device txtHydrometer. Locked ="True" txtHydrometer. Visible ="True" MyTable. Close strMessage ="Hydrometer Check Device"& Device Call TransmitMessage End If If (strSegment (7) ="Y") Then Set MyTable = MyDatabase. OpenRecordset ("AlcoholAlarm") MyTable. AddNew MyTable ("TimeStamp") = Now MyTable. Update MyTable. Bookmark = MyTable. LastModif :-ed txtAlcoholAlarm. Locked ="False" txtAlcoholAlarm. Text ="Alcohol Level Alarm Device"& Device txtAlcoholAlarm. Locked ="True" txtAlcoholAlarm. Visible ="True" MyTable. Close strMessage ="Alcohol Level Alarm Device"& Device Call TransmitMessage End If If (strSegment (6) ="Y") Then Set MyTable = MyDatabase. OpenRecordset ("UserAlarm") MyTable. AddNew MyTable ("TimeStamp") = Now MyTable. Update MyTable. Bookmark = MyTable. LastModified txtUserAlarm. Locked ="False" txtUserAlarm. Text ="User Specified Alarm Device"& Device txtUserAlarm. Locked ="True" txtUserAlarm. Visible ="True" MyTable. Close strMessage ="User Specified Alarm Device"& Device Call TransmitMessage End If MyDatabase. Close MyWorkspace. Close End Sub Sub CommunicationFailure () txtCommunicationDown. Locked ="False" txtCommunicationDown. Text ="Communication Device"& Device &" Down" txtCommunicationDown. Locked ="True" txtCommunicationDown. Visible ="True" strMessage ="Communication Failure Device"& Device Call TransmitMessage End Sub Sub CurrentDisagregate () I = 3 Do While I < 12 strSegment (I) = Mid (strIn, I, 1) iResponse (I) = Asc (strSegment (I))-23 I = I + 1 Loop Z = 0 Do While I < 5 txtCurrent (I). Locked ="False" I = I + 1 Loop txtLabel (0). Locked ="False" txtLabel (0). Text ="Device"& Left (strIn, 1) txtLabel (0). Locked ="True" txtCurrent (l). Text = CStr (iResponse (3)) &"liters" If ( (iResponse (4) + iResponse (5)) < 1) Then txtCurrent (2). Text ="Disabled" Else I = 4 Do While I < 6 If (iResponse (I) < 10) Then strSegment (I) ="0"& CStr (iResponse (I)) Else strSegment (I) = CStr (iResponse (I)) End If I + Loop txtCurrent (2). Text = strSegment (4) &" :" & strSegment (5) &" hh: mm" End If If ( (iResponse (6) + iResponse (7) ) < 1) Then txtCurrent (3). Text ="Disabled" Else If (iResponse (6) < 10) Then txtCurrent (3). Text =""& CStr (iResponse (6)) &"."& CStr (iResponse (7)) &"%" Else txtCurrent (3). Text = CStr (iResponse (6)) &"."& CStr (iResponse (7)) &"%" End If End If If (iResponse (8) = 0) Then txtCurrent (4). Text ="Disabled" Else txtCurrent (4). Text ="Enabled" End If I = 0 Do While I < 5 txtCurrent (I). Locked ="True" I = I + I Loop If (iResponse (9) = 0) Then txtCurrent (5). Text ="Sea Level" Else txtCurrent (5). Text = CStr (iResponse (9) ) &", 000 feet" End If If ((iResponse (10) + iResponse (11)) < 1) Then txtCurrent (6). Text ="Disabled" Else' If (iResponse (10) < 10) Then txtCurrent (6). Text =""& CStr (iResponse (10) ) &"."& CStr (iResponse (11)) &"CC/l/hr" Else txtCurrent (6). Text = CStr (iResponse (10)) &"."& CStr (iResponse (11)) &"CC/l/hr" End If End If iCurrentPoll = 0 End Sub Sub PollDisagregate () strSegment (2) = Mid (strIn, 1,1) I = 3 Do While I < 9 strSegment (I) = Mid (strIn, I, 1) I = I + 1 Loop If ( (strSegment (3) ="Y") Or (strSegment (4) ="Y") Or (strSegment (5) ="Y") Or (strSegment (6) ="Y") Or (strSegment (7) ="Y")) Then Call AddRecord End If If (strSegment (8) ="Y") Then iCurrentPoll = 1 End If End Sub Sub StringDisagregate () strin = Left (strIn, 2) If (strIn ="BE") Or (strin"LL") Or (strIn ="HC") Or (strIn ="AA") Or (strIn ="UA") Then Call AddRecord Else MsgBox"Failed test" End If End Sub Sub TestString () End Sub Private Sub cmdAcceptProposed Click () strToChange = Device &"S" I = CInt (Left (txtProposed (l). Text, 2)) + 23 strToChange = strToChange & Chr (I) If (txtProposed (2). Text ="Disabled") Then strToChange = strToChange & Chr (23) & Chr (23) Else I = CInt (Left (txtProposed (2). Text, 2)) + 23 strToChange = strToChange & Chr (I) I = CInt (Mid (txtProposed (2). Text, 4, 2)) + 23 strToChange = strToChange & Chr (I) End If If (txtProposed (3). Text ="Disabled") Then strToChange = strToChange & Chr (23) & Chr (23) Else I = CInt (Left (txtProposed (3). Text, 2)) + 23 strToChange = strToChange & Chr (I) I = CInt (Mid (txtProposed (3). Text, 4, 1)) + 23 strToChange = strToChange & Chr (I) End If If (txtProposed (4). Text ="Disabled") Then strToChange = strToChange & Chr (23) Else strToChange = strToChange & Chr (24) End If If (txtProposed (5). Text ="Sea Level") Then strToChange = strToChange & Chr (23) Else I = CInt (Left (txtProposed (5), 1)) strToChange = strToChange & Chr (I) End If If (txtProposed (6). Text ="Disabled") Then strToChange = strToChange & Chr (23) & Chr (23) Else I = CInt (Left (txtProposed (6). Text, 2)) + 23 strToChange = strToChange & Chr (I) I = CInt (Mid (txtProposed (6). Text, 4, 1)) + 23 strToChange = strToChange & Chr (I) End If strToChange = strToChange & Chr (123) iChangeSend = 1 I = 1 Do While I < 7 txtProposed (I). Locked ="False" txtProposed (I). Text ="" txtProposed (I). Locked ="True" txtProposed (I). Visible ="False" I + 1 Loop txtProposed (0). Visible ="False" cmdBatchSize. Visible ="False" cmdUserAlarm. Visible ="False" cmdAlcoholChange. Visible ="False" cmdHydrometer. Visible ="False" cmdChangeElevation. Visible ="False" cmdUserFlow. Visible ="False" cmdAcceptProposed. Visible ="False" cmdCancelProposed. Visible ="False" cmdChangeSettings. Visible ="True" Listl. Visible ="False" List2. Visible ="False" List3. Visible ="False" List4. Visible ="False" List5. Visible ="False" List7. Visible ="False" List8. Visible ="False" List9. Visible ="False" cmdCancelBatchSize. Visible ="False" cmdCancelUserChange. Visible ="False" cmdCancelAlcoholChange. Visible ="False" cmdCancelHydrometer. Visible ="False" End Sub Private Sub cmdAlcoholChange_Click () cmdAlcoholChange. Visible ="False" cmdCancelAlcoholChange. Visible ="True" Listl. Visible ="True" Listl. SetFocus End Sub Private Sub cmdBatchSizeClick () I = 0 Do While I < 5 txtProposed (I). Visible ="True" I = I + 1 Loop cmdBatchSize. Visible ="False" cmdCancelBatchSize. Visible ="True" List2. Visible ="True" List2. SetFocus End Sub Private Sub cmdCancelAlcoholChange Click () cmdAlcoholChange. Visible ="True" cmdCancelAlcoholChange. Visible ="False" Listl. Visible ="False" End Sub Private Sub cmdCancelBatchSize Click () I = 0 Do While I < 5 txtProposed (I). Visible ="False" I = I + 1 Loop cmdBatchSize. Visible ="True" cmdCancelBatchSize. Visible ="False" List2. Visible ="False" End Sub Private Sub cmdCancelHydrometer Click () cmdHydrometer. Visible ="True" cmdCancelHydrometer. Visible ="False" List5. Visible ="False" End Sub Private Sub cmdCancelProposed_Click () I = 1 Do While I < 7 txtProposed (I). Locked ="False" txtProposed (I). Text ="" txtProposed (I). Locked ="True" txtProposed (I). Visible ="False" I = I + 1 Loop txtProposed (0). Visible ="False" cmdBatchSize. Visible ="False" cmdUserAlarm. Visible ="False" cmdAlcoholChange. Visible ="False" cmdHydrometer. Visible ="False" cmdChangeElevation. Visible ="False" cmdUserFlow. Visible ="False" cmdAcceptProposed. Visible ="False" cmdCancelProposed. Visible ="False" cmdChangeSettings. Visiblel="True" Listl. Visible ="False" List2. Visible ="False" List3. Visible ="False" List4. Visible ="False" List5. Visible ="False" List7. Visible ="False" List8. Visible ="False" List9. Visible ="False" cmdCancelBatchSize. Visible ="False" cmdCancelUserChange. Visible ="False" cmdCancelAlcoholChange. Visible ="False" cmdCancelHydrometer. Visible ="False' End Sub Private Sub cmdCancelUserChange Click () cmdUserAlarm. Visible ="True" cmdCancelUserChange. Visible ="False" List3. Visible ="False" List4. Visible ="False" End Sub Private Sub cmdChangeElevation Click () cmdChangeElevation. Visible ="False" cmdCancelElevation. Visible ="True" List7. Visible ="True" List7. SetFocus End Sub Private Sub cmdChangeSettings Click () 1=1 Do While I < 7 txtProposed (I). Locked ="False" txtProposed (I). Text = txtCurrent (I). Text txtProposed (I). Locked ="False" txtProposed (I). Visible ="True" I = I + 1 Loop txtProposed (0). Visible ="True" cmdBatchSize. Visible ="True" cmdUserAlarm. Visible ="True" cmdAlcoholChange. Visible ="True" cmdHydrometer. Visible ="True" cmdChangeElevation. Visible ="True" cmdUserFlow. Visible ="True" cmdAcceptProposed. Visible ="True" cmdCancelProposed. Visible ="True" cmdChangeSettings. Visible ="False" End Sub Private Sub cmdCurrentSetting_Click () End Sub Private Sub cmdHydrometer Click () cmdHydrometer. Visible ="False" cmdCancelHydrometer. Visible ="True" List5. Visible ="True" List5. SetFocus End Sub Private Sub cmdResetLocal Click () txtCommunicationDown. Visible ="False" txtUserAlarm. Visible ="False" txtHydrometer. Visible ="False" txtAlcoholAlarm. Visible ="False" txtFluidAlarm. Visible ="False" End Sub Private Sub cmdResetSendClick () txtCommunicationDown. Visible ="False" txtUserAlarm. Visible ="False" txtHydrometer. Visible ="False" txtAlcoholAlarm. Visible ="False" txtFluidAlarm. Visible ="False" iResetSend = 1 End Sub Private Sub cmdUserAlarm Click () cmdUserAlarm. Visible ="False" cmdCancelUserChange. Visible ="True" List3. Visible ="True" List3. SetFocus End Sub Private Sub Commandl Click () iResetSend = 1 End Sub Private Sub cmdUserFlow Click () cmdUserFlow. Visible ="False" cmdCancelUserFlow. Visible ="True" List8. Visible ="True" List8. SetFocus End Sub Private Sub Form Activate () strMessageAddress = InputBox ("Enter the Email address for the alarm messages","Message Address",, 100, 100) Entry ="0. 0" Listl. AddItem Entry For I = 1 To 180 Entry = CStr (I) Select Case Len (Entry) Case 1 Entry ="0."& Entry Listl. AddItem Entry Case 2 Entry =""& Left (Entry, 1) &"."& Right (Entry, 1) Listl. AddItem Entry Case 3 Entry = Left (Entry, 2) &"."& Right (Entry, 1) Listl. AddItem Entry End Select Next I For I = 1 To 99 Entry = CStr (I) Select Case Len (Entry) Case 1 Entry ="0"& Entry List2. AddItem Entry Case 2 List2. AddItem Entry End Select Next I Entry ="00" List3. AddItem Entry For I = 1 To 23 Entry = CStr (I) Select Case Len (Entry) Case 1 Entry ="0"& Entry List3. AddItem Entry Case 2 List3. AddItem Entry End Select Next I Entry ="00" List4. AddItem Entry For I = 1 To 59 Entry = CStr (I) Select Case Len (Entry) Case 1 Entry ="0"& Entry List4. AddItem Entry Case 2 List4. AddItem Entry End Select Next I Entry ="Disable" List5. AddItem Entry Entry ="Enable" List5. AddItem Entry Entry ="Sea Level" List7. AddItem Entry Entry ="1, 000 feet" List7. AddItem Entry Entry ="2, 000 feet" List7. AddItem Entry Entry ="3, 000 feet" List7. AddItem Entry Entry ="4, 000 feet" List7. AddItem Entry Entry ="5, 000 feet" List7. AddItem Entry Entry ="6, 000 feet" List7. AddItem Entry Entry ="7, 000 feet" List7. AddItem Entry Entry ="8, 000 feet" List7. AddItem Entry Entry ="9, 000 feet" List7. AddItem Entry Entry ="00" List8. AddItem Entry For I = 1 To 99 Entry = CStr (I) Select Case Len (Entry) Case 1 Entry ="0"& Entry List8. AddItem Entry Case 2 List8. AddItem Entry End Select Next I Entry ="00" List9. AddItem Entry For I = 1 To 99 Entry = CStr (I.) Select Case Len (Entry) Case 1 Entry ="0"& Entry List9. AddItem Entry Case 2 List9. AddItem Entry End Select Next I Device ="1" iCurrentPoll = 1 iChangeSend = 0 iResetSend = 0 MSComml. InputLen = 12 L001 : MSComml. PortOpen = True Do DoEvents Loop Until MSComml. InBufferCount >= 11 strIn = MSComml. Input iCommunication = 0 txtCommunicationDown. Visible ="False" strTemp = Mid (strIn, 2, 1) If (strTemp ="P") Then Call PollDisagregate Else If (strTemp ="C") Then Call CurrentDisagregate Else End If End If MSComml. PortOpen = False GoTo L001 End Sub Private Sub Form Unload (Cancel As Integer) MSComml. PortOpen = False End Sub Private Sub List1 Click () ReturnValue = MsgBox ("You are about to select on alcohol alarm of"& Listl. Text &"% Press OK to proceed or Cancel to cancel.", Buttons : =vbOKCancel + vbExclamation, Title : ="SET ALCOHOL ALARM") If ReturnValue = vbCancel Then Listl. SetFocus Exit Sub Else If (Listl. Text ="0. 0") Then txtProposed (3). Text ="Disabled" Else txtProposed (3). Text = Listl. Text &"%" End If Listl. Visible ="False" End If cmdAlcoholChange. Visible ="True" cmdCancelAlcoholChange. Visible ="False" Listl. Visible ="False" End Sub Private Sub List2 Click () ReturnValue = MsgBox ("You are about to select a batch size of"& List2. Text &"liters. Press OK to proceed or Cancel to cancel.", Buttons : =vbOKCancel + vbExclamation, Title : ="SET BATCH SIZE") If ReturnValue = vbCancel Then List2. SetFocus Exit Sub Else txtProposed (l). Text = List2. Text &"liters" List2. Visible ="False" End If cmdBatchSize. Visible ="True" cmdCancelBatchSize. Visible ="False" List2. Visible ="False" End Sub Private Sub OLElUpdated (Code As Integer) End Sub Private Sub List2 MouseMove (Button As Integer, Shift As Integer, X As Single, Y As Single) iCommunication = 1 End Sub Private Sub List3 Click () ReturnValue = MsgBox ("You are about to select the hours for the user alarm at"& List3. Text &"hours Press OK to set minutes or Cancel to cancel.", Buttons : =vbOKCancel + vb3xclamation, Title : ="HOURS USER ALARM") If ReturnValue = vbCancel Then List3. SetFocus Exit Sub Else List3. Visible ="False" End If List3. Visible ="False" List4. Visible ="True" End Sub Private Sub List4 Click () ReturnValue = MsgBox ("You are about to select"& List3. Text &" hours"& List4. Text &"minutes for the user alarm. Press OK to proceed or Cancel to cancel.", Buttons : =vbOKCancel + vbExclamation, Title : ="HOURS AND MINUTES USER ALARM") If ReturnValue = vbCancel Then List4. SetFocus Exit Sub Else If ( (List3. Text ="00") And (List4. Text ="00")) Then txtProposed (2). Text ="Disabled" Else txtProposed (2). Text = List3. Text &" :" & List4. Text &" hh : mm" End If List3. Visible ="False" List4. Visible ="False" End If List3. Visible ="False" List4. Visible ="False" cmdUserAlarm. Visible ="True" cmdCancelUserChange. Visible ="False" End Sub Private Sub ListS Click () ReturnValue = MsgBox ("You are about to"& List5. Text &"the 24 hours Hydrometer Check Alarm Press OK to Accept or Cancel to cancel.", Buttons : =vbOKCancel + vbExclamation, Title : ='"SET BATCH SIZE") If ReturnValue = vbCancel Then List5. SetFocus Exit Sub Else txtProposed (4). Text = List5. Text &"d" List5. Visible ="False" End If cmdHydrometer. Visible ="True" cmdCancelHydrometer. Visible ="False" List5. Visible ="False" End Sub Private Sub TimerlTimer () End Sub Private Sub timPolling_Timer () End Sub Private Sub List7 Click () ReturnValue = MsgBox ("You are about to change the proposed elevation to"& List7. Text &"Press OK to Accept or Cancel to cancel.", Buttons : =vbOKCancel + vbExclamation, Title : ="SET ELEVATION") If ReturnValue = vbCancel Then List7. SetFocus Exit Sub Else txtProposed (5). Text = List7. Text List7. Visible ="False" End If cmdChangeElevation. Visible ="True" cmdCancelElevation. Visible ="False" List7. Visible ="False" End Sub Private Sub List8 Click () ReturnValue = MsgBox ("You are about to select the units for the user flow alarm at"& List8. Text &"CC/l/hr Press OK to set hundreths or Cancel to cancel.", Buttons : =vbOKCancel + vbExclamation, Title : ="UNITS USER FLOW ALARM") If ReturnValue = vbCancel Then List8. SetFocus Exit Sub Else List8. Visible ="False" End If List8. Visible ="False" List9. Visible ="True" List9. SetFocus End Sub Private Sub List9 Click () ReturnValue = MsgBox ("You are about to select List8. Text &"." & List9. Text &"CC/l/hr for the user flow alarm. Press OK to proceed or Cancel to cancel.", Buttons : =vbOKCancel + vbExclamation, Title : ="CC/l/hr USER FLOW ALARM") If ReturnValue = vbCancel Then List9. SetFocus Exit Sub Else If ( (List8. Text ="00") And (List9. Text ="00")) Then txtProposed (6). Text ="Disabled" Else txtProposed (6). Text = List8. Text &"."& List9. Text &" CC/l/hr" End If List8. Visible ="False" List9. Visible ="False" End If End Sub Private Sub timePolling Timer () If (iCommunication < 7) Then txtTimeSince. Locked ="False" dtToDisplay = Now-dtLastBubble If (dtToDisplay >= 1) Then txtTimeSince. Text ="Over 24hrs" Else txtTimeSince. Text = Format (dtToDisplay,"hh : mm : ss") End If txtTimeSince. Locked ="True" If (iCurrentPoll = 1) Then strToSend = Device &"C"& Chr (123) MSComml. Output = strToSend iCurrentPoll = 0 iCommunication = iCommunication + 1 Else If (iChangeSend = 1) Then MSComml. Output = strToChange iChangeSend = 0 iCurrentPoll = 1 Else If (iResetSend = 1) Then strToSend = Device &"R"& Chr (123) MSComml. Output = strToSend iResetSend = 0 Else strToSend = Device &"P"& Chr (123) MSComml. Output = strToSend iCommunication = iCommunication + 1 End If End If End If Else iCommunication = 0 Call CommunicationFailure End If End Sub Private Sub txtLowFluid Change () End Sub Private Sub TransmitMessage () frmMain. MAPISessionl. SignOn frmMain. MAPIMessagesl. SessionID = frmMain. MAPISessionl. SessionID frmMain. MAPIMessagesl. Compose frmMain. MAPIMessagesl. RecipAddress = strMessageAddress frmMain. MAPIMessagesl. MsgSubject = strMessage frmMain. MAPIMessagesl. MsgNoteText = strMessage frmMain. MAPIMessagesl. Send False frmMain. MAPISessionl. SignOff End Sub Private Sub UpdateInterval () Dim dblFlowRate As Double Dim dblBatchSize As Double Dim dblElevation As Double Dim strElevationTemp As String Dim dblAlcohol As Double longRecordCount = MyTable. RecordCount If (longRecordCount > 1) Then txtLastInterval. Locked ="False" dtLastBubble = MyTable ("TimeStamp") MyTable. MovePrevious dtNextLastBubble = MyTable ("TimeStamp") MyTable. MoveNext dtToDisplay = dtLastBubble-dtNextLastBubble If (dtToDisplay >= 1) Then frmMain. txtLastInterval. Text ="Over 24hrs" Else frmMain. txtLastInterval. Text = Format (dtToDisplay, "hh: mm: ss") If ((Left (txtCurrent (5). Text, 1) >="1") And (Left (txtCurrent (5). Text, 1) <>"C")) Then strElevationTemp = Left (txtCurrent (5). Text, 1) Select Case strElevationTemp Case"S" dblElevation = 1 Case"1" dblElevation = 0.9646 Case"2" dblElevation = 0.9298 Case"3" dblElevation = 0.8961 Case"4" dblElevation = 0.8636 Case"5" dblElevation = 0.8319 Case"6" dblElevation = 0.8014 Case"7" dblElevation = 0.7717 Case"8" dblElevation = 0.7426 Case"9" dblElevation = 0.7146 Case Else dblElevation = 1 End Select dblBatchSize = CDbl (Left (frmMain. txtCurrent (1).

Text, 2)) dblFlowRate = (1.7 * dblElevation)/ (dtToDisplay * dblBatchSize * 24) frmMain. txtFlowRate. Text = Format (dblFlowRate, "###0. 00") dblAlcohol = CDbl (longRecordCount) * 17 * dblElevation/ (4100 * dblBatchSize) If (dblAlcohol > 20#) Then frmMain. txtAlcohol. Text ="Confirm Batch Size" Else frmMain. txtAlcohol. Text Format (dblAlcohol,"&num 0. 0") End If End If End If End If End Sub STDIO. H #ifndef STDIO_H #define _ STDIo_H #include <_const. h> #define stdin 0 #define stdout 0 #define stderr 0 int getchar (void) ; int putchar (char) ; int puts (CONST char *) ; int printf (CONST char int sprintf (char *, CONST char *,...) ; #ifndef NULL #define NULL 0 #endif #if defined (AVR) int cprintf (const char *,...) ; #end-if #endif