70
BATTERY MONITORING ENHANCEMENT AND SYSTEM CHARACTERIZATION OF AN INTEGRATED SKI SUIT HEATING SYSTEM Nathan Hollcraft (PM), Matthew Bihis, and Remenick Bautista

Final Report v2

Embed Size (px)

Citation preview

Page 1: Final Report v2

BATTERY MONITORING ENHANCEMENT AND

SYSTEM CHARACTERIZATION OF

AN INTEGRATED SKI SUIT HEATING SYSTEM

Nathan Hollcraft (PM), Matthew Bihis, and Remenick Bautista

Academic Advisor: Dr. Wayne Kimura

Industrial Advisor: Dr. Arnold Berger

University of Washington | Bothell

Page 2: Final Report v2

Version 1.4 6/10/16

Table of ContentsList of Terms and Acronyms.................................................................................................................................3

Abstract................................................................................................................................................................4

1. Introduction......................................................................................................................................................4

1.1 Background.................................................................................................................................................4

1.2 Summary.....................................................................................................................................................5

1.3 Deliverables................................................................................................................................................5

1.3.1 Main PCB Redesign and Rebuild..........................................................................................................5

1.3.2 BMS PCB Design and Install.................................................................................................................6

1.3.3 Cabling System Redesign.....................................................................................................................7

1.3.4 Integrated System Walk-in Freezer Testing.........................................................................................9

1.4 Design Overview.......................................................................................................................................10

2. Design Goals...................................................................................................................................................10

2.1 Battery Life................................................................................................................................................10

2.2 Operational Temperature Range..............................................................................................................10

2.3 Ergonomics Goals.....................................................................................................................................11

3. Use Cases........................................................................................................................................................11

3.1 Equipping the ISSHS..................................................................................................................................11

3.2 Operating the ISSHS..................................................................................................................................11

3.3 Charging the ISSHS Battery Pack...............................................................................................................12

3.4 Changing the ISSHS Battery Pack..............................................................................................................12

3.5 Reading the Battery Level of the ISSHS.....................................................................................................12

3.6 Storing the ISSHS......................................................................................................................................12

3.7 The ISSHS in an Emergency.......................................................................................................................12

4. Tier 1 Design...................................................................................................................................................12

4.1 Tier 1 Hardware........................................................................................................................................12

4.2 Tier 1 Software..........................................................................................................................................13

5. Tier 2 Design...................................................................................................................................................14

5.1 Tier 2 Hardware........................................................................................................................................14Page | 1

Page 3: Final Report v2

5.1.1 Battery...............................................................................................................................................17

5.1.2 Battery Isolated Fuel Gauge...............................................................................................................17

5.1.3 Printed Circuit Board.........................................................................................................................17

5.1.4 Arduino Microcontrollers..................................................................................................................18

5.1.5 User Interface....................................................................................................................................18

5.1.6 DCM MOSFETS...................................................................................................................................19

5.1.7 Temperature Sensors.........................................................................................................................19

5.1.8 Overall Changes from Previous Team Systems..................................................................................19

5.2 Tier 2 Software..........................................................................................................................................19

6. Tier 3 Design...................................................................................................................................................20

6.1. Tier 3 Hardware.......................................................................................................................................20

6.2. Tier 3 Software.........................................................................................................................................24

6.3. Changes from Tier 2.................................................................................................................................24

7. Testing............................................................................................................................................................24

7.1 Breadboarding Testing..............................................................................................................................24

7.2 PCB Testing...............................................................................................................................................24

7.3 Battery Tracker Testing.............................................................................................................................25

7.4 Suit Performance Characterization...........................................................................................................25

7.5 Performance Results.................................................................................................................................25

8. Conclusions and Deliverables.........................................................................................................................27

9. Acknowledgements........................................................................................................................................27

10. Appendix.......................................................................................................................................................28

10.1. Appendix A: Previously used Software..................................................................................................28

10.2. Appendix B: B.O.M.................................................................................................................................30

10.3: Appendix C: Industry Standards............................................................................................................31

10.4: Appendix D: Previously Cited Industry Standards.................................................................................31

11. Total Previous Code......................................................................................................................................33

12. Total Current Code.......................................................................................................................................45

12.1. Main Code..............................................................................................................................................45

12.2. BMS Code:.............................................................................................................................................55

Page | 2

Page 4: Final Report v2

Page | 3

Page 5: Final Report v2

List of Terms and Acronyms

ISSHS: Integrated Ski Suit Heating System

MOSFET: Metal-Oxide-Semiconductor Field-Effect Transistor

PCB: Printed Circuit Board

EEPROM: Electrically Erasable Programmable Read-Only Memory

LCD: Liquid Crystal Display

LED: Light Emitting Diode

DCM: Duty Cycle Modulation

SMT: Surface Mount Technologies

APM: Arduino Pro Mini

BMS: Battery Monitoring System

mAh: Milli-Amp Hours

PTH: Plated Through-Hole

EFG: External Fuel Gauge

PCA: Printed Circuit Assembly

Page | 4

Page 6: Final Report v2

AbstractInnovation leads to new products that often revolutionize pre-existing markets or create entirely

new ones. These new inventions are built upon using pre-existing technology. However, innovation is not often just creating a product from a brand new idea, rather it can be taking an already applied idea and perfecting it. Our vision is no different – by improving upon existing technologies, we hoped to ultimately deliver an efficient electrically generated heating system. The goal of our proposed project was to develop a lightweight, compact, and energy-efficient ski suit that utilizes pre-existing electric heating technology to provide a warm, comfortable skiing experience. We took existing technology such as electrically heated ski wear and combined it with traditional ski wear, by means of an internal wiring system, that is able to heat devices, the gloves and boots, which are attached to a ski suit. The suit uses temperature sensors linked with a microcontroller, allowing for a digital display, and user interface via a control box. In addition, the suit has a standalone battery monitoring unit with an external display of its battery life.

1. Introduction

1.1 BackgroundSkiing is a popular recreational activity and competitive sport that has been around for many years.

In order to ensure the best experience, skiers are required to wear protective clothing known as a ski suit to keep the wearer dry and guard against cold temperatures. Ski suits are made from wind- and water-resistant or waterproof fabric, and has a non-removable liner made of nylon, silk, cotton or taffeta all to give the suit its protective effect. Separate from the ski suit are gloves and boots, which are used to protect the wearer’s outermost extremities.

However, there is still one major problem: in a cold environment, the body is designed to focus all of its energy in protecting vital organs, i.e., it reduces circulation to the arms and legs. This is an issue for many winter sports enthusiasts that reduces their performance and limits the time they can spend outdoors. To counteract this effect, gloves and boots have been made available containing built-in or insert-able heating elements. Typically, these devices are powered by a rechargeable battery pack and their performance duration can vary between two to eight hours depending on the outdoor conditions. The drawback with these electrically heated gloves and boots is that they operate separately from each other, require their own battery pack, have different rates of power consumption, which can be a hassle for the user to attend to individually.

The purpose of our project was to create an electrical heating system that integrates the heated gloves and boots with the jacket and pants to form one complete ski suit system. This system is controlled as one unit by a single battery pack. The user is able to adjust the temperature setting using controls connected to an Arduino microcontroller. The ski suit control unit displays the selected temperature along with the current temperature of the selected glove or boot heater. Compared to the current separated heating system

Page | 5

Page 7: Final Report v2

designs, our completed one-unit product system will be more convenient for the user to operate, at a lower overall cost.

1.2 SummaryIn summary, our plan was to build a main control unit that will allow the user to control the power

and set the suit temperature at a desired comfort level, with a separate battery life monitoring unit for the user to determine the life of the battery, which will be attached to the breast pocket of the jacket for ease of use.

1.3 DeliverablesThe main tasks in Capstone II were to build from the previous design a separate Battery Monitoring

System (BMS) using the LTC4150 coulomb counter chip with the Arduino Pro Mini (APM). This system serves as a counter, tracking the amperage the battery is supplying to the main unit. The APM, and the LTC4150 are surface mounted to a standalone Printed Circuit Board (PCB), which is permanently attached to the top of the battery. We display the power levels using Light Emitting Diodes (LEDs). We also redesigned and rebuilt the main PCB to increase performance and minimize size.

1.3.1 Main PCB Redesign and RebuildThe final PCBs of the teams that previously worked on this project were not of the best quality.

Looking at the figure below, one can see that the soldering work was amateur, there exists a lot of empty space, and has several unnecessary redundancies. We wanted to fix all of these problems when creating our PCBs, so we had our Battery Monitoring PCB implemented using Surface Mount Technologies (SMT) and then had the board soldered by a professional Surface Mount PCB soldering company, specifically Printed Circuit Assembly (PCA).

Figure 1.3.1.1: Prior team’s PCB.

Page | 6

Page 8: Final Report v2

Redesigning and recreating the prior team’s PCB will allow us to minimize the size of the PCB, allowing us to save room. Minimizing the size of the PCB will also save us money when ordering the PCB itself. We required SMT for our Battery Monitoring PCB because SMT components consume less power, allowing us to maximize battery shelf life. The SMT components were also less expensive, which helped us to save money on construction, and ultimately provide a more affordable product to the end user.

Redesigning the prior team’s PCB also gave us a chance to clean up and organize the wiring of the system. As the figure below clearly shows, the wiring of the prior system was haphazard. A main cause of this was how the previous team did not take spatial concerns into account when considering how long their wire connections should be. In other words, they didn’t know how long to make the wires that go from the PCB to the Liquid Crystal Display (LCD) screen, so they just made them really long and shoved the excess wherever they could fit it. We took these spatial concerns into consideration when designing our new PCB, so we have a much cleaner system overall.

Figure 1.3.1.2: Wiring of prior system.

1.3.2 BMS PCB Design and InstallThe BMS PCB is a separate PCB that is installed on the battery itself. The purpose of this PCB is to

give us a constant measure of the life of the battery so that we can display an accurate measure of remaining battery life to the user. An integral part of this design is the LTC4150 coulomb counter chip from Linear Technology, whose typical application can be seen in figure 1.3.2.1.

Page | 7

Page 9: Final Report v2

