Which drivers can control a DC motor and a step motor : DRV8834, DRV8428, A4950 and A4988.
If we focus on which ICs can drive both a DC motor and a stepper motor, let's break it down carefully:
1. DRV8834 - Designed as a stepper driver but can also drive bipolar DC motors in full-bridge mode. β Yes, both
2. DRV8428 - Dual H-bridge driver, intended for stepper motors but also works for DC motors. β Yes, both
3. A4950 - Specifically a DC motor driver, not designed for stepper motors. β DC only
4. A4988 - Specifically a stepper motor driver, cannot drive a normal DC motor. β Stepper only
π‘ Answer: Only DRV8834 and DRV8428 can drive both DC and stepper motors.
If you want, I can also explain why the DRV8834 is often preferred for βdual-useβ applications because it handles microstepping and DC current control efficiently. Do you want me to?
what is a bipolar DC motors
A bipolar DC motor is a type of brushed DC motor that has two terminals for connection, and its direction is controlled by reversing the polarity of the voltage applied. Let me break it down clearly:
________________________________________
Key Features of Bipolar DC Motors:
1. Two terminals only: Unlike unipolar stepper motors which have multiple windings with a common center tap, bipolar DC motors just have two wires (positive and negative).
2. Requires an H-bridge to reverse direction: To make the motor spin forward or backward, you need to swap the voltage polarity, which is usually done with an H-bridge driver.
3. Brushes and commutator: Internally, it has brushes that switch the current in the windings as the motor rotates, unlike brushless motors.
4. Speed control: You can control the speed using PWM (Pulse Width Modulation) applied to the motor voltage.
________________________________________
Simple Analogy:
Think of it as a toy car motor:
β’ If you connect the battery one way, it goes forward.
β’ If you reverse the battery, it goes backward.
That's basically a bipolar DC motor in action.
________________________________________
π‘ Contrast with Stepper Motors:
β’ A stepper motor moves in precise steps; it has multiple coils and requires a driver to energize them in sequence.
β’ A bipolar DC motor spins continuously, and you control direction by reversing voltage.
________________________________________
If you want, I can also make a quick diagram showing how an H-bridge drives a bipolar DC motor, which makes it super easy to visualize. Do you want me to do that?
I am using an 0.96 Inch OLED Module 128x64 Driver I2C with code from Quentin BOLSEE but i get an error messages.
This isn't actually a problem with your OLED code β it's a library conflict, and the error message is pointing right at it:
"typedef uint8_t SPIClass;"" vs. "class SPIClass"
π What's going wrong
β’ The official Arduino SPI library defines SPIClass as a class.
β’ But your installed Adafruit_BusIO (or a modified version of it in your local libraries folder) defines SPIClass as a typedef (uint8_t).
β’ These two definitions collide, causing the compiler error:
βusing typedef-name 'SPIClass' after 'class'β
This usually happens when:
β’ You have old or modified libraries in your codes/libraries/ folder
β’ Or you're using a non-standard board core (Fab_SAM_Arduino) with incompatible libraries
________________________________________
β How to fix it
β 1. Remove the broken local libraries (most likely fix)
You have this path:
OneDrive ... \codes\libraries\
π Inside it, you likely have:
β’ Adafruit_BusIO
β’ Adafruit_GFX_Library
β’ Adafruit_SSD1306
β οΈ These are probably outdated or modified.
Do this:
1. Go to that libraries folder
2. Delete (or rename) these folders:
o Adafruit_BusIO
o Adafruit_GFX_Library
o Adafruit_SSD1306
________________________________________
β 2. Install clean versions via Arduino Library Manager
In the Arduino IDE:
1. Go to Sketch β Include Library β Manage Libraries
2. Install:
o Adafruit SSD1306
o Adafruit GFX Library
o Adafruit BusIO
These versions are guaranteed to be compatible.
________________________________________
β 3. Check your board core (important)
You're using:
Fab_SAM_Arduino\hardware\samd\1.12.0
This is not a standard Arduino core, and may ship with a modified SPI library.
π Try switching temporarily to:
β’ Arduino Zero (SAMD)
β’ or another official SAMD board
If it compiles β the issue is your Fab_SAM core
________________________________________
β 4. (Quick workaround if needed)
If you must use your current setup:
Open:
Adafruit_BusIO/Adafruit_SPIDevice.h
Find:
typedef uint8_t SPIClass;
π Delete or comment it out
β οΈ This is a hack, not a proper fix β only use if necessary.
________________________________________
β οΈ Bonus issue: Serial
You wrote:
Serial.begin(0);
That's invalid. Use:
Serial.begin(115200);
________________________________________
β Summary
β’ β Problem: conflicting SPIClass definitions
β’ β Fix: remove local outdated libraries + reinstall clean ones
β’ β οΈ Possible cause: Fab Academy custom board core
β’ π οΈ Optional: patch Adafruit_BusIO if needed
________________________________________
If you want, tell me which board you're using (exact model) and I can give you a known-working setup for that OLED π
I am using a custom board based on the SAMD11C14A, i flashed a bootloader onto it and added the right board package.
Got it β that actually explains the error very well. Your issue is not your OLED or code, it's your custom SAMD11 board package breaking SPI compatibility.
________________________________________
π₯ Root cause (specific to your setup)
This line in your error is the smoking gun:
typedef uint8_t SPIClass;
That should never exist in a normal Arduino environment.
π What's happening:
β’ Your Fab / custom SAMD11 core defines a fake SPIClass
β’ Meanwhile, the official SPI library defines the real:
class SPIClass
β’ Result β hard compiler conflict
________________________________________
β οΈ Why this happens on SAMD11
The SAMD11C14A:
β’ Has very limited resources
β’ Often does NOT support SPI in standard Arduino cores
β’ Some custom cores βhackβ things by:
o disabling SPI
o or redefining SPIClass as a dummy type (what you're seeing)
But Adafruit_SSD1306 β depends on Adafruit_BusIO β expects real SPI support, even if you're using I2C.
________________________________________
β Best fixes (in order of reliability)
π₯ Option 1 β Fix the broken core (recommended)
Go into your board package:
Fab_SAM_Arduino/hardware/samd/1.12.0/libraries/SPI/SPI.h
Look for anything like:typedef uint8_t SPIClass;
π Delete or comment that out
Make sure only the real class exists:
class SPIClass { ... };
________________________________________
π₯ Option 2 β Force SSD1306 to avoid SPI completely
Even though you're using I2C, the library still pulls SPI in.
You can bypass this:
1. Open:
Adafruit_SSD1306.h
2. Make sure you're using I2C constructor only (you already are π)
3. Then open:
Adafruit_BusIO/Adafruit_SPIDevice.h
π Wrap SPI parts with guards like:
#ifndef ARDUINO_ARCH_SAMD11
// SPI stuff
#endif
β οΈ Slightly hacky, but works on minimal chips.
________________________________________
π₯ Option 3 β Use a lighter SSD1306 library (very recommended for SAMD11)
The Adafruit stack is heavy for SAMD11.
Switch to something like:
β’ SSD1306Ascii (lightweight, I2C only)
β’ or a minimal SSD1306 driver
π This avoids:
β’ SPI
β’ BusIO
β’ large RAM usage
________________________________________
π¨ Important: Memory constraints
SAMD11C14A has:
β’ 16 KB flash
β’ 4 KB RAM
Adafruit SSD1306 buffer alone:
128 x 64 / 8 = 1024 bytes (1 KB RAM!)
π That's 25% of your RAM gone instantly
If you see crashes later β that's why.
________________________________________
β My recommendation (practical)
Do this:
1. β Remove the fake typedef SPIClass
2. β Use clean Adafruit libraries
3. β οΈ If unstable β switch to SSD1306Ascii
________________________________________
π§ Small fix in your code
Change:
Serial.begin(0);
to:
Serial.begin(115200);
________________________________________
π If you want a clean working setup
I can give you:
β’ a minimal SSD1306 example for SAMD11
β’ or help fix your board package SPI properly
Just tell me:
π Do you want to keep Adafruit libraries, or go lightweight?
Give me a code based on the SSD1306Ascii library.
Good call β SSD1306Ascii is much better suited for a SAMD11 (tiny RAM, no SPI headaches).
Here's a minimal, clean working example using I2C π
________________________________________
β 1. Install the library
In Arduino IDE:
β’ Install SSD1306Ascii
β’ Install SSD1306AsciiWire
________________________________________
β 2. Working code (SAMD11 + I2C OLED)
#include <Wire.h>
#include <SSD1306Ascii.h>
#include <SSD1306AsciiWire.h>
#define I2C_ADDRESS 0x3C // common for 128x64 OLED
SSD1306AsciiWire oled;
void setup() {
// Start serial (optional, for debugging)
Serial.begin(115200);
// Initialize I2C
Wire.begin();
// Initialize OLED
oled.begin(&Adafruit128x64, I2C_ADDRESS);
// Set font (very important!)
oled.setFont(System5x7);
// Clear screen
oled.clear();
// Print text
oled.setCursor(0, 0);
oled.println("Hello world!");
oled.println("SAMD11 + OLED");
}
void loop() {
// Example: simple counter
static int counter = 0;
oled.setCursor(0, 4); // row 4
oled.print("Count: ");
oled.println(counter++);
delay(1000);
}
________________________________________
β Why this works better
β’ β No framebuffer (saves ~1KB RAM)
β’ β No SPI dependency β avoids your error completely
β’ β Designed for low-memory MCUs like SAMD11
β’ β Faster text rendering
________________________________________
β οΈ Important notes for your board
1. I2C pins
Make sure your SAMD11 uses the correct pins:
Wire.begin();
If it doesn't work, you may need:
Wire.begin(SDA_PIN, SCL_PIN);
(depends on your board variant)
________________________________________
2. Address check
If nothing shows:
β’ Try 0x3D instead of 0x3C
________________________________________
3. Power issues
These OLEDs are sensitive:
β’ Use 3.3V (not 5V on SAMD11)
β’ Ensure solid GND
________________________________________
π If screen stays blank
Try this quick scan sketch:
#include <Wire.h>
void setup() {
Serial.begin(115200);
Wire.begin();
Serial.println("Scanning...");
for (byte i = 1; i < 127; i++) {
Wire.beginTransmission(i);
if (Wire.endTransmission() == 0) {
Serial.print("Found: 0x");
Serial.println(i, HEX);
}
}
}
void loop() {
// Nothing here
}
________________________________________
π Next step (optional)
If you want, I can:
β’ help map your exact SAMD11 pins
β’ or strip this down even further for ultra-low memory use
β’ or show how to draw basic graphics (lines, bars, UI) with SSD1306Ascii
Just tell me π
The code you gave me for the new library gave me an error message (the size of the flash is exceeded).
You've now hit the real hard limit of the SAMD11 π
Even after slimming things down, you're still:
FLASH overflowed by 412 bytes
That's very close β but still too big. At this point, normal libraries (even SSD1306Ascii) are basically at the edge.
________________________________________
β What actually works from here
You have 3 realistic options. I'll give you the best one first.
________________________________________
π₯ BEST SOLUTION β Ultra-minimal OLED driver (no library)
We ditch all libraries and talk directly to the SSD1306 over I2C.
π This will:
β’ Save several KB
β’ Definitely fit on SAMD11
β’ Avoid all SPI / font / overhead issues
________________________________________
β Minimal working code (tiny, fits in flash)
#include <Wire.h>
#define OLED_ADDR 0x3C
void cmd(uint8_t c) {
Wire.beginTransmission(OLED_ADDR);
Wire.write(0x00); // command mode
Wire.write(c);
Wire.endTransmission();
}
void initOLED() {
cmd(0xAE); // display off
cmd(0xA8); cmd(0x3F); // multiplex
cmd(0xD3); cmd(0x00); // offset
cmd(0x40); // start line
cmd(0xA1); // segment remap
cmd(0xC8); // COM scan dec
cmd(0xDA); cmd(0x12);
cmd(0x81); cmd(0x7F);
cmd(0xA4);
cmd(0xA6);
cmd(0xD5); cmd(0x80);
cmd(0x8D); cmd(0x14);
cmd(0xAF); // display ON
}
void clearOLED() {
for (int page = 0; page < 8; page++) {
cmd(0xB0 + page);
cmd(0x00);
cmd(0x10);
Wire.beginTransmission(OLED_ADDR);
Wire.write(0x40); // data mode
for (int i = 0; i < 128; i++) {
Wire.write(0x00);
}
Wire.endTransmission();
}
}
void drawHello() {
// very small "Hello" pattern (hardcoded, saves memory)
const uint8_t text[] = {
0x7F,0x08,0x08,0x08,0x7F, // H
0x00,
0x3E,0x49,0x49,0x49,0x26, // e
0x00,
0x7F,0x40,0x40,0x40,0x40, // l
0x00,
0x7F,0x40,0x40,0x40,0x40, // l
0x00,
0x3E,0x41,0x41,0x41,0x3E // o
};
cmd(0xB3); // page
cmd(0x20); // column low
cmd(0x10); // column high
Wire.beginTransmission(OLED_ADDR);
Wire.write(0x40);
for (unsigned int i = 0; i < sizeof(text); i++) {
Wire.write(text[i]);
}
Wire.endTransmission();
}
void setup() {
Wire.begin();
initOLED();
clearOLED();
drawHello();
}
void loop() {
// Nothing here
}
________________________________________
π‘ Why this works
β’ β No framebuffer
β’ β No fonts
β’ β No external libraries
β’ β Tiny (~2-4 KB total)
π This is exactly what SAMD11 needs.
________________________________________
π₯ Alternative: Free more flash
If you really want to keep SSD1306Ascii:
π§ Remove bootloader
Upload via SWD instead.
π Gains you several KB, which solves everything instantly.
________________________________________
π₯ Last resort tweaks (if you insist on libraries)
β’ Remove Wire debug / Serial
β’ Strip fonts (already did)
β’ Disable features in SSD1306Ascii
β¦but honestly:
π You're already past the practical limit.
________________________________________
π§ Key takeaway
SAMD11 is extremely constrained:
β’ Libraries = luxury
β’ Direct hardware control = reality
________________________________________
π If you want next stepsI can help you:
β’ add a tiny font renderer (still <1KB)
β’ draw shapes / UI
β’ or optimize your entire firmware to fit comfortably
Just tell me π