Compare commits

...

57 Commits

Author SHA1 Message Date
SQFMI 667d86737d
Update main.actions.yml 2024-04-03 16:15:58 -04:00
SQFMI d65738fbaa
Update main.actions.yml 2024-04-03 16:09:29 -04:00
SQFMI 2dd98737fb
Update main.actions.yml 2024-04-03 16:08:09 -04:00
SQFMI 5a5b343737
fix path in GH actions 2024-04-03 15:57:14 -04:00
sqfmi 2da3fd9ede add board revision function 2024-04-03 15:10:09 -04:00
SQFMI acbb6eeece
Compile for different board revisions 2024-04-03 14:55:30 -04:00
sqfmi c1c95f9587 use chip icon 2024-04-02 22:59:02 -04:00
sqfmi bd1657e9c7 Save last used IP and SSID 2024-04-02 22:55:19 -04:00
sqfmi fbbcaabbd1 updated IP 2024-04-02 14:56:24 -04:00
SQFMI e9854a7fa2
Merge pull request #230 from denics/master
Check if wifi and change weather icon
2024-04-02 14:23:00 -04:00
sqfmi fddbe504c1 Merge branch 'pr/233' 2024-04-02 14:13:44 -04:00
sqfmi aa3528371d getWeatherData to accept cityID or lat lon 2024-04-02 14:13:15 -04:00
sqfmi 3ffb0f8697 Update version and use WIFI_CONFIGURED 2024-04-01 18:10:51 -04:00
sqfmi b786f24240 Use WIFI_CONFIGURED 2024-04-01 18:08:12 -04:00
sqfmi 2528878570 Merge branch 'pr/231' 2024-04-01 18:06:59 -04:00
sqfmi 1b15c1b5fe bump version 2024-03-31 14:27:07 -04:00
Daniel Ansorregui be185cbd54 Remove delay after hard reset
* Implemented by overloading the
  virtual method _reset() in GxEPD2_EPD
* Tested to write straight away
  and works ok. Seems unnecessary.
* 10ms might look like little but the
  ESP is not sleeping and CPUs are on.
  This is probably using 0.1 uAh
  (10% of display update total cost)
2024-01-16 23:15:29 +00:00
Daniel Ansorregui f369b6f207 Allow AsyncPowerOn
* The display takes 16ms to power on
  During this time we can render the
  content and finally display it
* The call is optional if we do not call
  it then the old code path is used
* Moved the init to constructor
2024-01-13 19:11:22 +00:00
Daniel Ansorregui 8103df1499 Refactor DarkBorder
* Allow to be changed dynamically between
  display updated.
2024-01-13 19:08:52 +00:00
Daniel Ansorregui 84c0cd106c Set boosters configuration
* Reduce the phase on times from 40ms->10ms
* Increase the driving strength, this reduces
  a little the power usage as well
* Reduces 220ms the display update
  -80ms the power on of the display
  -140ms the display partial update
- Note: This may have side effects, but I saw none
  tested on Watchy v1.0, display should be same on
  other Watchy boards
2024-01-13 18:24:19 +00:00
Daniel Ansorregui 3ce125247d No soft reset after reset
* Avoid a redundant reset after a reset
  The display is always reset after a hard reset
  and there is no need to re-reset it
2024-01-13 18:24:04 +00:00
Daniel Ansorregui f2c0c91a61 Refactor Display Init
* It makes more sense to put it in the Display class
* The reset should be 2ms, 10ms is worst case
* Also there was a disable call based on display
  that makes more sense to put in the default
  boot switch statement
