Reorg (#1)
* reorg to include core and librany deps in project using submodules * added script to insure submodules and such are setup * added OTA update support and started on syslog logging * added syslog logging support & Config saving via SPIFFS/Json file * start travis builds * DebugLevel * added eagle designs * added enclosure * update README
This commit is contained in:
parent
245cbc2dea
commit
8a53197001
20
.gitignore
vendored
20
.gitignore
vendored
|
|
@ -1,13 +1,15 @@
|
||||||
.metadata
|
.metadata
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.ino.cpp
|
|
||||||
.project
|
|
||||||
.cproject
|
|
||||||
.settings
|
|
||||||
Release
|
|
||||||
Debug
|
|
||||||
libraries
|
|
||||||
core
|
|
||||||
*.bak
|
*.bak
|
||||||
*-bak
|
*-bak
|
||||||
spec.d
|
/.setup_hook.sh
|
||||||
|
/ESPNTPServer/.ino.cpp
|
||||||
|
/ESPNTPServer/.project
|
||||||
|
/ESPNTPServer/.cproject
|
||||||
|
/ESPNTPServer/.settings
|
||||||
|
/ESPNTPServer/Release
|
||||||
|
/ESPNTPServer/Debug
|
||||||
|
/ESPNTPServer/libraries
|
||||||
|
/ESPNTPServer/core
|
||||||
|
/ESPNTPServer/spec.d
|
||||||
|
/RemoteSystemsTempFiles
|
||||||
|
|
|
||||||
30
.gitmodules
vendored
30
.gitmodules
vendored
|
|
@ -0,0 +1,30 @@
|
||||||
|
[submodule "hardware/esp8266com/esp8266"]
|
||||||
|
path = hardware/esp8266com/esp8266
|
||||||
|
url = https://github.com/esp8266/Arduino.git
|
||||||
|
[submodule "libraries/DLog"]
|
||||||
|
path = libraries/DLog
|
||||||
|
url = https://github.com/liebman/DLog.git
|
||||||
|
[submodule "libraries/DLogNet"]
|
||||||
|
path = libraries/DLogNet
|
||||||
|
url = https://github.com/liebman/DLogNet.git
|
||||||
|
[submodule "libraries/MicroNMEA"]
|
||||||
|
path = libraries/MicroNMEA
|
||||||
|
url = https://github.com/liebman/MicroNMEA.git
|
||||||
|
branch = handle-empty-date-or-time
|
||||||
|
[submodule "libraries/WiFiManager"]
|
||||||
|
path = libraries/WiFiManager
|
||||||
|
url = https://github.com/liebman/WiFiManager.git
|
||||||
|
branch = stdfunc
|
||||||
|
[submodule "libraries/esp8266-oled-ssd1306"]
|
||||||
|
path = libraries/esp8266-oled-ssd1306
|
||||||
|
url = https://github.com/liebman/esp8266-oled-ssd1306.git
|
||||||
|
branch = cleanup-warnings
|
||||||
|
[submodule "libraries/ESPAsyncUDP"]
|
||||||
|
path = libraries/ESPAsyncUDP
|
||||||
|
url = https://github.com/me-no-dev/ESPAsyncUDP.git
|
||||||
|
[submodule "libraries/Syslog"]
|
||||||
|
path = libraries/Syslog
|
||||||
|
url = https://github.com/arcao/Syslog.git
|
||||||
|
[submodule "libraries/ArduinoJson"]
|
||||||
|
path = libraries/ArduinoJson
|
||||||
|
url = https://github.com/bblanchon/ArduinoJson.git
|
||||||
46
.travis.yml
Normal file
46
.travis.yml
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
language: python
|
||||||
|
- "2.7"
|
||||||
|
|
||||||
|
sudo: required
|
||||||
|
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- APPLICATION_FOLDER="${HOME}/arduino-ide"
|
||||||
|
- SKETCHBOOK_FOLDER="${TRAVIS_BUILD_DIR}"
|
||||||
|
- ESP8266_DEVICE="esp8266com:esp8266:generic:CpuFrequency=160,CrystalFreq=26,FlashFreq=40,FlashMode=qio,FlashSize=4M1M,led=2,LwIPVariant=v2mss536,Debug=Serial1,DebugLevel=None____"
|
||||||
|
- ESPNTPSERVER_DIR="${TRAVIS_BUILD_DIR}/ESPNTPServer"
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- echo HOME is "'${HOME}'"
|
||||||
|
- id
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}"
|
||||||
|
- ./setup.sh
|
||||||
|
# setup arduino-ci-script
|
||||||
|
- git clone https://github.com/per1234/arduino-ci-script.git "${HOME}/scripts"
|
||||||
|
- cd "${HOME}/scripts"
|
||||||
|
# Get new tags from the remote
|
||||||
|
- git fetch --tags
|
||||||
|
# Checkout the latest tag
|
||||||
|
- git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
|
||||||
|
- source "${HOME}/scripts/arduino-ci-script.sh"
|
||||||
|
|
||||||
|
# Uncomment the following lines to get verbose output for debugging
|
||||||
|
# 0 (minimum/default) - 2 (maximum) verbosity
|
||||||
|
#- set_script_verbosity 1
|
||||||
|
# Turn on verbose output during compilation
|
||||||
|
#- set_verbose_output_during_compilation "true"
|
||||||
|
|
||||||
|
# Don't for library issues that don't affect compilation
|
||||||
|
- set_library_testing "false"
|
||||||
|
|
||||||
|
- set_application_folder "$APPLICATION_FOLDER"
|
||||||
|
- set_sketchbook_folder "$SKETCHBOOK_FOLDER"
|
||||||
|
|
||||||
|
- install_ide "1.8.5"
|
||||||
|
|
||||||
|
# make it look like a sketch for arduino
|
||||||
|
- touch "${ESPNTPSERVER_DIR}/ESPNTPServer.ino"
|
||||||
|
|
||||||
|
script:
|
||||||
|
# build with arduino
|
||||||
|
- build_sketch "${ESPNTPSERVER_DIR}" "${ESP8266_DEVICE}" "false" "1.8.5"
|
||||||
120
ESPNTPServer/Config.cpp
Normal file
120
ESPNTPServer/Config.cpp
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
* Config.cpp
|
||||||
|
*
|
||||||
|
* Created on: Jun 10, 2018
|
||||||
|
* Author: chris.l
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
#include "FS.h"
|
||||||
|
#include "Log.h"
|
||||||
|
#include "ArduinoJson.h"
|
||||||
|
|
||||||
|
static const char* TAG = "Config";
|
||||||
|
static const char* CONFIG_FILE = "Config.json";
|
||||||
|
|
||||||
|
|
||||||
|
Config::Config() : _syslog_host(), _syslog_port(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Config::~Config()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Config::begin()
|
||||||
|
{
|
||||||
|
dlog.info(TAG, "begin: Mounting SPIFFS");
|
||||||
|
|
||||||
|
if (!SPIFFS.begin())
|
||||||
|
{
|
||||||
|
dlog.warning(TAG, "begin: Formatting SPIFFS!!!!!");
|
||||||
|
if (SPIFFS.format())
|
||||||
|
{
|
||||||
|
dlog.error(TAG, "begin: SPIFFS format failed!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dlog.info(TAG, "begin: mounting SPIFFS after format!");
|
||||||
|
if (!SPIFFS.begin())
|
||||||
|
{
|
||||||
|
dlog.error(TAG, "begin: SPIFFS mount failed!!!!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Config::load()
|
||||||
|
{
|
||||||
|
dlog.info(TAG, "load: file: '%s'", CONFIG_FILE);
|
||||||
|
|
||||||
|
if (!SPIFFS.exists(CONFIG_FILE))
|
||||||
|
{
|
||||||
|
dlog.warning(TAG, "load: config file does not exist!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
File f = SPIFFS.open(CONFIG_FILE, "r");
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
dlog.error(TAG, "load: failed to open config file!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticJsonBuffer<512> buffer;
|
||||||
|
|
||||||
|
dlog.debug(TAG, "load: parsing file contents");
|
||||||
|
JsonObject& root = buffer.parseObject(f);
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
if (!root.success())
|
||||||
|
{
|
||||||
|
dlog.error(TAG, "load: fails to parse file!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
strlcpy(_syslog_host, root["syslogHost"]|"", sizeof(_syslog_host));
|
||||||
|
_syslog_port = root["syslogPort"] | 0;
|
||||||
|
|
||||||
|
dlog.info(TAG, "load: config loaded!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Config::save()
|
||||||
|
{
|
||||||
|
dlog.info(TAG, "save: file: '%s'", CONFIG_FILE);
|
||||||
|
|
||||||
|
File f = SPIFFS.open(CONFIG_FILE, "w");
|
||||||
|
|
||||||
|
StaticJsonBuffer<512> buffer;
|
||||||
|
JsonObject& root = buffer.createObject();
|
||||||
|
|
||||||
|
root["syslogHost"] = _syslog_host;
|
||||||
|
root["syslogPort"] = _syslog_port;
|
||||||
|
|
||||||
|
root.printTo(f);
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
dlog.info(TAG, "save: config saved");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Config::getSyslogHost()
|
||||||
|
{
|
||||||
|
return _syslog_host;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Config::setSyslogHost(const char* host)
|
||||||
|
{
|
||||||
|
strlcpy(_syslog_host, host, sizeof(_syslog_host));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t Config::getSyslogPort()
|
||||||
|
{
|
||||||
|
return _syslog_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Config::setSyslogPort(uint16_t port)
|
||||||
|
{
|
||||||
|
_syslog_port = port;
|
||||||
|
}
|
||||||
36
ESPNTPServer/Config.h
Normal file
36
ESPNTPServer/Config.h
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Config.h
|
||||||
|
*
|
||||||
|
* Created on: Jun 10, 2018
|
||||||
|
* Author: chris.l
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONFIG_H_
|
||||||
|
#define CONFIG_H_
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
class ConfigImpl;
|
||||||
|
|
||||||
|
class Config
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Config();
|
||||||
|
virtual ~Config();
|
||||||
|
|
||||||
|
bool begin();
|
||||||
|
|
||||||
|
bool load();
|
||||||
|
void save();
|
||||||
|
|
||||||
|
const char* getSyslogHost();
|
||||||
|
void setSyslogHost(const char* host);
|
||||||
|
uint16_t getSyslogPort();
|
||||||
|
void setSyslogPort(uint16_t port);
|
||||||
|
|
||||||
|
private:
|
||||||
|
char _syslog_host[64];
|
||||||
|
uint16_t _syslog_port;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* CONFIG_H_ */
|
||||||
|
|
@ -122,6 +122,19 @@ void Display::process()
|
||||||
display();
|
display();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Display::message(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
|
||||||
|
clear();
|
||||||
|
align(TEXT_ALIGN_CENTER);
|
||||||
|
vprint(64, 32, fmt, ap);
|
||||||
|
display();
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
void Display::clear()
|
void Display::clear()
|
||||||
{
|
{
|
||||||
_dsp.clear();
|
_dsp.clear();
|
||||||
|
|
@ -146,9 +159,13 @@ void Display::print(int16_t x, int16_t y, const char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
vprint(x, y, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Display::vprint(int16_t x, int16_t y, const char* fmt, va_list ap)
|
||||||
|
{
|
||||||
vsnprintf(_buffer, DISPLAY_BUFFER_LEN, fmt, ap);
|
vsnprintf(_buffer, DISPLAY_BUFFER_LEN, fmt, ap);
|
||||||
_buffer[DISPLAY_BUFFER_LEN-1] = '\0';
|
_buffer[DISPLAY_BUFFER_LEN-1] = '\0';
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
_dsp.drawString(x, y, _buffer);
|
_dsp.drawString(x, y, _buffer);
|
||||||
}
|
}
|
||||||
|
|
@ -24,12 +24,15 @@ public:
|
||||||
void end();
|
void end();
|
||||||
void process();
|
void process();
|
||||||
|
|
||||||
|
void message(const char* fmt, ...);
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
void display();
|
void display();
|
||||||
void align(OLEDDISPLAY_TEXT_ALIGNMENT alignment);
|
void align(OLEDDISPLAY_TEXT_ALIGNMENT alignment);
|
||||||
void font(const char* fontData);
|
void font(const char* fontData);
|
||||||
|
|
||||||
void print(int16_t x, int16_t y, const char* fmt, ...);
|
void print(int16_t x, int16_t y, const char* fmt, ...);
|
||||||
|
void vprint(int16_t x, int16_t y, const char* fmt, va_list ap);
|
||||||
private:
|
private:
|
||||||
SSD1306Wire _dsp;
|
SSD1306Wire _dsp;
|
||||||
GPS& _gps;
|
GPS& _gps;
|
||||||
|
|
@ -23,15 +23,20 @@
|
||||||
#include "ESPNTPServer.h"
|
#include "ESPNTPServer.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "DLogPrintWriter.h"
|
#include "DLogPrintWriter.h"
|
||||||
|
#include "DLogSyslogWriter.h"
|
||||||
|
|
||||||
#include "GPS.h"
|
#include "GPS.h"
|
||||||
#include "NTP.h"
|
#include "NTP.h"
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
DLog& dlog = DLog::getLog();
|
||||||
GPS gps(Serial, SYNC_PIN);
|
GPS gps(Serial, SYNC_PIN);
|
||||||
NTP ntp(gps);
|
NTP ntp(gps);
|
||||||
Display display(gps, ntp, SDA_PIN, SCL_PIN);
|
Display display(gps, ntp, SDA_PIN, SCL_PIN);
|
||||||
DLog& dlog = DLog::getLog();
|
Config config;
|
||||||
|
|
||||||
|
char devicename[32];
|
||||||
|
|
||||||
const char* SETUP_TAG = "setup";
|
const char* SETUP_TAG = "setup";
|
||||||
const char* LOOP_TAG = "loop";
|
const char* LOOP_TAG = "loop";
|
||||||
|
|
@ -54,9 +59,62 @@ void logTimeFirst(DLogBuffer& buffer, DLogLevel level)
|
||||||
tv.tv_usec);
|
tv.tv_usec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void processOTA(const char* ota_url, const char* ota_fp)
|
||||||
|
{
|
||||||
|
static PROGMEM const char TAG[] = "processOTA";
|
||||||
|
dlog.info(FPSTR(TAG), F("OTA update"));
|
||||||
|
|
||||||
|
dlog.info(FPSTR(TAG), F("checking for OTA from: '%s'"), ota_url);
|
||||||
|
display.message("Starting OTA");
|
||||||
|
|
||||||
|
ESPhttpUpdate.rebootOnUpdate(false);
|
||||||
|
|
||||||
|
t_httpUpdate_return ret;
|
||||||
|
|
||||||
|
if (strncmp(ota_url, "https:", 6) == 0)
|
||||||
|
{
|
||||||
|
ret = ESPhttpUpdate.update(ota_url, "0.4", ota_fp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = ESPhttpUpdate.update(ota_url, "0.4");
|
||||||
|
}
|
||||||
|
|
||||||
|
String reason = ESPhttpUpdate.getLastErrorString();
|
||||||
|
|
||||||
|
switch(ret)
|
||||||
|
{
|
||||||
|
case HTTP_UPDATE_OK:
|
||||||
|
dlog.info(FPSTR(TAG), F("OTA update OK! restarting..."));
|
||||||
|
dlog.end();
|
||||||
|
display.message("Success!");
|
||||||
|
delay(10000);
|
||||||
|
ESP.restart();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HTTP_UPDATE_FAILED:
|
||||||
|
dlog.info(FPSTR(TAG), F("OTA update failed! reason:'%s'"), reason.c_str());
|
||||||
|
display.message("FAILED!");
|
||||||
|
delay(10000);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HTTP_UPDATE_NO_UPDATES:
|
||||||
|
dlog.info(FPSTR(TAG), F("OTA no updates! reason:'%s'"), reason.c_str());
|
||||||
|
display.message("NO Update!");
|
||||||
|
delay(10000);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dlog.info(FPSTR(TAG), F("OTA update WTF? unexpected return code: %d reason: '%s'"), ret, reason.c_str());
|
||||||
|
display.message("Unknown!");
|
||||||
|
delay(10000);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
delay(5000); // delay for IDE to re-open serial
|
//delay(5000); // delay for IDE to re-open serial
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setup DLog with Serial1, set the pre function to add the date/time
|
// Setup DLog with Serial1, set the pre function to add the date/time
|
||||||
|
|
@ -65,32 +123,81 @@ void setup()
|
||||||
dlog.begin(new DLogPrintWriter(Serial1));
|
dlog.begin(new DLogPrintWriter(Serial1));
|
||||||
dlog.setPreFunc(&logTimeFirst);
|
dlog.setPreFunc(&logTimeFirst);
|
||||||
//dlog.setLevel("GPS", DLogLevel::DLOG_LEVEL_DEBUG);
|
//dlog.setLevel("GPS", DLogLevel::DLOG_LEVEL_DEBUG);
|
||||||
|
dlog.setLevel("Config", DLogLevel::DLOG_LEVEL_DEBUG);
|
||||||
|
|
||||||
dlog.info(SETUP_TAG, F("Startup!"));
|
dlog.info(SETUP_TAG, F("Startup!"));
|
||||||
|
|
||||||
|
String id = "ESPNTP:" + String(ESP.getChipId(), 16);
|
||||||
|
strncpy(devicename, id.c_str(), 32);
|
||||||
|
dlog.info(SETUP_TAG, "Device name: %s", devicename);
|
||||||
|
|
||||||
dlog.info(SETUP_TAG, F("initializing display"));
|
dlog.info(SETUP_TAG, F("initializing display"));
|
||||||
display.begin();
|
display.begin();
|
||||||
|
|
||||||
|
|
||||||
dlog.info(SETUP_TAG, F("initializing serial for GPS"));
|
dlog.info(SETUP_TAG, F("initializing serial for GPS"));
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
Serial.swap();
|
Serial.swap();
|
||||||
|
|
||||||
dlog.info(SETUP_TAG, F("initializing GPS"));
|
dlog.info(SETUP_TAG, F("initializing GPS"));
|
||||||
|
display.message("Starting GPS");
|
||||||
gps.begin();
|
gps.begin();
|
||||||
display.process();
|
display.process();
|
||||||
|
|
||||||
|
bool force_config = false;
|
||||||
|
|
||||||
|
config.begin();
|
||||||
|
|
||||||
|
if (!config.load())
|
||||||
|
{
|
||||||
|
dlog.warning(SETUP_TAG, "no config found, forcing config portal!");
|
||||||
|
force_config = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the reset/config button is pressed then force config
|
||||||
|
if (digitalRead(CONFIG_PIN) == 0)
|
||||||
|
{
|
||||||
|
time_t start = millis();
|
||||||
|
|
||||||
|
while (digitalRead(CONFIG_PIN) == 0)
|
||||||
|
{
|
||||||
|
time_t delta = millis() - start;
|
||||||
|
if (!force_config && delta > CONFIG_DELAY)
|
||||||
|
{
|
||||||
|
dlog.info(SETUP_TAG, F("reset button held, forcing config!"));
|
||||||
|
force_config = true;
|
||||||
|
display.message("Force Config");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(USE_NO_WIFI)
|
#if !defined(USE_NO_WIFI)
|
||||||
dlog.info(SETUP_TAG, F("initializing wifi"));
|
dlog.info(SETUP_TAG, F("initializing wifi"));
|
||||||
#if 0
|
display.message("Starting WiFi");
|
||||||
WiFiManager wifi;
|
WiFiSetup wifi(config, display, Serial1, false, devicename);
|
||||||
wifi.setDebugStream(Serial1);
|
wifi.connect(force_config);
|
||||||
wifi.setDebugOutput(false);
|
|
||||||
#else
|
const char* syslog_host = config.getSyslogHost();
|
||||||
WiFiManager wifi(Serial1);
|
uint16_t syslog_port = config.getSyslogPort();
|
||||||
wifi.setDebugOutput(true);
|
if (syslog_host != nullptr && strlen(syslog_host) > 0 && syslog_port != 0)
|
||||||
#endif
|
{
|
||||||
wifi.setDebugOutput(true);
|
dlog.info(SETUP_TAG, "enabling syslog: '%s:%u'", syslog_host, syslog_port);
|
||||||
String ssid = "ESPNTPServer" + String(ESP.getChipId());
|
dlog.begin(new DLogSyslogWriter("192.168.0.31", 514, devicename));
|
||||||
wifi.autoConnect(ssid.c_str(), NULL);
|
}
|
||||||
|
const char* url = wifi.getOTAURL();
|
||||||
|
const char* fp = wifi.getOTAFP();
|
||||||
|
if (fp == nullptr)
|
||||||
|
{
|
||||||
|
fp = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url != nullptr)
|
||||||
|
{
|
||||||
|
processOTA(url, fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
WiFiMode_t mode = WiFi.getMode();
|
||||||
|
dlog.error(SETUP_TAG, "WiFi mode: %d", mode);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
display.process();
|
display.process();
|
||||||
|
|
@ -140,6 +247,14 @@ void loop()
|
||||||
last_ip = ip;
|
last_ip = ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
uint32_t m = millis();
|
||||||
|
if (m % 1000 == 0)
|
||||||
|
{
|
||||||
|
dlog.info("loop", "uptime: %lu millis: %lu", m);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
gps.process();
|
gps.process();
|
||||||
|
|
||||||
static time_t last_seconds;
|
static time_t last_seconds;
|
||||||
|
|
@ -27,14 +27,18 @@
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include "Ticker.h"
|
#include "Ticker.h"
|
||||||
#if !defined(USE_NO_WIFI)
|
#if !defined(USE_NO_WIFI)
|
||||||
#include "WiFiManager.h"
|
#include "WiFiSetup.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "ESP8266httpUpdate.h"
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
// pin definitions
|
// pin definitions
|
||||||
#define SYNC_PIN 12 // (GPIO12) pin tied to 1hz square wave from GPS
|
#define SYNC_PIN 12 // GPIO12 pin tied to 1hz square wave from GPS
|
||||||
|
#define CONFIG_PIN 14 // GPIO14 tied to reset/config button
|
||||||
#define SDA_PIN 4
|
#define SDA_PIN 4
|
||||||
#define SCL_PIN 5
|
#define SCL_PIN 5
|
||||||
|
|
||||||
|
#define CONFIG_DELAY 1000 // how long to hold the button for config mode.
|
||||||
|
|
||||||
|
|
||||||
#endif /* _ESPNTPServer_H_ */
|
#endif /* _ESPNTPServer_H_ */
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* GPS.cpp
|
* GPS.cpp
|
||||||
*
|
*
|
||||||
* Copyright 2017 Christopher B. Liebman
|
* Copyright 2018 Christopher B. Liebman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -116,7 +116,9 @@ void GPS::process()
|
||||||
|
|
||||||
while (_stream.available() > 0)
|
while (_stream.available() > 0)
|
||||||
{
|
{
|
||||||
if (_nmea.process(_stream.read()))
|
int c = _stream.read();
|
||||||
|
dlog.trace(TAG, F("c: %c"), c);
|
||||||
|
if (_nmea.process(c))
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
getTime(&tv);
|
getTime(&tv);
|
||||||
|
|
@ -125,9 +127,9 @@ void GPS::process()
|
||||||
const char * id = _nmea.getMessageID();
|
const char * id = _nmea.getMessageID();
|
||||||
|
|
||||||
//
|
//
|
||||||
// if it was a GGA and its valid then check and maybe update the time
|
// if it was a RMC and its valid then check and maybe update the time
|
||||||
//
|
//
|
||||||
if (_nmea.getYear() > 2000 && strcmp("RMC", id) == 0)
|
if (_nmea.getYear() > 2017 && strcmp("RMC", id) == 0)
|
||||||
{
|
{
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
tm.tm_year = _nmea.getYear() - 1900;
|
tm.tm_year = _nmea.getYear() - 1900;
|
||||||
|
|
@ -174,7 +176,7 @@ void GPS::process()
|
||||||
}
|
}
|
||||||
else /* nmea not valid or sat count < 4 */
|
else /* nmea not valid or sat count < 4 */
|
||||||
{
|
{
|
||||||
if (_gps_valid)
|
if (_gps_valid || _valid_delay)
|
||||||
{
|
{
|
||||||
invalidate("NMEA:%s SATS:%d from: '%s'",
|
invalidate("NMEA:%s SATS:%d from: '%s'",
|
||||||
_nmea.isValid() ? "valid" : "invalid",
|
_nmea.isValid() ? "valid" : "invalid",
|
||||||
|
|
@ -220,6 +222,7 @@ void ICACHE_RAM_ATTR GPS::invalidate(const char* fmt, ...)
|
||||||
}
|
}
|
||||||
_valid = false;
|
_valid = false;
|
||||||
_gps_valid = false;
|
_gps_valid = false;
|
||||||
|
_valid_delay = 0;
|
||||||
_last_micros = 0;
|
_last_micros = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
#include "Ticker.h"
|
#include "Ticker.h"
|
||||||
|
|
||||||
#define REASON_SIZE 128
|
#define REASON_SIZE 128
|
||||||
#define NMEA_BUFFER_SIZE 128
|
#define NMEA_BUFFER_SIZE 250
|
||||||
#define PPS_TIMING_PIN 12 // (GPIO12) if defined PPS interrupt will make high during processing
|
#define PPS_TIMING_PIN 12 // (GPIO12) if defined PPS interrupt will make high during processing
|
||||||
#define VALID_DELAY 120 // delay (seconds) from gps valid to valid
|
#define VALID_DELAY 120 // delay (seconds) from gps valid to valid
|
||||||
#define VALID_TIMER_MS 1001 // if this timer expires we invalidate!
|
#define VALID_TIMER_MS 1001 // if this timer expires we invalidate!
|
||||||
128
ESPNTPServer/WiFiSetup.cpp
Normal file
128
ESPNTPServer/WiFiSetup.cpp
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* WiFiSetup.cpp
|
||||||
|
*
|
||||||
|
* Copyright 2018 Christopher B. Liebman
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Created on: May 27, 2018
|
||||||
|
* Author: chris.l
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "WiFiSetup.h"
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "Log.h"
|
||||||
|
static const char* TAG = "WiFiSetup";
|
||||||
|
|
||||||
|
WiFiSetup::WiFiSetup(Config& config, Display& display, Stream& serial, boolean debug, const char* devicename)
|
||||||
|
: _config(config),
|
||||||
|
_display(display),
|
||||||
|
_wm(serial),
|
||||||
|
_ota_url("ota_url", "OTA URL", "", 128),
|
||||||
|
_ota_fp("ota_fp", "OTA Fingerprint", "", 64),
|
||||||
|
_syslog_host("syslog_host", "Syslog Host", "", 64),
|
||||||
|
_syslog_port("syslog_port", "Syslog Port", "514", 8),
|
||||||
|
_devicename(devicename)
|
||||||
|
{
|
||||||
|
_wm.setDebugOutput(debug);
|
||||||
|
|
||||||
|
using namespace std::placeholders;
|
||||||
|
_wm.setAPCallback(std::bind(&WiFiSetup::startingPortal, this, _1));
|
||||||
|
_wm.setSaveConfigCallback(std::bind(&WiFiSetup::saveConfig, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
WiFiSetup::~WiFiSetup()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiSetup::connect(bool force_config)
|
||||||
|
{
|
||||||
|
WiFi.mode(WiFiMode::WIFI_STA);
|
||||||
|
if (force_config)
|
||||||
|
{
|
||||||
|
dlog.info(TAG, F("connect: starting forced config portal!"));
|
||||||
|
_wm.startConfigPortal(_devicename, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dlog.info(TAG, F("connect: auto-connecting"));
|
||||||
|
_wm.autoConnect(_devicename, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiSetup::startingPortal(WiFiManager* wmp)
|
||||||
|
{
|
||||||
|
(void) wmp;
|
||||||
|
dlog.info(TAG, F("startingPortal: updating param values"));
|
||||||
|
_syslog_host.setValue(_config.getSyslogHost(), 64);
|
||||||
|
char value[10];
|
||||||
|
snprintf(value, sizeof(value), "%u", _config.getSyslogPort());
|
||||||
|
_syslog_port.setValue(value, 8);
|
||||||
|
dlog.info(TAG, F("startingPortal: adding params"));
|
||||||
|
_wm.addParameter(&_ota_url);
|
||||||
|
_wm.addParameter(&_ota_fp);
|
||||||
|
_wm.addParameter(&_syslog_host);
|
||||||
|
_wm.addParameter(&_syslog_port);
|
||||||
|
|
||||||
|
dlog.debug(TAG, F("startingPortal: params added!"));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Update the display with the SSID to show portal is up
|
||||||
|
//
|
||||||
|
dlog.info(TAG, F("startingPortal: updating display"));
|
||||||
|
_display.message("SSID: %s", _wm.getConfigPortalSSID().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiSetup::saveConfig()
|
||||||
|
{
|
||||||
|
dlog.info(TAG, "saveConfig: updating values");
|
||||||
|
_config.setSyslogHost(_syslog_host.getValue());
|
||||||
|
_config.setSyslogPort(atoi(_syslog_port.getValue()));
|
||||||
|
dlog.debug(TAG, "saveConfig: saving!");
|
||||||
|
_config.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* WiFiSetup::getParam(WiFiManagerParameter& param)
|
||||||
|
{
|
||||||
|
const char* value = param.getValue();
|
||||||
|
|
||||||
|
if (strlen(value) > 0)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* WiFiSetup::getOTAURL()
|
||||||
|
{
|
||||||
|
return getParam(_ota_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* WiFiSetup::getOTAFP()
|
||||||
|
{
|
||||||
|
return getParam(_ota_fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* WiFiSetup::getSyslogHost()
|
||||||
|
{
|
||||||
|
return getParam(_syslog_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t WiFiSetup::getSyslogPort()
|
||||||
|
{
|
||||||
|
const char* value = getParam(_syslog_port);
|
||||||
|
int port = atoi(value);
|
||||||
|
return port;
|
||||||
|
}
|
||||||
54
ESPNTPServer/WiFiSetup.h
Normal file
54
ESPNTPServer/WiFiSetup.h
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* WiFiSetup.h
|
||||||
|
*
|
||||||
|
* Copyright 2018 Christopher B. Liebman
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Created on: May 27, 2018
|
||||||
|
* Author: chris.l
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WIFISETUP_H_
|
||||||
|
#define WIFISETUP_H_
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include "WiFiManager.h"
|
||||||
|
#include "Display.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
class WiFiSetup {
|
||||||
|
public:
|
||||||
|
WiFiSetup(Config& config, Display& display, Stream& serial, boolean debug, const char* devicename);
|
||||||
|
virtual ~WiFiSetup();
|
||||||
|
void connect(bool force_config = false);
|
||||||
|
const char* getOTAURL();
|
||||||
|
const char* getOTAFP();
|
||||||
|
const char* getSyslogHost();
|
||||||
|
uint16_t getSyslogPort();
|
||||||
|
private:
|
||||||
|
Config& _config;
|
||||||
|
Display& _display;
|
||||||
|
WiFiManager _wm;
|
||||||
|
WiFiManagerParameter _ota_url;
|
||||||
|
WiFiManagerParameter _ota_fp;
|
||||||
|
WiFiManagerParameter _syslog_host;
|
||||||
|
WiFiManagerParameter _syslog_port;
|
||||||
|
const char* _devicename;
|
||||||
|
void startingPortal(WiFiManager* wmp);
|
||||||
|
void saveConfig();
|
||||||
|
const char*getParam(WiFiManagerParameter& param);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* WIFISETUP_H_ */
|
||||||
20
README.md
20
README.md
|
|
@ -1,6 +1,22 @@
|
||||||
# ESPNTPServer
|
# ESPNTPServer
|
||||||
GPS fueled ESP8266 based NTP Server
|
GPS fueled ESP8266 based NTP Server
|
||||||
|
|
||||||
GPS: any with standard NMEA sentences & a pulse per second signal..
|
[](https://travis-ci.org/liebman/ESPNTPServer.svg)
|
||||||
|
|
||||||
Work in progress....
|
[ESPNTPServer](ESPNTPServer) Contains the code for the NTP Server
|
||||||
|
|
||||||
|
[hardware](hardware) contains the esp8266 arduino core version used as a git submodule
|
||||||
|
|
||||||
|
[libraries](libraries) has all needed libraries as git submodules
|
||||||
|
|
||||||
|
[eagle](eagle) contains the schematic and board designs in Eagle cad.
|
||||||
|
|
||||||
|
[enclosure](enclosure) contains the STL files for the enclosure.
|
||||||
|
|
||||||
|
This is designed around [this GPS module](https://www.amazon.com/gp/product/B075DD5746/) but any module with standard NMEA output and a pult per second signal will work if you redesign the board or use an adapter.
|
||||||
|
|
||||||
|
I also used [this display module](https://www.amazon.com/gp/product/B00O2KDQBE/). You can use others but be careful with the power polarity, I have modules where VCC and ground pins are in a different order.
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
|
|
||||||
2218
eagle/ESPNTPServer/ESPNTPServer.brd
Normal file
2218
eagle/ESPNTPServer/ESPNTPServer.brd
Normal file
File diff suppressed because it is too large
Load Diff
194
eagle/ESPNTPServer/ESPNTPServer.cam
Normal file
194
eagle/ESPNTPServer/ESPNTPServer.cam
Normal file
|
|
@ -0,0 +1,194 @@
|
||||||
|
{
|
||||||
|
"author": {
|
||||||
|
"email": "liebman@zod.com",
|
||||||
|
"name": "Chris Liebman"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"EN": "EAGLE default 2 layer CAM job."
|
||||||
|
},
|
||||||
|
"output_type": "zip",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"format_specifier": {
|
||||||
|
"decimal": 3,
|
||||||
|
"integer": 3
|
||||||
|
},
|
||||||
|
"output_type": "drill",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"drills": {
|
||||||
|
"NPTH": true,
|
||||||
|
"PTH": true,
|
||||||
|
"VIA": true
|
||||||
|
},
|
||||||
|
"filename_format": "outputs/drills.xln",
|
||||||
|
"layers": {
|
||||||
|
"from": 1,
|
||||||
|
"to": 16
|
||||||
|
},
|
||||||
|
"name": "Excellon",
|
||||||
|
"type": "excellon"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename_prefix": "outputs",
|
||||||
|
"format_specifier": {
|
||||||
|
"decimal": 4,
|
||||||
|
"integer": 3
|
||||||
|
},
|
||||||
|
"generate_job_file": true,
|
||||||
|
"output_type": "gerber",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"board_outline": false,
|
||||||
|
"config": {
|
||||||
|
"file_function": "Copper",
|
||||||
|
"layer": 1,
|
||||||
|
"layer_details": "mixed",
|
||||||
|
"layer_type": "top"
|
||||||
|
},
|
||||||
|
"filename_format": "%PREFIX/copper_top.gbr",
|
||||||
|
"layers": [
|
||||||
|
1,
|
||||||
|
18,
|
||||||
|
17
|
||||||
|
],
|
||||||
|
"name": "Top Copper",
|
||||||
|
"polarity": "positive",
|
||||||
|
"type": "gerber_layer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"board_outline": false,
|
||||||
|
"config": {
|
||||||
|
"file_function": "Copper",
|
||||||
|
"layer": 2,
|
||||||
|
"layer_details": "mixed",
|
||||||
|
"layer_type": "bottom"
|
||||||
|
},
|
||||||
|
"filename_format": "%PREFIX/copper_bottom.gbr",
|
||||||
|
"layers": [
|
||||||
|
16,
|
||||||
|
17,
|
||||||
|
18
|
||||||
|
],
|
||||||
|
"name": "Bottom Copper",
|
||||||
|
"polarity": "positive",
|
||||||
|
"type": "gerber_layer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"board_outline": true,
|
||||||
|
"config": {
|
||||||
|
"file_function": "Profile",
|
||||||
|
"plating": "non-plated"
|
||||||
|
},
|
||||||
|
"filename_format": "%PREFIX/profile.gbr",
|
||||||
|
"layers": [
|
||||||
|
],
|
||||||
|
"milling": true,
|
||||||
|
"polarity": "positive",
|
||||||
|
"type": "gerber_layer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"board_outline": false,
|
||||||
|
"config": {
|
||||||
|
"file_function": "Soldermask",
|
||||||
|
"index": 1,
|
||||||
|
"layer_type": "top"
|
||||||
|
},
|
||||||
|
"filename_format": "%PREFIX/soldermask_top.gbr",
|
||||||
|
"layers": [
|
||||||
|
29
|
||||||
|
],
|
||||||
|
"name": "Soldermask Top",
|
||||||
|
"polarity": "negative",
|
||||||
|
"type": "gerber_layer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"board_outline": false,
|
||||||
|
"config": {
|
||||||
|
"file_function": "Soldermask",
|
||||||
|
"index": 1,
|
||||||
|
"layer_type": "bottom"
|
||||||
|
},
|
||||||
|
"filename_format": "%PREFIX/soldermask_bottom.gbr",
|
||||||
|
"layers": [
|
||||||
|
30
|
||||||
|
],
|
||||||
|
"name": "Soldermask Bottom",
|
||||||
|
"polarity": "negative",
|
||||||
|
"type": "gerber_layer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"board_outline": false,
|
||||||
|
"config": {
|
||||||
|
"file_function": "Paste",
|
||||||
|
"layer_type": "top"
|
||||||
|
},
|
||||||
|
"filename_format": "%PREFIX/solderpaste_top.gbr",
|
||||||
|
"layers": [
|
||||||
|
31
|
||||||
|
],
|
||||||
|
"milling": false,
|
||||||
|
"name": "Solderpaste Top",
|
||||||
|
"polarity": "positive",
|
||||||
|
"type": "gerber_layer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"board_outline": false,
|
||||||
|
"config": {
|
||||||
|
"file_function": "Paste",
|
||||||
|
"layer_type": "bottom"
|
||||||
|
},
|
||||||
|
"filename_format": "%PREFIX/solderpaste_bottom.gbr",
|
||||||
|
"layers": [
|
||||||
|
32
|
||||||
|
],
|
||||||
|
"milling": false,
|
||||||
|
"name": "Solderpaste Bottom",
|
||||||
|
"polarity": "positive",
|
||||||
|
"type": "gerber_layer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"board_outline": false,
|
||||||
|
"config": {
|
||||||
|
"file_function": "Legend",
|
||||||
|
"index": 1,
|
||||||
|
"layer_type": "top"
|
||||||
|
},
|
||||||
|
"filename_format": "%PREFIX/silkscreen_top.gbr",
|
||||||
|
"layers": [
|
||||||
|
21,
|
||||||
|
25
|
||||||
|
],
|
||||||
|
"milling": false,
|
||||||
|
"name": "Silkscreen Top",
|
||||||
|
"polarity": "positive",
|
||||||
|
"type": "gerber_layer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"board_outline": false,
|
||||||
|
"config": {
|
||||||
|
"file_function": "Legend",
|
||||||
|
"index": 1,
|
||||||
|
"layer_type": "bottom"
|
||||||
|
},
|
||||||
|
"filename_format": "%PREFIX/silkscreen_bottom.gbr",
|
||||||
|
"layers": [
|
||||||
|
22,
|
||||||
|
26
|
||||||
|
],
|
||||||
|
"milling": false,
|
||||||
|
"name": "Silkscreen Bottom",
|
||||||
|
"polarity": "positive",
|
||||||
|
"type": "gerber_layer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": "X2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": "2018-05-27T17:04:39",
|
||||||
|
"type": "EAGLE CAM job",
|
||||||
|
"units": "metric",
|
||||||
|
"version": "8.6.1"
|
||||||
|
}
|
||||||
4907
eagle/ESPNTPServer/ESPNTPServer.lbr
Normal file
4907
eagle/ESPNTPServer/ESPNTPServer.lbr
Normal file
File diff suppressed because it is too large
Load Diff
18799
eagle/ESPNTPServer/ESPNTPServer.sch
Normal file
18799
eagle/ESPNTPServer/ESPNTPServer.sch
Normal file
File diff suppressed because it is too large
Load Diff
365
eagle/ESPNTPServer/eagle.epf
Normal file
365
eagle/ESPNTPServer/eagle.epf
Normal file
|
|
@ -0,0 +1,365 @@
|
||||||
|
[Eagle]
|
||||||
|
Version="09 00 01"
|
||||||
|
Platform="Mac OS X"
|
||||||
|
Globals="Globals"
|
||||||
|
Desktop="Desktop"
|
||||||
|
|
||||||
|
[Globals]
|
||||||
|
AutoSaveProject=1
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:79"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:88"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:178"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:179"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:180"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:181"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:182"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:183"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:184"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:185"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:186"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:187"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:89"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:188"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:189"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:190"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:191"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:192"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:193"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:194"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:195"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:196"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:197"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:90"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:198"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:199"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:200"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:201"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:202"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:203"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:204"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:205"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:206"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:207"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:91"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:208"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:209"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:210"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:211"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:212"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:213"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:214"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:215"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:216"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:217"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:92"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:218"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:219"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:220"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:221"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:222"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:223"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:224"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:225"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:226"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:227"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:93"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:228"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:229"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:230"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:231"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:232"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:233"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:234"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:235"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:236"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:237"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:94"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:238"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:239"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:240"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:241"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:242"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:243"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:244"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:245"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:246"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:247"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:95"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:248"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:249"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:250"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:251"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:252"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:253"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:254"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:255"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:256"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:257"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:96"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:258"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:259"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:260"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:261"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:262"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:263"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:264"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:265"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:266"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:267"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:97"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:268"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:269"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:270"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:271"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:272"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:273"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:274"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:275"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:276"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:277"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:80"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:98"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:278"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:279"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:280"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:281"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:282"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:283"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:284"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:285"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:286"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:287"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:99"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:288"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:289"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:290"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:291"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:292"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:293"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:294"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:295"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:296"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:297"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:100"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:298"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:299"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:300"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:301"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:302"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:303"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:304"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:305"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:306"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:307"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:101"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:308"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:309"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:310"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:311"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:312"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:313"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:314"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:315"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:316"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:317"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:102"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:318"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:319"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:320"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:321"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:322"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:323"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:324"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:325"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:326"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:327"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:103"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:328"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:329"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:330"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:331"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:332"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:333"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:334"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:335"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:336"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:337"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:104"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:338"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:339"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:340"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:341"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:342"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:343"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:344"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:345"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:346"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:347"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:105"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:348"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:349"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:350"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:351"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:352"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:353"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:354"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:355"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:356"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:357"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:106"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:358"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:359"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:360"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:361"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:362"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:363"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:364"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:365"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:366"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:367"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:107"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:368"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:369"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:370"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:371"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:372"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:373"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:374"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:375"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:376"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:377"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:81"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:108"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:378"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:379"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:380"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:381"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:382"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:383"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:384"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:385"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:386"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:387"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:109"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:388"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:389"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:390"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:391"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:392"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:393"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:394"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:395"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:396"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:397"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:110"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:398"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:399"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:400"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:401"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:402"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:403"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:404"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:405"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:406"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:407"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:111"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:408"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:409"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:410"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:411"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:412"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:413"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:414"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:415"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:416"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:417"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:112"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:418"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:419"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:527439"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:536"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:531"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:518"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:113"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:114"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:115"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:116"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:117"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:82"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:118"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:119"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:120"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:121"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:122"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:123"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:124"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:125"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:126"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:127"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:83"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:128"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:129"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:130"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:131"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:132"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:133"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:134"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:135"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:136"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:137"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:84"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:138"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:139"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:140"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:141"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:142"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:143"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:144"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:145"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:146"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:147"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:85"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:148"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:149"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:150"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:151"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:152"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:153"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:154"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:155"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:156"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:157"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:86"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:158"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:159"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:160"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:161"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:162"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:163"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:164"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:165"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:166"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:167"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:87"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:168"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:169"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:170"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:171"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:172"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:173"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:174"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:175"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:176"
|
||||||
|
UsedLibraryUrn="urn:adsk.eagle:library:177"
|
||||||
|
UsedLibrary="/Users/chris.l/Dropbox/Eagle/lbr/MCP1825.lbr"
|
||||||
|
UsedLibrary="/Users/chris.l/Dropbox/Eagle/SynchroClock/SynchroClock.lbr"
|
||||||
|
UsedLibrary="/Users/chris.l/Dropbox/Eagle/lbr/SparkFun-Eagle-Libraries/SparkFun-Connectors.lbr"
|
||||||
|
UsedLibrary="ESPNTPServer.lbr"
|
||||||
|
|
||||||
|
[Win_1]
|
||||||
|
Type="Control Panel"
|
||||||
|
Number=0
|
||||||
|
|
||||||
|
[Desktop]
|
||||||
|
Screen="1680 1050"
|
||||||
|
Window="Win_1"
|
||||||
BIN
enclosure/Bottom-0.5v33.stl
Normal file
BIN
enclosure/Bottom-0.5v33.stl
Normal file
Binary file not shown.
BIN
enclosure/Top-0.5v33.stl
Normal file
BIN
enclosure/Top-0.5v33.stl
Normal file
Binary file not shown.
1
hardware/esp8266com/esp8266
Submodule
1
hardware/esp8266com/esp8266
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 9c5c16e9c8d90c3bd21a756c3a1487f3826b6e24
|
||||||
BIN
images/ESPNTPServer.png
Normal file
BIN
images/ESPNTPServer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 72 KiB |
BIN
images/closed.png
Normal file
BIN
images/closed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 MiB |
BIN
images/open.png
Normal file
BIN
images/open.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 MiB |
1
libraries/ArduinoJson
Submodule
1
libraries/ArduinoJson
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 7b229e4c3810c65fc3c5620a42fc3f934d7f1b59
|
||||||
1
libraries/DLog
Submodule
1
libraries/DLog
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 733b67f7c650e5f6652172b7194b3044d8d73ee4
|
||||||
1
libraries/DLogNet
Submodule
1
libraries/DLogNet
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 26fd5f194b978ae19b5726022410b9cc86cfeb1d
|
||||||
1
libraries/ESPAsyncUDP
Submodule
1
libraries/ESPAsyncUDP
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit b592ac6e93e9dbfd61db70ce80dcd04a2afcc76a
|
||||||
1
libraries/MicroNMEA
Submodule
1
libraries/MicroNMEA
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 87d5508cc105be222cc62f090742b2b26ea580bc
|
||||||
1
libraries/Syslog
Submodule
1
libraries/Syslog
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 9f1a2506b38e49312f2b353559ef4eca11616975
|
||||||
1
libraries/WiFiManager
Submodule
1
libraries/WiFiManager
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 2d194ea518e22424d12418d8a7b36ff4406dec5c
|
||||||
1
libraries/esp8266-oled-ssd1306
Submodule
1
libraries/esp8266-oled-ssd1306
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit ca4e8b7d2e7062475686181cc01251bffa67dcce
|
||||||
Loading…
Reference in New Issue
Block a user