Figure 1.3.2.1: LTC4150 typical application.

In this design, the APM keeps track of how much life the battery has left using the LTC4150 coulomb counter. The APM calculates which power percentage bracket we are in and will then use a digital output pin to light up the corresponding color of LED color, shown in Table 1.3.2.1 below. These three LED colors serve as our External Fuel Gauge (EFG) and will be wired with connectors external to the BMS. The LED is attached to the breast pocket of the jacket for ease of access to the user.

Power Percentage Table

Percent Bracket LED Color LED Function

>75% BLUE Steady

75-50% GREEN Steady

50-25% RED Steady

<25% RED Flashing

Table 1.3.2.21 Power percentage chart.

1.3.3 Cabling System RedesignWe started with a new jacket and pair of pants; therefore, we redesigned the previous internal

wiring system, which used duct tape to keep its wires in place. We will use 18 AWG 5-cable braided wiring for flexibility and to ensure that the cables can handle the correct current. 12-wire waterproof inline connectors are used to make connections between the fanny pack and the wiring within the jacket and pants. A couple of the pins are left unused in our design, which should allow future teams to implement additional features without significantly changing the overall design. The previously used cabling system is shown in Figure 1.3.3.1 below.

Page | 8

Page 10: Final Report v2

Figure 1.3.3.1: Internal connection to main conduit (Molex Connectors).

We estimated 20 ft. of wire to go through the jacket and pants. We added a tubing system in the jacket and pants for the wires to go through. This way, wires are neatly hidden and can be removed easily from the suit to wash. Additionally, the previous waterproof connectors have been replaced by 5-wire waterproof connectors to eliminate the external ground wire connection. The previously used connectors are shown in Figure 1.3.3.2 below, while Figure 1.3.3.3 shows the currently used connectors and wiring.

Figure 1.3.3.2: Waterproof connectors with external ground wire.

Page | 9

Page 11: Final Report v2

Figure 1.3.3.3: New waterproof connectors

1.3.4 Integrated System Walk-in Freezer TestingOur goal was to develop a ski suit that is going to make a skier feel comfortable in a given cold

temperature. Since our project was scheduled during summer, we simulated the cold environment in a walk-in freezer. We want to test to make sure that the heating elements are producing the correct amount of heat per user setting and the temperature sensors are producing accurate readings.

The walk-in-freezer test was conducted in the walk-in freezer on the second floor of Discovery Hall on the UW Bothell campus. In this test the Integrated Ski Suit Heating System (ISSHS) was worn into the freezer to simulate actual cold-weather conditions. Since heat loss is linear, we can project the ISSHS performance at any temperature given accurate readings at any two temperatures. The goal of this test was to gather temperature range and battery life measurements. To achieve this, we operated the ISSHS at low and high temperature settings while also tracking coulomb consumption over 15 minute intervals. This allowed us to extrapolate a minimum and maximum performance characteristic and determine whether the ISSHS will reach our performance goals. To simulate real-world conditions further, the person wearing the ISSHS will be performing skiing motions to mimic the production of body heat.

Page | 10

Page 12: Final Report v2

1.4 Design OverviewOur high level design overview is in Figure 1.4.1 below.

Figure 1.4.1: High level design overview.

2. Design GoalsThis section outlines the technical goals that we tried to achieve with this project.

2.1 Battery LifeThe battery we have is rated at 11.1V and 4.4Ah. We drive four separate heating elements, each with

an overall resistance of ~11 Ohms. We put these four loads in parallel, so the overall resistance of our load becomes ~11/4 = ~2.75 Ohms. This means, at 100% duty cycle, with the entire battery across the loads, we get a steady current draw of ~4 Amps, or in other words, a battery life of ~1 hour. However, having a constant 100% duty cycle would most likely burn out the heating elements and possibly be a safety concern for a user. Thus, we limited the amount of time that we are at a high duty cycle percent. Looking at our Tier 2 Software shows that we have an average duty cycle of 50%. This extends our expected battery life to ~2 hours in a cold environment, which we set as our goal.

2.2 Operational Temperature RangeWe had the system operate effectively in a range of environments and temperatures, as well as

transition between them easily. However, due to the limiting of the duty cycle as explained above, we recognize that our system may not be effective in extremely cold environments. As such, our goal was to at

Page | 11

Page 13: Final Report v2

least maintain comfortable operation at a low temperature boundary of ~0 degrees F. This is only an estimate, but we believe that an environment colder than this would overwhelm our system, as well as reduce the battery’s capacity. In an environment colder than 0 degrees F, our system would most likely drain far too fast to be effective for any useful duration of time. As for the upper bound of temperature ranges, it is not a fault of our system that will calculate this. At higher temperatures, our system will turn off all heating, meaning that the only draw on the battery is from the temperature sensors and the LCD display, which adds to a very small amount of current draw. Thus, what limits the system is the nature of the suit itself. If a user wears a heavy ski jacket in a warm environment, then they will get uncomfortably hot. Not because the suit is heated, but because it is a suit meant for cold environments. Therefore, we believe a fitting overall goal for our temperature range is about [0 - 60] degrees F.

2.3 Ergonomics GoalsWe wanted our system to be easily usable and unobtrusive to the user. We want a user to feel

comfortable wearing the ISSHS. To satisfy this, we made sure that the connections and wires within the suit do not limit mobility, and that the gloves and boots are easy to connect. Our goal was to allow a single person to get the suit on and hooked up within a minute of the time it would take them to put on an identical normal ski suit.

3. Use CasesThis section describes some typical scenarios a user will encounter when using the ISSHS.

3.1 Equipping the ISSHSTo begin, our user should ensure that there is a fully charged battery properly connected to the main

conduit within the fanny pack. From there, our user will continue by wearing the ISSHS jacket and pants over their inner layers of clothing. Before zipping up their jacket, we recommend fastening the fanny pack around their waist and completing the proper connections between it and the jacket and pants. We intend to color code these connection ports accordingly for quick and easy identification. The user can then zip up their jacket and proceed to equip their boots, our heating elements are located within a typical pair of ski boots therefore making this step fairly simple, the only additional effort will be securely fastening the wiring within the pants to boots via the waterproof screw connectors. Finally, our user can complete this process by putting on each glove and connecting the wiring within the jacket to the gloves via another set of waterproof screw connectors.

3.2 Operating the ISSHSThe vision of the ISSHS was to have the system operate independently once our user sets their

desired comfort level. This comfort level will vary between our users and will also depend on the current weather conditions, some users may require higher settings to achieve their comfort level while others may only require the lower settings. The controls to this system are located on the main conduit within the fanny pack and consists of five buttons, one for power and the remaining four for controls. Operating the ISSHS is as simple as setting the user’s preferred heat settings and enabling the device. More on this process will be

Page | 12

Page 14: Final Report v2

described within this document. When our user is finished using the ISSHS, they simply disable the device and turn off the power. We recommend recharging the battery pack between uses and always making sure that the pack does not lose its charge over time.

3.3 Charging the ISSHS Battery PackAfter each use, our battery packs may require charging. Doing so should keep the batteries in good

condition. The ISSHS battery comes paired with a wall outlet charger. To operate this device, the user plugs it into any wall outlet and sets the charging level to the 11.1V charging level, then connect the battery pack. When ready, the charger itself will ensure that the battery does not get overcharged.

3.4 Changing the ISSHS Battery PackOur battery packs will be designed for quick interchangeability, simply have your auxiliary battery

pack charged and it is as simple as unplugging the used battery and plugging in the fresh one. We recommend promptly recharging any depleted batteries as soon as possible to prevent damage.

3.5 Reading the Battery Level of the ISSHSWhile the ISSHS is in use, the user can check its battery life using the EFG located within the jacket

chest pocket. This EFG will light up according to the current battery level: a blue light will signify a fully-charged battery, green will signify a moderately-charged battery, a solid red will signify a weak battery, and flashing red will signify the immediate need for the battery to be charged.

3.6 Storing the ISSHSWhen the ISSHS is not in use, the user should store it in a dry place, similar to storing normal skiing

equipment. During long periods of storage, the user should be sure to periodically charge the battery pack. This will prevent any damage and keep the battery healthy. We recommend recharging any stored batteries about once a month.

3.7 The ISSHS in an EmergencyIn case of an emergency, the ISSHS contains a safety card. This card outlines the power-down and

disconnect sequence. Each of the connectors will be clearly marked by number to communicate to emergency responders the number of connections that need to be undone. In addition, each of the ISSHS connectors are lock-free to enable quick, simple disconnects.

4. Tier 1 Design4.1 Tier 1 Hardware

The ISSHS is powered by a rechargeable 11.1V lithium-ion battery pack. We added a monitoring system to this pack to monitor the amount of charge in the battery and relays this information to the user through the LED display. The current entering each heating element will be controlled by the Arduino Mega

Page | 13

Page 15: Final Report v2

using the pulse width modulation Metal-Oxide-Semiconductor Field-Effect Transistors (MOSFETs). In this design, each heating element is coupled with a sensor which communicates temperature readings back to the Arduino Mega. The Arduino Mega then uses these readings to ensure that the user experiences the desired comfort level. The user controls the ISSHS using the button system and LCD screen. Our hardware design is outlined in Figure 4.1.1 below.

Figure 4.1.1: Tier 1 diagram of the hardware thought process.

4.2 Tier 1 SoftwareThe main point of the software for this project is to integrate all of the information from the push

button inputs, the temperature sensors, and the battery monitor chip. Then the software uses that information to properly control each individual heating element to ensure even and constant heating, as well as keeping the display up-to-date.

Figure 4.2.1 below shows the basic idea behind how the Main system operates. When the “ON” button is pressed, the program initializes the default variables and temperature settings. Then, it updates the display.

Figure 4.2.2 shows the basic idea behind how the BMS software operates. When a pulse comes from the LTC4150, the program either adds or subtracts from our battery count depending on if the battery is being charged or not.

The main system will begin in “Standby Mode,” where no heating is to be applied and the display will be simply updated with the status of the heating elements. This cycle will continue until the system receives an operator input. Once the operator inputs their desired heat setting, the operator can disable “Standby Mode” by pressing the “Standby” button. The system can be returned to “Standby Mode” at any time by pressing the “Standby” button again.

