Skip to content

Commit

Permalink
[Experimental] pwm motor control (#54)
Browse files Browse the repository at this point in the history
* experimental - pwm motor control

* fix callout block

* install-software edits

* change channels

* update to 20 rpm & 145 resolution

* Update `motorSpeed` to `145` in MotorControl

* Update bom-requirements to include MX1508 callout

* typo in bom-requirements

* Update bom-requirements.md

* add timing duration in troubleshooting

* fix link
  • Loading branch information
mwood77 authored May 17, 2024
1 parent ead282b commit b2519ec
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 26 deletions.
6 changes: 4 additions & 2 deletions docs/bom-requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
### Total cost of required Parts
- **$8.00 (April 2023)**

> [!NOTE]
> The following tables contains affiliate links to Aliexpress; you do not pay an inflated price because of this. Should you decide to use another supplier, please ensure that you cross-reference this table and buy identical components.
>
> While most of these components are standardized, I will not be able to assist you if you purchase your components from a separate supplier, as the winder was designed around the components (as supplied) beneath.
| | Quantity per Order | Link / Part Name | Comments | Cost Incl. Shipping |
Expand All @@ -24,11 +25,12 @@
### Optional parts
The following parts list will allow you to add:
- 1x SSD1306 compatible OLED screen (0.96" size)

- 1x MX1508 Motor Controller. This is a much smaller DC motor controller. Winderoo supports granular motor control with this board (PWM control); you must set a build flag to use this, which has a callout step during the [software installation instructions](./install-software.md).

| | 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 |
| 🔲 | 1 | [MX1508 Miniature Motor Controller (PWM)](https://www.aliexpress.com/item/4000408025093.html) | | $3.00 |

## Next Steps
> [Proceed to software installation 👉](./install-software.md)
Expand Down
39 changes: 28 additions & 11 deletions docs/install-software.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Software Installtion & Flashing your ESP32

> [!IMPORTANT]
> This project is an add-on to your already built [Open Source Watch Winder (OSWW)](https://github.com/mwood77/osww).
> This project is an add-on to your already built [Open Source Watch Winder (OSWW)](https://github.com/mwood77/osww).
- This project requires a microncontroller which replaces the Pi Pico used in the OSWW.
- The Raspberry Pi Pico is incompatible with this project and must be swapped.
Expand All @@ -21,16 +21,20 @@
- 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`
1. **Build Options - IMPORTANT**
- if you're building Winderoo with an OLED screen or you desire fine-grained motor control (pulse width modulation), you must enable one (or two) build flags to tell PlatformIO to include additional libraries.
- To toggle these build flags, navigate to the file called `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
- In this file, you'll see the following block of code:
```yml
build_flags =
-D OLED_ENABLED=false
-D PWM_MOTOR_CONTROL=false
```
- Change `-D OLED_ENABLED=false` to `-D OLED_ENABLED=true` to enable OLED screen support
- Change `-D PWM_MOTOR_CONTROL=false` to `-D PWM_MOTOR_CONTROL=true` to enable PWM motor control
- > PWM_MOTOR_CONTROL is an experimental flag. You will encounter incorrect cycle time estimation and other possible bugs unless you align the motor speed to **20 RPM** (see [Troubleshooting](#troubleshooting)). Use at your own risk.
- PlatformIO will now compile Winderoo with OLED screen and or PWM motor 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 All @@ -41,7 +45,7 @@
<div align="center"><img src="images/code_uploaded.png" alt="upload filesystem button"></div>
1. All done! Your microcontroller should now have 2 LEDs illuminated (see beneath). If it does, proceed to [Next steps](#next-steps). If not, try to upload the code & file system again.
<div align="center"><img src="images/led_states/blue_on.png" alt="upload filesystem button" height="300"></div>
1. If you have a different LED state, compare it with this table:
1. If you have a different LED state, compare it with this table:
- [Understanding Winderoo's LED Blink Status](user-manual.md#understanding-winderoos-led-blink-status)

## Next steps:
Expand All @@ -59,3 +63,16 @@ Ok, you've got 2 LEDs illuminated on your board. Great! Let's make sure the code
- [http://winderoo.local/](http://winderoo.local/)
1. If you see Winderoo's user interface, you're all done!
- [Here is an overview of Winderoo's user interface](./user-manual.md)

## Troubleshooting
### Motor Turns too fast when using PWM
> [!WARNING]
> PWM_MOTOR_CONTROL is an experimental flag. You will encounter incorrect cycle time estimation and other possible bugs unless you align the motor speed to **20 RPM**.
- The default speed is `145` (8-bit resolution), where `0` is the slowest and `255` is the fastest. You can modify this value here:
- [`MotorControl.cpp`](../src/platformio/osww-server/src/utils/MotorControl.cpp#L7)
- Change the value for the variable `motorSpeed` to any value between `0` and `255`
- After changing that value, you must recompile the software and upload it to your ESP32
- You can also tweak the rotational timing value. By default this is set at 8 seconds to complete one revolution.
- To change this value, change the variable `durationInSecondsToCompleteOneRevolution` here:
- [`main.cpp`](../src/platformio/osww-server/src/main.cpp#L38)
4 changes: 3 additions & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ monitor_speed = 115200
build_src_filter = +<*> -<./angular/>
board_build.filesystem = littlefs
check_tool = cppcheck, clangtidy
build_flags =
build_flags =
-D OLED_ENABLED=false
-D PWM_MOTOR_CONTROL=false
check_flags =
clangtidy: -fix-errors,--format-style=google
lib_deps =
Expand All @@ -32,3 +33,4 @@ lib_deps =
https://github.com/bblanchon/ArduinoJson.git
fbiego/ESP32Time@^2.0.0
adafruit/Adafruit SSD1306@^2.5.9
electromagus/ESPMX1508@^1.0.5
8 changes: 6 additions & 2 deletions src/platformio/osww-server/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,22 @@ struct RUNTIME_VARS
*/
RUNTIME_VARS userDefinedSettings;
LedControl LED(ledPin);
MotorControl motor(directionalPinA, directionalPinB);
WiFiManager wm;
AsyncWebServer server(80);
HTTPClient http;
WiFiClient client;
ESP32Time rtc;

#if PWM_MOTOR_CONTROL
MotorControl motor(directionalPinA, directionalPinB, true);
#else
MotorControl motor(directionalPinA, directionalPinB);
#endif

#ifdef OLED_ENABLED
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#endif


void drawCentreStringToMemory(const char *buf, int x, int y)
{
int16_t x1, y1;
Expand Down
43 changes: 34 additions & 9 deletions src/platformio/osww-server/src/utils/MotorControl.cpp
Original file line number Diff line number Diff line change
@@ -1,35 +1,60 @@
#include "MotorControl.h"

MotorControl::MotorControl(int pinA, int pinB)
#if PWM_MOTOR_CONTROL
#include <ESP32MX1508.h>
#define CH1 1
#define CH2 2
int motorSpeed = 145;
#endif

MotorControl::MotorControl(int pinA, int pinB, bool pwmMotorControl)
{
_pinA = pinA;
_pinB = pinB;
_motorDirection = 0;
_pwmMotorControl = pwmMotorControl;
}

void MotorControl::clockwise()
{
digitalWrite(_pinA, HIGH);
digitalWrite(_pinB, LOW);
#if PWM_MOTOR_CONTROL
MX1508 pwmControl(_pinA, _pinB, CH1, CH2);
pwmControl.motorGo(motorSpeed);
#else
digitalWrite(_pinA, HIGH);
digitalWrite(_pinB, LOW);
#endif
Serial.println("[STATUS] - Motor turning clockwise");
}

void MotorControl::countClockwise()
{
digitalWrite(_pinA, LOW);
digitalWrite(_pinB, HIGH);
#if PWM_MOTOR_CONTROL
MX1508 pwmControl(_pinA, _pinB, CH1, CH2);
pwmControl.motorRev(motorSpeed);
#else
digitalWrite(_pinA, LOW);
digitalWrite(_pinB, HIGH);
#endif
Serial.println("[STATUS] - Motor turning counter clockwise");
}

void MotorControl::stop()
{
digitalWrite(_pinA, LOW);
digitalWrite(_pinB, LOW);
#if PWM_MOTOR_CONTROL
MX1508 pwmControl(_pinA, _pinB, CH1, CH2);
pwmControl.motorBrake();
#else
digitalWrite(_pinA, LOW);
digitalWrite(_pinB, LOW);
#endif
Serial.println("[STATUS] - Motor stopped");
}

void MotorControl::determineMotorDirectionAndBegin()
{
stop();
// @todo - investigate if this is still needed
// stop();

if (_motorDirection)
{
Expand All @@ -49,4 +74,4 @@ int MotorControl::getMotorDirection()
void MotorControl::setMotorDirection(int direction)
{
_motorDirection = direction;
}
}
3 changes: 2 additions & 1 deletion src/platformio/osww-server/src/utils/MotorControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ class MotorControl
int _pinB;
// 1 = clockwise, 0 = counter clockwise
int _motorDirection;
bool _pwmMotorControl;

public:
MotorControl(int _pinA, int _pinB);
MotorControl(int _pinA, int _pinB, bool pwmMotorControl = false);

void clockwise();

Expand Down

0 comments on commit b2519ec

Please sign in to comment.