2024-01-13 18:23:45 +00:00
Daniel Ansorregui 2b21e50c2f Move Display specifics
* Move BusyCallback
* Move constructor pins
2024-01-13 18:19:37 +00:00
Sudrien b84ab91c6b Switch from CityID to Lat an Lon, expose sunrise and sunset 2023-06-16 00:17:20 -04:00
Sean M. Collins b8eeda70c6 Fix indenting 2023-05-25 13:42:34 +01:00
Sean M. Collins a719bfa116 Switch wifi off after info display 2023-05-24 20:55:47 +01:00
Sean M. Collins 459cc2a18f Display WiFi information in About screen 2023-05-24 20:42:31 +01:00
Denis Pitzalis df5fce8d40 fix issue #229 2023-05-15 16:07:03 +02:00
SQFMI 342eb48a49
Merge pull request #221 from wjgeorge/dev
bump lib version number
2023-04-25 14:37:44 -04:00
wjgeorge 98fd0abfeb bump lib version number 2023-04-24 17:02:44 -04:00
SQFMI 1d5605c0e9 Update dev.actions.yml 2023-04-23 23:36:49 -04:00
SQFMI 704ef60470 Update dev.actions.yml 2023-04-23 23:32:27 -04:00
SQFMI cc6c196e37 Create main.actions.yml 2023-04-23 23:28:57 -04:00
SQFMI 35e65a1972 update 2023-04-23 18:18:39 -04:00
SQFMI 65061fd30f updated 2023-04-23 18:16:57 -04:00
SQFMI b1b5eeb890
Merge pull request #217 from wjgeorge/dev
'WIDTH_VISIBLE' is not a member of 'WatchyDisplay'
2023-04-22 22:23:05 -04:00
SQFMI 2b327c64b8
remove dstOffset from watchySettings struct 2023-04-22 22:21:12 -04:00
wjgeorge 3c73c7e2c8 Add new static member WIDTH_VISIBLE 2023-04-21 23:13:53 -04:00
SQFMI cc1ff02123 Update test-compilation.yml 2023-04-11 16:19:06 -04:00
SQFMI 0e1aa800dd Update test-compilation.yml 2023-04-11 13:01:36 -04:00
SQFMI cc882cd9f7 Update test-compilation.yml 2023-04-11 11:01:48 -04:00
SQFMI 6682d501a6 test compile 2023-04-11 10:33:50 -04:00
SQFMI dc2795dcd9
Merge pull request #209 from aminch/weather-fix
Reset weather counter on Wifi connection
2023-04-11 09:48:25 -04:00
SQFMI 9177aee6d6 Merge branch 'master' into dev 2023-04-11 09:46:53 -04:00
SQFMI c2bbf8a01a
Update README.md 2023-04-10 20:14:46 -04:00
Adam Minchinton 0e319fe3e7 Reset weather counter on Wifi connection 2023-02-14 20:22:05 +01:00
SQFMI f6f7a38c8e
fix path 2023-02-09 16:32:16 -05:00
SQFMI 266ae56458
fix path 2023-02-09 15:57:01 -05:00
SQFMI 96c4465924
fix path 2023-02-09 13:57:40 -05:00
SQFMI b48408be6e
Upload bins 2023-02-09 01:08:57 -05:00
SQFMI c0e814d269
Update test-compilation.yml 2023-02-08 21:15:51 -05:00
SQFMI 3300f6f271
Merge pull request #204 from khenderick/feature/virtual-button-press
Allow button press overrides
2023-02-08 20:57:03 -05:00
SQFMI e125f85926
Update test-compilation.yml 2023-02-08 20:40:20 -05:00
SQFMI ce8c5d4f78
Update test-compilation.yml 2023-02-08 20:34:25 -05:00
SQFMI 851467cc86
Merge pull request #122 from Meptl/auto-compile-check
Compile example programs on push with Github Actions
2023-02-08 17:00:21 -05:00
Kenneth Henderick 3a3a926c2a
Allow button press overrides 2022-12-30 17:14:13 +01:00
Christopher Chin 20dd8a26e0 Auto compile using Github Action. 2021-12-20 01:12:12 +00:00
20 changed files with 483 additions and 108 deletions

27
.github/workflows/dev.actions.yml vendored Normal file
View File