In “Heating Mode,” the program will fetch the temperature setting data to find the selected temperature and compare it with the current temperature data given by the temperature sensors. If the temperature reading is too cold, the amount of heating to be applied is increased proportionally, as outlined

Page | 14

Page 16: Final Report v2

further. If the temperature reading is too hot, then the amount of heating to be applied is decreased proportionally, possibly disabling the heaters entirely, as outlined further. If the temperature is just right, i.e. within a few degrees of the target temperature, then the amount of heating to be applied will stay constant. The heating is then applied and the whole program loops back to check the battery and button inputs, and updates the display accordingly.

Due to the nature of heating devices, there is a lot of intrinsic overshoot and undershoot in the heating process. This is because the heat coming from the heating elements does not always directly reflect the amount of power going through the heating elements at any given time. The time it takes for the heating elements to heat up or cool down causes a significant lag in the proper application of heat, which our system attempts to take into account. In mathematical terms, the amount of heating that will be applied when a temperature change needs to happen will be asymptotically proportional to the difference between the current temperature and the target temperature. Our general software design is outlined in Figure 4.2.1 below.

Figure 4.2.1: Tier 1 diagram of the software thought process.

5. Tier 2 Design5.1 Tier 2 Hardware

Our Tier 2 Hardware Layout is below, Figure 5.1.1 shows the main system PCB and Figure 5.1.2 shows the BMS PCB. The temperature sensors, battery, LCD screen, and heating elements are all located outside of the main fanny pack box. Every other component is contained within the box or the BMS. This means that our main PCB will contain: 4 resettable fuses, a 5V Regulator, 4 pull-up resistors (for the push-buttons), 4 MOSFETS to control heating, and rows of pins to connect to the Arduino. The LCD screen, 4 push-

Page | 15

Page 17: Final Report v2

buttons, and the main ON/OFF switch will be mounted on the front of the fanny pack box to protect the rest of the system.

Page | 16

Page 18: Final Report v2

Page | 17

Page 19: Final Report v2

Figure 5.1.1: Schematic of main system.

Page | 18

Page 20: Final Report v2

Figure 5.1.2: Schematic of BMS.

5.1.1 BatteryOur battery is the Tenergy 18650 Lithium Ion (Li-Ion) multi-cell battery, made up of three individual

battery cells placed in series. Each cell is rated at 3.7V, meaning that our overall battery is rated at 11.1V. The battery used is also rated for 4,400 milli-Amp hours (mAh). This means that the battery could output a constant 1 milliamp for 4,400 hours, or could supply 1,000 milliamps for 4.4 hours. The cost of this battery pack is $50.39, excluding shipping.

5.1.2 Battery Isolated Fuel GaugeAttached to the top of the battery is a PCB, which contains an APM microcontroller and an LTC4150

coulomb counter. Inter-spliced between two of the battery cells is a small resistance sense resistor (about 15 milli-Ohms). Whenever a certain amount of power passes through this sense resistor, the LTC4150 outputs a 6 micro second pulse to the APM. The APM then counts these pulses to find out what the current charge of the battery is. The APM then displays this battery charge level with the breast-mounted LED power indication display, as shown in the Design Overview. It is absolutely necessary that the fuel gauge remains attached to the battery and powered on AT ALL TIMES. This is so that the user can charge or discharge the battery separate of the main Ski Suit system, and still keep an accurate measure of the battery’s state-of-charge. This way, the entire Ski Suit is not rendered unusable whenever the battery dies and needs to be recharged. An empty battery can quickly and easily be replaced with an identical full battery, and the empty battery can be set-up to charge while the user continues using the ISSHS. In short, this allows a user to have spare battery packs that each keep track of their own charge.

5.1.3 Printed Circuit BoardThe two PCBs for our design contain all of the key components necessary for the proper execution of

the ISSHS. The PCB boards were created using the free PCB editing software available from ExpressPCB. Depending on the size of the board, and how many layers the board includes, the price range can vary from $30 per board to well over $100 per board. To further improve over the designs of previous teams, we will be implementing our BMS design in SMT. This means the PCB is smaller and cheaper to produce, saving money for both us and the end consumer.

The main fanny pack PCB contains these components:

- 4 MOSFETS- 4 pull-up resistors - A 5V Voltage Regulator- 4 resettable fuses- Rows of pins (for Arduino Mega interface)

The battery mounted BMS PCB board contains these components:

- The LTC4150 coulomb counter chip- Rows of pins (for APM interface)

Page | 19

Page 21: Final Report v2

- 15 milli-Ohm Resistor- Two (2) pull-up resistors- Two (2) 4.7 micro-F bypass capacitors

5.1.4 Arduino MicrocontrollersOur system uses two separate Arduino microcontrollers. The first is the Arduino Mega 2560 R3

microcontroller, and is used to operate and control the main system, including: controlling the MOSFET Duty Cycle Modulation (DCM); operating and monitoring the temperature sensors; monitoring the push-buttons; and updating the LCD screen user interface. The price of the Arduino Mega ranges from $40 to $50. The second Arduino is the Arduino Pro Mini (APM), which is used to monitor and display the state-of-charge of the battery by monitoring pulses from the LTC4150 coulomb counter.

5.1.5 User InterfaceThe user interface of the ISSHS consists of an LCD display, four push buttons, and a main power

switch. The main power switch directly controls the power from the battery, meaning that the main power switch determines if the entire system is on or off. The four push buttons are labeled as such: standby, up, down, and select. The standby button is similar in function to the main power switch, except it only controls the on/off state of the heating elements. This means the standby button allows the system to remain powered and monitor the temperature, but disable heating so that the battery lasts longer. Using the up, down, and select buttons, the user can select the heating setting of each boot or glove individually, as outlined in the Tier 2 software section. The interface and a typical display can be seen in Figure 5.1.5.1.

Figure 5.1.5.1: Typical display of user interface

Page | 20

Page 22: Final Report v2

5.1.6 DCM MOSFETSTo properly control the heating elements, we needed a method of controlling the amount of current

that goes through the heating elements over time. A MOSFET has the ability to control large amounts of current flow, while only using a small amount of current itself. However, the MOSFET only has an off or on state, with little in between. This means that, in order to control current flow over time, we have to implement Duty Cycle Modulation (DCM). With DCM, we quickly turn the MOSFET on and off. The relation between the duration the MOSFET is on versus off is called the Duty Cycle percentage. That is to say, if for a unit of time, the MOSFET is on for 25% of that time and off for 75% of that time, then the MOSFET is said to be using a 25% Duty Cycle. This also means that, for this example, we are, over time, delivering 25% of the maximum amount of current possible, effectively controlling how much heat is generated within the heating elements.

5.1.7 Temperature SensorsIn order to properly determine how much heating is needed in each component, we placed

temperature sensors within each glove and boot. These temperature measurements allow the software to judge the required Duty Cycle needed to properly heat the gloves and boots to the desired temperature. This is also a safety feature, since overheating the heating elements could potentially cause harm to a user.

5.1.8 Overall Changes from Previous Team SystemsOur design is very similar to the previous teams’ systems in terms of Hardware. The primary

difference is that we took the job of battery monitoring away from the main core system, and gave it to a dedicated system attached to the battery itself, utilizing a separate Arduino connected to a second PCB.

5.2 Tier 2 SoftwareThe majority of software code used for this project was reused from previous Capstone teams. A

thorough description of the software that we are using can be found in Appendix A. The only changes that we made are within the “battery tracker” segment of the software. We took this code, modified it, and then removed it entirely from the Arduino Mega, so that we could place it within the APM. The new battery tracker software operates as such:

Battery Tracker:

Triggered whenever a pulse comes from the LTC4150:1. If POL pin is logical High (charging):

a. Add 1 to the fuel count2. If POL pin is logical Low (Discharging):

a. Subtract 1 from the fuel count

Every half second:3. Divide current fuel count by theoretical maximum fuel count (7076) to get current battery fuel level 4. Update external LED display with the current battery fuel level if needed

Page | 21

Page 23: Final Report v2

6. Tier 3 Design6.1. Tier 3 Hardware

This section describes the final version of hardware of the system, after several edits and changes, as will be described further in section 6.3. Figure 6.1.1 shows the final schematic of the hardware for the Main system. Figure 6.1.2 shows the final PCB design for the Main system, while Figure 6.1.3 shows the actualized version of that PCB. The BMS system is shown in Figures 6.1.4 through 6.1.7 in a similar fashion.

Figure 6.1.1: Final schematic of Main system hardware

Page | 22

Page 24: Final Report v2

Figure 6.1.2: Final PCB design of the Main system

Figure 6.1.3: Actual loaded PCB of Main system

Page | 23

Page 25: Final Report v2

Figure 6.1.4: Final schematic of BMS system

Figure 6.1.5: Final PCB design for BMS system

Page | 24

Page 26: Final Report v2

Figure 6.1.6: Actual BMS hardware (Note: the specific board pictured was used as a test board instead of the final product)

Figure 6.1.7: Battery with BMS Installed

Page | 25

Page 27: Final Report v2

6.2. Tier 3 SoftwareThe final version of our code is included in section 12.

6.3. Changes from Tier 2This section goes over all of the changes that were made to any part of the project since the planning

stages of the project. In terms of hardware, there were many small changes that needed to be made to get the system working properly. As can be seen in Figure 6.1.3, there is a data bus of blue wires across the top of the PCB. This is the result of a problem that we had with the Arduino Mega. Initially, we thought that we could communicate with the LCD screen through any of the Arduino’s digital pins, so we picked pins 22-26 for data transfer. This was backed up by the fact that a previous team had used these same pins and managed to properly drive the LCD screen. However, after extensive testing, we found that only the Arduino’s PWM compatible pins are able to switch states fast enough for proper data transfer. Thus, we had to improvise and use our spare PWM pins to drive the LCD screen by running those blue wires across the PCB. Other hardware changes include connectors being installed incorrectly and needing re-soldering, as well as a design error that required us to redesign and reorder our PCB for the BMS system.

