Skip to content

Commit

Permalink
Support for OLED Screens (#47)
Browse files Browse the repository at this point in the history
* hackish oled implementation

* bug - save state when winding complet

* basic GUI

* tweaks

* formatting

* more formatting

* update documenation

* update images

* fix centering on multi-line messages

* modify `drawStaticGUI()` method

* Added timer and wifi reception to oled

* add `_screen` related variables for front end

* add `_screen` related flags in front end

* add translations

* add FE build with screen changes

* update user manual

* update OAS

* remove log statement

* remove extra whitespace

* fix screen rotation
  • Loading branch information
mwood77 authored Apr 8, 2024
1 parent 644702f commit 9c118c0
Show file tree
Hide file tree
Showing 36 changed files with 458 additions and 48 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<br>
<br>
<p>
Winderoo is open source firmware which adds "smart" functionality, and a GUI, to your <a href="https://github.com/mwood77/osww" target="_blank">OSWW</a> or other microcontroller equipped watch winder.
Winderoo is open source firmware which adds <i>smart functionality</i> to your <a href="https://github.com/mwood77/osww" target="_blank">OSWW build</a> or microcontroller equipped watch winder. <i>Smart functionality</i> includes a Web UI (fully-translated in 5 languages!), OLED screen support, start timer, and more!
</p>
</div>

Expand All @@ -32,13 +32,15 @@
* Estimated cycle duration (how long it'll take to wind your watch).
* Cycle progress display (how far along the current winding routine is).
* Software or optional physical button to trigger ON/OFF state, so you can disable the winder completely.
* OLED screen support
* Simple setup. Flash the firmware and File System with a few clicks, then connect your phone (or other device) to the winder's setup wifi network & add it to your home network.
* There's no app required! You control it from a web browser.
* There's no app required! You control it from a web browser.
* Minimal electronics / programming experience required
* Web UI is fully tranlated into 5 langauges (more are welcome!)


### Winderoo Requires a Different Microcontroller
* **You must replace the Pi Pico, as spec'd in the OSWW build guide, with an ESP32. This project will not run on the Pi Pico!**
* **You must replace the Pi Pico, as spec'd in the OSWW build guide, with an ESP32. This project will not run on a Pi Pico!**

# User Manual
* [Click Here to see the user manual](./docs/user-manual.md)
Expand Down
Binary file modified data/3rdpartylicenses.txt.gz
Binary file not shown.
3 changes: 2 additions & 1 deletion data/assets/i18n/de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"COUNTER_CLOCKWISE": "Gegen den Uhrzeigersinn",
"BOTH": "Beide Richtungen",
"PLEASE_WAIT": "Zyklusfortschritt wird angezeigt, bitte warten",
"PROGRESS": "Zyklusfortschritt"
"PROGRESS": "Zyklusfortschritt",
"SCREEN": "OLED Bildschirm"
}
}
3 changes: 2 additions & 1 deletion data/assets/i18n/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"COUNTER_CLOCKWISE": "Counter Clockwise",
"BOTH": "Both",
"PLEASE_WAIT": "Getting cycle progress, please wait",
"PROGRESS": "Cycle Progress"
"PROGRESS": "Cycle Progress",
"SCREEN": "OLED Screen"
}
}
3 changes: 2 additions & 1 deletion data/assets/i18n/es-ES.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"COUNTER_CLOCKWISE": "En sentido anti-horario",
"BOTH": "Ambos",
"PLEASE_WAIT": "Obteniendo el progreso del ciclo, espere",
"PROGRESS": "Progreso del ciclo"
"PROGRESS": "Progreso del ciclo",
"SCREEN": "Pantalla OLED"
}
}
3 changes: 2 additions & 1 deletion data/assets/i18n/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"COUNTER_CLOCKWISE": "Dans le sens inverse des aiguilles d'une montre",
"BOTH": "Les deux",
"PLEASE_WAIT": "Obtenir la progression du cycle, veuillez patienter",
"PROGRESS": "Progression du cycle"
"PROGRESS": "Progression du cycle",
"SCREEN": "Écran OLED"
}
}
3 changes: 2 additions & 1 deletion data/assets/i18n/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"COUNTER_CLOCKWISE": "Sentido anti-horário",
"BOTH": "Ambos",
"PLEASE_WAIT": "Obtendo o progresso do ciclo, aguarde",
"PROGRESS": "Progresso do Ciclo"
"PROGRESS": "Progresso do Ciclo",
"SCREEN": "Ecrã OLED"
}
}
Binary file modified data/index.html.gz
Binary file not shown.
Binary file modified data/main.js.gz
Binary file not shown.
Binary file modified data/polyfills.js.gz
Binary file not shown.
Binary file modified data/runtime.js.gz
Binary file not shown.
Binary file modified data/styles.css.gz
Binary file not shown.
9 changes: 9 additions & 0 deletions docs/bom-requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@
| 🔲 | 1 | [ESP32 Dev Kit](https://s.click.aliexpress.com/e/_Derbd5r) | Select `Color: ESP32` | $8.00 |


### Optional parts
The following parts list will allow you to add:
- 1x SSD1306 compatible OLED screen (0.96" size)


| | Quantity per Order | Link / Part Name | Comments | Cost Incl. Shipping |
| :-: | :------------: | :-------------------------------------------------------------------------------: | :-------------------------------------------------------------------: |:-----:
| 🔲 | 1 | [0.96" SSD1306 OLED](https://s.click.aliexpress.com/e/_DFywAW1) | Select: whichever colour you'd like! | $2.00 |

## Next Steps
> [Proceed to software installation 👉](./install-software.md)
Binary file added docs/gui/oled_screen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/gui/overview_v0.1.0.png
Binary file not shown.
Binary file added docs/gui/overview_v1.0.0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/platformio-ini.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions docs/install-software.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@
- If you downloaded the repository as a zip, uzip it before proceeding to step 2.
<div align="center"><img src="images/download_directory.png" alt="how to download"></div>
1. Open the extracted folder (or cloned repository if using git) in Visual Studio Code
1. **IMPORTANT** -> if you're building Winderoo with an OLED screen attached, you must enable a build flag to tell PlatformIO to include additional libraries. To do this:
- Navigate to the file `platformio.ini`
<div align="center"><img src="images/platformio-ini.png" alt="how to download"></div>
- In this file, you'll see the following block of code:
```yml
build_flags =
-D OLED_ENABLED=false
```
- Change `-D OLED_ENABLED=false` to `-D OLED_ENABLED=true`
- PlatformIO will now compile Winderoo with OLED screen support
1. Select 'PlatformIO' (alien/insect looking button) on the workspace menu and wait for visual studio code to finish initializing the project
<div align="center"><img src="images/platformIO.png" alt="platformIO button"></div>
1. Expand the main heading: **"esp32doit-devkit-v1"**:
Expand Down
12 changes: 11 additions & 1 deletion docs/user-manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

| v1.0.0 | |
| :---: |:---: |
|<img src="gui/overview_v0.1.0.png" height="600"> | This is winderoo's primary interface. From here you can change any settings you need |
|<img src="gui/overview_v1.0.0.png" height="600"> | This is winderoo's primary interface. From here you can change any settings you need |


### Enable / Disable Winding
Expand Down Expand Up @@ -59,6 +59,16 @@
|<img src="gui/cycle-start-time-toggle.png" > | This will enable or disable the winder's timer. When the switch is set to **ENABLED**, Winderoo will begin winding at a your desired 'Cycle Start Time.' If the switch is set to **DISABLED**, you must start the winder using the [control buttons](#control-buttons) |
|<img src="gui/cycle-start-time.png" > | Set which time you'd like Winderoo to begin winding at. **_Important!_** WInderoo will _always_ start at this time, even if you've already triggered a manual run with a [control button](#control-buttons). To stop this behaviour, see: [Enable / Disable Winding](#enable--disable-winding) |

### OLED Screen

>[!IMPORTANT]
> This element will appear _only if_ you've compiled Winderoo with an OLED screen attached, and set the build flag accordingly.
| UI Element | Function |
| :---: |:---: |
|<img src="gui/oled_screen.png" > | This will toggle the attached OLED screen on and off. |


### Save / Update Settings
| UI Element | Function |
| :---: |:---: |
Expand Down
Binary file added docs/winderoo-with-oled-wiring-diagram.pdf
Binary file not shown.
Binary file added docs/winderoo-with-oled.fzz
Binary file not shown.
36 changes: 34 additions & 2 deletions docs/wiring-diagram.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
> [👈 Back to main page](../README.md)
# Wiring Diagram - Winderoo
![fritzing wiring diagram](./images/winderoo.png)
# Wiring Diagrams - Winderoo
- [Winderoo](#winderoo)
- [Winderoo With OLED Screen](#winderoo-with-oled-screen)


## Winderoo
![fritzing wiring diagram](./images/winderoo-wiring-diagram.png)

<div align="center">
<a href="./winderoo-wiring-diagram-fritzing.pdf">Is the image hard to view? Open the PDF instead</a>
Expand All @@ -15,6 +20,33 @@
- Make sure the L298N's jumpers are in place (small blue wires on board)
- Connect the ESP32's `GPIO25` to `IN1` on the L298N driver board (yellow wire)
- Connect the ESP32's `GPIO26` to `IN2` on the L298N driver board (blue wire)
- Connect the DC motor to channel 1 on the L298N driver board.
- > Note: polarity does not matter here
- You may add an external button off `GPIO 13` on the ESP32; this will enable and disable winding

## Winderoo with OLED Screen

> [!IMPORTANT]
> This wiring diagram assumes you've purchased an I2C 4-wire OLED (SSD1306 driver compatible). Complex LCDs are currently not supported.
![fritzing wiring diagram](./images/winderoo-with-oled-wiring-diagram.png)

<div align="center">
<a href="./winderoo-with-oled-wiring-diagram.pdf">Is the image hard to view? Open the PDF instead</a>
</div>
<br />


- Connect the ESP32's `5V` output pin to the 5V input of the L298N driver board (red wire)
- Connect the ESP32's `5V` output pin to the `VCC` input pin on your OLED screen
- Connect a ground wire from the ESP32 to the L298N driver board (black wire)
- Connect a ground wire from the ESP32 to the OLED screen's `GRND` pin
- Connect a wire from the ESP32's `D22` pin to the OLED screen's `SCL` pin
- Connect a wire from the ESP32's `D21` pin to the OLED screen's `SDA` pin
- Connect the L298N driver board's 5V and 12V terminals together (red jumper wire)
- Make sure the L298N's jumpers are in place (small blue wires on board)
- Connect the ESP32's `GPIO25` to `IN1` on the L298N driver board (yellow wire)
- Connect the ESP32's `GPIO26` to `IN2` on the L298N driver board (blue wire)
- Connect the DC motor to channel 1 on the L298N driver board.
- > Note: polarity does not matter here
- You may add an external button off `GPIO 13` on the ESP32; this will enable and disable winding
11 changes: 10 additions & 1 deletion openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ paths:
post:
tags:
- Modify
summary: Change the state of Winderoo
summary: Change the timer state of Winderoo
parameters:
- in: query
name: timerEnabled
Expand Down Expand Up @@ -134,6 +134,7 @@ components:
timerEnabled: "0"
action: "START"
rotationDirection: "BOTH"
screenSleep: false
PowerBody:
description: a JSON object containing winderoo power information
required: true
Expand Down Expand Up @@ -243,6 +244,14 @@ components:
type: number
examples:
- -67
screenSleep:
type: boolean
examples:
- false
screenEquipped:
type: boolean
examples:
- false
Resetting:
type: object
properties:
Expand Down
5 changes: 4 additions & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ monitor_speed = 115200
build_src_filter = +<*> -<./angular/>
board_build.filesystem = littlefs
check_tool = cppcheck, clangtidy
check_flags=
build_flags =
-D OLED_ENABLED=false
check_flags =
clangtidy: -fix-errors,--format-style=google
lib_deps =
esphome/AsyncTCP-esphome@^1.2.2
Expand All @@ -29,3 +31,4 @@ lib_deps =
https://github.com/tzapu/WiFiManager.git
https://github.com/bblanchon/ArduinoJson.git
fbiego/ESP32Time@^2.0.0
adafruit/Adafruit SSD1306@^2.5.9
7 changes: 5 additions & 2 deletions src/angular/osww-frontend/src/app/api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface Update {
hour: string;
minutes: string;
timerEnabled: number;
screenSleep: boolean;
}

export interface Status {
Expand All @@ -27,6 +28,8 @@ export interface Status {
estimatedRoutineFinishEpoch: number;
winderEnabled: number;
timerEnabled: number;
screenSleep: boolean;
screenEquipped: boolean;
}

@Injectable({
Expand Down Expand Up @@ -69,12 +72,12 @@ export class ApiService {
let powerStateToNum;
const baseURL = ApiService.constructURL() + 'power';

if (powerState) {
if (powerState) {
powerStateToNum = 1;
} else {
powerStateToNum = 0;
}

const powerBody = {
winderEnabled: powerStateToNum
}
Expand Down
28 changes: 23 additions & 5 deletions src/angular/osww-frontend/src/app/settings/settings.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
</div>
</div>
</mat-card>

<mat-card class="mat-elevation-z1">
<div class="individual-setting ">
{{ "SETTINGS.DIRECTION" | translate }}
Expand Down Expand Up @@ -94,7 +94,7 @@
<mat-card class="mat-elevation-z1">
<div class="individual-setting">
<div>{{ "SETTINGS.CYCLE_START" | translate }}</div>

<div style="display: flex; justify-content: center;">
<mat-slide-toggle [(ngModel)]="this.isTimerEnabled" (ngModelChange)="updateTimerEnabledState($event)">
<span *ngIf="this.isTimerEnabled; else elseBlock">
Expand All @@ -110,11 +110,11 @@


<div *ngIf="this.isTimerEnabled">

<div class="individual-status-text">
{{ this.upload.hour }}:{{ this.upload.minutes }}
</div>

<div class="time-input">
<mat-form-field color="accent" appearance="outline">
<mat-label>
Expand Down Expand Up @@ -144,10 +144,28 @@
</div>
</mat-card>

<mat-card class="mat-elevation-z1" *ngIf="this.screenEquipped">
<div class="individual-setting">
<div>{{ "SETTINGS.SCREEN" | translate }}</div>

<div style="display: flex; justify-content: center;">
<mat-slide-toggle [(ngModel)]="!this.upload.screenSleep" (ngModelChange)="updateScreenSleepState(!$event)">
<span *ngIf="this.upload.screenSleep; else elseBlock">
{{ "SETTINGS.DISABLED" | translate | uppercase }}
</span>
<ng-template #elseBlock>
<span>
{{ "SETTINGS.ENABLED" | translate | uppercase }}
</span>
</ng-template>
</mat-slide-toggle>
</div>
</div>
</mat-card>

<mat-card class="mat-elevation-z1">
<button mat-raised-button color="primary" class="upload-button" (click)="uploadSettings()" [disabled]="upload.disabled">
<div class="save-button-text">{{ upload.statusMessage }}</div>
</button>
</mat-card>
</div>

14 changes: 12 additions & 2 deletions src/angular/osww-frontend/src/app/settings/settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class SettingsComponent implements OnInit, AfterViewChecked {
];

wifiSignalIcon = ''

upload = {
activityState: '',
statusMessage: '',
Expand All @@ -64,7 +64,8 @@ export class SettingsComponent implements OnInit, AfterViewChecked {
durationInSecondsToCompleteOneRevolution: 0,
startTimeEpoch: 0,
estimatedRoutineFinishEpoch: 0,
isTimerEnabledNum: 0
isTimerEnabledNum: 0,
screenSleep: false
}

selectedHour: any;
Expand All @@ -76,6 +77,7 @@ export class SettingsComponent implements OnInit, AfterViewChecked {
progressPercentageComplete: number = 0;
isWinderEnabled: number;
isTimerEnabled: boolean;
screenEquipped: boolean = false;

watchWindingParametersURL = 'https://watch-winder.store/watch-winding-table/';

Expand Down Expand Up @@ -118,6 +120,8 @@ export class SettingsComponent implements OnInit, AfterViewChecked {
this.upload.startTimeEpoch = data.startTimeEpoch;
this.upload.estimatedRoutineFinishEpoch = data.estimatedRoutineFinishEpoch;
this.upload.isTimerEnabledNum = data.timerEnabled;
this.upload.screenSleep = data.screenSleep;
this.screenEquipped = data.screenEquipped;

this.apiService.isWinderEnabled$.next(data.winderEnabled);

Expand Down Expand Up @@ -211,6 +215,7 @@ export class SettingsComponent implements OnInit, AfterViewChecked {
hour: this.selectedHour == null ? this.upload.hour : this.selectedHour,
minutes: this.selectedMinutes == null ? this.upload.minutes : this.selectedMinutes,
timerEnabled: this.upload.isTimerEnabledNum,
screenSleep: this.upload.screenSleep,
}

this.apiService.updateState(body).subscribe((response) => {
Expand Down Expand Up @@ -292,4 +297,9 @@ export class SettingsComponent implements OnInit, AfterViewChecked {
});
};

updateScreenSleepState($state: boolean) {
this.upload.screenSleep = $state;
this.uploadSettings();
};

}
3 changes: 2 additions & 1 deletion src/angular/osww-frontend/src/assets/i18n/de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"COUNTER_CLOCKWISE": "Gegen den Uhrzeigersinn",
"BOTH": "Beide Richtungen",
"PLEASE_WAIT": "Zyklusfortschritt wird angezeigt, bitte warten",
"PROGRESS": "Zyklusfortschritt"
"PROGRESS": "Zyklusfortschritt",
"SCREEN": "OLED Bildschirm"
}
}
3 changes: 2 additions & 1 deletion src/angular/osww-frontend/src/assets/i18n/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"COUNTER_CLOCKWISE": "Counter Clockwise",
"BOTH": "Both",
"PLEASE_WAIT": "Getting cycle progress, please wait",
"PROGRESS": "Cycle Progress"
"PROGRESS": "Cycle Progress",
"SCREEN": "OLED Screen"
}
}
Loading

0 comments on commit 9c118c0

Please sign in to comment.