Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Experimental] pwm motor control #54

Merged
merged 11 commits into from
May 17, 2024
Merged
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
Loading