In terms of software, there were very few changes made overall. We initially planned for there to be four unique colors to the EFG, but we decided on a single 3-color LED and had to edit the code accordingly. Also, we modified the PWM heating levels of the main code for safety and consistency reasons.

7. Testing7.1 Breadboarding Testing

Breadboarding is where we tested the circuit with physical components. We conducted our breadboarding test in the following manner:

1. Turned on power and checked for main system functionality.2. Tested for communication with Arduino Mega and Pro Mini.3. Verified LTC4150 chip coulomb counting by checking the number of pulses using an oscilloscope. 4. Asked Dr. Berger and Dr. Kimura to review and feedback on the completed breadboard circuit as a

peer review to minimize error before moving to PCB phase.

7.2 PCB TestingOnce we completed our breadboarding, we began our PCB building and testing phase. We conducted

our PCB test in the following manner:

Unloaded PCB

1. Visual check.2. Simple Ohmic continuity check.3. Asked Dr. Berger to review and verify before loading PCB with components to minimize error.

Page | 26

Page 28: Final Report v2

Loaded PCB

1. Visual check.2. Simple ohmic continuity check.3. Turned on power and check for functionality.4. Verified LTC4150 chip coulomb counting by comparing the number of pulses to expected battery

amp hour. We monitored to make sure that the coulomb counter counted down as the battery charge went down. We constantly monitored the count until the battery was fully drained.

5. Asked Dr. Berger for guidance and feedback on the complete loaded PCB.

7.3 Battery Tracker TestingWe set our goal to be an expected battery life to ~2 hours in a cold environment. To verify this, we

conducted the following tests while the unit was in a cold environment:

1. Voltage check using voltage meter.2. Verified LTC4150 chip coulomb counting by comparing the number of pulses to expected battery

amp hour. We monitored to make sure that the coulomb counter was counting down as the battery charge goes down.

7.4 Suit Performance CharacterizationOur goal was to develop a ski suit that is going to make a skier feel comfortable in a given cold

temperature. Since our project was completed during summer, we needed to simulate a cold environment with a walk-in freezer. We had an actual user wearing the suit in a walk-in freezer on the UW Bothell campus, Discovery Hall 2nd floor. We tested the suit for comfort level at the coldest temperature that the walk-in freezer made available, which was ~4 degrees Celsius. In parallel, we monitored the battery life readout of the fuel gauge to test and verify the expected charge range in the cold environment.

We also tested for comfort level at room temperature (about 70° F) by having a user wear the suit in a room temperature room with the suit on. In parallel, we again monitored the fuel gauge to test and verify the expected charge range in the room temperature environment.

Since we were dealing with electronics in a fanny pack worn by a skier, we expected the device to experience a lot of vibration. During the walk-in freezer test, we conducted a vibration test in parallel to see if the device remained stable when the user is moving.

7.5 Performance ResultsThe below figures show our results for our performance characterization tests. Something to note is

that our battery lasted a very long time at low setting in room temperature. This is due to the fact that the system’s low setting is the same as room temperature, meaning the system barely needed to heat at all. Thus, the battery life for low setting at room temperature should be considered the measure for the battery life of the system when not heating (A.K.A. in standby).

Page | 27

Page 29: Final Report v2

Figure 7.5.1: Battery life of each heating setting at Room Temp (~70 degrees F)

Figure 7.5.2: Battery life of each heating setting at Cold Temperature (~40 degrees F)

Page | 28

Page 30: Final Report v2

0

2

4

6

8

10

12

-30 -20 -10 0 10 20 30

Batte

ry Li

fe (h

)

Temperature (C)

ISSHS Performance Estimation

Low

Medium

High

Linear (Low)

Linear (Medium)

Linear (High)

Figure 7.5.3: Battery life estimation vs temperature

8. Conclusions and DeliverablesIn summary, we built upon the work of a previous Capstone team to produce a functioning ski suit

heating system. This system integrates existing commercial glove and boot heaters and powers them with a single power source. We used the same rechargeable 11.1V lithium-ion battery chosen and purchased by the original Capstone team; however, we implemented a brand new BMS that was built into this battery pack.

Our final product consists of a jacket, pair of pants, pair of gloves, pair of boots, and fanny pack. The controls of our final system are enclosed within a waterproof casing that has an LCD screen and pushbuttons for the user to operate the device. This casing and the battery are carried by the user within the fanny pack. The wiring is sewn into the inner linings of the clothing and travel through the jacket and pants to the gloves and boots, respectively. There is also an external battery status display to allow the user to monitor the battery without having to open up the fanny pack.

In addition to these system design improvements, we performed an extensive characterization of our final design. First, we evaluated the system for its functionality. This is where we determined the usability of our design. Second, we tested the system for its effectiveness. Here we brought the unit from a cold environment (to simulate a ski slope) into a heated environment (to simulate a ski lodge). These tests were vital to proving the viability of the final ISSHS design and ultimately determined if we had created a sellable product.

9. AcknowledgementsWe would like to thank Doctor Arnold Berger for all of his help with this project so far. He has been

extremely helpful with his advice, and has been very generous with his time. We wouldn’t have been able to get this far without Dr. Berger’s support. We would also like to thank our faculty advisor Wayne Kimura for

Page | 29

Page 31: Final Report v2

his contributions. Lastly, we would like to thank Dr. Kim Gunnerson, Dr. Dan Jafe, and Woodinville Play It Again Sports for their donations to our project.

10. Appendix10.1. Appendix A: Previously used Software

This appendix contains the final description of the software that was created and used by previous Capstone teams to operate the system. Also note that the actual Arduino code that they created from this description is included in the next section. The following was taken directly from the final report of the first Capstone team to work on this project, whose members include Kevin Echols, Amit Moolani, Enoch Fu, and Michael Lu.

Identification of Software

In order to achieve the full functionality of the Integrated Heated Ski Suit, we implemented the use of the following software:

Arduino IDE with use of the following libraries:

EEPROMex

LiquidCrystal

PWM

Timer

Wire

Control Flow of Software Subsystems

Start-up Routine:

1. Power on, Arduino self-boot2. Display welcome message3. Check battery level and read temperature settings from EEPROM4. Update display to default display

Battery Tracker:

1. Read VCC

2. Divide by original battery level to determine percentage

3. Present battery level to screen

4. If battery percentage ≤ 30%, display low battery warning.

Page | 30

Page 32: Final Report v2

Default Setup:

1. On line 1 of LCD, display “BAT LVL: ” with the current battery level.2. On line 2 of LCD, display selected “block” (default: block 1) title and set battery level separated by a

“:”.3. Keep these displayed until the user responds. 4. If user presses ‘Select button’:

a. If the selected block is the last in the sequence, move to select settings from block 1.b. Else, move to select settings from the next block in the sequence c. Display the new selected block’s title and current temperature setting.

5. If user presses ‘Up button’:a. If the current temperature of the selected block is the same as the max range temperature,

keep the current temperature setting.b. Else, increment the selected block’s current temperature setting to the next temperature

level up.6. If user presses ‘Down button’:

a. If the current temperature of the selected block is the same as the min range temperature, keep the current temperature setting.

b. Else, decrement the selected block’s current temperature setting to the next temperature level down.

7. If user presses ‘Standby button’: a. Start heating sequence b. Display message indicating that heating is on

Side Notes:

• Block 1: Left Glove

• Block 2: Right Glove

• Block 3: Left Boot

• Block 4: Right Boot

Heating Sequence:

1. Read temperature readings from temperature sensors2. Read temperature settings from EEPROM3. Compare temperatures to determine if temperature needs to increase or decrease4. If increasing:*

a. 100% duty cycle until 80% target temp.b. 50% duty cycle until 90% target temp.c. 25% duty cycle (maintaining mode) when target reached

5. If decreasing:*a. 0% duty cycle until 120% target temp.b. 50% duty cycle until 110% target temp.c. 25% duty cycle when target temp reached

6. +/- 5% duty cycle for >-/+5°F difference from target temp.*These duty cycles and temperature percentages were estimates. See Table 5 in the heat subsection of the Function subsection in the Tier III Software section

Page | 31

Page 33: Final Report v2

10.2. Appendix B: B.O.M.Table 10.2: List of parts needed for breadboard testing and final product.

Item Manufacturer Model Number QuantityPrice (USD)

Temperature SensorAnalog Devices Incorporated TMP36GT9Z 4 1.45

MOSFET Infineon IPB065N03L G 4 3.15

Voltage Regulator STMicroelectronics L78S05CV 1 0.67

Resettable Fuses PolySwitch RXE025 5 1.25

Potentiometer - 20K - - 1 *

Resistors - - *

On Main Board - 3K 4 *

On BMS Board - 3K SMT 2 *

Various - 2K 2 *

Capacitors - 4.7uFMurata Electronics North America

GRM21BR61C475KA88L 2 0.17

15 mΩ Sense Resistor Ohmite 14AFR015E 1 1.77

18 AWG wires 100 ft

12 Pin Connector Molex PH-61-412 4 5.39

3 Pin Connector Molex PH-61-403 1 2.89

6 Pin Inline Waterproof Connector - 18-24 AWG (Male) Vetco VUPN8233 4 9.20

6 Pin Inline Waterproof Connector - 18-24 AWG (Female) Vetco VUPN8234 4 9.95

PCB Board Print (Main) ExpressPCB MiniBoard Service 1 41.00

Page | 32

Page 34: Final Report v2

PCB Board Print (Battery) ExpressPCB MiniBoard Service 1 41.00

LED Light 1 *

LTC4150 Micro Chip Linear Technology LTC4150CMS#PBF 2 -

Arduino Mega Arduino ATMega 2560 R3 1 19.95

Arduino Pro Mini SparkFun Electronics DEV-11114 ROHS 1 9.95

* Note: Indicates part was already purchased during prior Capstone, or was already available

10.3: Appendix C: Industry StandardsStandards are set in place to ensure that a design will work properly. For our work, we will refer to

the standards cited by the previous Capstone team, these are noted in Appendix D. In addition, we will determine additional design parameters using the PCB Trace Width Calculator from circuitcalculator.com and Recommended Wire Gauge Calculator from bulkwire.com.

