diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..05f86c2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,45 @@
+# ---> KiCad
+# For PCBs designed using KiCad: https://www.kicad.org/
+# Format documentation: https://kicad.org/help/file-formats/
+
+# Temporary files
+*.000
+*.bak
+*.bck
+*.kicad_pcb-bak
+*.kicad_sch-bak
+*-backups
+*.kicad_prl
+*.sch-bak
+*~
+_autosave-*
+*.tmp
+*-save.pro
+*-save.kicad_pcb
+fp-info-cache
+*.kicad_pro
+*.lck
+
+# Netlist files (exported from Eeschema)
+*.net
+
+# Autorouter files (exported from Pcbnew)
+*.dsn
+*.ses
+
+# Exported BOM files
+*.xml
+*.csv
+
+# Fabrication files
+*.gb*
+*.gm*
+*.drl
+*.zip
+*.gt*
+
+# Avrdude files
+*.hex
+*.elf
+*.lst
+*.o
diff --git a/HotWaterManager.h b/HotWaterManager.h
new file mode 100644
index 0000000..ba2599f
--- /dev/null
+++ b/HotWaterManager.h
@@ -0,0 +1,222 @@
+// ****** Hardware Model definitions ********
+
+#define ARDUINO_ 0 // Use this one if you want to build this project around an Arduino
+#define HWV_1_0 1 // Hardware version 1.0 of the Thermal Optimizer board (only a few were made)
+#define HWV_1_1 2 // Hardware version 1.1 of the Thermal Optimizer board
+#define HWV_1_2 3 // Hardware version 1.2 of the Thermal Optimizer board
+
+// ********* Hardware Model ************
+#define HWMODEL ARDUINO_ // Change this into the hardware model you want to compile for
+
+// Debug definitions, leave commented for production!
+//#define SIMTEMP 80 // Use this to test the program without actual temperature sensors connected. 50 simulates 8.0 Celcius
+//#define SIMVOLT 132 // Use this to test the program for a specific voltage. 132 simulates 13.2
+//#define USEDEFAULT 1 // declutter the EPROM, use the defaults
+
+#if HWMODEL == ARDUINO_
+#define HWVER "UNO"
+#endif
+#if HWMODEL == HWV_1_0
+#define HWVER "1.0"
+#endif
+#if HWMODEL == HWV_1_1
+#define HWVER "1.1"
+#endif
+#if HWMODEL == HWV_1_2
+#define HWVER "1.2"
+#endif
+
+/*
+ * Voltage measuring
+ * =================
+ * To bring the system voltage within the range of the ADC's we have to use a resistor divider
+ * We want to be compatible with 24V systems, so we dimensioned the resistor dividers accordingly
+ * ADC1
+ * _______ | _______
+ * VCC --|_____|---|----|_____|--- GND
+ * R1 R2
+ *
+ * In the latest Thermal Optimizer board we use for R1 39k, for R2 7k5.
+ * If R1=39k, and R2=7k5...
+ * If we assume a maximum voltage of 15V, then this would give 2.42V on the input of ADC1, with a load of 0.25mA
+ * If we assume a maximum voltage of 30V, then this would give 4.84V on the input of ADC1, with a load of 0.5mA
+ *
+ * The math:
+ * Voltage = ADC1*AREF/(1024+1) * (R1+R2)/(R2)
+ *
+ * If you build an Arduino based circuit yourself, You can change the values of R1 and R2 in the source code.
+ *
+*/
+#define ADCREF 5000UL // Voltage of the 5V power supply in millivolts
+
+#if HWMODEL == ARDUINO_
+#define R1 10000UL // Ohms
+#define R2 1800UL // Ohms
+#endif
+#if HWMODEL == HWV_1_0
+#define R1 10000UL // Ohms
+#define R2 1880UL // Ohms
+#endif
+#if HWMODEL > HWV_1_0
+#define R1 39000UL // Ohms
+#define R2 7500UL // Ohms
+#endif
+
+#if HWMODEL == ARDUINO_
+#define TEMPR 4700 // Ohms of the temperature sensor pull up resistor
+#endif
+#if HWMODEL == HWV_1_0
+#define TEMPR 4700 // Ohms of the temperature sensor pull up resistor
+#endif
+#if HWMODEL > HWV_1_0
+#define TEMPR 10000 // Ohms of the temperature sensor pull up resistor
+#endif
+
+#define THERMISTOR 5000 // Reference value of the thermistor
+#define THERMBETA 3950 // Beta value of the thermistor
+#define TEMPSAMPLES 8 // Number of samples for averaging the temperature with a thermistor
+
+
+// IO ports
+#define BUTTON 2 // Button needs to be port PD2 or PD3 because of wake up interrupt
+#define VCCREF A1 // Voltage sense
+#define ENGINE 16 // Engine contact sense wire
+
+#if HWMODEL == ARDUINO_
+#define TEMP 14
+#else
+#define TEMP 19 // Temperature sensor (port 19 is ADC 5, conflict if I2C bus is used)
+#endif
+
+#define LED 13 // Conventionally, this port is used to control a LED
+
+#if HWMODEL == ARDUINO_
+#define HEATER 3 // Heater relay control output (Port 18 is ADC 4, conflict if I2C bus is used)
+#define BACKLIGHT_B0 18 // Display backlight, bit 0
+#define BACKLIGHT_B1 12 // Display backlight, bit 1
+#define BACKLIGHT_B2 11 // Display backlight, bit 2
+#endif
+#if HWMODEL == HWV_1_0
+#define HEATER 18 // Heater relay control output (Port 18 is ADC 4, conflict if I2C bus is used)
+#define BACKLIGHT_B0 3 // Display backlight, bit 0, NOT IMPLEMENTED IN HWV 1_0
+#define BACKLIGHT_B1 14 // Display backlight, bit 1, NOT IMPLEMENTED IN HWV 1_0
+#define BACKLIGHT_B2 11 // Display backlight, bit 2
+#endif
+#if HWMODEL > HWV_1_0
+#define HEATER 3
+#define BACKLIGHT_B0 18 // Display backlight, bit 0
+#define BACKLIGHT_B1 14 // Display backlight, bit 1
+#define BACKLIGHT_B2 11 // Display backlight, bit 2
+#endif
+
+#if HWMODEL > HWV_1_0
+#define OWPULLUP 24 // (ATMEGA328pb only, PE1) PullUp for one wire interface
+#endif
+
+#if HWMODEL > HWV_1_1
+#define LUMSENS 25 // (ATMEGA328pb only, PE2) ADC port to sens LED luminance
+#endif
+
+#define AUX 17 // Auxilliary output
+#define HWV 10 // Hot Water Valve
+
+// Interfaces
+//#define LCDADDR 0x3F // I2C address, uncomment for I2C display (but you have to free up ADC4 (18) and ADC5 (19))
+#define LCD_RS 9 // Used only when no I2C is used
+#define LCD_EN 8 // Used only when no I2C is used
+#define LCD_D4 4 // Used only when no I2C is used
+#define LCD_D5 5 // Used only when no I2C is used
+#define LCD_D6 6 // Used only when no I2C is used
+#define LCD_D7 7 // Used only when no I2C is used
+
+
+// Constants
+#define VERSION "1.1" // Software version to display on the screen
+#define EPROMCHK 0x7875 // EPROM signature so we can detect that the EPROM content is ours.
+//#define SHORTPRESS 25 // Minimum time in milliseconds to register a button press as valid instead of just a noise spike (not used with touch sensor)
+#define LONGPRESS 650 // Time in milliseconds to register a key press as a long press.
+#define MENUTIMEOUT 10 // Timeout in seconds to return to default operation from within the menu.
+
+// Defaults after factory reset (can be changed in the menu afterwards)
+#define BRIGHTNESS 5 // Default LCD backlight brightness, 0 to 7
+#define DISPTIMEOUT 0 // LCD backlight timeout in seconds
+#define NIGHTSENSOR 11 // Darkness sensor value
+#define VREQ 141 // Required voltage*10 to switch on the heater automatically.
+#define VFLOAT 135 // Float voltage*10 to switch off the heater automatically
+#define VOFF 125 // Voltage*10 at which a pause has to be taken to recharge the batteries first
+#define PAUSE 20 // Duration of the pause in minutes
+#define TMIN 40 // Antifreeze protection should be initiated below this temperature (Celsius*10)
+#define TTARGET 400 // Target temperature (Celsius*10) for daily usage
+#define TSANITY 600 // Temperature (Celsius*10) needed to clear the "sanity alert"
+#define TMAX 800 // Maximum allowed temperature (Celsius*10)
+#define TNOSAN 250 // Don't display a sanity alert below this temperature (Celsius*10)
+#define TSANDAYS 7 // Interval in days between reaching the "sanity temperature" to not raise the "sanity alert"
+#define PUMPDELTA 25 // Difference in input and boiler temperature in Celsius*10
+#define PUMPAFTERRUN 60 // Time in seconds to continue running the pump after PUMPDELTA is no longer met
+#define HWVTIMER 0 // Time in minutes to enable hot water valve
+#define HWVPWM 100 // Hot water valve PWM in % (100 is disable)
+#define HWVBLEED 5 // Time in seconds to open the HWV when the heating element is energized, to bleed out any air.
+#define HOLDON 5 // Time in seconds to hold on, after switching the boiler on, to give chargers some time to react to the load
+#define RELAYPWM 100 // Percentage of hold current of the relay
+
+// Constants that are not configurable in the menu.
+#define HOLD_OFF 60 // Seconds to wait after last heater state change before switching it on again.
+#define TRENDDELTA 3 // Temperature (Celsius*10) difference required to change the trend arrow
+#define LUMSAMPLES 16 // Samples to average the measured luminance via the LED.
+
+// LED mode constants
+#define LEDM_TOUCH 0
+#define LEDM_WARMWATER 1
+#define LEDM_HEATING 2
+#define LEDM_HWVALVE 3
+#define LEDM_LEGIONELLA 4
+
+
+// Structure definitions
+
+struct rom_t {
+ uint16_t epromchk; uint8_t brightness; uint8_t disptimeout; uint16_t vreq; uint16_t vfloat; uint16_t voff; int16_t pause; boolean fahrenheit; int16_t tmin; int16_t ttarget;
+ int16_t tsanity; int16_t tmax; int16_t tsandays; int16_t tnosan; uint16_t calibration; int16_t pumpdelta; uint16_t pumpafterrun; uint16_t hwv_timer; bool vmul; uint8_t hwv_pwm;
+ uint8_t pumpMode; uint8_t ledmode; bool lcdglow; uint8_t holdon; uint8_t nightbright; uint8_t nightsensor; uint8_t relaypwm; bool altfunc;
+};
+
+struct sensors_t {
+ uint16_t epromchk;
+ uint8_t temphwa[2][8];
+ int16_t thermistor;
+ int16_t thermbeta;
+ bool useDS;
+};
+
+struct mma_t {
+ uint16_t samples;
+ int16_t avg;
+ int32_t sum;
+};
+
+struct tempdata_t {
+ int16_t temperature;
+ int16_t failures;
+ int16_t fallback;
+ mma_t mmaTemp;
+};
+
+struct button_t {
+ const uint8_t button;
+ uint32_t pressed; // Button press duration
+ bool longpressed;
+};
+
+void fptr_dummy(void);
+void fptr_brightness(void);
+void fptr_showvoltage(void);
+void fptr_showTemp(void);
+void fptr_showtemps(void);
+void fptr_vmul(void);
+void fptr_units(void);
+void fptr_altfunc(void);
+void fptr_ledmode(void);
+void fptr_pumpsource(void);
+void fptr_lumsens(void);
+void fptr_versions(void);
+void fptr_serialnr(void);
diff --git a/HotWaterManager.ino b/HotWaterManager.ino
new file mode 100644
index 0000000..df79251
--- /dev/null
+++ b/HotWaterManager.ino
@@ -0,0 +1,1521 @@
+/* Hot water manager
+ * -----------------
+ * This is a feature rich smart hot water management system
+ *
+ * More details and explanation of this project can be found at https://www.thefloatinglab.world/en/boilers.html
+ * This project is developed and maintained at https://git.thefloatinglab.world/thefloatinglab/hotwatermanager
+ *
+ * License
+ * -------
+ * HotWaterManager, a feature rich smart hot water management system.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * Objective
+ * ---------
+ * Objective was to create a hot water management system based on an Arduino architecture.
+ *
+ * More details and a list of features can be found at https://www.thefloatinglab.world/en/boilers.html
+ *
+ * Requirements
+ * ------------
+ * The microcontroller should be a ATMEGA328.
+ * The microcontroller clock speed needs to be at least 4 MHz
+ * The power supply should be 5V, with lower voltages the voltage measurement and range degrades and a standard 5V LCD will not work.
+ */
+
+// Libraries
+#include "HotWaterManager.h"
+#include
+#include
+#include
+#include
+
+#ifdef LCDADDR
+#include
+LiquidCrystal_I2C lcd(LCDADDR,16,2); // set the LCD address to LCDADDR for a 16 chars and 2 line display
+#else
+#include
+// initialize the library by associating any needed LCD interface pin
+// with the arduino pin number it is connected to
+LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
+#endif
+
+#include
+OneWire ds(TEMP); // Connect 1-wire devices
+
+rom_t rom = {EPROMCHK,BRIGHTNESS,DISPTIMEOUT,VREQ,VFLOAT,VOFF,PAUSE,false,TMIN,TTARGET,TSANITY,TMAX,TSANDAYS,TNOSAN, 1000, PUMPDELTA, PUMPAFTERRUN, HWVTIMER, false, HWVPWM, 0, LEDM_TOUCH, false, HOLDON, 0, NIGHTSENSOR, RELAYPWM, false};
+
+sensors_t sensors = {EPROMCHK,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, THERMISTOR, THERMBETA, true};
+
+// Reserve space for two DS18B20 sensors
+tempdata_t tempdata[] = {{0,0,1000},{0,0,-1000}};
+
+button_t button = {BUTTON,0,false};
+
+// Special characters for LCD
+uint8_t hwvchar[8] = {0b10001,0b10001,0b10001,0b10001,0b10001,0b10001,0b10001,0b00000};
+uint8_t Anchor[8] = {0b00100,0b01010,0b00100,0b00100,0b00100,0b10101,0b01110,0b00000};
+uint8_t Sailing[8] = {0b00010,0b00110,0b01111,0b01111,0b11111,0b00010,0b11111,0b01110};
+uint8_t engine[8] = {0b00000,0b01111,0b00100,0b01111,0b11111,0b01111,0b00000,0b00000};
+uint8_t solar[8] = {0b11111,0b11111,0b01110,0b00000,0b10101,0b10101,0b10101,0b00000};
+uint8_t legion[8] = {0b01110,0b11111,0b10101,0b11111,0b11011,0b11011,0b01110,0b00000};
+uint8_t down[8] = {0b00100,0b00100,0b00100,0b00100,0b10101,0b01110,0b00100,0b00000};
+uint8_t up[8] = {0b00100,0b01110,0b10101,0b00100,0b00100,0b00100,0b00100,0b00000};
+uint8_t lightning[8]={0b00011,0b00110,0b01100,0b11110,0b00110,0b01100,0b01000,0b10000};
+uint8_t Tmr[8] = {0b00000,0b01110,0b10101,0b10111,0b10001,0b01110,0b00000,0b00000};
+
+// Variables
+
+uint8_t mode=0;
+uint8_t menusel=0;
+boolean menuedit=false;
+boolean swapTsens=false;
+
+int16_t lastTemperature=0;
+
+boolean lcdon=true;
+boolean romdirty=false;
+boolean freset=false;
+boolean sreset=false;
+boolean reboot=false;
+
+boolean paused=true;
+boolean restartTmrReq=true;
+boolean hwv=false;
+
+uint32_t secs=0;
+uint32_t disptimer=0;
+uint32_t menuseltimer=0;
+uint32_t pauseTmr=0;
+uint32_t restartTmr=0;
+uint32_t pumpTimer=0;
+uint32_t HWVtmr=0;
+uint32_t lastlum=0;
+
+uint16_t hwv_timer=0;
+uint16_t rawVoltages[5];
+uint16_t thermists[5];
+
+uint8_t dummy;
+
+uint8_t bright;
+mma_t lum;
+
+
+
+// menu code, 8 bits
+#define MENU_8 B00001000
+#define MENU_16 B00010000
+#define MENU_SIGNED B10000000
+#define MENU_FLOAT B00000011
+#define MENU_BOOLEAN B01000000
+#define MENU_TEMP B00000100
+#define MENU_VOLTS B00100000
+#define MENU_SHOW B11111111
+
+// SFX extension code, 4 bits
+#define NOALT B01000000
+#define FNALT B00100000
+
+// Suffixes for some menu options
+const char sfx_seconds[] PROGMEM = " seconds";
+const char sfx_minutes[] PROGMEM = " minutes";
+const char sfx_days[] PROGMEM = " days";
+const char sfx_percent[] PROGMEM = " percent";
+const char sfx_volts[] PROGMEM = "V";
+const char sfx_deg[] PROGMEM = "\xDF""C";
+const char sfx_ohms[] PROGMEM = "\xF4";
+const char* const suffixes[] = {sfx_seconds,sfx_minutes,sfx_days,sfx_percent,sfx_volts,sfx_deg,sfx_ohms};
+
+
+// Build the menu table structure
+
+typedef void (*funcptr_t)();
+
+struct menu_t {
+ const char txt[17];
+ const uint8_t sfx;
+ const uint8_t code;
+ const int16_t min;
+ const int16_t max;
+ const int16_t step;
+ funcptr_t funcptr;
+ const void *varptr;
+};
+
+const menu_t PROGMEM menu[]= {
+ // Display, suffix, Menu flags min, max, step, function call, address of variable
+ {"System Volts", 0, MENU_8, 0, 1, 1, &fptr_vmul, &rom.vmul},
+ {"Temp Units", 0, MENU_8, 0, 1, 1, &fptr_units, &rom.fahrenheit},
+ {"Min Temperature", 0, MENU_16+MENU_SIGNED+MENU_TEMP+1, 0, 100, 10, &fptr_dummy, &rom.tmin},
+ {"Target Temp", 0, MENU_16+MENU_SIGNED+MENU_TEMP+1, 340, 520, 20, &fptr_dummy, &rom.ttarget},
+ {"Max Temperature", 0, MENU_16+MENU_SIGNED+MENU_TEMP+1, 600, 900, 50, &fptr_dummy, &rom.tmax},
+ {"Sanity Temp", 0, MENU_16+MENU_SIGNED+MENU_TEMP+1, 560, 680, 20, &fptr_dummy, &rom.tsanity},
+ {"Sanity interval", 3, MENU_16+MENU_SIGNED, 2, 14, 1, &fptr_dummy, &rom.tsandays},
+ {"No Sanity below", 0, MENU_16+MENU_SIGNED+MENU_TEMP+1, 200, 300, 10, &fptr_dummy, &rom.tnosan},
+ {"Start Voltage", 5, MENU_16+MENU_VOLTS+1, 138, 148, 1, &fptr_dummy, &rom.vreq},
+ {"Float Voltage", 5, MENU_16+MENU_VOLTS+1, 125, 140, 1, &fptr_dummy, &rom.vfloat},
+ {"Abort Voltage", 5, MENU_16+MENU_VOLTS+1, 120, 135, 1, &fptr_dummy, &rom.voff},
+ {"Pause duration", 2, MENU_16+MENU_SIGNED, 5, 45, 5, &fptr_dummy, &rom.pause},
+ {"Hold On time", 1, MENU_8, 0, 10, 1, &fptr_dummy, &rom.holdon},
+#if HWMODEL != HWV_1_0
+ {"LCD Brightness", 0, MENU_8, 1, 7, 1, &fptr_brightness, &rom.brightness},
+#if HWMODEL > HWV_1_1
+ {"LCD NightBright", 0, MENU_8, 0, 7, 1, &fptr_dummy, &rom.nightbright},
+ {"LCD NightSensor", 0, MENU_8, 6, 16, 1, &fptr_lumsens, &rom.nightsensor},
+#endif
+ {"LCD Glow", 0, MENU_BOOLEAN, 0, 1, 1, &fptr_dummy, &rom.lcdglow},
+#endif
+ {"LCD TimeOut", 1, MENU_8, 0, 10, 1, &fptr_dummy, &rom.disptimeout},
+ {"LED Mode", 0, MENU_8, 0, 4, 1, &fptr_ledmode, &rom.ledmode},
+ {"Vlt Calibration", 0, MENU_16, 920, 1080, 1, &fptr_showvoltage, &rom.calibration},
+ {"Pump Source", 0, MENU_8, 0, 2, 1, &fptr_pumpsource, &rom.pumpMode},
+ {"Pump delta", 6, MENU_16+MENU_SIGNED, 5, 100, 5, &fptr_dummy, &rom.pumpdelta},
+ {"Pump afterrun", 1, MENU_16, 0, 300, 30, &fptr_dummy, &rom.pumpafterrun},
+ {"Hot Water timer", 2, MENU_16, 0, 180, 15, &fptr_dummy, &rom.hwv_timer},
+ {"Hot Water pwr", 4, MENU_8, 50, 100, 10, &fptr_dummy, &rom.hwv_pwm},
+#if HWMODEL != HWV_1_0
+ {"Relay hold pwr", 4, MENU_8, 50, 100, 10, &fptr_dummy, &rom.relaypwm},
+#endif
+ {"Thermistor R", 7, MENU_16, 5000, 10000,5000, &fptr_showTemp, &sensors.thermistor},
+ {"Thermistor Beta", 0, MENU_16, 3000, 4200, 50, &fptr_showTemp, &sensors.thermbeta},
+ {"Swap temp sens", 0, MENU_BOOLEAN, 0, 1, 1, &fptr_showtemps, &swapTsens},
+ {"Reboot", 0, MENU_BOOLEAN, 0, 1, 1, &fptr_dummy, &reboot},
+ {"Factory reset", 0, MENU_BOOLEAN, 0, 1, 1, &fptr_dummy, &freset},
+ {"Sensors reset", 0, MENU_BOOLEAN, 0, 1, 1, &fptr_dummy, &sreset},
+ {"Versions", 0, MENU_SHOW, 0, 1, 1, &fptr_versions, &dummy},
+#if HWMODEL != ARDUINO_
+ {"Serial number", 0, MENU_8, 0, 1, 1, &fptr_serialnr, &dummy},
+#endif
+ {"",0,0,0,0,0,NULL,NULL}
+};
+
+
+
+// Interrupt routines
+
+EMPTY_INTERRUPT(INT0_vect); // external interrupt 0 (button press) wakes the MCU
+
+ISR(WDT_vect) { // Watchdog interrupt for the sleep timer
+ wdt_disable(); // disable watchdog
+}
+
+void(* resetFunc) (void) = 0; // declare reset function at address 0
+
+
+// If no bootloader is used, this code is necessary to prevent a watchdog reset repeating itself after the reboot
+
+void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));
+
+void wdt_init(void) {
+ MCUSR = 0;
+ wdt_disable();
+ return;
+}
+
+
+void setup() {
+ MCUSR = 0; // Just to make sure the watchdog from the previous run...
+ wdt_disable(); // ... does not continue to run
+
+ pinMode(BUTTON,INPUT_PULLUP);
+ pinMode(ENGINE,INPUT);
+ pinMode(LED,OUTPUT);
+ pinMode(HEATER,OUTPUT);
+ pinMode(AUX,OUTPUT);
+ pinMode(HWV,OUTPUT);
+
+#if HWMODEL != ARDUINO_
+ pinMode(PIN_PB6,INPUT_PULLUP); // We use the internal oscillator, prevent this pin from floating
+ pinMode(PIN_PB7,INPUT_PULLUP); // We use the internal oscillator, prevent this pin from floating
+#endif
+
+#if HWMODEL > HWV_1_1
+ pinMode(LUMSENS,OUTPUT); // We use this ADC input to use the LED as a light sensor
+#endif
+
+ brightness(BRIGHTNESS); // The brightness routine will define output ports as required
+ initLCD(); // Now the brightness has been set, initialize the LCD
+
+ boolean resetpressed=false;
+ uint32_t tmr=millis();
+ while(millis()-tmr<3000) { // If in these 3 seconds...
+ if(!digitalRead(BUTTON)) // the button is pressed...
+ resetpressed=true; // record the reset request
+ }
+ lcd.clear();
+
+#ifndef SIMTEMP
+ // Read the sensor addresses
+ eeprom_read_block((void*)&sensors, (void*)128, sizeof(sensors));
+
+ // If the reset button is pressed and we already have sensor addresses, offer the user to reset the sensor addresses as well
+ if(resetpressed && sensors.epromchk==EPROMCHK) {
+ lcd.print(F("Hold button to"));
+ lcd.setCursor(0,1);
+ lcd.print(F("reset sensors"));
+ delay(5000);
+ }
+ lcd.clear();
+
+ // Button still pressed or sensor addresses never initialized?
+ if(!digitalRead(BUTTON) || sensors.epromchk!=EPROMCHK || (!sensors.temphwa[0][0] && sensors.useDS)) {
+ lcd.print(F("Sensors reset"));
+ delay(2000);
+ lcd.clear();
+ sensors.epromchk=EPROMCHK;
+ sensors.useDS=true;
+ sensors.thermistor=THERMISTOR;
+ sensors.thermbeta=THERMBETA;
+ uint8_t x=1;
+ if(analogRead(TEMP)<980 && analogRead(TEMP)>200) {
+ sensors.useDS=false;
+ lcd.print(F("1 analog"));
+ } else {
+#if HWMODEL > HWV_1_0
+ pinMode(OWPULLUP,OUTPUT);
+ digitalWrite(OWPULLUP,HIGH); // Switch on the extra pullup resistor for the digital sensors
+#endif
+ x=searchSensors();
+ lcd.print(x);
+ lcd.print(F(" digital"));
+ }
+ lcd.setCursor(0,1);
+ lcd.print(F("sensors found"));
+ if(!x) // If no temperature sensors have been found...
+ while(true); // continuation is pointless
+
+ eeprom_write_block((void*)&sensors, (void*)128, sizeof(sensors));
+ }
+#endif
+
+ if(sensors.useDS) { // Do we use Digital Sensors?
+#if HWMODEL > HWV_1_0
+ pinMode(OWPULLUP,OUTPUT);
+ digitalWrite(OWPULLUP,HIGH); // Switch on the extra pullup resistor for the digital sensors
+#endif
+ ds.reset(); // Reset 'em
+ ds.select(sensors.temphwa[0]); // Request first temperature conversion
+ ds.write(0x44,1); // Temperature conversion
+ }
+
+ // Prime the Voltage and thermistor median arrays
+ for (int i = 0; i < 5; i++) {
+ rawVoltages[i] = readvoltage(10);
+ thermists[i] = analogRead(TEMP);
+ delay(15 + i * 10); // Use a non constant delay to avoid any pulsing loads to sync with the sampling frequency
+ }
+
+ eeprom_read_block((void*)&rom, (void*)0, sizeof(2)); // Read the ROM header
+
+ if(resetpressed || rom.epromchk!=EPROMCHK) { // Reset key pressed or ROM not yet initialized?
+ if(rom.epromchk==EPROMCHK) {
+ lcd.print(F("Hold button to")); // Offer user to reset the ROM
+ lcd.setCursor(0,1);
+ lcd.print(F("Factory Reset"));
+ delay(5000);
+ }
+ lcd.clear();
+ if(!digitalRead(BUTTON)) { // button is pressed
+ rom.epromchk=EPROMCHK;
+ if(getvoltage()>180) { // If the voltage is above 18 volts
+ rom.vreq*=2; // Multiply all default voltages by 2
+ rom.vfloat*=2;
+ rom.voff*=2;
+ rom.vmul=true; // Set the system up for 24 Volts
+ }
+ eeprom_write_block((void*)&rom, (void*)0, sizeof(rom));
+ lcd.print(F("Reset OK"));
+ delay(1500);
+ lcd.clear();
+ }
+ }
+
+#ifndef USEDEFAULT
+ eeprom_read_block((void*)&rom, (void*)0, sizeof(rom)); // These are the configuration settings.
+ brightness(rom.brightness);
+#endif
+
+ // Prime the "history" of the temperature. Make sure we start with a downward trend
+ delay(1500);
+ lastTemperature=readtemp(0)+TRENDDELTA;
+
+ wdt_enable(WDTO_4S); // Enable watchdog, Use a 4 second interval
+}
+
+
+void initLCD() {
+ digitalWrite(LED,HIGH);
+#ifdef LCDADDR
+ lcd.begin();
+#else
+ lcd.begin(16, 2);
+#endif
+ lcd.createChar(1, Anchor);
+ lcd.createChar(2, Sailing);
+
+ delay(100);
+
+ for(int offset=0;offset<6;offset++) {
+ lcd.setCursor(offset,0);
+ lcd.print(" ");
+ lcd.write((uint8_t)2);
+ delay(400);
+ }
+ delay(800);
+ lcd.setCursor(6,1);
+ lcd.write((uint8_t)1);
+ delay(1000);
+
+ lcd.clear();
+ lcd.print(F(" Hot Water"));
+ lcd.setCursor(2,1);
+ lcd.print(F("Manager V" VERSION));
+
+ lcd.createChar(1, engine);
+ lcd.createChar(2, solar);
+ lcd.createChar(3, lightning);
+ lcd.createChar(4, legion);
+ lcd.createChar(5, down);
+ lcd.createChar(6, up);
+ lcd.createChar(7, Tmr);
+ digitalWrite(LED,LOW);
+}
+
+
+// Main menu string constants
+const char mode0[] PROGMEM = "Automatic";
+const char mode1[] PROGMEM = "Pause";
+const char mode2[] PROGMEM = "WarmUp";
+const char mode3[] PROGMEM = "Sanitize";
+const char mode4[] PROGMEM = "Thermostat";
+const char mode5[] PROGMEM = "AntiFreeze";
+const char mode6[] PROGMEM = "Heater On";
+const char mode7[] PROGMEM = "Pump on";
+const char mode8[] PROGMEM = "Off";
+const char mode9[] PROGMEM = "Setup";
+
+const char* const modes[] = {mode0,mode1,mode2,mode3,mode4,mode5,mode6,mode7,mode8,mode9,NULL};
+
+void modemenu() {
+ // This function is used to traverse through the main menu
+ if(modes[menusel]==NULL) // Reached the end?
+ menusel=0; // Go to the first one
+
+ lcd.print("> ");
+ pgmLcdPrint(modes[menusel]); // Print the menu option from PROGMEM
+ lcd.setCursor(0,1); // On the next line...
+ lcd.print(F("Hold to select")); // Print this
+ menusel++; // Advance to the next menu option
+}
+
+
+void loop() {
+ wdt_reset(); // pat the watchdog, at least every 4 seconds, otherwise the microcontroller will reset
+
+#if HWMODEL > HWV_1_1
+ // Use the LED to sense ambient light, so we can dim the LCD in the dark
+
+ if(rom.nightbright && rom.nightbright1) { // Only once per 2 seconds
+ lastlum=seconds();
+ boolean ledstate=digitalRead(LED); // Remember the current state of the LED
+ analogRead(LUMSENS); // Prime the ADC (we arrive here after sleep mode, so extra long read)
+ analogRead(LUMSENS); // Throw away the next read as well (just to be sure)
+ pinMode(LUMSENS,OUTPUT); // Set LUMSENS to an output again
+ digitalWrite(LUMSENS,HIGH); // Switch everything to high
+ digitalWrite(LED,HIGH); // Switch the LED to high
+ // See comments below why we manipulate the register manually
+ DDRE &= ~4; // Switch the LUMSENS pin to an INPUT, and since the output was HIGH, it is now an INPUT_PULLUP
+ uint16_t sens=analogRead(LUMSENS); // Read full voltage (should be close to 1023)
+ pinMode(LUMSENS,OUTPUT); // Switch back to output again
+ digitalWrite(LUMSENS,HIGH); // Reverse bias the LED
+ digitalWrite(LED,LOW); // Reverse bias the LED
+ // What we want to do:
+ // pinMode(LUMSENS,INPUT_PULLUP); // Switch it to input pullup
+ // But if pinMode first switches the output to LOW, and then switches to an input, we lost some charge from the LED.
+ // So we do it manually, FIRST swich to an INPUT, THEN get rid of the pullup resistor.
+ DDRE &= ~4; // Switch the LUMSENS pin to an INPUT, and since the output was HIGH, it is now an INPUT_PULLUP
+ PORTE &= ~4; // Switch off the PULLUP resistor.
+ delay(5); // Wait 5 milliseconds
+ sens-=analogRead(LUMSENS); // Read the difference
+ pinMode(LUMSENS,OUTPUT); // Switch LUMSENS back to an output again
+ digitalWrite(LUMSENS,LOW); // Make sure it is low again
+ digitalWrite(LED,ledstate); // Reset the led to whatever state it had
+
+ if(sens>1024) // Full voltage lower than what we measured on the LED?
+ sens=0; // Makes no sens...
+
+ int16_t br=rom.nightbright+(modMovAvg(&lum,sens,LUMSAMPLES)-rom.nightsensor);
+ if(br>rom.brightness) // If brightness is higher than what we allow
+ br=rom.brightness; // Limit it
+ if(br= rom.ttarget));
+ }
+ break;
+ case LEDM_HEATING: { // Are we currently heating?
+ digitalWrite(LED,(digitalRead(HEATER) || digitalRead(AUX)));
+ }
+ break;
+ case LEDM_HWVALVE: { // Is the hot water timer running?
+ digitalWrite(LED,hwv && hwv_timer);
+ }
+ break;
+ case LEDM_LEGIONELLA: { // Is the water unsafe?
+ digitalWrite(LED,sanitycheck());
+ }
+ break;
+ default: { // Is the button pressed?
+ digitalWrite(LED,!digitalRead(button.button));
+ }
+ }
+
+ // Deal with the LCD backlight
+ if(butt) { // Did we have a button press?
+ disptimer=seconds(); // Restart the display timeout timer
+ if(!lcdon) { // If the backlight was not already on, turn it on now
+ brightness(bright); // Set the configured brightness
+ lcdon=true; // Remember that the LCD backlight is on
+ butt=0; // This keypress is "used up" to switch the LCD backlight on.
+ }
+ }
+
+ if(butt) { // We still have the button press? (Could be "eaten up" by the LCD backlight timeout)
+ menuseltimer=seconds(); // Reset the menu timeout timer
+
+ if(butt==2) { // Long button press
+ if(menusel) { // Are we already in the menu?
+ if(menusel>=100) { // Are we in the setup menu?
+ menuedit=!menuedit; // Long press is either exit or entry of a setup function
+ lcd.clear();
+ // Show the associated menu option
+ printMenu(menusel-100,menuedit,rom.fahrenheit);
+
+ if(!menuedit && romdirty) { // We are not in edit mode but made the rom "dirty"?
+ if(freset)
+ rom.epromchk=0;
+ if(sreset)
+ sensors.epromchk=0;
+#ifndef SIMTEMP
+ if(swapTsens) { // If we need to swap the sensors, do it now...
+ for(uint8_t i=0;i<8;i++) {
+ uint8_t x=sensors.temphwa[0][i];
+ sensors.temphwa[0][i]=sensors.temphwa[1][i];
+ sensors.temphwa[1][i]=x;
+ }
+ swapTsens=false;
+ }
+#endif
+
+ if(reboot) // Only a reboot?
+ resetFunc(); // Don't write EEPROM, just reboot.
+
+ // Save the changed entries in the ROM
+ eeprom_write_block((void*)&rom, (void*)0, sizeof(rom));
+ eeprom_write_block((void*)&sensors, (void*)128, sizeof(sensors));
+ if(freset || sreset) // Reset rom or sensors?
+ resetFunc(); // Follow it with a reset
+ }
+
+ } else { // We are not in the setup menu
+ if(modes[menusel]==NULL) { // We reached the setup menu
+ menusel=99; // Select it
+ butt=1; // Simulate short press to enter it
+ } else { // It is a long press on a menu option
+ paused=false;
+ mode=menusel-1; // so we selected this one
+ menusel=0; // Exit the menu
+ lcd.clear();
+ }
+ }
+ } else { // Not yet in the menu
+ lcd.clear();
+ modemenu(); // So start it now
+ }
+ }
+ if(butt==1) { // Short press
+ lcd.clear();
+ // Are we editing a setup menu item?
+ if(menuedit) { // Are we in edit mode?
+ editItem(menusel-100, rom.vmul); // Edit the item
+ printMenu(menusel-100,menuedit,rom.fahrenheit);
+ } else { // Not in edit mode
+ if(menusel>=99) { // Are we in the setup menu?
+ nextMenuItem(); // Advance to the next menu item
+ } else { // Not in the setup menu
+ if(!menusel && rom.hwv_timer) { // Have we configured a hot water valve timer?
+ // Toggle the hot water valve timer
+ setHWV(!(hwv && hwv_timer>HWVBLEED),rom.hwv_timer*60);
+ } else { // No HWV...
+ modemenu(); // ...just go into the main menu
+ }
+ }
+ }
+ }
+ } else { // No button was pressed
+ if(menusel>=100 && menuedit && getPgmVal(&menu[menusel-100].code)==MENU_SHOW) {
+ lcd.setCursor(0,0);
+ printMenu(menusel-100,menuedit,rom.fahrenheit); // This menu option has no timeout
+
+ } else {
+ if(menusel && seconds()-menuseltimer>(MENUTIMEOUT)) {
+ menusel=0; // Menu timed out, get out of it
+ menuedit=false; // Exit edit mode
+ romdirty=false; // If we were in edit mode, discard the change
+ lcd.clear();
+ }
+ }
+ if(!menusel) { // If we are not in a menu...
+ processmodes(); // ... Process the mode
+ }
+ }
+
+ if(!menusel && !butt && !button.pressed && !hwv && !digitalRead(HEATER)) {
+ // We are not in a menu, no button is pressed, and we have no hot water valve timer going...
+ // Let's get some sleep!
+ // We are going to use the Watchdog timer for this.
+ // We will shut down everything else.
+ // The sleep will end when either the watchdog timer or an interrupt (button press) fires.
+
+ uint8_t wdt_prescale = 6; // Sleep for 1 second
+ uint8_t wdtcsr = bit(WDIE) | (wdt_prescale&7) | ((wdt_prescale&8)<<2);
+
+ wdt_disable(); // Disable the watchdog timer for now.
+
+ uint8_t adcsra=ADCSRA; // Store current state of ADCSRA
+ ADCSRA = 0; // disable the ADC
+
+ MCUSR = 0; // clear various "reset" flags
+ WDTCSR = bit (WDCE) | bit (WDE); // allow changes, disable reset
+ WDTCSR = wdtcsr; // set WDIE, and prescaler
+ wdt_reset(); // pat the dog
+
+ EICRA = _BV(ISC01); // configure INT0 to trigger on falling edge
+ EIMSK = _BV(INT0); // enable INT0, so we wake up immediately if the button is pressed
+
+ set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Power down everything
+ sleep_enable();
+ sei(); // ensure interrupts enabled so we can wake up again
+ sleep_cpu(); // go to sleep. Here we sleep
+
+ // Zzzzzzz
+
+ sleep_disable(); // We woke up, don't fall asleep again, there is work to do
+
+ ADCSRA=adcsra; // Restore ADCSRA
+
+ wdt_enable(WDTO_4S); // Re-enable the watch dog
+
+ secs++; // The timer stopped during sleep, make good for it with the one second we slept
+// _millis+=(16<rom.disptimeout) {
+ lcdon=false;
+ brightness(0); // Switch off the back light
+ }
+
+ // Change the value displayed on the LCD only once per second
+ if(!LCDvoltage || seconds()-vfreq>1) {
+ LCDvoltage=voltage;
+ vfreq=seconds();
+ }
+
+ lcd.setCursor(0,0);
+
+ // If the alternate temp sensor has a higher value than the tank sensor, show both of them alternately.
+ uint8_t src=0;
+ if(rom.pumpMode && readtemp(1)-readtemp(0)>rom.pumpdelta && (seconds() & 2)) {
+ lcd.print(F("Source"));
+ src=1;
+ } else {
+ lcd.print(F("Water "));
+ }
+
+ printTemperature(readtemp(src),1,rom.fahrenheit); // Display the temperature
+ if(tempdata[src].failures) // If we failed to receive valid data from the sensor...
+ lcd.write('?'); // ... indicate this with a question mark...
+ else // ... othersiwse...
+ lcd.write(' '); // ... clear any previous error
+
+ lcd.setCursor(0,1);
+ pgmLcdPrint(modes[mode]); // Print the current operation mode
+
+ lcd.setCursor(11,1);
+ lcd.print(((float)LCDvoltage)/10.0,1); // Display the voltage
+ lcd.print("V ");
+
+ // Update the temperature trend arrow
+ lcd.setCursor(13,0);
+ if(readtemp(0)-lastTemperature>=TRENDDELTA) {
+ lcd.write(6); // Trend is going up
+ lastTemperature=readtemp(0);
+ } else
+ if(lastTemperature-readtemp(0)>=TRENDDELTA) {
+ lcd.write(5); // Trend is going down
+ lastTemperature=readtemp(0);
+ }
+
+ lcd.setCursor(14,0);
+
+ if(hwv && hwv_timer) { // If the hot water valve is selected...
+ for(uint8_t i=0; i < 7 ;i++) { // build the character
+ if(i<6 && ((seconds()-HWVtmr)*7)/hwv_timer > i)
+ hwvchar[i] = 0b10001;
+ else
+ hwvchar[i] = 0b11111;
+ }
+ lcd.createChar(0, hwvchar); // create the character
+ lcd.setCursor(14,0); // needed after createChar
+ lcd.write((uint8_t)0); // Display the character
+ } else
+
+ if(sanitycheck())
+ lcd.write(4); // Display the legionella warning
+ else // Or...
+ lcd.write(' '); // ... clear it
+
+ lcd.setCursor(15,0);
+ if(!mode && digitalRead(ENGINE)) // AUtomatic mode and engine contact is on?
+ lcd.write(1); // Show the engine symbol
+ else
+ if(digitalRead(AUX)) // Is the auxilliary pump running?
+ lcd.write(3 - (int8_t) rom.pumpMode); // Show the respective symbol
+ else
+ if(paused) // If we are pausing...
+ lcd.write(7); // ... show it on the screen
+ else
+ if(digitalRead(HEATER)) // If the heating element is energized
+ lcd.write(3); // Show the symbol on the display
+ else // Or...
+ lcd.write(' '); // ... clear it when the heating element is de-energized.
+
+ if(hwv && seconds()-HWVtmr > hwv_timer) // If the HWV is enabled and expired...
+ setHWV(false,0); // ... switch it off
+
+ if(voltagerom.tmax) { // If Temp is higher than max...
+ heaterState(false); // Switch off the heating element
+ pumpState(LOW); // Switch off the auxilliary pump
+ return; // Nothing else needs to be done, we're finished
+ }
+
+ if(voltage=rom.vreq) { // Voltage reached the required value
+ if(!pauseTmr) { // Did we already start the countdown?
+ pauseTmr=seconds(); // If not, start it now
+ } else {
+ if(seconds()-pauseTmr>rom.pause*60L) { // Has the timer already expired?
+ paused=false; // Cancel pause mode
+ if(mode==1) // If the pause mode was manually selected...
+ mode=0; // ... reset it to automatic mode
+ } else { // Nope, we still need to pause
+ heaterState(false); // Make sure the water heater is off
+ // Do not return, maybe solar can still input some heat
+ }
+ }
+ }
+ }
+
+ // We've handled all hard limits, now look at the modes
+
+ if(mode==8) { // If mode is OFF...
+ heaterState(false); // - Shut down the water heater
+ pumpState(LOW); // - Shut down also the auxilliary pump
+ return; // - No further actions required.
+ }
+
+ if(mode==7) { // Is mode is PUMP
+ pumpState(HIGH); // Run the pump
+ return; // Do nothing else
+ }
+
+ // If we have an auxilliary pump,
+ if(rom.pumpMode) { // Do we have an auxilliary pump?
+ if(readtemp(1)-readtemp(0)>rom.pumpdelta) { // Is there a worthwile temperature difference between the source and hot water tank?
+ pumpState(HIGH); // Then start the pump
+ heaterState(false); // And disable the heating element
+ pumpTimer=seconds(); // Record the time
+ if(mode!=6) // Unless the mode is "heater on"...
+ return; // We are warming the boiler, as long as we can do that no electricity is needed, skip the rest.
+ } else { // Not enough temperature difference
+ if(seconds()-pumpTimer>rom.pumpafterrun) // Unless the "aterrun" timer is still running
+ pumpState(LOW); // Switch off the pump
+ }
+ }
+
+ if(mode==6) { // If program=ON...
+ heaterState(true); // ... just keep the heater on. Overtemp and pause is already dealt with above.
+ return; // Nothing else needs to be done
+ }
+
+ if(mode==2) { // If the program is in WarmUp mode...
+ if(readtemp(0)rom.ttarget) {
+ if(sanitycheck()) {
+ holdoff=2; // We are due to run a sanity cycle, so let's try to reach it with moderate conservatism
+ } else {
+ holdoff=5; // Sanity cycle is not due, so let's not try too hard to get the temperature up to the sanity level
+ }
+ }
+
+ if(readtemp(0)>rom.tsanity) // Did we reach the sanity temperature?
+ holdoff=10; // We just heat the water further but only if we are otherwise waisting available energy.
+
+ if(seconds()-restartTmr>holdoff*60L) // Now we need to see how long ago we reached (again) VREQ. Can we already start?
+ heaterState(true);
+
+ return;
+ }
+
+ // If we arrive here, the boiler is on. Do we want to keep it that way?
+
+ if(voltage2)
+ analogWrite(HEATER,((uint16_t)rom.relaypwm*255)/100);// Set the PWM to the desired percentage.
+
+ // If we want to change state, do so only after at least some time has passed since the last change
+ if((!state && seconds()-lastChange>rom.holdon) || (state && seconds()-lastChange>HOLD_OFF)) {
+ if(state) // If we switch the heater on...
+ pumpState(LOW); // Switch off the auxilliary pump
+ if(digitalRead(HEATER)!=state) { // Need to change the heater state?
+ lastChange=seconds();
+ delay(20);
+ digitalWrite(HEATER,state); // Switch the heater
+ if(rom.hwv_timer && !hwv && state) // If we have a HWV and it is not on, and we switch on the heater...
+ setHWV(true,HWVBLEED); // ... switch on the HWV to equalize the pressure
+ }
+ }
+}
+
+
+void pumpState(boolean state) {
+ digitalWrite(AUX,state);
+}
+
+
+void setHWV(bool state, uint16_t hwvtmr) {
+ if(state) { // We want to switch on the Hot Water Valve?
+ HWVtmr=seconds(); // Record the time
+ hwv_timer=hwvtmr; // Set the duration
+ }
+ hwv=state; // Register the new state
+ if(state) // We want to switch it on
+ analogWrite(HWV,((uint16_t)rom.hwv_pwm*255)/100); // Use PWM for this
+ else // Otherwise
+ digitalWrite(HWV,LOW); // Switch it off
+}
+
+// This routine will keep track whether there is a legionella chance
+boolean sanitycheck() {
+ static boolean sancounting=false;
+ static boolean keepalarm=false; // Prevent the alarm switching off after timer rollover
+ static uint32_t santotal=0;
+ static uint32_t sancount=0x80000000;
+
+ if(readtemp(0)>=rom.tsanity) { // The temperature in boiler is high enough to kill legionella, so clear all alarms.
+ santotal=0;
+ sancounting=false;
+ keepalarm=false;
+ } else {
+ if(readtemp(0)>rom.tnosan) {
+ if(!sancounting) {
+ sancounting=true;
+ sancount=seconds();
+ }
+ if(santotal+(seconds()-sancount)>((uint32_t)rom.tsandays)*60L*60L*24L) {
+ keepalarm=true;
+ }
+ } else {
+ if(sancounting) {
+ sancounting=false;
+ santotal+=(seconds()-sancount);
+ }
+ }
+ }
+ return keepalarm;
+}
+
+
+void brightness(uint8_t brightness) {
+ // Controlling the brightness of the LCD backlight could be done with a single PWM output, but then we couldn't use the sleep function of the processor anymore.
+ // We have enough IO ports anyway, so we use three outputs with different resistors with which we can make 8 different brightness values.
+
+ // Setup an array with the output ports in binary order
+ const uint8_t blports[]={BACKLIGHT_B0, BACKLIGHT_B1, BACKLIGHT_B2};
+
+ if(brightness)
+ bright=brightness; // Remember the new brightness
+ uint8_t inputmode=INPUT; // If a port is not used, set it as input
+ if(!brightness && rom.lcdglow) // but if the brightness is 0 and we selected "glow"....
+ inputmode=INPUT_PULLUP; // ...make it input_pullup to allow some leak current through the LCD backlight
+ for(uint8_t i=0; i<3; i++) { // Process all three bits
+ if(brightness & (1<180) { // Divide all configurable voltages by 2 if the configured voltage is above 18 volts
+ rom.vreq/=2;
+ rom.vfloat/=2;
+ rom.voff/=2;
+ }
+ }
+ lcd.print(F("Volt"));
+}
+
+void fptr_units() {
+ if(rom.fahrenheit)
+ lcd.print(F("Fahrenheit"));
+ else
+ lcd.print(F("Celsius"));
+}
+
+void fptr_ledmode() {
+ static const char lmod0[] PROGMEM = "Touch";
+ static const char lmod1[] PROGMEM = "Warm water";
+ static const char lmod2[] PROGMEM = "Heating up";
+ static const char lmod3[] PROGMEM = "HW Valve";
+ static const char lmod4[] PROGMEM = "Legionella";
+ static const char* const ledmods[] = {lmod0,lmod1,lmod2,lmod3,lmod4};
+
+ lcd.setCursor(4,1);
+ pgmLcdPrint(ledmods[rom.ledmode]);
+}
+
+void fptr_versions() {
+ lcd.print(F("SW " VERSION " HW " HWVER ));
+}
+
+#if HWMODEL != ARDUINO_
+
+void fptr_lumsens() {
+ lcd.setCursor(8,1);
+ lcd.print(lum.avg); // Show the current sensor output
+ lcd.print(" ");
+}
+
+void fptr_serialnr() {
+ char signature[10];
+ char base64str[17];
+
+ lcd.setCursor(0,1);
+
+ for(uint8_t i=0;i<10;i++)
+ signature[i]=boot_signature_byte_get(i+14);
+
+ base64_encode(base64str, signature, 10);
+ lcd.print(base64str);
+}
+
+#endif
+
+
+void printMenu(uint8_t item, boolean edit, boolean fahrenheit) {
+ uint8_t code = getPgmVal(&menu[item].code);
+ uint16_t value = getRomValue(code,item);
+
+ if(!edit)
+ lcd.write('>');
+
+ if(code==MENU_SHOW) {
+ if(edit)
+ lcd.print(F("Hold btn to exit"));
+ else
+ pgmLcdPrint(menu[item].txt);
+ lcd.setCursor(2,1);
+ } else {
+ pgmLcdPrint(menu[item].txt);
+ lcd.setCursor(0,1);
+ if(edit)
+ lcd.print("> ");
+ else
+ lcd.print(" ");
+
+ if(code & (MENU_8 | MENU_16)) {
+ if(code & MENU_FLOAT)
+ if(code & MENU_TEMP)
+ printTemperature(value,0,fahrenheit);
+ else
+ lcd.print((float) ((float)value/pow(10.0,(float)(code & MENU_FLOAT))), code & MENU_FLOAT);
+ else
+ if(code & MENU_SIGNED)
+ lcd.print((int)value);
+ else
+ lcd.print(value);
+ }
+ uint8_t i=pgm_read_byte(&menu[item].sfx) & 0x0F;
+ if(i)
+ pgmLcdPrint(suffixes[i-1]);
+
+ if(code & MENU_BOOLEAN)
+ if(value)
+ lcd.print("Yes");
+ else
+ lcd.print("No ");
+ }
+
+ // If the menu has a function pointer, process it now
+ lcd.setCursor(2,1);
+ void (*function)(void); // function buffer
+ function = (funcptr_t)pgm_read_ptr(&menu[item].funcptr);// get it from PROGMEM
+ function(); // Call the function
+}
+
+
+uint16_t getRomValue(uint8_t code, uint8_t item) {
+ if(code & (MENU_8 | MENU_BOOLEAN)) {
+ if(code & MENU_SIGNED)
+ return (uint16_t)((int16_t)*((int8_t *)pgm_read_word(&menu[item].varptr)));
+ else
+ return (uint16_t)*((uint8_t *)pgm_read_word(&menu[item].varptr));
+ }
+
+ if(code & MENU_16)
+ return (uint16_t)*((uint16_t *)pgm_read_word(&menu[item].varptr));
+}
+
+
+void editItem(uint8_t item, bool vmul) {
+ uint8_t code = getPgmVal(&menu[item].code);
+
+ if(code==MENU_SHOW)
+ return;
+
+ int16_t value = getRomValue(code,item);
+
+ int16_t step=getPgmVal(&menu[item].step);
+ int16_t max=getPgmVal(&menu[item].max);
+ int16_t min=getPgmVal(&menu[item].min);
+
+ romdirty=true; // Remember to save changes in EEPROM
+
+ if(code & MENU_VOLTS && vmul) { // If some voltage menu option is selected and we operate on a 24V system...
+ step*=2; max*=2; min*=2; // Multiply all voltage steps, minimums and maximums by two.
+ }
+
+ value+=step;
+ value-=value%step;
+ if(value>max || value1100 || t<-350)
+ tempdata[currsensor].failures++;
+ else {
+ tempdata[currsensor].temperature = t;
+ tempdata[currsensor].failures=0;
+ }
+ } else {
+ tempdata[currsensor].failures++;
+ }
+ }
+
+ // Setup the sensors for measuring the temperature, so we have new data ready at the next reading attempt
+ ds.reset();
+ currsensor=1-currsensor;
+
+ ds.select(sensors.temphwa[currsensor]);
+ ds.write(0x44,1); // Temperature conversion
+ } else {
+ float ratio = ((float)medianp(thermists))/1024.0;
+ float R = TEMPR * ratio / (1.0-ratio); // Calculate thermistor resistor value
+ tempdata[0].temperature = modMovAvg(&tempdata[0].mmaTemp,(int16_t)round(10.0* ((1.0 / ((log(R/sensors.thermistor) / sensors.thermbeta) + (1.0 / 298.15)))-273.15)),TEMPSAMPLES);
+ }
+
+ if(tempdata[sensor].failures>10)
+ // Too many failures, start returning a "safe" but unusual value.
+ tempdata[sensor].temperature = tempdata[sensor].fallback;
+
+ return tempdata[sensor].temperature;
+}
+
+
+uint8_t searchSensors() {
+ uint8_t owaddr[8];
+ uint8_t sensor=0;
+
+ sensors.temphwa[0][0]=0;
+ sensors.temphwa[1][0]=0;
+
+ ds.reset();
+ while(ds.search(owaddr) && sensor<2) { // We have found a one-wire device. Is it a temperature sensor and is the data valid?
+ if(owaddr[0]==0x28 && OneWire::crc8( owaddr, 7) == owaddr[7]) {
+ // Seems to be ok. So copy this hardware address
+ for(uint8_t i=0;i<8;i++)
+ sensors.temphwa[sensor][i]=owaddr[i];
+ // Now we have it, configure the sensor
+ ds.reset();
+ ds.select(sensors.temphwa[sensor]);
+ ds.write(0x4E); // Write scratchpad command
+ ds.write(0); // TL data
+ ds.write(0); // TH data
+ ds.write(0x7F); // Configuration Register (resolution) 7F=12bits 5F=11bits 3F=10bits 1F=9bits
+ ds.reset(); // This "reset" sequence is mandatory, it allows the DS18B20 to understand the copy scratchpad to EEPROM command
+ ds.select(sensors.temphwa[sensor]);
+ ds.write(0x48); // Copy Scratchpad command
+ sensor++;
+ ds.reset();
+ }
+ }
+ return sensor;
+}
+
+
+int16_t getPgmVal(const int16_t *ptr) {
+ return pgm_read_word(ptr);
+}
+
+uint16_t getPgmVal(const uint16_t *ptr) {
+ return pgm_read_word(ptr);
+}
+
+char getPgmVal(const char *ptr) {
+ return pgm_read_byte(ptr);
+}
+
+byte getPgmVal(const byte *ptr) {
+ return pgm_read_byte(ptr);
+}
+
+// Prints a string from flash memory
+const char* pgmLcdPrint(const char *txt) {
+ char c=pgm_read_byte_near(txt);
+ while(c) {
+ lcd.write(c);
+ txt++;
+ c=pgm_read_byte_near(txt);
+ }
+ txt++;
+ return txt;
+}
+
+
+void printTemperature(int16_t value,uint8_t precision, boolean fahrenheit) {
+ if(fahrenheit) {
+ lcd.print(((float)value*0.18)+32.0,precision);
+ lcd.print("\xDF""F");
+ if(precision && (float)value*0.18+32.0<100)
+ lcd.write(' ');
+ } else {
+ lcd.print((float)value/10.0,precision);
+ lcd.print("\xDF""C");
+ if(precision) {
+ if(value<100 && value>0)
+ lcd.write(' ');
+ if(value>-100)
+ lcd.write(' ');
+ }
+ }
+}
+
+
+uint32_t seconds() {
+ static uint32_t prevmillis=0;
+
+ uint32_t dsecs=(millis()-prevmillis)/1000L;
+ if(dsecs) {
+ secs+=dsecs;
+ prevmillis+=dsecs*1000L;
+ }
+ return secs;
+}
+
+
+// This function handles the button functionality. Button presses are separated into long, short and double clicks presses.
+int chkbutton(struct button_t* button) {
+ if(digitalRead(button->button)==LOW) { // button pressed
+ if(button->pressed==0)
+ button->pressed=millis();
+ if(millis()-button->pressed>=LONGPRESS) {
+ if(!button->longpressed) {
+ button->longpressed=true;
+ return 2;
+ }
+ }
+ return 0;
+ } else { // button released
+ if(button->longpressed) {
+ button->longpressed=false;
+ button->pressed=0;
+ }
+ if(button->pressed==0)
+ return 0;
+ unsigned long pressed=millis()-button->pressed;
+ button->pressed=0;
+#ifdef SHORTPRESS
+ if(pressedsamplessamples++; // This is going to be an additional sample
+ else
+ mma->sum-=mma->avg; // Max amount of samples reached, substract average to make room for new value
+ mma->sum+=val;
+ mma->avg=(int16_t)((mma->sum+(mma->samples>>1))/mma->samples);
+ return mma->avg;
+}
+
+
+// ******** Routine to find the median in an array of 5 values *********
+
+// We use this to reject voltage spikes and erroneous temperature readings, rather than averaging them.
+
+// Trick using XOR to swap two variables
+#define swap(a,b) a ^= b; b ^= a; a ^= b;
+#define sort(a,b) if(a>b){ swap(a,b); }
+
+uint16_t median(uint16_t a, uint16_t b, uint16_t c, uint16_t d, uint16_t e) {
+ sort(a, b);
+ sort(d, e);
+ sort(a, c);
+ sort(b, c);
+ sort(a, d);
+ sort(c, d);
+ sort(b, e);
+ sort(b, c);
+ return c;
+}
+
+uint16_t medianp(uint16_t values[5]) {
+ return median(values[0], values[1], values[2], values[3], values[4]);
+}
+
+
+#if HWMODEL != ARDUINO_
+// ********* These routine are necessary to represent the serial number in Base64 ************
+// In the commercial version we like to keep track of serial numbers.
+// In the Arduino versions we don't need that.
+
+// Routines to encode to base64
+
+unsigned char binary_to_base64(unsigned char v) {
+ if(v < 26) return v + 'A'; // Capital letters - 'A' is ascii 65 and base64 0
+ if(v < 52) return v + 71; // Lowercase letters - 'a' is ascii 97 and base64 26
+ if(v < 62) return v - 4; // Digits - '0' is ascii 48 and base64 52
+ if(v == 62) return '+'; // Special case for value 62
+ if(v == 63) return '/'; // Special case for value 63
+ return 64;
+}
+
+void a3_to_a4(uint8_t *a4, uint8_t *a3) {
+ a4[0] = (a3[0] & 0xfc) >> 2;
+ a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
+ a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
+ a4[3] = (a3[2] & 0x3f);
+}
+
+int8_t base64_encode(char *output, char *input, int8_t inputLen) {
+ int8_t i = 0, j = 0;
+ int8_t encLen = 0;
+ uint8_t a3[3];
+ uint8_t a4[4];
+
+ while(inputLen--) {
+ a3[i++] = *(input++);
+ if(i == 3) {
+ a3_to_a4(a4, a3);
+
+ for(i = 0; i < 4; i++)
+ output[encLen++] = binary_to_base64(a4[i]);
+
+ i = 0;
+ }
+ }
+
+ if(i) {
+ for(j = i; j < 3; j++)
+ a3[j] = '\0';
+
+ a3_to_a4(a4, a3);
+
+ for(j = 0; j < i + 1; j++)
+ output[encLen++] = binary_to_base64(a4[j]);
+
+ while((i++ < 3))
+ output[encLen++] = '=';
+ }
+ output[encLen] = '\0';
+ return encLen;
+}
+#endif
diff --git a/HotWaterManager_Arduino.kicad_sch b/HotWaterManager_Arduino.kicad_sch
new file mode 100644
index 0000000..162c614
--- /dev/null
+++ b/HotWaterManager_Arduino.kicad_sch
@@ -0,0 +1,5478 @@
+(kicad_sch
+ (version 20231120)
+ (generator "eeschema")
+ (generator_version "8.0")
+ (uuid "2cebea01-a9ab-4da4-addb-e9c778a0107c")
+ (paper "A5")
+ (title_block
+ (title "HotWaterManager_Arduino")
+ (date "2025-03-029")
+ (rev "1.1")
+ (company "TheFloatingLab LLC")
+ )
+ (lib_symbols
+ (symbol "BoilerControlModule-rescue:CP_Small-Device"
+ (pin_numbers hide)
+ (pin_names
+ (offset 0.254) hide)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "C"
+ (at 0.254 1.778 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "Device_CP_Small"
+ (at 0.254 -2.032 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_fp_filters" "CP_*"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "CP_Small-Device_0_1"
+ (rectangle
+ (start -1.524 -0.3048)
+ (end 1.524 -0.6858)
+ (stroke
+ (width 0)
+ (type solid)
+ )
+ (fill
+ (type outline)
+ )
+ )
+ (rectangle
+ (start -1.524 0.6858)
+ (end 1.524 0.3048)
+ (stroke
+ (width 0)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -1.27 1.524) (xy -0.762 1.524)
+ )
+ (stroke
+ (width 0)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -1.016 1.27) (xy -1.016 1.778)
+ )
+ (stroke
+ (width 0)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ )
+ (symbol "CP_Small-Device_1_1"
+ (pin passive line
+ (at 0 2.54 270)
+ (length 1.8542)
+ (name "~"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 0 -2.54 90)
+ (length 1.8542)
+ (name "~"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "BoilerControlModule-rescue:D_Small_ALT-Device"
+ (pin_numbers hide)
+ (pin_names
+ (offset 0.254) hide)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "D"
+ (at -1.27 2.032 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "Device_D_Small_ALT"
+ (at -3.81 -2.032 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 0 0 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_fp_filters" "TO-???* *_Diode_* *SingleDiode* D_*"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "D_Small_ALT-Device_0_1"
+ (polyline
+ (pts
+ (xy -0.762 -1.016) (xy -0.762 1.016)
+ )
+ (stroke
+ (width 0)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -0.762 0) (xy 0.762 0)
+ )
+ (stroke
+ (width 0)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 0.762 -1.016) (xy -0.762 0) (xy 0.762 1.016) (xy 0.762 -1.016)
+ )
+ (stroke
+ (width 0)
+ (type solid)
+ )
+ (fill
+ (type outline)
+ )
+ )
+ )
+ (symbol "D_Small_ALT-Device_1_1"
+ (pin passive line
+ (at -2.54 0 0)
+ (length 1.778)
+ (name "K"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 2.54 0 180)
+ (length 1.778)
+ (name "A"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "BoilerControlModule-rescue:LCD1602A-New_Library"
+ (pin_names
+ (offset 1.016)
+ )
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "M"
+ (at 0 -2.54 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "New_Library_LCD1602A"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 0 -2.54 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 -2.54 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "LCD1602A-New_Library_0_1"
+ (rectangle
+ (start -24.13 3.81)
+ (end 19.05 -8.89)
+ (stroke
+ (width 0)
+ (type solid)
+ )
+ (fill
+ (type background)
+ )
+ )
+ )
+ (symbol "LCD1602A-New_Library_1_1"
+ (pin power_in line
+ (at -21.59 -11.43 90)
+ (length 2.54)
+ (name "GND"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -1.27 -11.43 90)
+ (length 2.54)
+ (name "D3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "10"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 1.27 -11.43 90)
+ (length 2.54)
+ (name "D4"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "11"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 3.81 -11.43 90)
+ (length 2.54)
+ (name "D5"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "12"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 6.35 -11.43 90)
+ (length 2.54)
+ (name "D6"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "13"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 8.89 -11.43 90)
+ (length 2.54)
+ (name "D7"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "14"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at 13.97 -11.43 90)
+ (length 2.54)
+ (name "Backlight_+"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "15"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at 16.51 -11.43 90)
+ (length 2.54)
+ (name "Backlight_-"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "16"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_in line
+ (at -21.59 6.35 270)
+ (length 2.54)
+ (name "VCC"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at -26.67 -2.54 0)
+ (length 2.54)
+ (name "Contrast"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at -19.05 -11.43 90)
+ (length 2.54)
+ (name "RS"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "4"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at -16.51 -11.43 90)
+ (length 2.54)
+ (name "RW"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "5"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at -13.97 -11.43 90)
+ (length 2.54)
+ (name "EN"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "6"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -8.89 -11.43 90)
+ (length 2.54)
+ (name "D0"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "7"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -6.35 -11.43 90)
+ (length 2.54)
+ (name "D1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "8"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -3.81 -11.43 90)
+ (length 2.54)
+ (name "D2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "9"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "Device:C"
+ (pin_numbers hide)
+ (pin_names
+ (offset 0.254)
+ )
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "C"
+ (at 0.635 2.54 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "C"
+ (at 0.635 -2.54 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 0.9652 -3.81 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Unpolarized capacitor"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "cap capacitor"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_fp_filters" "C_*"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "C_0_1"
+ (polyline
+ (pts
+ (xy -2.032 -0.762) (xy 2.032 -0.762)
+ )
+ (stroke
+ (width 0.508)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -2.032 0.762) (xy 2.032 0.762)
+ )
+ (stroke
+ (width 0.508)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ )
+ (symbol "C_1_1"
+ (pin passive line
+ (at 0 3.81 270)
+ (length 2.794)
+ (name "~"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 0 -3.81 90)
+ (length 2.794)
+ (name "~"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "Device:R"
+ (pin_numbers hide)
+ (pin_names
+ (offset 0)
+ )
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "R"
+ (at 2.032 0 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "R"
+ (at 0 0 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at -1.778 0 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Resistor"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "R res resistor"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_fp_filters" "R_*"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "R_0_1"
+ (rectangle
+ (start -1.016 -2.54)
+ (end 1.016 2.54)
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ )
+ (symbol "R_1_1"
+ (pin passive line
+ (at 0 3.81 270)
+ (length 1.27)
+ (name "~"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 0 -3.81 90)
+ (length 1.27)
+ (name "~"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "MCU_Module:Arduino_UNO_R3"
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "A"
+ (at -10.16 23.495 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left bottom)
+ )
+ )
+ (property "Value" "Arduino_UNO_R3"
+ (at 5.08 -26.67 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ )
+ )
+ (property "Footprint" "Module:Arduino_UNO_R3"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ (italic yes)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "https://www.arduino.cc/en/Main/arduinoBoardUno"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Arduino UNO Microcontroller Module, release 3"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "Arduino UNO R3 Microcontroller Module Atmel AVR USB"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_fp_filters" "Arduino*UNO*R3*"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "Arduino_UNO_R3_0_1"
+ (rectangle
+ (start -10.16 22.86)
+ (end 10.16 -25.4)
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type background)
+ )
+ )
+ )
+ (symbol "Arduino_UNO_R3_1_1"
+ (pin no_connect line
+ (at -10.16 -20.32 0)
+ (length 2.54) hide
+ (name "NC"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 12.7 -2.54 180)
+ (length 2.54)
+ (name "A1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "10"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 12.7 -5.08 180)
+ (length 2.54)
+ (name "A2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "11"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 12.7 -7.62 180)
+ (length 2.54)
+ (name "A3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "12"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 12.7 -10.16 180)
+ (length 2.54)
+ (name "SDA/A4"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "13"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 12.7 -12.7 180)
+ (length 2.54)
+ (name "SCL/A5"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "14"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 15.24 0)
+ (length 2.54)
+ (name "D0/RX"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "15"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 12.7 0)
+ (length 2.54)
+ (name "D1/TX"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "16"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 10.16 0)
+ (length 2.54)
+ (name "D2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "17"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 7.62 0)
+ (length 2.54)
+ (name "D3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "18"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 5.08 0)
+ (length 2.54)
+ (name "D4"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "19"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin output line
+ (at 12.7 10.16 180)
+ (length 2.54)
+ (name "IOREF"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 2.54 0)
+ (length 2.54)
+ (name "D5"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "20"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 0 0)
+ (length 2.54)
+ (name "D6"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "21"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 -2.54 0)
+ (length 2.54)
+ (name "D7"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "22"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 -5.08 0)
+ (length 2.54)
+ (name "D8"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "23"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 -7.62 0)
+ (length 2.54)
+ (name "D9"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "24"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 -10.16 0)
+ (length 2.54)
+ (name "D10"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "25"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 -12.7 0)
+ (length 2.54)
+ (name "D11"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "26"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 -15.24 0)
+ (length 2.54)
+ (name "D12"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "27"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 -17.78 0)
+ (length 2.54)
+ (name "D13"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "28"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_in line
+ (at -2.54 -27.94 90)
+ (length 2.54)
+ (name "GND"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "29"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at 12.7 15.24 180)
+ (length 2.54)
+ (name "~{RESET}"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at 12.7 5.08 180)
+ (length 2.54)
+ (name "AREF"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "30"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 12.7 -17.78 180)
+ (length 2.54)
+ (name "SDA/A4"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "31"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 12.7 -20.32 180)
+ (length 2.54)
+ (name "SCL/A5"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "32"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_out line
+ (at 2.54 25.4 270)
+ (length 2.54)
+ (name "3V3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "4"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_out line
+ (at 5.08 25.4 270)
+ (length 2.54)
+ (name "+5V"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "5"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_in line
+ (at 0 -27.94 90)
+ (length 2.54)
+ (name "GND"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "6"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_in line
+ (at 2.54 -27.94 90)
+ (length 2.54)
+ (name "GND"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "7"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_in line
+ (at -2.54 25.4 270)
+ (length 2.54)
+ (name "VIN"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "8"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 12.7 0 180)
+ (length 2.54)
+ (name "A0"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "9"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "Regulator_Linear:L78L05_TO92"
+ (pin_names
+ (offset 0.254)
+ )
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "U"
+ (at -3.81 3.175 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "L78L05_TO92"
+ (at 0 3.175 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline"
+ (at 0 5.715 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ (italic yes)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "http://www.st.com/content/ccc/resource/technical/document/datasheet/15/55/e5/aa/23/5b/43/fd/CD00000446.pdf/files/CD00000446.pdf/jcr:content/translations/en.CD00000446.pdf"
+ (at 0 -1.27 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Positive 100mA 30V Linear Regulator, Fixed Output 5V, TO-92"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "Voltage Regulator 100mA Positive"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_fp_filters" "TO?92*"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "L78L05_TO92_0_1"
+ (rectangle
+ (start -5.08 -5.08)
+ (end 5.08 1.905)
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type background)
+ )
+ )
+ )
+ (symbol "L78L05_TO92_1_1"
+ (pin power_out line
+ (at 7.62 0 180)
+ (length 2.54)
+ (name "VO"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_in line
+ (at 0 -7.62 90)
+ (length 2.54)
+ (name "GND"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_in line
+ (at -7.62 0 0)
+ (length 2.54)
+ (name "VI"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "Switch:SW_Push"
+ (pin_numbers hide)
+ (pin_names
+ (offset 1.016) hide)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "SW"
+ (at 1.27 2.54 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "SW_Push"
+ (at 0 -1.524 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 0 5.08 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 0 5.08 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Push button switch, generic, two pins"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "switch normally-open pushbutton push-button"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "SW_Push_0_1"
+ (circle
+ (center -2.032 0)
+ (radius 0.508)
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 0 1.27) (xy 0 3.048)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 2.54 1.27) (xy -2.54 1.27)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (circle
+ (center 2.032 0)
+ (radius 0.508)
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (pin passive line
+ (at -5.08 0 0)
+ (length 2.54)
+ (name "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 5.08 0 180)
+ (length 2.54)
+ (name "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "Transistor_BJT:BC547"
+ (pin_names
+ (offset 0) hide)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "Q"
+ (at 5.08 1.905 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "BC547"
+ (at 5.08 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline"
+ (at 5.08 -1.905 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ (italic yes)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "https://www.onsemi.com/pub/Collateral/BC550-D.pdf"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Description" "0.1A Ic, 45V Vce, Small Signal NPN Transistor, TO-92"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "NPN Transistor"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_fp_filters" "TO?92*"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "BC547_0_1"
+ (polyline
+ (pts
+ (xy 0 0) (xy 0.635 0)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 0.635 0.635) (xy 2.54 2.54)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 0.635 -0.635) (xy 2.54 -2.54) (xy 2.54 -2.54)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 0.635 1.905) (xy 0.635 -1.905) (xy 0.635 -1.905)
+ )
+ (stroke
+ (width 0.508)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 1.27 -1.778) (xy 1.778 -1.27) (xy 2.286 -2.286) (xy 1.27 -1.778) (xy 1.27 -1.778)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type outline)
+ )
+ )
+ (circle
+ (center 1.27 0)
+ (radius 2.8194)
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ )
+ (symbol "BC547_1_1"
+ (pin passive line
+ (at 2.54 5.08 270)
+ (length 2.54)
+ (name "C"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at -5.08 0 0)
+ (length 5.08)
+ (name "B"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 2.54 -5.08 90)
+ (length 2.54)
+ (name "E"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ (junction
+ (at 165.1 68.58)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "09ae8a03-2b1e-4c78-a4eb-d462e3235ea6")
+ )
+ (junction
+ (at 165.1 22.86)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "0f05e17f-90cc-4817-bcec-d804ab42f754")
+ )
+ (junction
+ (at 48.26 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "17b1a21d-e93e-4d94-83f0-2eb3e6c07df7")
+ )
+ (junction
+ (at 62.23 22.86)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "181a5f0d-7037-4036-9ebe-fa63bd05d79d")
+ )
+ (junction
+ (at 41.91 40.64)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "1d9c7ab3-c43e-4911-b985-0d1f7c301da6")
+ )
+ (junction
+ (at 41.91 62.23)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "21e48251-b507-455d-9194-bb4bfa79c3a6")
+ )
+ (junction
+ (at 77.47 27.94)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "24819108-ed87-4bf1-8c89-1261fb40f3c8")
+ )
+ (junction
+ (at 41.91 27.94)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "29f1d678-f873-490e-adcc-0ff7760ebb39")
+ )
+ (junction
+ (at 168.91 22.86)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "30b7dbd8-62e3-48f2-935e-68b3cf7cbc08")
+ )
+ (junction
+ (at 109.22 88.9)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "453de089-c522-4121-a0d6-c11b8b9d3c94")
+ )
+ (junction
+ (at 123.19 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "577c0ace-4c73-42ee-b439-1ceabfadf290")
+ )
+ (junction
+ (at 59.69 27.94)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "691ee65d-5f40-49c5-9f31-7db2d761d192")
+ )
+ (junction
+ (at 93.98 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "694be018-90c2-4b5e-be9d-fdc931fff995")
+ )
+ (junction
+ (at 115.57 88.9)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "72d030b5-e57d-453c-9495-8686a89e1a31")
+ )
+ (junction
+ (at 57.15 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "72fe39e5-ecff-4a9a-bf0f-a1c6cfa4404c")
+ )
+ (junction
+ (at 161.29 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "7836f5c5-8772-44c6-9b1c-da4cc0b84ded")
+ )
+ (junction
+ (at 172.72 72.39)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "7a0aff61-d421-4528-a068-706d74a52cd9")
+ )
+ (junction
+ (at 62.23 59.69)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "7c7e3375-070c-45bf-9dba-a65e4f0f4a69")
+ )
+ (junction
+ (at 62.23 72.39)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "993d5015-af55-435d-84de-2acd681d6b2c")
+ )
+ (junction
+ (at 152.4 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "9a11ec3d-0c67-459a-b59c-8261b314b0c6")
+ )
+ (junction
+ (at 77.47 57.15)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "9f6dbb86-7b84-4eb2-9452-480d874840c5")
+ )
+ (junction
+ (at 96.52 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "b52abf9e-e403-42e5-bcde-ef3fd7dd83ed")
+ )
+ (junction
+ (at 48.26 62.23)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "b6df8e25-0525-490d-8370-9f57b627c10d")
+ )
+ (junction
+ (at 123.19 46.99)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "c42d6620-c7f3-482c-aef9-2957c04db7b4")
+ )
+ (junction
+ (at 62.23 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "c80f75b8-63b3-46d2-ae14-f44bfbd870c4")
+ )
+ (junction
+ (at 50.8 40.64)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "d3107d64-7e36-4922-8558-2b534956dbc2")
+ )
+ (junction
+ (at 91.44 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "d46a4cf8-72e0-430c-b9f3-f756914d9c5d")
+ )
+ (junction
+ (at 142.24 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "dd97161a-e191-400b-9cdc-d968854cee48")
+ )
+ (junction
+ (at 116.84 46.99)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "eda6630f-267c-40ca-8e27-364ef95bc646")
+ )
+ (junction
+ (at 88.9 27.94)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "f3c40699-6ac4-4323-9fed-3670f160ed9c")
+ )
+ (junction
+ (at 168.91 64.77)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "f760b1d1-04c3-4cfb-9f0d-6a5abe10e49c")
+ )
+ (wire
+ (pts
+ (xy 148.59 45.72) (xy 148.59 54.61)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "025ece39-b111-45a4-a678-d23e88b25bec")
+ )
+ (wire
+ (pts
+ (xy 62.23 22.86) (xy 165.1 22.86)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "04bc6eaa-3c52-4f3e-b42f-d482cf186695")
+ )
+ (wire
+ (pts
+ (xy 118.11 81.28) (xy 125.73 81.28)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "063a02c3-dd48-4f00-b091-ad22c349cace")
+ )
+ (wire
+ (pts
+ (xy 106.68 57.15) (xy 151.13 57.15)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "0d36e047-9a7a-4d49-803d-497b8ff16a62")
+ )
+ (wire
+ (pts
+ (xy 123.19 46.99) (xy 123.19 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "0e1d5497-0197-4a65-8c92-0c9b915345a6")
+ )
+ (wire
+ (pts
+ (xy 168.91 52.07) (xy 168.91 64.77)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "1128754c-fcca-4e91-8df0-3d2865f72b6b")
+ )
+ (wire
+ (pts
+ (xy 172.72 22.86) (xy 172.72 46.99)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "14a7bca7-1b29-4ac0-8ecb-7841c3623ab7")
+ )
+ (wire
+ (pts
+ (xy 168.91 22.86) (xy 168.91 46.99)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "1526753e-5bc4-42e1-b5cb-4d0ddeea2db2")
+ )
+ (wire
+ (pts
+ (xy 116.84 44.45) (xy 116.84 46.99)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "15ea865f-a39a-4b75-b6fe-0fdb4b239d3b")
+ )
+ (wire
+ (pts
+ (xy 77.47 53.34) (xy 77.47 57.15)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "1678e147-f5ee-4506-8c67-2fb9e986413e")
+ )
+ (wire
+ (pts
+ (xy 120.65 49.53) (xy 106.68 49.53)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "1726c90b-5ed5-48ca-b3c3-dbca7ae1bd6d")
+ )
+ (wire
+ (pts
+ (xy 152.4 68.58) (xy 152.4 69.85)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "18b8d5d2-ab00-4b86-9a9e-d3939679ea77")
+ )
+ (wire
+ (pts
+ (xy 165.1 22.86) (xy 168.91 22.86)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "1ab5de2e-f31f-4316-951a-b7b370d2f4ab")
+ )
+ (wire
+ (pts
+ (xy 158.75 88.9) (xy 158.75 45.72)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "1b2ede75-5539-45ae-93dc-828538d840de")
+ )
+ (wire
+ (pts
+ (xy 96.52 93.98) (xy 123.19 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "1c9567c9-565c-4932-a341-c19735501826")
+ )
+ (wire
+ (pts
+ (xy 80.01 64.77) (xy 81.28 64.77)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "224d6337-b3db-40ff-9833-8a35d85005e7")
+ )
+ (wire
+ (pts
+ (xy 146.05 45.72) (xy 146.05 52.07)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "26d11170-94f2-4383-a2c6-a1f6be8b6b00")
+ )
+ (wire
+ (pts
+ (xy 123.19 46.99) (xy 123.19 45.72)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "29b7600c-1b26-4328-8f7c-24c3f4c05a62")
+ )
+ (wire
+ (pts
+ (xy 38.1 62.23) (xy 41.91 62.23)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "2b43d5a7-1fed-4a44-83ef-14335b9f3e04")
+ )
+ (wire
+ (pts
+ (xy 59.69 40.64) (xy 50.8 40.64)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "2bb0dd65-9821-41b3-b516-d9e75f9dfd11")
+ )
+ (wire
+ (pts
+ (xy 91.44 93.98) (xy 93.98 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "2c692142-363f-43a4-a240-424601888a05")
+ )
+ (wire
+ (pts
+ (xy 165.1 22.86) (xy 165.1 46.99)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "2fbf418b-f05f-44fc-83b6-9286fb915ec0")
+ )
+ (wire
+ (pts
+ (xy 88.9 27.94) (xy 123.19 27.94)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "33b96955-8910-4d58-a3cf-df26e6f29d2c")
+ )
+ (wire
+ (pts
+ (xy 62.23 93.98) (xy 91.44 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "34623ca4-828f-4084-ad68-7d8bf45b632f")
+ )
+ (wire
+ (pts
+ (xy 80.01 91.44) (xy 125.73 91.44)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "347ef86b-000d-447a-8852-fbf1a090ccd3")
+ )
+ (wire
+ (pts
+ (xy 106.68 54.61) (xy 148.59 54.61)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "35641f40-836a-4ac0-abb0-2253acab7260")
+ )
+ (wire
+ (pts
+ (xy 41.91 40.64) (xy 50.8 40.64)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "3626e2ec-ac8a-426a-8c20-2b63982edc70")
+ )
+ (wire
+ (pts
+ (xy 106.68 59.69) (xy 153.67 59.69)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "3986772d-2d37-4d40-844e-d69d33d80a8b")
+ )
+ (wire
+ (pts
+ (xy 128.27 45.72) (xy 128.27 46.99)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "3a55f7d2-6781-43ec-815a-c6f550d7584f")
+ )
+ (wire
+ (pts
+ (xy 172.72 52.07) (xy 172.72 72.39)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "3af7f68c-2559-4358-94db-0d305e14fcb7")
+ )
+ (wire
+ (pts
+ (xy 172.72 86.36) (xy 172.72 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "3c255367-f3f2-43e4-b681-2c38c58a7e28")
+ )
+ (wire
+ (pts
+ (xy 74.93 74.93) (xy 74.93 67.31)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "3edb4633-e43d-4ba7-ae7e-b422d4e2c58d")
+ )
+ (wire
+ (pts
+ (xy 109.22 72.39) (xy 109.22 74.93)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "3f99100b-e625-4d22-8c2f-f28dc4daf951")
+ )
+ (wire
+ (pts
+ (xy 41.91 22.86) (xy 62.23 22.86)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "430ea02c-e132-4369-a543-4edf1b03a796")
+ )
+ (wire
+ (pts
+ (xy 48.26 93.98) (xy 57.15 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "44bb79aa-f082-47cd-92fb-4311efb8a432")
+ )
+ (wire
+ (pts
+ (xy 88.9 31.75) (xy 88.9 27.94)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "45fb80b7-a3c5-40ba-b4cd-76befcfc79eb")
+ )
+ (wire
+ (pts
+ (xy 133.35 81.28) (xy 134.62 81.28)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "4887cc0a-5c32-4aca-a163-ebdecbd86f23")
+ )
+ (wire
+ (pts
+ (xy 48.26 82.55) (xy 48.26 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "4958e3bf-682c-463b-b4ea-e092ffa86f55")
+ )
+ (wire
+ (pts
+ (xy 48.26 62.23) (xy 81.28 62.23)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "49a57af4-dc46-4389-b047-0d74f019ae2e")
+ )
+ (wire
+ (pts
+ (xy 41.91 27.94) (xy 41.91 22.86)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "4ce448b7-0fc9-40e5-9a1f-674ac83b253e")
+ )
+ (wire
+ (pts
+ (xy 59.69 31.75) (xy 59.69 27.94)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "4dd49c44-9f19-423f-9d12-8709b8277b66")
+ )
+ (wire
+ (pts
+ (xy 48.26 53.34) (xy 48.26 62.23)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "4e1c4e41-c22a-4d07-bb0d-e615278f5802")
+ )
+ (wire
+ (pts
+ (xy 152.4 68.58) (xy 165.1 68.58)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "51783be5-43db-47d0-9229-7775d1d5bafe")
+ )
+ (wire
+ (pts
+ (xy 41.91 93.98) (xy 48.26 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "536ef513-5baf-44d6-98d1-e545da2492d8")
+ )
+ (wire
+ (pts
+ (xy 91.44 85.09) (xy 91.44 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "53b5effd-5af4-414b-b802-a24ba0ec99cd")
+ )
+ (wire
+ (pts
+ (xy 165.1 81.28) (xy 165.1 91.44)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "546c7992-1b48-45a6-9a10-b86b63d36e86")
+ )
+ (wire
+ (pts
+ (xy 118.11 67.31) (xy 118.11 81.28)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "5485a3d1-a1d6-49d1-a83e-7b0049ba36e1")
+ )
+ (wire
+ (pts
+ (xy 41.91 36.83) (xy 41.91 40.64)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "5517d8db-9991-4d5a-8c4e-605c2ef8859d")
+ )
+ (wire
+ (pts
+ (xy 115.57 88.9) (xy 115.57 82.55)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "5669dde8-5285-4d63-a097-7febe458747f")
+ )
+ (wire
+ (pts
+ (xy 130.81 45.72) (xy 130.81 62.23)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "56a93ee7-98e2-42a1-af96-34167538e4a3")
+ )
+ (wire
+ (pts
+ (xy 109.22 88.9) (xy 115.57 88.9)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "5a34f7b0-3287-4e4d-9c59-9a6269200d12")
+ )
+ (wire
+ (pts
+ (xy 59.69 27.94) (xy 77.47 27.94)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "5a499387-f191-45d6-abd4-79a2dc83d706")
+ )
+ (wire
+ (pts
+ (xy 118.11 67.31) (xy 106.68 67.31)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "5c369f84-7090-4d27-9bfc-b27c52843234")
+ )
+ (wire
+ (pts
+ (xy 165.1 91.44) (xy 133.35 91.44)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "5e1e298f-79a7-42de-b0bf-2c43a520f1d3")
+ )
+ (wire
+ (pts
+ (xy 165.1 68.58) (xy 176.53 68.58)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "5fadadf9-2e08-4443-ae7a-a72241920201")
+ )
+ (wire
+ (pts
+ (xy 109.22 82.55) (xy 109.22 88.9)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "60a60a54-aef9-489d-bd60-32f70e7d2d9d")
+ )
+ (wire
+ (pts
+ (xy 128.27 46.99) (xy 123.19 46.99)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "645cccf0-8b60-4433-8a82-4cdfd8dab395")
+ )
+ (wire
+ (pts
+ (xy 120.65 74.93) (xy 125.73 74.93)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "6716a945-bda5-4d85-92a1-48389a66adde")
+ )
+ (wire
+ (pts
+ (xy 93.98 85.09) (xy 93.98 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "6ad21ada-1c3c-4c30-b83c-8f7e172070b5")
+ )
+ (wire
+ (pts
+ (xy 59.69 36.83) (xy 59.69 40.64)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "6b7b016a-152d-45af-ae56-391a27768efb")
+ )
+ (wire
+ (pts
+ (xy 152.4 93.98) (xy 161.29 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "6d1065c7-1fdd-493c-8a2e-bce4f395ae4c")
+ )
+ (wire
+ (pts
+ (xy 41.91 40.64) (xy 41.91 62.23)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "6e05e367-e149-4122-a521-88547e7d0df9")
+ )
+ (wire
+ (pts
+ (xy 106.68 69.85) (xy 115.57 69.85)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "6f24fab1-6e8a-41fa-adee-d9ba22ab7ea0")
+ )
+ (wire
+ (pts
+ (xy 153.67 45.72) (xy 153.67 59.69)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "703d96f9-c092-4302-8346-5b980e2cb4f8")
+ )
+ (wire
+ (pts
+ (xy 38.1 27.94) (xy 41.91 27.94)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "70f04503-7bfa-47bb-a364-9548d47d3794")
+ )
+ (wire
+ (pts
+ (xy 62.23 72.39) (xy 62.23 74.93)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "777d9901-061e-460d-b289-e3d74c6baf1d")
+ )
+ (wire
+ (pts
+ (xy 57.15 72.39) (xy 62.23 72.39)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "7dfbc34b-5c67-4318-b67b-f9a2d0cbe516")
+ )
+ (wire
+ (pts
+ (xy 142.24 93.98) (xy 152.4 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "8303ed4c-2aa9-447a-9507-95477c71ff22")
+ )
+ (wire
+ (pts
+ (xy 152.4 80.01) (xy 152.4 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "84981f4d-fcac-40a3-93a0-0cbaaa28d74f")
+ )
+ (wire
+ (pts
+ (xy 77.47 57.15) (xy 81.28 57.15)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "85f5747d-cd50-4db2-b767-df6b8c988bfe")
+ )
+ (wire
+ (pts
+ (xy 48.26 62.23) (xy 48.26 74.93)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "8612db84-6d3b-413b-bdf9-ff6ad00ae82a")
+ )
+ (wire
+ (pts
+ (xy 125.73 64.77) (xy 106.68 64.77)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "8bb9b8c9-7a6f-4617-a4fd-b1d5242f2b87")
+ )
+ (wire
+ (pts
+ (xy 77.47 27.94) (xy 77.47 45.72)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "8d27efeb-0f98-4517-b9e8-1f1603a07a76")
+ )
+ (wire
+ (pts
+ (xy 57.15 82.55) (xy 57.15 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "8e9af4c9-6e29-41f4-8bf2-d1444747f333")
+ )
+ (wire
+ (pts
+ (xy 168.91 64.77) (xy 176.53 64.77)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "8fa94889-336a-4dbb-b42b-db25395d17ed")
+ )
+ (wire
+ (pts
+ (xy 62.23 53.34) (xy 62.23 59.69)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "90b4f434-6de7-414e-b9b8-9e7f26ee45e2")
+ )
+ (wire
+ (pts
+ (xy 80.01 64.77) (xy 80.01 91.44)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "91ecc3bd-f013-4b13-9f4e-88105f41a0fd")
+ )
+ (wire
+ (pts
+ (xy 115.57 88.9) (xy 158.75 88.9)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "92af08df-01f8-48c2-9231-5bf9226b4217")
+ )
+ (wire
+ (pts
+ (xy 116.84 36.83) (xy 118.11 36.83)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "9425f90d-5767-4b67-ac36-b6df8fd56c86")
+ )
+ (wire
+ (pts
+ (xy 106.68 72.39) (xy 109.22 72.39)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "964a5018-ac52-445a-8c60-3355d04cd9f6")
+ )
+ (wire
+ (pts
+ (xy 62.23 22.86) (xy 62.23 45.72)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "9708fd33-0559-4afb-80fb-e09d35cd8dd5")
+ )
+ (wire
+ (pts
+ (xy 41.91 31.75) (xy 41.91 27.94)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "9843d635-3d65-45b8-a706-a6e504f871b4")
+ )
+ (wire
+ (pts
+ (xy 57.15 93.98) (xy 62.23 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "9cbabf80-dbc0-4b4d-b8d8-41d850514110")
+ )
+ (wire
+ (pts
+ (xy 168.91 22.86) (xy 172.72 22.86)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "9f0d9b33-4760-4eda-949f-50978ceec3b6")
+ )
+ (wire
+ (pts
+ (xy 38.1 40.64) (xy 41.91 40.64)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "a01e0137-676b-45c2-99d6-d578561d002f")
+ )
+ (wire
+ (pts
+ (xy 74.93 82.55) (xy 74.93 88.9)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "a5bd3f8c-b731-4ef0-b088-83818bb972ec")
+ )
+ (wire
+ (pts
+ (xy 62.23 59.69) (xy 62.23 72.39)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "a61d2613-c6e2-41ca-a81b-2e228f3faf17")
+ )
+ (wire
+ (pts
+ (xy 62.23 82.55) (xy 62.23 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "a9b9e604-af02-4716-9d7c-0932f98cce32")
+ )
+ (wire
+ (pts
+ (xy 133.35 74.93) (xy 144.78 74.93)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "ade1db25-6e56-4696-ad15-9f80438a4533")
+ )
+ (wire
+ (pts
+ (xy 38.1 45.72) (xy 48.26 45.72)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "b0943662-19ff-4816-8333-054523b7e4da")
+ )
+ (wire
+ (pts
+ (xy 50.8 35.56) (xy 50.8 40.64)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "ba4f1c04-7e59-4624-b266-0b6aaae8e89f")
+ )
+ (wire
+ (pts
+ (xy 130.81 62.23) (xy 106.68 62.23)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "ba9749c4-23ac-45f8-850a-57ceca746891")
+ )
+ (wire
+ (pts
+ (xy 41.91 27.94) (xy 43.18 27.94)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "c0976920-37a6-4f88-ae9d-dabd737913aa")
+ )
+ (wire
+ (pts
+ (xy 142.24 76.2) (xy 142.24 64.77)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "c19df471-0b5e-4713-8238-e8e40b384df7")
+ )
+ (wire
+ (pts
+ (xy 116.84 46.99) (xy 123.19 46.99)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "c2016032-19f7-4966-b2f2-c06e6ceb578e")
+ )
+ (wire
+ (pts
+ (xy 58.42 27.94) (xy 59.69 27.94)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "c32de964-b09a-4989-bc6d-8c0f8d81784c")
+ )
+ (wire
+ (pts
+ (xy 142.24 64.77) (xy 168.91 64.77)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "c49ad67b-18b8-4518-8f3d-04bcaa449d4c")
+ )
+ (wire
+ (pts
+ (xy 172.72 72.39) (xy 176.53 72.39)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "c4c2803a-4bc4-4be5-b312-2962337c8c12")
+ )
+ (wire
+ (pts
+ (xy 165.1 52.07) (xy 165.1 68.58)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "c6844a03-82b1-4329-8f37-8e0d6e60690d")
+ )
+ (wire
+ (pts
+ (xy 123.19 93.98) (xy 142.24 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "c7aced9b-1f5e-47c0-b15f-b56e9f7a5b90")
+ )
+ (wire
+ (pts
+ (xy 125.73 45.72) (xy 125.73 64.77)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "cb6ebd8a-aed1-496d-984d-6353bb8b63a8")
+ )
+ (wire
+ (pts
+ (xy 96.52 85.09) (xy 96.52 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "d04f9019-a69a-4353-8296-a59293cd14fd")
+ )
+ (wire
+ (pts
+ (xy 172.72 72.39) (xy 172.72 76.2)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "d12ad63e-0cdc-46cc-80aa-6c92463b795d")
+ )
+ (wire
+ (pts
+ (xy 151.13 45.72) (xy 151.13 57.15)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "d7ec47e0-654b-4ded-9482-e7dc4281c352")
+ )
+ (wire
+ (pts
+ (xy 38.1 57.15) (xy 77.47 57.15)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "d8669caf-df4c-47b9-b7d2-d2be843b066e")
+ )
+ (wire
+ (pts
+ (xy 142.24 86.36) (xy 142.24 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "dd8d9245-11d2-4cb8-b8fb-47b9d76517ec")
+ )
+ (wire
+ (pts
+ (xy 161.29 93.98) (xy 172.72 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "de68dd7e-73dd-4f6b-a29d-73c4795bb2d0")
+ )
+ (wire
+ (pts
+ (xy 57.15 72.39) (xy 57.15 74.93)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "df329b93-adb5-4387-ab2d-fa3208ae66eb")
+ )
+ (wire
+ (pts
+ (xy 41.91 62.23) (xy 41.91 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "e03d1bbf-d27e-4297-a753-8c3e2c8a9c6c")
+ )
+ (wire
+ (pts
+ (xy 161.29 45.72) (xy 161.29 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "e1f2f6c1-5a30-4592-9b51-26a125c0b7de")
+ )
+ (wire
+ (pts
+ (xy 146.05 52.07) (xy 106.68 52.07)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "e23cb067-54e1-4abe-807c-9337e72cd2b1")
+ )
+ (wire
+ (pts
+ (xy 74.93 88.9) (xy 109.22 88.9)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "e915962d-6d8e-4963-abb7-eca2acd56b3b")
+ )
+ (wire
+ (pts
+ (xy 93.98 93.98) (xy 96.52 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "e970dd17-bc76-4005-b567-6c01a838b73b")
+ )
+ (wire
+ (pts
+ (xy 115.57 69.85) (xy 115.57 74.93)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "eb637872-8d1d-4a67-abba-fcb737e54a81")
+ )
+ (wire
+ (pts
+ (xy 74.93 67.31) (xy 81.28 67.31)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "ebde20ee-188c-4707-8777-cbde292495bf")
+ )
+ (wire
+ (pts
+ (xy 77.47 27.94) (xy 88.9 27.94)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "f3208390-6f41-42ea-9683-be3cf53d1d13")
+ )
+ (wire
+ (pts
+ (xy 62.23 59.69) (xy 81.28 59.69)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "fa06d685-4179-4558-ab77-9f08cff9a1a1")
+ )
+ (wire
+ (pts
+ (xy 120.65 74.93) (xy 120.65 49.53)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "fff85d36-77f0-459c-9a4a-9ff8631cc4ac")
+ )
+ (text "12V"
+ (exclude_from_sim no)
+ (at 33.02 31.75 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left bottom)
+ )
+ (uuid "a90837bd-b7f7-4b8d-a791-195459f5dba7")
+ )
+ (text "LCD Display"
+ (exclude_from_sim no)
+ (at 135.89 30.48 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left bottom)
+ )
+ (uuid "ea3df8be-4bc1-4e89-a31d-db9aef6681c5")
+ )
+ (global_label "Heater_RY"
+ (shape output)
+ (at 176.53 68.58 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "16e2599b-2858-48bf-b9d0-055bdf2a0a9d")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 176.53 68.58 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ )
+ (global_label "AUX_RY"
+ (shape output)
+ (at 176.53 72.39 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "192d6e95-9420-425a-8a0c-aa99f4d32f50")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 176.53 72.39 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ )
+ (global_label "ENGINE"
+ (shape input)
+ (at 38.1 45.72 180)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "3c039427-d63d-4852-aa1e-e41619697ca6")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 38.1 45.72 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ )
+ (global_label "Control"
+ (shape output)
+ (at 176.53 64.77 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "6316472a-c1c3-4fb3-81ec-9cb68557ecac")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 176.53 64.77 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ )
+ (global_label "GND"
+ (shape input)
+ (at 38.1 40.64 180)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "6d4fa618-fd3e-4b88-843b-3c3cbcb74e9f")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 38.1 40.64 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ )
+ (global_label "TempGround"
+ (shape output)
+ (at 38.1 62.23 180)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "9fd1ac04-8bf2-46a8-884f-f40590a988f7")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 38.1 62.23 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ )
+ (global_label "TEMP"
+ (shape bidirectional)
+ (at 38.1 57.15 180)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "a3822570-4ac2-4d24-bea4-a534b34a799d")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 38.1 57.15 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ )
+ (global_label "VCC"
+ (shape input)
+ (at 38.1 27.94 180)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "f8ab26d3-f041-4b7f-9ba8-a39d5eda09d7")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 38.1 27.94 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ )
+ (symbol
+ (lib_id "MCU_Module:Arduino_UNO_R3")
+ (at 93.98 57.15 0)
+ (mirror y)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b12330")
+ (property "Reference" "A1"
+ (at 93.98 27.1526 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Value" "Arduino"
+ (at 93.98 57.15 0)
+ (effects
+ (font
+ (size 1.4986 1.4986)
+ )
+ )
+ )
+ (property "Footprint" "Module:Arduino_UNO_R3"
+ (at 93.98 57.15 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ (italic yes)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "https://www.arduino.cc/en/Main/arduinoBoardUno"
+ (at 93.98 57.15 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 93.98 57.15 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "13"
+ (uuid "e0bd3351-63aa-4d1e-a017-d1a455d83fdd")
+ )
+ (pin "21"
+ (uuid "9ac9cb91-a452-4fb6-a580-5fe61bcc5e41")
+ )
+ (pin "22"
+ (uuid "69e97d36-4794-4f96-917e-a5bd0e6efd0c")
+ )
+ (pin "7"
+ (uuid "8410ed29-c902-4df3-ba84-477e341d1a45")
+ )
+ (pin "8"
+ (uuid "3fb43f69-9cb7-4550-ab95-8f3d8a142122")
+ )
+ (pin "9"
+ (uuid "1581679d-f99e-4721-9368-b1a3450f9f42")
+ )
+ (pin "30"
+ (uuid "d9b37db4-941e-42ce-b4cb-2382abc57f9c")
+ )
+ (pin "31"
+ (uuid "e2c0a214-cbdc-429e-8a4b-9506064d6d08")
+ )
+ (pin "32"
+ (uuid "74f420b5-e8b8-4ddf-b00b-4a239d40bddf")
+ )
+ (pin "4"
+ (uuid "e611c51b-e91c-4f68-87b5-a1013f519e64")
+ )
+ (pin "27"
+ (uuid "70247246-0d02-43c2-83d8-240f9dc13ed9")
+ )
+ (pin "28"
+ (uuid "1d40f114-9a3c-45fb-a446-99e371485957")
+ )
+ (pin "5"
+ (uuid "a9306a7f-7d8c-4269-ba52-3fa798ffd830")
+ )
+ (pin "6"
+ (uuid "cdcaf8cd-de5c-437f-96f2-e9315ed0b3cb")
+ )
+ (pin "25"
+ (uuid "79b9dfa3-e7f3-48f0-9f0a-6f1209d078b7")
+ )
+ (pin "26"
+ (uuid "9323194e-1556-4e35-9978-3885e79acec9")
+ )
+ (pin "29"
+ (uuid "37448e41-2bbd-4c86-9aa4-43c7af18dbca")
+ )
+ (pin "3"
+ (uuid "bb78f91d-0152-459a-9363-66af364e79d9")
+ )
+ (pin "23"
+ (uuid "69e12e97-d34e-4691-9b0c-027f5d09cb32")
+ )
+ (pin "24"
+ (uuid "81967713-213b-401a-9856-26becaaebf50")
+ )
+ (pin "16"
+ (uuid "c74e9ee7-6b25-44e3-b5b5-18f5c373a22c")
+ )
+ (pin "17"
+ (uuid "04a04e7c-e34b-43eb-80a9-00830cdf8d68")
+ )
+ (pin "11"
+ (uuid "0deed893-3ecf-44aa-811e-f6f70c53c9cf")
+ )
+ (pin "18"
+ (uuid "346ece7e-65d5-4947-9477-2777d2a1c8c0")
+ )
+ (pin "19"
+ (uuid "5d6a1ffe-bd8e-4c72-8c88-66573795b976")
+ )
+ (pin "2"
+ (uuid "4c9f3e04-dbbb-49fb-a99b-c7cc507d034b")
+ )
+ (pin "20"
+ (uuid "e884c40c-1c5f-4813-9854-e270e0fee71f")
+ )
+ (pin "12"
+ (uuid "6fad2ea7-21b1-4d30-aded-be0f634efbc7")
+ )
+ (pin "1"
+ (uuid "81b37ced-01ac-4c33-8f6f-cde68bdaf5b7")
+ )
+ (pin "10"
+ (uuid "5761029c-759c-4210-86b3-39d0239e9f92")
+ )
+ (pin "15"
+ (uuid "afa53881-e513-40c2-98d0-cdf00c3d2c70")
+ )
+ (pin "14"
+ (uuid "72888482-1224-4326-81a1-df76cf654355")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "A1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "BoilerControlModule-rescue:LCD1602A-New_Library")
+ (at 144.78 34.29 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b1641f")
+ (property "Reference" "M1"
+ (at 140.97 31.75 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Value" "LCD1602A"
+ (at 137.16 35.56 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 144.78 36.83 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 144.78 36.83 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 144.78 34.29 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "3"
+ (uuid "d50078b6-7bef-4e4c-b467-dbd668630bbe")
+ )
+ (pin "14"
+ (uuid "4e78ef6c-f7e4-46ec-b201-9ccf8c14b21f")
+ )
+ (pin "13"
+ (uuid "5e6868a9-0b41-4501-a1dc-b96142b8ff36")
+ )
+ (pin "10"
+ (uuid "e9f7be73-3fa6-4f1d-9990-58fd54518be4")
+ )
+ (pin "12"
+ (uuid "cad2f34a-5226-4ba2-af59-99becddabbcb")
+ )
+ (pin "5"
+ (uuid "79c2704a-36ca-4763-ba23-c9cfbe5fc4b8")
+ )
+ (pin "1"
+ (uuid "6d1d593f-d5b7-4407-a251-ab19eb3aafaa")
+ )
+ (pin "15"
+ (uuid "d6ac221a-b9ce-4a22-a213-6756add4b1f9")
+ )
+ (pin "7"
+ (uuid "7c8a31b3-4e0e-4e6e-993c-bde7098d55f1")
+ )
+ (pin "11"
+ (uuid "fa50be9d-8a38-43e9-b2f6-383954ebeb85")
+ )
+ (pin "9"
+ (uuid "29d97b22-b8a3-4482-8f56-3b192e796de7")
+ )
+ (pin "8"
+ (uuid "91d8bf6b-3a32-4591-9784-dd2ea6ee4b88")
+ )
+ (pin "4"
+ (uuid "213b12e0-4566-4d8f-9e18-a454b355120a")
+ )
+ (pin "2"
+ (uuid "80fea78f-cc09-46e7-9abd-69e1d3db41e4")
+ )
+ (pin "6"
+ (uuid "d7cd1c5f-5ff9-4b0f-a568-d1b98b23ec40")
+ )
+ (pin "16"
+ (uuid "457c8dd0-d3dd-4a96-bcee-6cbac99e96fc")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "M1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Switch:SW_Push")
+ (at 111.76 46.99 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b259f8")
+ (property "Reference" "SW1"
+ (at 111.76 39.751 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Value" "Button"
+ (at 111.76 42.0878 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 111.76 41.91 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 111.76 41.91 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 111.76 46.99 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "560ce6b9-2827-4166-82e6-4e886207f817")
+ )
+ (pin "1"
+ (uuid "de1bed64-9f0c-450a-962b-a2ed617fdeec")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "SW1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Transistor_BJT:BC547")
+ (at 139.7 81.28 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b32834")
+ (property "Reference" "Q2"
+ (at 144.5514 80.1116 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "BC547"
+ (at 144.5514 82.423 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline"
+ (at 144.78 83.185 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ (italic yes)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "http://www.fairchildsemi.com/ds/BC/BC547.pdf"
+ (at 139.7 81.28 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 139.7 81.28 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "2ae7f351-adea-48ad-8f52-963dfc47e47f")
+ )
+ (pin "3"
+ (uuid "4e4bb8cf-5471-4eea-a306-1a0745f56f0c")
+ )
+ (pin "1"
+ (uuid "b8d27bea-581e-4be3-b084-42cb104fde88")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "Q2")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Transistor_BJT:BC547")
+ (at 149.86 74.93 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b384d9")
+ (property "Reference" "Q1"
+ (at 154.7114 73.7616 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "BC547"
+ (at 154.7114 76.073 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline"
+ (at 154.94 76.835 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ (italic yes)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "http://www.fairchildsemi.com/ds/BC/BC547.pdf"
+ (at 149.86 74.93 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 149.86 74.93 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "21f67f15-ea3d-4bb6-b3d6-7246afe218d9")
+ )
+ (pin "3"
+ (uuid "495ba0b3-043f-44e2-9508-51d7eadbdafe")
+ )
+ (pin "1"
+ (uuid "1f08704d-714d-48ad-ac11-1c2c343e668a")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "Q1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 129.54 74.93 270)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b467c6")
+ (property "Reference" "R6"
+ (at 129.54 70.866 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "8k2"
+ (at 129.54 72.644 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 129.54 73.152 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 129.54 74.93 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 129.54 74.93 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "ee260cff-4103-433f-976a-02bec8c3bd14")
+ )
+ (pin "2"
+ (uuid "7b8f5491-b1ac-4f7a-b4ad-ea5956ad5ae7")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R6")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 129.54 81.28 270)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b4cc6d")
+ (property "Reference" "R7"
+ (at 129.54 77.216 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "8k2"
+ (at 129.54 79.248 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 129.54 79.502 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 129.54 81.28 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 129.54 81.28 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "2b50c7dd-d790-4288-aebb-540baeb3d346")
+ )
+ (pin "2"
+ (uuid "d1ecdb64-2ebd-4154-b6be-8c44fadabf2e")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R7")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 62.23 78.74 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b780ab")
+ (property "Reference" "R2"
+ (at 63.5 77.724 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "7k5"
+ (at 63.5 80.01 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 60.452 78.74 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 62.23 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 62.23 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "a16fce3d-14df-4b67-be27-75ab1d21db09")
+ )
+ (pin "1"
+ (uuid "4ea8af4d-48bb-4816-82cb-f8341b77678e")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R2")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 62.23 49.53 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b7dcc8")
+ (property "Reference" "R1"
+ (at 64.008 48.3616 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "39k"
+ (at 64.008 50.673 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 60.452 49.53 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 62.23 49.53 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 62.23 49.53 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "d8b6ead1-9a83-4f7b-9060-23fdae496f78")
+ )
+ (pin "2"
+ (uuid "0e4c9d89-147e-4ecf-b19a-da9ea433557a")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 48.26 49.53 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b83257")
+ (property "Reference" "R4"
+ (at 51.054 48.514 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "6k8"
+ (at 51.562 50.546 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 46.482 49.53 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 48.26 49.53 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 48.26 49.53 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "b1aae5bf-320d-4666-8700-158450bc4fc1")
+ )
+ (pin "1"
+ (uuid "9cd8ed96-a54e-4c64-8b3f-fcb57cb8a811")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R4")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 48.26 78.74 180)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b854cb")
+ (property "Reference" "R5"
+ (at 50.8 77.724 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "3k3"
+ (at 51.308 80.01 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 50.038 78.74 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 48.26 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 48.26 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "9ac9257a-1504-43f2-9825-d5fbb6d75037")
+ )
+ (pin "1"
+ (uuid "431f57c1-8ba7-4701-b7a1-a14516482f19")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R5")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Regulator_Linear:L78L05_TO92")
+ (at 50.8 27.94 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061c38dba")
+ (property "Reference" "U1"
+ (at 50.8 21.7932 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Value" "78L05"
+ (at 50.8 24.1046 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline"
+ (at 50.8 22.225 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ (italic yes)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "http://www.st.com/content/ccc/resource/technical/document/datasheet/15/55/e5/aa/23/5b/43/fd/CD00000446.pdf/files/CD00000446.pdf/jcr:content/translations/en.CD00000446.pdf"
+ (at 50.8 29.21 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 50.8 27.94 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "991ef9f4-9621-475f-8379-30efc1f601f6")
+ )
+ (pin "3"
+ (uuid "33e4732a-1719-46d3-91cb-f884914e89e3")
+ )
+ (pin "2"
+ (uuid "a11b77f8-1015-45e5-b099-093866fdbe68")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "U1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 77.47 49.53 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061c49556")
+ (property "Reference" "R9"
+ (at 72.39 48.514 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "4k7"
+ (at 72.39 50.8 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 75.692 49.53 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 77.47 49.53 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 77.47 49.53 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "5765e718-e535-4e33-97e1-250ddf2e640b")
+ )
+ (pin "2"
+ (uuid "9873149d-a81d-474e-ba0b-24225ca8a17d")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R9")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "BoilerControlModule-rescue:CP_Small-Device")
+ (at 59.69 34.29 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061c53b29")
+ (property "Reference" "C3"
+ (at 54.61 35.56 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "22uF"
+ (at 54.61 38.1 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 59.69 34.29 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 59.69 34.29 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 59.69 34.29 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "c1b08009-871d-410f-bba1-dca13f8de758")
+ )
+ (pin "2"
+ (uuid "9dc2f6eb-bd34-4f84-9faa-d7bd11b9573d")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "C3")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "BoilerControlModule-rescue:CP_Small-Device")
+ (at 41.91 34.29 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061c5463f")
+ (property "Reference" "C2"
+ (at 44.45 35.56 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "22uF"
+ (at 44.45 38.1 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 41.91 34.29 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 41.91 34.29 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 41.91 34.29 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "56b3d430-4bc4-4981-9c71-d14d044067fc")
+ )
+ (pin "2"
+ (uuid "b65fb0f6-d5fc-4593-b6e0-a590b5cc2c4e")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "C2")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "BoilerControlModule-rescue:D_Small_ALT-Device")
+ (at 165.1 49.53 270)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061ef2406")
+ (property "Reference" "D1"
+ (at 165.1 47.752 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "D_Small_ALT"
+ (at 166.8272 50.673 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Footprint" ""
+ (at 165.1 49.53 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 165.1 49.53 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 165.1 49.53 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "df2f69fb-4873-4e01-8433-a9a41c1b9c2f")
+ )
+ (pin "2"
+ (uuid "0b944660-5114-4939-963f-73382404cffa")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "D1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "BoilerControlModule-rescue:D_Small_ALT-Device")
+ (at 168.91 49.53 270)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061ef3466")
+ (property "Reference" "D2"
+ (at 168.91 47.752 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "D_Small_ALT"
+ (at 170.6372 50.673 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Footprint" ""
+ (at 168.91 49.53 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 168.91 49.53 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 168.91 49.53 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "6cae2e7c-d7d8-4419-b43b-4b128e8a6036")
+ )
+ (pin "2"
+ (uuid "0d44944d-0ef1-43c2-b3c2-e2348a5bcb80")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "D2")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 74.93 78.74 180)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "260ba27c-5fb2-4f45-abd5-09d165c9eab2")
+ (property "Reference" "R10"
+ (at 77.978 77.724 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "3k3"
+ (at 77.978 80.01 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 76.708 78.74 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 74.93 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 74.93 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "b0b08caa-5799-4843-8271-3393ce5aa6ee")
+ )
+ (pin "1"
+ (uuid "bd98f891-a075-4feb-9c12-bd81da69a414")
+ )
+ (instances
+ (project "BoilerControlModule"
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R10")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 109.22 78.74 180)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "33d4bd0f-ed74-4696-b631-490fea57d22c")
+ (property "Reference" "R11"
+ (at 112.268 77.724 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "1k5"
+ (at 112.268 80.01 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 110.998 78.74 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 109.22 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 109.22 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "14142d6d-88eb-4633-bcf3-4a375a828e23")
+ )
+ (pin "1"
+ (uuid "7c55e504-4ca9-4bfd-bfb3-0b1e075ac3e1")
+ )
+ (instances
+ (project "BoilerControlModule"
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R11")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 129.54 91.44 270)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "5a636c1b-c9ce-44b0-8d6c-b0d477f16ecd")
+ (property "Reference" "R8"
+ (at 129.286 85.852 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "8k2"
+ (at 129.54 87.884 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 129.54 89.662 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 129.54 91.44 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 129.54 91.44 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "358fde96-d5df-44ca-86b3-5c332c8d6972")
+ )
+ (pin "2"
+ (uuid "881ede44-2d30-4e1c-9d30-1a67347bc964")
+ )
+ (instances
+ (project "BoilerControlModule"
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R8")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:C")
+ (at 57.15 78.74 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "5b56dc85-02d8-4f39-90ec-b6030a0c4d1b")
+ (property "Reference" "C1"
+ (at 57.404 76.454 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "100n"
+ (at 57.15 82.042 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 58.1152 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 57.15 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Unpolarized capacitor"
+ (at 57.15 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "5a447abc-542a-4a45-a4b2-22c69f2d1645")
+ )
+ (pin "1"
+ (uuid "c4e64a58-54e5-4658-99d3-47df4e5aa7e0")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "C1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 115.57 78.74 180)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "797ac7f6-e11a-4726-b189-b215b43d3664")
+ (property "Reference" "R12"
+ (at 118.618 77.724 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "820"
+ (at 119.126 80.01 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 117.348 78.74 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 115.57 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 115.57 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "63a0dad5-41d6-418a-a950-d882b0c80b53")
+ )
+ (pin "1"
+ (uuid "91d2ea74-996c-4215-99d3-735da60f9d27")
+ )
+ (instances
+ (project "BoilerControlModule"
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R12")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "BoilerControlModule-rescue:D_Small_ALT-Device")
+ (at 172.72 49.53 270)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "9f1e2f71-12d0-4b59-b463-bee3cbf218a6")
+ (property "Reference" "D3"
+ (at 172.466 47.752 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "D_Small_ALT"
+ (at 174.4472 50.673 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Footprint" ""
+ (at 172.72 49.53 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 172.72 49.53 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 172.72 49.53 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "5aef5384-0209-4d34-ae4b-e20f44a31adc")
+ )
+ (pin "2"
+ (uuid "8bd03e6a-cf37-4735-b895-7070182c177c")
+ )
+ (instances
+ (project "BoilerControlModule"
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "D3")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Transistor_BJT:BC547")
+ (at 170.18 81.28 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "a8f8afd1-16c9-44f6-ba0d-bce95a98dc78")
+ (property "Reference" "Q3"
+ (at 175.0314 80.1116 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "BC547"
+ (at 175.0314 82.423 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline"
+ (at 175.26 83.185 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ (italic yes)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "http://www.fairchildsemi.com/ds/BC/BC547.pdf"
+ (at 170.18 81.28 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 170.18 81.28 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "c2c92de9-5395-41e1-a230-3d448a957b1b")
+ )
+ (pin "3"
+ (uuid "2ccfd052-e3ff-40f6-9002-3c95aea8a704")
+ )
+ (pin "1"
+ (uuid "d64ea2c0-3ad8-485b-8aef-c48c6b2d8e1d")
+ )
+ (instances
+ (project "BoilerControlModule"
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "Q3")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 116.84 40.64 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "b299ec57-c640-40b0-89f3-dc8cc725e992")
+ (property "Reference" "R3"
+ (at 117.856 39.37 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "1k5"
+ (at 117.094 44.45 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 115.062 40.64 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 116.84 40.64 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Resistor"
+ (at 116.84 40.64 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "9c241b2b-dc43-42b1-ad14-469acdd337ba")
+ )
+ (pin "2"
+ (uuid "10fc5700-be84-4fb0-a291-09274721f115")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R3")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (sheet_instances
+ (path "/"
+ (page "1")
+ )
+ )
+)
diff --git a/HotWaterManager_Arduino.svg b/HotWaterManager_Arduino.svg
new file mode 100644
index 0000000..3bb929d
--- /dev/null
+++ b/HotWaterManager_Arduino.svg
@@ -0,0 +1,26709 @@
+
+
+
diff --git a/HotWaterManager_Arduino_Minimalistic.kicad_sch b/HotWaterManager_Arduino_Minimalistic.kicad_sch
new file mode 100644
index 0000000..aeea1c0
--- /dev/null
+++ b/HotWaterManager_Arduino_Minimalistic.kicad_sch
@@ -0,0 +1,3654 @@
+(kicad_sch
+ (version 20231120)
+ (generator "eeschema")
+ (generator_version "8.0")
+ (uuid "2cebea01-a9ab-4da4-addb-e9c778a0107c")
+ (paper "A5")
+ (title_block
+ (title "HotWaterManager_Arduino_Minimalistic")
+ (date "2025-03-029")
+ (rev "1.1")
+ (company "TheFloatingLab LLC")
+ )
+ (lib_symbols
+ (symbol "BoilerControlModule-rescue:D_Small_ALT-Device"
+ (pin_numbers hide)
+ (pin_names
+ (offset 0.254) hide)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "D"
+ (at -1.27 2.032 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "Device_D_Small_ALT"
+ (at -3.81 -2.032 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 0 0 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_fp_filters" "TO-???* *_Diode_* *SingleDiode* D_*"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "D_Small_ALT-Device_0_1"
+ (polyline
+ (pts
+ (xy -0.762 -1.016) (xy -0.762 1.016)
+ )
+ (stroke
+ (width 0)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -0.762 0) (xy 0.762 0)
+ )
+ (stroke
+ (width 0)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 0.762 -1.016) (xy -0.762 0) (xy 0.762 1.016) (xy 0.762 -1.016)
+ )
+ (stroke
+ (width 0)
+ (type solid)
+ )
+ (fill
+ (type outline)
+ )
+ )
+ )
+ (symbol "D_Small_ALT-Device_1_1"
+ (pin passive line
+ (at -2.54 0 0)
+ (length 1.778)
+ (name "K"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 2.54 0 180)
+ (length 1.778)
+ (name "A"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "BoilerControlModule-rescue:LCD1602A-New_Library"
+ (pin_names
+ (offset 1.016)
+ )
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "M"
+ (at 0 -2.54 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "New_Library_LCD1602A"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 0 -2.54 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 -2.54 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "LCD1602A-New_Library_0_1"
+ (rectangle
+ (start -24.13 3.81)
+ (end 19.05 -8.89)
+ (stroke
+ (width 0)
+ (type solid)
+ )
+ (fill
+ (type background)
+ )
+ )
+ )
+ (symbol "LCD1602A-New_Library_1_1"
+ (pin power_in line
+ (at -21.59 -11.43 90)
+ (length 2.54)
+ (name "GND"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -1.27 -11.43 90)
+ (length 2.54)
+ (name "D3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "10"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 1.27 -11.43 90)
+ (length 2.54)
+ (name "D4"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "11"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 3.81 -11.43 90)
+ (length 2.54)
+ (name "D5"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "12"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 6.35 -11.43 90)
+ (length 2.54)
+ (name "D6"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "13"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 8.89 -11.43 90)
+ (length 2.54)
+ (name "D7"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "14"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at 13.97 -11.43 90)
+ (length 2.54)
+ (name "Backlight_+"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "15"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at 16.51 -11.43 90)
+ (length 2.54)
+ (name "Backlight_-"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "16"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_in line
+ (at -21.59 6.35 270)
+ (length 2.54)
+ (name "VCC"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at -26.67 -2.54 0)
+ (length 2.54)
+ (name "Contrast"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at -19.05 -11.43 90)
+ (length 2.54)
+ (name "RS"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "4"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at -16.51 -11.43 90)
+ (length 2.54)
+ (name "RW"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "5"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at -13.97 -11.43 90)
+ (length 2.54)
+ (name "EN"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "6"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -8.89 -11.43 90)
+ (length 2.54)
+ (name "D0"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "7"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -6.35 -11.43 90)
+ (length 2.54)
+ (name "D1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "8"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -3.81 -11.43 90)
+ (length 2.54)
+ (name "D2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "9"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "Device:C"
+ (pin_numbers hide)
+ (pin_names
+ (offset 0.254)
+ )
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "C"
+ (at 0.635 2.54 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "C"
+ (at 0.635 -2.54 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 0.9652 -3.81 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Unpolarized capacitor"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "cap capacitor"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_fp_filters" "C_*"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "C_0_1"
+ (polyline
+ (pts
+ (xy -2.032 -0.762) (xy 2.032 -0.762)
+ )
+ (stroke
+ (width 0.508)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -2.032 0.762) (xy 2.032 0.762)
+ )
+ (stroke
+ (width 0.508)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ )
+ (symbol "C_1_1"
+ (pin passive line
+ (at 0 3.81 270)
+ (length 2.794)
+ (name "~"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 0 -3.81 90)
+ (length 2.794)
+ (name "~"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "Device:R"
+ (pin_numbers hide)
+ (pin_names
+ (offset 0)
+ )
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "R"
+ (at 2.032 0 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "R"
+ (at 0 0 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at -1.778 0 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Resistor"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "R res resistor"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_fp_filters" "R_*"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "R_0_1"
+ (rectangle
+ (start -1.016 -2.54)
+ (end 1.016 2.54)
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ )
+ (symbol "R_1_1"
+ (pin passive line
+ (at 0 3.81 270)
+ (length 1.27)
+ (name "~"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 0 -3.81 90)
+ (length 1.27)
+ (name "~"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "MCU_Module:Arduino_UNO_R3"
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "A"
+ (at -10.16 23.495 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left bottom)
+ )
+ )
+ (property "Value" "Arduino_UNO_R3"
+ (at 5.08 -26.67 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ )
+ )
+ (property "Footprint" "Module:Arduino_UNO_R3"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ (italic yes)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "https://www.arduino.cc/en/Main/arduinoBoardUno"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Arduino UNO Microcontroller Module, release 3"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "Arduino UNO R3 Microcontroller Module Atmel AVR USB"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_fp_filters" "Arduino*UNO*R3*"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "Arduino_UNO_R3_0_1"
+ (rectangle
+ (start -10.16 22.86)
+ (end 10.16 -25.4)
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type background)
+ )
+ )
+ )
+ (symbol "Arduino_UNO_R3_1_1"
+ (pin no_connect line
+ (at -10.16 -20.32 0)
+ (length 2.54) hide
+ (name "NC"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 12.7 -2.54 180)
+ (length 2.54)
+ (name "A1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "10"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 12.7 -5.08 180)
+ (length 2.54)
+ (name "A2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "11"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 12.7 -7.62 180)
+ (length 2.54)
+ (name "A3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "12"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 12.7 -10.16 180)
+ (length 2.54)
+ (name "SDA/A4"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "13"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 12.7 -12.7 180)
+ (length 2.54)
+ (name "SCL/A5"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "14"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 15.24 0)
+ (length 2.54)
+ (name "D0/RX"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "15"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 12.7 0)
+ (length 2.54)
+ (name "D1/TX"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "16"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 10.16 0)
+ (length 2.54)
+ (name "D2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "17"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 7.62 0)
+ (length 2.54)
+ (name "D3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "18"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 5.08 0)
+ (length 2.54)
+ (name "D4"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "19"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin output line
+ (at 12.7 10.16 180)
+ (length 2.54)
+ (name "IOREF"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 2.54 0)
+ (length 2.54)
+ (name "D5"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "20"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 0 0)
+ (length 2.54)
+ (name "D6"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "21"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 -2.54 0)
+ (length 2.54)
+ (name "D7"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "22"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 -5.08 0)
+ (length 2.54)
+ (name "D8"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "23"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 -7.62 0)
+ (length 2.54)
+ (name "D9"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "24"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 -10.16 0)
+ (length 2.54)
+ (name "D10"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "25"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 -12.7 0)
+ (length 2.54)
+ (name "D11"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "26"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 -15.24 0)
+ (length 2.54)
+ (name "D12"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "27"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -12.7 -17.78 0)
+ (length 2.54)
+ (name "D13"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "28"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_in line
+ (at -2.54 -27.94 90)
+ (length 2.54)
+ (name "GND"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "29"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at 12.7 15.24 180)
+ (length 2.54)
+ (name "~{RESET}"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at 12.7 5.08 180)
+ (length 2.54)
+ (name "AREF"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "30"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 12.7 -17.78 180)
+ (length 2.54)
+ (name "SDA/A4"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "31"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 12.7 -20.32 180)
+ (length 2.54)
+ (name "SCL/A5"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "32"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_out line
+ (at 2.54 25.4 270)
+ (length 2.54)
+ (name "3V3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "4"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_out line
+ (at 5.08 25.4 270)
+ (length 2.54)
+ (name "+5V"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "5"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_in line
+ (at 0 -27.94 90)
+ (length 2.54)
+ (name "GND"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "6"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_in line
+ (at 2.54 -27.94 90)
+ (length 2.54)
+ (name "GND"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "7"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_in line
+ (at -2.54 25.4 270)
+ (length 2.54)
+ (name "VIN"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "8"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at 12.7 0 180)
+ (length 2.54)
+ (name "A0"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "9"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "Switch:SW_Push"
+ (pin_numbers hide)
+ (pin_names
+ (offset 1.016) hide)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "SW"
+ (at 1.27 2.54 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "SW_Push"
+ (at 0 -1.524 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 0 5.08 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 0 5.08 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Push button switch, generic, two pins"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "switch normally-open pushbutton push-button"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "SW_Push_0_1"
+ (circle
+ (center -2.032 0)
+ (radius 0.508)
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 0 1.27) (xy 0 3.048)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 2.54 1.27) (xy -2.54 1.27)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (circle
+ (center 2.032 0)
+ (radius 0.508)
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (pin passive line
+ (at -5.08 0 0)
+ (length 2.54)
+ (name "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 5.08 0 180)
+ (length 2.54)
+ (name "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "Transistor_BJT:BC547"
+ (pin_names
+ (offset 0) hide)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "Q"
+ (at 5.08 1.905 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "BC547"
+ (at 5.08 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline"
+ (at 5.08 -1.905 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ (italic yes)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "https://www.onsemi.com/pub/Collateral/BC550-D.pdf"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Description" "0.1A Ic, 45V Vce, Small Signal NPN Transistor, TO-92"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "NPN Transistor"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_fp_filters" "TO?92*"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "BC547_0_1"
+ (polyline
+ (pts
+ (xy 0 0) (xy 0.635 0)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 0.635 0.635) (xy 2.54 2.54)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 0.635 -0.635) (xy 2.54 -2.54) (xy 2.54 -2.54)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 0.635 1.905) (xy 0.635 -1.905) (xy 0.635 -1.905)
+ )
+ (stroke
+ (width 0.508)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 1.27 -1.778) (xy 1.778 -1.27) (xy 2.286 -2.286) (xy 1.27 -1.778) (xy 1.27 -1.778)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type outline)
+ )
+ )
+ (circle
+ (center 1.27 0)
+ (radius 2.8194)
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ )
+ (symbol "BC547_1_1"
+ (pin passive line
+ (at 2.54 5.08 270)
+ (length 2.54)
+ (name "C"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at -5.08 0 0)
+ (length 5.08)
+ (name "B"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 2.54 -5.08 90)
+ (length 2.54)
+ (name "E"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ (junction
+ (at 41.91 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "078387ce-a7ab-4d9a-a611-b52abb92fdef")
+ )
+ (junction
+ (at 165.1 68.58)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "09ae8a03-2b1e-4c78-a4eb-d462e3235ea6")
+ )
+ (junction
+ (at 62.23 22.86)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "181a5f0d-7037-4036-9ebe-fa63bd05d79d")
+ )
+ (junction
+ (at 96.52 22.86)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "251101c5-3481-4d6a-a673-1a517a5d42be")
+ )
+ (junction
+ (at 123.19 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "577c0ace-4c73-42ee-b439-1ceabfadf290")
+ )
+ (junction
+ (at 93.98 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "694be018-90c2-4b5e-be9d-fdc931fff995")
+ )
+ (junction
+ (at 57.15 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "72fe39e5-ecff-4a9a-bf0f-a1c6cfa4404c")
+ )
+ (junction
+ (at 62.23 59.69)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "7c7e3375-070c-45bf-9dba-a65e4f0f4a69")
+ )
+ (junction
+ (at 62.23 72.39)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "993d5015-af55-435d-84de-2acd681d6b2c")
+ )
+ (junction
+ (at 152.4 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "9a11ec3d-0c67-459a-b59c-8261b314b0c6")
+ )
+ (junction
+ (at 77.47 57.15)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "9f6dbb86-7b84-4eb2-9452-480d874840c5")
+ )
+ (junction
+ (at 96.52 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "b52abf9e-e403-42e5-bcde-ef3fd7dd83ed")
+ )
+ (junction
+ (at 123.19 46.99)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "c42d6620-c7f3-482c-aef9-2957c04db7b4")
+ )
+ (junction
+ (at 62.23 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "c80f75b8-63b3-46d2-ae14-f44bfbd870c4")
+ )
+ (junction
+ (at 91.44 93.98)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "d46a4cf8-72e0-430c-b9f3-f756914d9c5d")
+ )
+ (junction
+ (at 116.84 46.99)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "eda6630f-267c-40ca-8e27-364ef95bc646")
+ )
+ (junction
+ (at 88.9 27.94)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "f3c40699-6ac4-4323-9fed-3670f160ed9c")
+ )
+ (wire
+ (pts
+ (xy 148.59 45.72) (xy 148.59 54.61)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "025ece39-b111-45a4-a678-d23e88b25bec")
+ )
+ (wire
+ (pts
+ (xy 62.23 22.86) (xy 96.52 22.86)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "04bc6eaa-3c52-4f3e-b42f-d482cf186695")
+ )
+ (wire
+ (pts
+ (xy 106.68 57.15) (xy 151.13 57.15)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "0d36e047-9a7a-4d49-803d-497b8ff16a62")
+ )
+ (wire
+ (pts
+ (xy 123.19 46.99) (xy 123.19 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "0e1d5497-0197-4a65-8c92-0c9b915345a6")
+ )
+ (wire
+ (pts
+ (xy 116.84 44.45) (xy 116.84 46.99)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "15ea865f-a39a-4b75-b6fe-0fdb4b239d3b")
+ )
+ (wire
+ (pts
+ (xy 77.47 53.34) (xy 77.47 57.15)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "1678e147-f5ee-4506-8c67-2fb9e986413e")
+ )
+ (wire
+ (pts
+ (xy 120.65 49.53) (xy 106.68 49.53)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "1726c90b-5ed5-48ca-b3c3-dbca7ae1bd6d")
+ )
+ (wire
+ (pts
+ (xy 152.4 68.58) (xy 152.4 69.85)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "18b8d5d2-ab00-4b86-9a9e-d3939679ea77")
+ )
+ (wire
+ (pts
+ (xy 158.75 88.9) (xy 158.75 45.72)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "1b2ede75-5539-45ae-93dc-828538d840de")
+ )
+ (wire
+ (pts
+ (xy 96.52 93.98) (xy 123.19 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "1c9567c9-565c-4932-a341-c19735501826")
+ )
+ (wire
+ (pts
+ (xy 96.52 22.86) (xy 96.52 31.75)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "215f212f-c555-40c2-86e1-f28007f87259")
+ )
+ (wire
+ (pts
+ (xy 146.05 45.72) (xy 146.05 52.07)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "26d11170-94f2-4383-a2c6-a1f6be8b6b00")
+ )
+ (wire
+ (pts
+ (xy 123.19 46.99) (xy 123.19 45.72)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "29b7600c-1b26-4328-8f7c-24c3f4c05a62")
+ )
+ (wire
+ (pts
+ (xy 38.1 62.23) (xy 41.91 62.23)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "2b43d5a7-1fed-4a44-83ef-14335b9f3e04")
+ )
+ (wire
+ (pts
+ (xy 91.44 93.98) (xy 93.98 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "2c692142-363f-43a4-a240-424601888a05")
+ )
+ (wire
+ (pts
+ (xy 96.52 22.86) (xy 165.1 22.86)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "2c6b0331-d7ff-40ef-a162-1d92ca060147")
+ )
+ (wire
+ (pts
+ (xy 165.1 22.86) (xy 165.1 46.99)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "2fbf418b-f05f-44fc-83b6-9286fb915ec0")
+ )
+ (wire
+ (pts
+ (xy 88.9 27.94) (xy 123.19 27.94)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "33b96955-8910-4d58-a3cf-df26e6f29d2c")
+ )
+ (wire
+ (pts
+ (xy 62.23 93.98) (xy 91.44 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "34623ca4-828f-4084-ad68-7d8bf45b632f")
+ )
+ (wire
+ (pts
+ (xy 106.68 54.61) (xy 148.59 54.61)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "35641f40-836a-4ac0-abb0-2253acab7260")
+ )
+ (wire
+ (pts
+ (xy 106.68 59.69) (xy 153.67 59.69)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "3986772d-2d37-4d40-844e-d69d33d80a8b")
+ )
+ (wire
+ (pts
+ (xy 128.27 45.72) (xy 128.27 46.99)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "3a55f7d2-6781-43ec-815a-c6f550d7584f")
+ )
+ (wire
+ (pts
+ (xy 88.9 31.75) (xy 88.9 27.94)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "45fb80b7-a3c5-40ba-b4cd-76befcfc79eb")
+ )
+ (wire
+ (pts
+ (xy 152.4 68.58) (xy 165.1 68.58)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "51783be5-43db-47d0-9229-7775d1d5bafe")
+ )
+ (wire
+ (pts
+ (xy 41.91 93.98) (xy 57.15 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "536ef513-5baf-44d6-98d1-e545da2492d8")
+ )
+ (wire
+ (pts
+ (xy 91.44 85.09) (xy 91.44 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "53b5effd-5af4-414b-b802-a24ba0ec99cd")
+ )
+ (wire
+ (pts
+ (xy 115.57 88.9) (xy 115.57 82.55)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "5669dde8-5285-4d63-a097-7febe458747f")
+ )
+ (wire
+ (pts
+ (xy 130.81 45.72) (xy 130.81 62.23)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "56a93ee7-98e2-42a1-af96-34167538e4a3")
+ )
+ (wire
+ (pts
+ (xy 165.1 68.58) (xy 176.53 68.58)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "5fadadf9-2e08-4443-ae7a-a72241920201")
+ )
+ (wire
+ (pts
+ (xy 128.27 46.99) (xy 123.19 46.99)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "645cccf0-8b60-4433-8a82-4cdfd8dab395")
+ )
+ (wire
+ (pts
+ (xy 120.65 74.93) (xy 125.73 74.93)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "6716a945-bda5-4d85-92a1-48389a66adde")
+ )
+ (wire
+ (pts
+ (xy 93.98 85.09) (xy 93.98 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "6ad21ada-1c3c-4c30-b83c-8f7e172070b5")
+ )
+ (wire
+ (pts
+ (xy 152.4 93.98) (xy 161.29 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "6d1065c7-1fdd-493c-8a2e-bce4f395ae4c")
+ )
+ (wire
+ (pts
+ (xy 106.68 69.85) (xy 115.57 69.85)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "6f24fab1-6e8a-41fa-adee-d9ba22ab7ea0")
+ )
+ (wire
+ (pts
+ (xy 153.67 45.72) (xy 153.67 59.69)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "703d96f9-c092-4302-8346-5b980e2cb4f8")
+ )
+ (wire
+ (pts
+ (xy 38.1 22.86) (xy 62.23 22.86)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "70f04503-7bfa-47bb-a364-9548d47d3794")
+ )
+ (wire
+ (pts
+ (xy 62.23 72.39) (xy 62.23 74.93)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "777d9901-061e-460d-b289-e3d74c6baf1d")
+ )
+ (wire
+ (pts
+ (xy 57.15 72.39) (xy 62.23 72.39)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "7dfbc34b-5c67-4318-b67b-f9a2d0cbe516")
+ )
+ (wire
+ (pts
+ (xy 123.19 93.98) (xy 152.4 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "8303ed4c-2aa9-447a-9507-95477c71ff22")
+ )
+ (wire
+ (pts
+ (xy 152.4 80.01) (xy 152.4 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "84981f4d-fcac-40a3-93a0-0cbaaa28d74f")
+ )
+ (wire
+ (pts
+ (xy 77.47 57.15) (xy 81.28 57.15)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "85f5747d-cd50-4db2-b767-df6b8c988bfe")
+ )
+ (wire
+ (pts
+ (xy 125.73 64.77) (xy 106.68 64.77)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "8bb9b8c9-7a6f-4617-a4fd-b1d5242f2b87")
+ )
+ (wire
+ (pts
+ (xy 77.47 27.94) (xy 77.47 45.72)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "8d27efeb-0f98-4517-b9e8-1f1603a07a76")
+ )
+ (wire
+ (pts
+ (xy 57.15 82.55) (xy 57.15 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "8e9af4c9-6e29-41f4-8bf2-d1444747f333")
+ )
+ (wire
+ (pts
+ (xy 62.23 53.34) (xy 62.23 59.69)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "90b4f434-6de7-414e-b9b8-9e7f26ee45e2")
+ )
+ (wire
+ (pts
+ (xy 115.57 88.9) (xy 158.75 88.9)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "92af08df-01f8-48c2-9231-5bf9226b4217")
+ )
+ (wire
+ (pts
+ (xy 116.84 36.83) (xy 118.11 36.83)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "9425f90d-5767-4b67-ac36-b6df8fd56c86")
+ )
+ (wire
+ (pts
+ (xy 62.23 22.86) (xy 62.23 45.72)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "9708fd33-0559-4afb-80fb-e09d35cd8dd5")
+ )
+ (wire
+ (pts
+ (xy 57.15 93.98) (xy 62.23 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "9cbabf80-dbc0-4b4d-b8d8-41d850514110")
+ )
+ (wire
+ (pts
+ (xy 38.1 93.98) (xy 41.91 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "a01e0137-676b-45c2-99d6-d578561d002f")
+ )
+ (wire
+ (pts
+ (xy 62.23 59.69) (xy 62.23 72.39)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "a61d2613-c6e2-41ca-a81b-2e228f3faf17")
+ )
+ (wire
+ (pts
+ (xy 62.23 82.55) (xy 62.23 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "a9b9e604-af02-4716-9d7c-0932f98cce32")
+ )
+ (wire
+ (pts
+ (xy 133.35 74.93) (xy 144.78 74.93)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "ade1db25-6e56-4696-ad15-9f80438a4533")
+ )
+ (wire
+ (pts
+ (xy 130.81 62.23) (xy 106.68 62.23)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "ba9749c4-23ac-45f8-850a-57ceca746891")
+ )
+ (wire
+ (pts
+ (xy 116.84 46.99) (xy 123.19 46.99)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "c2016032-19f7-4966-b2f2-c06e6ceb578e")
+ )
+ (wire
+ (pts
+ (xy 165.1 52.07) (xy 165.1 68.58)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "c6844a03-82b1-4329-8f37-8e0d6e60690d")
+ )
+ (wire
+ (pts
+ (xy 125.73 45.72) (xy 125.73 64.77)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "cb6ebd8a-aed1-496d-984d-6353bb8b63a8")
+ )
+ (wire
+ (pts
+ (xy 96.52 85.09) (xy 96.52 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "d04f9019-a69a-4353-8296-a59293cd14fd")
+ )
+ (wire
+ (pts
+ (xy 151.13 45.72) (xy 151.13 57.15)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "d7ec47e0-654b-4ded-9482-e7dc4281c352")
+ )
+ (wire
+ (pts
+ (xy 38.1 57.15) (xy 77.47 57.15)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "d8669caf-df4c-47b9-b7d2-d2be843b066e")
+ )
+ (wire
+ (pts
+ (xy 57.15 72.39) (xy 57.15 74.93)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "df329b93-adb5-4387-ab2d-fa3208ae66eb")
+ )
+ (wire
+ (pts
+ (xy 41.91 62.23) (xy 41.91 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "e03d1bbf-d27e-4297-a753-8c3e2c8a9c6c")
+ )
+ (wire
+ (pts
+ (xy 161.29 45.72) (xy 161.29 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "e1f2f6c1-5a30-4592-9b51-26a125c0b7de")
+ )
+ (wire
+ (pts
+ (xy 146.05 52.07) (xy 106.68 52.07)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "e23cb067-54e1-4abe-807c-9337e72cd2b1")
+ )
+ (wire
+ (pts
+ (xy 93.98 93.98) (xy 96.52 93.98)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "e970dd17-bc76-4005-b567-6c01a838b73b")
+ )
+ (wire
+ (pts
+ (xy 115.57 69.85) (xy 115.57 74.93)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "eb637872-8d1d-4a67-abba-fcb737e54a81")
+ )
+ (wire
+ (pts
+ (xy 77.47 27.94) (xy 88.9 27.94)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "f3208390-6f41-42ea-9683-be3cf53d1d13")
+ )
+ (wire
+ (pts
+ (xy 62.23 59.69) (xy 81.28 59.69)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "fa06d685-4179-4558-ab77-9f08cff9a1a1")
+ )
+ (wire
+ (pts
+ (xy 120.65 74.93) (xy 120.65 49.53)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "fff85d36-77f0-459c-9a4a-9ff8631cc4ac")
+ )
+ (text "12V"
+ (exclude_from_sim no)
+ (at 32.766 26.67 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left bottom)
+ )
+ (uuid "a90837bd-b7f7-4b8d-a791-195459f5dba7")
+ )
+ (text "LCD Display"
+ (exclude_from_sim no)
+ (at 135.89 30.48 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left bottom)
+ )
+ (uuid "ea3df8be-4bc1-4e89-a31d-db9aef6681c5")
+ )
+ (global_label "Heater_RY"
+ (shape output)
+ (at 176.53 68.58 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "16e2599b-2858-48bf-b9d0-055bdf2a0a9d")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 176.53 68.58 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ )
+ (global_label "GND"
+ (shape input)
+ (at 38.1 93.98 180)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "6d4fa618-fd3e-4b88-843b-3c3cbcb74e9f")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 38.1 93.98 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ )
+ (global_label "TempGround"
+ (shape output)
+ (at 38.1 62.23 180)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "9fd1ac04-8bf2-46a8-884f-f40590a988f7")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 38.1 62.23 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ )
+ (global_label "TEMP"
+ (shape bidirectional)
+ (at 38.1 57.15 180)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "a3822570-4ac2-4d24-bea4-a534b34a799d")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 38.1 57.15 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ )
+ (global_label "VCC"
+ (shape input)
+ (at 38.1 22.86 180)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "f8ab26d3-f041-4b7f-9ba8-a39d5eda09d7")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 38.1 22.86 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ )
+ (symbol
+ (lib_id "MCU_Module:Arduino_UNO_R3")
+ (at 93.98 57.15 0)
+ (mirror y)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b12330")
+ (property "Reference" "A1"
+ (at 93.98 27.1526 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Value" "Arduino"
+ (at 93.98 57.15 0)
+ (effects
+ (font
+ (size 1.4986 1.4986)
+ )
+ )
+ )
+ (property "Footprint" "Module:Arduino_UNO_R3"
+ (at 93.98 57.15 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ (italic yes)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "https://www.arduino.cc/en/Main/arduinoBoardUno"
+ (at 93.98 57.15 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 93.98 57.15 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "13"
+ (uuid "e0bd3351-63aa-4d1e-a017-d1a455d83fdd")
+ )
+ (pin "21"
+ (uuid "9ac9cb91-a452-4fb6-a580-5fe61bcc5e41")
+ )
+ (pin "22"
+ (uuid "69e97d36-4794-4f96-917e-a5bd0e6efd0c")
+ )
+ (pin "7"
+ (uuid "8410ed29-c902-4df3-ba84-477e341d1a45")
+ )
+ (pin "8"
+ (uuid "3fb43f69-9cb7-4550-ab95-8f3d8a142122")
+ )
+ (pin "9"
+ (uuid "1581679d-f99e-4721-9368-b1a3450f9f42")
+ )
+ (pin "30"
+ (uuid "d9b37db4-941e-42ce-b4cb-2382abc57f9c")
+ )
+ (pin "31"
+ (uuid "e2c0a214-cbdc-429e-8a4b-9506064d6d08")
+ )
+ (pin "32"
+ (uuid "74f420b5-e8b8-4ddf-b00b-4a239d40bddf")
+ )
+ (pin "4"
+ (uuid "e611c51b-e91c-4f68-87b5-a1013f519e64")
+ )
+ (pin "27"
+ (uuid "70247246-0d02-43c2-83d8-240f9dc13ed9")
+ )
+ (pin "28"
+ (uuid "1d40f114-9a3c-45fb-a446-99e371485957")
+ )
+ (pin "5"
+ (uuid "a9306a7f-7d8c-4269-ba52-3fa798ffd830")
+ )
+ (pin "6"
+ (uuid "cdcaf8cd-de5c-437f-96f2-e9315ed0b3cb")
+ )
+ (pin "25"
+ (uuid "79b9dfa3-e7f3-48f0-9f0a-6f1209d078b7")
+ )
+ (pin "26"
+ (uuid "9323194e-1556-4e35-9978-3885e79acec9")
+ )
+ (pin "29"
+ (uuid "37448e41-2bbd-4c86-9aa4-43c7af18dbca")
+ )
+ (pin "3"
+ (uuid "bb78f91d-0152-459a-9363-66af364e79d9")
+ )
+ (pin "23"
+ (uuid "69e12e97-d34e-4691-9b0c-027f5d09cb32")
+ )
+ (pin "24"
+ (uuid "81967713-213b-401a-9856-26becaaebf50")
+ )
+ (pin "16"
+ (uuid "c74e9ee7-6b25-44e3-b5b5-18f5c373a22c")
+ )
+ (pin "17"
+ (uuid "04a04e7c-e34b-43eb-80a9-00830cdf8d68")
+ )
+ (pin "11"
+ (uuid "0deed893-3ecf-44aa-811e-f6f70c53c9cf")
+ )
+ (pin "18"
+ (uuid "346ece7e-65d5-4947-9477-2777d2a1c8c0")
+ )
+ (pin "19"
+ (uuid "5d6a1ffe-bd8e-4c72-8c88-66573795b976")
+ )
+ (pin "2"
+ (uuid "4c9f3e04-dbbb-49fb-a99b-c7cc507d034b")
+ )
+ (pin "20"
+ (uuid "e884c40c-1c5f-4813-9854-e270e0fee71f")
+ )
+ (pin "12"
+ (uuid "6fad2ea7-21b1-4d30-aded-be0f634efbc7")
+ )
+ (pin "1"
+ (uuid "81b37ced-01ac-4c33-8f6f-cde68bdaf5b7")
+ )
+ (pin "10"
+ (uuid "5761029c-759c-4210-86b3-39d0239e9f92")
+ )
+ (pin "15"
+ (uuid "afa53881-e513-40c2-98d0-cdf00c3d2c70")
+ )
+ (pin "14"
+ (uuid "72888482-1224-4326-81a1-df76cf654355")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "A1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "BoilerControlModule-rescue:LCD1602A-New_Library")
+ (at 144.78 34.29 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b1641f")
+ (property "Reference" "M1"
+ (at 140.97 31.75 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Value" "LCD1602A"
+ (at 137.16 35.56 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 144.78 36.83 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 144.78 36.83 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 144.78 34.29 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "3"
+ (uuid "d50078b6-7bef-4e4c-b467-dbd668630bbe")
+ )
+ (pin "14"
+ (uuid "4e78ef6c-f7e4-46ec-b201-9ccf8c14b21f")
+ )
+ (pin "13"
+ (uuid "5e6868a9-0b41-4501-a1dc-b96142b8ff36")
+ )
+ (pin "10"
+ (uuid "e9f7be73-3fa6-4f1d-9990-58fd54518be4")
+ )
+ (pin "12"
+ (uuid "cad2f34a-5226-4ba2-af59-99becddabbcb")
+ )
+ (pin "5"
+ (uuid "79c2704a-36ca-4763-ba23-c9cfbe5fc4b8")
+ )
+ (pin "1"
+ (uuid "6d1d593f-d5b7-4407-a251-ab19eb3aafaa")
+ )
+ (pin "15"
+ (uuid "d6ac221a-b9ce-4a22-a213-6756add4b1f9")
+ )
+ (pin "7"
+ (uuid "7c8a31b3-4e0e-4e6e-993c-bde7098d55f1")
+ )
+ (pin "11"
+ (uuid "fa50be9d-8a38-43e9-b2f6-383954ebeb85")
+ )
+ (pin "9"
+ (uuid "29d97b22-b8a3-4482-8f56-3b192e796de7")
+ )
+ (pin "8"
+ (uuid "91d8bf6b-3a32-4591-9784-dd2ea6ee4b88")
+ )
+ (pin "4"
+ (uuid "213b12e0-4566-4d8f-9e18-a454b355120a")
+ )
+ (pin "2"
+ (uuid "80fea78f-cc09-46e7-9abd-69e1d3db41e4")
+ )
+ (pin "6"
+ (uuid "d7cd1c5f-5ff9-4b0f-a568-d1b98b23ec40")
+ )
+ (pin "16"
+ (uuid "457c8dd0-d3dd-4a96-bcee-6cbac99e96fc")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "M1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Switch:SW_Push")
+ (at 111.76 46.99 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b259f8")
+ (property "Reference" "SW1"
+ (at 111.76 39.751 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Value" "Button"
+ (at 111.76 42.0878 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 111.76 41.91 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 111.76 41.91 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 111.76 46.99 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "560ce6b9-2827-4166-82e6-4e886207f817")
+ )
+ (pin "1"
+ (uuid "de1bed64-9f0c-450a-962b-a2ed617fdeec")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "SW1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Transistor_BJT:BC547")
+ (at 149.86 74.93 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b384d9")
+ (property "Reference" "Q1"
+ (at 154.7114 73.7616 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "BC547"
+ (at 154.7114 76.073 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline"
+ (at 154.94 76.835 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ (italic yes)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "http://www.fairchildsemi.com/ds/BC/BC547.pdf"
+ (at 149.86 74.93 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 149.86 74.93 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "21f67f15-ea3d-4bb6-b3d6-7246afe218d9")
+ )
+ (pin "3"
+ (uuid "495ba0b3-043f-44e2-9508-51d7eadbdafe")
+ )
+ (pin "1"
+ (uuid "1f08704d-714d-48ad-ac11-1c2c343e668a")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "Q1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 129.54 74.93 270)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b467c6")
+ (property "Reference" "R6"
+ (at 129.54 70.866 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "8k2"
+ (at 129.54 72.644 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 129.54 73.152 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 129.54 74.93 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 129.54 74.93 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "ee260cff-4103-433f-976a-02bec8c3bd14")
+ )
+ (pin "2"
+ (uuid "7b8f5491-b1ac-4f7a-b4ad-ea5956ad5ae7")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R6")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 62.23 78.74 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b780ab")
+ (property "Reference" "R2"
+ (at 63.5 77.724 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "7k5"
+ (at 63.5 80.01 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 60.452 78.74 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 62.23 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 62.23 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "a16fce3d-14df-4b67-be27-75ab1d21db09")
+ )
+ (pin "1"
+ (uuid "4ea8af4d-48bb-4816-82cb-f8341b77678e")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R2")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 62.23 49.53 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061b7dcc8")
+ (property "Reference" "R1"
+ (at 64.008 48.3616 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "39k"
+ (at 64.008 50.673 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 60.452 49.53 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 62.23 49.53 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 62.23 49.53 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "d8b6ead1-9a83-4f7b-9060-23fdae496f78")
+ )
+ (pin "2"
+ (uuid "0e4c9d89-147e-4ecf-b19a-da9ea433557a")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 77.47 49.53 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061c49556")
+ (property "Reference" "R9"
+ (at 72.39 48.514 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "4k7"
+ (at 72.39 50.8 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 75.692 49.53 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 77.47 49.53 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 77.47 49.53 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "5765e718-e535-4e33-97e1-250ddf2e640b")
+ )
+ (pin "2"
+ (uuid "9873149d-a81d-474e-ba0b-24225ca8a17d")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R9")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "BoilerControlModule-rescue:D_Small_ALT-Device")
+ (at 165.1 49.53 270)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "00000000-0000-0000-0000-000061ef2406")
+ (property "Reference" "D1"
+ (at 165.1 47.752 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "D_Small_ALT"
+ (at 166.8272 50.673 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ (property "Footprint" ""
+ (at 165.1 49.53 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 165.1 49.53 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 165.1 49.53 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "df2f69fb-4873-4e01-8433-a9a41c1b9c2f")
+ )
+ (pin "2"
+ (uuid "0b944660-5114-4939-963f-73382404cffa")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "D1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:C")
+ (at 57.15 78.74 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "5b56dc85-02d8-4f39-90ec-b6030a0c4d1b")
+ (property "Reference" "C1"
+ (at 57.404 76.454 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "100n"
+ (at 57.15 82.042 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 58.1152 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 57.15 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Unpolarized capacitor"
+ (at 57.15 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "5a447abc-542a-4a45-a4b2-22c69f2d1645")
+ )
+ (pin "1"
+ (uuid "c4e64a58-54e5-4658-99d3-47df4e5aa7e0")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "C1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 115.57 78.74 180)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "797ac7f6-e11a-4726-b189-b215b43d3664")
+ (property "Reference" "R12"
+ (at 118.618 77.724 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "470"
+ (at 119.126 80.01 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 117.348 78.74 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 115.57 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 115.57 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "63a0dad5-41d6-418a-a950-d882b0c80b53")
+ )
+ (pin "1"
+ (uuid "91d2ea74-996c-4215-99d3-735da60f9d27")
+ )
+ (instances
+ (project "BoilerControlModule"
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R12")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:R")
+ (at 116.84 40.64 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "b299ec57-c640-40b0-89f3-dc8cc725e992")
+ (property "Reference" "R3"
+ (at 117.856 39.37 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "1k5"
+ (at 117.094 44.45 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" ""
+ (at 115.062 40.64 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 116.84 40.64 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Resistor"
+ (at 116.84 40.64 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "9c241b2b-dc43-42b1-ad14-469acdd337ba")
+ )
+ (pin "2"
+ (uuid "10fc5700-be84-4fb0-a291-09274721f115")
+ )
+ (instances
+ (project ""
+ (path "/2cebea01-a9ab-4da4-addb-e9c778a0107c"
+ (reference "R3")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (sheet_instances
+ (path "/"
+ (page "1")
+ )
+ )
+)
diff --git a/HotWaterManager_Arduino_Minimalistic.svg b/HotWaterManager_Arduino_Minimalistic.svg
new file mode 100644
index 0000000..12f7792
--- /dev/null
+++ b/HotWaterManager_Arduino_Minimalistic.svg
@@ -0,0 +1,21008 @@
+
+
+
diff --git a/README.md b/README.md
index 6d7ffea..bc67089 100644
--- a/README.md
+++ b/README.md
@@ -1,42 +1,56 @@
-This is the open source version of the BoilerOptimizer as described at https://www.thefloatinglab.world/en/boilers.html
+This is the open source version of the [HotWaterManager](https://www.thefloatinglab.world/en/boilers.html).
-This BoilerOptimizer is intended for controlling the Boiler on sailboats, features are:
+This HotWaterManager is intended for controlling the HotWater system on sailboats, features are:
-- Uses the excess energy of the solar panels, once the batteries are fully charged, to heat the electric boiler
-- Can optionally be used to feed the boiler directly from the solar panels, so the heating element will be "modulated" with the available solar energy.
+- It can be build with an Arduino but also a customized circuit board ([ThermalOptimizer](https://git.thefloatinglab.world/TheFloatingLab/ThermalOptimizer)) is available.
+- Uses the excess energy of the solar panels, once the batteries are fully charged, to heat the Hot Water Tank.
- It will instantly switch off the heating element when a heavy consumer switches on (anchor winch etc).
-- Energy saving of 66% by heating up to 40°C instead of 60°C.
+- Energy saving of 66% by heating up to 40°C instead of 60°C, but when there is an ambundant of energy allowing the water to heat up to 90°C.
- Fast warmup mode to just "shower temperature" so you can take a shower for just 1/3th of the energy.
- Legionella prevention and warning, by periodically heating the water to a bacteria killing temperature or warning when it has been too long ago that this temperature could be reached.
-- Thermostatic control when connected to shore power
+- Can control a solenoid to switch off the hot water pressure after a configurable timer expires, to limit shower time and to reduce the chance of water leaks.
+- Thermostatic control when connected to shore power.
- Can optionally control a pump based on a differential temperature, so you can build your own "solar panel" consisting of nothing more than just a hose on deck and a small electric pump.
-- Guards the boiler against freezing
-- Automatic energy saving when it detects that the engine is running and coolant can be used to heat up the boiler.
-- Reliable voltage measurement with optional voltage reference inputs
-- LCD display with boiler temperature, trend, voltage and heater status
-- Fully configurable by an on screen menu
-- Switchable between degrees Celsius and Fahrenheit
+- Guards the hot water tank against freezing.
+- Automatic energy saving when it detects that the engine is running and coolant can be used to heat up the water.
+- LCD display with hot water temperature, trend, voltage and heater status.
+- Fully configurable by an on screen menu.
+- Low energy use when not activated.
+- Switchable between degrees Celsius and Fahrenheit, 12V and 24V systems.
-See for details and background https://www.thefloatinglab.world/en/boilers.html
+See for details and background [https://www.thefloatinglab.world/en/boilers.html](https://www.thefloatinglab.world/en/boilers.html)
-## Notes about the Boiler Optimizer Schematic
+## Notes about the schematics
-### Explanation of some less obvious parts
+### Explanation of the Arduino version
-- R1, R2 and R3 are used to bring the reference voltage into the window of the ADC's. R1 together with C1 also services as a *low pass filter* to filter out induction peaks. The function of R3 is to be able to measure GNDref voltages wich are slightly more *negative* than GND.
+- R1 and R2 are used to bring the reference voltage into the window of the ADC. R1 together with C1 also services as a *low pass filter* to filter out induction peaks.
+- R10, R11 and R12 are used to control the brightness of the LCD. With these 3 resistors there are 8 brightness levels possible. Brightness control could also be achieved with a single PWM output, but PWM is not available during microcontroller sleep.
+- Q1 controls the output relay which is used to switch the heater. The relay is not drawn on the schematic. One pin of the coil is connected to 12V (or 24V) and the other one to the transistor output.
+- Q2 controls the optional Hot Water Solenoid. The associated circuitry can be omitted if no Hot Water Solenoid is used.
+- Q3 controls the optional solar pump. The associated circuitry can be omitted if no solar pump is used.
### Components
- You can use an Aduino UNO (or clone) or an Arduino Pro Mini (5V, 32Kb). Some other variants probably will work too but you might have to change the PIN definitons in the software.
-- If you use an Arduino UNO, you can probably use its internal voltage regulator and ommit the 78L05. If you use an Arduino Pro Mini, you will definitely have to use the 78L05 like shown in the schematic.
-- For use on 24V systems, you will have to change R1 into 27K and R4 into 18K, and you will need a 78L05 voltage regulator even for the Arduino UNO. The current version of the software doesn't support 24V yet.
-- The relation between R1, R2 and R3 is important. If you change any of these values, you *MUST* change their definitions in the software too! You don't need high precision resistors; the software will be able to calibrate around small deviations.
-- Q1 and Q2 can be any NPN transistor, D1 and D2 are generic diodes.
-- The LCD is a generic 16x2 display (make sure it is a 5V version), you can use an I2C variant as well but then you have to adapt the schematic and uncomment the relevant definition in the software.
-- If you want to connect the solar panels directly to the boiler, you *MUST* use a solid state relay and wire everything exactly like shown in "Installation". A normal mechanical relay can not break a high voltage DC current; *it will arc and melt*! The mechanical relay in the minus is ok, the solid state relay in the plus will break the arc.
+- If you use an Arduino UNO, you can probably use its internal voltage regulator and ommit the 78L05. If you use an Arduino Pro Mini, you will definitely have to use the 78L05 like shown in the schematic. If you want to use 3.3V versions you will have to change some components (noticably the voltage dividers on the ADC's, and an LCD that can work at 3.3V) and change some calculations in the software.
+- For use on 24V systems, you will need a 78L05 voltage regulator even for the Arduino UNO. You also have to change the input resistor (R4) of the ENGINE input to 22k.
+- The relation between R1 and R2 is important. If you change any of these values, you *MUST* change their definitions in the software too! You don't need high precision resistors; the software will be able to calibrate around small deviations.
+- Q1, Q2 and Q3 can be any NPN transistor or N-channel MOSFET, D1, D2 and D3 are generic diodes.
+- The LCD is a generic 16x2 display (make sure it is a 5V version), you can use an I2C variant as well but then you have to free A5 (use one of the now vacant LCD ports) and adapt the software.
+- You can, in addition to the onboard LED, connect an external LED (with appropriate series resistor) to pin 13.
### Commissioning
-- The LCD might stay blank or black until the contrast pot has been tuned. It is best to test and adjust this before executing the software on the Arduino for the first time.
- Connect the temperature sensor(s). Perform a factory reset (will be done automatically if it is the first time the software runs) and the software will start pairing the sensor(s). If you use more than one sensor, you have to find out which one is for the boiler and which is for the solar panel. Some hot water will be handy with testing. ;-)
-- Connect the voltage reference inputs to the power supply (5V!) of the Arduino and reboot. This will automatically start the calibration. Once the calibration is completed, power down and connect the voltage reference inputs to 12V.
+
+## Changes from 1.0 to 1.1
+- The name was changed from BoilerOptimizer to HotWaterManager.
+- The system can still be built around an Arduino but a dedicated circuit board [ThermalOptimizer](https://git.thefloatinglab.world/thefloatinglab/thermaloptimizer) is also available.
+- Some IO ports in the Arduino version are changed to match the ports used in the dedicated "ThermalOptimizer" circuit board.
+- The contrast pot of the LCD is changed into a fixed resistor.
+- An additional output is now used to control an optional hot water solenoid.
+- To allow the microcontroller to go into sleep mode, the display brightness is no longer controlled by PWM but with 3 binary outputs to facilitate 8 brightness levels.
+- We no longer use a "reference voltage" but just use the power supply voltage.
+- Diodes D1, D2, and D3 are now connected in the right way.
+- The software has been significantly enhanced.
diff --git a/SchematicDiagram.png b/SchematicDiagram.png
deleted file mode 100644
index a964cfe..0000000
Binary files a/SchematicDiagram.png and /dev/null differ
diff --git a/boileroptimizer.ino b/boileroptimizer.ino
deleted file mode 100644
index 5dbbdd7..0000000
--- a/boileroptimizer.ino
+++ /dev/null
@@ -1,1096 +0,0 @@
-/* BoilerControl. See https://www.thefloatinglab.world/en/boilers.html for detailed description.
- * Copyright 2022 Frans Veldman (www.thefloatinglab.world)
- * Released under GNU General Public License v3.0
- *
- * Voltage measuring
- * =================
- * To get the reference voltage within the windows of the ADC's, we need to bring VCCref down to max 5V and we need to bring up GNDref to allow for "negative" GNDref deviations
- *
- * ADC1 ADC0
- * _______ | _______ | _______
- * VCCref --|_____|---|----|_____|---|---|_____|---- GNDref
- * R1 R2 R3
- *
- * The approximate ratio for the resistor divider is 10:3:1.5, like 10K, 3K3, 1K5, which loads the reference voltage supply with less than 1mA.
- * If we assume a maximum voltage of 15V, then this would give 4.86V on the input of ADC1 and 1,52V on the input of ADC0.
- * If we assume a scenario like a firm load on the bus (inverter?) so the voltage sags to 12V, with an additional loss of 0.5V on the negative lead of the power supply,
- * it would give 3.39V on ADC1 and 0.71V on ADC0 (remember in this scenario the ADC's get biased by the 0.5V "elevated" ADC GND).
- *
- * The math:
- * ((ADC1-ADC0)*AREF/1024+1) * (R1+R2+R3)/R2
- *
- * If we use option "NoRef" we just measure ADC1 against GND. The formula would then be:
- * ADC1*AREF/(1024+1) * (R1+R2+R3)/(R2+R3)
- *
- * For a 24V system, there should be a 15K resistor in series with R1.
- *
- */
-
-// Debug
-//#define SIMTEMP 300
-//#define USEDEFAULT
-
-// Electrical properties
-#define ADCREF 5000 // Voltage of the 5V power supply in millivolts
-#define R1 10000 // Ohms
-#define R2 3300 // Ohms
-#define R3 1500 // Ohms
-// Inputs
-#define BUTTON 2
-#define GNDREF A0
-#define VCCREF A1
-#define TEMP 6
-#define ENGINE 9
-// Outputs
-#define HEATER 13
-#define AUX 12
-#define BACKLIGHT 5
-// Interfaces
-// #define LCDADDR 0x3F // I2C address, uncomment for I2C display
-#define LCD_RS 10
-#define LCD_EN 11
-#define LCD_D4 3
-#define LCD_D5 4
-#define LCD_D6 7
-#define LCD_D7 8
-
-// Constants
-#define VERSION "1.0"
-#define EPROMCHK 0x7874
-#define SHORTPRESS 25 // Minimum time in milliseconds to register a button press as valid instead of just a noise spike.
-#define LONGPRESS 650 // Time in milliseconds to register a key press as a long press.
-#define DBLPRESS 500 // max milliseconds between keypresses to consider them double clicks.
-#define MENUTIMEOUT 10 // Timeout in seconds to return to default operation from within the menu.
-#define VSAMPLES 100 // Voltage samples to average to cancel out noise.
-
-// Defaults after factory reset (can be changed in the menu afterwards)
-#define BRIGHTNESS 4 // LCD backlight brightness
-#define DISPTIMEOUT 0 // LCD backlight timeout in seconds
-#define VREQ 141 // Required voltage*10 to switch on the heater automatically.
-#define VFLOAT 135 // Float voltage*10
-#define VOFF 125 // Voltage*10 at which a pause has to be initiated
-#define PAUSE 20 // Duration of the pause in minutes
-#define TMIN 40 // Antifreeze protection should be initiated below this temperature (Celsius*10)
-#define TTARGET 400 // Target temperature (Celsius*10) for daily usage
-#define TSANITY 600 // Temperature (Celsius*10) needed to clear the "sanity alert"
-#define TMAX 800 // Maximum allowed temperature (Celsius*10)
-#define TNOSAN 250 // Don't display a sanity alert below this temperature (Celsius*10)
-#define TSANDAYS 7 // Interval in days between reaching the "sanity temperature" to not raise the "sanity alert"
-#define PUMPDELTA 250 // Difference in input and boiler temperature in Celsius*10
-#define PUMPAFTERRUN 60 // Time in seconds to continue running the pump after PUMPDELTA is no longer met
-
-// Constants that are not configurable in the menu.
-#define RETARD 60 // Seconds to wait after last heater state change before switching it on again.
-#define VINTERVAL 500 // Display interval of voltage
-#define TRENDDELTA 3 // Temperature (Celsius*10) difference required to change the trend arrow
-
-struct rom_t {
- uint16_t epromchk; uint8_t brightness; uint8_t disptimeout; uint16_t vreq; uint16_t vfloat; uint16_t voff; int16_t pause; boolean fahrenheit; int16_t tmin; int16_t ttarget;
- int16_t tsanity; int16_t tmax; int16_t tsandays; int16_t tnosan; int16_t pumpdelta; boolean noref; uint16_t pumpafterrun; uint8_t pvdirect;
-} rom = {EPROMCHK,BRIGHTNESS,DISPTIMEOUT,VREQ,VFLOAT,VOFF,PAUSE,false,TMIN,TTARGET,TSANITY,TMAX,TSANDAYS,TNOSAN, PUMPDELTA, false, PUMPAFTERRUN, 0};
-
-struct sensors_t {
- uint16_t epromchk;
- uint8_t temphwa[2][8];
-} sensors = {EPROMCHK,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-
-struct cal_t {
- uint16_t epromchk;
- uint16_t calibration;
-} cal = {EPROMCHK,1000};
-
-
-struct mma_t {
- uint16_t samples;
- uint16_t avg;
- uint32_t sum;
-};
-
-struct tempdata_t {
- int16_t temperature;
- int16_t failures;
- int16_t fallback;
- mma_t mmaTemp;
-};
-
-tempdata_t tempdata[] = {{0,0,0,1000},{0,0,0,-1000}};
-
-
-struct button_t {
- const uint8_t button;
- uint32_t pressed; // Button press duration
- boolean longpressed;
-} button = {BUTTON,0,false};
-
-
-// menu code, 8 bits
-#define MENU_8 B00001000
-#define MENU_16 B00010000
-#define MENU_SIGNED B10000000
-#define MENU_FLOAT B00000011
-#define MENU_BOOLEAN B01000000
-#define MENU_TEMP B00000100
-
-
-struct menu_t {
- const char txt[17];
- const char sfx[13];
- const uint8_t code;
- const int16_t min;
- const uint16_t max;
- const uint16_t step;
- const void* varptr;
-};
-
-const menu_t PROGMEM menu[]= {
- {"LCD Brightness", "", MENU_8, 1, 8, 1, &rom.brightness},
- {"LCD TimeOut", " seconds", MENU_8, 0, 10, 1, &rom.disptimeout},
- {"Start Voltage", "V", MENU_16+1, 138, 148, 1, &rom.vreq},
- {"Float Voltage", "V", MENU_16+1, 125, 140, 1, &rom.vfloat},
- {"Abort Voltage", "V", MENU_16+1, 120, 135, 1, &rom.voff},
- {"Pause duration", " minutes", MENU_16+MENU_SIGNED, 5, 45, 5, &rom.pause},
- {"Fahrenheit", "", MENU_BOOLEAN, 0, 1, 1, &rom.fahrenheit},
- {"Min Temperature", "", MENU_16+MENU_SIGNED+MENU_TEMP+1, 0, 100, 10, &rom.tmin},
- {"Target Temp", "", MENU_16+MENU_SIGNED+MENU_TEMP+1, 340, 520, 20, &rom.ttarget},
- {"Max Temperature", "", MENU_16+MENU_SIGNED+MENU_TEMP+1, 600, 900, 50, &rom.tmax},
- {"Sanity Temp", "", MENU_16+MENU_SIGNED+MENU_TEMP+1, 560, 680, 20, &rom.tsanity},
- {"Sanity interval", " days", MENU_16+MENU_SIGNED, 2, 14, 1, &rom.tsandays},
- {"No Sanity below", "", MENU_16+MENU_SIGNED+MENU_TEMP+1, 200, 300, 10, &rom.tnosan},
- {"V Calibration", "", MENU_16, 920, 1080, 1, &cal.calibration},
- {"No Voltage Ref", "", MENU_BOOLEAN, 0, 1, 1, &rom.noref},
- {"Pump delta", "", MENU_16+MENU_SIGNED+MENU_TEMP+1, 0, 100, 5, &rom.pumpdelta},
- {"Pump afterrun", " seconds", MENU_16, 0, 300, 30, &rom.pumpafterrun},
- {"PV direct feed", "", MENU_8, 0, 2, 1, &rom.pvdirect},
- {NULL,0,0,0,0,NULL}
-};
-
-const char mode0[] PROGMEM = "Automatic";
-const char mode1[] PROGMEM = "Pause";
-const char mode2[] PROGMEM = "WarmUp";
-const char mode3[] PROGMEM = "Sanitize";
-const char mode4[] PROGMEM = "Thermostat";
-const char mode5[] PROGMEM = "AntiFreeze";
-const char mode6[] PROGMEM = "Heater On";
-const char mode7[] PROGMEM = "Pump on";
-const char mode8[] PROGMEM = "Off";
-const char mode9[] PROGMEM = "Setup";
-
-const char* const modes[] = {mode0,mode1,mode2,mode3,mode4,mode5,mode6,mode7,mode8,mode9,NULL};
-
-uint8_t mode=0;
-uint8_t menusel=0;
-boolean menuedit=false;
-int16_t lastTemperature=0;
-
-boolean lcdon=true;
-boolean romdirty=false;
-boolean paused=true;
-boolean restartTmrReq=true;
-
-uint32_t disptimer=0;
-uint32_t menuseltimer=0;
-uint32_t pauseTmr=0;
-uint32_t restartTmr=0;
-uint32_t pumpTimer=0;
-
-uint16_t rawVoltages[5];
-
-#ifdef LCDADDR
-// Libraries
-#include
-LiquidCrystal_I2C lcd(LCDADDR,16,2); // set the LCD address to LCDADDR for a 16 chars and 2 line display
-#else
-#include
-// initialize the library by associating any needed LCD interface pin
-// with the arduino pin number it is connected to
-LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
-#endif
-
-#include
-OneWire ds(TEMP); // Connect 1-wire devices
-
-
-void setup() {
- pinMode(BUTTON,INPUT_PULLUP);
- pinMode(ENGINE,INPUT_PULLUP);
- pinMode(HEATER,OUTPUT);
- pinMode(AUX,OUTPUT);
- pinMode(BACKLIGHT,OUTPUT);
-
- digitalWrite(HEATER,LOW);
- digitalWrite(AUX,LOW);
-
- pinMode(BACKLIGHT,OUTPUT);
- analogWrite(BACKLIGHT,(32*BRIGHTNESS)-1);
-
- bitSet (DIDR0, ADC2D); // disable digital buffer on A2
- bitSet (DIDR0, ADC3D); // disable digital buffer on A3
-
- initLCD();
-
- boolean resetpressed=false;
- uint32_t tmr=millis();
- while(millis()-tmr<3000) {
- if(!digitalRead(BUTTON))
- resetpressed=true;
- }
-
-#ifndef SIMTEMP
- // Read the sensor addresses
- eeprom_read_block((void*)&sensors, (void*)128, sizeof(sensors));
-
- // If the reset button is pressed and we already have sensor addresses, offer the user to reset the sensor addresses as well
- if(resetpressed && sensors.epromchk==EPROMCHK) {
- lcd.clear();
- lcd.print(F("Hold button to"));
- lcd.setCursor(0,1);
- lcd.print(F("reset sensors"));
- delay(5000);
- }
- lcd.clear();
-
- // Button still pressed or sensor addresses never initialized?
- if(!digitalRead(BUTTON) || sensors.epromchk!=EPROMCHK) {
- lcd.print(F("Sensors reset"));
- delay(2000);
- sensors.epromchk=EPROMCHK;
- searchSensors();
- if(!sensors.temphwa[0][0]) {
- lcd.print(F("no sensor found"));
- while(true);
- }
- eeprom_write_block((void*)&sensors, (void*)128, sizeof(sensors));
- }
-#endif
-
- // Setup sensors to measure temperatures
- ds.reset();
- ds.write(0xCC); // Skip command, next command is for all devices
- ds.write(0x44); // Temperature conversion
-
- // Read the calibration values and reset them if factory new
- eeprom_read_block((void*)&cal, (void*)196, sizeof(2));
- if(cal.epromchk!=EPROMCHK) {
- cal.epromchk=EPROMCHK;
-cal.calibration=1020;
- eeprom_write_block((void*)&cal, (void*)196, sizeof(cal));
- }
- eeprom_read_block((void*)&cal, (void*)196, sizeof(cal));
-
- // Read the configuration settings from ROM
- eeprom_read_block((void*)&rom, (void*)0, sizeof(2));
-
- // Reset key pressed or ROM not yet initialized?
- if(resetpressed || rom.epromchk!=EPROMCHK) {
- // Perform factory reset
- rom.epromchk=EPROMCHK;
- lcd.print(F("Hold button to"));
- lcd.setCursor(0,1);
- lcd.print(F("Factory Reset"));
- delay(5000);
- lcd.clear();
- if(!digitalRead(BUTTON))
- eeprom_write_block((void*)&rom, (void*)0, sizeof(rom));
- }
-
-#ifndef USEDEFAULT
- eeprom_read_block((void*)&rom, (void*)0, sizeof(rom)); // These are the configuration settings.
- analogWrite(BACKLIGHT,(32*rom.brightness)-1);
-#endif
-
- // Prime the Voltage median array
- for (int i = 0; i < 5; i++) {
- rawVoltages[i] = readvoltage(10);
- delay(15 + i * 10); // Use a non constant delay to avoid any pulsing loads to sync with the sampling frequency
- }
- // Collect some voltage samples
- for (int i = 0; i < VSAMPLES; i++)
- getvoltage();
-
- uint16_t voltage=getvoltage();
- // If it looks like the voltage is connected to the 5V power source, perform a calibration.
- // The 5V power source is used by the ADC as a reference (ADCREF), so this calibration works even if the 5V is not very precise.
- if(voltage<65 && voltage>35) {
- // We don't care about the exact values of the resistors, we only care about the ratio between (R1+R2+R3) and R2.
- lcd.clear();
- lcd.print(F("Calibrating..."));
- voltage=0;
- for(uint8_t i=0; i<10; i++) { // We need EXACTLY 10 samples, so we can compare the result directly against ADCREF which is in milliVolts.
- voltage+=readvoltage(1);
- delay(10*i);
- }
- // We now have the voltage, it should be 5000, the same as ADCREF.
- cal.calibration=(uint16_t)( ((1000L * (uint32_t)voltage) +(ADCREF/2) ) / ADCREF );
- lcd.setCursor(0,0);
- lcd.print(F("Calibration ok!"));
- delay(2000);
- if(digitalRead(BUTTON) && rom.epromchk==EPROMCHK)
- eeprom_write_block((void*)&cal, (void*)196, sizeof(cal));
- while(true) {
- lcd.setCursor(0,1);
- lcd.print("Value ");
- lcd.print(cal.calibration);
- lcd.print("=");
- lcd.print(((float)getvoltage())/10.0,1);
- lcd.print("V");
- delay(1000);
- }
- }
-
- // Prime the "history" of the temperature. Make sure we start with a downward trend
- delay(1500);
- lastTemperature=readtemp(0)+TRENDDELTA;
-}
-
-
-void loop() {
- int16_t butt=chkbutton(&button);
-
- // Deal with the LCD backlight
- if(butt) {
- // We had a keypress, reset LCD backlight timeout
- disptimer=seconds();
- // If the backlight was not on, turn it on now
- if(!lcdon) {
- analogWrite(BACKLIGHT,(32*rom.brightness)-1);
- lcdon=true;
- butt=0; // This keypress is "used up" to switch the LCD backlight on.
- }
- }
-
- if(butt) {
- menuseltimer=seconds();
- if(butt==2) {
- if(menusel) {
- if(menusel>=100) {
- menuedit=!menuedit;
- lcd.clear();
- printMenu(menusel-100,menuedit,rom.fahrenheit);
-#ifndef SIMTEMP
- if(!menuedit && romdirty) {
- eeprom_write_block((void*)&rom, (void*)0, sizeof(rom));
- eeprom_write_block((void*)&cal, (void*)196, sizeof(cal));
- }
-#endif
-
- } else {
- if(modes[menusel]==NULL) {
- menusel=99;
- butt=1;
- } else {
- paused=false;
- mode=menusel-1;
- menusel=0;
- lcd.clear();
- }
- }
- }
- }
- if(butt==1) {
- lcd.clear();
- if(menuedit) {
- romdirty=true;
- editItem(menusel-100);
- printMenu(menusel-100,menuedit,rom.fahrenheit);
- if(!(menusel-100))
- analogWrite(BACKLIGHT,(32*rom.brightness)-1);
- } else {
- menusel++;
- if(menusel>=100) {
- if(getPgmVal(menu[menusel-100].txt)==NULL)
- menusel=100;
- printMenu(menusel-100,menuedit,rom.fahrenheit);
- } else {
- if(modes[menusel-1]==NULL)
- menusel=1;
-
- lcd.print("> ");
- pgmLcdPrint(modes[menusel-1]);
- lcd.setCursor(0,1);
- lcd.print(F("LongPress=Select"));
- }
- }
- }
- } else {
- if(menusel==113) {
- lcd.setCursor(11,1);
- lcd.print((float)getvoltage()/10.0,1);
- lcd.write('V');
- }
- if(menusel && seconds()-menuseltimer>(MENUTIMEOUT)) {
- menusel=0;
- menuedit=false;
- romdirty=false;
- lcd.clear();
- }
- if(!menusel) {
- processmodes();
- }
- }
-}
-
-
-void processmodes() {
- uint16_t voltage=getvoltage();
- static int16_t LCDvoltage;
- static uint32_t vfreq;
-
- // Did the display backlight timeout?
- if(lcdon && rom.disptimeout && seconds()-disptimer>rom.disptimeout) {
- lcdon=false;
- analogWrite(BACKLIGHT,0);
- }
-
- // Change the value displayed on the LCD only twice per second
- if(!LCDvoltage || millis()-vfreq>VINTERVAL) {
- LCDvoltage=voltage;
- vfreq=millis();
- }
-
- lcd.setCursor(0,0);
- lcd.print(F("Boiler "));
- printTemperature(readtemp(0),1,rom.fahrenheit);
- if(readtemp(0)<100)
- lcd.write(' ');
-
- lcd.setCursor(0,1);
- pgmLcdPrint(modes[mode]);
-
- lcd.setCursor(11,1);
- lcd.print(((float)LCDvoltage)/10.0,1);
- lcd.print("V");
-
- // Update the temperature trend arrow
- lcd.setCursor(13,0);
- if(readtemp(0)-lastTemperature>=TRENDDELTA) {
- lcd.write(6);
- lastTemperature=readtemp(0);
- } else
- if(lastTemperature-readtemp(0)>=TRENDDELTA) {
- lcd.write(5);
- lastTemperature=readtemp(0);
- }
-
- lcd.setCursor(14,0);
- if(sanitycheck())
- lcd.write(4);
- else
- lcd.write(' ');
-
- lcd.setCursor(15,0);
- if(!mode && !digitalRead(ENGINE))
- lcd.write(1);
- else
- if(!mode && rom.pvdirect && digitalRead(AUX))
- lcd.write(2);
- else
- if(paused)
- lcd.write(7);
- else
- if(digitalRead(HEATER))
- lcd.write(3);
- else
- lcd.write(' ');
-
- // If the voltage is below the float voltage, note it, so for automatic mode we need to restart the timer
- if(voltagerom.tmax) {
- boilerState(false);
- pumpState(LOW);
- return; // Nothing else needs to be done.
- }
-
- // If voltage below the lower threshold, pause whatever program is running
- if(voltage=rom.vreq) {
- // Did we already start the countdown?
- if(!pauseTmr) {
- pauseTmr=seconds();
- } else {
- // Did the timer expire?
- if(seconds()-pauseTmr>rom.pause*60L) {
- paused=false;
- if(mode==1) // If the pause mode was manually selected...
- mode=0; // ... reset it to automatic mode
- } else {
- // Nope, we still need to pause
- boilerState(false);
- // Do not return, maybe solar can still input some heat
- }
- }
- }
- }
-
- // We've handled all hard limits, now look at the modes
-
- // If mode is OFF, shut down everything, we are finished.
- if(mode==8) {
- boilerState(false);
- pumpState(LOW);
- return; // No further actions required.
- }
-
- // Is mode is PUMP, keep on the pump.
- if(mode==7) {
- pumpState(HIGH);
- return;
- }
-
- // If we have a solar pump, is there a worthwile temperature difference between solarpanel and boiler?
- if(readtemp(1)-readtemp(0)>rom.pumpdelta) {
- pumpState(HIGH);
- boilerState(false);
- pumpTimer=seconds();
- return; // We are warming the boiler, as long as we can do that no electricity is needed, skip the rest.
- } else {
- if(seconds()-pumpTimer>rom.pumpafterrun)
- pumpState(LOW);
- }
-
- if(paused) {
- boilerState(false);
- return;
- }
-
- // If program=ON, just keep the boiler on. Overtemp and pause is already dealt with above.
- if(mode==6) {
- boilerState(true);
- return;
- }
-
- // If program is WarmUp, set/keep the boiler on when Trom.ttarget) {
- if(sanitycheck()) {
- holdoff=2; // We are due to run a sanity cycle, so let's try to reach it with moderate conservatism
- } else {
- holdoff=5; // Sanity cycle is not due, so let's not try too hard to get the temperature up to the sanity level
- if(rom.pvdirect==1)
- usePVdirect=true; // PVdirect option 1, so use "PV direct"
- }
- }
-
- if(rom.pvdirect>=2)
- usePVdirect=true; // PVdirect option 2, always use "PV direct" in automatic mode
-
- // Did we reach the sanity temperature?
- if(readtemp(0)>rom.tsanity)
- holdoff=10; // We just heat the water further but only if we are otherwise waisting available energy.
-
- // Now we need to see how long ago we reached (again) VREQ. Can we already start?
- if(seconds()-restartTmr>holdoff*60L)
- _boilerState(true,usePVdirect);
-
- return;
- }
-
- // If we arrive here, the boiler is on. Do we want to keep it that way?
-
- // If boiler is on but we get under the float voltage, switch it off
- if(voltageRETARD*1000L) {
- if(pvdirect) {
- digitalWrite(HEATER,LOW);
- if(digitalRead(AUX)!=state) {
- delay(20);
- lastChange=millis();
- digitalWrite(AUX,state);
- }
- } else {
- digitalWrite(AUX,LOW);
- if(digitalRead(HEATER)!=state) {
- delay(20);
- lastChange=millis();
- digitalWrite(HEATER,state);
- }
- }
- }
-}
-
-
-void pumpState(boolean state) {
- if(rom.pvdirect)
- return;
- digitalWrite(AUX,state);
-}
-
-
-// This routine will keep track whether there is a legionella chance
-boolean sanitycheck() {
- static boolean sancounting=false;
- static boolean keepalarm=false; // Prevent the alarm switching off after timer rollover
- static uint32_t santotal=0;
- static uint32_t sancount=0x80000000;
-
- if(readtemp(0)>=rom.tsanity) {
- // The temperature in boiler is high enough to kill legionella, so clear all alarms.
- santotal=0;
- sancounting=false;
- keepalarm=false;
- } else {
- if(readtemp(0)>rom.tnosan) {
- if(!sancounting) {
- sancounting=true;
- sancount=seconds();
- }
- if(santotal+(seconds()-sancount)>((uint32_t)rom.tsandays)*60L*60L*24L) {
- keepalarm=true;
- }
- } else {
- if(sancounting) {
- sancounting=false;
- santotal+=(seconds()-sancount);
- }
- }
- }
- return keepalarm;
-}
-
-
-void printMenu(uint8_t item, boolean edit, boolean fahrenheit) {
- uint8_t code = getPgmVal(&menu[item].code);
- uint16_t value = getRomValue(code,item);
-
- if(!edit)
- lcd.write('>');
- pgmLcdPrint(menu[item].txt);
- lcd.setCursor(0,1);
- if(edit)
- lcd.print("> ");
-
- if(code & (MENU_8 | MENU_16)) {
- if(code & MENU_FLOAT)
- if(code & MENU_TEMP)
- printTemperature(value,0,fahrenheit);
- else
- lcd.print((float) ((float)value/pow(10.0,(float)(code & MENU_FLOAT))), code & MENU_FLOAT);
- else
- if(code & MENU_SIGNED)
- lcd.print((int)value);
- else
- lcd.print(value);
- }
-
- if(code & MENU_BOOLEAN)
- if(value)
- lcd.print("Yes");
- else
- lcd.print("No ");
-}
-
-
-uint16_t getRomValue(uint8_t code, uint8_t item) {
- if(code & (MENU_8 | MENU_BOOLEAN)) {
- if(code & MENU_SIGNED)
- return (uint16_t)((int16_t)*((int8_t *)pgm_read_word(&menu[item].varptr)));
- else
- return (uint16_t)*((uint8_t *)pgm_read_word(&menu[item].varptr));
- }
-
- if(code & MENU_16)
- return (uint16_t *)*((uint16_t *)pgm_read_word(&menu[item].varptr));
-}
-
-
-void editItem(uint8_t item) {
- uint8_t code = getPgmVal(&menu[item].code);
- uint16_t value = getRomValue(code,item);
-
- value+=getPgmVal(&menu[item].step);
- value-=value%getPgmVal(&menu[item].step);
- if(value>getPgmVal(&menu[item].max) || value10)
- // Too many failures, start returning a "safe" but unusual value.
- return tempdata[sensor].fallback;
-
- return tempdata[sensor].temperature;
-}
-
-
-void searchSensors() {
- uint8_t owaddr[8];
- uint8_t sensor=0;
-
- sensors.temphwa[0][0]=0;
- sensors.temphwa[1][0]=0;
-
- ds.reset();
- while(ds.search(owaddr) && sensor<2) {
- // We have found a one-wire device. Is it a temperature sensor and is the data valid?
- if(owaddr[0]==0x28 && OneWire::crc8( owaddr, 7) == owaddr[7]) {
- // Seems to be ok. So copy this hardware address
- for(uint8_t i=0;i<8;i++)
- sensors.temphwa[sensor][i]=owaddr[i];
- // Now we have it, configure the sensor
- ds.reset();
- ds.select(sensors.temphwa[sensor]);
- ds.write(0x4E); // Write scratchpad command
- ds.write(0); // TL data
- ds.write(0); // TH data
- ds.write(0x7F); // Configuration Register (resolution) 7F=12bits 5F=11bits 3F=10bits 1F=9bits
- ds.reset(); // This "reset" sequence is mandatory, it allows the DS18B20 to understand the copy scratchpad to EEPROM command
- ds.select(sensors.temphwa[sensor]);
- ds.write(0x48); // Copy Scratchpad command
- sensor++;
- ds.reset();
- }
- }
-}
-
-
-int16_t getPgmVal(const int16_t *ptr) {
- return pgm_read_word(ptr);
-}
-
-uint16_t getPgmVal(const uint16_t *ptr) {
- return pgm_read_word(ptr);
-}
-
-char getPgmVal(const char *ptr) {
- return pgm_read_byte(ptr);
-}
-
-byte getPgmVal(const byte *ptr) {
- return pgm_read_byte(ptr);
-}
-
-// Prints a string from flash memory
-const char* pgmLcdPrint(const char *txt) {
- char c=pgm_read_byte_near(txt);
- while(c) {
- lcd.write(c);
- txt++;
- c=pgm_read_byte_near(txt);
- }
- txt++;
- return txt;
-}
-
-
-void printTemperature(int16_t value,uint8_t precision, boolean fahrenheit) {
- if(fahrenheit) {
- lcd.print(((float)value*0.18)+32.0,precision);
- lcd.print("\xDF""F");
- } else {
- lcd.print((float)value/10.0,precision);
- lcd.print("\xDF""C");
- }
-}
-
-
-void initLCD() {
- // Special characters for LCD
- uint8_t Anchor[8] = {0b00100,0b01010,0b00100,0b00100,0b00100,0b10101,0b01110,0b00000};
- uint8_t Sailing[8] = {0b00010,0b00110,0b01111,0b01111,0b11111,0b00010,0b11111,0b01110};
- uint8_t solar[8] = { B11111, B11111, B01110, B00000, B10101, B10101, B10101, B00000};
- uint8_t legion[8] = { B01010, B01010, B01010, B01000, B01010, B01000, B01111, B00000};
- uint8_t down[8] = { B00100, B00100, B00100, B00100, B10101, B01110, B00100, B00000};
- uint8_t up[8] = { B00100, B01110, B10101, B00100, B00100, B00100, B00100, B00000};
- uint8_t lightning[8]={ B00011, B00110, B01100, B11110, B00110, B01100, B01000, B10000};
- uint8_t Tmr[8] = { B00000, B01110, B10101, B10111, B10001, B01110, B00000, B00000};
- uint8_t engine[8] = { B00000, B01111, B00100, B01111, B11111, B01111, B00000, B00000};
-
-#ifdef LCDADDR
- lcd.begin();
-#else
- lcd.begin(16, 2);
-#endif
- lcd.createChar(1, Anchor);
- lcd.createChar(2, Sailing);
-
- delay(100);
-
- for(int offset=0;offset<6;offset++) {
- lcd.setCursor(offset,0);
- lcd.print(" ");
- lcd.write((uint8_t)2);
- delay(400);
- }
- delay(800);
- lcd.setCursor(6,1);
- lcd.write((uint8_t)1);
- delay(1000);
-
- lcd.clear();
- lcd.print(F("BoilerControl" VERSION));
- lcd.setCursor(0,1);
- lcd.print(F("by Frans Veldman"));
-
- lcd.createChar(1, engine);
- lcd.createChar(2, solar);
- lcd.createChar(3, lightning);
- lcd.createChar(4, legion);
- lcd.createChar(5, down);
- lcd.createChar(6, up);
- lcd.createChar(7, Tmr);
-}
-
-
-uint32_t seconds() {
- static uint32_t secs=0;
- static uint32_t prevmillis=0;
-
- uint32_t dsecs=(millis()-prevmillis)/1000L;
- if(dsecs) {
- secs+=dsecs;
- prevmillis+=dsecs*1000L;
- }
- return secs;
-}
-
-
-// This function handles the button functionality. Button presses are separated into long, short and double clicks presses.
-int chkbutton(struct button_t* button) {
- if(digitalRead(button->button)==LOW) { // button pressed
- if(button->pressed==0)
- button->pressed=millis();
- if(millis()-button->pressed>=LONGPRESS) {
- if(!button->longpressed) {
- button->longpressed=true;
- return 2;
- }
- }
- return 0;
- } else { // button released
- if(button->longpressed) {
- button->longpressed=false;
- button->pressed=0;
- }
- if(button->pressed==0)
- return 0;
- unsigned long pressed=millis()-button->pressed;
- button->pressed=0;
- if(pressedsamplessamples++; // This is going to be an additional sample
- else
- mma->sum-=mma->avg; // Max amount of samples reached, substract average to make room for new value
- mma->sum+=val;
- mma->avg=(uint16_t)((mma->sum+(mma->samples>>1))/mma->samples);
- return mma->avg;
-}
-
-// ******** Routines to find the median in an array of 5 values *********
-
-// Trick using XOR to swap two variables
-#define swap(a,b) a ^= b; b ^= a; a ^= b;
-#define sort(a,b) if(a>b){ swap(a,b); }
-
-// http://cs.engr.uky.edu/~lewis/essays/algorithms/sortnets/sort-net.html
-// Median could be computed two less steps...
-uint16_t median(uint16_t a, uint16_t b, uint16_t c, uint16_t d, uint16_t e) {
- sort(a, b);
- sort(d, e);
- sort(a, c);
- sort(b, c);
- sort(a, d);
- sort(c, d);
- sort(b, e);
- sort(b, c);
- // this last one is obviously unnecessary for the median
- //sort(d,e);
-
- return c;
-}
-
-uint16_t medianp(uint16_t values[5]) {
- return median(values[0], values[1], values[2], values[3], values[4]);
-}