@ -0,0 +1,27 @@
name: Build Example Watchfaces
on:
push:
branches:
- "dev"
pull_request:
branches:
- "dev"
jobs:
build:
name: Build Example Watchfaces
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: ArminJo/arduino-test-compile@v3
with:
arduino-board-fqbn: esp32:esp32:watchy:Revision=v20,PartitionScheme=min_spiffs,UploadSpeed=921600,DebugLevel=none,EraseFlash=none
platform-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
required-libraries: Adafruit GFX Library,Arduino_JSON,DS3232RTC,NTPClient,Rtc_Pcf8563,GxEPD2,WiFiManager
set-build-path: true
- uses: actions/upload-artifact@v3
with:
name: binaries
path: ${{ github.workspace }}/examples/WatchFaces/**/build/*.bin
- uses: actions/download-artifact@v3
- name: Display structure of downloaded files
run: ls -R

38
.github/workflows/main.actions.yml vendored Normal file
View File

@ -0,0 +1,38 @@
name: Release
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
jobs:
release:
name: Build and Release
runs-on: ubuntu-latest
strategy:
matrix:
board-revisions: [v10, v15, v20]
steps:
- uses: actions/checkout@master
- uses: ArminJo/arduino-test-compile@v3
with:
arduino-board-fqbn: esp32:esp32:watchy:Revision=${{ matrix.board-revisions }},PartitionScheme=min_spiffs,UploadSpeed=921600,DebugLevel=none,EraseFlash=none
platform-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
required-libraries: Adafruit GFX Library,Arduino_JSON,DS3232RTC,NTPClient,Rtc_Pcf8563,GxEPD2,WiFiManager
set-build-path: true
- name: Rename binaries with board revision
run: |
parent_dir="${{ github.workspace }}/examples/WatchFaces"
for dir in "$parent_dir"/*; do
if [ -d "$dir" ]; then
cd "$dir/build"
for file in *; do
name="${file%%.*}"
ext="${file#$name.}"
mv "$file" "$name-${{ matrix.board-revisions }}.$ext"
done
cd -
fi
done
- uses: softprops/action-gh-release@v1
with:
name: "Watchy Arduino Library ${{ github.ref_name }}"
files: ${{ github.workspace }}/examples/WatchFaces/**/build/*.bin

View File

@ -2,7 +2,7 @@
![Watchy](https://watchy.sqfmi.com/img/watchy_render.png)
**Buy Watchy at [Crowd Supply](https://www.crowdsupply.com/sqfmi/watchy) and [Mouser](https://www.mouser.com/ProductDetail/SQFMI/SQFMI-WATCHY-10?qs=DRkmTr78QARN9VSJRzqRxw%3D%3D)!**
**Buy Watchy from [The Pi Hut](https://thepihut.com/collections/sqfmi), [Crowd Supply](https://www.crowdsupply.com/sqfmi/watchy), and [Mouser](https://www.mouser.com/ProductDetail/SQFMI/SQFMI-WATCHY-10?qs=DRkmTr78QARN9VSJRzqRxw%3D%3D)!**
[**Watchy Case & Accessories**](https://shop.sqfmi.com)

View File

@ -125,24 +125,29 @@ void Watchy7SEG::drawWeather(){
display.drawBitmap(165, 110, currentWeather.isMetric ? celsius : fahrenheit, 26, 20, DARKMODE ? GxEPD_WHITE : GxEPD_BLACK);
const unsigned char* weatherIcon;
//https://openweathermap.org/weather-conditions
if(weatherConditionCode > 801){//Cloudy
weatherIcon = cloudy;
}else if(weatherConditionCode == 801){//Few Clouds
weatherIcon = cloudsun;
}else if(weatherConditionCode == 800){//Clear
weatherIcon = sunny;
}else if(weatherConditionCode >=700){//Atmosphere
weatherIcon = atmosphere;
}else if(weatherConditionCode >=600){//Snow
weatherIcon = snow;
}else if(weatherConditionCode >=500){//Rain
weatherIcon = rain;
}else if(weatherConditionCode >=300){//Drizzle
weatherIcon = drizzle;
}else if(weatherConditionCode >=200){//Thunderstorm
weatherIcon = thunderstorm;
}else
return;
if(WIFI_CONFIGURED){
//https://openweathermap.org/weather-conditions
if(weatherConditionCode > 801){//Cloudy
weatherIcon = cloudy;
}else if(weatherConditionCode == 801){//Few Clouds
weatherIcon = cloudsun;
}else if(weatherConditionCode == 800){//Clear
weatherIcon = sunny;
}else if(weatherConditionCode >=700){//Atmosphere
weatherIcon = atmosphere;
}else if(weatherConditionCode >=600){//Snow
weatherIcon = snow;
}else if(weatherConditionCode >=500){//Rain
weatherIcon = rain;
}else if(weatherConditionCode >=300){//Drizzle
weatherIcon = drizzle;
}else if(weatherConditionCode >=200){//Thunderstorm
weatherIcon = thunderstorm;
}else
return;
}else{
weatherIcon = chip;
}
display.drawBitmap(145, 158, weatherIcon, WEATHER_ICON_WIDTH, WEATHER_ICON_HEIGHT, DARKMODE ? GxEPD_WHITE : GxEPD_BLACK);
}

View File

@ -150,6 +150,21 @@ const unsigned char thunderstorm[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x01,
0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 'cputemp', 48x32px
const unsigned char cputemp [] PROGMEM = {
0x00, 0x01, 0x8c, 0xe7, 0x00, 0x00, 0x00, 0x01, 0x8c, 0xe7, 0x00, 0x00, 0x00, 0x01, 0x8c, 0xe7,
0x00, 0x00, 0x00, 0x01, 0x8c, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x03, 0xef, 0xff, 0xff, 0xef, 0x80,
0x03, 0xef, 0xff, 0xff, 0xef, 0x80, 0x03, 0xef, 0xff, 0xff, 0xe7, 0x80, 0x00, 0x0f, 0xff, 0xff,
0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x03, 0xef, 0xff, 0xff, 0xef, 0x80, 0x03, 0xef,
0xff, 0xff, 0xef, 0x80, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x03, 0xef, 0xff, 0xff, 0xef, 0x80, 0x03, 0xef, 0xff, 0xff,
0xef, 0x80, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f,
0xff, 0xff, 0xe0, 0x00, 0x03, 0xef, 0xff, 0xff, 0xef, 0x80, 0x03, 0xef, 0xff, 0xff, 0xef, 0x80,
0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8c, 0xe7, 0x00, 0x00, 0x00, 0x01,
0x8c, 0xe7, 0x00, 0x00, 0x00, 0x01, 0x8c, 0xe7, 0x00, 0x00, 0x00, 0x01, 0x8c, 0xe7, 0x00, 0x00
};
// 'steps', 19x23px
const unsigned char steps [] PROGMEM = {
0x00, 0x03, 0xc0, 0x00, 0x07, 0xe0, 0x00, 0x07, 0xe0, 0x00, 0x0f, 0xe0, 0x78, 0x0f, 0xe0, 0xfc,
@ -174,3 +189,19 @@ const unsigned char wifioff [] PROGMEM = {
0x01, 0xff, 0xc0, 0x00, 0x07, 0xe1, 0xc0, 0x00, 0x0f, 0xc0, 0x80, 0x00, 0x1f, 0x0c, 0x00, 0x00,
0x3c, 0x1e, 0x00, 0x00, 0xf8, 0x0c, 0x00, 0x00
};
// 'chip', 48x32px
const unsigned char chip [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x48, 0x00, 0x00, 0x00, 0x00,
0x12, 0x48, 0x00, 0x00, 0x00, 0x00, 0x12, 0x48, 0x00, 0x00, 0x00, 0x00, 0x12, 0x48, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01,
0x00, 0x00, 0x00, 0x0f, 0x87, 0xf9, 0xf0, 0x00, 0x00, 0x00, 0x88, 0x09, 0x00, 0x00, 0x00, 0x00,
0x90, 0x09, 0x00, 0x00, 0x00, 0x0f, 0x90, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00,
0x00, 0x00, 0x90, 0x09, 0x00, 0x00, 0x00, 0x0f, 0x90, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x90, 0x09,
0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, 0x00, 0x0f, 0x9f, 0xf9, 0xf0, 0x00, 0x00, 0x00,
0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x12, 0x48, 0x00, 0x00, 0x00, 0x00, 0x12, 0x48, 0x00, 0x00, 0x00, 0x00, 0x12, 0x48,
0x00, 0x00, 0x00, 0x00, 0x12, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

View File

@ -3,8 +3,18 @@
//Weather Settings
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
//You can also use LAT,LON for your location instead of CITY_ID, but not both
//#define LAT "40.7127" //New York City, Looked up on https://www.latlong.net/
//#define LON "-74.0059"
#ifdef CITY_ID
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id={cityID}&lang={lang}&units={units}&appid={apiKey}" //open weather api using city ID
#else
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&lang={lang}&units={units}&appid={apiKey}" //open weather api using lat lon
#endif
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
#define TEMP_LANG "en"
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
@ -13,7 +23,13 @@
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
watchySettings settings{
.cityID = CITY_ID,
#ifdef CITY_ID
.cityID = CITY_ID,
#else
.cityID = "",
.lat = LAT,
.lon = LON,
#endif
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
.weatherURL = OPENWEATHERMAP_URL,
.weatherUnit = TEMP_UNIT,
@ -24,4 +40,4 @@ watchySettings settings{
.vibrateOClock = true,
};
#endif
#endif

View File

@ -3,8 +3,18 @@
//Weather Settings
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
//You can also use LAT,LON for your location instead of CITY_ID, but not both
//#define LAT "40.7127" //New York City, Looked up on https://www.latlong.net/
//#define LON "-74.0059"
#ifdef CITY_ID
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id={cityID}&lang={lang}&units={units}&appid={apiKey}" //open weather api using city ID
#else
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&lang={lang}&units={units}&appid={apiKey}" //open weather api using lat lon
#endif
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
#define TEMP_LANG "en"
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
@ -13,7 +23,13 @@
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
watchySettings settings{
.cityID = CITY_ID,
#ifdef CITY_ID
.cityID = CITY_ID,
#else
.cityID = "",
.lat = LAT,
.lon = LON,
#endif
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
.weatherURL = OPENWEATHERMAP_URL,
.weatherUnit = TEMP_UNIT,
@ -21,6 +37,7 @@ watchySettings settings{
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
.ntpServer = NTP_SERVER,
.gmtOffset = GMT_OFFSET_SEC,
.vibrateOClock = true,
};
#endif
#endif

View File

@ -3,8 +3,18 @@
//Weather Settings
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
//You can also use LAT,LON for your location instead of CITY_ID, but not both
//#define LAT "40.7127" //New York City, Looked up on https://www.latlong.net/
//#define LON "-74.0059"
#ifdef CITY_ID
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id={cityID}&lang={lang}&units={units}&appid={apiKey}" //open weather api using city ID
#else
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&lang={lang}&units={units}&appid={apiKey}" //open weather api using lat lon
#endif
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
#define TEMP_LANG "en"
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
@ -13,7 +23,13 @@
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
watchySettings settings{
.cityID = CITY_ID,
#ifdef CITY_ID
.cityID = CITY_ID,
#else
.cityID = "",
.lat = LAT,
.lon = LON,
#endif
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
.weatherURL = OPENWEATHERMAP_URL,
.weatherUnit = TEMP_UNIT,
@ -21,6 +37,7 @@ watchySettings settings{
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
.ntpServer = NTP_SERVER,
.gmtOffset = GMT_OFFSET_SEC,
.vibrateOClock = true,
};
#endif
#endif

View File

@ -3,8 +3,18 @@
//Weather Settings
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
//You can also use LAT,LON for your location instead of CITY_ID, but not both
//#define LAT "40.7127" //New York City, Looked up on https://www.latlong.net/
//#define LON "-74.0059"
#ifdef CITY_ID
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id={cityID}&lang={lang}&units={units}&appid={apiKey}" //open weather api using city ID
#else
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&lang={lang}&units={units}&appid={apiKey}" //open weather api using lat lon
#endif
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
#define TEMP_LANG "en"
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
@ -13,7 +23,13 @@
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
watchySettings settings{
.cityID = CITY_ID,
#ifdef CITY_ID
.cityID = CITY_ID,
#else
.cityID = "",
.lat = LAT,
.lon = LON,
#endif
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
.weatherURL = OPENWEATHERMAP_URL,
.weatherUnit = TEMP_UNIT,
@ -21,6 +37,7 @@ watchySettings settings{
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
.ntpServer = NTP_SERVER,
.gmtOffset = GMT_OFFSET_SEC,
.vibrateOClock = true,
};
#endif
#endif

View File

@ -3,8 +3,18 @@
//Weather Settings
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
//You can also use LAT,LON for your location instead of CITY_ID, but not both
//#define LAT "40.7127" //New York City, Looked up on https://www.latlong.net/
//#define LON "-74.0059"
#ifdef CITY_ID
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id={cityID}&lang={lang}&units={units}&appid={apiKey}" //open weather api using city ID
#else
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&lang={lang}&units={units}&appid={apiKey}" //open weather api using lat lon
#endif
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
#define TEMP_LANG "en"
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
@ -13,7 +23,13 @@
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
watchySettings settings{
.cityID = CITY_ID,
#ifdef CITY_ID
.cityID = CITY_ID,
#else
.cityID = "",
.lat = LAT,
.lon = LON,
#endif
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
.weatherURL = OPENWEATHERMAP_URL,
.weatherUnit = TEMP_UNIT,
@ -24,4 +40,4 @@ watchySettings settings{
.vibrateOClock = true,
};
#endif
#endif

View File

@ -3,8 +3,18 @@
//Weather Settings
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
//You can also use LAT,LON for your location instead of CITY_ID, but not both
//#define LAT "40.7127" //New York City, Looked up on https://www.latlong.net/
//#define LON "-74.0059"
#ifdef CITY_ID
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id={cityID}&lang={lang}&units={units}&appid={apiKey}" //open weather api using city ID
#else
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&lang={lang}&units={units}&appid={apiKey}" //open weather api using lat lon
#endif
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
#define TEMP_LANG "en"
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
@ -13,7 +23,13 @@
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
watchySettings settings{
.cityID = CITY_ID,
#ifdef CITY_ID
.cityID = CITY_ID,
#else
.cityID = "",
.lat = LAT,
.lon = LON,
#endif
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
.weatherURL = OPENWEATHERMAP_URL,
.weatherUnit = TEMP_UNIT,
@ -21,6 +37,7 @@ watchySettings settings{
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
.ntpServer = NTP_SERVER,
.gmtOffset = GMT_OFFSET_SEC,
.vibrateOClock = true,
};
#endif
#endif

View File

@ -3,8 +3,18 @@
//Weather Settings
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
//You can also use LAT,LON for your location instead of CITY_ID, but not both
//#define LAT "40.7127" //New York City, Looked up on https://www.latlong.net/
//#define LON "-74.0059"
#ifdef CITY_ID
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id={cityID}&lang={lang}&units={units}&appid={apiKey}" //open weather api using city ID
#else
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&lang={lang}&units={units}&appid={apiKey}" //open weather api using lat lon
#endif
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
#define TEMP_LANG "en"
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
@ -13,7 +23,13 @@
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
watchySettings settings{
.cityID = CITY_ID,
#ifdef CITY_ID
.cityID = CITY_ID,
#else
.cityID = "",
.lat = LAT,
.lon = LON,
#endif
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
.weatherURL = OPENWEATHERMAP_URL,
.weatherUnit = TEMP_UNIT,
@ -21,6 +37,7 @@ watchySettings settings{
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
.ntpServer = NTP_SERVER,
.gmtOffset = GMT_OFFSET_SEC,
.vibrateOClock = true,
};
#endif
#endif

View File

@ -3,8 +3,18 @@
//Weather Settings
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
//You can also use LAT,LON for your location instead of CITY_ID, but not both
//#define LAT "40.7127" //New York City, Looked up on https://www.latlong.net/
//#define LON "-74.0059"
#ifdef CITY_ID
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id={cityID}&lang={lang}&units={units}&appid={apiKey}" //open weather api using city ID
#else
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&lang={lang}&units={units}&appid={apiKey}" //open weather api using lat lon
#endif
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
#define TEMP_LANG "en"
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
@ -13,7 +23,13 @@
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
watchySettings settings{
.cityID = CITY_ID,
#ifdef CITY_ID
.cityID = CITY_ID,
#else
.cityID = "",
.lat = LAT,
.lon = LON,
#endif
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
.weatherURL = OPENWEATHERMAP_URL,
.weatherUnit = TEMP_UNIT,
@ -21,6 +37,7 @@ watchySettings settings{
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
.ntpServer = NTP_SERVER,
.gmtOffset = GMT_OFFSET_SEC,
.vibrateOClock = true,
};
#endif
#endif

View File

@ -1,6 +1,6 @@
{
"name": "Watchy",
"version": "1.4.6",
"version": "1.4.10",
"description": "Watchy - An Open Source E-Paper Watch by SQFMI",
"authors": [
{

View File

@ -1,5 +1,5 @@
name=Watchy
version=1.4.6
version=1.4.10
author=SQFMI
maintainer=SQFMI
sentence=Watchy - An Open Source E-Paper Watch by SQFMI

View File

@ -15,11 +15,44 @@
// Link: https://github.com/sqfmi/Watchy
#include "Display.h"
#include "config.h"
WatchyDisplay::WatchyDisplay(int16_t cs, int16_t dc, int16_t rst, int16_t busy) :
GxEPD2_EPD(cs, dc, rst, busy, HIGH, 10000000, WIDTH, HEIGHT, panel, hasColor, hasPartialUpdate, hasFastPartialUpdate)
RTC_DATA_ATTR bool displayFullInit = true;
void WatchyDisplay::busyCallback(const void *) {
gpio_wakeup_enable((gpio_num_t)DISPLAY_BUSY, GPIO_INTR_LOW_LEVEL);
esp_sleep_enable_gpio_wakeup();
esp_light_sleep_start();
}
WatchyDisplay::WatchyDisplay() :
GxEPD2_EPD(DISPLAY_CS, DISPLAY_DC, DISPLAY_RES, DISPLAY_BUSY, HIGH, 10000000, WIDTH, HEIGHT, panel, hasColor, hasPartialUpdate, hasFastPartialUpdate)
{
selectSPI(SPI, SPISettings(20000000, MSBFIRST, SPI_MODE0)); // Set SPI to 20Mhz (default is 4Mhz)
// Setup callback and SPI by default
selectSPI(SPI, SPISettings(20000000, MSBFIRST, SPI_MODE0));
setBusyCallback(busyCallback);
}
void WatchyDisplay::initWatchy() {
// Watchy default initialization
init(0, displayFullInit, 2, true);
}
void WatchyDisplay::asyncPowerOn() {
// This is expensive if unused
if (!waitingPowerOn && !_hibernating) {
_InitDisplay();
_PowerOnAsync();
}
}
void WatchyDisplay::setDarkBorder(bool dark) {
if (_hibernating) return;
darkBorder = dark;
_startTransfer();
_transferCommand(0x3C); // BorderWavefrom
_transfer(dark ? 0x02 : 0x05);
_endTransfer();
}
void WatchyDisplay::clearScreen(uint8_t value)
@ -324,31 +357,52 @@ void WatchyDisplay::_setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint1
_endTransfer();
}
void WatchyDisplay::_PowerOnAsync()
{
if (_power_is_on)
return;
_startTransfer();
_transferCommand(0x22);
_transfer(0xf8);
_transferCommand(0x20);
_endTransfer();
waitingPowerOn = true;
_power_is_on = true;
}
void WatchyDisplay::_PowerOn()
{
if (!_power_is_on)
if (waitingPowerOn)
{
_startTransfer();
_transferCommand(0x22);
_transfer(0xf8);
_transferCommand(0x20);
_endTransfer();
waitingPowerOn = false;
_waitWhileBusy("_PowerOn", power_on_time);
}
if (_power_is_on)
return;
_startTransfer();
_transferCommand(0x22);
_transfer(0xf8);
_transferCommand(0x20);
_endTransfer();
_waitWhileBusy("_PowerOn", power_on_time);
_power_is_on = true;
}
void WatchyDisplay::_PowerOff()
{
if (_power_is_on)
if (waitingPowerOn)
{
_startTransfer();
_transferCommand(0x22);
_transfer(0x83);
_transferCommand(0x20);
_endTransfer();
_waitWhileBusy("_PowerOff", power_off_time);
waitingPowerOn = false;
_waitWhileBusy("_PowerOn", power_on_time);
}
if (!_power_is_on)
return;
_startTransfer();
_transferCommand(0x22);
_transfer(0x83);
_transferCommand(0x20);
_endTransfer();
_waitWhileBusy("_PowerOff", power_off_time);
_power_is_on = false;
_using_partial_mode = false;
}
@ -356,23 +410,54 @@ void WatchyDisplay::_PowerOff()
void WatchyDisplay::_InitDisplay()
{
if (_hibernating) _reset();
_writeCommand(0x12); // soft reset
_waitWhileBusy("_SoftReset", 10); // 10ms max according to specs
// No need to soft reset, the Display goes to same state after hard reset
// _writeCommand(0x12); // soft reset
// _waitWhileBusy("_SoftReset", 10); // 10ms max according to specs*/
_startTransfer();
_transferCommand(0x01); // Driver output control
_transfer(0xC7);
_transfer(0x00);
_transfer(0x00);
_transferCommand(0x3C); // BorderWavefrom
_transfer(darkBorder ? 0x02 : 0x05);
if (reduceBoosterTime) {
// SSD1675B controller datasheet
_transferCommand(0x0C); // BOOSTER_SOFT_START_CONTROL
// Set the driving strength of GDR for all phases to maximun 0b111 -> 0xF
// Set the minimum off time of GDR to minimum 0x4 (values below sould be same)
_transfer(0xF4); // Phase1 Default value 0x8B
_transfer(0xF4); // Phase2 Default value 0x9C
_transfer(0xF4); // Phase3 Default value 0x96
_transfer(0x00); // Duration of phases, Default 0xF = 0b00 11 11 (40ms Phase 1/2, 10ms Phase 3)
}
_transferCommand(0x18); // Read built-in temperature sensor
_transfer(0x80);
_endTransfer();
setDarkBorder(darkBorder);
_setPartialRamArea(0, 0, WIDTH, HEIGHT);
}
void WatchyDisplay::_reset()
{
// Call default method if not configured the same way
if (_rst < 0 || !_pulldown_rst_mode) {
GxEPD2_EPD::_reset();
return;
}
digitalWrite(_rst, LOW);
pinMode(_rst, OUTPUT);
delay(_reset_duration);
pinMode(_rst, INPUT_PULLUP);
// Tested calling _powerOn() inmediately, and works ok, no need to sleep
// delay(_reset_duration > 10 ? _reset_duration : 0);
_hibernating = false;
}
void WatchyDisplay::_Init_Full()
{
_InitDisplay();
@ -395,6 +480,7 @@ void WatchyDisplay::_Update_Full()
_transferCommand(0x20);
_endTransfer();
_waitWhileBusy("_Update_Full", full_refresh_time);
displayFullInit = false;
}
void WatchyDisplay::_Update_Part()