10.4: Appendix D: Previously Cited Industry StandardsThis appendix contains the industry standards that were cited and used by the previous Capstone teams to operate the system. The following was taken directly from the final report of the first Capstone team to work on this project, whose members include Kevin Echols, Amit Moolani, Enoch Fu, and Michael Lu.

Low-Voltage Power Fuses

In electrical engineering, IEC 60269 is a set of technical standards built to help engineers determine appropriate fuse sizes for low-voltage power fuses. Our circuit design utilizes fuses on our PCB to assure the safety of the user, which operate at 11.1V (considered to be low-voltage).

There are a total of five fuses, four that link the positive terminal of the battery to the MOSFETs, which are used in a switching application that is controlling current into the individual heating elements. There will be a fifth fuse, not currently implemented, between the positive terminal of the battery and the Positive Voltage Regulator, which will provide 5V to our PCB.

These fuses protect our circuitry in the case too much current is drawn by a certain subsystem, i.e. in the case of the heating system, the fuse will burn out causing an open in the circuit in case wires get crossed in our ski suit conduit. The fuses will also help in troubleshooting our design in the case wires do get crossed, as each heating element in the gloves/boots will have its own fuse.

Page | 33

Page 35: Final Report v2

American Wire Gauge (AWG) and Current Limits

The American Wire Gauge and current limits describes what amperage can be run through what AWG sized wire. The rated current limits are only a rule of thumb; however, we do not exceed this rule of thumb in our design to assure the safety of the user. We used wiring in our ski suit conduit, which links the different pieces of the design, i.e. user interface and battery to the suit, the suit to the pants, the suit to the gloves, and the pants to the boots. We have a total of four wires being run to each hand and foot of the ISSHS. Two wires are used for heating elements, where the AWG and current limits are of great importance. The other two wires run to the temperature-sending unit, which is not operating at such high current levels so wire size may not be stressed as heavily.

If we oblige to the recommendations of the AWG and Current Limits we assure ourselves that no wiring is burnt up by accidentally passing too much current through it. We also assure our safety, as all components and subsystems are operating at or below recommended specifications.

Designing with Li-Ion Batteries

Power is provided to our design project using a Li-Ion battery. There is a small rate of failure associated with the Li-Ion battery; however, some more recent publicized failures (including fires and explosions) have raised concerns regarding the batteries overall safety. Specific standardized tests have been put in place to assess the battery’s safety, which we can perform if necessary.

The battery we have chosen for our project is the Li-Ion 18650, which has a built-in IC that prevents the battery pack from over charging and over discharging. This also helps to prolong the battery’s life. In addition, we also try to purchase the smart Li-Ion battery charger made by Tenergy and featured on AllBattery.com for charging our Li-Ion battery.

To assure that we do not hurt ourselves or anyone else in the process of creating our design project, we never exceeded the manufacturer’s specifications of the battery. These specifications are given on the product page, or can be found in Table 10.4.

TABLE 10.4: TENERGY LI-ION BATTERY SPECIFICATIONS

Specification Rating

Max Current Charge 4.4A (1C)

Max Discharge Current 5A (2.5C)

Cut-off Voltage 9V

Page | 34

Page 36: Final Report v2

11. Total Previous CodeThe following is the currently existing version of the software for the Arduino Mega. We changed and added to this code as specified in the Tier 2 and Tier 3 sections of this document.

1 /*2 Integrated Ski Suit Heating System (ISSHS) interface and control program3 by Enoch Fu45 Used with the Arduino Mega 25606 The circuit:7 LCD RS pin to digital pin 238 LCD Enable pin to digital pin 259 LCD D4 pin to digital pin 2710 LCD D5 pin to digital pin 2211 LCD D6 pin to digital pin 2412 LCD D7 pin to digital pin 2613 LCD R/W pin to ground14 10K potentiometer:15 ends to +5V and ground16 wiper to LCD VO pin (pin 3)17 select button to digital pin 318 down button to digital pin 1819 up button to digital pin 220 standby button to digital pin 1921 220 Ohm resistors from MOSFET gates to digital(PWM) pins 7,8,11,1222 TMP36 temperature sensor Vout pins to analog pins 0-323 voltage divided battery to analog pin 424 */2526 // Libraries27 #include <LiquidCrystal.h>28 LiquidCrystal lcd(23,25,27,22,24,26);29 #include <EEPROMex.h>30 #include <PWM.h>31 #include "Timer.h"32 #include <Wire.h>3334 // Temperature settings35 #define L 70 // low temperature setting level36 #define M 85 // medium temperature setting level37 #define H 100 // high temperature setting level38 #define BUFFER 5 // temperature (F) buffer range39 #define NEAR 10 // temperature (F) near/approaching range40 #define FAR 20 // temperature (F) far/aggressive range41 // Periods of function calls42 #define N 50 // number of temperature readings to average43 #define tempReadRate 1000 // rate of temperature readings in milliseconds44 #define batReadRate 10000 // rate of battry readings in milliseconds45 #define heatRate 1000 // rate of DCM heating function calls in milliseconds4647 #define TEST_TOGGLE 50000 // value counter needs to reach to toggle test display

Page | 35

Page 37: Final Report v2

48 // Battery reading numbers for calculation49 #define MAXBAT 78550 #define MINBAT 5051 #define LOWBAT 30 // low battery level to start flashing LED5253 // Timer object for attaching events to54 Timer t;55 // I/O pins56 const int standby_pin = 19;57 const int up_pin = 2;58 const int down_pin = 18;59 const int select_pin = 3;60 const int tempSensPin[] = 3,2,1,0;61 const int moduleHeatPin[] = 12,11,8,7;62 const int batlvl_pin = 4;63 const int led_pin = 6;64 const int bat_addr = 10;65 const int lastBat_addr = 30;66 //const int bm_addr = 0x10;6768 // Testing booleans69 boolean debug = false; // for serial prints70 boolean cutoffTest = true; // for testing cutoff reading of battery7172 // test display toggle variables73 boolean test = false; // determines if test menu should be displayed74 int lastButtonPressed = 0; // tracks which button was last pressed75 long testToggleCount = 0; // counter for how long the button was pressed7677 int batlvl = 100; // battery percentage remaining78 // temperature variables79 byte moduleSetTemp[] = 70,70,70,70; // set temperatures of each module80 char moduleSetLvl[] = 'L','L','L','L'; // set temperature level (0/L/M/H) of each module81 float moduleTemp[] = 70.0,70.0,70.0,70.0; // current temperature of each module82 float temps[4*N]; // array of temperature readings for averaging83 float tempRate[] = 0.0,0.0,0.0,0.0; // temperature rates of change84 int n = 0; // index of temp readings85 // button variables86 boolean toggled = false; // heating status87 int buttonState[] = 0,0,0,0; // state of each button88 int lastButtonState[] = LOW,LOW,LOW,LOW; // previous state of each button89 long lastDebounceTime = 0; // time (ms) of last button debounce90 long debounceDelay = 250; // amount of delay (ms) between button presses91 int selected = 0; // current module selected92 // heating variables93 boolean buffered[] = false,false,false,false; // tracks if temperature exceeded buffering range94 int heatLvl = 127; // duty cycle (0-255) of PWM output95 int aggrLvl = 255; // aggresive heating level96 int apprLvl = 127; // approaching heating level97 boolean reached[] = false,false,false,false; // if set temperature has been reached98 int32_t freq = 5; // frequency of PWM output99100 // Standby button ISR

Page | 36

Page 38: Final Report v2

101 void standbyPress() 102 if ((millis() - lastDebounceTime) < debounceDelay)103 return;104 noInterrupts();105 lastDebounceTime = millis();106 buttonState[0] = HIGH;107 108 // Up button ISR109 void upPress() 110 if ((millis() - lastDebounceTime) < debounceDelay)111 return;112 noInterrupts();113 lastDebounceTime = millis();114 buttonState[1] = HIGH;115 116 // Down button ISR117 void downPress() 118 if ((millis() - lastDebounceTime) < debounceDelay)119 return;120 noInterrupts();121 lastDebounceTime = millis();122 buttonState[2] = HIGH;123 124 // Select button ISR125 void selectPress() 126 if ((millis() - lastDebounceTime) < debounceDelay)127 return;128 noInterrupts();129 lastDebounceTime = millis();130 buttonState[3] = HIGH;131 132133 void setup() 134 // Welcome message135 lcd.begin(16,2);136 lcd.print("Integ. Ski Suit");137 lcd.setCursor(0,1);138 lcd.print("Heating System");139140 if (debug) 141 Serial.begin(9600);142 Serial.println("Integ. Ski Suit\nHeating System");143 144 // Retrieve last set temperatures from EEPROM145 for (int addr = 0; addr < 4; addr++) 146 setTemp(EEPROM.read(addr),addr);147 148 // Testing cutoff reading of battery149 if (cutoffTest) 150 delay(3000);151 int lastBat = EEPROM.readInt(bat_addr);152 if (debug) Serial.println(lastBat);153 lcd.clear();

Page | 37

Page 39: Final Report v2

154 lcd.setCursor(0,0);155 lcd.print("Cutoff reading: ");156 lcd.setCursor(0,1);157 lcd.print(lastBat);158 delay(2000);159 160 // Initialize button pins as inputs and the switch LED pin as output161 pinMode(standby_pin, INPUT);162 pinMode(up_pin, INPUT);163 pinMode(down_pin, INPUT);164 pinMode(select_pin, INPUT);165 pinMode(led_pin, OUTPUT);166167 // Set PWM pins to required frequency168 InitTimersSafe();169 for (int i = 0; i < 4; i++) 170 if (debug) 171 Serial.print("Setting frequency for heat pin ");172 Serial.print(i);173 Serial.print("...");174 175 while (!SetPinFrequencySafe(moduleHeatPin[i], freq));176 if (debug) Serial.println("success");177 178 // Attach interrupts for buttons179 attachInterrupt(4, standbyPress, RISING);180 attachInterrupt(0, upPress, RISING);181 attachInterrupt(5, downPress, RISING);182 attachInterrupt(1, selectPress, RISING);183184 // Initialize temperature readings185 for (int i = 0; i < N; i++) 186 readTemp();187 188189 delay(5000);190 lcd.clear();191192 // Read battery level and display menu to LCD193 //Wire.begin();194 readBatlvl();195 menu(selected);196197 // Attach functions for reading temperature and battery and heating to timer198 t.every(tempReadRate/N,readTemp);199 t.every(batReadRate,readBatlvl);200 t.every(heatRate,heat);201202 if (debug) Serial.println("setup complete\n");203 204205 void loop() 206 // Check for button presses

