I have attached the schematic and the full code for the PWM motor control. Both are available under GPL V3.
The schematic was developed using KiCAD.
Best regards,
Steve
Code: Select all
/* Written by Steven E. Stock who retains all Copyrights, released 8-1-2021.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You may have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_I2C_ADDR 0x3C
#define OLED_WIDTH 128
#define OLED_HEIGHT 32
#define pwm_lathe PB0
#define pwm_mill PB1
TIM_TypeDef *InstanceMill = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(pwm_mill), PinMap_PWM);
uint32_t channelMill = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pwm_mill), PinMap_PWM));
HardwareTimer *MyTim = new HardwareTimer(InstanceMill);
TIM_TypeDef *InstanceLathe = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(pwm_lathe), PinMap_PWM);
uint32_t channelLathe = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pwm_lathe), PinMap_PWM));
Adafruit_SSD1306 display(OLED_WIDTH, OLED_HEIGHT, &Wire);
int pwm = 0;
int pwm_set_Lathe = 0;
int pwm_set_Mill = 0;
int loop1 = 1;
int LatheActive = 1;
int MillActive = 0;
char person_pwm[3];
char percnt[1] = {'%'};
char pending[1] = {'P'};
int ButtonUp = 0;
int ButtonDown = 0;
int ButtonSwitch = 0;
int ButtonCommit = 0;
void pwm_Mill(int duty)
{
MyTim->setCaptureCompare(channelLathe, duty, PERCENT_COMPARE_FORMAT);
delay(50);
}
void pwm_Lathe(int duty)
{
MyTim->setCaptureCompare(channelMill, duty, PERCENT_COMPARE_FORMAT);
delay(50);
}
void setup()
{
pinMode(PC13, OUTPUT);
pinMode(PA10, OUTPUT); //pwm pin
pinMode(PB5, INPUT);
pinMode(PB4, INPUT);
pinMode(PB3, INPUT);
pinMode(PA15, INPUT);
MyTim->setPWM(channelLathe, pwm_lathe, 20, 1);
MyTim->setPWM(channelMill, pwm_mill, 20, 1);
ButtonCommit = digitalRead(PA15);
ButtonDown = digitalRead(PB4);
ButtonUp = digitalRead(PB5);
ButtonSwitch = digitalRead(PB3);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c))
{
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
display.setRotation(2);
pwm_Mill(pwm);
}
void oled_write() {
display.clearDisplay();
display.display();
display.setTextSize(3);
display.setTextColor(SSD1306_WHITE);
display.setCursor(45,5);
display.print(person_pwm);
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10,25);
if (LatheActive) {display.print("Lathe");} else {display.print("Mill");}
display.display(); // actually display all of the above
}
void loop() {
if ((!ButtonUp) && (pwm<94)) {
pwm++;
sprintf(person_pwm, "%02d", pwm);
person_pwm[2]= *pending;
oled_write();
}
if ((!ButtonDown) && (pwm>0)) {
pwm--;
sprintf(person_pwm, "%02d", pwm);
person_pwm[2]= *pending;
oled_write();
}
if (!ButtonSwitch) {
if (LatheActive) {LatheActive = 0; MillActive=1;pwm = pwm_set_Mill;} else {LatheActive = 1; MillActive=0;pwm = pwm_set_Lathe;}
sprintf(person_pwm, "%02d", pwm);
person_pwm[2]= *percnt;
oled_write();
pwm_Mill(pwm);
}
if (!ButtonCommit) {
if (LatheActive) {pwm_set_Lathe = pwm; pwm_Lathe(pwm);} else {pwm_set_Mill = pwm; pwm_Mill(pwm);}
person_pwm[2]= *percnt;
oled_write();
}
// sprintf(person_pwm, "%02d", pwm);
delay(200); // Pause for however long feels right
ButtonCommit = digitalRead(PA15);
ButtonDown = digitalRead(PB4);
ButtonUp = digitalRead(PB5);
ButtonSwitch = digitalRead(PB3);
if (loop1 == 1) {sprintf(person_pwm, "%02d", pwm);person_pwm[2]= *percnt;oled_write();loop1 = 0;}
}