Showing preview only (389K chars total). Download the full file or copy to clipboard to get everything.
Repository: vojtamolda/homebridge-bluetooth
Branch: master
Commit: fa3c44748900
Files: 65
Total size: 369.6 KB
Directory structure:
gitextract_nhq2hgc9/
├── config.json
├── examples/
│ ├── humidity/
│ │ ├── arduino101/
│ │ │ ├── Si7021.cpp
│ │ │ ├── Si7021.h
│ │ │ ├── arduino101.fzz
│ │ │ └── arduino101.ino
│ │ ├── bluefruit/
│ │ │ ├── Si7021.cpp
│ │ │ ├── Si7021.h
│ │ │ ├── bluefruit.fzz
│ │ │ └── bluefruit.ino
│ │ ├── config.json
│ │ ├── images/
│ │ │ └── humidity.psd
│ │ └── readme.md
│ ├── lightbulb/
│ │ ├── arduino101/
│ │ │ ├── arduino101.fzz
│ │ │ └── arduino101.ino
│ │ ├── config.json
│ │ ├── images/
│ │ │ └── lightbulb.psd
│ │ └── readme.md
│ ├── lightbulb-rgb/
│ │ ├── arduino101/
│ │ │ ├── arduino101.fzz
│ │ │ └── arduino101.ino
│ │ ├── config.json
│ │ ├── images/
│ │ │ └── lightbulb-rgb.psd
│ │ └── readme.md
│ ├── lock/
│ │ ├── arduino101/
│ │ │ ├── arduino101.ino
│ │ │ ├── arduino101.sch
│ │ │ ├── dummy/
│ │ │ │ └── dummy.ino
│ │ │ ├── lock.cpp
│ │ │ ├── lock.h
│ │ │ ├── motor.cpp
│ │ │ ├── motor.h
│ │ │ ├── sensor.cpp
│ │ │ └── sensor.h
│ │ ├── config.json
│ │ ├── images/
│ │ │ └── lock.psd
│ │ ├── readme.md
│ │ └── rfduino/
│ │ ├── lock.cpp
│ │ ├── lock.h
│ │ ├── motor.cpp
│ │ ├── motor.h
│ │ ├── rfduino.ino
│ │ ├── rfduino.sch
│ │ ├── sensor.cpp
│ │ └── sensor.h
│ ├── readme.md
│ ├── switch/
│ │ ├── arduino101/
│ │ │ ├── arduino101.fzz
│ │ │ └── arduino101.ino
│ │ ├── config.json
│ │ ├── images/
│ │ │ └── switch.psd
│ │ └── readme.md
│ └── thermometer/
│ ├── arduino101/
│ │ ├── arduino101.fzz
│ │ └── arduino101.ino
│ ├── bluefruit/
│ │ ├── bluefruit.fzz
│ │ └── bluefruit.ino
│ ├── config.json
│ ├── images/
│ │ └── thermometer.psd
│ └── readme.md
├── images/
│ ├── examples.psd
│ └── overview.psd
├── index.js
├── license.txt
├── package.json
├── readme.md
└── source/
├── accessory.js
├── characteristic.js
├── platform.js
└── service.js
================================================
FILE CONTENTS
================================================
================================================
FILE: config.json
================================================
{
"bridge": {
"name": "Raspberry Pi 3",
"username": "CC:22:3D:E3:CE:30",
"port": 51826,
"pin": "031-45-154"
},
"description": "Raspberry Pi 3 Homebridge-Bluetooth Example",
"platforms": [
{
"platform": "Bluetooth",
"accessories": [
{
"name": "Arduino 101",
"name_note": "Name of the accessory as shown in the Home app on iOS.",
"address": "01:23:45:67:89:AB",
"address_note": "Bluetooth address of the accessory. Non-matching devices are ignored.",
"services": [
{
"name": "LED 13",
"name_note": "Name of the service as shown in the Home app on iOS.",
"type": "Lightbulb",
"type_note1": "Type of the service - i.e. Lightbulb, Switch, Lock, HumiditySensor, ...",
"type_note2": "Must match this list - https://github.com/KhaosT/HAP-NodeJS/blob/master/lib/gen/HomeKitTypes.js",
"type_note3": "Service.Lightbulb has a mandatory On characteristic and Brightness, Hue and Saturation are optional.",
"UUID": "A7B10010-EEEE-5377-FF6C-D104768A1214",
"UUID_note": "Bluetooth UUID of the service. Capitalization and dashes doesn't matter.",
"characteristics": [
{
"type": "On",
"type_note1": "Type of the characteristic - i.e. On, Brightness, CurrentHumidity, CurrentTemperature, ...",
"type_note2": "Must match this list - https://github.com/KhaosT/HAP-NodeJS/blob/master/lib/gen/HomeKitTypes.js",
"type_note3": "Characteristic.On is a BOOL value and expects READ, WRITE and NOTIFY permissions.",
"UUID": "A7B10010-EEEE-5377-FF6C-D104768A1214",
"UUID_note": "Bluetooth UUID of the characteristic. Capitalization and dashes doesn't matter."
},
{
"type": "Brightness",
"type_note1": "Type of the characteristic - i.e. On, Brightness, CurrentHumidity, CurrentTemperature, ...",
"type_note2": "Must match this list - https://github.com/KhaosT/HAP-NodeJS/blob/master/lib/gen/HomeKitTypes.js",
"type_note3": "Characteristic.Brightness is an INT value and expects READ, WRITE and NOTIFY permissions.",
"UUID": "A7B10012-EEEE-5377-FF6C-D104768A1214",
"UUID_note": "Bluetooth UUID of the characteristic. Capitalization and dashes doesn't matter."
}
],
"characteristics_note1": "List of Bluetooth characteristics that will be exposed to HomeKit.",
"characteristics_note2": "Characteristics with non-matching UUIDs are ignored."
}
],
"services_note1": "List of Bluetooth services that will be exposed to HomeKit.",
"services_note2": "Services with non-matching UUIDs are ignored."
}
]
}
]
}
================================================
FILE: examples/humidity/arduino101/Si7021.cpp
================================================
/**************************************************************************
@file Si7021.cpp
@author Limor Fried (Adafruit Industries), Vojta Molda
@license BSD (see license.txt)
This is a library for the Adafruit Si7021 breakout board
----> https://www.adafruit.com/products/3251
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
@section HISTORY
v1.0 - First release
v1.1 - Modified to use <SoftWire.h>
**************************************************************************/
#include "Si7021.h"
Si7021::Si7021(SoftwareWire& Wire_) :
sernum_a(0), sernum_b(0), Wire(Wire_)
{ }
bool Si7021::begin(void) {
Wire.begin();
reset();
if (readRegister8(Si7021::Cmd.READRHT_REG) != 0x3A) return false;
readSerialNumber();
return true;
}
float Si7021::readHumidity(void) {
Wire.beginTransmission(Si7021::Cmd.ADDRESS);
Wire.write(Si7021::Cmd.MEASRH_NOHOLD);
Wire.endTransmission(false);
delay(25);
Wire.requestFrom(Si7021::Cmd.ADDRESS, (uint8_t)3);
uint16_t hum = Wire.read();
hum <<= 8;
hum |= Wire.read();
uint8_t chxsum = Wire.read();
float humidity = hum;
humidity *= 125;
humidity /= 65536;
humidity -= 6;
return humidity;
}
float Si7021::readTemperature(void) {
Wire.beginTransmission(Si7021::Cmd.ADDRESS);
Wire.write(Si7021::Cmd.MEASTEMP_NOHOLD);
Wire.endTransmission(false);
delay(25);
Wire.requestFrom(Si7021::Cmd.ADDRESS, (uint8_t)3);
uint16_t temp = Wire.read();
temp <<= 8;
temp |= Wire.read();
uint8_t chxsum = Wire.read();
float temperature = temp;
temperature *= 175.72;
temperature /= 65536;
temperature -= 46.85;
return temperature;
}
void Si7021::reset(void) {
Wire.beginTransmission(Si7021::Cmd.ADDRESS);
Wire.write(Si7021::Cmd.RESET);
Wire.endTransmission();
delay(50);
}
void Si7021::readSerialNumber(void) {
Wire.beginTransmission(Si7021::Cmd.ADDRESS);
Wire.write(Si7021::Cmd.ID1 >> 8);
Wire.write(Si7021::Cmd.ID1 & 0xFF);
Wire.endTransmission();
Wire.requestFrom(Si7021::Cmd.ADDRESS, (uint8_t)8);
sernum_a = Wire.read();
Wire.read();
sernum_a <<= 8;
sernum_a |= Wire.read();
Wire.read();
sernum_a <<= 8;
sernum_a |= Wire.read();
Wire.read();
sernum_a <<= 8;
sernum_a |= Wire.read();
Wire.read();
Wire.beginTransmission(Si7021::Cmd.ADDRESS);
Wire.write(Si7021::Cmd.ID2 >> 8);
Wire.write(Si7021::Cmd.ID2 & 0xFF);
Wire.endTransmission();
Wire.requestFrom(Si7021::Cmd.ADDRESS, (uint8_t)8);
sernum_b = Wire.read();
Wire.read();
sernum_b <<= 8;
sernum_b |= Wire.read();
Wire.read();
sernum_b <<= 8;
sernum_b |= Wire.read();
Wire.read();
sernum_b <<= 8;
sernum_b |= Wire.read();
Wire.read();
}
void Si7021::writeRegister8(uint8_t reg, uint8_t value) {
Wire.beginTransmission(Si7021::Cmd.ADDRESS);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}
uint8_t Si7021::readRegister8(uint8_t reg) {
uint8_t value;
Wire.beginTransmission(Si7021::Cmd.ADDRESS);
Wire.write(reg);
Wire.endTransmission(false);
Wire.requestFrom(Si7021::Cmd.ADDRESS, (uint8_t)1);
value = Wire.read();
return value;
}
uint16_t Si7021::readRegister16(uint8_t reg) {
uint16_t value;
Wire.beginTransmission(Si7021::Cmd.ADDRESS);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(Si7021::Cmd.ADDRESS, (uint8_t)2);
value = Wire.read();
value <<= 8;
value |= Wire.read();
return value;
}
================================================
FILE: examples/humidity/arduino101/Si7021.h
================================================
#ifndef _SI7021_H_
#define _SI7021_H_
/**************************************************************************
@file Si7021.cpp
@author Limor Fried (Adafruit Industries), Vojta Molda
@license BSD (see license.txt)
This is a library for the Adafruit Si7021 breakout board
----> https://www.adafruit.com/products/3251
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
@section HISTORY
v1.0 - First release
v1.1 - Modified to use <SoftWire.h>
**************************************************************************/
#include <Arduino.h>
#include <SoftwareWire.h>
class Si7021 {
public:
Si7021(SoftwareWire& Wire_);
bool begin(void);
void reset(void);
void readSerialNumber(void);
float readTemperature(void);
float readHumidity(void);
uint32_t sernum_a, sernum_b;
private:
uint8_t readRegister8(uint8_t reg);
uint16_t readRegister16(uint8_t reg);
void writeRegister8(uint8_t reg, uint8_t value);
SoftwareWire& Wire;
const static struct WireCommands {
static const uint8_t ADDRESS = 0x40;
static const uint8_t MEASRH_HOLD = 0xE5;
static const uint8_t MEASRH_NOHOLD = 0xF5;
static const uint8_t MEASTEMP_HOLD = 0xE3;
static const uint8_t MEASTEMP_NOHOLD = 0xF3;
static const uint8_t READPREVTEMP = 0xE0;
static const uint8_t RESET = 0xFE;
static const uint8_t WRITERHT_REG = 0xE6;
static const uint8_t READRHT_REG = 0xE7;
static const uint8_t WRITEHEATER_REG = 0x51;
static const uint8_t READHEATER_REG = 0x11;
static const uint16_t ID1 = 0xFA0F;
static const uint16_t ID2 = 0xFCC9;
static const uint16_t FIRMVERS = 0x84B8;
} Cmd;
};
#endif
================================================
FILE: examples/humidity/arduino101/arduino101.ino
================================================
#include <Arduino.h>
#include <CurieBLE.h>
#include <SoftwareWire.h>
#include "Si7021.h"
static struct BoardPins {
const uint8_t VIN = A0;
const uint8_t VO3 = A1;
const uint8_t GND = A2;
const uint8_t SCL = A3;
const uint8_t SDA = A4;
} Pin;
SoftwareWire wire = SoftwareWire(Pin.SDA, Pin.SCL);
Si7021 sensor = Si7021(wire);
BLEPeripheral ble;
BLEService informationService("180A");
BLECharacteristic modelCharacteristic("2A24", BLERead, "101");
BLECharacteristic manufacturerCharacteristic("2A29", BLERead, "Arduino");
BLECharacteristic serialNumberCharacteristic("2A25", BLERead, "2.71828");
BLEService humidityService("10525F60-CF73-11E6-9598-F8E2251C9A69");
BLEFloatCharacteristic humidityCharacteristic("10525F61-CF73-11E6-9598-F8E2251C9A69", BLERead | BLENotify);
BLEService thermometerService("F489CB00-C177-11E6-9598-9854249C9A66");
BLEFloatCharacteristic temperatureCharacteristic("F489CB01-C177-11E6-9598-9854249C9A66", BLERead | BLENotify);
void setup() {
Serial.begin(115200);
pinMode(Pin.VIN, OUTPUT);
digitalWrite(Pin.VIN, HIGH);
pinMode(Pin.GND, OUTPUT);
digitalWrite(Pin.GND, LOW);
sensor.begin();
ble.setLocalName("Humidity");
ble.setAdvertisedServiceUuid(thermometerService.uuid());
ble.addAttribute(informationService);
ble.addAttribute(modelCharacteristic);
ble.addAttribute(manufacturerCharacteristic);
ble.addAttribute(serialNumberCharacteristic);
ble.addAttribute(humidityService);
ble.addAttribute(humidityCharacteristic);
humidityCharacteristic.setValueLE(0.0);
ble.addAttribute(thermometerService);
ble.addAttribute(temperatureCharacteristic);
temperatureCharacteristic.setValueLE(0.0);
ble.setEventHandler(BLEConnected, centralConnect);
ble.setEventHandler(BLEDisconnected, centralDisconnect);
ble.begin();
Serial.println("Bluetooth on");
}
void loop() {
ble.poll();
static float averageHumidity = sensor.readHumidity();
averageHumidity += (sensor.readTemperature() - averageHumidity) / 30.0;
float previousHumidity = humidityCharacteristic.valueLE();
if (abs(averageHumidity - previousHumidity) > 1.50) {
humidityCharacteristic.setValueLE(averageHumidity);
Serial.print("Update temperature | ");
Serial.println(averageHumidity, 0);
} else {
Serial.print("Temperature | ");
Serial.println(averageHumidity, 0);
}
static float averageCelsius = sensor.readTemperature();
averageCelsius += (sensor.readTemperature() - averageCelsius) / 30.0;
float previousCelsius = temperatureCharacteristic.valueLE();
if (abs(averageCelsius - previousCelsius) > 0.20) {
temperatureCharacteristic.setValueLE(averageCelsius);
Serial.print("Update temperature | ");
Serial.println(averageCelsius, 2);
} else {
Serial.print("Temperature | ");
Serial.println(averageCelsius, 2);
}
delay(1000);
}
void centralConnect(BLECentral& central) {
Serial.print("Central connected | ");
Serial.println(central.address());
}
void centralDisconnect(BLECentral& central) {
Serial.print("Central disconnected | ");
Serial.println(central.address());
}
================================================
FILE: examples/humidity/bluefruit/Si7021.cpp
================================================
/**************************************************************************
@file Si7021.cpp
@author Limor Fried (Adafruit Industries), Vojta Molda
@license BSD (see license.txt)
This is a library for the Adafruit Si7021 breakout board
----> https://www.adafruit.com/products/3251
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
@section HISTORY
v1.0 - First release
v1.1 - Modified to use <SoftWire.h>
**************************************************************************/
#include "Si7021.h"
Si7021::Si7021(SoftwareWire& Wire_) :
sernum_a(0), sernum_b(0), Wire(Wire_)
{ }
bool Si7021::begin(void) {
Wire.begin();
reset();
if (readRegister8(Si7021::Cmd.READRHT_REG) != 0x3A) return false;
readSerialNumber();
return true;
}
float Si7021::readHumidity(void) {
Wire.beginTransmission(Si7021::Cmd.ADDRESS);
Wire.write(Si7021::Cmd.MEASRH_NOHOLD);
Wire.endTransmission(false);
delay(25);
Wire.requestFrom(Si7021::Cmd.ADDRESS, (uint8_t)3);
uint16_t hum = Wire.read();
hum <<= 8;
hum |= Wire.read();
uint8_t chxsum = Wire.read();
float humidity = hum;
humidity *= 125;
humidity /= 65536;
humidity -= 6;
return humidity;
}
float Si7021::readTemperature(void) {
Wire.beginTransmission(Si7021::Cmd.ADDRESS);
Wire.write(Si7021::Cmd.MEASTEMP_NOHOLD);
Wire.endTransmission(false);
delay(25);
Wire.requestFrom(Si7021::Cmd.ADDRESS, (uint8_t)3);
uint16_t temp = Wire.read();
temp <<= 8;
temp |= Wire.read();
uint8_t chxsum = Wire.read();
float temperature = temp;
temperature *= 175.72;
temperature /= 65536;
temperature -= 46.85;
return temperature;
}
void Si7021::reset(void) {
Wire.beginTransmission(Si7021::Cmd.ADDRESS);
Wire.write(Si7021::Cmd.RESET);
Wire.endTransmission();
delay(50);
}
void Si7021::readSerialNumber(void) {
Wire.beginTransmission(Si7021::Cmd.ADDRESS);
Wire.write(Si7021::Cmd.ID1 >> 8);
Wire.write(Si7021::Cmd.ID1 & 0xFF);
Wire.endTransmission();
Wire.requestFrom(Si7021::Cmd.ADDRESS, (uint8_t)8);
sernum_a = Wire.read();
Wire.read();
sernum_a <<= 8;
sernum_a |= Wire.read();
Wire.read();
sernum_a <<= 8;
sernum_a |= Wire.read();
Wire.read();
sernum_a <<= 8;
sernum_a |= Wire.read();
Wire.read();
Wire.beginTransmission(Si7021::Cmd.ADDRESS);
Wire.write(Si7021::Cmd.ID2 >> 8);
Wire.write(Si7021::Cmd.ID2 & 0xFF);
Wire.endTransmission();
Wire.requestFrom(Si7021::Cmd.ADDRESS, (uint8_t)8);
sernum_b = Wire.read();
Wire.read();
sernum_b <<= 8;
sernum_b |= Wire.read();
Wire.read();
sernum_b <<= 8;
sernum_b |= Wire.read();
Wire.read();
sernum_b <<= 8;
sernum_b |= Wire.read();
Wire.read();
}
void Si7021::writeRegister8(uint8_t reg, uint8_t value) {
Wire.beginTransmission(Si7021::Cmd.ADDRESS);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}
uint8_t Si7021::readRegister8(uint8_t reg) {
uint8_t value;
Wire.beginTransmission(Si7021::Cmd.ADDRESS);
Wire.write(reg);
Wire.endTransmission(false);
Wire.requestFrom(Si7021::Cmd.ADDRESS, (uint8_t)1);
value = Wire.read();
return value;
}
uint16_t Si7021::readRegister16(uint8_t reg) {
uint16_t value;
Wire.beginTransmission(Si7021::Cmd.ADDRESS);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(Si7021::Cmd.ADDRESS, (uint8_t)2);
value = Wire.read();
value <<= 8;
value |= Wire.read();
return value;
}
================================================
FILE: examples/humidity/bluefruit/Si7021.h
================================================
#ifndef _SI7021_H_
#define _SI7021_H_
/**************************************************************************
@file Si7021.cpp
@author Limor Fried (Adafruit Industries), Vojta Molda
@license BSD (see license.txt)
This is a library for the Adafruit Si7021 breakout board
----> https://www.adafruit.com/products/3251
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
@section HISTORY
v1.0 - First release
v1.1 - Modified to use <SoftWire.h>
**************************************************************************/
#include <Arduino.h>
#include <SoftwareWire.h>
class Si7021 {
public:
Si7021(SoftwareWire& Wire_);
bool begin(void);
void reset(void);
void readSerialNumber(void);
float readTemperature(void);
float readHumidity(void);
uint32_t sernum_a, sernum_b;
private:
uint8_t readRegister8(uint8_t reg);
uint16_t readRegister16(uint8_t reg);
void writeRegister8(uint8_t reg, uint8_t value);
SoftwareWire& Wire;
const static struct WireCommands {
static const uint8_t ADDRESS = 0x40;
static const uint8_t MEASRH_HOLD = 0xE5;
static const uint8_t MEASRH_NOHOLD = 0xF5;
static const uint8_t MEASTEMP_HOLD = 0xE3;
static const uint8_t MEASTEMP_NOHOLD = 0xF3;
static const uint8_t READPREVTEMP = 0xE0;
static const uint8_t RESET = 0xFE;
static const uint8_t WRITERHT_REG = 0xE6;
static const uint8_t READRHT_REG = 0xE7;
static const uint8_t WRITEHEATER_REG = 0x51;
static const uint8_t READHEATER_REG = 0x11;
static const uint16_t ID1 = 0xFA0F;
static const uint16_t ID2 = 0xFCC9;
static const uint16_t FIRMVERS = 0x84B8;
} Cmd;
};
#endif
================================================
FILE: examples/humidity/bluefruit/bluefruit.ino
================================================
#include <SPI.h>
#include <Arduino.h>
#include <Adafruit_BLE.h>
#include <Adafruit_BLEGatt.h>
#include <Adafruit_BluefruitLE_SPI.h>
#include "Si7021.h"
static struct BoardPins {
const uint8_t VIN = A0;
const uint8_t VO3 = A1;
const uint8_t GND = A2;
const uint8_t SCL = A3;
const uint8_t SDA = A4;
} Pin;
SoftwareWire wire = SoftwareWire(Pin.SDA, Pin.SCL);
Si7021 sensor = Si7021(wire);
Adafruit_BluefruitLE_SPI ble(8, 7, 4); // Firmware > 0.7.0
Adafruit_BLEGatt gatt(ble);
int32_t humidityService;
int32_t humidityCharacteristic;
int32_t thermometerService;
int32_t temperatureCharacteristic;
union float_bytes {
float value;
uint8_t bytes[sizeof(float)];
};
void setup(void) {
Serial.begin(115200);
pinMode(Pin.VIN, OUTPUT);
digitalWrite(Pin.VIN, HIGH);
pinMode(Pin.GND, OUTPUT);
digitalWrite(Pin.GND, LOW);
sensor.begin();
ble.begin(/* true - useful for debugging */);
ble.factoryReset();
ble.info();
uint8_t humidityServiceUUID[] = {0x10,0x52,0x5F,0x60,0xCF,0x73,0x11,0xE6,0x95,0x98,0xF8,0xE2,0x25,0x1C,0x9A,0x69};
humidityService = gatt.addService(humidityServiceUUID);
uint8_t humidityCharacteristicUUID[] = {0x10,0x52,0x5F,0x61,0xCF,0x73,0x11,0xE6,0x95,0x98,0xF8,0xE2,0x25,0x1C,0x9A,0x69};
humidityCharacteristic = gatt.addCharacteristic(humidityCharacteristicUUID,
GATT_CHARS_PROPERTIES_READ | GATT_CHARS_PROPERTIES_NOTIFY,
sizeof(float), sizeof(float), BLE_DATATYPE_BYTEARRAY);
uint8_t thermometerServiceUUID[] = {0xF4,0x89,0xCB,0x00,0xC1,0x77,0x11,0xE6,0x95,0x98,0x98,0x54,0x24,0x9C,0x9A,0x66};
thermometerService = gatt.addService(thermometerServiceUUID);
uint8_t thermometerCharacteristicUUID[] = {0xF4,0x89,0xCB,0x01,0xC1,0x77,0x11,0xE6,0x95,0x98,0x98,0x54,0x24,0x9C,0x9A,0x66};
temperatureCharacteristic = gatt.addCharacteristic(thermometerCharacteristicUUID,
GATT_CHARS_PROPERTIES_READ | GATT_CHARS_PROPERTIES_NOTIFY,
sizeof(float), sizeof(float), BLE_DATATYPE_BYTEARRAY);
ble.reset();
ble.setConnectCallback(centralConnect);
ble.setDisconnectCallback(centralDisconnect);
Serial.println("Bluetooth on");
}
/** Send randomized heart rate data continuously **/
void loop(void) {
ble.update();
static union float_bytes averageHumidity = { .value = sensor.readHumidity() };
averageHumidity.value += (sensor.readHumidity() - averageHumidity.value) / 30.0;
static union float_bytes previousHumidity = { .value = 0.0 };
gatt.getChar(humidityCharacteristic, previousHumidity.bytes, sizeof(previousHumidity));
if (abs(averageHumidity.value - previousHumidity.value) > 1.5) {
gatt.setChar(humidityCharacteristic, averageHumidity.bytes, sizeof(averageHumidity));
Serial.print("Update humidity | ");
Serial.println(averageHumidity.value, 0);
} else {
Serial.print("Humidity | ");
Serial.println(averageHumidity.value, 0);
}
static union float_bytes averageCelsius = { .value = sensor.readTemperature()};
averageCelsius.value += (sensor.readTemperature() - averageCelsius.value) / 30.0;
static union float_bytes previousCelsius = { .value = 0.0 };
gatt.getChar(temperatureCharacteristic, previousCelsius.bytes, sizeof(previousCelsius));
if (abs(averageCelsius.value - previousCelsius.value) > 0.20) {
gatt.setChar(temperatureCharacteristic, averageCelsius.bytes, sizeof(averageCelsius));
Serial.print("Update temperature | ");
Serial.println(averageCelsius.value, 2);
} else {
Serial.print("Temperature | ");
Serial.println(averageCelsius.value, 2);
}
delay(1000);
}
void centralConnect(void) {
Serial.print("Central connected | ");
if (ble.sendCommandCheckOK("AT+BLEGETPEERADDR")) {
Serial.println(ble.buffer);
}
}
void centralDisconnect(void) {
Serial.print("Central disconnected | ");
if (ble.sendCommandCheckOK("AT+BLEGETPEERADDR")) {
Serial.println(ble.buffer);
}
}
================================================
FILE: examples/humidity/config.json
================================================
{
"bridge": {
"name": "Raspberry Pi 3",
"username": "CC:22:3D:E3:CE:30",
"port": 51826,
"pin": "314-15-926"
},
"description": "Raspberry Pi 3 Homebridge-Bluetooth Humidity Sensor Example",
"platforms": [
{
"platform": "Bluetooth",
"accessories": [
{
"name": "Arduino",
"address": "01:23:45:67:89:AB",
"services": [
{
"name": "Humidity Sensor",
"type": "HumiditySensor",
"UUID": "10525F60-CF73-11E6-9598-F8E2251C9A69",
"characteristics": [
{
"type": "CurrentRelativeHumidity",
"UUID": "10525F61-CF73-11E6-9598-F8E2251C9A69"
}
]
},
{
"name": "Temperature Sensor",
"type": "TemperatureSensor",
"UUID": "F489CB00-C177-11E6-9598-9854249C9A66",
"characteristics": [
{
"type": "CurrentTemperature",
"UUID": "F489CB01-C177-11E6-9598-9854249C9A66"
}
]
}
]
}
]
}
]
}
================================================
FILE: examples/humidity/readme.md
================================================
# Humidity and Temperature Sensor
Turn a BLE capable microprocessor and the [Si7021](https://www.silabs.com/Support%20Documents/TechnicalDocs/Si7021-A20.pdf) humidity and temperature sensor into a wireless HomeKit weather station. Temperature and Humidity readings can be displayed in the Home app on your Apple device and used to setup automation rules for your thermostat and humidifier.
<img src="images/humidity.jpg">
This example uses [Arduino 101](https://www.arduino.cc/en/Main/ArduinoBoard101) or [Bluefruit Micro LE](https://www.adafruit.com/products/2661) and [Raspberry Pi 3](https://www.raspberrypi.org/). Generally, any programmable BLE peripheral and a box capable of running [Node.js](https://nodejs.org) with [Noble](https://github.com/sandeepmistry/noble) will work. You'll also need the Si7021 humidity and temperature sensor. There is a nice breakout done by [Adafruit](https://www.adafruit.com/products/3251) and you can also use another breakout done by [Sparkfun](https://www.sparkfun.com/products/13763).
## BLE Periphral (Arduino 101, Bluefruit Micro LE or Other BLE Board)
Download and install the latest version of the [Arduino IDE](https://www.arduino.cc/en/Main/Software). If you're totally new to microcontrollers take some time to go through an introductory tutorial and learn how to make a LED blink. This will help you to understand how to use the IDE, how to upload a sketch and what is the code actually doing.
### Wiring
The Si7021 breakout is wired to ports `A0`-`A4`. `A0` and `A2` are set as outputs `HIGH`/`LOW` and serve as `VCC` and `GND` to provide power to the sensor. Ports `A3` and `A4` serve as two wire interface data `SDA` and clock `SCL` lines. `A3` is connected to optional `3VO` outptu of the voltage regulator built into the Adafruit's breakout and is not used at all. This pin setup was chosen so the breakout can be soldered directly onto the Bluefruit board to create a small and compact package.
<img src="arduino101/arduino101.png" width="30%">
<img src="bluefruit/bluefruit.png" width="30%">
**Note** _Alternatively, you can use any of the many BLE boards available on the market ([BlueBean](https://punchthrough.com/bean/), [RedBearLabs BLE Nano](http://redbearlab.com/blenano), ...) as long as you keep UUIDs of the services and characteristics in sync with your `config.json` file, everything will work just fine._
### Running the Sketch
Compile, run and upload the [arduino101.ino](arduino101/arduino101.ino) or [bluefruit.ino](bluefruit/bluefruit.ino) sketch using the [Arduino IDE](https://www.arduino.cc/en/Main/Software). The sketch creates two BLE services with a readable and notifiable characteristic for the current temperature and humidity. Both values are a `float` type.
```cpp
BLEService humidityService("10525F60-CF73-11E6-9598-F8E2251C9A69");
BLEFloatCharacteristic humidityCharacteristic("10525F61-CF73-11E6-9598-F8E2251C9A69", BLERead | BLENotify);
BLEService thermometerService("F489CB00-C177-11E6-9598-9854249C9A66");
BLEFloatCharacteristic temperatureCharacteristic("F489CB01-C177-11E6-9598-9854249C9A66", BLERead | BLENotify);
```
Take a look into [this file](https://github.com/KhaosT/HAP-NodeJS/blob/master/lib/gen/HomeKitTypes.js#L1147) to see the full definition of the _CurrentRelativeHumidity_ characteristic used in the _HumiditySensor_ service. _TemperatureSensor_ service has _CurrentTemperature_ characteristic. Once the BLE central device is setup, it connects to these characteristics and exposes them via Homebridge as a HomeKit accessory of type _HumiditySensor_ and _TemperatureSensor_.
The code also calculates (pseudo-moving) average to prevent noise in the measurements to trigger frequent mew value notifications. Duration of the averaging window is about 30 s. Once the moving average accumulates change above a certain threshold a new value of the characteristic is set which triggers the notify mechanism and propagates the measurement to HomeKit. The threshold is approximately half of the sensor accuracy (±0.4°C and ±3%).
Leave the device powered on and the sketch running while you setup the Homebridge server. The sketch has some built-in logging, so keeping the Serial monitor open may be helpful for debugging.
## BLE Central & Homebridge Server (Raspberry Pi 3 or Other Compatible Box)
For help installing an operating system on your new Pi, the official documentation contains a couple of [nice videos](https://www.raspberrypi.org/help/videos/).
### Wiring
No wiring except for the micro-USB cable providing power is needed. The Pi needs to be connected to the same router (subnet) as the Apple device you plan to use. It doesn't matter whether via Wifi or Ethernet. Otherwise, you won't be able discover and connect to the Homebridge server running on the Pi.
<img src="images/raspberry.png" width="30%">
**Note** _Alternatively, you can use a Raspberry Pi 2 with a supported USB BLE dongle instead of the Pi 3._
### Running Homebridge
Running Homebridge on a Raspberry Pi is straightforward. Follow [this guide](https://github.com/nfarina/homebridge/wiki/Running-HomeBridge-on-a-Raspberry-Pi) to install Homebridge server and then run the following command to install the homebridge-bluetooth plugin:
```sh
[sudo] npm install -g homebridge-bluetooth
```
Edit the `~/.homebridge/config.json`, name your Homebridge server and add a new accessory to allow the plugin to connect to the BLE service running on the Arduino:
```js
"name": "Arduino",
"address": "01:23:45:67:89:AB",
"services": [
{
"name": "Humidity Sensor",
"type": "HumiditySensor",
"UUID": "10525F60-CF73-11E6-9598-F8E2251C9A69",
"characteristics": [
{
"type": "CurrentRelativeHumidity",
"UUID": "10525F61-CF73-11E6-9598-F8E2251C9A69"
}
]
},
{
"name": "Temperature Sensor",
"type": "TemperatureSensor",
"UUID": "F489CB00-C177-11E6-9598-9854249C9A66",
"characteristics": [
{
"type": "CurrentTemperature",
"UUID": "F489CB01-C177-11E6-9598-9854249C9A66"
}
]
}
]
```
Finally, start the Homebridge server. If you use Linux you may need to run with higher privileges in order to have access to the BLE hardware layer. See [this link](https://github.com/sandeepmistry/noble#running-without-rootsudo) for more details about running without `sudo`.
```sh
[sudo] homebridge -D
```
**Note** _Running with `-D` turns on additional debugging output that is very helpful for getting addresses and UUIDs of your BLE devices that needs to match with the `config.json` file._
<img src="images/homebridge.png">
**Note** _Homebridge server doesn't run only on Linux. MacOS and Windows machines are also supported given they have a built-in BLE adapter or an USB dongle. For more details see supported platforms of [Homebridge](https://github.com/nfarina/homebridge) and [Noble](https://github.com/sandeepmistry/noble)._
## Apple Device (iOS 10 or newer)
### Pairing
Open Home app and tap the '+' button to add new accessory. When you attempt to add the 'Raspberry Pi 3' bridge, it will ask for a "PIN" from the `config.json` file. Once you are paired with your new Rapsberry, Homebridge server all the connected BLE accesories can be added the same way as the bridge.
### Interacting
Once your BLE accessory has been added to HomeKit database, besides using the Home app or Control Center at the bottom of the screen, you should be able to tell Siri to get the reading from any HomeKit accessory. Try _"Hey Siri, what's the humidity of the Arduino?"_. However, Siri is a cloud service and iOS may need some time to synchronize your HomeKit database to iCloud.
<img src="images/ios-home.png" width="30%">
<img src="images/ios-temperature.png" width="30%">
<img src="images/ios-siri-temperature.png" width="30%">
<img src="images/ios-humidity.png" width="30%">
<img src="images/ios-siri-humidity.png" width="30%">
================================================
FILE: examples/lightbulb/arduino101/arduino101.ino
================================================
#include <Arduino.h>
#include <CurieBLE.h>
const int pinLED = 13;
BLEPeripheral ble;
BLEService informationService("180A");
BLECharacteristic modelCharacteristic("2A24", BLERead, "101");
BLECharacteristic manufacturerCharacteristic("2A29", BLERead, "Arduino");
BLECharacteristic serialNumberCharacteristic("2A25", BLERead, "2.71828");
BLEService lightbulbService("8E76F000-690E-472E-88C3-051277686A73");
BLECharCharacteristic onCharacteristic("8E76F001-690E-472E-88C3-051277686A73", BLEWrite | BLERead | BLENotify);
void setup() {
Serial.begin(115200);
pinMode(pinLED, OUTPUT);
ble.setLocalName("Light");
ble.setAdvertisedServiceUuid(lightbulbService.uuid());
ble.addAttribute(informationService);
ble.addAttribute(modelCharacteristic);
ble.addAttribute(manufacturerCharacteristic);
ble.addAttribute(serialNumberCharacteristic);
ble.addAttribute(lightbulbService);
ble.addAttribute(onCharacteristic);
bool on = true;
onCharacteristic.setValueLE(on);
setLED(on);
ble.setEventHandler(BLEConnected, centralConnect);
ble.setEventHandler(BLEDisconnected, centralDisconnect);
onCharacteristic.setEventHandler(BLEWritten, characteristicWrite);
ble.begin();
Serial.println("Bluetooth on");
}
void loop() {
ble.poll();
}
void centralConnect(BLECentral& central) {
Serial.print("Central connected | ");
Serial.println(central.address());
}
void centralDisconnect(BLECentral& central) {
Serial.print("Central disconnected | ");
Serial.println(central.address());
}
void characteristicWrite(BLECentral& central, BLECharacteristic& characteristic) {
Serial.print("Characteristic written | ");
Serial.println(characteristic.uuid());
bool on = (bool) onCharacteristic.valueLE();
setLED(on);
}
void setLED(bool on) {
Serial.print("LED | ");
Serial.print(on);
digitalWrite(pinLED, on);
}
================================================
FILE: examples/lightbulb/config.json
================================================
{
"bridge": {
"name": "Raspberry Pi 3",
"username": "CC:22:3D:E3:CE:30",
"port": 51826,
"pin": "314-15-926"
},
"description": "Raspberry Pi 3 Homebridge-Bluetooth Lightbulb Example",
"platforms": [
{
"platform": "Bluetooth",
"accessories": [
{
"name": "Arduino",
"address": "01:23:45:67:89:AB",
"services": [
{
"name": "LED",
"type": "Lightbulb",
"UUID": "8E76F000-690E-472E-88C3-051277686A73",
"characteristics": [
{
"type": "On",
"UUID": "8E76F001-690E-472E-88C3-051277686A73"
}
]
}
]
}
]
}
]
}
================================================
FILE: examples/lightbulb/readme.md
================================================
# Lightbulb
Turn an LED connected to a BLE capable microprocessor into a wireless HomeKit lightbulb. Use the Home app or Siri on your Apple device to switch it on and off.
<img src="images/lightbulb.jpg">
This example uses [Arduino 101](https://www.arduino.cc/en/Main/ArduinoBoard101) and [Raspberry Pi 3](https://www.raspberrypi.org/). Generally, any programmable BLE peripheral and a box capable of running [Node.js](https://nodejs.org) with [Noble](https://github.com/sandeepmistry/noble) will work.
## BLE Peripheral (Arduino 101 or Other BLE Board)
Download and install the latest version of the [Arduino IDE](https://www.arduino.cc/en/Main/Software). If you're totally new to microcontrollers take some time to go through an introductory tutorial and learn how to make a LED blink. This will help you to understand how to use the IDE, how to upload a sketch and what is the code actually doing.
### Wiring
Connect the LED to pin 13. The LED has to have a resistor in series to limit the current passing through - max current per I/O pin is 20 mA. Generally, anything between 100 and 1k Ohms will do. If you're lazy you can also skip the wiring and use the onboard LED connected to pin 13.
<img src="arduino101/arduino101.png" width="30%">
**Note** _Alternatively, you can use any of the many BLE boards available on the market ([BlueBean](https://punchthrough.com/bean/), [RedBearLabs BLE Nano](http://redbearlab.com/blenano), ...) as long as you keep UUIDs of the services and characteristics in sync with your `config.json` file, everything will work just fine._
### Running the Sketch
Compile, run and upload the [arduino101.ino sketch](arduino101/arduino101.ino) using the [Arduino IDE](https://www.arduino.cc/en/Main/Software). The sketch creates a BLE service with a readable, writable and notifiable characteristic for on/off state.
```cpp
BLEService lightbulbService("8E76F000-690E-472E-88C3-051277686A73");
BLECharCharacteristic onCharacteristic("8E76F001-690E-472E-88C3-051277686A73", BLEWrite | BLERead | BLENotify);
```
Take a look into [this file](https://github.com/KhaosT/HAP-NodeJS/blob/master/lib/gen/HomeKitTypes.js#L1147) to see the full definition of the _On_ characteristic used in the _Lightbulb_ service. Once the BLE central device is setup, it connects to this characteristic and exposes it via Homebridge as a HomeKit accessory of type _Lightbulb_.
Leave the device powered on and the sketch running while you setup the Homebridge server. The sketch has some built-in logging, so keeping the Serial monitor open may be helpful for debugging.
## BLE Central & Homebridge Server (Raspberry Pi 3 or Other Compatible Box)
For help installing an operating system on your new Pi, the official documentation contains a couple of [nice videos](https://www.raspberrypi.org/help/videos/).
### Wiring
No wiring except for the micro-USB cable providing power is needed. The Pi needs to be connected to the same router (subnet) as the Apple device you plan to use. It doesn't matter whether via Wifi or Ethernet. Otherwise, you won't be able discover and connect to the Homebridge server running on the Pi.
<img src="images/raspberry.png" width="30%">
**Note** _Alternatively, you can use a Raspberry Pi 2 with a supported USB BLE dongle instead of the Pi 3._
### Running Homebridge
Running Homebridge on a Raspberry Pi is straightforward. Follow [this guide](https://github.com/nfarina/homebridge/wiki/Running-HomeBridge-on-a-Raspberry-Pi) to install Homebridge server and then run the following command to install the homebridge-bluetooth plugin:
```sh
[sudo] npm install -g homebridge-bluetooth
```
Edit the `~/.homebridge/config.json`, name your Homebridge server and add a new accessory to allow the plugin to connect to the BLE service running on the Arduino:
```js
"name": "Arduino",
"address": "01:23:45:67:89:AB",
"services": [ {
"name": "LED",
"type": "Lightbulb",
"UUID": "8E76F000-690E-472E-88C3-051277686A73",
"characteristics": [ {
"type": "On",
"UUID": "8E76F001-690E-472E-88C3-051277686A73"
} ]
} ]
```
Finally, start the Homebridge server. If you use Linux you may need to run with higher privileges in order to have access to the BLE hardware layer. See [this link](https://github.com/sandeepmistry/noble#running-without-rootsudo) for more details about running without `sudo`.
```sh
[sudo] homebridge -D
```
**Note** _Running with `-D` turns on additional debugging output that is very helpful for getting addresses and UUIDs of your BLE devices that needs to match with the `config.json` file._
<img src="images/homebridge.png">
**Note** _Homebridge server doesn't run only on Linux. MacOS and Windows machines are also supported given they have a built-in BLE adapter or an USB dongle. For more details see supported platforms of [Homebridge](https://github.com/nfarina/homebridge) and [Noble](https://github.com/sandeepmistry/noble)._
## Apple Device (iOS 10 or newer)
### Pairing
Open Home app and tap the '+' button to add new accessory. When you attempt to add the 'Raspberry Pi 3' bridge, it will ask for a "PIN" from the `config.json` file. Once you are paired with your new Rapsberry, Homebridge server all the connected BLE accesories can be added the same way as the bridge.
### Interacting
Once your BLE accessory has been added to HomeKit database, besides using the Home app or Control Center at the bottom of the screen, you should be able to tell Siri to control any HomeKit accessory. Try _"Hey Siri, turn on LED"_. However, Siri is a cloud service and iOS may need some time to synchronize your HomeKit database to iCloud.
<img src="images/ios-home.png" width="30%">
<img src="images/ios-on.png" width="30%">
<img src="images/ios-siri.png" width="30%">
================================================
FILE: examples/lightbulb-rgb/arduino101/arduino101.ino
================================================
#include <math.h>
#include <Arduino.h>
#include <CurieBLE.h>
const int pinRedLED = 5;
const int pinGreenLED = 6;
const int pinBlueLED = 9;
const int pinSwitch = 2;
BLEPeripheral ble;
BLEService informationService("180A");
BLECharacteristic modelCharacteristic("2A24", BLERead, "101");
BLECharacteristic manufacturerCharacteristic("2A29", BLERead, "Arduino");
BLECharacteristic serialNumberCharacteristic("2A25", BLERead, "2.71828");
BLEService lightbulbService("57E54BF0-8574-47BE-9C1D-A0DBFC8FA183");
BLECharCharacteristic onCharacteristic("57E54BF1-8574-47BE-9C1D-A0DBFC8FA183", BLERead | BLEWrite | BLENotify);
BLEFloatCharacteristic hueCharacteristic("57E54BF2-8574-47BE-9C1D-A0DBFC8FA183", BLERead | BLEWrite | BLENotify);
BLEFloatCharacteristic saturationCharacteristic("57E54BF3-8574-47BE-9C1D-A0DBFC8FA183", BLERead | BLEWrite | BLENotify);
BLEIntCharacteristic brightnessCharacteristic("57E54BF4-8574-47BE-9C1D-A0DBFC8FA183", BLERead | BLEWrite | BLENotify);
bool lastSwitch = HIGH;
void setup() {
Serial.begin(115200);
pinMode(pinRedLED, OUTPUT);
pinMode(pinGreenLED, OUTPUT);
pinMode(pinBlueLED, OUTPUT);
pinMode(pinSwitch, INPUT_PULLUP);
ble.setLocalName("Light");
ble.setAdvertisedServiceUuid(lightbulbService.uuid());
ble.addAttribute(informationService);
ble.addAttribute(modelCharacteristic);
ble.addAttribute(manufacturerCharacteristic);
ble.addAttribute(serialNumberCharacteristic);
ble.addAttribute(lightbulbService);
ble.addAttribute(onCharacteristic);
ble.addAttribute(hueCharacteristic);
ble.addAttribute(saturationCharacteristic);
ble.addAttribute(brightnessCharacteristic);
bool on = true;
float hue = 0.0;
float saturation = 0.0;
int brightness = 100;
onCharacteristic.setValueLE(on);
hueCharacteristic.setValueLE(hue);
saturationCharacteristic.setValueLE(saturation);
brightnessCharacteristic.setValueLE(brightness);
setLED(on, hue, saturation, brightness);
ble.setEventHandler(BLEConnected, centralConnect);
ble.setEventHandler(BLEDisconnected, centralDisconnect);
onCharacteristic.setEventHandler(BLEWritten, characteristicWrite);
hueCharacteristic.setEventHandler(BLEWritten, characteristicWrite);
saturationCharacteristic.setEventHandler(BLEWritten, characteristicWrite);
brightnessCharacteristic.setEventHandler(BLEWritten, characteristicWrite);
ble.begin();
Serial.println("Bluetooth on");
lastSwitch = digitalRead(pinSwitch);
}
void loop() {
ble.poll();
if ((digitalRead(pinSwitch) == LOW) && (lastSwitch == HIGH)) {
bool on = (bool) onCharacteristic.valueLE();
float hue = (float) hueCharacteristic.valueLE();
float saturation = (float) saturationCharacteristic.valueLE();
int brightness = (int) brightnessCharacteristic.valueLE();
setLED(!on, hue, saturation, brightness);
onCharacteristic.setValue(!on);
ble.poll();
lastSwitch = LOW;
delay(1);
} else if ((digitalRead(pinSwitch) == HIGH) && (lastSwitch == LOW)) {
lastSwitch = HIGH;
delay(1);
}
}
void centralConnect(BLECentral& central) {
Serial.print("Central connected | ");
Serial.println(central.address());
}
void centralDisconnect(BLECentral& central) {
Serial.print("Central disconnected | ");
Serial.println(central.address());
}
void characteristicWrite(BLECentral& central, BLECharacteristic& characteristic) {
Serial.print("Characteristic written | ");
Serial.println(characteristic.uuid());
bool on = (bool) onCharacteristic.valueLE();
float hue = (float) hueCharacteristic.valueLE();
float saturation = (float) saturationCharacteristic.valueLE();
int brightness = (int) brightnessCharacteristic.valueLE();
setLED(on, hue, saturation, brightness);
}
void setLED(bool on, float hue, float saturation, int brightness) {
hue = max(0.0, min(360.0, hue));
saturation = max(0.0, min(100.0, saturation));
brightness = max(0, min(100, brightness));
unsigned int red, green, blue;
hsv2rgb(hue, saturation/100.0, brightness/100.0, &red, &green, &blue);
analogWrite(pinRedLED, on * red);
analogWrite(pinGreenLED, on * green);
analogWrite(pinBlueLED, on * blue);
Serial.print("RGB LED | ");
Serial.print(on);
Serial.print(" HSB(");
Serial.print(hue);
Serial.print(",");
Serial.print(saturation);
Serial.print(",");
Serial.print(brightness);
Serial.print(") -> RGB(");
Serial.print(red);
Serial.print(",");
Serial.print(green);
Serial.print(",");
Serial.print(blue);
Serial.println(")");
}
void hsv2rgb(float hue, float saturation, float value,
unsigned int* red, unsigned int* green, unsigned int* blue) {
if (saturation == 0.0) {
*red = (unsigned int) round(value * 255.0);
*green = (unsigned int) round(value * 255.0);
*blue = (unsigned int) round(value * 255.0);
} else {
int h = ((int) floor(hue / 60.0) % 6);
float f = (hue / 60.0) - floor(hue / 60.0);
float p = value * (1.0 - saturation);
float q = value * (1.0 - saturation * f);
float t = value * (1.0 - (saturation * (1.0 - f)));
switch (h) {
case 0:
*red = (unsigned int) round(value * 255.0);
*green = (unsigned int) round(t * 255.0);
*blue = (unsigned int) round(p * 255.0);
break;
case 1:
*red = (unsigned int) round(q * 255.0);
*green = (unsigned int) round(value * 255.0);
*blue = (unsigned int) round(p * 255.0);
break;
case 2:
*red = (unsigned int) round(p * 255.0);
*green = (unsigned int) round(value * 255.0);
*blue = (unsigned int) round(t * 255.0);
break;
case 3:
*red = (unsigned int) round(p * 255.0);
*green = (unsigned int) round(q * 255.0);
*blue = (unsigned int) round(value * 255.0);
break;
case 4:
*red = (unsigned int) round(t * 255.0);
*green = (unsigned int) round(p * 255.0);
*blue = (unsigned int) round(value * 255.0);
break;
case 5:
*red = (unsigned int) round(value * 255.0);
*green = (unsigned int) round(p * 255.0);
*blue = (unsigned int) round(q * 255.0);
break;
}
}
}
================================================
FILE: examples/lightbulb-rgb/config.json
================================================
{
"bridge": {
"name": "Raspberry Pi 3",
"username": "CC:22:3D:E3:CE:30",
"port": 51826,
"pin": "314-15-926"
},
"description": "Raspberry Pi 3 Homebridge-Bluetooth RGB Lightbulb Example",
"platforms": [
{
"platform": "Bluetooth",
"accessories": [
{
"name": "Arduino",
"address": "01:23:45:67:89:AB",
"services": [
{
"name": "RGB LED",
"type": "Lightbulb",
"UUID": "57E54BF0-8574-47BE-9C1D-A0DBFC8FA183",
"characteristics": [
{
"type": "On",
"UUID": "57E54BF1-8574-47BE-9C1D-A0DBFC8FA183"
},
{
"type": "Hue",
"UUID": "57E54BF2-8574-47BE-9C1D-A0DBFC8FA183"
},
{
"type": "Saturation",
"UUID": "57E54BF3-8574-47BE-9C1D-A0DBFC8FA183"
},
{
"type": "Brightness",
"UUID": "57E54BF4-8574-47BE-9C1D-A0DBFC8FA183"
}
]
}
]
}
]
}
]
}
================================================
FILE: examples/lightbulb-rgb/readme.md
================================================
# RGB Lightbulb
Turn a bunch of LEDs connected to a BLE capable microprocessor into a wireless HomeKit light. Use the Home app or Siri on your Apple device to switch it on, change color or reduce brightness.
<img src="images/lightbulb-rgb.jpg">
This example uses [Arduino 101](https://www.arduino.cc/en/Main/ArduinoBoard101) and [Raspberry Pi 3](https://www.raspberrypi.org/). Generally, any programmable BLE peripheral and a box capable of running [Node.js](https://nodejs.org) with [Noble](https://github.com/sandeepmistry/noble) will work.
## BLE Peripheral (Arduino 101 or Other BLE Board)
Download and install the latest version of the [Arduino IDE](https://www.arduino.cc/en/Main/Software). If you're totally new to microcontrollers take some time to go through an introductory tutorial and learn how to make a LED blink. This will help you to understand how to use the IDE, how to upload a sketch and what is the code actually doing.
### Wiring
Connect 3 LEDs to pins 9, 6 and 5. These pins support PWM and therefore can be programmed to dim the LEDs. Each LED needs to have a resistor to limit the current passing through - max current per I/O pin is 20 mA. Anything between 100 Ohms and 1k Ohms will do.
The tactile switch is connected to pin 2 and when pushed connects the pin to the ground. The sketch code activates the internal 10k Ohm pull-up resitor to keep the pin high when the switch isn't pressed.
<img src="arduino101/arduino101.png" width="30%">
**Note** _Alternatively, you can use any of the many BLE boards available on the market ([BlueBean](https://punchthrough.com/bean/), [RedBearLabs BLE Nano](http://redbearlab.com/blenano), ...) as long as you keep UUIDs of the services and characteristics in sync with your `config.json` file, everything will work just fine._
### Running the Sketch
Compile, run and upload the [arduino101.ino sketch](arduino101/arduino101.ino) using the [Arduino IDE](https://www.arduino.cc/en/Main/Software).
The sketch creates a BLE service with 4 characteristics. There's one characteristic for on/off characteristic (type `BOOL`), two for hue & saturation (type `FLOAT`) and the fourth one for brightness (type `INT`). All charactersitis have read, write and notify permissions.
```cpp
BLEService lightbulbService("57E54BF0-8574-47BE-9C1D-A0DBFC8FA183");
BLECharCharacteristic onCharacteristic("57E54BF1-8574-47BE-9C1D-A0DBFC8FA183", BLERead | BLEWrite | BLENotify);
BLEFloatCharacteristic hueCharacteristic("57E54BF2-8574-47BE-9C1D-A0DBFC8FA183", BLERead | BLEWrite | BLENotify);
BLEFloatCharacteristic saturationCharacteristic("57E54BF3-8574-47BE-9C1D-A0DBFC8FA183", BLERead | BLEWrite | BLENotify);
BLEIntCharacteristic brightnessCharacteristic("57E54BF4-8574-47BE-9C1D-A0DBFC8FA183", BLERead | BLEWrite | BLENotify);
```
When the tactile switch is toggled the LEDs turn on (or turn off if they were on) and the BLE subscribe-notification mechanism cases the an update update on the Homebridge. This way the information about switching propagates through callbacks to the Apple device without any polling.
Take a look into [this file](https://github.com/KhaosT/HAP-NodeJS/blob/master/lib/gen/HomeKitTypes.js#L1147) to see the full definition of the _Lightbulb_ service.
Once the BLE central device is setup, it connects to this characteristic and exposes it via Homebridge as a HomeKit accessory of type _Lightbulb_. The sketch also contains some logic to convert HSV colors to RGB values for each LED.
Leave the device powered on and the sketch running while you setup the Homebridge server. The sketch has some built-in logging, so keeping the Serial monitor open may be helpful for debugging.
## BLE Central & Homebridge Server (Raspberry Pi 3 or Other Compatible Box)
For help installing an operating system on your new Pi, the official documentation contains a couple of [nice videos](https://www.raspberrypi.org/help/videos/).
### Wiring
No wiring except for the micro-USB cable providing power is needed. The Pi needs to be connected to the same router (subnet) as the Apple device you plan to use. It doesn't matter whether via Wifi or Ethernet. Otherwise, you won't be able discover and connect to the Homebridge server running on the Pi.
<img src="images/raspberry.png" width="30%">
**Note** _Alternatively, you can use a Raspberry Pi 2 with a supported USB BLE dongle instead of the Pi 3._
### Running Homebridge
Running Homebridge on a Raspberry Pi is straightforward. Follow [this guide](https://github.com/nfarina/homebridge/wiki/Running-HomeBridge-on-a-Raspberry-Pi) to install Homebridge server and then run the following command to install the homebridge-bluetooth plugin:
```sh
[sudo] npm install -g homebridge-bluetooth
```
Edit the `~/.homebridge/config.json`, name your Homebridge server and add a new accessory to allow the plugin to connect to the BLE service running on the Arduino:
```js
"name": "Arduino",
"address": "01:23:45:67:89:AB",
"services": [ {
"name": "RGB LED",
"type": "Lightbulb",
"UUID": "57E54BF0-8574-47BE-9C1D-A0DBFC8FA183",
"characteristics": [ {
"type": "On",
"UUID": "57E54BF1-8574-47BE-9C1D-A0DBFC8FA183"
}, {
"type": "Brightness",
"UUID": "57E54BF2-8574-47BE-9C1D-A0DBFC8FA183"
}, {
"type": "Saturation",
"UUID": "857E54BF3-8574-47BE-9C1D-A0DBFC8FA183"
}, {
"type": "Hue",
"UUID": "857E54BF4-8574-47BE-9C1D-A0DBFC8FA183"
} ]
} ]
```
Finally, start the Homebridge server. If you use Linux you may need to run with higher privileges in order to have access to the BLE hardware layer. See [this link](https://github.com/sandeepmistry/noble#running-without-rootsudo) for more details about running without `sudo`.
```
[sudo] homebridge -D
```
**Note** _Running with `-D` turns on additional debugging output that is very helpful for getting addresses and UUIDs of your BLE devices that needs to match with the `config.json` file._
<img src="images/homebridge.png">
**Note** _Homebridge server doesn't run only on Linux. MacOS and Windows machines are also supported given they have a built-in BLE adapter or an USB dongle. For more details see supported platforms of [Homebridge](https://github.com/nfarina/homebridge) and [Noble](https://github.com/sandeepmistry/noble)._
## Apple Device
### Pairing
Open Home app and tap the '+' button to add new accessory. When you attempt to add the 'Raspberry Pi 3' bridge, it will ask for a "PIN" from the `config.json` file. Once you are paired with your new Rapsberry Homebridge server all the Arduino accesory can be added the same way as the bridge.
### Interacting
Once your BLE accessory has been added to HomeKit database, besides using the Home app or Control Center at the bottom of the screen, you should be able to tell Siri to control any HomeKit accessory. Try _"Hey Siri, dim RGB LED to 50%"_. However, Siri is a cloud service and iOS may need some time to synchronize your HomeKit database to iCloud.
<img src="images/ios-accesories.png" width="30%">
<img src="images/ios-brightness.png" width="30%">
<img src="images/ios-color.png" width="30%">
<img src="images/ios-hsv.png" width="30%">
<img src="images/ios-siri-brightness.png" width="30%">
<img src="images/ios-siri-color.png" width="30%">
================================================
FILE: examples/lock/arduino101/arduino101.ino
================================================
#include <Arduino.h>
#include <CurieBLE.h>
#include "sensor.h"
#include "motor.h"
#include "lock.h"
static struct BoardPins {
const uint8_t Motor1 = 1;
const uint8_t Motor2 = 2;
const uint8_t MotorPWM = 3;
const uint8_t Sensor1A = 4;
const uint8_t Sensor1B = 5;
const uint8_t Sensor2A = 6;
const uint8_t Sensor2B = 7;
} Pin;
BLEPeripheral ble;
BLEService informationService("180A");
BLECharacteristic modelCharacteristic("2A24", BLERead, "Arduino 101");
BLECharacteristic manufacturerCharacteristic("2A29", BLERead, "Lockitron");
BLECharacteristic serialNumberCharacteristic("2A25", BLERead, "V1");
BLEService lockMechanismService("43AAF900-5FF0-4633-95A2-FE4189EE103B");
BLEUnsignedCharCharacteristic targetStateCharacteristic("43AAF901-5FF0-4633-95A2-FE4189EE103B",
BLEWrite | BLERead | BLENotify);
BLEUnsignedCharCharacteristic currentStateCharacteristic("43AAF902-5FF0-4633-95A2-FE4189EE103B",
BLERead | BLENotify);
Sensor sensor1A(Pin.Sensor1A);
Sensor sensor1B(Pin.Sensor1B);
Sensor sensor2A(Pin.Sensor2A);
Sensor sensor2B(Pin.Sensor2B);
Motor motor(Pin.Motor1, Pin.Motor2, Pin.MotorPWM, 128);
Lock lock = Lock(sensor1A, sensor1B, sensor2A, sensor2B, motor, true);
volatile bool targetStateUpdate = false;
void targetStateWritten(BLECentral& /*central*/, BLECharacteristic& /*characteristic*/) {
targetStateUpdate = true;
}
void setup() {
Serial.begin(115200);
ble.setLocalName("Lock");
ble.addAttribute(informationService);
ble.addAttribute(modelCharacteristic);
ble.addAttribute(manufacturerCharacteristic);
ble.addAttribute(serialNumberCharacteristic);
ble.addAttribute(lockMechanismService);
ble.addAttribute(targetStateCharacteristic);
ble.addAttribute(currentStateCharacteristic);
targetStateCharacteristic.setEventHandler(BLEWritten, targetStateWritten);
ble.begin();
lock.begin();
}
void loop() {
ble.poll();
delay(200);
if (targetStateUpdate) {
lock.set(targetStateCharacteristic.valueLE());
currentStateCharacteristic.setValueLE(lock.state());
targetStateUpdate = false;
}
if (lock.state() != currentStateCharacteristic.valueLE()) {
targetStateCharacteristic.setValueLE(lock.state());
currentStateCharacteristic.setValueLE(lock.state());
}
}
================================================
FILE: examples/lock/arduino101/arduino101.sch
================================================
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE eagle SYSTEM "eagle.dtd">
<eagle version="7.5.0">
<drawing>
<settings>
<setting alwaysvectorfont="no"/>
<setting verticaltext="up"/>
</settings>
<grid distance="0.1" unitdist="inch" unit="inch" style="lines" multiple="1" display="no" altdistance="0.01" altunitdist="inch" altunit="inch"/>
<layers>
<layer number="1" name="Top" color="4" fill="1" visible="no" active="no"/>
<layer number="16" name="Bottom" color="1" fill="1" visible="no" active="no"/>
<layer number="17" name="Pads" color="2" fill="1" visible="no" active="no"/>
<layer number="18" name="Vias" color="2" fill="1" visible="no" active="no"/>
<layer number="19" name="Unrouted" color="6" fill="1" visible="no" active="no"/>
<layer number="20" name="Dimension" color="15" fill="1" visible="no" active="no"/>
<layer number="21" name="tPlace" color="7" fill="1" visible="no" active="no"/>
<layer number="22" name="bPlace" color="7" fill="1" visible="no" active="no"/>
<layer number="23" name="tOrigins" color="15" fill="1" visible="no" active="no"/>
<layer number="24" name="bOrigins" color="15" fill="1" visible="no" active="no"/>
<layer number="25" name="tNames" color="7" fill="1" visible="no" active="no"/>
<layer number="26" name="bNames" color="7" fill="1" visible="no" active="no"/>
<layer number="27" name="tValues" color="7" fill="1" visible="no" active="no"/>
<layer number="28" name="bValues" color="7" fill="1" visible="no" active="no"/>
<layer number="29" name="tStop" color="7" fill="3" visible="no" active="no"/>
<layer number="30" name="bStop" color="7" fill="6" visible="no" active="no"/>
<layer number="31" name="tCream" color="7" fill="4" visible="no" active="no"/>
<layer number="32" name="bCream" color="7" fill="5" visible="no" active="no"/>
<layer number="33" name="tFinish" color="6" fill="3" visible="no" active="no"/>
<layer number="34" name="bFinish" color="6" fill="6" visible="no" active="no"/>
<layer number="35" name="tGlue" color="7" fill="4" visible="no" active="no"/>
<layer number="36" name="bGlue" color="7" fill="5" visible="no" active="no"/>
<layer number="37" name="tTest" color="7" fill="1" visible="no" active="no"/>
<layer number="38" name="bTest" color="7" fill="1" visible="no" active="no"/>
<layer number="39" name="tKeepout" color="4" fill="11" visible="no" active="no"/>
<layer number="40" name="bKeepout" color="1" fill="11" visible="no" active="no"/>
<layer number="41" name="tRestrict" color="4" fill="10" visible="no" active="no"/>
<layer number="42" name="bRestrict" color="1" fill="10" visible="no" active="no"/>
<layer number="43" name="vRestrict" color="2" fill="10" visible="no" active="no"/>
<layer number="44" name="Drills" color="7" fill="1" visible="no" active="no"/>
<layer number="45" name="Holes" color="7" fill="1" visible="no" active="no"/>
<layer number="46" name="Milling" color="3" fill="1" visible="no" active="no"/>
<layer number="47" name="Measures" color="7" fill="1" visible="no" active="no"/>
<layer number="48" name="Document" color="7" fill="1" visible="no" active="no"/>
<layer number="49" name="Reference" color="7" fill="1" visible="no" active="no"/>
<layer number="50" name="dxf" color="7" fill="1" visible="no" active="no"/>
<layer number="51" name="tDocu" color="7" fill="1" visible="no" active="no"/>
<layer number="52" name="bDocu" color="7" fill="1" visible="no" active="no"/>
<layer number="53" name="tGND_GNDA" color="7" fill="9" visible="no" active="no"/>
<layer number="54" name="bGND_GNDA" color="1" fill="9" visible="no" active="no"/>
<layer number="56" name="wert" color="7" fill="1" visible="no" active="no"/>
<layer number="57" name="tCAD" color="7" fill="1" visible="no" active="no"/>
<layer number="59" name="tCarbon" color="7" fill="1" visible="no" active="no"/>
<layer number="60" name="bCarbon" color="7" fill="1" visible="no" active="no"/>
<layer number="90" name="Modules" color="5" fill="1" visible="yes" active="yes"/>
<layer number="91" name="Nets" color="2" fill="1" visible="yes" active="yes"/>
<layer number="92" name="Busses" color="1" fill="1" visible="yes" active="yes"/>
<layer number="93" name="Pins" color="2" fill="1" visible="no" active="yes"/>
<layer number="94" name="Symbols" color="4" fill="1" visible="yes" active="yes"/>
<layer number="95" name="Names" color="7" fill="1" visible="yes" active="yes"/>
<layer number="96" name="Values" color="7" fill="1" visible="yes" active="yes"/>
<layer number="97" name="Info" color="7" fill="1" visible="yes" active="yes"/>
<layer number="98" name="Guide" color="6" fill="1" visible="yes" active="yes"/>
<layer number="99" name="SpiceOrder" color="7" fill="1" visible="yes" active="yes"/>
<layer number="100" name="Muster" color="7" fill="1" visible="no" active="no"/>
<layer number="101" name="Patch_Top" color="12" fill="4" visible="yes" active="yes"/>
<layer number="102" name="Vscore" color="7" fill="1" visible="yes" active="yes"/>
<layer number="103" name="tMap" color="7" fill="1" visible="yes" active="yes"/>
<layer number="104" name="Name" color="16" fill="1" visible="yes" active="yes"/>
<layer number="105" name="tPlate" color="7" fill="1" visible="yes" active="yes"/>
<layer number="106" name="bPlate" color="7" fill="1" visible="yes" active="yes"/>
<layer number="107" name="Crop" color="7" fill="1" visible="yes" active="yes"/>
<layer number="108" name="fp8" color="7" fill="1" visible="yes" active="yes"/>
<layer number="109" name="fp9" color="7" fill="1" visible="yes" active="yes"/>
<layer number="110" name="fp0" color="7" fill="1" visible="yes" active="yes"/>
<layer number="111" name="LPC17xx" color="7" fill="1" visible="yes" active="yes"/>
<layer number="112" name="tSilk" color="7" fill="1" visible="yes" active="yes"/>
<layer number="113" name="IDFDebug" color="4" fill="1" visible="yes" active="yes"/>
<layer number="114" name="Badge_Outline" color="7" fill="1" visible="yes" active="yes"/>
<layer number="115" name="ReferenceISLANDS" color="7" fill="1" visible="yes" active="yes"/>
<layer number="116" name="Patch_BOT" color="9" fill="4" visible="yes" active="yes"/>
<layer number="118" name="Rect_Pads" color="7" fill="1" visible="yes" active="yes"/>
<layer number="121" name="_tsilk" color="7" fill="1" visible="yes" active="yes"/>
<layer number="122" name="_bsilk" color="7" fill="1" visible="yes" active="yes"/>
<layer number="123" name="tTestmark" color="7" fill="1" visible="yes" active="yes"/>
<layer number="124" name="bTestmark" color="7" fill="1" visible="yes" active="yes"/>
<layer number="125" name="_tNames" color="7" fill="1" visible="yes" active="yes"/>
<layer number="126" name="_bNames" color="7" fill="1" visible="yes" active="yes"/>
<layer number="127" name="_tValues" color="7" fill="1" visible="yes" active="yes"/>
<layer number="128" name="_bValues" color="7" fill="1" visible="yes" active="yes"/>
<layer number="129" name="Mask" color="7" fill="1" visible="yes" active="yes"/>
<layer number="131" name="tAdjust" color="7" fill="1" visible="yes" active="yes"/>
<layer number="132" name="bAdjust" color="7" fill="1" visible="yes" active="yes"/>
<layer number="144" name="Drill_legend" color="7" fill="1" visible="yes" active="yes"/>
<layer number="150" name="Notes" color="7" fill="1" visible="yes" active="yes"/>
<layer number="151" name="HeatSink" color="7" fill="1" visible="yes" active="yes"/>
<layer number="152" name="_bDocu" color="7" fill="1" visible="yes" active="yes"/>
<layer number="153" name="FabDoc1" color="7" fill="1" visible="yes" active="yes"/>
<layer number="154" name="FabDoc2" color="7" fill="1" visible="yes" active="yes"/>
<layer number="155" name="FabDoc3" color="7" fill="1" visible="yes" active="yes"/>
<layer number="199" name="Contour" color="7" fill="1" visible="yes" active="yes"/>
<layer number="200" name="200bmp" color="1" fill="10" visible="yes" active="yes"/>
<layer number="201" name="201bmp" color="2" fill="10" visible="yes" active="yes"/>
<layer number="202" name="202bmp" color="3" fill="10" visible="yes" active="yes"/>
<layer number="203" name="203bmp" color="4" fill="10" visible="yes" active="yes"/>
<layer number="204" name="204bmp" color="5" fill="10" visible="yes" active="yes"/>
<layer number="205" name="205bmp" color="6" fill="10" visible="yes" active="yes"/>
<layer number="206" name="206bmp" color="7" fill="10" visible="yes" active="yes"/>
<layer number="207" name="207bmp" color="8" fill="10" visible="yes" active="yes"/>
<layer number="208" name="208bmp" color="9" fill="10" visible="yes" active="yes"/>
<layer number="209" name="209bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="210" name="210bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="211" name="211bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="212" name="212bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="213" name="213bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="214" name="214bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="215" name="215bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="216" name="216bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="217" name="217bmp" color="18" fill="1" visible="no" active="no"/>
<layer number="218" name="218bmp" color="19" fill="1" visible="no" active="no"/>
<layer number="219" name="219bmp" color="20" fill="1" visible="no" active="no"/>
<layer number="220" name="220bmp" color="21" fill="1" visible="no" active="no"/>
<layer number="221" name="221bmp" color="22" fill="1" visible="no" active="no"/>
<layer number="222" name="222bmp" color="23" fill="1" visible="no" active="no"/>
<layer number="223" name="223bmp" color="24" fill="1" visible="no" active="no"/>
<layer number="224" name="224bmp" color="25" fill="1" visible="no" active="no"/>
<layer number="225" name="225bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="226" name="226bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="227" name="227bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="228" name="228bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="229" name="229bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="230" name="230bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="231" name="231bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="248" name="Housing" color="7" fill="1" visible="yes" active="yes"/>
<layer number="249" name="Edge" color="7" fill="1" visible="yes" active="yes"/>
<layer number="250" name="Descript" color="3" fill="1" visible="no" active="no"/>
<layer number="251" name="SMDround" color="12" fill="11" visible="no" active="no"/>
<layer number="254" name="cooling" color="7" fill="1" visible="yes" active="yes"/>
<layer number="255" name="routoute" color="7" fill="1" visible="yes" active="yes"/>
</layers>
<schematic xreflabel="%F%N/%S.%C%R" xrefpart="/%S.%C%R">
<libraries>
<library name="battery">
<description><b>Lithium Batteries and NC Accus</b><p>
<author>Created by librarian@cadsoft.de</author></description>
<packages>
<package name="CRAA">
<description><b>LI BATTERY</b> Varta</description>
<wire x1="23.622" y1="-7.493" x2="-25.146" y2="-7.493" width="0.1524" layer="21"/>
<wire x1="-25.146" y1="6.985" x2="-25.146" y2="7.493" width="0.1524" layer="21"/>
<wire x1="-25.4" y1="-3.175" x2="-25.4" y2="3.175" width="0.4064" layer="21"/>
<wire x1="-25.146" y1="-7.493" x2="-25.146" y2="-6.985" width="0.1524" layer="21"/>
<wire x1="25.4" y1="-2.413" x2="25.4" y2="2.413" width="0.4064" layer="51"/>
<wire x1="-25.4" y1="-6.985" x2="-25.4" y2="-3.175" width="0.1524" layer="51"/>
<wire x1="-25.4" y1="3.175" x2="-25.4" y2="6.985" width="0.4064" layer="51"/>
<wire x1="25.146" y1="1.778" x2="25.146" y2="3.556" width="0.1524" layer="21"/>
<wire x1="25.146" y1="-3.556" x2="25.146" y2="-1.778" width="0.1524" layer="21"/>
<wire x1="25.146" y1="3.556" x2="24.257" y2="3.556" width="0.1524" layer="21"/>
<wire x1="24.257" y1="3.556" x2="24.257" y2="6.858" width="0.1524" layer="21"/>
<wire x1="25.146" y1="-3.556" x2="24.257" y2="-3.556" width="0.1524" layer="21"/>
<wire x1="24.257" y1="-3.556" x2="24.257" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="24.257" y1="-1.27" x2="24.257" y2="1.27" width="0.1524" layer="51"/>
<wire x1="24.257" y1="1.27" x2="24.257" y2="3.556" width="0.1524" layer="21"/>
<wire x1="-24.384" y1="0" x2="-22.86" y2="0" width="0.254" layer="21"/>
<wire x1="-23.622" y1="-0.762" x2="-23.622" y2="0.762" width="0.254" layer="21"/>
<wire x1="20.447" y1="0" x2="21.971" y2="0" width="0.1524" layer="21"/>
<wire x1="23.622" y1="-7.493" x2="24.257" y2="-6.858" width="0.1524" layer="21" curve="90"/>
<wire x1="23.622" y1="7.493" x2="24.257" y2="6.858" width="0.1524" layer="21" curve="-90"/>
<wire x1="24.257" y1="-6.858" x2="24.257" y2="-3.556" width="0.1524" layer="21"/>
<wire x1="23.622" y1="7.493" x2="-25.146" y2="7.493" width="0.1524" layer="21"/>
<wire x1="-2.921" y1="-2.54" x2="-2.921" y2="0" width="0.254" layer="21"/>
<wire x1="0.254" y1="0" x2="-1.651" y2="0" width="0.1524" layer="21"/>
<wire x1="-2.921" y1="0" x2="-5.207" y2="0" width="0.1524" layer="21"/>
<wire x1="-2.921" y1="0" x2="-2.921" y2="2.54" width="0.254" layer="21"/>
<wire x1="-3.429" y1="-1.524" x2="-4.445" y2="-1.524" width="0.1524" layer="21"/>
<wire x1="-3.937" y1="-2.032" x2="-3.937" y2="-1.016" width="0.1524" layer="21"/>
<pad name="+" x="-25.4" y="-5.08" drill="1.3208" diameter="3.1496" shape="octagon"/>
<pad name="+@1" x="-25.4" y="5.08" drill="1.3208" diameter="3.1496" shape="octagon"/>
<pad name="-" x="25.4" y="0" drill="1.3208" diameter="3.1496" shape="octagon"/>
<text x="-25.4" y="8.255" size="1.27" layer="25" ratio="10">>NAME</text>
<text x="-10.16" y="-5.08" size="1.27" layer="21" ratio="10">Lithium 3V</text>
<text x="17.018" y="-6.731" size="1.27" layer="21" ratio="10">CR-AA</text>
<text x="-7.62" y="3.81" size="1.27" layer="27" ratio="10">>VALUE</text>
<rectangle x1="-2.286" y1="-1.27" x2="-1.651" y2="1.27" layer="21"/>
</package>
</packages>
<symbols>
<symbol name="1V2+2">
<wire x1="-1.905" y1="0.635" x2="-1.905" y2="0" width="0.4064" layer="94"/>
<wire x1="-2.54" y1="0" x2="-1.905" y2="0" width="0.1524" layer="94"/>
<wire x1="-1.905" y1="0" x2="-1.905" y2="-0.635" width="0.4064" layer="94"/>
<wire x1="-0.635" y1="2.54" x2="-0.635" y2="0" width="0.4064" layer="94"/>
<wire x1="-0.635" y1="0" x2="2.54" y2="0" width="0.1524" layer="94"/>
<wire x1="-0.635" y1="0" x2="-0.635" y2="-2.54" width="0.4064" layer="94"/>
<text x="-2.54" y="3.175" size="1.778" layer="95">>NAME</text>
<text x="-2.54" y="-5.08" size="1.778" layer="96">>VALUE</text>
<pin name="+" x="5.08" y="0" visible="pad" length="short" direction="pas" rot="R180"/>
<pin name="-" x="-5.08" y="0" visible="pad" length="short" direction="pas"/>
<pin name="+@1" x="2.54" y="0" visible="off" length="point" direction="pas" rot="R180"/>
</symbol>
</symbols>
<devicesets>
<deviceset name="CRAA" prefix="G">
<description><b>LI BATTERY</b> Varta</description>
<gates>
<gate name="G$1" symbol="1V2+2" x="0" y="0"/>
</gates>
<devices>
<device name="" package="CRAA">
<connects>
<connect gate="G$1" pin="+" pad="+"/>
<connect gate="G$1" pin="+@1" pad="+@1"/>
<connect gate="G$1" pin="-" pad="-"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
</devices>
</deviceset>
</devicesets>
</library>
<library name="supply1">
<description><b>Supply Symbols</b><p>
GND, VCC, 0V, +5V, -5V, etc.<p>
Please keep in mind, that these devices are necessary for the
automatic wiring of the supply signals.<p>
The pin name defined in the symbol is identical to the net which is to be wired automatically.<p>
In this library the device names are the same as the pin names of the symbols, therefore the correct signal names appear next to the supply symbols in the schematic.<p>
<author>Created by librarian@cadsoft.de</author></description>
<packages>
</packages>
<symbols>
<symbol name="+12V">
<wire x1="1.27" y1="-1.905" x2="0" y2="0" width="0.254" layer="94"/>
<wire x1="0" y1="0" x2="-1.27" y2="-1.905" width="0.254" layer="94"/>
<wire x1="1.27" y1="-0.635" x2="0" y2="1.27" width="0.254" layer="94"/>
<wire x1="0" y1="1.27" x2="-1.27" y2="-0.635" width="0.254" layer="94"/>
<text x="-2.54" y="-5.08" size="1.778" layer="96" rot="R90">>VALUE</text>
<pin name="+12V" x="0" y="-2.54" visible="off" length="short" direction="sup" rot="R90"/>
</symbol>
<symbol name="GND">
<wire x1="-1.905" y1="0" x2="1.905" y2="0" width="0.254" layer="94"/>
<text x="-2.54" y="-2.54" size="1.778" layer="96">>VALUE</text>
<pin name="GND" x="0" y="2.54" visible="off" length="short" direction="sup" rot="R270"/>
</symbol>
</symbols>
<devicesets>
<deviceset name="+12V" prefix="P+">
<description><b>SUPPLY SYMBOL</b></description>
<gates>
<gate name="1" symbol="+12V" x="0" y="0"/>
</gates>
<devices>
<device name="">
<technologies>
<technology name=""/>
</technologies>
</device>
</devices>
</deviceset>
<deviceset name="GND" prefix="GND">
<description><b>SUPPLY SYMBOL</b></description>
<gates>
<gate name="1" symbol="GND" x="0" y="0"/>
</gates>
<devices>
<device name="">
<technologies>
<technology name=""/>
</technologies>
</device>
</devices>
</deviceset>
</devicesets>
</library>
<library name="SparkFun-Electromechanical">
<description><h3>SparkFun Electronics' preferred foot prints</h3>
In this library you'll find anything that moves- switches, relays, buttons, potentiometers. Also, anything that goes on a board but isn't electrical in nature- screws, standoffs, etc.<br><br>
We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com.
<br><br>
<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/
<br><br>
You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage.</description>
<packages>
<package name="SWITCH-SPDT">
<wire x1="2.175" y1="5.815" x2="-2.175" y2="5.815" width="0.2032" layer="21"/>
<wire x1="-2.175" y1="5.815" x2="-2.175" y2="-5.815" width="0.2032" layer="21"/>
<wire x1="-2.175" y1="-5.815" x2="2.175" y2="-5.815" width="0.2032" layer="21"/>
<wire x1="2.175" y1="-5.815" x2="2.175" y2="5.815" width="0.2032" layer="21"/>
<pad name="1" x="0" y="2.54" drill="1.016" diameter="1.8796"/>
<pad name="2" x="0" y="0" drill="1.016" diameter="1.8796"/>
<pad name="3" x="0" y="-2.54" drill="1.016" diameter="1.8796"/>
<text x="-3.81" y="7.62" size="1.778" layer="25" ratio="10">>NAME</text>
<text x="-3.81" y="-9.525" size="1.778" layer="27" ratio="10">>VALUE</text>
</package>
<package name="AYZ0202">
<description><b>DPDT Slide Switch SMD</b>
www.SparkFun.com SKU : Comp-SMDS</description>
<wire x1="-3.6" y1="1.75" x2="-3.6" y2="-1.75" width="0.2032" layer="21"/>
<wire x1="-3.6" y1="-1.75" x2="3.6" y2="-1.75" width="0.2032" layer="21"/>
<wire x1="3.6" y1="-1.75" x2="3.6" y2="1.75" width="0.2032" layer="21"/>
<wire x1="3.6" y1="1.75" x2="-3.6" y2="1.75" width="0.2032" layer="21"/>
<smd name="3" x="2.5" y="2.825" dx="1" dy="1.15" layer="1"/>
<smd name="2" x="0" y="2.825" dx="1" dy="1.15" layer="1"/>
<smd name="1" x="-2.5" y="2.825" dx="1" dy="1.15" layer="1"/>
<smd name="6" x="2.5" y="-2.825" dx="1" dy="1.15" layer="1"/>
<smd name="5" x="0" y="-2.825" dx="1" dy="1.15" layer="1"/>
<smd name="4" x="-2.5" y="-2.825" dx="1" dy="1.15" layer="1"/>
<text x="-2.54" y="1.143" size="0.4064" layer="25">>Name</text>
<text x="0.508" y="1.143" size="0.4064" layer="27">>Value</text>
<hole x="1.5" y="0" drill="0.85"/>
<hole x="-1.5" y="0" drill="0.85"/>
</package>
<package name="SWITCHE-DPDT">
<wire x1="8" y1="3.25" x2="-8" y2="3.25" width="0.127" layer="51"/>
<wire x1="-8" y1="3.25" x2="-8" y2="-3.25" width="0.127" layer="51"/>
<wire x1="-8" y1="-3.25" x2="8" y2="-3.25" width="0.127" layer="51"/>
<wire x1="8" y1="-3.25" x2="8" y2="3.25" width="0.127" layer="51"/>
<wire x1="-6" y1="3.25" x2="6" y2="3.25" width="0.2032" layer="21"/>
<wire x1="8" y1="1" x2="8" y2="-1" width="0.2032" layer="21"/>
<wire x1="6" y1="-3.25" x2="-6" y2="-3.25" width="0.2032" layer="21"/>
<wire x1="-8" y1="-1" x2="-8" y2="1" width="0.2032" layer="21"/>
<pad name="P$1" x="-7.5" y="3" drill="1.5" diameter="2.54"/>
<pad name="P$2" x="-7.5" y="-3" drill="1.5" diameter="2.54"/>
<pad name="P$3" x="7.5" y="3" drill="1.5" diameter="2.54"/>
<pad name="P$4" x="7.5" y="-3" drill="1.5" diameter="2.54"/>
<pad name="1" x="-4" y="1.25" drill="0.7" diameter="1.6764"/>
<pad name="2" x="0" y="1.25" drill="0.7" diameter="1.6764"/>
<pad name="3" x="4" y="1.25" drill="0.7" diameter="1.6764"/>
<pad name="4" x="-4" y="-1.25" drill="0.7" diameter="1.6764"/>
<pad name="5" x="0" y="-1.25" drill="0.7" diameter="1.6764"/>
<pad name="6" x="4" y="-1.25" drill="0.7" diameter="1.6764"/>
</package>
<package name="R_SW_TH">
<wire x1="-1.651" y1="19.2532" x2="-1.651" y2="-1.3716" width="0.2032" layer="21"/>
<wire x1="-1.651" y1="-1.3716" x2="-1.651" y2="-2.2352" width="0.2032" layer="21"/>
<wire x1="-1.651" y1="19.2532" x2="13.589" y2="19.2532" width="0.2032" layer="21"/>
<wire x1="13.589" y1="19.2532" x2="13.589" y2="-2.2352" width="0.2032" layer="21"/>
<wire x1="13.589" y1="-2.2352" x2="-1.651" y2="-2.2352" width="0.2032" layer="21"/>
<pad name="P$1" x="0" y="0" drill="1.6002"/>
<pad name="P$2" x="0" y="16.9926" drill="1.6002"/>
<pad name="P$3" x="12.0904" y="15.494" drill="1.6002"/>
<pad name="P$4" x="12.0904" y="8.4582" drill="1.6002"/>
</package>
<package name="SWITCH-SPDT-SMD">
<wire x1="-4.5" y1="1.75" x2="-4.5" y2="-1.75" width="0.127" layer="51"/>
<wire x1="-4.5" y1="-1.75" x2="4.5" y2="-1.75" width="0.127" layer="51"/>
<wire x1="4.5" y1="-1.75" x2="4.5" y2="1.75" width="0.127" layer="51"/>
<wire x1="4.5" y1="1.75" x2="2" y2="1.75" width="0.127" layer="51"/>
<wire x1="2" y1="1.75" x2="0.5" y2="1.75" width="0.127" layer="51"/>
<wire x1="0.5" y1="1.75" x2="-4.5" y2="1.75" width="0.127" layer="51"/>
<wire x1="0.5" y1="1.75" x2="0.5" y2="3.75" width="0.127" layer="51"/>
<wire x1="0.5" y1="3.75" x2="2" y2="3.75" width="0.127" layer="51"/>
<wire x1="2" y1="3.75" x2="2" y2="1.75" width="0.127" layer="51"/>
<wire x1="-4" y1="-1.75" x2="-4.5" y2="-1.75" width="0.2032" layer="21"/>
<wire x1="-4.5" y1="-1.75" x2="-4.5" y2="1.75" width="0.2032" layer="21"/>
<wire x1="-4.5" y1="1.75" x2="4.5" y2="1.75" width="0.2032" layer="21"/>
<wire x1="4.5" y1="1.75" x2="4.5" y2="-1.75" width="0.2032" layer="21"/>
<wire x1="4.5" y1="-1.75" x2="4" y2="-1.75" width="0.2032" layer="21"/>
<smd name="1" x="-2.5" y="-2.75" dx="1.2" dy="2.5" layer="1" rot="R180"/>
<smd name="2" x="0" y="-2.75" dx="1.2" dy="2.5" layer="1" rot="R180"/>
<smd name="3" x="2.5" y="-2.75" dx="1.2" dy="2.5" layer="1" rot="R180"/>
<text x="-1.27" y="0.635" size="0.6096" layer="25">>Name</text>
<text x="-1.27" y="-1.27" size="0.6096" layer="27">>Value</text>
<hole x="-3.55" y="0" drill="0.9"/>
<hole x="3.55" y="0" drill="0.9"/>
</package>
<package name="SWITCH-SPDT_LOCK.007S">
<wire x1="2.175" y1="5.815" x2="-2.175" y2="5.815" width="0.2032" layer="21"/>
<wire x1="-2.175" y1="5.815" x2="-2.175" y2="-5.815" width="0.2032" layer="21"/>
<wire x1="-2.175" y1="-5.815" x2="2.175" y2="-5.815" width="0.2032" layer="21"/>
<wire x1="2.175" y1="-5.815" x2="2.175" y2="5.815" width="0.2032" layer="21"/>
<pad name="1" x="0" y="2.7178" drill="1.016" diameter="1.8796"/>
<pad name="2" x="0" y="0" drill="1.016" diameter="1.8796"/>
<pad name="3" x="0" y="-2.7178" drill="1.016" diameter="1.8796"/>
<text x="-3.81" y="7.62" size="1.778" layer="25" ratio="10">>NAME</text>
<text x="-3.81" y="-9.525" size="1.778" layer="27" ratio="10">>VALUE</text>
<rectangle x1="-0.2286" y1="-0.3048" x2="0.2286" y2="0.3048" layer="51"/>
<rectangle x1="-0.2286" y1="2.2352" x2="0.2286" y2="2.8448" layer="51"/>
<rectangle x1="-0.2286" y1="-2.8448" x2="0.2286" y2="-2.2352" layer="51"/>
</package>
<package name="SWITCH-SPDT_KIT">
<description><h3>SWITCH-SPDT_KIT</h3>
Through-hole SPDT Switch<br>
<br>
<b>Warning:</b> This is the KIT version of this package. This package has a smaller diameter top stop mask, which doesn't cover the diameter of the pad. This means only the bottom side of the pads' copper will be exposed. You'll only be able to solder to the bottom side.</description>
<wire x1="2.175" y1="5.815" x2="-2.175" y2="5.815" width="0.2032" layer="21"/>
<wire x1="-2.175" y1="5.815" x2="-2.175" y2="-5.815" width="0.2032" layer="21"/>
<wire x1="-2.175" y1="-5.815" x2="2.175" y2="-5.815" width="0.2032" layer="21"/>
<wire x1="2.175" y1="-5.815" x2="2.175" y2="5.815" width="0.2032" layer="21"/>
<pad name="1" x="0" y="2.7178" drill="1.016" diameter="1.8796" stop="no"/>
<pad name="2" x="0" y="0" drill="1.016" diameter="1.8796" stop="no"/>
<pad name="3" x="0" y="-2.7178" drill="1.016" diameter="1.8796" stop="no"/>
<text x="-3.81" y="7.62" size="1.778" layer="25" ratio="10">>NAME</text>
<text x="-3.81" y="-9.525" size="1.778" layer="27" ratio="10">>VALUE</text>
<rectangle x1="-0.2286" y1="-0.3048" x2="0.2286" y2="0.3048" layer="51"/>
<rectangle x1="-0.2286" y1="2.2352" x2="0.2286" y2="2.8448" layer="51"/>
<rectangle x1="-0.2286" y1="-2.8448" x2="0.2286" y2="-2.2352" layer="51"/>
<polygon width="0.127" layer="30">
<vertex x="-0.0178" y="1.8414" curve="-90.039946"/>
<vertex x="-0.8787" y="2.6975" curve="-90"/>
<vertex x="-0.0026" y="3.5916" curve="-90.006409"/>
<vertex x="0.8738" y="2.6975" curve="-90.03214"/>
</polygon>
<polygon width="0.127" layer="30">
<vertex x="-0.0051" y="-3.5967" curve="-90.006558"/>
<vertex x="-0.8788" y="-2.7431" curve="-90.037923"/>
<vertex x="0.0128" y="-1.8363" curve="-90.006318"/>
<vertex x="0.8814" y="-2.7432" curve="-90.038792"/>
</polygon>
<polygon width="0.127" layer="30">
<vertex x="-0.0102" y="-0.8738" curve="-90.019852"/>
<vertex x="-0.8762" y="-0.0203" curve="-90.019119"/>
<vertex x="0.0153" y="0.8789" curve="-90"/>
<vertex x="0.8739" y="-0.0077" curve="-90.038897"/>
</polygon>
<polygon width="0.127" layer="29">
<vertex x="0" y="2.2758" curve="-90.012891"/>
<vertex x="-0.4445" y="2.7" curve="-90"/>
<vertex x="0" y="3.1673" curve="-90"/>
<vertex x="0.4419" y="2.7102" curve="-90.012967"/>
</polygon>
<polygon width="0.127" layer="29">
<vertex x="0.0026" y="-3.1648" curve="-90.012891"/>
<vertex x="-0.4419" y="-2.7406" curve="-90"/>
<vertex x="0.0026" y="-2.2733" curve="-90"/>
<vertex x="0.4445" y="-2.7304" curve="-90.012967"/>
</polygon>
<polygon width="0.127" layer="29">
<vertex x="0.0102" y="-0.4471" curve="-90.012891"/>
<vertex x="-0.4343" y="-0.0229" curve="-90"/>
<vertex x="0.0102" y="0.4444" curve="-90"/>
<vertex x="0.4521" y="-0.0127" curve="-90.012967"/>
</polygon>
</package>
<package name="SWITCH-SPST-SMD-A">
<wire x1="-3.35" y1="1.3" x2="-3.35" y2="-1.3" width="0.127" layer="51"/>
<wire x1="-3.35" y1="-1.3" x2="3.35" y2="-1.3" width="0.127" layer="51"/>
<wire x1="3.35" y1="-1.3" x2="3.35" y2="1.3" width="0.127" layer="51"/>
<wire x1="3.35" y1="1.3" x2="-0.1" y2="1.3" width="0.127" layer="51"/>
<wire x1="-0.1" y1="1.3" x2="-1.4" y2="1.3" width="0.127" layer="51"/>
<wire x1="-1.4" y1="1.3" x2="-3.35" y2="1.3" width="0.127" layer="51"/>
<wire x1="-0.1" y1="1.3" x2="-0.1" y2="2.8" width="0.127" layer="51"/>
<wire x1="-0.1" y1="2.8" x2="-1.4" y2="2.8" width="0.127" layer="51"/>
<wire x1="-1.4" y1="2.8" x2="-1.4" y2="1.3" width="0.127" layer="51"/>
<wire x1="-3.35" y1="0.3" x2="-3.35" y2="-0.3" width="0.2032" layer="21"/>
<wire x1="3.35" y1="0.3" x2="3.35" y2="-0.3" width="0.2032" layer="21"/>
<wire x1="2.7" y1="1.3" x2="-2.7" y2="1.3" width="0.2032" layer="21"/>
<wire x1="1.5" y1="-1.3" x2="0" y2="-1.3" width="0.2032" layer="21"/>
<smd name="1" x="-2.25" y="-1.75" dx="0.7" dy="1.5" layer="1" rot="R180"/>
<smd name="2" x="-0.75" y="-1.75" dx="0.7" dy="1.5" layer="1" rot="R180"/>
<smd name="3" x="2.25" y="-1.75" dx="0.7" dy="1.5" layer="1" rot="R180"/>
<smd name="GND1" x="-3.65" y="1" dx="1" dy="0.6" layer="1"/>
<smd name="GND2" x="-3.65" y="-1.1" dx="1" dy="0.8" layer="1"/>
<smd name="GND3" x="3.65" y="1" dx="1" dy="0.6" layer="1"/>
<smd name="GND4" x="3.65" y="-1.1" dx="1" dy="0.8" layer="1"/>
<text x="-1.27" y="0.635" size="0.6096" layer="25">>Name</text>
<text x="-1.27" y="-1.27" size="0.6096" layer="27">>Value</text>
<hole x="-1.5" y="0" drill="0.9"/>
<hole x="1.5" y="0" drill="0.9"/>
</package>
<package name="VIBE-MOTOR-10MM">
<wire x1="-1.5" y1="-4.8" x2="-1.5" y2="-7.8" width="0.127" layer="51"/>
<wire x1="-1.5" y1="-7.8" x2="1.5" y2="-7.8" width="0.127" layer="51"/>
<wire x1="1.5" y1="-7.8" x2="1.5" y2="-4.8" width="0.127" layer="51"/>
<circle x="0" y="0" radius="5.0009" width="0.127" layer="51"/>
<pad name="+" x="-5" y="-3.9" drill="0.8" diameter="1.6764"/>
<pad name="-" x="-6.35" y="-2.54" drill="0.8" diameter="1.6764"/>
<text x="-6.8" y="-2" size="1.27" layer="21">-</text>
<text x="-4.7" y="-5.3" size="1.27" layer="21">+</text>
</package>
<package name="BUZZER-12MM">
<description><b>BUZZER</b></description>
<circle x="0" y="0" radius="5.9" width="0.2032" layer="21"/>
<circle x="0" y="0" radius="1.27" width="0.2032" layer="51"/>
<pad name="-" x="-3.25" y="0" drill="0.9" diameter="1.778"/>
<pad name="+" x="3.25" y="0" drill="0.9" diameter="1.778"/>
<text x="-2.54" y="2.54" size="0.6096" layer="25" ratio="10">>NAME</text>
<text x="-3.175" y="-3.048" size="0.6096" layer="27" ratio="10">>VALUE</text>
</package>
<package name="BUZZER-CMT1603">
<wire x1="-8" y1="8" x2="-8" y2="-8" width="0.127" layer="21"/>
<wire x1="-8" y1="-8" x2="8" y2="-8" width="0.127" layer="21"/>
<wire x1="8" y1="-8" x2="8" y2="8" width="0.127" layer="21"/>
<wire x1="8" y1="8" x2="-8" y2="8" width="0.127" layer="21"/>
<smd name="P$1" x="-9.3" y="0" dx="2.5" dy="3" layer="1"/>
<smd name="P$2" x="9.3" y="0" dx="2.5" dy="3" layer="1"/>
</package>
<package name="BUZZER-CCV">
<wire x1="2.6" y1="-6" x2="-2.6" y2="-6" width="0.127" layer="51"/>
<wire x1="2.6" y1="-6" x2="2.6" y2="-3.7" width="0.127" layer="51"/>
<wire x1="-2.6" y1="-6" x2="-2.6" y2="-3.7" width="0.127" layer="51"/>
<wire x1="-4.2" y1="1.6" x2="1.27" y2="4.318" width="0.2032" layer="21" curve="-86.141052"/>
<wire x1="3.048" y1="3.302" x2="4.191" y2="1.651" width="0.2032" layer="21" curve="-25.69541"/>
<wire x1="4.2" y1="-1.6" x2="2.6" y2="-3.7" width="0.2032" layer="21" curve="-31.605028"/>
<wire x1="-3.302" y1="-3.048" x2="-2.6" y2="-3.6" width="0.2032" layer="21" curve="12.917633"/>
<wire x1="-2.6" y1="-6" x2="2.6" y2="-6" width="0.2032" layer="21"/>
<wire x1="2.6" y1="-6" x2="2.6" y2="-3.7" width="0.2032" layer="21"/>
<wire x1="-2.6" y1="-6" x2="-2.6" y2="-3.6" width="0.2032" layer="21"/>
<circle x="0" y="0" radius="4.5" width="0.127" layer="51"/>
<smd name="-" x="-4" y="0" dx="3.2" dy="2.5" layer="1"/>
<smd name="+" x="4" y="0" dx="3.2" dy="2.5" layer="1"/>
<hole x="-3.9" y="-2.25" drill="0.8"/>
<hole x="2.25" y="3.9" drill="0.8"/>
</package>
<package name="BUZZER-CMT1102">
<wire x1="-5.5" y1="4.5" x2="5.5" y2="4.5" width="0.127" layer="51"/>
<wire x1="5.5" y1="4.5" x2="5.5" y2="-4.5" width="0.127" layer="51"/>
<wire x1="5.5" y1="-4.5" x2="-5.5" y2="-4.5" width="0.127" layer="51"/>
<wire x1="-5.5" y1="-4.5" x2="-5.5" y2="4.5" width="0.127" layer="51"/>
<wire x1="-5.5" y1="4.5" x2="-5.5" y2="2" width="0.2032" layer="21"/>
<wire x1="-5.5" y1="4.5" x2="5.5" y2="4.5" width="0.2032" layer="21"/>
<wire x1="5.5" y1="4.5" x2="5.5" y2="2" width="0.2032" layer="21"/>
<wire x1="5.5" y1="-2" x2="5.5" y2="-4.5" width="0.2032" layer="21"/>
<wire x1="5.5" y1="-4.5" x2="-5.5" y2="-4.5" width="0.2032" layer="21"/>
<wire x1="-5.5" y1="-4.5" x2="-5.5" y2="-2" width="0.2032" layer="21"/>
<smd name="1" x="-6.5" y="0" dx="3" dy="3" layer="1"/>
<smd name="2" x="6.5" y="0" dx="3" dy="3" layer="1"/>
</package>
<package name="BUZZER-12MM-NS">
<circle x="0" y="0" radius="5.9" width="0.2032" layer="51"/>
<circle x="0" y="0" radius="1.27" width="0.2032" layer="51"/>
<pad name="-" x="-3.25" y="0" drill="0.9"/>
<pad name="+" x="3.25" y="0" drill="0.9"/>
<text x="-2.54" y="2.54" size="0.6096" layer="25" ratio="10">>NAME</text>
<text x="-3.175" y="-3.048" size="0.6096" layer="27" ratio="10">>VALUE</text>
<text x="2.667" y="1.143" size="1.778" layer="51">+</text>
</package>
<package name="BUZZER-12MM-NS-KIT">
<description><h3>BUZZER-12MM-NS-KIT</h3>
Through-hole buzzer<br>
<br>
<b>Warning:</b> This is the KIT version of this package. This package has a smaller diameter top stop mask, which doesn't cover the diameter of the pad. This means only the bottom side of the pads' copper will be exposed. You'll only be able to solder to the bottom side.</description>
<circle x="0" y="0" radius="5.9" width="0.2032" layer="51"/>
<circle x="0" y="0" radius="1.27" width="0.2032" layer="51"/>
<pad name="-" x="-3.25" y="0" drill="0.9" diameter="1.8796" stop="no"/>
<pad name="+" x="3.25" y="0" drill="0.9" diameter="1.8796" stop="no"/>
<text x="-2.54" y="2.54" size="0.6096" layer="25" ratio="10">>NAME</text>
<text x="-3.175" y="-3.048" size="0.6096" layer="27" ratio="10">>VALUE</text>
<text x="2.667" y="1.143" size="1.778" layer="51">+</text>
<polygon width="0.127" layer="30">
<vertex x="3.2537" y="-0.9525" curve="-90"/>
<vertex x="2.2988" y="-0.0228" curve="-90.011749"/>
<vertex x="3.2512" y="0.9526" curve="-90"/>
<vertex x="4.2012" y="-0.0254" curve="-90.024193"/>
</polygon>
<polygon width="0.127" layer="29">
<vertex x="3.2512" y="-0.4445" curve="-90.012891"/>
<vertex x="2.8067" y="-0.0203" curve="-90"/>
<vertex x="3.2512" y="0.447" curve="-90"/>
<vertex x="3.6931" y="-0.0101" curve="-90.012967"/>
</polygon>
<polygon width="0.127" layer="30">
<vertex x="-3.2487" y="-0.9525" curve="-90"/>
<vertex x="-4.2036" y="-0.0228" curve="-90.011749"/>
<vertex x="-3.2512" y="0.9526" curve="-90"/>
<vertex x="-2.3012" y="-0.0254" curve="-90.024193"/>
</polygon>
<polygon width="0.127" layer="29">
<vertex x="-3.2512" y="-0.4445" curve="-90.012891"/>
<vertex x="-3.6957" y="-0.0203" curve="-90"/>
<vertex x="-3.2512" y="0.447" curve="-90"/>
<vertex x="-2.8093" y="-0.0101" curve="-90.012967"/>
</polygon>
</package>
<package name="BUZZER-CCV-KIT">
<description><h3>BUZZER-CCV-KIT</h3>
SMD Buzzer<br>
<br>
<b>Warning:</b> This is the KIT version of this package. This package has longer pads to aid in hand soldering.</description>
<wire x1="2.6" y1="-6" x2="-2.6" y2="-6" width="0.127" layer="51"/>
<wire x1="2.6" y1="-6" x2="2.6" y2="-3.7" width="0.127" layer="51"/>
<wire x1="-2.6" y1="-6" x2="-2.6" y2="-3.7" width="0.127" layer="51"/>
<wire x1="-4.2" y1="1.6" x2="1.27" y2="4.318" width="0.2032" layer="21" curve="-86.141052"/>
<wire x1="3.048" y1="3.302" x2="4.191" y2="1.651" width="0.2032" layer="21" curve="-25.69541"/>
<wire x1="4.2" y1="-1.6" x2="2.6" y2="-3.7" width="0.2032" layer="21" curve="-31.605028"/>
<wire x1="-3.302" y1="-3.048" x2="-2.6" y2="-3.6" width="0.2032" layer="21" curve="12.917633"/>
<wire x1="-2.6" y1="-6" x2="2.6" y2="-6" width="0.2032" layer="21"/>
<wire x1="2.6" y1="-6" x2="2.6" y2="-3.7" width="0.2032" layer="21"/>
<wire x1="-2.6" y1="-6" x2="-2.6" y2="-3.6" width="0.2032" layer="21"/>
<circle x="0" y="0" radius="4.5" width="0.127" layer="51"/>
<smd name="-" x="-4.15" y="0" dx="3.5" dy="2" layer="1"/>
<smd name="+" x="4.15" y="0" dx="3.5" dy="2" layer="1"/>
<rectangle x1="-5.2" y1="-0.75" x2="-2.9" y2="0.75" layer="51"/>
<rectangle x1="2.9" y1="-0.75" x2="5.2" y2="0.75" layer="51" rot="R180"/>
<hole x="-3.9" y="-2.25" drill="0.8"/>
<hole x="2.25" y="3.9" drill="0.8"/>
</package>
<package name="BUZZER-12MM-KIT">
<circle x="0" y="0" radius="5.9" width="0.2032" layer="21"/>
<circle x="0" y="0" radius="1.27" width="0.2032" layer="51"/>
<pad name="-" x="-3.25" y="0" drill="0.9" diameter="1.8796" stop="no"/>
<pad name="+" x="3.25" y="0" drill="0.9" diameter="1.8796" stop="no"/>
<text x="-2.54" y="2.54" size="0.6096" layer="25" ratio="10">>NAME</text>
<text x="-3.175" y="-3.048" size="0.6096" layer="27" ratio="10">>VALUE</text>
<text x="2.667" y="1.143" size="1.778" layer="51">+</text>
<polygon width="0.127" layer="30">
<vertex x="3.2537" y="-0.9525" curve="-90"/>
<vertex x="2.2988" y="-0.0228" curve="-90.011749"/>
<vertex x="3.2512" y="0.9526" curve="-90"/>
<vertex x="4.2012" y="-0.0254" curve="-90.024193"/>
</polygon>
<polygon width="0.127" layer="29">
<vertex x="3.2512" y="-0.4445" curve="-90.012891"/>
<vertex x="2.8067" y="-0.0203" curve="-90"/>
<vertex x="3.2512" y="0.447" curve="-90"/>
<vertex x="3.6931" y="-0.0101" curve="-90.012967"/>
</polygon>
<polygon width="0.127" layer="30">
<vertex x="-3.2487" y="-0.9525" curve="-90"/>
<vertex x="-4.2036" y="-0.0228" curve="-90.011749"/>
<vertex x="-3.2512" y="0.9526" curve="-90"/>
<vertex x="-2.3012" y="-0.0254" curve="-90.024193"/>
</polygon>
<polygon width="0.127" layer="29">
<vertex x="-3.2512" y="-0.4445" curve="-90.012891"/>
<vertex x="-3.6957" y="-0.0203" curve="-90"/>
<vertex x="-3.2512" y="0.447" curve="-90"/>
<vertex x="-2.8093" y="-0.0101" curve="-90.012967"/>
</polygon>
</package>
</packages>
<symbols>
<symbol name="TOGGLE">
<wire x1="0" y1="0" x2="2.54" y2="1.27" width="0.254" layer="94"/>
<wire x1="2.54" y1="-2.54" x2="3.175" y2="-2.54" width="0.127" layer="94"/>
<wire x1="2.54" y1="2.54" x2="3.175" y2="2.54" width="0.1524" layer="94"/>
<circle x="2.54" y="2.54" radius="0.3592" width="0.2032" layer="94"/>
<circle x="2.54" y="-2.54" radius="0.3592" width="0.2032" layer="94"/>
<circle x="0" y="0" radius="0.3592" width="0.2032" layer="94"/>
<text x="-1.905" y="-6.35" size="1.778" layer="95">>NAME</text>
<text x="-2.54" y="3.81" size="1.778" layer="96">>VALUE</text>
<pin name="P" x="-2.54" y="0" visible="off" length="short" direction="pas"/>
<pin name="S" x="5.08" y="-2.54" visible="off" length="short" direction="pas" rot="R180"/>
<pin name="O" x="5.08" y="2.54" visible="off" length="short" direction="pas" rot="R180"/>
</symbol>
<symbol name="MOTOR">
<wire x1="-1.27" y1="3.81" x2="-1.27" y2="1.778" width="0.2032" layer="94"/>
<wire x1="-1.27" y1="3.81" x2="0" y2="3.81" width="0.2032" layer="94"/>
<wire x1="0" y1="3.81" x2="1.27" y2="3.81" width="0.2032" layer="94"/>
<wire x1="1.27" y1="3.81" x2="1.27" y2="1.778" width="0.2032" layer="94"/>
<wire x1="1.27" y1="-3.81" x2="1.27" y2="-1.778" width="0.2032" layer="94"/>
<wire x1="1.27" y1="-3.81" x2="0" y2="-3.81" width="0.2032" layer="94"/>
<wire x1="0" y1="-3.81" x2="-1.27" y2="-3.81" width="0.2032" layer="94"/>
<wire x1="-1.27" y1="-3.81" x2="-1.27" y2="-1.778" width="0.2032" layer="94"/>
<wire x1="0" y1="5.08" x2="0" y2="3.81" width="0.1524" layer="94"/>
<wire x1="0" y1="-5.08" x2="0" y2="-3.81" width="0.1524" layer="94"/>
<wire x1="0.254" y1="3.302" x2="-0.254" y2="3.302" width="0.1524" layer="94"/>
<wire x1="0" y1="3.556" x2="0" y2="3.048" width="0.1524" layer="94"/>
<wire x1="0.254" y1="-3.302" x2="-0.254" y2="-3.302" width="0.1524" layer="94"/>
<circle x="0" y="0" radius="2.032" width="0.254" layer="94"/>
<text x="2.54" y="0" size="1.778" layer="95">>NAME</text>
<text x="2.54" y="-2.54" size="1.778" layer="96">>VALUE</text>
<pin name="+" x="0" y="5.08" visible="off" length="point" rot="R270"/>
<pin name="-" x="0" y="-5.08" visible="off" length="point" rot="R270"/>
</symbol>
<symbol name="BUZZER">
<wire x1="-1.27" y1="1.905" x2="0" y2="1.905" width="0.1524" layer="94"/>
<wire x1="0" y1="1.905" x2="0" y2="2.54" width="0.1524" layer="94"/>
<wire x1="0" y1="1.905" x2="0" y2="1.27" width="0.1524" layer="94"/>
<wire x1="0.635" y1="3.175" x2="0.635" y2="0.635" width="0.1524" layer="94"/>
<wire x1="0.635" y1="0.635" x2="1.905" y2="0.635" width="0.1524" layer="94"/>
<wire x1="1.905" y1="0.635" x2="1.905" y2="3.175" width="0.1524" layer="94"/>
<wire x1="1.905" y1="3.175" x2="0.635" y2="3.175" width="0.1524" layer="94"/>
<wire x1="2.54" y1="2.54" x2="2.54" y2="1.905" width="0.1524" layer="94"/>
<wire x1="2.54" y1="1.905" x2="3.81" y2="1.905" width="0.1524" layer="94"/>
<wire x1="2.54" y1="1.905" x2="2.54" y2="1.27" width="0.1524" layer="94"/>
<wire x1="5.08" y1="0" x2="5.08" y2="3.81" width="0.254" layer="94"/>
<wire x1="5.08" y1="3.81" x2="5.715" y2="3.81" width="0.254" layer="94"/>
<wire x1="5.715" y1="3.81" x2="5.715" y2="4.445" width="0.254" layer="94"/>
<wire x1="5.715" y1="4.445" x2="-3.175" y2="4.445" width="0.254" layer="94"/>
<wire x1="-3.175" y1="4.445" x2="-3.175" y2="3.81" width="0.254" layer="94"/>
<wire x1="-3.175" y1="3.81" x2="-2.54" y2="3.81" width="0.254" layer="94"/>
<wire x1="-2.54" y1="3.81" x2="-2.54" y2="0" width="0.254" layer="94"/>
<wire x1="-2.54" y1="3.81" x2="5.08" y2="3.81" width="0.254" layer="94"/>
<wire x1="-2.54" y1="0" x2="5.08" y2="0" width="0.254" layer="94"/>
<text x="-2.54" y="5.08" size="1.778" layer="95">>NAME</text>
<text x="6.35" y="0" size="1.778" layer="96">>VALUE</text>
<pin name="2" x="2.54" y="-2.54" visible="off" length="short" direction="pas" rot="R90"/>
<pin name="1" x="0" y="-2.54" visible="off" length="short" direction="pas" rot="R90"/>
</symbol>
</symbols>
<devicesets>
<deviceset name="SWITCH-SPDT" prefix="S" uservalue="yes">
<description><b>SPDT Switch</b><br>
Simple slide switch, Spark Fun Electronics SKU : COM-00102<br>
DPDT SMT slide switch, AYZ0202, SWCH-08179</description>
<gates>
<gate name="1" symbol="TOGGLE" x="-2.54" y="0"/>
</gates>
<devices>
<device name="PTH" package="SWITCH-SPDT">
<connects>
<connect gate="1" pin="O" pad="1"/>
<connect gate="1" pin="P" pad="2"/>
<connect gate="1" pin="S" pad="3"/>
</connects>
<technologies>
<technology name="">
<attribute name="PROD_ID" value="SWCH-08261"/>
</technology>
</technologies>
</device>
<device name="SMD" package="AYZ0202">
<connects>
<connect gate="1" pin="O" pad="1"/>
<connect gate="1" pin="P" pad="2"/>
<connect gate="1" pin="S" pad="3"/>
</connects>
<technologies>
<technology name="">
<attribute name="PROD_ID" value="SWCH-08179" constant="no"/>
<attribute name="SF_ID" value="COM-00597" constant="no"/>
</technology>
</technologies>
</device>
<device name="PTH2" package="SWITCHE-DPDT">
<connects>
<connect gate="1" pin="O" pad="1"/>
<connect gate="1" pin="P" pad="2"/>
<connect gate="1" pin="S" pad="3"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
<device name="PTH3" package="R_SW_TH">
<connects>
<connect gate="1" pin="O" pad="P$1"/>
<connect gate="1" pin="P" pad="P$2"/>
<connect gate="1" pin="S" pad="P$3"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
<device name="SMD2" package="SWITCH-SPDT-SMD">
<connects>
<connect gate="1" pin="O" pad="1"/>
<connect gate="1" pin="P" pad="2"/>
<connect gate="1" pin="S" pad="3"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
<device name="PTH_LOCK" package="SWITCH-SPDT_LOCK.007S">
<connects>
<connect gate="1" pin="O" pad="1"/>
<connect gate="1" pin="P" pad="2"/>
<connect gate="1" pin="S" pad="3"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
<device name="KIT" package="SWITCH-SPDT_KIT">
<connects>
<connect gate="1" pin="O" pad="1"/>
<connect gate="1" pin="P" pad="2"/>
<connect gate="1" pin="S" pad="3"/>
</connects>
<technologies>
<technology name="">
<attribute name="PROD_ID" value="SWCH-08261" constant="no"/>
</technology>
</technologies>
</device>
<device name="-SMD-A" package="SWITCH-SPST-SMD-A">
<connects>
<connect gate="1" pin="O" pad="1"/>
<connect gate="1" pin="P" pad="2"/>
<connect gate="1" pin="S" pad="3"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
</devices>
</deviceset>
<deviceset name="MOTOR">
<description><b>Vibration Motor- ROB-08449</b>
Physical dimension and wire connections for this powerful vibration motor. Motor has a self adhesive backing.</description>
<gates>
<gate name="G$1" symbol="MOTOR" x="0" y="0"/>
</gates>
<devices>
<device name="10MM" package="VIBE-MOTOR-10MM">
<connects>
<connect gate="G$1" pin="+" pad="+"/>
<connect gate="G$1" pin="-" pad="-"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
</devices>
</deviceset>
<deviceset name="BUZZER" prefix="SG">
<description><b>Buzzer 12mm</b>
Spark Fun Electronics SKU : Comp-Buzzer</description>
<gates>
<gate name="G$1" symbol="BUZZER" x="0" y="0"/>
</gates>
<devices>
<device name="PTH" package="BUZZER-12MM">
<connects>
<connect gate="G$1" pin="1" pad="+"/>
<connect gate="G$1" pin="2" pad="-"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
<device name="SMD" package="BUZZER-CMT1603">
<connects>
<connect gate="G$1" pin="1" pad="P$1"/>
<connect gate="G$1" pin="2" pad="P$2"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
<device name="SMD2" package="BUZZER-CCV">
<connects>
<connect gate="G$1" pin="1" pad="+"/>
<connect gate="G$1" pin="2" pad="-"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
<device name="SMD3" package="BUZZER-CMT1102">
<connects>
<connect gate="G$1" pin="1" pad="1"/>
<connect gate="G$1" pin="2" pad="2"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
<device name="NS" package="BUZZER-12MM-NS">
<connects>
<connect gate="G$1" pin="1" pad="+"/>
<connect gate="G$1" pin="2" pad="-"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
<device name="PTH-NS-KIT" package="BUZZER-12MM-NS-KIT">
<connects>
<connect gate="G$1" pin="1" pad="+"/>
<connect gate="G$1" pin="2" pad="-"/>
</connects>
<technologies>
<technology name="">
<attribute name="PROD_ID" value="COMP-08253" constant="no"/>
</technology>
</technologies>
</device>
<device name="SMD2-KIT" package="BUZZER-CCV-KIT">
<connects>
<connect gate="G$1" pin="1" pad="+"/>
<connect gate="G$1" pin="2" pad="-"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
<device name="PTH-KIT" package="BUZZER-12MM-KIT">
<connects>
<connect gate="G$1" pin="1" pad="+"/>
<connect gate="G$1" pin="2" pad="-"/>
</connects>
<technologies>
<technology name="">
<attribute name="PROD_ID" value="COMP-08253" constant="no"/>
</technology>
</technologies>
</device>
</devices>
</deviceset>
</devicesets>
</library>
<library name="SparkFun-PowerIC">
<description><h3>SparkFun Electronics' preferred foot prints</h3>
In this library you'll find drivers, regulators, and amplifiers.<br><br>
We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com.
<br><br>
<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/
<br><br>
You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage.</description>
<packages>
<package name="SSOP24">
<wire x1="-4.25" y1="2.5" x2="4.25" y2="2.5" width="0.2032" layer="21"/>
<wire x1="4.25" y1="2.5" x2="4.25" y2="-2.5" width="0.2032" layer="21"/>
<wire x1="4.25" y1="-2.5" x2="-4.25" y2="-2.5" width="0.2032" layer="21"/>
<wire x1="-4.25" y1="-2.5" x2="-4.25" y2="2.5" width="0.2032" layer="21"/>
<circle x="-4.826" y="-3.048" radius="0.2231" width="0.2032" layer="21"/>
<smd name="24" x="-3.575" y="3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="23" x="-2.925" y="3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="22" x="-2.275" y="3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="20" x="-0.975" y="3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="21" x="-1.625" y="3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="19" x="-0.325" y="3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="18" x="0.325" y="3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="17" x="0.975" y="3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="16" x="1.625" y="3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="15" x="2.275" y="3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="1" x="-3.575" y="-3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="2" x="-2.925" y="-3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="3" x="-2.275" y="-3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="4" x="-1.625" y="-3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="5" x="-0.975" y="-3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="6" x="-0.325" y="-3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="7" x="0.325" y="-3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="8" x="0.975" y="-3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="9" x="1.625" y="-3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="10" x="2.275" y="-3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="11" x="2.925" y="-3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="12" x="3.575" y="-3.656" dx="0.348" dy="1.397" layer="1"/>
<smd name="13" x="3.575" y="3.656" dx="0.348" dy="1.397" layer="1" rot="R180"/>
<smd name="14" x="2.925" y="3.656" dx="0.348" dy="1.397" layer="1" rot="R180"/>
<text x="-3.81" y="1.27" size="0.4064" layer="25">>NAME</text>
<text x="-3.81" y="0" size="0.4064" layer="27">>VALUE</text>
</package>
</packages>
<symbols>
<symbol name="TB6612FNG">
<wire x1="-12.7" y1="-17.78" x2="10.16" y2="-17.78" width="0.4064" layer="94"/>
<wire x1="10.16" y1="-17.78" x2="10.16" y2="15.24" width="0.4064" layer="94"/>
<wire x1="10.16" y1="15.24" x2="-12.7" y2="15.24" width="0.6096" layer="94"/>
<wire x1="-12.7" y1="15.24" x2="-12.7" y2="-17.78" width="0.4064" layer="94"/>
<text x="-10.16" y="16.51" size="1.778" layer="95">>NAME</text>
<text x="-10.16" y="-20.32" size="1.778" layer="96">>VALUE</text>
<pin name="MA1" x="-15.24" y="5.08" visible="pin" length="short" direction="out"/>
<pin name="PGND1" x="-15.24" y="0" visible="pin" length="short" direction="pwr"/>
<pin name="MA2" x="-15.24" y="2.54" visible="pin" length="short" direction="out"/>
<pin name="MB2" x="-15.24" y="-5.08" visible="pin" length="short" direction="out" swaplevel="1"/>
<pin name="PGND2" x="-15.24" y="-2.54" visible="pin" length="short" direction="pwr"/>
<pin name="MB1" x="-15.24" y="-7.62" visible="pin" length="short" direction="out" swaplevel="1"/>
<pin name="PWMB" x="12.7" y="-5.08" visible="pin" length="short" direction="in" swaplevel="1" rot="R180"/>
<pin name="BIN2" x="12.7" y="-2.54" visible="pin" length="short" direction="in" swaplevel="1" rot="R180"/>
<pin name="BIN1" x="12.7" y="0" visible="pin" length="short" direction="in" swaplevel="1" rot="R180"/>
<pin name="GND" x="12.7" y="-7.62" visible="pin" length="short" direction="pwr" rot="R180"/>
<pin name="STBY" x="12.7" y="2.54" visible="pin" length="short" rot="R180"/>
<pin name="VCC" x="12.7" y="-10.16" visible="pin" length="short" direction="pwr" rot="R180"/>
<pin name="AIN1" x="12.7" y="5.08" visible="pin" length="short" direction="in" rot="R180"/>
<pin name="AIN2" x="12.7" y="7.62" visible="pin" length="short" direction="in" rot="R180"/>
<pin name="PWMA" x="12.7" y="10.16" visible="pin" length="short" direction="in" rot="R180"/>
<pin name="VM" x="12.7" y="-12.7" visible="pin" length="short" direction="pwr" rot="R180"/>
<pin name="VM+" x="7.62" y="-20.32" visible="off" length="short" direction="pwr" rot="R90"/>
<pin name="VM-" x="5.08" y="-20.32" visible="off" length="short" direction="pwr" rot="R90"/>
</symbol>
</symbols>
<devicesets>
<deviceset name="TB6612FNG">
<description>Toshiba 1A dual motor driver
IC-09363</description>
<gates>
<gate name="G$1" symbol="TB6612FNG" x="0" y="0"/>
</gates>
<devices>
<device name="" package="SSOP24">
<connects>
<connect gate="G$1" pin="AIN1" pad="21"/>
<connect gate="G$1" pin="AIN2" pad="22"/>
<connect gate="G$1" pin="BIN1" pad="17"/>
<connect gate="G$1" pin="BIN2" pad="16"/>
<connect gate="G$1" pin="GND" pad="18"/>
<connect gate="G$1" pin="MA1" pad="1"/>
<connect gate="G$1" pin="MA2" pad="5"/>
<connect gate="G$1" pin="MB1" pad="11"/>
<connect gate="G$1" pin="MB2" pad="7"/>
<connect gate="G$1" pin="PGND1" pad="3"/>
<connect gate="G$1" pin="PGND2" pad="9"/>
<connect gate="G$1" pin="PWMA" pad="23"/>
<connect gate="G$1" pin="PWMB" pad="15"/>
<connect gate="G$1" pin="STBY" pad="19"/>
<connect gate="G$1" pin="VCC" pad="20"/>
<connect gate="G$1" pin="VM" pad="24"/>
<connect gate="G$1" pin="VM+" pad="13"/>
<connect gate="G$1" pin="VM-" pad="10"/>
</connects>
<technologies>
<technology name="">
<attribute name="PROD_ID" value="IC-09363"/>
<attribute name="VALUE" value="TB6612FNG"/>
</technology>
</technologies>
</device>
</devices>
</deviceset>
</devicesets>
</library>
<library name="switch-coto">
<description><b>COTO TECHNOLOGY</b><p>
Reed switch<br>
<author>Created by librarian@cadsoft.de</author></description>
<packages>
<package name="CT10-XXXX-A2">
<description><b>CT10 Series Molded Switch</b><p>
Source: www.cotorelay.com .. Coto_Technology__CT10-1530-G1.pdf</description>
<wire x1="-6.275" y1="1.1" x2="6.3" y2="1.1" width="0.2032" layer="21"/>
<wire x1="6.3" y1="1.1" x2="6.3" y2="-1.1" width="0.2032" layer="21"/>
<wire x1="6.3" y1="-1.1" x2="-6.3" y2="-1.1" width="0.2032" layer="21"/>
<wire x1="-6.3" y1="-1.1" x2="-6.3" y2="1.1" width="0.2032" layer="21"/>
<wire x1="-6.5" y1="-1.3" x2="-6.5" y2="1.3" width="0" layer="20"/>
<wire x1="-6.5" y1="1.3" x2="6.5" y2="1.3" width="0" layer="20"/>
<wire x1="6.5" y1="1.3" x2="6.5" y2="-1.3" width="0" layer="20"/>
<wire x1="6.5" y1="-1.3" x2="-6.5" y2="-1.3" width="0" layer="20"/>
<smd name="1" x="-7.5" y="0" dx="1.8" dy="1.8" layer="1"/>
<smd name="2" x="7.5" y="0" dx="1.8" dy="1.8" layer="1"/>
<text x="-8.32" y="1.3302" size="1.27" layer="25">>NAME</text>
<text x="-8.32" y="-3.1082" size="1.27" layer="27">>VALUE</text>
<rectangle x1="-7.85" y1="-0.575" x2="-6.25" y2="0.575" layer="51"/>
<rectangle x1="6.3" y1="-0.575" x2="7.85" y2="0.575" layer="51"/>
</package>
<package name="CT10-XXXX-G1">
<description><b>CT10 Series Molded Switch</b><p>
Source: www.cotorelay.com .. Coto_Technology__CT10-1530-G1.pdf</description>
<wire x1="-6.275" y1="1.1" x2="6.3" y2="1.1" width="0.2032" layer="21"/>
<wire x1="6.3" y1="1.1" x2="6.3" y2="-1.1" width="0.2032" layer="21"/>
<wire x1="6.3" y1="-1.1" x2="-6.3" y2="-1.1" width="0.2032" layer="21"/>
<wire x1="-6.3" y1="-1.1" x2="-6.3" y2="1.1" width="0.2032" layer="21"/>
<smd name="1" x="-7.625" y="0" dx="1.8" dy="1.8" layer="1"/>
<smd name="2" x="7.625" y="0" dx="1.8" dy="1.8" layer="1"/>
<text x="-8.32" y="1.3302" size="1.27" layer="25">>NAME</text>
<text x="-8.32" y="-3.1082" size="1.27" layer="27">>VALUE</text>
<rectangle x1="-8.2" y1="-0.575" x2="-6.4" y2="0.575" layer="51"/>
<rectangle x1="6.4" y1="-0.575" x2="8.2" y2="0.575" layer="51"/>
</package>
<package name="CT10-XXXX-G4">
<description><b>CT10 Series Molded Switch</b><p>
Source: www.cotorelay.com .. Coto_Technology__CT10-1530-G1.pdf</description>
<wire x1="-6.275" y1="1.1" x2="6.3" y2="1.1" width="0.2032" layer="21"/>
<wire x1="6.3" y1="1.1" x2="6.3" y2="-1.1" width="0.2032" layer="21"/>
<wire x1="6.3" y1="-1.1" x2="-6.3" y2="-1.1" width="0.2032" layer="21"/>
<wire x1="-6.3" y1="-1.1" x2="-6.3" y2="1.1" width="0.2032" layer="21"/>
<smd name="1" x="-9.2" y="0" dx="1.8" dy="1.8" layer="1"/>
<smd name="2" x="9.225" y="0" dx="1.8" dy="1.8" layer="1"/>
<text x="-8.32" y="1.3302" size="1.27" layer="25">>NAME</text>
<text x="-8.32" y="-3.1082" size="1.27" layer="27">>VALUE</text>
<rectangle x1="-9.8" y1="-0.575" x2="-6.4" y2="0.575" layer="51"/>
<rectangle x1="6.4" y1="-0.575" x2="9.8" y2="0.575" layer="51"/>
</package>
</packages>
<symbols>
<symbol name="SWITCH-NO">
<wire x1="-2.54" y1="0" x2="2.54" y2="0.889" width="0.254" layer="94"/>
<circle x="-2.54" y="0" radius="0.2839" width="0" layer="94"/>
<circle x="2.54" y="0" radius="0.2839" width="0" layer="94"/>
<text x="-3.81" y="2.54" size="1.778" layer="95">>NAME</text>
<text x="-3.81" y="-3.81" size="1.778" layer="96">>VALUE</text>
<pin name="1" x="-5.08" y="0" visible="pad" length="short" direction="pas"/>
<pin name="2" x="5.08" y="0" visible="pad" length="short" direction="pas" rot="R180"/>
</symbol>
</symbols>
<devicesets>
<deviceset name="CT10-XXXX-" prefix="SW">
<description><b>CT10 Series Molded Switch</b><p>
Source: www.cotorelay.com .. Coto_Technology__CT10-1530-G1.pdf</description>
<gates>
<gate name="G$1" symbol="SWITCH-NO" x="0" y="0"/>
</gates>
<devices>
<device name="A2" package="CT10-XXXX-A2">
<connects>
<connect gate="G$1" pin="1" pad="1"/>
<connect gate="G$1" pin="2" pad="2"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
<device name="G1" package="CT10-XXXX-G1">
<connects>
<connect gate="G$1" pin="1" pad="1"/>
<connect gate="G$1" pin="2" pad="2"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
<device name="G4" package="CT10-XXXX-G4">
<connects>
<connect gate="G$1" pin="1" pad="1"/>
<connect gate="G$1" pin="2" pad="2"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
</devices>
</deviceset>
</devicesets>
</library>
<library name="SparkFun-Resistors">
<description><h3>SparkFun Electronics' preferred foot prints</h3>
In this library you'll find resistors, capacitors, inductors, test points, jumper pads, etc.<br><br>
We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com.
<br><br>
<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/
<br><br>
You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage.</description>
<packages>
<package name="0603-RES">
<wire x1="-1.6002" y1="0.6858" x2="1.6002" y2="0.6858" width="0.0508" layer="39"/>
<wire x1="1.6002" y1="0.6858" x2="1.6002" y2="-0.6858" width="0.0508" layer="39"/>
<wire x1="1.6002" y1="-0.6858" x2="-1.6002" y2="-0.6858" width="0.0508" layer="39"/>
<wire x1="-1.6002" y1="-0.6858" x2="-1.6002" y2="0.6858" width="0.0508" layer="39"/>
<wire x1="-0.356" y1="0.432" x2="0.356" y2="0.432" width="0.1016" layer="51"/>
<wire x1="-0.356" y1="-0.419" x2="0.356" y2="-0.419" width="0.1016" layer="51"/>
<smd name="1" x="-0.85" y="0" dx="1.1" dy="1" layer="1"/>
<smd name="2" x="0.85" y="0" dx="1.1" dy="1" layer="1"/>
<text x="-0.889" y="0.762" size="0.4064" layer="25" font="vector">>NAME</text>
<text x="-1.016" y="-1.143" size="0.4064" layer="27" font="vector">>VALUE</text>
<rectangle x1="-0.8382" y1="-0.4699" x2="-0.3381" y2="0.4801" layer="51"/>
<rectangle x1="0.3302" y1="-0.4699" x2="0.8303" y2="0.4801" layer="51"/>
<rectangle x1="-0.1999" y1="-0.3" x2="0.1999" y2="0.3" layer="35"/>
<rectangle x1="-0.1905" y1="-0.381" x2="0.1905" y2="0.381" layer="21"/>
</package>
</packages>
<symbols>
<symbol name="RESISTOR">
<wire x1="-2.54" y1="0" x2="-2.159" y2="1.016" width="0.1524" layer="94"/>
<wire x1="-2.159" y1="1.016" x2="-1.524" y2="-1.016" width="0.1524" layer="94"/>
<wire x1="-1.524" y1="-1.016" x2="-0.889" y2="1.016" width="0.1524" layer="94"/>
<wire x1="-0.889" y1="1.016" x2="-0.254" y2="-1.016" width="0.1524" layer="94"/>
<wire x1="-0.254" y1="-1.016" x2="0.381" y2="1.016" width="0.1524" layer="94"/>
<wire x1="0.381" y1="1.016" x2="1.016" y2="-1.016" width="0.1524" layer="94"/>
<wire x1="1.016" y1="-1.016" x2="1.651" y2="1.016" width="0.1524" layer="94"/>
<wire x1="1.651" y1="1.016" x2="2.286" y2="-1.016" width="0.1524" layer="94"/>
<wire x1="2.286" y1="-1.016" x2="2.54" y2="0" width="0.1524" layer="94"/>
<text x="-3.81" y="1.4986" size="1.778" layer="95">>NAME</text>
<text x="-3.81" y="-3.302" size="1.778" layer="96">>VALUE</text>
<pin name="2" x="5.08" y="0" visible="off" length="short" direction="pas" swaplevel="1" rot="R180"/>
<pin name="1" x="-5.08" y="0" visible="off" length="short" direction="pas" swaplevel="1"/>
</symbol>
</symbols>
<devicesets>
<deviceset name="680OHM1/10W5%(0603)" prefix="R" uservalue="yes">
<description>RES-09333</description>
<gates>
<gate name="G$1" symbol="RESISTOR" x="0" y="0"/>
</gates>
<devices>
<device name="" package="0603-RES">
<connects>
<connect gate="G$1" pin="1" pad="1"/>
<connect gate="G$1" pin="2" pad="2"/>
</connects>
<technologies>
<technology name="">
<attribute name="PROD_ID" value="RES-09333"/>
<attribute name="VALUE" value="680" constant="no"/>
</technology>
</technologies>
</device>
</devices>
</deviceset>
</devicesets>
</library>
<library name="SparkFun-Boards">
<description><h3>SparkFun Electronics' preferred foot prints</h3>
In this library you'll find boards and modules: Arduino footprints, breadboards, non-RF modules, etc.<br><br>
We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com.
<br><br>
<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/
<br><br>
You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage.</description>
<packages>
<package name="ARDUINO_R3">
<description>Arduino Uno Footprint R3</description>
<wire x1="0" y1="0" x2="0" y2="53.34" width="0.2032" layer="51"/>
<wire x1="0" y1="53.34" x2="64.516" y2="53.34" width="0.2032" layer="51"/>
<wire x1="64.516" y1="53.34" x2="66.04" y2="51.816" width="0.2032" layer="51"/>
<wire x1="66.04" y1="51.816" x2="66.04" y2="40.386" width="0.2032" layer="51"/>
<wire x1="66.04" y1="40.386" x2="68.58" y2="37.846" width="0.2032" layer="51"/>
<wire x1="68.58" y1="37.846" x2="68.58" y2="5.08" width="0.2032" layer="51"/>
<wire x1="68.58" y1="5.08" x2="66.04" y2="2.54" width="0.2032" layer="51"/>
<wire x1="66.04" y1="2.54" x2="66.04" y2="0" width="0.2032" layer="51"/>
<wire x1="66.04" y1="0" x2="0" y2="0" width="0.2032" layer="51"/>
<hole x="15.24" y="50.8" drill="3.175"/>
<hole x="66.04" y="35.56" drill="3.175"/>
<hole x="66.04" y="7.62" drill="3.175"/>
<hole x="13.97" y="2.54" drill="3.175"/>
<pad name="NC" x="27.94" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="IOREF" x="30.48" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="RESET@1" x="33.02" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="3.3V" x="35.56" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="5V" x="38.1" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="GND@1" x="40.64" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="GND@2" x="43.18" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="VIN" x="45.72" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="A0" x="50.8" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="A1" x="53.34" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="A2" x="55.88" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="A3" x="58.42" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="A4" x="60.96" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="A5" x="63.5" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="D0" x="63.5" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D1" x="60.96" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D2" x="58.42" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D3" x="55.88" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D4" x="53.34" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D5" x="50.8" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D6" x="48.26" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D7" x="45.72" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D8" x="41.656" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D9" x="39.116" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D10" x="36.576" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D11" x="34.036" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D12" x="31.496" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D13" x="28.956" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="GND@3" x="26.416" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="AREF" x="23.876" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="SDA" x="21.336" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="SCL" x="18.796" y="50.8" drill="1.016" diameter="1.9304"/>
<wire x1="-6.35" y1="43.815" x2="9.525" y2="43.815" width="0.2032" layer="51"/>
<wire x1="9.525" y1="43.815" x2="9.525" y2="32.385" width="0.2032" layer="51"/>
<wire x1="9.525" y1="32.385" x2="-6.35" y2="32.385" width="0.2032" layer="51"/>
<wire x1="-6.35" y1="32.385" x2="-6.35" y2="43.815" width="0.2032" layer="51"/>
<wire x1="-1.905" y1="3.175" x2="-1.905" y2="12.065" width="0.2032" layer="51"/>
<wire x1="-1.905" y1="12.065" x2="11.43" y2="12.065" width="0.2032" layer="51"/>
<wire x1="11.43" y1="12.065" x2="11.43" y2="3.175" width="0.2032" layer="51"/>
<wire x1="11.43" y1="3.175" x2="-1.905" y2="3.175" width="0.2032" layer="51"/>
<pad name="MISO" x="63.64000625" y="30.4299875" drill="1.016" diameter="1.9304"/>
<pad name="VCC" x="66.18000625" y="30.4299875" drill="1.016" diameter="1.9304"/>
<pad name="SCK" x="63.64000625" y="27.8899875" drill="1.016" diameter="1.9304"/>
<pad name="MOSI" x="66.18000625" y="27.8899875" drill="1.016" diameter="1.9304"/>
<pad name="RESET@2" x="63.64000625" y="25.3499875" drill="1.016" diameter="1.9304"/>
<pad name="GND@4" x="66.18000625" y="25.3499875" drill="1.016" diameter="1.9304"/>
<text x="18.796" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">SCL</text>
<text x="21.336" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">SDA</text>
<text x="23.876" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">AREF</text>
<text x="26.416" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">GND</text>
<text x="28.956" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D13</text>
<text x="31.496" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D12</text>
<text x="34.036" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D11</text>
<text x="36.576" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D10</text>
<text x="39.116" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D9</text>
<text x="41.656" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D8</text>
<text x="45.72" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D7</text>
<text x="48.26" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D6</text>
<text x="50.8" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D5</text>
<text x="53.34" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D4</text>
<text x="55.88" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D3</text>
<text x="58.42" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D2</text>
<text x="63.5" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D0/RXI</text>
<text x="60.96" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D1/TXO</text>
<text x="33.02" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">!RESET!</text>
<text x="35.56" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">3.3V</text>
<text x="38.1" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">5V</text>
<text x="40.64" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">GND</text>
<text x="43.18" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">GND</text>
<text x="45.72" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">VIN</text>
<text x="50.8" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">A0</text>
<text x="53.34" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">A1</text>
<text x="55.88" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">A2</text>
<text x="58.42" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">A3</text>
<text x="60.96" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">A4</text>
<text x="63.5" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">A5</text>
<text x="30.48" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">IOREF</text>
<text x="62.23" y="30.48" size="0.8128" layer="51" font="vector" ratio="15" align="center-right">MISO</text>
<text x="62.23" y="27.94" size="0.8128" layer="51" font="vector" ratio="15" align="center-right">SCK</text>
<text x="62.23" y="25.4" size="0.8128" layer="51" font="vector" ratio="15" align="center-right">RST</text>
<text x="67.31" y="25.4" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="top-center">GND</text>
<text x="67.31" y="27.94" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="top-center">MOSI</text>
<text x="67.31" y="30.48" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="top-center">5V</text>
</package>
<package name="ARDUINO_R3_NO_HOLES">
<wire x1="0" y1="0" x2="0" y2="53.34" width="0.2032" layer="51"/>
<wire x1="0" y1="53.34" x2="64.516" y2="53.34" width="0.2032" layer="51"/>
<wire x1="64.516" y1="53.34" x2="66.04" y2="51.816" width="0.2032" layer="51"/>
<wire x1="66.04" y1="51.816" x2="66.04" y2="40.386" width="0.2032" layer="51"/>
<wire x1="66.04" y1="40.386" x2="68.58" y2="37.846" width="0.2032" layer="51"/>
<wire x1="68.58" y1="37.846" x2="68.58" y2="5.08" width="0.2032" layer="51"/>
<wire x1="68.58" y1="5.08" x2="66.04" y2="2.54" width="0.2032" layer="51"/>
<wire x1="66.04" y1="2.54" x2="66.04" y2="0" width="0.2032" layer="51"/>
<wire x1="66.04" y1="0" x2="0" y2="0" width="0.2032" layer="51"/>
<pad name="NC" x="27.94" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="IOREF" x="30.48" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="RESET@1" x="33.02" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="3.3V" x="35.56" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="5V" x="38.1" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="GND@1" x="40.64" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="GND@2" x="43.18" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="VIN" x="45.72" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="A0" x="50.8" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="A1" x="53.34" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="A2" x="55.88" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="A3" x="58.42" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="A4" x="60.96" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="A5" x="63.5" y="2.54" drill="1.016" diameter="1.9304"/>
<pad name="D0" x="63.5" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D1" x="60.96" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D2" x="58.42" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D3" x="55.88" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D4" x="53.34" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D5" x="50.8" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D6" x="48.26" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D7" x="45.72" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D8" x="41.656" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D9" x="39.116" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D10" x="36.576" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D11" x="34.036" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D12" x="31.496" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="D13" x="28.956" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="GND@3" x="26.416" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="AREF" x="23.876" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="SDA" x="21.336" y="50.8" drill="1.016" diameter="1.9304"/>
<pad name="SCL" x="18.796" y="50.8" drill="1.016" diameter="1.9304"/>
<wire x1="-6.35" y1="43.815" x2="9.525" y2="43.815" width="0.2032" layer="51"/>
<wire x1="9.525" y1="43.815" x2="9.525" y2="32.385" width="0.2032" layer="51"/>
<wire x1="9.525" y1="32.385" x2="-6.35" y2="32.385" width="0.2032" layer="51"/>
<wire x1="-6.35" y1="32.385" x2="-6.35" y2="43.815" width="0.2032" layer="51"/>
<wire x1="-1.905" y1="3.175" x2="-1.905" y2="12.065" width="0.2032" layer="51"/>
<wire x1="-1.905" y1="12.065" x2="11.43" y2="12.065" width="0.2032" layer="51"/>
<wire x1="11.43" y1="12.065" x2="11.43" y2="3.175" width="0.2032" layer="51"/>
<wire x1="11.43" y1="3.175" x2="-1.905" y2="3.175" width="0.2032" layer="51"/>
<pad name="MISO" x="63.64000625" y="30.4299875" drill="1.016" diameter="1.9304"/>
<pad name="VCC" x="66.18000625" y="30.4299875" drill="1.016" diameter="1.9304"/>
<pad name="SCK" x="63.64000625" y="27.8899875" drill="1.016" diameter="1.9304"/>
<pad name="MOSI" x="66.18000625" y="27.8899875" drill="1.016" diameter="1.9304"/>
<pad name="RESET@2" x="63.64000625" y="25.3499875" drill="1.016" diameter="1.9304"/>
<pad name="GND@4" x="66.18000625" y="25.3499875" drill="1.016" diameter="1.9304"/>
<text x="18.796" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">SCL</text>
<text x="21.336" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">SDA</text>
<text x="23.876" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">AREF</text>
<text x="26.416" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">GND</text>
<text x="28.956" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D13</text>
<text x="31.496" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D12</text>
<text x="34.036" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D11</text>
<text x="36.576" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D10</text>
<text x="39.116" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D9</text>
<text x="41.656" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D8</text>
<text x="45.72" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D7</text>
<text x="48.26" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D6</text>
<text x="50.8" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D5</text>
<text x="53.34" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D4</text>
<text x="55.88" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D3</text>
<text x="58.42" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D2</text>
<text x="63.5" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D0/RXI</text>
<text x="60.96" y="49.53" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-right">D1/TXO</text>
<text x="33.02" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">!RESET!</text>
<text x="35.56" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">3.3V</text>
<text x="38.1" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">5V</text>
<text x="40.64" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">GND</text>
<text x="43.18" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">GND</text>
<text x="45.72" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">VIN</text>
<text x="50.8" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">A0</text>
<text x="53.34" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">A1</text>
<text x="55.88" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">A2</text>
<text x="58.42" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">A3</text>
<text x="60.96" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">A4</text>
<text x="63.5" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">A5</text>
<text x="30.48" y="3.81" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="center-left">IOREF</text>
<text x="62.23" y="30.48" size="0.8128" layer="51" font="vector" ratio="15" align="center-right">MISO</text>
<text x="62.23" y="27.94" size="0.8128" layer="51" font="vector" ratio="15" align="center-right">SCK</text>
<text x="62.23" y="25.4" size="0.8128" layer="51" font="vector" ratio="15" align="center-right">RST</text>
<text x="67.31" y="25.4" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="top-center">GND</text>
<text x="67.31" y="27.94" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="top-center">MOSI</text>
<text x="67.31" y="30.48" size="0.8128" layer="51" font="vector" ratio="15" rot="R90" align="top-center">5V</text>
<circle x="13.97" y="2.54" radius="1.02390625" width="0.127" layer="51"/>
<circle x="66.04" y="7.62" radius="1.02390625" width="0.127" layer="51"/>
<circle x="66.04" y="35.56" radius="1.02390625" width="0.127" layer="51"/>
<circle x="15.24" y="50.8" radius="1.02390625" width="0.127" layer="51"/>
</package>
</packages>
<symbols>
<symbol name="ARDUINO_R3">
<wire x1="-10.16" y1="-35.56" x2="-10.16" y2="25.4" width="0.4064" layer="94"/>
<wire x1="-10.16" y1="25.4" x2="10.16" y2="25.4" width="0.4064" layer="94"/>
<wire x1="10.16" y1="25.4" x2="10.16" y2="-35.56" width="0.4064" layer="94"/>
<wire x1="10.16" y1="-35.56" x2="-10.16" y2="-35.56" width="0.4064" layer="94"/>
<text x="-9.652" y="26.162" size="1.778" layer="95">>Name</text>
<text x="-10.16" y="-35.814" size="1.778" layer="96" align="top-left">101</text>
<pin name="D0" x="12.7" y="22.86" visible="pin" length="short" rot="R180"/>
<pin name="D1" x="12.7" y="20.32" visible="pin" length="short" rot="R180"/>
<pin name="D2" x="12.7" y="17.78" visible="pin" length="short" rot="R180"/>
<pin name="*D3" x="12.7" y="15.24" visible="pin" length="short" rot="R180"/>
<pin name="D4" x="12.7" y="12.7" visible="pin" length="short" rot="R180"/>
<pin name="*D5" x="12.7" y="10.16" visible="pin" length="short" rot="R180"/>
<pin name="*D6" x="12.7" y="7.62" visible="pin" length="short" rot="R180"/>
<pin name="D7" x="12.7" y="5.08" visible="pin" length="short" rot="R180"/>
<pin name="D8" x="12.7" y="2.54" visible="pin" length="short" rot="R180"/>
<pin name="*D9" x="12.7" y="0" visible="pin" length="short" rot="R180"/>
<pin name="*D10" x="12.7" y="-2.54" visible="pin" length="short" rot="R180"/>
<pin name="*D11" x="12.7" y="-5.08" visible="pin" length="short" rot="R180"/>
<pin name="D12" x="12.7" y="-7.62" visible="pin" length="short" rot="R180"/>
<pin name="D13" x="12.7" y="-10.16" visible="pin" length="short" rot="R180"/>
<pin name="A0" x="-12.7" y="22.86" visible="pin" length="short"/>
<pin name="A1" x="-12.7" y="20.32" visible="pin" length="short"/>
<pin name="A2" x="-12.7" y="17.78" visible="pin" length="short"/>
<pin name="A3" x="-12.7" y="15.24" visible="pin" length="short"/>
<pin name="A4" x="-12.7" y="12.7" visible="pin" length="short"/>
<pin name="A5" x="-12.7" y="10.16" visible="pin" length="short"/>
<pin name="VIN" x="-12.7" y="0" visible="pin" length="short"/>
<pin name="!RESET!@1" x="-12.7" y="2.54" visible="pin" length="short"/>
<pin name="5V" x="-12.7" y="-2.54" visible="pin" length="short"/>
<pin name="AREF" x="-12.7" y="-7.62" visible="pin" length="short"/>
<pin name="GND@2" x="-12.7" y="-10.16" visible="pin" length="short"/>
<pin name="GND@1" x="-12.7" y="-12.7" visible="pin" length="short"/>
<pin name="GND@0" x="-12.7" y="-15.24" visible="pin" length="short"/>
<pin name="3.3V" x="-12.7" y="-5.08" visible="pin" length="short"/>
<pin name="IOREF" x="-12.7" y="5.08" visible="pin" length="short"/>
<pin name="SDA" x="12.7" y="-12.7" visible="pin" length="short" rot="R180"/>
<pin name="SCL" x="12.7" y="-15.24" visible="pin" length="short" rot="R180"/>
<pin name="VCC" x="12.7" y="-20.32" visible="pin" length="short" rot="R180"/>
<pin name="MISO" x="12.7" y="-22.86" visible="pin" length="short" rot="R180"/>
<pin name="MOSI" x="12.7" y="-25.4" visible="pin" length="short" rot="R180"/>
<pin name="SCK" x="12.7" y="-27.94" visible="pin" length="short" rot="R180"/>
<pin name="!RESET!@2" x="12.7" y="-30.48" visible="pin" length="short" rot="R180"/>
<pin name="GND" x="12.7" y="-33.02" visible="pin" length="short" rot="R180"/>
</symbol>
</symbols>
<devicesets>
<deviceset name="ARDUINO_R3" prefix="J">
<description><h3>Arduino R3 Footprint (w/ SPI header)</h3></description>
<gates>
<gate name="G$1" symbol="ARDUINO_R3" x="0" y="0"/>
</gates>
<devices>
<device name="" package="ARDUINO_R3">
<connects>
<connect gate="G$1" pin="!RESET!@1" pad="RESET@1"/>
<connect gate="G$1" pin="!RESET!@2" pad="RESET@2"/>
<connect gate="G$1" pin="*D10" pad="D10"/>
<connect gate="G$1" pin="*D11" pad="D11"/>
<connect gate="G$1" pin="*D3" pad="D3"/>
<connect gate="G$1" pin="*D5" pad="D5"/>
<connect gate="G$1" pin="*D6" pad="D6"/>
<connect gate="G$1" pin="*D9" pad="D9"/>
<connect gate="G$1" pin="3.3V" pad="3.3V"/>
<connect gate="G$1" pin="5V" pad="5V"/>
<connect gate="G$1" pin="A0" pad="A0"/>
<connect gate="G$1" pin="A1" pad="A1"/>
<connect gate="G$1" pin="A2" pad="A2"/>
<connect gate="G$1" pin="A3" pad="A3"/>
<connect gate="G$1" pin="A4" pad="A4"/>
<connect gate="G$1" pin="A5" pad="A5"/>
<connect gate="G$1" pin="AREF" pad="AREF"/>
<connect gate="G$1" pin="D0" pad="D0"/>
<connect gate="G$1" pin="D1" pad="D1"/>
<connect gate="G$1" pin="D12" pad="D12"/>
<connect gate="G$1" pin="D13" pad="D13"/>
<connect gate="G$1" pin="D2" pad="D2"/>
<connect gate="G$1" pin="D4" pad="D4"/>
<connect gate="G$1" pin="D7" pad="D7"/>
<connect gate="G$1" pin="D8" pad="D8"/>
<connect gate="G$1" pin="GND" pad="GND@1"/>
<connect gate="G$1" pin="GND@0" pad="GND@2"/>
<connect gate="G$1" pin="GND@1" pad="GND@3"/>
<connect gate="G$1" pin="GND@2" pad="GND@4"/>
<connect gate="G$1" pin="IOREF" pad="IOREF"/>
<connect gate="G$1" pin="MISO" pad="MISO"/>
<connect gate="G$1" pin="MOSI" pad="MOSI"/>
<connect gate="G$1" pin="SCK" pad="SCK"/>
<connect gate="G$1" pin="SCL" pad="SCL"/>
<connect gate="G$1" pin="SDA" pad="SDA"/>
<connect gate="G$1" pin="VCC" pad="VCC"/>
<connect gate="G$1" pin="VIN" pad="VIN"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
<device name="NO_HOLES" package="ARDUINO_R3_NO_HOLES">
<connects>
<connect gate="G$1" pin="!RESET!@1" pad="RESET@1"/>
<connect gate="G$1" pin="!RESET!@2" pad="RESET@2"/>
<connect gate="G$1" pin="*D10" pad="D10"/>
<connect gate="G$1" pin="*D11" pad="D11"/>
<connect gate="G$1" pin="*D3" pad="D3"/>
<connect gate="G$1" pin="*D5" pad="D5"/>
<connect gate="G$1" pin="*D6" pad="D6"/>
<connect gate="G$1" pin="*D9" pad="D9"/>
<connect gate="G$1" pin="3.3V" pad="3.3V"/>
<connect gate="G$1" pin="5V" pad="5V"/>
<connect gate="G$1" pin="A0" pad="A0"/>
<connect gate="G$1" pin="A1" pad="A1"/>
<connect gate="G$1" pin="A2" pad="A2"/>
<connect gate="G$1" pin="A3" pad="A3"/>
<connect gate="G$1" pin="A4" pad="A4"/>
<connect gate="G$1" pin="A5" pad="A5"/>
<connect gate="G$1" pin="AREF" pad="AREF"/>
<connect gate="G$1" pin="D0" pad="D0"/>
<connect gate="G$1" pin="D1" pad="D1"/>
<connect gate="G$1" pin="D12" pad="D12"/>
<connect gate="G$1" pin="D13" pad="D13"/>
<connect gate="G$1" pin="D2" pad="D2"/>
<connect gate="G$1" pin="D4" pad="D4"/>
<connect gate="G$1" pin="D7" pad="D7"/>
<connect gate="G$1" pin="D8" pad="D8"/>
<connect gate="G$1" pin="GND" pad="GND@1"/>
<connect gate="G$1" pin="GND@0" pad="GND@2"/>
<connect gate="G$1" pin="GND@1" pad="GND@3"/>
<connect gate="G$1" pin="GND@2" pad="GND@4"/>
<connect gate="G$1" pin="IOREF" pad="IOREF"/>
<connect gate="G$1" pin="MISO" pad="MISO"/>
<connect gate="G$1" pin="MOSI" pad="MOSI"/>
<connect gate="G$1" pin="SCK" pad="SCK"/>
<connect gate="G$1" pin="SCL" pad="SCL"/>
<connect gate="G$1" pin="SDA" pad="SDA"/>
<connect gate="G$1" pin="VCC" pad="VCC"/>
<connect gate="G$1" pin="VIN" pad="VIN"/>
</connects>
<technologies>
<technology name=""/>
</technologies>
</device>
</devices>
</deviceset>
</devicesets>
</library>
</libraries>
<attributes>
</attributes>
<variantdefs>
</variantdefs>
<classes>
<class number="0" name="default" width="0" drill="0">
</class>
</classes>
<parts>
<part name="BAT" library="battery" deviceset="CRAA" device="" value="4xAA"/>
<part name="1B-" library="SparkFun-Electromechanical" deviceset="SWITCH-SPDT" device="PTH_LOCK" value="1B"/>
<part name="1A" library="SparkFun-Electromechanical" deviceset="SWITCH-SPDT" device="PTH_LOCK" value="1A"/>
<part name="2B" library="SparkFun-Electromechanical" deviceset="SWITCH-SPDT" device="PTH_LOCK" value="2B"/>
<part name="2A" library="SparkFun-Electromechanical" deviceset="SWITCH-SPDT" device="PTH_LOCK" value="2A"/>
<part name="+6V" library="supply1" deviceset="+12V" device="" value="6V"/>
<part name="MOTOR" library="SparkFun-Electromechanical" deviceset="MOTOR" device="10MM"/>
<part name="HBRIDGE" library="SparkFun-PowerIC" deviceset="TB6612FNG" device="" value="TB6612FNG"/>
<part name="DOOR" library="switch-coto" deviceset="CT10-XXXX-" device="A2"/>
<part name="BUZZER" library="SparkFun-Electromechanical" deviceset="BUZZER" device="PTH"/>
<part name="R1" library="SparkFun-Resistors" deviceset="680OHM1/10W5%(0603)" device="" value="680"/>
<part name="GND9" library="supply1" deviceset="GND" device=""/>
<part name="GND1" library="supply1" deviceset="GND" device=""/>
<part name="ARDUINO" library="SparkFun-Boards" deviceset="ARDUINO_R3" device=""/>
</parts>
<sheets>
<sheet>
<plain>
<circle x="78.74" y="184.15" radius="3.048" width="0.762" layer="104"/>
<circle x="78.74" y="209.55" radius="3.048" width="0.762" layer="255"/>
<text x="96.266" y="175.26" size="1.778" layer="97" rot="R90">ORANGE RING</text>
<text x="94.488" y="217.17" size="1.778" layer="97" rot="R270">BLACK RING</text>
<text x="53.34" y="200.914" size="1.27" layer="98">BLUE</text>
<text x="53.34" y="198.374" size="1.27" layer="98">GREEN</text>
<text x="53.34" y="195.834" size="1.27" layer="98">YELLOW</text>
<text x="53.34" y="193.294" size="1.27" layer="98">ORANGE</text>
<text x="88.646" y="238.76" size="1.27" layer="98" rot="R90">BROWN</text>
<text x="91.186" y="238.76" size="1.27" layer="98" rot="R90">RED</text>
<text x="53.34" y="152.654" size="1.27" layer="98">GREY</text>
<text x="53.34" y="155.194" size="1.27" layer="98">WHITE</text>
<text x="53.34" y="157.734" size="1.27" layer="98">BLACK</text>
<text x="19.05" y="152.654" size="1.27" layer="98">RED</text>
<text x="19.05" y="150.114" size="1.27" layer="98">BLACK</text>
<text x="38.1" y="134.874" size="1.27" layer="98">BLACK</text>
<text x="38.1" y="132.334" size="1.27" layer="98">RED</text>
<wire x1="48.26" y1="220.98" x2="38.1" y2="220.98" width="0.1524" layer="93" style="longdash"/>
<wire x1="-2.54" y1="220.98" x2="12.7" y2="220.98" width="0.4064" layer="94" style="longdash"/>
<wire x1="12.7" y1="220.98" x2="12.7" y2="246.38" width="0.4064" layer="94" style="longdash"/>
<wire x1="12.7" y1="246.38" x2="-2.54" y2="246.38" width="0.4064" layer="94" style="longdash"/>
<wire x1="-2.54" y1="246.38" x2="-2.54" y2="220.98" width="0.4064" layer="94" style="longdash"/>
<text x="-0.508" y="247.142" size="1.778" layer="95">BATTERY</text>
<wire x1="73.66" y1="198.12" x2="93.98" y2="198.12" width="0.4064" layer="94" style="longdash"/>
<wire x1="93.98" y1="198.12" x2="93.98" y2="220.98" width="0.4064" layer="94" style="longdash"/>
<wire x1="93.98" y1="220.98" x2="73.66" y2="220.98" width="0.4064" layer="94" style="longdash"/>
<wire x1="73.66" y1="220.98" x2="73.66" y2="198.12" width="0.4064" layer="94" style="longdash"/>
<wire x1="73.66" y1="195.58" x2="93.98" y2="195.58" width="0.4064" layer="94" style="longdash"/>
<wire x1="93.98" y1="195.58" x2="93.98" y2="172.72" width="0.4064" layer="94" style="longdash"/>
<wire x1="93.98" y1="172.72" x2="73.66" y2="172.72" width="0.4064" layer="94" style="longdash"/>
<wire x1="73.66" y1="172.72" x2="73.66" y2="195.58" width="0.4064" layer="94" style="longdash"/>
<text x="53.34" y="150.114" size="1.27" layer="98">WHITE</text>
<text x="53.34" y="147.574" size="1.27" layer="98">GREY</text>
<text x="53.34" y="190.754" size="1.27" layer="98">GREY</text>
<text x="98.806" y="238.76" size="1.27" layer="98" rot="R90">WHITE</text>
<text x="101.346" y="238.76" size="1.27" layer="98" rot="R90">GREY</text>
<text x="53.34" y="185.674" size="1.27" layer="98">BLACK</text>
<text x="53.34" y="188.214" size="1.27" layer="98">WHITE</text>
<text x="2.286" y="213.36" size="1.27" layer="98" rot="R90">BLACK</text>
<text x="-0.254" y="213.36" size="1.27" layer="98" rot="R90">RED</text>
</plain>
<instances>
<instance part="BAT" gate="G$1" x="7.62" y="233.68" smashed="yes" rot="R90">
<attribute name="VALUE" x="4.064" y="230.632" size="1.778" layer="96" rot="R90"/>
</instance>
<instance part="1B-" gate="1" x="81.28" y="190.5" smashed="yes">
<attribute name="VALUE" x="83.82" y="189.23" size="1.778" layer="96"/>
</instance>
<instance part="1A" gate="1" x="81.28" y="177.8" smashed="yes">
<attribute name="VALUE" x="83.82" y="176.53" size="1.778" layer="96"/>
</instance>
<instance part="2B" gate="1" x="81.28" y="215.9" smashed="yes">
<attribute name="VALUE" x="83.82" y="214.63" size="1.778" layer="96"/>
</instance>
<instance part="2A" gate="1" x="81.28" y="203.2" smashed="yes">
<attribute name="VALUE" x="83.82" y="201.93" size="1.778" layer="96"/>
</instance>
<instance part="+6V" gate="1" x="7.62" y="243.84" smashed="yes">
<attribute name="VALUE" x="3.048" y="241.808" size="1.778" layer="96"/>
</instance>
<instance part="MOTOR" gate="G$1" x="10.16" y="152.4" smashed="yes" rot="R270">
<attribute name="NAME" x="6.35" y="154.94" size="1.778" layer="95"/>
</instance>
<instance part="HBRIDGE" gate="G$1" x="40.64" y="157.48"/>
<instance part="DOOR" gate="G$1" x="17.78" y="182.88" smashed="yes">
<attribute name="NAME" x="15.24" y="180.34" size="1.778" layer="95"/>
</instance>
<instance part="BUZZER" gate="G$1" x="10.16" y="187.96" smashed="yes">
<attribute name="NAME" x="7.62" y="193.04" size="1.778" layer="95"/>
</instance>
<instance part="R1" gate="G$1" x="17.78" y="185.42" smashed="yes">
<attribute name="VALUE" x="16.51" y="187.198" size="1.778" layer="96"/>
</instance>
<instance part="GND9" gate="1" x="10.16" y="180.34"/>
<instance part="GND1" gate="1" x="7.62" y="226.06" smashed="yes">
<attribute name="VALUE" x="5.08" y="223.774" size="1.778" layer="96"/>
</instance>
<instance part="ARDUINO" gate="G$1" x="40.64" y="205.74" rot="MR180"/>
</instances>
<busses>
</busses>
<nets>
<net name="BLACK_GND" class="0">
<segment>
<pinref part="DOOR" gate="G$1" pin="1"/>
<pinref part="GND9" gate="1" pin="GND"/>
<wire x1="12.7" y1="182.88" x2="10.16" y2="182.88" width="0.1524" layer="91"/>
<pinref part="BUZZER" gate="G$1" pin="1"/>
<wire x1="10.16" y1="185.42" x2="10.16" y2="182.88" width="0.1524" layer="91"/>
<junction x="10.16" y="182.88"/>
</segment>
</net>
<net name="2A" class="0">
<segment>
<pinref part="2A" gate="1" pin="P"/>
<wire x1="78.74" y1="203.2" x2="71.12" y2="203.2" width="0.1524" layer="91"/>
<wire x1="71.12" y1="203.2" x2="71.12" y2="198.12" width="0.1524" layer="91"/>
<pinref part="ARDUINO" gate="G$1" pin="*D6"/>
<wire x1="71.12" y1="198.12" x2="53.34" y2="198.12" width="0.1524" layer="91"/>
</segment>
</net>
<net name="1A" class="0">
<segment>
<pinref part="1A" gate="1" pin="P"/>
<wire x1="78.74" y1="177.8" x2="68.58" y2="177.8" width="0.1524" layer="91"/>
<wire x1="68.58" y1="177.8" x2="68.58" y2="193.04" width="0.1524" layer="91"/>
<pinref part="ARDUINO" gate="G$1" pin="D4"/>
<wire x1="68.58" y1="193.04" x2="53.34" y2="193.04" width="0.1524" layer="91"/>
</segment>
</net>
<net name="BLACK_OUT" class="0">
<segment>
<pinref part="MOTOR" gate="G$1" pin="-"/>
<wire x1="5.08" y1="152.4" x2="5.08" y2="149.86" width="0.1524" layer="91"/>
<wire x1="5.08" y1="149.86" x2="25.4" y2="149.86" width="0.1524" layer="91"/>
<pinref part="HBRIDGE" gate="G$1" pin="MB1"/>
</segment>
</net>
<net name="MB2" class="0">
<segment>
<pinref part="MOTOR" gate="G$1" pin="+"/>
<pinref part="HBRIDGE" gate="G$1" pin="MB2"/>
<wire x1="15.24" y1="152.4" x2="25.4" y2="152.4" width="0.1524" layer="91"/>
</segment>
</net>
<net name="PWMB" class="0">
<segment>
<pinref part="HBRIDGE" gate="G$1" pin="PWMB"/>
<wire x1="53.34" y1="152.4" x2="66.04" y2="152.4" width="0.1524" layer="91"/>
<wire x1="66.04" y1="152.4" x2="66.04" y2="190.5" width="0.1524" layer="91"/>
<pinref part="ARDUINO" gate="G$1" pin="*D3"/>
<wire x1="66.04" y1="190.5" x2="53.34" y2="190.5" width="0.1524" layer="91"/>
</segment>
</net>
<net name="BIN2" class="0">
<segment>
<pinref part="HBRIDGE" gate="G$1" pin="BIN2"/>
<wire x1="63.5" y1="154.94" x2="53.34" y2="154.94" width="0.1524" layer="91"/>
<wire x1="63.5" y1="154.94" x2="63.5" y2="187.96" width="0.1524" layer="91"/>
<pinref part="ARDUINO" gate="G$1" pin="D2"/>
<wire x1="63.5" y1="187.96" x2="53.34" y2="187.96" width="0.1524" layer="91"/>
</segment>
</net>
<net name="BIN1" class="0">
<segment>
<pinref part="HBRIDGE" gate="G$1" pin="BIN1"/>
<wire x1="53.34" y1="157.48" x2="60.96" y2="157.48" width="0.1524" layer="91"/>
<wire x1="60.96" y1="157.48" x2="60.96" y2="185.42" width="0.1524" layer="91"/>
<pinref part="ARDUINO" gate="G$1" pin="D1"/>
<wire x1="60.96" y1="185.42" x2="53.34" y2="185.42" width="0.1524" layer="91"/>
</segment>
</net>
<net name="2B" class="0">
<segment>
<pinref part="2B" gate="1" pin="P"/>
<wire x1="78.74" y1="215.9" x2="68.58" y2="215.9" width="0.1524" layer="91"/>
<wire x1="68.58" y1="215.9" x2="68.58" y2="200.66" width="0.1524" layer="91"/>
<pinref part="ARDUINO" gate="G$1" pin="D7"/>
<wire x1="53.34" y1="200.66" x2="68.58" y2="200.66" width="0.1524" layer="91"/>
</segment>
</net>
<net name="1B" class="0">
<segment>
<pinref part="1B-" gate="1" pin="P"/>
<wire x1="78.74" y1="190.5" x2="71.12" y2="190.5" width="0.1524" layer="91"/>
<wire x1="71.12" y1="190.5" x2="71.12" y2="195.58" width="0.1524" layer="91"/>
<pinref part="ARDUINO" gate="G$1" pin="*D5"/>
<wire x1="71.12" y1="195.58" x2="53.34" y2="195.58" width="0.1524" layer="91"/>
</segment>
</net>
<net name="N$4" class="0">
<segment>
<pinref part="R1" gate="G$1" pin="1"/>
<pinref part="BUZZER" gate="G$1" pin="2"/>
</segment>
</net>
<net name="+6V" class="0">
<segment>
<wire x1="0" y1="132.08" x2="0" y2="238.76" width="0.1524" layer="91"/>
<pinref part="BAT" gate="G$1" pin="+"/>
<wire x1="0" y1="238.76" x2="7.62" y2="238.76" width="0.1524" layer="91"/>
<junction x="7.62" y="238.76"/>
<pinref part="+6V" gate="1" pin="+12V"/>
<wire x1="7.62" y1="241.3" x2="7.62" y2="238.76" width="0.1524" layer="91"/>
<wire x1="0" y1="132.08" x2="48.26" y2="132.08" width="0.1524" layer="91"/>
<pinref part="HBRIDGE" gate="G$1" pin="VM+"/>
<wire x1="48.26" y1="132.08" x2="48.26" y2="137.16" width="0.1524" layer="91"/>
</segment>
</net>
<net name="GND" class="0">
<segment>
<pinref part="HBRIDGE" gate="G$1" pin="VM-"/>
<wire x1="45.72" y1="137.16" x2="45.72" y2="134.62" width="0.1524" layer="91"/>
<wire x1="45.72" y1="134.62" x2="2.54" y2="134.62" width="0.1524" layer="91"/>
<wire x1="2.54" y1="134.62" x2="2.54" y2="228.6" width="0.1524" layer="91"/>
<pinref part="BAT" gate="G$1" pin="-"/>
<wire x1="2.54" y1="228.6" x2="7.62" y2="228.6" width="0.1524" layer="91"/>
<pinref part="GND1" gate="1" pin="GND"/>
<junction x="7.62" y="228.6"/>
<pinref part="HBRIDGE" gate="G$1" pin="GND"/>
<wire x1="53.34" y1="149.86" x2="99.06" y2="149.86" width="0.1524" layer="91"/>
<wire x1="53.34" y1="149.86" x2="45.72" y2="149.86" width="0.1524" layer="91"/>
<wire x1="45.72" y1="149.86" x2="45.72" y2="137.16" width="0.1524" layer="91"/>
<wire x1="99.06" y1="149.86" x2="99.06" y2="246.38" width="0.1524" layer="91"/>
<pinref part="1A" gate="1" pin="S"/>
<pinref part="ARDUINO" gate="G$1" pin="GND@2"/>
<wire x1="25.4" y1="215.9" x2="27.94" y2="215.9" width="0.1524" layer="91"/>
<wire x1="25.4" y1="215.9" x2="25.4" y2="246.38" width="0.1524" layer="91"/>
<wire x1="25.4" y1="246.38" x2="88.9" y2="246.38" width="0.1524" layer="91"/>
<pinref part="2B" gate="1" pin="S"/>
<wire x1="88.9" y1="213.36" x2="86.36" y2="213.36" width="0.1524" layer="91"/>
<wire x1="88.9" y1="213.36" x2="88.9" y2="246.38" width="0.1524" layer="91"/>
<junction x="88.9" y="213.36"/>
<pinref part="2A" gate="1" pin="S"/>
<wire x1="88.9" y1="200.66" x2="86.36" y2="200.66" width="0.1524" layer="91"/>
<wire x1="88.9" y1="200.66" x2="88.9" y2="213.36" width="0.1524" layer="91"/>
<junction x="88.9" y="200.66"/>
<pinref part="1B-" gate="1" pin="S"/>
<wire x1="88.9" y1="187.96" x2="86.36" y2="187.96" width="0.1524" layer="91"/>
<wire x1="88.9" y1="187.96" x2="88.9" y2="200.66" width="0.1524" layer="91"/>
<junction x="88.9" y="187.96"/>
<wire x1="88.9" y1="175.26" x2="88.9" y2="187.96" width="0.1524" layer="91"/>
<wire x1="88.9" y1="175.26" x2="86.36" y2="175.26" width="0.1524" layer="91"/>
<wire x1="88.9" y1="246.38" x2="99.06" y2="246.38" width="0.1524" layer="91"/>
<junction x="88.9" y="246.38"/>
</segment>
</net>
<net name="N$2" class="0">
<segment>
<pinref part="ARDUINO" gate="G$1" pin="A1"/>
<pinref part="R1" gate="G$1" pin="2"/>
<wire x1="27.94" y1="185.42" x2="22.86" y2="185.42" width="0.1524" layer="91"/>
</segment>
</net>
<net name="N$3" class="0">
<segment>
<pinref part="ARDUINO" gate="G$1" pin="A0"/>
<pinref part="DOOR" gate="G$1" pin="2"/>
<wire x1="27.94" y1="182.88" x2="22.86" y2="182.88" width="0.1524" layer="91"/>
</segment>
</net>
<net name="N$5" class="0">
<segment>
<pinref part="HBRIDGE" gate="G$1" pin="VCC"/>
<wire x1="53.34" y1="147.32" x2="101.6" y2="147.32" width="0.1524" layer="91"/>
<wire x1="101.6" y1="248.92" x2="101.6" y2="147.32" width="0.1524" layer="91"/>
<pinref part="1A" gate="1" pin="O"/>
<pinref part="2B" gate="1" pin="O"/>
<wire x1="91.44" y1="218.44" x2="86.36" y2="218.44" width="0.1524" layer="91"/>
<wire x1="91.44" y1="218.44" x2="91.44" y2="248.92" width="0.1524" layer="91"/>
<junction x="91.44" y="218.44"/>
<pinref part="2A" gate="1" pin="O"/>
<wire x1="91.44" y1="205.74" x2="86.36" y2="205.74" width="0.1524" layer="91"/>
<wire x1="91.44" y1="205.74" x2="91.44" y2="218.44" width="0.1524" layer="91"/>
<junction x="91.44" y="205.74"/>
<pinref part="1B-" gate="1" pin="O"/>
<wire x1="91.44" y1="193.04" x2="86.36" y2="193.04" width="0.1524" layer="91"/>
<wire x1="91.44" y1="193.04" x2="91.44" y2="205.74" width="0.1524" layer="91"/>
<junction x="91.44" y="193.04"/>
<wire x1="91.44" y1="180.34" x2="91.44" y2="193.04" width="0.1524" layer="91"/>
<wire x1="91.44" y1="180.34" x2="86.36" y2="180.34" width="0.1524" layer="91"/>
<wire x1="22.86" y1="248.92" x2="91.44" y2="248.92" width="0.1524" layer="91"/>
<wire x1="101.6" y1="248.92" x2="91.44" y2="248.92" width="0.1524" layer="91"/>
<wire x1="22.86" y1="248.92" x2="22.86" y2="210.82" width="0.1524" layer="91"/>
<pinref part="ARDUINO" gate="G$1" pin="3.3V"/>
<wire x1="22.86" y1="210.82" x2="27.94" y2="210.82" width="0.1524" layer="91"/>
<junction x="91.44" y="248.92"/>
</segment>
</net>
</nets>
</sheet>
</sheets>
</schematic>
</drawing>
</eagle>
================================================
FILE: examples/lock/arduino101/dummy/dummy.ino
================================================
#include <Arduino.h>
#include <CurieBLE.h>
const int pinStateLED = 13;
BLEPeripheral ble;
BLEService informationService("180A");
BLECharacteristic modelCharacteristic("2A24", BLERead, "101");
BLECharacteristic manufacturerCharacteristic("2A29", BLERead, "Arduino");
BLECharacteristic serialNumberCharacteristic("2A25", BLERead, "Dummy Testing Lock");
BLEService lockMechanismService("43AAF900-5FF0-4633-95A2-FE4189EE103B");
BLEUnsignedCharCharacteristic targetStateCharacteristic("43AAF901-5FF0-4633-95A2-FE4189EE103B", BLEWrite | BLERead | BLENotify);
BLEUnsignedCharCharacteristic currentStateCharacteristic("43AAF902-5FF0-4633-95A2-FE4189EE103B", BLERead | BLENotify);
void setup() {
Serial.begin(115200);
pinMode(pinStateLED, OUTPUT);
ble.setLocalName("Lock");
ble.setAdvertisedServiceUuid(lockMechanismService.uuid());
ble.addAttribute(lockMechanismService);
ble.addAttribute(targetStateCharacteristic);
ble.addAttribute(currentStateCharacteristic);
targetStateCharacteristic.setValueLE(0);
currentStateCharacteristic.setValueLE(0);
digitalWrite(pinStateLED, 0);
ble.setEventHandler(BLEConnected, centralConnect);
ble.setEventHandler(BLEDisconnected, centralDisconnect);
ble.begin();
Serial.println("Bluetooth on");
}
void loop() {
ble.poll();
if (targetStateCharacteristic.valueLE() != currentStateCharacteristic.valueLE()) {
unsigned char state = targetStateCharacteristic.valueLE();
delay(500);
digitalWrite(pinStateLED, (bool) state);
currentStateCharacteristic.setValueLE(state);
Serial.print("Lock state | ");
Serial.println(state);
}
}
void centralConnect(BLECentral& central) {
Serial.print("Central connected | ");
Serial.println(central.address());
}
void centralDisconnect(BLECentral& central) {
Serial.print("Central disconnected | ");
Serial.println(central.address());
}
================================================
FILE: examples/lock/arduino101/lock.cpp
================================================
#include "lock.h"
//#define DEBUG(message) Serial.print(message)
#define DEBUG(message)
Lock::Lock(Sensor& sensor1A_, Sensor& sensor1B_, Sensor& sensor2A_, Sensor& sensor2B_,
Motor& motor_, const bool lockClockwise_) :
working(false), sensor1A(sensor1A_), sensor1B(sensor1B_), sensor2A(sensor2A_), sensor2B(sensor2B_),
motor(motor_), lockClockwise(lockClockwise_)
{ }
void Lock::begin() {
DEBUG("Lock::begin()\n");
motor.begin();
rotate(Position.Neutral, Position.Any, false, false);
lastState = Position.Unlocked;
}
uint8_t Lock::state() {
switch (orange()) {
case Position.Jammed:
lastState = Position.Jammed;
return State.Jammed;
case Position.Unlocked:
if (lastState != Position.Unlocked) {
DEBUG("Lock::state() = Unsecured (Manually)\n");
lastState = Position.Unlocked;
}
return State.Unsecured;
case Position.Locked:
if (lastState != Position.Locked) {
DEBUG("Lock::state() = Secured (Manually)\n");
lastState = Position.Locked;
}
return State.Secured;
case Position.Unknown:
return lastState;
}
}
bool Lock::set(uint8_t state) {
switch (state) {
case State.Secured:
DEBUG("Lock::set(Secured)\n");
if (!rotate(Position.Any, Position.Locked, lockClockwise)) {
DEBUG("Full lock failed\n");
return false;
}
delay(Delay.DirectionChange);
if (!rotate(Position.Neutral, Position.Any, !lockClockwise)) {
DEBUG("Parking back to neutral failed\n");
return false;
}
lastState = state;
return true;
case State.Unsecured:
DEBUG("Lock::set(Unsecured)\n");
if (!rotate(Position.Any, Position.Unlocked, !lockClockwise)) {
DEBUG("Full unlock failed\n");
return false;
}
delay(Delay.DirectionChange);
if (!rotate(Position.Neutral, Position.Any, lockClockwise)) {
DEBUG("Parking back to neutral failed\n");
return false;
}
lastState = state;
return true;
default:
DEBUG("Lock::set(Neutral)\n");
rotate(Position.Neutral, Position.Any, false, false);
lastState = state;
return true;
}
}
bool Lock::rotate(uint8_t blck, uint8_t orng, bool clockwise, bool sure) {
DEBUG("Lock::rotate(blck="); DEBUG(blck); DEBUG(", orng="); DEBUG(orng);
DEBUG(", clkws="); DEBUG(clockwise); DEBUG(")\n");
static bool recursion = false;
working = true;
timeout = millis();
motor.start(clockwise);
do {
if ((!sure) && (blck == Position.Neutral)) {
if ((black() == Position.Locked) || (black() == Position.Unlocked)) {
/* Wrong direction while trying to reach mid-point, back out */
DEBUG("Reverse\n");
motor.stop();
working = false;
delay(Delay.DirectionChange);
if (!recursion) {
bool direction = (black() == Position.Unlocked);
bool retval = rotate(Position.Neutral, Position.Any, direction);
return retval;
}
}
}
if (black() == Position.Jammed) {
/* Ooooppss... */
DEBUG("Jammed!!!\n");
motor.stop();
delay(Delay.DirectionChange);
if (!recursion) {
recursion = true;
uint32_t keep = timeout;
rotate(Position.Neutral, Position.Any, !clockwise);
recursion = false;
timeout = keep;
working = true;
}
return false;
}
/* Keep cranking... */
} while ( ((black() != blck) || (blck == Position.Any)) &&
((orange() != orng) || (orng == Position.Any)) );
if ((orng == Position.Locked) || (orng == Position.Unlocked)) {
/* Keep cranking for a bit longer when locking/unlocking to fully extend/retract the bolt */
delay(Delay.Override);
}
motor.stop();
working = false;
return true;
}
uint8_t Lock::black() {
DEBUG("Lock:black(2A="); DEBUG(sensor2A); DEBUG(", 2B="); DEBUG(sensor2B); DEBUG(")");
if (working && ((millis() - timeout) > Delay.Timeout)) {
DEBUG(" = Jammed\n");
return Position.Jammed;
}
if (lockClockwise) {
if ((sensor2A == HIGH) && (sensor2B == HIGH)) {
/* Black ring parked at neutral mid-point */
DEBUG(" = Neutral\n");
return Position.Neutral;
}
if ((sensor2A == LOW ) && (sensor2B == HIGH)) {
/* Black ring rotated all the way clockwise */
DEBUG(" = Locked\n");
return Position.Locked;
}
if ((sensor2A == HIGH) && (sensor2B == LOW )) {
/* Black ring rotated all the way counter-clockwise */
DEBUG(" = Unlocked\n");
return Position.Unlocked;
}
DEBUG(" = Unknown\n");
return Position.Unknown;
} else {
if ((sensor2A == HIGH) && (sensor2B == HIGH)) {
/* Black ring parked at neutral mid-point */
DEBUG(" = Neutral\n");
return Position.Neutral;
}
if ((sensor2A == LOW ) && (sensor2B == HIGH)) {
/* Black ring rotated all the way clockwise */
DEBUG(" = Unlocked\n");
return Position.Unlocked;
}
if ((sensor2A == HIGH) && (sensor2B == LOW )) {
/* Black ring rotated all the way counter-clockwise */
DEBUG(" = Locked\n");
return Position.Locked;
}
DEBUG(" = Unknown\n");
return Position.Unknown;
}
}
uint8_t Lock::orange() {
if (working && ((millis() - timeout) > Delay.Timeout)) {
return Position.Jammed;
}
if (lockClockwise) {
if ((sensor1A == HIGH) && (sensor1B == LOW )) {
/* Orange ring rotated all the way clockwise relative to the black ring */
return Position.Unlocked;
}
if ((sensor1A == LOW ) && (sensor1B == HIGH)) {
/* Orange ring rotated all the way counter-clockwise relative to the black ring */
return Position.Locked;
}
return Position.Unknown;
} else {
if ((sensor1A == HIGH) && (sensor1B == LOW )) {
/* Orange ring rotated all the way clockwise relative to the black ring */
return Position.Locked;
}
if ((sensor1A == LOW ) && (sensor1B == HIGH)) {
/* Orange ring rotated all the way counter-clockwise relative to the black ring */
return Position.Unlocked;
}
return Position.Unknown;
}
}
================================================
FILE: examples/lock/arduino101/lock.h
================================================
#ifndef _LOCK_H_
#define _LOCK_H_
#include <Arduino.h>
#include "sensor.h"
#include "motor.h"
class Lock {
public:
Lock(Sensor& sensor1A_, Sensor& sensor1B_, Sensor& sensor2A_, Sensor& sensor2B_,
Motor& motor_, const bool lockClockwise_);
void begin();
uint8_t state(void);
bool set(uint8_t state);
static struct LockState { // HAP-NodeJS/lib/gen/HomeKitTypes.js #897
static const uint8_t Unsecured = 0;
static const uint8_t Secured = 1;
static const uint8_t Jammed = 2;
static const uint8_t Unknown = 3;
} State;
private:
bool rotate(uint8_t blck, uint8_t orng, bool clockwise = true, bool sure = true);
uint8_t orange();
uint8_t black();
static struct RingPosition {
static const uint8_t Unlocked = 0;
static const uint8_t Locked = 1;
static const uint8_t Jammed = 2;
static const uint8_t Unknown = 3;
static const uint8_t Neutral = 4;
static const uint8_t Any = ~0;
} Position;
static struct LockTimeDelay {
static const uint32_t Timeout = 3000; // milliseconds
static const uint32_t DirectionChange = 300; // milliseconds
static const uint32_t Override = 500; // milliseconds - needs to be tuned for each lock
} Delay;
bool working;
uint32_t timeout; // milliseconds - overflows after ~50 days
uint8_t lastState;
Sensor& sensor1A;
Sensor& sensor1B;
Sensor& sensor2A;
Sensor& sensor2B;
Motor& motor;
const bool lockClockwise;
};
#endif
================================================
FILE: examples/lock/arduino101/motor.cpp
================================================
#include "motor.h"
// #define DEBUG(message) Serial.print(message)
#define DEBUG(message)
Motor::Motor(const uint32_t minusPin_, const uint32_t plusPin_,
const uint32_t pwmPin_, const uint8_t pwm_) :
minusPin(minusPin_),
plusPin(plusPin_),
pwmPin(pwmPin_),
pwm(pwm_)
{ }
void Motor::begin() {
pinMode(minusPin, OUTPUT);
pinMode(plusPin, OUTPUT);
pinMode(pwmPin, OUTPUT);
}
void Motor::start(bool clockwise) {
analogWrite(pwmPin, pwm);
if (clockwise) {
digitalWrite(minusPin, HIGH);
digitalWrite(plusPin, LOW);
} else {
digitalWrite(minusPin, LOW);
digitalWrite(plusPin, HIGH);
}
DEBUG("Motor::start(clkws="); DEBUG(clockwise); DEBUG(")\n");
}
void Motor::stop() {
analogWrite(pwmPin, 0);
digitalWrite(minusPin, LOW);
digitalWrite(plusPin, LOW);
DEBUG("Motor::stop()\n");
}
Motor::~Motor() {
stop();
DEBUG("Motor::destructor()\n");
}
================================================
FILE: examples/lock/arduino101/motor.h
================================================
#ifndef _MOTOR_H_
#define _MOTOR_H_
#include <Arduino.h>
class Motor {
public:
Motor(const uint32_t minusPin_, const uint32_t plusPin_,
const uint32_t pwmPin_, const uint8_t pwm_);
~Motor();
void begin();
void start(bool clockwise = true);
void stop();
private:
const uint32_t minusPin;
const uint32_t plusPin;
const uint32_t pwmPin;
const uint8_t pwm;
};
#endif
================================================
FILE: examples/lock/arduino101/sensor.cpp
================================================
#include "sensor.h"
// #define DEBUG(message) Serial.print(message)
#define DEBUG(message)
Sensor::Sensor(uint32_t pin_) :
pin(pin_)
{
pinMode(pin, INPUT);
}
Sensor::operator int() {
int retval = digitalRead(pin);
DEBUG("Sensor::int(pin="); DEBUG(pin); DEBUG(", val="); DEBUG(retval); DEBUG(")\n");
return retval;
}
================================================
FILE: examples/lock/arduino101/sensor.h
================================================
#ifndef _SENSOR_H_
#define _SENSOR_H_
#include <Arduino.h>
class Sensor {
public:
Sensor(uint32_t pin_);
operator int();
private:
const uint32_t pin;
};
#endif
================================================
FILE: examples/lock/config.json
================================================
{
"bridge": {
"name": "Raspberry Pi 3",
"username": "CC:22:3D:E3:CE:30",
"port": 51826,
"pin": "314-15-926"
},
"description": "Raspberry Pi 3 Homebridge-Bluetooth RGB Lightbulb Example",
"platforms": [
{
"platform": "Bluetooth",
"accessories": [
{
"name": "Arduino",
"address": "01:23:45:67:89:AB",
"services": [
{
"name": "Lock",
"type": "LockMechanism",
"UUID": "43AAF900-5FF0-4633-95A2-FE4189EE103B",
"characteristics": [
{
"type": "LockTargetState",
"UUID": "43AAF901-5FF0-4633-95A2-FE4189EE103B"
},
{
"type": "LockCurrentState",
"UUID": "43AAF902-5FF0-4633-95A2-FE4189EE103B"
}
]
}
]
}
]
}
]
}
================================================
FILE: examples/lock/readme.md
================================================
# Lock
Turn an old _Lockitron V1_ body connected to a BLE capable microprocessor into a wireless HomeKit lock. Use the Home app or Siri on your Apple device to secure and unsecure the lock.
<img src="images/lock.jpg">
This example uses [Arduino 101](https://www.arduino.cc/en/Main/ArduinoBoard101) or [RFduino](http://www.rfduino.com/) and [Raspberry Pi 3](https://www.raspberrypi.org/). Generally, any programmable BLE peripheral and a box capable of running [Node.js](https://nodejs.org) with [Noble](https://github.com/sandeepmistry/noble) will work. You'll also need a [H-Bridge breakout](https://www.adafruit.com/product/2448) to power the motor and an old _Lockitron V1_ body . It's sold by [Sparkfun](https://www.sparkfun.com/products/retired/13648), [Adafruit](https://www.adafruit.com/products/2579) or [eBay](http://www.ebay.com/sch/i.html?_from=R40&_trksid=p2050601.m570.l1313.TR12.TRC2.A0.H0.Xlockitron.TRS0&_nkw=lockitron&_sacat=0) :).
## Lock Mechanism
### Installation
Here's the official [Installation Manual](https://cdn.sparkfun.com/datasheets/Components/General/installation_manual_lockitron.pdf). Or if you preffer here's the [Installation Video](https://www.youtube.com/watch?v=ZOJhfsSCoYs).
[](https://www.youtube.com/watch?v=ZOJhfsSCoYs)
### Wiring
Here's how the lock looks inside, when you take off the black cover. The lock uses tactile switch sensors to detect position of the orange and black rings. Sparkfun has a nice article about the hookup [here](https://learn.sparkfun.com/tutorials/lockitron-hardware-hookup-guide?_ga=1.268388430.1924023418.1474989120). I've borrowed some pics from them. Generally, you want to solder wire to each sensor and possibly to extend the battery and motor wires to reach outside of the case.
<img src="lockitron/internals.jpg" width="30%">
<img src="lockitron/sensors.jpg" width="50%">
If you use _RFDuino_ and want to power the whole thing from the batteries, you'll want add a voltage regulator. Theoretically, you could add another wire to the battery pack and just use the voltage of two AA batteries, but the motor is quite hungry and eats about 2 A when running. The voltage of the two batteries drop below 1.9 V and the poor _RFduino_ resets. This doesn't happen with the regulator.
I've managed to put the voltage regulator on the [proto shield](http://www.rfduino.com/product/rfd22125-proto-shield-for-rfduino/index.html). If you cut and throw away some plastics, it's possible to squeeze the _RFDuino_ inside of the original case.
<img src="lockitron/detail.jpg" width="45%">
## BLE Accessory (Arduino 101, RFDuino or Other BLE Board)
Download and install the latest version of the [Arduino IDE](https://www.arduino.cc/en/Main/Software). If you're totally new to microcontrollers take some time to go through an introductory tutorial and learn how to make a LED blink. This will help you to understand how to use the IDE, how to upload a sketch and what is the code actually doing.
### Wiring
Connect your board to the H-Bridge breakout, voltage regulator and lock according the the following schematics. This may, again, require some soldering.
<img src="arduino101/arduino101.png" width="45%">
<img src="rfduino/rfduino.png" width="45%">
**Note** _Alternatively, you can use any of the many BLE boards available on the market ([BlueBean](https://punchthrough.com/bean/), [RedBearLabs BLE Nano](http://redbearlab.com/blenano), ...) as long as you keep UUIDs of the services and characteristics in sync with your `config.json` file, everything will work just fine._
### Running the Sketch
Compile, run and upload the [arduino101.ino](arduino101/arduino101.ino) or [rfduino.ino](rfduino/rfduino.ino) sketch using the [Arduino IDE](https://www.arduino.cc/en/Main/Software).
The sketch creates a BLE service with 2 characteristics. There's one characteristic for the lock target state (`Unsecured/Secured`) and the other for the lock current state (`Unsecured/Secured/Jammed/Unknown`). Only the target characteristic is writeable ans is used to trigger the locking mechanism.
```cpp
BLEService lockMechanismService("43AAF900-5FF0-4633-95A2-FE4189EE103B");
BLEUnsignedCharCharacteristic targetStateCharacteristic("43AAF901-5FF0-4633-95A2-FE4189EE103B",
BLEWrite | BLERead | BLENotify);
BLEUnsignedCharCharacteristic currentStateCharacteristic("43AAF902-5FF0-4633-95A2-FE4189EE103B",
BLERead | BLENotify);
```
When the tactile switch is toggled the LEDs turn on (or turn off if they were on) and the BLE subscribe-notification mechanism cases the an update update on the Homebridge. This way the information about switching propagates through callbacks to the Apple device without any polling.
Take a look into [this file](https://github.com/KhaosT/HAP-NodeJS/blob/master/lib/gen/HomeKitTypes.js#L2896) to see the full definition of the _LockMechanism_ service.
Once the BLE central device is setup, it connects to this characteristic and exposes it via Homebridge as a HomeKit accessory of type _LockMechanism_. The sketch also contains some logic to handle jamming and other corner cases.
Leave the device powered on and the sketch running while you setup the Homebridge server. The sketch has some built-in logging, so keeping the Serial monitor open may be helpful for debugging.
## BLE Central & Homebridge Server (Raspberry Pi 3 or Other Compatible Box)
For help installing an operating system on your new Pi, the official documentation contains a couple of [nice videos](https://www.raspberrypi.org/help/videos/).
### Wiring
No wiring except for the micro-USB cable providing power is needed. The Pi needs to be connected to the same router (subnet) as the Apple device you plan to use. It doesn't matter whether via Wifi or Ethernet. Otherwise, you won't be able discover and connect to the Homebridge server running on the Pi.
<img src="images/raspberry.png" width="30%">
**Note** _Alternatively, you can use a Raspberry Pi 2 with a supported USB BLE dongle instead of the Pi 3._
### Running Homebridge
Running Homebridge on a Raspberry Pi is straightforward. Follow [this guide](https://github.com/nfarina/homebridge/wiki/Running-HomeBridge-on-a-Raspberry-Pi) to install Homebridge server and then run the following command to install the homebridge-bluetooth plugin:
```sh
[sudo] npm install -g homebridge-bluetooth
```
Edit the `~/.homebridge/config.json`, name your Homebridge server and add a new accessory to allow the plugin to connect to the BLE service running on the Arduino:
```js
"name": "Arduino",
"address": "01:23:45:67:89:AB",
"services": [ {
"name": "Lock",
"type": "LockMechanism",
"UUID": "43AAF900-5FF0-4633-95A2-FE4189EE103B",
"characteristics": [ {
"type": "LockTargetState",
"UUID": "43AAF901-5FF0-4633-95A2-FE4189EE103B"
}, {
"type": "LockCurrentState",
"UUID": "43AAF902-5FF0-4633-95A2-FE4189EE103B"
} ]
} ]
```
Finally, start the Homebridge server. If you use Linux you may need to run with higher privileges in order to have access to the BLE hardware layer. See [this link](https://github.com/sandeepmistry/noble#running-without-rootsudo) for more details about running without `sudo`.
```
[sudo] homebridge -D
```
**Note** _Running with `-D` turns on additional debugging output that is very helpful for getting addresses and UUIDs of your BLE devices that needs to match with the `config.json` file._
<img src="images/homebridge.png">
**Note** _Homebridge server doesn't run only on Linux. MacOS and Windows machines are also supported given they have a built-in BLE adapter or an USB dongle. For more details see supported platforms of [Homebridge](https://github.com/nfarina/homebridge) and [Noble](https://github.com/sandeepmistry/noble)._
## Apple Device
### Pairing
Open Home app and tap the '+' button to add new accessory. When you attempt to add the 'Raspberry Pi 3' bridge, it will ask for a "PIN" from the `config.json` file. Once you are paired with your new Rapsberry Homebridge server all the Arduino accesories are added at the same time as the bridge.
### Interacting
Once your BLE accessory has been added to HomeKit database, besides using the Home app or Control Center at the bottom of the screen, you should be able to tell Siri to control any HomeKit accessory. Try _"Hey Siri, lock the Arduino"_. However, Siri is a cloud service and iOS may need some time to synchronize your HomeKit database to iCloud.
<img src="images/ios-home.png" width="30%">
<img src="images/ios-unlocked.png" width="30%">
<img src="images/ios-siri.png" width="30%">
================================================
FILE: examples/lock/rfduino/lock.cpp
================================================
#include "lock.h"
// #define DEBUG(message) Serial.print(message)
#define DEBUG(message)
Lock::Lock(Sensor& sensor1A_, Sensor& sensor1B_, Sensor& sensor2A_, Sensor& sensor2B_,
Motor& motor_, const bool lockClockwise_) :
working(false), sensor1A(sensor1A_), sensor1B(sensor1B_), sensor2A(sensor2A_), sensor2B(sensor2B_),
motor(motor_), lockClockwise(lockClockwise_)
{ }
void Lock::begin() {
DEBUG("Lock::begin()\n");
motor.begin();
rotate(Position.Neutral, Position.Any, false, false);
lastState = Position.Unlocked;
}
uint8_t Lock::state() {
uint8_t orng = orange();
if (orng == Position.Jammed) {
lastState = Position.Jammed;
return State.Jammed;
} else if (orng == Position.Unlocked) {
if (lastState != Position.Unlocked) {
DEBUG("Lock::state() = Unsecured (Manually)\n");
lastState = Position.Unlocked;
}
return State.Unsecured;
} else if (orng == Position.Locked) {
if (lastState != Position.Locked) {
DEBUG("Lock::state() = Secured (Manually)\n");
lastState = Position.Locked;
}
return State.Secured;
} else if (orng == Position.Unknown) {
return lastState;
}
}
bool Lock::set(uint8_t state) {
if (state == State.Secured) {
DEBUG("Lock::set(Secured)\n");
if (!rotate(Position.Any, Position.Locked, lockClockwise)) {
DEBUG("Full lock failed\n");
return false;
}
delay(Delay.DirectionChange);
if (!rotate(Position.Neutral, Position.Any, !lockClockwise)) {
DEBUG("Parking back to neutral failed\n");
return false;
}
lastState = state;
return true;
} else if (state == State.Unsecured) {
DEBUG("Lock::set(Unsecured)\n");
if (!rotate(Position.Any, Position.Unlocked, !lockClockwise)) {
DEBUG("Full unlock failed\n");
return false;
}
delay(Delay.DirectionChange);
if (!rotate(Position.Neutral, Position.Any, lockClockwise)) {
DEBUG("Parking back to neutral failed\n");
return false;
}
lastState = state;
return true;
} else {
DEBUG("Lock::set(Neutral)\n");
rotate(Position.Neutral, Position.Any, false, false);
lastState = state;
return true;
}
}
bool Lock::rotate(uint8_t blck, uint8_t orng, bool clockwise, bool sure) {
DEBUG("Lock::rotate(blck="); DEBUG(blck); DEBUG(", orng="); DEBUG(orng);
DEBUG(", clkws="); DEBUG(clockwise); DEBUG(")\n");
static bool recursion = false;
working = true;
timeout = millis();
motor.start(clockwise);
do {
if ((!sure) && (blck == Position.Neutral)) {
if ((black() == Position.Locked) || (black() == Position.Unlocked)) {
/* Wrong direction while trying to reach mid-point, back out */
DEBUG("Reverse\n");
motor.stop();
working = false;
delay(Delay.DirectionChange);
if (!recursion) {
bool direction = (black() == Position.Unlocked);
bool retval = rotate(Position.Neutral, Position.Any, direction);
return retval;
}
}
}
if (black() == Position.Jammed) {
/* Ooooppss... */
DEBUG("Jammed!!!\n");
motor.stop();
delay(Delay.DirectionChange);
if (!recursion) {
recursion = true;
uint32_t keep = timeout;
rotate(Position.Neutral, Position.Any, !clockwise);
recursion = false;
timeout = keep;
working = true;
}
return false;
}
/* Keep cranking... */
} while ( ((black() != blck) || (blck == Position.Any)) &&
((orange() != orng) || (orng == Position.Any)) );
if ((orng == Position.Locked) || (orng == Position.Unlocked)) {
/* Keep cranking for a bit longer when locking/unlocking to fully extend/retract the bolt */
delay(Delay.Override);
}
motor.stop();
working = false;
return true;
}
uint8_t Lock::black() {
DEBUG("Lock:black(2A="); DEBUG(sensor2A); DEBUG(", 2B="); DEBUG(sensor2B); DEBUG(")");
if (working && ((millis() - timeout) > Delay.Timeout)) {
DEBUG(" = Jammed\n");
return Position.Jammed;
}
if (lockClockwise) {
if ((sensor2A == HIGH) && (sensor2B == HIGH)) {
/* Black ring parked at neutral mid-point */
DEBUG(" = Neutral\n");
return Position.Neutral;
}
if ((sensor2A == LOW ) && (sensor2B == HIGH)) {
/* Black ring rotated all the way clockwise */
DEBUG(" = Locked\n");
return Position.Locked;
}
if ((sensor2A == HIGH) && (sensor2B == LOW )) {
/* Black ring rotated all the way counter-clockwise */
DEBUG(" = Unlocked\n");
return Position.Unlocked;
}
DEBUG(" = Unknown\n");
return Position.Unknown;
} else {
if ((sensor2A == HIGH) && (sensor2B == HIGH)) {
/* Black ring parked at neutral mid-point */
DEBUG(" = Neutral\n");
return Position.Neutral;
}
if ((sensor2A == LOW ) && (sensor2B == HIGH)) {
/* Black ring rotated all the way clockwise */
DEBUG(" = Unlocked\n");
return Position.Unlocked;
}
if ((sensor2A == HIGH) && (sensor2B == LOW )) {
/* Black ring rotated all the way counter-clockwise */
DEBUG(" = Locked\n");
return Position.Locked;
}
DEBUG(" = Unknown\n");
return Position.Unknown;
}
}
uint8_t Lock::orange() {
if (working && ((millis() - timeout) > Delay.Timeout)) {
return Position.Jammed;
}
if (lockClockwise) {
if ((sensor1A == HIGH) && (sensor1B == LOW )) {
/* Orange ring rotated all the way clockwise relative to the black ring */
return Position.Unlocked;
}
if ((sensor1A == LOW ) && (sensor1B == HIGH)) {
/* Orange ring rotated all the way counter-clockwise relative to the black ring */
return Position.Locked;
}
return Position.Unknown;
} else {
if ((sensor1A == HIGH) && (sensor1B == LOW )) {
/* Orange ring rotated all the way clockwise relative to the black ring */
return Position.Locked;
}
if ((sensor1A == LOW ) && (sensor1B == HIGH)) {
/* Orange ring rotated all the way counter-clockwise relative to the black ring */
return Position.Unlocked;
}
return Position.Unknown;
}
}
================================================
FILE: examples/lock/rfduino/lock.h
================================================
#ifndef _LOCK_H_
#define _LOCK_H_
#include <Arduino.h>
#include "sensor.h"
#include "motor.h"
class Lock {
public:
Lock(Sensor& sensor1A_, Sensor& sensor1B_, Sensor& sensor2A_, Sensor& sensor2B_,
Motor& motor_, const bool lockClockwise_);
void begin();
uint8_t state(void);
bool set(uint8_t state);
const static struct LockState { // HAP-NodeJS/lib/gen/HomeKitTypes.js #897
static const uint8_t Unsecured = 0;
static const uint8_t Secured = 1;
static const uint8_t Jammed = 2;
static const uint8_t Unknown = 3;
} State;
private:
bool rotate(uint8_t blck, uint8_t orng, bool clockwise = true, bool sure = true);
uint8_t orange();
uint8_t black();
const static struct RingPosition {
static const uint8_t Unlocked = 0;
static const uint8_t Locked = 1;
static const uint8_t Jammed = 2;
static const uint8_t Unknown = 3;
static const uint8_t Neutral = 4;
static const uint8_t Any = ~0;
} Position;
const static struct LockTimeDelay {
static const uint32_t Timeout = 3000; // milliseconds
static const uint32_t DirectionChange = 300; // milliseconds
static const uint32_t Override = 500; // milliseconds - needs to be tuned for each lock
} Delay;
bool working;
uint32_t timeout; // milliseconds - overflows after ~50 days
uint8_t lastState;
Sensor& sensor1A;
Sensor& sensor1B;
Sensor& sensor2A;
Sensor& sensor2B;
Motor& motor;
const bool lockClockwise;
};
#endif
================================================
FILE: examples/lock/rfduino/motor.cpp
================================================
#include "motor.h"
// #define DEBUG(message) Serial.print(message)
#define DEBUG(message)
Motor::Motor(const uint32_t minusPin_, const uint32_t plusPin_,
const uint32_t pwmPin_, const uint8_t pwm_) :
minusPin(minusPin_),
plusPin(plusPin_),
pwmPin(pwmPin_),
pwm(pwm_)
{ }
void Motor::begin() {
pinMode(minusPin, OUTPUT);
pinMode(plusPin, OUTPUT);
pinMode(pwmPin, OUTPUT);
}
void Motor::start(bool clockwise) {
analogWrite(pwmPin, pwm);
if (clockwise) {
digitalWrite(minusPin, HIGH);
digitalWrite(plusPin, LOW);
} else {
digitalWrite(minusPin, LOW);
digitalWrite(plusPin, HIGH);
}
DEBUG("Motor::start(clkws="); DEBUG(clockwise); DEBUG(")\n");
}
void Motor::stop() {
analogWrite(pwmPin, 0);
digitalWrite(minusPin, LOW);
digitalWrite(plusPin, LOW);
DEBUG("Motor::stop()\n");
}
Motor::~Motor() {
stop();
DEBUG("Motor::destructor()\n");
}
================================================
FILE: examples/lock/rfduino/motor.h
================================================
#ifndef _MOTOR_H_
#define _MOTOR_H_
#include <Arduino.h>
class Motor {
public:
Motor(const uint32_t minusPin_, const uint32_t plusPin_,
const uint32_t pwmPin_, const uint8_t pwm_);
~Motor();
void begin();
void start(bool clockwise = true);
void stop();
private:
const uint32_t minusPin;
const uint32_t plusPin;
const uint32_t pwmPin;
const uint8_t pwm;
};
#endif
================================================
FILE: examples/lock/rfduino/rfduino.ino
================================================
#include <Arduino.h>
#include <BLEPeripheral.h>
#include "sensor.h"
#include "motor.h"
#include "lock.h"
static struct BoardPins {
const uint8_t Motor1 = 0;
const uint8_t Motor2 = 1;
const uint8_t MotorPWM = 2;
const uint8_t Sensor1A = 3;
const uint8_t Sensor1B = 4;
const uint8_t Sensor2A = 5;
const uint8_t Sensor2B = 6;
} Pin;
BLEPeripheral ble;
BLEService informationService("180A");
BLECharacteristic modelCharacteristic("2A24", BLERead, "RFduino");
BLECharacteristic manufacturerCharacteristic("2A29", BLERead, "Lockitron");
BLECharacteristic serialNumberCharacteristic("2A25", BLERead, "V1");
BLEService lockMechanismService("43AAF900-5FF0-4633-95A2-FE4189EE103B");
BLEUnsignedCharCharacteristic targetStateCharacteristic("43AAF901-5FF0-4633-95A2-FE4189EE103B",
BLEWrite | BLERead | BLENotify);
BLEUnsignedCharCharacteristic currentStateCharacteristic("43AAF902-5FF0-4633-95A2-FE4189EE103B",
BLERead | BLENotify);
Sensor sensor1A(Pin.Sensor1A);
Sensor sensor1B(Pin.Sensor1B);
Sensor sensor2A(Pin.Sensor2A);
Sensor sensor2B(Pin.Sensor2B);
Motor motor(Pin.Motor1, Pin.Motor2, Pin.MotorPWM, 128);
Lock lock = Lock(sensor1A, sensor1B, sensor2A, sensor2B, motor, true);
volatile bool targetStateUpdate = false;
void targetStateWritten(BLECentral& /*central*/, BLECharacteristic& /*characteristic*/) {
targetStateUpdate = true;
}
void setup() {
// DEBUG Serial.begin(115200);
ble.setLocalName("Lock");
ble.addAttribute(informationService);
ble.addAttribute(modelCharacteristic);
ble.addAttribute(manufacturerCharacteristic);
ble.addAttribute(serialNumberCharacteristic);
ble.addAttribute(lockMechanismService);
ble.addAttribute(targetStateCharacteristic);
ble.addAttribute(currentStateCharacteristic);
targetStateCharacteristic.setEventHandler(BLEWritten, targetStateWritten);
ble.begin();
lock.begin();
}
void loop() {
ble.poll();
RFduino_ULPDelay(200);
if (targetStateUpdate) {
lock.set(targetStateCharacteristic.value());
currentStateCharacteristic.setValue(lock.state());
targetStateUpdate = false;
}
if (lock.state() != currentStateCharacteristic.value()) {
targetStateCharacteristic.setValue(lock.state());
currentStateCharacteristic.setValue(lock.state());
}
}
================================================
FILE: examples/lock/rfduino/rfduino.sch
================================================
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE eagle SYSTEM "eagle.dtd">
<eagle version="7.5.0">
<drawing>
<settings>
<setting alwaysvectorfont="no"/>
<setting verticaltext="up"/>
</settings>
<grid distance="0.1" unitdist="inch" unit="inch" style="lines" multiple="1" display="no" altdistance="0.01" altunitdist="inch" altunit="inch"/>
<layers>
<layer number="1" name="Top" color="4" fill="1" visible="no" active="no"/>
<layer number="16" name="Bottom" color="1" fill="1" visible="no" active="no"/>
<layer number="17" name="Pads" color="2" fill="1" visible="no" active="no"/>
<layer number="18" name="Vias" color="2" fill="1" visible="no" active="no"/>
<layer number="19" name="Unrouted" color="6" fill="1" visible="no" active="no"/>
<layer number="20" name="Dimension" color="15" fill="1" visible="no" active="no"/>
<layer number="21" name="tPlace" color="7" fill="1" visible="no" active="no"/>
<layer number="22" name="bPlace" color="7" fill="1" visible="no" active="no"/>
<layer number="23" name="tOrigins" color="15" fill="1" visible="no" active="no"/>
<layer number="24" name="bOrigins" color="15" fill="1" visible="no" active="no"/>
<layer number="25" name="tNames" color="7" fill="1" visible="no" active="no"/>
<layer number="26" name="bNames" color="7" fill="1" visible="no" active="no"/>
<layer number="27" name="tValues" color="7" fill="1" visible="no" active="no"/>
<layer number="28" name="bValues" color="7" fill="1" visible="no" active="no"/>
<layer number="29" name="tStop" color="7" fill="3" visible="no" active="no"/>
<layer number="30" name="bStop" color="7" fill="6" visible="no" active="no"/>
<layer number="31" name="tCream" color="7" fill="4" visible="no" active="no"/>
<layer number="32" name="bCream" color="7" fill="5" visible="no" active="no"/>
<layer number="33" name="tFinish" color="6" fill="3" visible="no" active="no"/>
<layer number="34" name="bFinish" color="6" fill="6" visible="no" active="no"/>
<layer number="35" name="tGlue" color="7" fill="4" visible="no" active="no"/>
<layer number="36" name="bGlue" color="7" fill="5" visible="no" active="no"/>
<layer number="37" name="tTest" color="7" fill="1" visible="no" active="no"/>
<layer number="38" name="bTest" color="7" fill="1" visible="no" active="no"/>
<layer number="39" name="tKeepout" color="4" fill="11" visible="no" active="no"/>
<layer number="40" name="bKeepout" color="1" fill="11" visible="no" active="no"/>
<layer number="41" name="tRestrict" color="4" fill="10" visible="no" active="no"/>
<layer number="42" name="bRestrict" color="1" fill="10" visible="no" active="no"/>
<layer number="43" name="vRestrict" color="2" fill="10" visible="no" active="no"/>
<layer number="44" name="Drills" color="7" fill="1" visible="no" active="no"/>
<layer number="45" name="Holes" color="7" fill="1" visible="no" active="no"/>
<layer number="46" name="Milling" color="3" fill="1" visible="no" active="no"/>
<layer number="47" name="Measures" color="7" fill="1" visible="no" active="no"/>
<layer number="48" name="Document" color="7" fill="1" visible="no" active="no"/>
<layer number="49" name="Reference" color="7" fill="1" visible="no" active="no"/>
<layer number="50" name="dxf" color="7" fill="1" visible="no" active="no"/>
<layer number="51" name="tDocu" color="7" fill="1" visible="no" active="no"/>
<layer number="52" name="bDocu" color="7" fill="1" visible="no" active="no"/>
<layer number="53" name="tGND_GNDA" color="7" fill="9" visible="no" active="no"/>
<layer number="54" name="bGND_GNDA" color="1" fill="9" visible="no" active="no"/>
<layer number="56" name="wert" color="7" fill="1" visible="no" active="no"/>
<layer number="57" name="tCAD" color="7" fill="1" visible="no" active="no"/>
<layer number="59" name="tCarbon" color="7" fill="1" visible="no" active="no"/>
<layer number="60" name="bCarbon" color="7" fill="1" visible="no" active="no"/>
<layer number="90" name="Modules" color="5" fill="1" visible="yes" active="yes"/>
<layer number="91" name="Nets" color="2" fill="1" visible="yes" active="yes"/>
<layer number="92" name="Busses" color="1" fill="1" visible="yes" active="yes"/>
<layer number="93" name="Pins" color="2" fill="1" visible="no" active="yes"/>
<layer number="94" name="Symbols" color="4" fill="1" visible="yes" active="yes"/>
<layer number="95" name="Names" color="7" fill="1" visible="yes" active="yes"/>
<layer number="96" name="Values" color="7" fill="1" visible="yes" active="yes"/>
<layer number="97" name="Info" color="7" fill="1" visible="yes" active="yes"/>
<layer number="98" name="Guide" color="6" fill="1" visible="yes" active="yes"/>
<layer number="99" name="SpiceOrder" color="7" fill="1" visible="yes" active="yes"/>
<layer number="100" name="Muster" color="7" fill="1" visible="no" active="no"/>
<layer number="101" name="Patch_Top" color="12" fill="4" visible="yes" active="yes"/>
<layer number="102" name="Vscore" color="7" fill="1" visible="yes" active="yes"/>
<layer number="103" name="tMap" color="7" fill="1" visible="yes" active="yes"/>
<layer number="104" name="Name" color="16" fill="1" visible="yes" active="yes"/>
<layer number="105" name="tPlate" color="7" fill="1" visible="yes" active="yes"/>
<layer number="106" name="bPlate" color="7" fill="1" visible="yes" active="yes"/>
<layer number="107" name="Crop" color="7" fill="1" visible="yes" active="yes"/>
<layer number="108" name="fp8" color="7" fill="1" visible="yes" active="yes"/>
<layer number="109" name="fp9" color="7" fill
gitextract_nhq2hgc9/
├── config.json
├── examples/
│ ├── humidity/
│ │ ├── arduino101/
│ │ │ ├── Si7021.cpp
│ │ │ ├── Si7021.h
│ │ │ ├── arduino101.fzz
│ │ │ └── arduino101.ino
│ │ ├── bluefruit/
│ │ │ ├── Si7021.cpp
│ │ │ ├── Si7021.h
│ │ │ ├── bluefruit.fzz
│ │ │ └── bluefruit.ino
│ │ ├── config.json
│ │ ├── images/
│ │ │ └── humidity.psd
│ │ └── readme.md
│ ├── lightbulb/
│ │ ├── arduino101/
│ │ │ ├── arduino101.fzz
│ │ │ └── arduino101.ino
│ │ ├── config.json
│ │ ├── images/
│ │ │ └── lightbulb.psd
│ │ └── readme.md
│ ├── lightbulb-rgb/
│ │ ├── arduino101/
│ │ │ ├── arduino101.fzz
│ │ │ └── arduino101.ino
│ │ ├── config.json
│ │ ├── images/
│ │ │ └── lightbulb-rgb.psd
│ │ └── readme.md
│ ├── lock/
│ │ ├── arduino101/
│ │ │ ├── arduino101.ino
│ │ │ ├── arduino101.sch
│ │ │ ├── dummy/
│ │ │ │ └── dummy.ino
│ │ │ ├── lock.cpp
│ │ │ ├── lock.h
│ │ │ ├── motor.cpp
│ │ │ ├── motor.h
│ │ │ ├── sensor.cpp
│ │ │ └── sensor.h
│ │ ├── config.json
│ │ ├── images/
│ │ │ └── lock.psd
│ │ ├── readme.md
│ │ └── rfduino/
│ │ ├── lock.cpp
│ │ ├── lock.h
│ │ ├── motor.cpp
│ │ ├── motor.h
│ │ ├── rfduino.ino
│ │ ├── rfduino.sch
│ │ ├── sensor.cpp
│ │ └── sensor.h
│ ├── readme.md
│ ├── switch/
│ │ ├── arduino101/
│ │ │ ├── arduino101.fzz
│ │ │ └── arduino101.ino
│ │ ├── config.json
│ │ ├── images/
│ │ │ └── switch.psd
│ │ └── readme.md
│ └── thermometer/
│ ├── arduino101/
│ │ ├── arduino101.fzz
│ │ └── arduino101.ino
│ ├── bluefruit/
│ │ ├── bluefruit.fzz
│ │ └── bluefruit.ino
│ ├── config.json
│ ├── images/
│ │ └── thermometer.psd
│ └── readme.md
├── images/
│ ├── examples.psd
│ └── overview.psd
├── index.js
├── license.txt
├── package.json
├── readme.md
└── source/
├── accessory.js
├── characteristic.js
├── platform.js
└── service.js
SYMBOL INDEX (15 symbols across 12 files)
FILE: examples/humidity/arduino101/Si7021.h
function class (line 25) | class Si7021 {
FILE: examples/humidity/bluefruit/Si7021.h
function class (line 25) | class Si7021 {
FILE: examples/lock/arduino101/lock.h
function class (line 10) | class Lock {
FILE: examples/lock/arduino101/motor.h
function class (line 7) | class Motor {
FILE: examples/lock/arduino101/sensor.h
function class (line 7) | class Sensor {
FILE: examples/lock/rfduino/lock.h
function class (line 10) | class Lock {
FILE: examples/lock/rfduino/motor.h
function class (line 7) | class Motor {
FILE: examples/lock/rfduino/sensor.h
function class (line 7) | class Sensor {
FILE: source/accessory.js
function BluetoothAccessory (line 12) | function BluetoothAccessory(log, config) {
function trimUUID (line 126) | function trimUUID(uuid) {
FILE: source/characteristic.js
function BluetoothCharacteristic (line 11) | function BluetoothCharacteristic(log, config, prefix) {
FILE: source/platform.js
function BluetoothPlatform (line 13) | function BluetoothPlatform(log, config, homebridgeAPI) {
function trimAddress (line 126) | function trimAddress(address) {
FILE: source/service.js
function BluetoothService (line 12) | function BluetoothService(log, config, prefix) {
function trimUUID (line 100) | function trimUUID(uuid) {
Condensed preview — 65 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (421K chars).
[
{
"path": "config.json",
"chars": 3000,
"preview": "{\n \"bridge\": {\n \"name\": \"Raspberry Pi 3\",\n \"username\": \"CC:22:3D:E3:CE:30\",\n \"port\": 51826,\n \"pin\": \"031-45"
},
{
"path": "examples/humidity/arduino101/Si7021.cpp",
"chars": 3558,
"preview": "/**************************************************************************\n @file Si7021.cpp\n @author Limor Fried"
},
{
"path": "examples/humidity/arduino101/Si7021.h",
"chars": 1795,
"preview": "#ifndef _SI7021_H_\n#define _SI7021_H_\n\n/**************************************************************************\n @fi"
},
{
"path": "examples/humidity/arduino101/arduino101.ino",
"chars": 3088,
"preview": "#include <Arduino.h>\n#include <CurieBLE.h>\n#include <SoftwareWire.h>\n#include \"Si7021.h\"\n\nstatic struct BoardPins {\n co"
},
{
"path": "examples/humidity/bluefruit/Si7021.cpp",
"chars": 3558,
"preview": "/**************************************************************************\n @file Si7021.cpp\n @author Limor Fried"
},
{
"path": "examples/humidity/bluefruit/Si7021.h",
"chars": 1795,
"preview": "#ifndef _SI7021_H_\n#define _SI7021_H_\n\n/**************************************************************************\n @fi"
},
{
"path": "examples/humidity/bluefruit/bluefruit.ino",
"chars": 4049,
"preview": "#include <SPI.h>\n#include <Arduino.h>\n\n#include <Adafruit_BLE.h>\n#include <Adafruit_BLEGatt.h>\n#include <Adafruit_Bluefr"
},
{
"path": "examples/humidity/config.json",
"chars": 1189,
"preview": "{\n \"bridge\": {\n \"name\": \"Raspberry Pi 3\",\n \"username\": \"CC:22:3D:E3:CE:30\",\n \"port\": 51826,\n \"pin\": \"314-15"
},
{
"path": "examples/humidity/readme.md",
"chars": 7913,
"preview": "\n# Humidity and Temperature Sensor\n\n\nTurn a BLE capable microprocessor and the [Si7021](https://www.silabs.com/Support%2"
},
{
"path": "examples/lightbulb/arduino101/arduino101.ino",
"chars": 1849,
"preview": "#include <Arduino.h>\n#include <CurieBLE.h>\n\nconst int pinLED = 13;\n\n\nBLEPeripheral ble;\nBLEService informationService(\"1"
},
{
"path": "examples/lightbulb/config.json",
"chars": 767,
"preview": "{\n \"bridge\": {\n \"name\": \"Raspberry Pi 3\",\n \"username\": \"CC:22:3D:E3:CE:30\",\n \"port\": 51826,\n \"pin\": \"314-15"
},
{
"path": "examples/lightbulb/readme.md",
"chars": 5873,
"preview": "\r\n# Lightbulb\r\n\r\n\r\nTurn an LED connected to a BLE capable microprocessor into a wireless HomeKit lightbulb. Use the Home"
},
{
"path": "examples/lightbulb-rgb/arduino101/arduino101.ino",
"chars": 6169,
"preview": "#include <math.h>\n#include <Arduino.h>\n#include <CurieBLE.h>\n\nconst int pinRedLED = 5;\nconst int pinGreenLED = 6;\nconst "
},
{
"path": "examples/lightbulb-rgb/config.json",
"chars": 1194,
"preview": "{\n \"bridge\": {\n \"name\": \"Raspberry Pi 3\",\n \"username\": \"CC:22:3D:E3:CE:30\",\n \"port\": 51826,\n \"pin\": \"314-15"
},
{
"path": "examples/lightbulb-rgb/readme.md",
"chars": 7334,
"preview": "\n# RGB Lightbulb\n\n\nTurn a bunch of LEDs connected to a BLE capable microprocessor into a wireless HomeKit light. Use the"
},
{
"path": "examples/lock/arduino101/arduino101.ino",
"chars": 2361,
"preview": "#include <Arduino.h>\n#include <CurieBLE.h>\n#include \"sensor.h\"\n#include \"motor.h\"\n#include \"lock.h\"\n\n\nstatic struct Boar"
},
{
"path": "examples/lock/arduino101/arduino101.sch",
"chars": 102009,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE eagle SYSTEM \"eagle.dtd\">\n<eagle version=\"7.5.0\">\n<drawing>\n<settings>\n"
},
{
"path": "examples/lock/arduino101/dummy/dummy.ino",
"chars": 1875,
"preview": "#include <Arduino.h>\n#include <CurieBLE.h>\n\nconst int pinStateLED = 13;\n\nBLEPeripheral ble;\nBLEService informationServic"
},
{
"path": "examples/lock/arduino101/lock.cpp",
"chars": 6172,
"preview": "#include \"lock.h\"\n\n//#define DEBUG(message) Serial.print(message)\n#define DEBUG(message)\n\n\nLock::Lock(Sensor& sensor1A_,"
},
{
"path": "examples/lock/arduino101/lock.h",
"chars": 1534,
"preview": "#ifndef _LOCK_H_\n#define _LOCK_H_\n\n#include <Arduino.h>\n\n#include \"sensor.h\"\n#include \"motor.h\"\n\n\nclass Lock {\n public:"
},
{
"path": "examples/lock/arduino101/motor.cpp",
"chars": 906,
"preview": "#include \"motor.h\"\n\n// #define DEBUG(message) Serial.print(message)\n#define DEBUG(message)\n\n\nMotor::Motor(const uint32_t"
},
{
"path": "examples/lock/arduino101/motor.h",
"chars": 420,
"preview": "#ifndef _MOTOR_H_\n#define _MOTOR_H_\n\n#include <Arduino.h>\n\n\nclass Motor {\n public:\n Motor(const uint32_t minusPin_, "
},
{
"path": "examples/lock/arduino101/sensor.cpp",
"chars": 331,
"preview": "#include \"sensor.h\"\n\n// #define DEBUG(message) Serial.print(message)\n#define DEBUG(message)\n\n\nSensor::Sensor(uint32_t pi"
},
{
"path": "examples/lock/arduino101/sensor.h",
"chars": 183,
"preview": "#ifndef _SENSOR_H_\n#define _SENSOR_H_\n\n#include <Arduino.h>\n\n\nclass Sensor {\n public:\n Sensor(uint32_t pin_);\n\n o"
},
{
"path": "examples/lock/config.json",
"chars": 937,
"preview": "{\n \"bridge\": {\n \"name\": \"Raspberry Pi 3\",\n \"username\": \"CC:22:3D:E3:CE:30\",\n \"port\": 51826,\n \"pin\": \"314-15"
},
{
"path": "examples/lock/readme.md",
"chars": 8825,
"preview": "\n# Lock\n\n\nTurn an old _Lockitron V1_ body connected to a BLE capable microprocessor into a wireless HomeKit lock. Use th"
},
{
"path": "examples/lock/rfduino/lock.cpp",
"chars": 6147,
"preview": "#include \"lock.h\"\n\n// #define DEBUG(message) Serial.print(message)\n#define DEBUG(message)\n\n\nLock::Lock(Sensor& sensor1A_"
},
{
"path": "examples/lock/rfduino/lock.h",
"chars": 1551,
"preview": "#ifndef _LOCK_H_\n#define _LOCK_H_\n\n#include <Arduino.h>\n\n#include \"sensor.h\"\n#include \"motor.h\"\n\n\nclass Lock {\n public:"
},
{
"path": "examples/lock/rfduino/motor.cpp",
"chars": 906,
"preview": "#include \"motor.h\"\n\n// #define DEBUG(message) Serial.print(message)\n#define DEBUG(message)\n\n\nMotor::Motor(const uint32_t"
},
{
"path": "examples/lock/rfduino/motor.h",
"chars": 420,
"preview": "#ifndef _MOTOR_H_\n#define _MOTOR_H_\n\n#include <Arduino.h>\n\n\nclass Motor {\n public:\n Motor(const uint32_t minusPin_, "
},
{
"path": "examples/lock/rfduino/rfduino.ino",
"chars": 2372,
"preview": "#include <Arduino.h>\n#include <BLEPeripheral.h>\n#include \"sensor.h\"\n#include \"motor.h\"\n#include \"lock.h\"\n\n\nstatic struct"
},
{
"path": "examples/lock/rfduino/rfduino.sch",
"chars": 127158,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE eagle SYSTEM \"eagle.dtd\">\n<eagle version=\"7.5.0\">\n<drawing>\n<settings>\n"
},
{
"path": "examples/lock/rfduino/sensor.cpp",
"chars": 331,
"preview": "#include \"sensor.h\"\n\n// #define DEBUG(message) Serial.print(message)\n#define DEBUG(message)\n\n\nSensor::Sensor(uint32_t pi"
},
{
"path": "examples/lock/rfduino/sensor.h",
"chars": 183,
"preview": "#ifndef _SENSOR_H_\n#define _SENSOR_H_\n\n#include <Arduino.h>\n\n\nclass Sensor {\n public:\n Sensor(uint32_t pin_);\n\n o"
},
{
"path": "examples/readme.md",
"chars": 2095,
"preview": "\r\n# Examples\r\n\r\n\r\nHere's couple of example how to use this plugin. Each example also contains sketches/code for selected"
},
{
"path": "examples/switch/arduino101/arduino101.ino",
"chars": 2373,
"preview": "#include <Arduino.h>\n#include <CurieBLE.h>\n\nconst int pinSwitch = 2;\n\n\nBLEPeripheral ble;\nBLEService informationService("
},
{
"path": "examples/switch/config.json",
"chars": 764,
"preview": "{\n \"bridge\": {\n \"name\": \"Raspberry Pi 3\",\n \"username\": \"CC:22:3D:E3:CE:30\",\n \"port\": 51826,\n \"pin\": \"314-15"
},
{
"path": "examples/switch/readme.md",
"chars": 5742,
"preview": "\n# Switch\n\n\nTurn a tactile push button connected to a BLE capable microprocessor into a wireless HomeKit switch. Use the"
},
{
"path": "examples/thermometer/arduino101/arduino101.ino",
"chars": 1981,
"preview": "#include <Arduino.h>\n#include <CurieBLE.h>\n#include <CurieIMU.h>\n\n\nBLEPeripheral ble;\nBLEService informationService(\"180"
},
{
"path": "examples/thermometer/bluefruit/bluefruit.ino",
"chars": 3431,
"preview": "#include <SPI.h>\n#include <Arduino.h>\n#include <Adafruit_BLE.h>\n#include <Adafruit_BLEGatt.h>\n#include <Adafruit_Bluefru"
},
{
"path": "examples/thermometer/config.json",
"chars": 801,
"preview": "{\n \"bridge\": {\n \"name\": \"Raspberry Pi 3\",\n \"username\": \"CC:22:3D:E3:CE:30\",\n \"port\": 51826,\n \"pin\": \"314-15"
},
{
"path": "examples/thermometer/readme.md",
"chars": 6681,
"preview": "\n# Thermometer\n\n\nTurn a BLE capable microprocessor into a wireless HomeKit thermometer. Temperature reading can be displ"
},
{
"path": "index.js",
"chars": 828,
"preview": "var Noble, Accessory, Service, Characteristic, UUIDGen;\r\n\r\nmodule.exports = function (homebridge) {\r\n console.log(\"Home"
},
{
"path": "license.txt",
"chars": 1068,
"preview": "MIT License\n\nCopyright (c) 2016 Vojta Molda\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
},
{
"path": "package.json",
"chars": 658,
"preview": "{\r\n \"name\": \"homebridge-bluetooth\",\r\n \"description\": \"Homebridge plugin that exposes Bluetooth peripherals as HomeKit "
},
{
"path": "readme.md",
"chars": 14451,
"preview": "\r\n# homebridge-bluetooth\r\n\r\n\r\n[](https://badge.fury.io/"
},
{
"path": "source/accessory.js",
"chars": 4318,
"preview": "var Accessory, BluetoothService;\r\nvar Chalk = require('chalk');\r\n\r\nmodule.exports = function (accessory, bluetoothServic"
},
{
"path": "source/characteristic.js",
"chars": 7339,
"preview": "var Characteristic;\r\nvar Chalk = require('chalk');\r\n\r\nmodule.exports = function (characteristic) {\r\n Characteristic = c"
},
{
"path": "source/platform.js",
"chars": 4644,
"preview": "var Noble, UUIDGen, Accessory, BluetoothAccessory;\r\n\r\nmodule.exports = function (noble, uuidGen, accessory, bluetoothAcc"
},
{
"path": "source/service.js",
"chars": 3498,
"preview": "var Service, BluetoothCharacteristic;\r\nvar Chalk = require('chalk');\r\n\r\nmodule.exports = function (service, bluetoothCha"
}
]
// ... and 15 more files (download for full content)
About this extraction
This page contains the full source code of the vojtamolda/homebridge-bluetooth GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 65 files (369.6 KB), approximately 137.0k tokens, and a symbol index with 15 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.