Page | 38

Page 40: Final Report v2

207 buttonCheck();208 // Service all events associated with the timer209 t.update();210 211212 // Function for setting the temperature of a module213 byte setTemp(byte temp, byte module) 214 if (temp >= 0 && temp <= 110) 215 // Update temperature setting for the module216 switch (temp) 217 case 0:218 moduleSetLvl[module] = '0';219 break;220 case L:221 moduleSetLvl[module] = 'L';222 break;223 case M:224 moduleSetLvl[module] = 'M';225 break;226 case H:227 moduleSetLvl[module] = 'H';228 break;229 default:230 moduleSetLvl[module] = '0';231 break;232 233 moduleSetTemp[module] = temp;234 // Write temperature setting to EEPROM for retrieval on reset235 EEPROM.write(module, temp);236 237 238239 int batRead;240241 // Function for reading battery level242 void readBatlvl() 243 // STC3100 battery monitoring IC communication244 /*245 Wire.requestFrom(bm_addr, 1);246 while (Wire.available() == 0);247 batlvl = Wire.read();248 */249 // Read battery level from analog pin250 batlvl = analogRead(batlvl_pin);251 if (cutoffTest) 252 batRead = batlvl;253 if (debug) 254 Serial.print("batRead: ");255 Serial.println(batRead);256257 EEPROM.writeInt(bat_addr, batRead);258259 // Calculate percentage of 5V

Page | 39

Page 41: Final Report v2