View File

@ -23,6 +23,7 @@ class WatchyDisplay : public GxEPD2_EPD
public:
// attributes
static const uint16_t WIDTH = 200;
static const uint16_t WIDTH_VISIBLE = WIDTH;
static const uint16_t HEIGHT = 200;
static const GxEPD2::Panel panel = GxEPD2::GDEH0154D67;
static const bool hasColor = false;
@ -33,7 +34,13 @@ class WatchyDisplay : public GxEPD2_EPD
static const uint16_t full_refresh_time = 2600; // ms, e.g. 2509602us
static const uint16_t partial_refresh_time = 500; // ms, e.g. 457282us
// constructor
WatchyDisplay(int16_t cs, int16_t dc, int16_t rst, int16_t busy);
WatchyDisplay();
void initWatchy();
void setDarkBorder(bool darkBorder);
void asyncPowerOn();
void _PowerOnAsync();
bool waitingPowerOn = false;
static void busyCallback(const void *);
// methods (virtual)
// Support for Bitmaps (Sprites) to Controller Buffer and to Screen
void clearScreen(uint8_t value = 0xFF); // init controller memory and screen (default white)
@ -68,6 +75,8 @@ class WatchyDisplay : public GxEPD2_EPD
void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
bool darkBorder = false; // adds a dark border outside the normal screen area
static constexpr bool reduceBoosterTime = true; // Saves ~200ms
private:
void _writeScreenBuffer(uint8_t command, uint8_t value);
void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@ -82,5 +91,7 @@ class WatchyDisplay : public GxEPD2_EPD
void _Update_Full();
void _Update_Part();
void _reset();
void _transferCommand(uint8_t command);
};