260 batlvl = (batlvl261 if (batlvl > 100) 262 batlvl = 100;263 else if (batlvl < 0) 264 batlvl = 0;265266 // Display battery level to LCD267 lcd.setCursor(0,0);268 if (!test) 269 lcd.print("BAT LVL: ");270 if (batlvl < 100) 271 // Flash switch LED if low battery272 if (batlvl < LOWBAT) 273 t.oscillate(led_pin, 1000, HIGH);274 if (batlvl < 10) 275 lcd.print(" ");276277278 lcd.print(" ");279280 lcd.print(batlvl);281 lcd.print("%");282 if (debug) 283 Serial.print("Updating Batlvl: ");284 Serial.print(batlvl);285 Serial.println("286287 else 288 if (batlvl < LOWBAT) 289 t.oscillate(led_pin, 1000, HIGH);290291292293294 float V[4*N];295296 // Function for reading temperatures from all modules297 void readTemp() 298 int reading;299 float voltage;300 for (int i = 0; i < 4; i++) 301 // read from temperature sensor analog pin302 reading = analogRead(tempSensPin[i]);303 // convert the reading to voltage304 voltage = (reading * 5.0) / 1024.0;305 if (debug) 306 V[N*i+n] = voltage;307 //Serial.println(voltage);308 309 // convert voltage to degrees celcius310 float c = (voltage - 0.5) * 100.0;311 // store in array312 temps[N*i+n] = c;

Page | 40

Page 42: Final Report v2

313 314 // increment index315 n++;316 // loop index back to 0 if it reaches N and average temperature readings317 if (n >= N) 318 n = 0;319 if (debug) 320 float sumV = 0;321 for (int j = 0; j < N; j++) 322 sumV += V[j];323 324 Serial.print("Voltage: ");325 Serial.println(sumV/N);326 327 readAvgTemp();328 329 330331 // Function for averaging temperatures332 void readAvgTemp() 333 float oldTemp;334 float sum = 0;335 if (debug) Serial.print("Updating Temps: ");336 for (int i = 0; i < 4; i++) 337 // save old temperature average reading338 oldTemp = moduleTemp[i];339 // sum up temperature readings340 for (int j = 0; j < N; j++) 341 sum += temps[N*i+j];342 343 // calculate average temperature reading and convert to degrees farenheit344 if (debug) 345 Serial.print(sum / N);346 Serial.print("C\t");347 348 moduleTemp[i] = (sum / N) * 9.0 / 5.0 + 32.0;349 // save temperature rate of change350 tempRate[i] = moduleTemp[i] - oldTemp;351 //Serial.print(moduleTemp[i]);352 //Serial.print("F ");353 // reset sum to 0354 sum = 0;355 356 if (debug) 357 Serial.print("\n ");358 for (int j = 0; j < 4; j++) 359 Serial.print(moduleTemp[j]);360 Serial.print("F\t");361 362 Serial.println("\n");363 364 if (test) 365 lcd.setCursor(0,0);

Page | 41

Page 43: Final Report v2

366 lcd.print("TEMP: ");367 if (moduleTemp[selected] < 100)368 lcd.print(" ");369 lcd.print(moduleTemp[selected]);370 lcd.print("F ");371 372 373374 // Function for displaying the menu to the LCD375 void menu(int module) 376 // Move cursor to the first column of the second row377 lcd.setCursor(0,1);378 if (debug) 379 Serial.print("\nBAT LVL: ");380 Serial.print(batlvl);381 Serial.println("%");382 383 // print selected module to LCD384 switch(module) 385 case 0:386 lcd.print("LEFT GLOVE: ");387 if (debug) Serial.print("LEFT GLOVE: ");388 break;389 case 1:390 lcd.print("RIGHT GLOVE: ");391 if (debug) Serial.print("RIGHT GLOVE: ");392 break;393 case 2:394 lcd.print("LEFT BOOT: ");395 if (debug) Serial.print("LEFT BOOT: ");396 break;397 case 3:398 lcd.print("RIGHT BOOT: ");399 if (debug) Serial.print("RIGHT BOOT: ");400 break;401 402 // print the temperature setting of the module to the LCD403 lcd.setCursor(15,1);404 lcd.print(moduleSetLvl[module]);405 selected = module;406 if (debug) Serial.print(moduleSetLvl[module]);407 408409 // Function for checking status of buttons410 void buttonCheck() 411 // Wait until the time to the last button debounce is greater than the debouncedelay to do anything412 long now = millis();413 if ((now - lastDebounceTime) > debounceDelay) 414 int state = digitalRead(select_pin);415 if (buttonState[0] == HIGH) // Check if standby button pressed416 if (debug) Serial.println("\nStandby button pressed!");417 // invert toggled state and set the standby button state to low

Page | 42

Page 44: Final Report v2

418 toggled = !toggled;419 buttonState[0] = LOW;420 // reset all reached states to false and outputs to low if untoggled421 for (int i = 0; i < 4; i++) 422 reached[i] = false;423 if (!toggled) digitalWrite(moduleHeatPin[i],LOW);424 425 if (!toggled) lcd.noBlink();426 lastButtonPressed = 0;427 interrupts();428 else if (buttonState[1] == HIGH) // Check if up button pressed429 if (debug) Serial.println("\nUp button pressed!");430 // Increment the set temperature and update the menu431 incTemp();432 menu(selected);433 // reset variables434 buttonState[1] = LOW;435 for (int i = 0; i < 4; i++) reached[i] = false;436 lastButtonPressed = 1;437 interrupts();438 else if (buttonState[2] == HIGH) // Check if down button pressed439 if (debug) Serial.println("\nDown button pressed!");440 // Decrement the set temperature and update the menu441 decTemp();442 menu(selected);443 // reset variables444 buttonState[2] = LOW;445 for (int i = 0; i < 4; i++)446 reached[i] = false;447 lastButtonPressed = 2;448 interrupts();449 else if (buttonState[3] == HIGH) // Check if the select button is pressed450 if (debug) Serial.println("\nSelect button pressed!");451 // Update selected module and menu452 select();453 menu(selected);454 // reset variables455 buttonState[3] = LOW;456 if (test) readBatlvl();457 lastButtonPressed = 3;458 interrupts();459 else // if no button is pressed460 // if select is held, toggle the test display461 if (lastButtonPressed == 3 && state == HIGH) 462 testToggleCount++;463 //Serial.println(testToggleCount);464 if (testToggleCount > TEST_TOGGLE) 465 test = !test;466 testToggleCount = 0;467 readAvgTemp();468 469 else 470 testToggleCount = 0;

Page | 43

Page 45: Final Report v2

471 472 473 474 475476 // Function for controlling the heating elements with PWM/DCM477 void heat() 478 // Check if standby is toggled479 if (toggled) 480 // blink the temperature setting if any of the modules have not reached their settemperatures481 if (!reached[0] || !reached[1] || !reached[2] || !reached[3]) 482 lcd.setCursor(15,1);483 lcd.blink();484 else // turn off blinking otherwise485 lcd.noBlink();486 487 // Adjust PWM/DCM for each module if on488 for (int j=0; j < 4; j++) 489 if (debug) Serial.println(moduleTemp[j]);490 if (moduleSetLvl[j] == '0') continue;491492 // calculate the difference in temperature from current to set temperature493 float diff = moduleTemp[j] - (float)moduleSetTemp[j];494 if (diff < -FAR) // use aggressive heating level if colder by more than FAR495 if (debug) Serial.print("aggresive heating at ");496 heatLvl = aggrLvl;497 else if (diff < -NEAR) // use approaching heating level if colder by morethan NEAR498 if (debug) Serial.print("approuching heating at ");499 heatLvl = 230.0 * moduleSetTemp[j] / H;500 else if (diff < -BUFFER) // increase duty cycle if temp falls more thanBUFFER from set temp501 if (debug) Serial.println("buffer heating at ");502 if (reached[j]) 503 if (!buffered && heatLvl <= 245) 504 heatLvl+=10;505 buffered[j] = true;506 else if (heatLvl <= 253) heatLvl+=2;507 else 508 heatLvl = 204.0 * moduleSetTemp[j] / H;509 510 else if (diff < -BUFFER*2/5 && reached[j] && heatLvl < 255 && !buffered[j]) // increase heating if temp falls more than 2/5 of BUFFER511 heatLvl++;512 else if (diff > -1 && diff < 1 && !reached[j]) // set reached to true ifwithin 1513 if (debug) Serial.print("reached at ");514 reached[j] = true;515 buffered[j] = false;516 else if (diff > NEAR) // turn off heating if hotter by more than FAR517 if (debug) Serial.print("cooling at ");518 heatLvl = 0;

Page | 44

Page 46: Final Report v2

519 else if (diff > BUFFER) // decrease duty cycle if temp rises more thanBUFFER from set temp520 if (debug) Serial.print("buffer cooling at ");521 if (reached) 522 if (!buffered[j] && heatLvl >= 10) 523 heatLvl -= 15;524 buffered[j] = true;525 else if (heatLvl > 5) heatLvl -= 5;526 else 527 heatLvl = 0;528 529 else if (diff > BUFFER*2/5 && reached[j] && heatLvl > 5 && !buffered[j]) //decrease heating if temp rises more than 2/5 if BUFFER530 heatLvl -= 5;531 else // maintain heat level532 if (debug) Serial.print("maintaining at ");533 534 // set PWM duty cycle535 if (heatLvl >= 0 && heatLvl <= 255)536 pwmWrite(moduleHeatPin[j], heatLvl);537 if (debug) Serial.println(heatLvl);538539 //Serial.print("heating ");540 //Serial.println(j);541 542 //Serial.println("heating");543 //pwmWrite(moduleHeatPin[3], moduleSetLvl[3]);544 545 546547 // Function for incrementing the set temperature level of the selected module548 void incTemp() 549 switch(moduleSetLvl[selected]) 550 case '0':551 setTemp(L, selected);552 break;553 case 'L':554 setTemp(M, selected);555 break;556 case 'M':558 break;557 setTemp(H, selected);559 case 'H':560 break;561 562 563564 // Function for decrementing the set temperature level of the selected module565 void decTemp() 566 switch(moduleSetLvl[selected]) 567 case 'O':568 break;569 case 'L':

Page | 45

Page 47: Final Report v2

570 setTemp(0, selected);571 break;572 case 'M':573 setTemp(L, selected);574 break;575 case 'H':576 setTemp(M, selected);577 break;578 579 580 // Function for incrementing the selected variable to the next menu number581 void select() 582 if (selected < 3) // increments selected583 selected++;584 585 else // resets to 0 after 3586 selected = 0;587 588

Page | 46

Page 48: Final Report v2

12. Total Current CodeThe following is the currently existing version of the software for the Arduino Mega and APM. This includes all of the changes and edits that our team made as described in the rest of this document.

12.1. Main Code/* Integrated Ski Suit Heating System (ISSHS) interface and control program by Nathan Hollcraft

Used with the Arduino Mega 2560 The circuit: * LCD RS pin to digital pin 4 * LCD Enable pin to digital pin 6 * LCD D4 pin to digital pin 10 * LCD D5 pin to digital pin 5 * LCD D6 pin to digital pin 9 * LCD D7 pin to digital pin 13 * LCD R/W pin to ground * 10K potentiometer: * ends to +5V and ground * wiper to LCD VO pin (pin 3) * select button to digital pin 3 * down button to digital pin 18 * up button to digital pin 2 * standby button to digital pin 19 * 220 Ohm resistors from MOSFET gates to digital(PWM) pins 7,8,11,12 * TMP36 temperature sensor Vout pins to analog pins 0-3*/

// Libraries#include <LiquidCrystal.h>LiquidCrystal lcd(4,6,10,5,9,13);#include <EEPROMex.h>#include <PWM.h>#include "Timer.h"#include <Wire.h>

// Temperature settings#define L 70 // low temperature setting level#define M 85 // medium temperature setting level#define H 100 // high temperature setting level#define BUFFER 5 // temperature (F) buffer range#define NEAR 10 // temperature (F) near/approaching range#define FAR 20 // temperature (F) far/aggressive range// Periods of function calls#define N 50 // number of temperature readings to average#define tempReadRate 1000 // rate of temperature readings in milliseconds#define heatRate 1000 // rate of DCM heating function calls in milliseconds

Page | 47

Page 49: Final Report v2

#define TEST_TOGGLE 50000 // value counter needs to reach to toggle test display// Battery reading numbers for calculation

// Timer object for attaching events to Timer t;// I/O pinsconst int standby_pin = 19;const int up_pin = 2;const int down_pin = 18;const int select_pin = 3;const int tempSensPin[] = 0,1,2,3;const int moduleHeatPin[] = 12,11,8,7;

// Testing booleansboolean debug = true; // for serial prints

// test display toggle variablesboolean test = true; // determines if test menu should be displayedint lastButtonPressed = 0; // tracks which button was last pressedlong testToggleCount = 0; // counter for how long the button was pressed

// temperature variablesbyte moduleSetTemp[] = 70,70,70,70; // set temperatures of each modulechar moduleSetLvl[] = 'L','L','L','L'; // set temperature level (0/L/M/H) of each modulefloat moduleTemp[] = 70.0,70.0,70.0,70.0; // current temperature of each modulefloat temps[4*N]; // array of temperature readings for averagingfloat tempRate[] = 0.0,0.0,0.0,0.0; // temperature rates of changeint n = 0; // index of temp readings// button variablesboolean toggled = false; // heating status !!!!Note: This will determine if system begins in a heating state (true) or in a standby state (false)int buttonState[] = 0,0,0,0; // state of each buttonint lastButtonState[] = LOW,LOW,LOW,LOW; // previous state of each buttonlong lastDebounceTime = 0; // time (ms) of last button debouncelong debounceDelay = 250; // amount of delay (ms) between button pressesint selected = 0; // current module selected// heating variablesboolean buffered[] = false,false,false,false; // tracks if temperature exceeded buffering rangeint heatLvl = 64; // duty cycle (0-255) of PWM outputint aggrLvl = 127; // aggresive heating levelint apprLvl = 64; // approaching heating levelboolean reached[] = false,false,false,false; // if set temperature has been reachedint32_t freq = 5; // frequency of PWM output

// Standby button ISRvoid standbyPress() if ((millis() - lastDebounceTime) < debounceDelay) return; noInterrupts(); lastDebounceTime = millis(); buttonState[0] = HIGH;

Page | 48

Page 50: Final Report v2

// Up button ISRvoid upPress() if ((millis() - lastDebounceTime) < debounceDelay) return; noInterrupts(); lastDebounceTime = millis(); buttonState[1] = HIGH;

// Down button ISRvoid downPress() if ((millis() - lastDebounceTime) < debounceDelay) return; noInterrupts(); lastDebounceTime = millis(); buttonState[2] = HIGH;

// Select button ISRvoid selectPress() if ((millis() - lastDebounceTime) < debounceDelay) return; noInterrupts(); lastDebounceTime = millis(); buttonState[3] = HIGH;

void setup() // Welcome message lcd.begin(16,2); lcd.print("Integ. Ski Suit"); lcd.setCursor(0,1); lcd.print("Heating System"); if (debug) Serial.begin(9600); Serial.println("Integ. Ski Suit\nHeating System"); // Retrieve last set temperatures from EEPROM for (int addr = 0; addr < 4; addr++) setTemp(EEPROM.read(addr),addr); // Initialize button pins as inputs and the switch LED pin as output pinMode(standby_pin, INPUT); pinMode(up_pin, INPUT); pinMode(down_pin, INPUT); pinMode(select_pin, INPUT); // Set PWM pins to required frequency InitTimersSafe();

Page | 49

Page 51: Final Report v2

for (int i = 0; i < 4; i++) if (debug) Serial.print("Setting frequency for heat pin "); Serial.print(i); Serial.print("..."); while (!SetPinFrequencySafe(moduleHeatPin[i], freq)); if (debug) Serial.println("success"); // Attach interrupts for buttons attachInterrupt(4, standbyPress, RISING); attachInterrupt(0, upPress, RISING); attachInterrupt(5, downPress, RISING); attachInterrupt(1, selectPress, RISING); // Initialize temperature readings for (int i = 0; i < N; i++) readTemp(); delay(5000); lcd.clear(); menu(selected); // Attach functions for reading temperature and battery and heating to timer t.every(tempReadRate/N,readTemp); //t.every(batReadRate,readBatlvl); t.every(heatRate,heat); if (debug) Serial.println("setup complete\n");

void loop() // Check for button presses buttonCheck(); // Service all events associated with the timer t.update();

// Function for setting the temperature of a modulebyte setTemp(byte temp, byte module) if (temp >= 0 && temp <= 110) // Update temperature setting for the module switch (temp) case 0: moduleSetLvl[module] = '0'; break; case L: moduleSetLvl[module] = 'L'; break; case M:

Page | 50

Page 52: Final Report v2

moduleSetLvl[module] = 'M'; break; case H: moduleSetLvl[module] = 'H'; break; default: moduleSetLvl[module] = '0'; break; moduleSetTemp[module] = temp; // Write temperature setting to EEPROM for retrieval on reset EEPROM.write(module, temp);

float V[4*N];

// Function for reading temperatures from all modulesvoid readTemp() int reading; float voltage; for (int i = 0; i < 4; i++) // read from temperature sensor analog pin reading = analogRead(tempSensPin[i]); // convert the reading to voltage voltage = (reading * 5.0) / 1023; if (debug) V[N*i+n] = voltage; //Serial.println(voltage); // convert voltage to degrees celcius float c = (voltage - 0.5) * 100.0; // store in array temps[N*i+n] = c; // increment index n++; // loop index back to 0 if it reaches N and average temperature readings if (n >= N) n = 0; if (debug) float sumV = 0; for (int j = 0; j < N; j++) sumV += V[j]; Serial.print("Voltage: "); Serial.println(sumV/N); readAvgTemp();

// Function for averaging temperaturesPage | 51

Page 53: Final Report v2

void readAvgTemp() float oldTemp; float sum = 0; if (debug) Serial.print("Updating Temps: "); for (int i = 0; i < 4; i++) // save old temperature average reading oldTemp = moduleTemp[i]; // sum up temperature readings for (int j = 0; j < N; j++) sum += temps[N*i+j]; // calculate average temperature reading and convert to degrees farenheit if (debug) Serial.print(sum / N); Serial.print("C\t"); moduleTemp[i] = (sum / N) * 9.0 / 5.0 + 32.0; // save temperature rate of change tempRate[i] = moduleTemp[i] - oldTemp; //Serial.print(moduleTemp[i]); //Serial.print("F "); // reset sum to 0 sum = 0; if (debug) Serial.print("\n "); for (int j = 0; j < 4; j++) Serial.print(moduleTemp[j]); Serial.print("F\t"); Serial.println("\n"); if (test) lcd.setCursor(0,0); lcd.print("TEMP: "); if (moduleTemp[selected] < 100) lcd.print(" "); lcd.print(moduleTemp[selected]); lcd.print("F ");

// Function for displaying the menu to the LCDvoid menu(int module) // Move cursor to the first column of the second row lcd.setCursor(0,1); // print selected module to LCD switch(module) case 0: lcd.print("RIGHT BOOT: "); if (debug) Serial.print("LEFT GLOVE: "); break;

Page | 52

Page 54: Final Report v2

case 1: lcd.print("LEFT BOOT: "); if (debug) Serial.print("RIGHT GLOVE: "); break; case 2: lcd.print("RIGHT GLOVE: "); if (debug) Serial.print("LEFT BOOT: "); break; case 3: lcd.print("LEFT GLOVE: "); if (debug) Serial.print("RIGHT BOOT: "); break; // print the temperature setting of the module to the LCD lcd.setCursor(15,1); lcd.print(moduleSetLvl[module]); selected = module; if (debug) Serial.println(moduleSetLvl[module]);

// Function for checking status of buttonsvoid buttonCheck() // Wait until the time to the last button debounce is greater than the debounce delay to do anything long now = millis(); if ((now - lastDebounceTime) > debounceDelay) int state = digitalRead(select_pin); if (buttonState[0] == HIGH) // Check if standby button pressed if (debug) Serial.println("\nStandby button pressed!"); // invert toggled state and set the standby button state to low toggled = !toggled; buttonState[0] = LOW; // reset all reached states to false and outputs to low if untoggled for (int i = 0; i < 4; i++) reached[i] = false; if (!toggled) digitalWrite(moduleHeatPin[i],LOW); if (!toggled) lcd.noBlink(); lastButtonPressed = 0; interrupts(); else if (buttonState[1] == HIGH) // Check if up button pressed if (debug) Serial.println("\nUp button pressed!"); // Increment the set temperature and update the menu incTemp(); menu(selected); // reset variables buttonState[1] = LOW; for (int i = 0; i < 4; i++) reached[i] = false; lastButtonPressed = 1; interrupts(); else if (buttonState[2] == HIGH) // Check if down button pressed if (debug) Serial.println("\nDown button pressed!"); // Decrement the set temperature and update the menu decTemp();

Page | 53

Page 55: Final Report v2

menu(selected); // reset variables buttonState[2] = LOW; for (int i = 0; i < 4; i++) reached[i] = false; lastButtonPressed = 2; interrupts(); else if (buttonState[3] == HIGH) // Check if the select button is pressed if (debug) Serial.println("\nSelect button pressed!"); // Update selected module and menu select(); menu(selected); // reset variables buttonState[3] = LOW; //if (test) readBatlvl(); lastButtonPressed = 3; interrupts(); else // if no button is pressed // if select is held, toggle the test display if (lastButtonPressed == 3 && state == HIGH) testToggleCount++; //Serial.println(testToggleCount); if (testToggleCount > TEST_TOGGLE) test = !test; testToggleCount = 0; readAvgTemp(); else testToggleCount = 0;

// Function for controlling the heating elements with PWM/DCMvoid heat() // Check if standby is toggled if (toggled) // blink the temperature setting if any of the modules have not reached their set temperatures if (!reached[0] || !reached[1] || !reached[2] || !reached[3]) lcd.setCursor(15,1); lcd.blink(); else // turn off blinking otherwise lcd.noBlink(); // Adjust PWM/DCM for each module if on for (int j=0; j < 4; j++) if (debug) Serial.println(moduleTemp[j]); if (moduleSetLvl[j] == '0') continue; // calculate the difference in temperature from current to set temperature float diff = moduleTemp[j] - (float)moduleSetTemp[j]; if (diff < -FAR) // use aggressive heating level if colder by more than FAR

Page | 54

Page 56: Final Report v2

if (debug) Serial.print("aggresive heating at "); heatLvl = aggrLvl; else if (diff < -NEAR) // use approaching heating level if colder by more than NEAR if (debug) Serial.print("approuching heating at "); heatLvl = 230.0 * moduleSetTemp[j] / H; else if (diff < -BUFFER) // increase duty cycle if temp falls more than BUFFER from set temp if (debug) Serial.println("buffer heating at "); if (reached[j]) if (!buffered && heatLvl <= 245) heatLvl+=10; buffered[j] = true; else if (heatLvl <= 253) heatLvl+=2; else heatLvl = 204.0 * moduleSetTemp[j] / H; else if (diff < -BUFFER*2/5 && reached[j] && heatLvl < 255 && !buffered[j]) // increase heating if temp falls more than 2/5 of BUFFER heatLvl++; else if (diff > -1 && diff < 1 && !reached[j]) // set reached to true if within 1 if (debug) Serial.print("reached at "); reached[j] = true; buffered[j] = false; else if (diff > NEAR) // turn off heating if hotter by more than FAR if (debug) Serial.print("cooling at "); heatLvl = 0; else if (diff > BUFFER) // decrease duty cycle if temp rises more than BUFFER from set temp if (debug) Serial.print("buffer cooling at "); if (reached) if (!buffered[j] && heatLvl >= 10) heatLvl -= 15; buffered[j] = true; else if (heatLvl > 5) heatLvl -= 5; else heatLvl = 0; else if (diff > BUFFER*2/5 && reached[j] && heatLvl > 5 && !buffered[j]) // decrease heating if temp rises more than 2/5 if BUFFER heatLvl -= 5; else // maintain heat level if (debug) Serial.print("maintaining at "); // set PWM duty cycle if (heatLvl >= 0 && heatLvl <= 255) pwmWrite(moduleHeatPin[j], heatLvl); if (debug) Serial.println(heatLvl); //Serial.print("heating "); //Serial.println(j); //Serial.println("heating"); //pwmWrite(moduleHeatPin[3], moduleSetLvl[3]);

Page | 55

Page 57: Final Report v2

// Function for incrementing the set temperature level of the selected modulevoid incTemp() switch(moduleSetLvl[selected]) case '0': setTemp(L, selected); break; case 'L': setTemp(M, selected); break; case 'M': setTemp(H, selected); break; case 'H': break;

// Function for decrementing the set temperature level of the selected modulevoid decTemp() switch(moduleSetLvl[selected]) case 'O': break; case 'L': setTemp(0, selected); break; case 'M': setTemp(L, selected); break; case 'H': setTemp(M, selected); break; // Function for incrementing the selected variable to the next menu numbervoid select() if (selected < 3) // increments selected selected++; else // resets to 0 after 3 selected = 0;

Page | 56

Page 58: Final Report v2

12.2. BMS Code: /*Integrated Ski Suit Heating System (ISSHS) Part II Battery Monitoring Systemby Nathan Hollcraft

Arduino Pro Mini was used.Circuit: LTC 4150 POL pin to digital 4LTC 4150 ~INT pin to digital 3LED GRN to digital 6LED YLW to digital 7LED ORN to digital 8LED RED to digital 9 */

// Write Library inclusions here

// Definitions// Temp Settings#define MAXBAT 7072 // maximum battery counts possible with given battery#define GRNBAT (MAXBAT*0.75) // below this count, Green LED is turned on#define REDBAT (MAXBAT*0.5) // below this count, Red LED is turned on solid#define BNKBAT (MAXBAT*0.25) // below this count, Red LED is flashed on and off#define flashRate 500 // rate at which Red LED is flashed in milliseconds

// I/O pinsconst int POL_pin = 4;const int INT_pin = 3;const int BLU_pin = 6;const int GRN_pin = 7;const int GND_pin = 8;const int RED_pin = 9;int x=0;

volatile long BATcount = 7070; //

boolean debug = false; // for testing purposes

unsigned long T;

void setup() // put your setup code here, to run once: if (debug) Serial.begin (9600); pinMode(POL_pin, INPUT); attachInterrupt(digitalPinToInterrupt(INT_pin), BatteryCounter, FALLING); pinMode(BLU_pin, OUTPUT); pinMode(GRN_pin, OUTPUT); pinMode(GND_pin, OUTPUT); pinMode(RED_pin, OUTPUT);

Page | 57

Page 59: Final Report v2

digitalWrite(GND_pin, LOW);

void loop() // put your main code here, to run repeatedly: updateLEDs(BATcount); if (debug) T=millis(); Serial.println(BATcount); Serial.println(T); Serial.println();

if (BATcount < 0) BATcount = 0; else if (BATcount > MAXBAT) BATcount = MAXBAT; delay(flashRate);// if (BATcount > 44000) // BATcount = 44000;// // Serial.print("DATA,TIME,TIMER");// Serial.print(T);// Serial.print(BATcount);// Serial.println();// delay(100);

void BatteryCounter() if (digitalRead(POL_pin) == LOW) BATcount--; // we are discharging else BATcount++; // we are charging

void updateLEDs(volatile long BATcount) if (BATcount > GRNBAT) digitalWrite(BLU_pin, HIGH); digitalWrite(GRN_pin, LOW); digitalWrite(RED_pin, LOW); else if (BATcount > REDBAT) digitalWrite(BLU_pin, LOW); digitalWrite(GRN_pin, HIGH); digitalWrite(RED_pin, LOW); else if (BATcount > BNKBAT) digitalWrite(BLU_pin, LOW);

Page | 58

Page 60: Final Report v2

digitalWrite(GRN_pin, LOW); digitalWrite(RED_pin, HIGH); else x++; digitalWrite(BLU_pin, LOW); digitalWrite(GRN_pin, LOW); if (x%2 == 0) digitalWrite(RED_pin, HIGH); else digitalWrite(RED_pin, LOW);

Page | 59