View File

@ -2,7 +2,7 @@
WatchyRTC Watchy::RTC;
GxEPD2_BW<WatchyDisplay, WatchyDisplay::HEIGHT> Watchy::display(
WatchyDisplay(DISPLAY_CS, DISPLAY_DC, DISPLAY_RES, DISPLAY_BUSY));
WatchyDisplay{});
RTC_DATA_ATTR int guiState;
RTC_DATA_ATTR int menuIndex;
@ -11,10 +11,11 @@ RTC_DATA_ATTR bool WIFI_CONFIGURED;
RTC_DATA_ATTR bool BLE_CONFIGURED;
RTC_DATA_ATTR weatherData currentWeather;
RTC_DATA_ATTR int weatherIntervalCounter = -1;
RTC_DATA_ATTR bool displayFullInit = true;
RTC_DATA_ATTR long gmtOffset = 0;
RTC_DATA_ATTR bool alreadyInMenu = true;
RTC_DATA_ATTR tmElements_t bootTime;
RTC_DATA_ATTR uint32_t lastIPAddress;
RTC_DATA_ATTR char lastSSID[30];
void Watchy::init(String datetime) {
esp_sleep_wakeup_cause_t wakeup_reason;
@ -22,11 +23,8 @@ void Watchy::init(String datetime) {
Wire.begin(SDA, SCL); // init i2c
RTC.init();
// Init the display here for all cases, if unused, it will do nothing
display.epd2.selectSPI(SPI, SPISettings(20000000, MSBFIRST, SPI_MODE0)); // Set SPI to 20Mhz (default is 4Mhz)
display.init(0, displayFullInit, 10,
true); // 10ms by spec, and fast pulldown reset
display.epd2.setBusyCallback(displayBusyCallback);
// Init the display since is almost sure we will use it
display.epd2.initWatchy();
switch (wakeup_reason) {
case ESP_SLEEP_WAKEUP_EXT0: // RTC Alarm
@ -63,22 +61,14 @@ void Watchy::init(String datetime) {
RTC.read(bootTime);
showWatchFace(false); // full update on reset
vibMotor(75, 4);
// For some reason, seems to be enabled on first boot
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
break;
}
deepSleep();
}
void Watchy::displayBusyCallback(const void *) {
gpio_wakeup_enable((gpio_num_t)DISPLAY_BUSY, GPIO_INTR_LOW_LEVEL);
esp_sleep_enable_gpio_wakeup();
esp_light_sleep_start();
}
void Watchy::deepSleep() {
display.hibernate();
if (displayFullInit) // For some reason, seems to be enabled on first boot
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
displayFullInit = false; // Notify not to init it again
RTC.clearAlarm(); // resets the alarm flag in the RTC
// Set GPIOs 0-39 to input to avoid power leaking out
@ -325,9 +315,8 @@ void Watchy::showAbout() {
display.print("LibVer: ");
display.println(WATCHY_LIB_VER);
const char *RTC_HW[3] = {"<UNKNOWN>", "DS3231", "PCF8563"};
display.print("RTC: ");
display.println(RTC_HW[RTC.rtcType]); // 0 = UNKNOWN, 1 = DS3231, 2 = PCF8563
display.print("Rev: v");
display.println(getBoardRevision());
display.print("Batt: ");
float voltage = getBatteryVoltage();
@ -348,7 +337,15 @@ void Watchy::showAbout() {
display.print(hours);
display.print("h");
display.print(minutes);
display.print("m");
display.println("m");
if(WIFI_CONFIGURED){
display.print("SSID: ");
display.println(lastSSID);
display.print("IP: ");
display.println(IPAddress(lastIPAddress).toString());
}else{
display.println("WiFi Not Connected");
}
display.display(false); // full refresh
guiState = APP_STATE;
@ -606,6 +603,8 @@ void Watchy::showAccelerometer() {
void Watchy::showWatchFace(bool partialRefresh) {
display.setFullWindow();
// At this point it is sure we are going to update
display.epd2.asyncPowerOn();
drawWatchFace();
display.display(partialRefresh); // partial refresh
guiState = WATCHFACE_STATE;
@ -626,12 +625,12 @@ void Watchy::drawWatchFace() {
}
weatherData Watchy::getWeatherData() {
return getWeatherData(settings.cityID, settings.weatherUnit,
settings.weatherLang, settings.weatherURL,
settings.weatherAPIKey, settings.weatherUpdateInterval);
return _getWeatherData(settings.cityID, settings.lat, settings.lon,
settings.weatherUnit, settings.weatherLang, settings.weatherURL,
settings.weatherAPIKey, settings.weatherUpdateInterval);
}
weatherData Watchy::getWeatherData(String cityID, String units, String lang,
weatherData Watchy::_getWeatherData(String cityID, String lat, String lon, String units, String lang,
String url, String apiKey,
uint8_t updateInterval) {
currentWeather.isMetric = units == String("metric");
@ -644,9 +643,16 @@ weatherData Watchy::getWeatherData(String cityID, String units, String lang,
if (connectWiFi()) {
HTTPClient http; // Use Weather API for live data if WiFi is connected
http.setConnectTimeout(3000); // 3 second max timeout
String weatherQueryURL = url + cityID + String("&units=") + units +
String("&lang=") + lang + String("&appid=") +
apiKey;
String weatherQueryURL = url;
if(cityID != ""){
weatherQueryURL.replace("{cityID}", cityID);
}else{
weatherQueryURL.replace("{lat}", lat);
weatherQueryURL.replace("{lon}", lon);
}
weatherQueryURL.replace("{units}", units);
weatherQueryURL.replace("{lang}", lang);
weatherQueryURL.replace("{apiKey}", apiKey);
http.begin(weatherQueryURL.c_str());
int httpResponseCode = http.GET();
if (httpResponseCode == 200) {
@ -656,9 +662,11 @@ weatherData Watchy::getWeatherData(String cityID, String units, String lang,
currentWeather.weatherConditionCode =
int(responseObject["weather"][0]["id"]);
currentWeather.weatherDescription =
JSONVar::stringify(responseObject["weather"][0]["main"]);
currentWeather.external = true;
// sync NTP during weather API call and use timezone of city
JSONVar::stringify(responseObject["weather"][0]["main"]);
currentWeather.external = true;
breakTime((time_t)(int)responseObject["sys"]["sunrise"], currentWeather.sunrise);
breakTime((time_t)(int)responseObject["sys"]["sunset"], currentWeather.sunset);
// sync NTP during weather API call and use timezone of lat & lon
gmtOffset = int(responseObject["timezone"]);
syncNTP(gmtOffset);
} else {
@ -693,6 +701,31 @@ float Watchy::getBatteryVoltage() {
}
}
uint8_t Watchy::getBoardRevision() {
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
if(chip_info.model == CHIP_ESP32){ //Revision 1.0 - 2.0
Wire.beginTransmission(0x68); //v1.0 has DS3231
if (Wire.endTransmission() == 0){
return 10;
}
delay(1);
Wire.beginTransmission(0x51); //v1.5 and v2.0 have PCF8563
if (Wire.endTransmission() == 0){
pinMode(35, INPUT);
if(digitalRead(35) == 0){
return 20; //in rev 2.0, pin 35 is BTN 3 and has a pulldown
}else{
return 15; //in rev 1.5, pin 35 is the battery ADC
}
}
}
if(chip_info.model == CHIP_ESP32S3){ //Revision 3.0
return 30;
}
return -1;
}
uint16_t Watchy::_readRegister(uint8_t address, uint8_t reg, uint8_t *data,
uint16_t len) {
Wire.beginTransmission(address);
@ -824,17 +857,20 @@ void Watchy::setupWifi() {
display.println("Setup failed &");
display.println("timed out!");
} else {
display.println("Connected to");
display.println("Connected to:");
display.println(WiFi.SSID());
display.println("Local IP:");
display.println(WiFi.localIP());
weatherIntervalCounter = -1; // Reset to force weather to be read again
lastIPAddress = WiFi.localIP();
WiFi.SSID().toCharArray(lastSSID, 30);
}
display.display(false); // full refresh
// turn off radios
WiFi.mode(WIFI_OFF);
btStop();
display.epd2.setBusyCallback(displayBusyCallback); // enable lightsleep on
// busy
// enable lightsleep on busy
display.epd2.setBusyCallback(WatchyDisplay::busyCallback);
guiState = APP_STATE;
}
@ -862,6 +898,8 @@ bool Watchy::connectWiFi() {
} else {
if (WL_CONNECTED ==
WiFi.waitForConnectResult()) { // attempt to connect for 10s
lastIPAddress = WiFi.localIP();
WiFi.SSID().toCharArray(lastSSID, 30);
WIFI_CONFIGURED = true;
} else { // connection failed, time out
WIFI_CONFIGURED = false;

View File

@ -16,6 +16,7 @@
#include "BLE.h"
#include "bma.h"
#include "config.h"
#include "esp_chip_info.h"
typedef struct weatherData {
int8_t temperature;
@ -23,11 +24,15 @@ typedef struct weatherData {
bool isMetric;
String weatherDescription;
bool external;
tmElements_t sunrise;
tmElements_t sunset;
} weatherData;
typedef struct watchySettings {
// Weather Settings
String cityID;
String lat;
String lon;
String weatherAPIKey;
String weatherURL;
String weatherUnit;
@ -36,7 +41,6 @@ typedef struct watchySettings {
// NTP Settings
String ntpServer;
int gmtOffset;
int dstOffset;
//
bool vibrateOClock;
} watchySettings;
@ -52,11 +56,11 @@ public:
explicit Watchy(const watchySettings &s) : settings(s) {} // constructor
void init(String datetime = "");
void deepSleep();
static void displayBusyCallback(const void *);
float getBatteryVoltage();
uint8_t getBoardRevision();
void vibMotor(uint8_t intervalMs = 100, uint8_t length = 20);
void handleButtonPress();
virtual void handleButtonPress();
void showMenu(byte menuIndex, bool partialRefresh);
void showFastMenu(byte menuIndex);
void showAbout();
@ -71,8 +75,6 @@ public:
void setupWifi();
bool connectWiFi();
weatherData getWeatherData();
weatherData getWeatherData(String cityID, String units, String lang,
String url, String apiKey, uint8_t updateInterval);
void updateFWBegin();
void showWatchFace(bool partialRefresh);
@ -86,6 +88,8 @@ private:
uint16_t len);
static uint16_t _writeRegister(uint8_t address, uint8_t reg, uint8_t *data,
uint16_t len);
weatherData _getWeatherData(String cityID, String lat, String lon, String units, String lang,
String url, String apiKey, uint8_t updateInterval);
};
extern RTC_DATA_ATTR int guiState;

View File

@ -1,6 +1,9 @@
#ifndef CONFIG_H
#define CONFIG_H
// Versioning
#define WATCHY_LIB_VER "1.4.10"
//pins
#if !defined(ARDUINO_WATCHY_V10) && !defined(ARDUINO_WATCHY_V15) && !defined(ARDUINO_WATCHY_V20)
@ -75,6 +78,4 @@
#define SOFTWARE_VERSION_PATCH 0
#define HARDWARE_VERSION_MAJOR 1
#define HARDWARE_VERSION_MINOR 0
// Versioning
#define WATCHY_LIB_VER "1.4.6"
#endif