Hello
this is the product we need help with
https://www.adafruit.com/product/4416
We are using the Arduino code given in the GitHub link in the description on the product page (this: https://github.com/adafruit/Adafruit_Mo ... erMotorRPM) to output the rpm of the dc motor with encoder in the serial monitor. Everything is hooked up correctly but after uploading the code in the serial monitor it says "Direction: forward @ 0 RPM" continuously even when the motor is spinning and is going backwards. The motor is rotating fine and is following the code. We have the motor's yellow wire in M1, the brown wire in the gnd next to M1, the red wire in 5v, the black wire in gnd next to the red wire, the white wire in pin 11 and the green wire in pin 12 as the code calls for. Please help and we can answer questions. Note that we are only trying to output rpm in the serial monitor, not on an lcd display or anything like that.
Thanks :D
dc motor with encoder - example code not working
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- weatherballoon2023
- Posts: 10
- Joined: Wed Mar 08, 2023 1:33 pm
- dastels
- Posts: 15662
- Joined: Tue Oct 20, 2015 3:22 pm
Re: dc motor with encoder - example code not working
It sounds like it should work. I did that myself. What are you running it on? Can you post the actual code you are running?
Dave
Dave
- weatherballoon2023
- Posts: 10
- Joined: Wed Mar 08, 2023 1:33 pm
Re: dc motor with encoder - example code not working
We are using an Arduino Uno. We are using the exact code given on the link on the product page:
Thanks for your reply and let us know if you need more answers to your questions!
Code: Select all
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <Adafruit_SSD1306.h>
// Connect to the two encoder outputs!
#define ENCODER_A 12
#define ENCODER_B 11
// These let us convert ticks-to-RPM
#define GEARING 20
#define ENCODERMULT 12
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// And connect a DC motor to port M1
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
// We'll display the speed/direction on the OLED
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &Wire);
volatile float RPM = 0;
volatile uint32_t lastA = 0;
volatile bool motordir = FORWARD;
void interruptA() {
motordir = digitalRead(ENCODER_B);
digitalWrite(LED_BUILTIN, HIGH);
uint32_t currA = micros();
if (lastA < currA) {
// did not wrap around
float rev = currA - lastA; // us
rev = 1.0 / rev; // rev per us
rev *= 1000000; // rev per sec
rev *= 60; // rev per min
rev /= GEARING; // account for gear ratio
rev /= ENCODERMULT; // account for multiple ticks per rotation
RPM = rev;
}
lastA = currA;
digitalWrite(LED_BUILTIN, LOW);
}
void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
pinMode(ENCODER_B, INPUT_PULLUP);
pinMode(ENCODER_A, INPUT_PULLUP);
attachInterrupt(ENCODER_A, interruptA, RISING);
delay(100);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
display.display();
display.setTextSize(2);
display.setTextColor(WHITE);
//while (!Serial) delay(1);
Serial.println("MMMMotor party!");
if (!AFMS.begin()) { // create with the default frequency 1.6KHz
// if (!AFMS.begin(1000)) { // OR with a different frequency, say 1KHz
Serial.println("Could not find Motor Shield. Check wiring.");
while (1);
}
Serial.println("Motor Shield found."); Serial.println("Begun");
// turn on motor M1
myMotor->setSpeed(0);
}
void printRPM() {
display.clearDisplay();
display.setCursor(0,0);
Serial.print("Direction: ");
if (motordir) {
display.println("Forward");
Serial.println("forward @ ");
} else {
display.println("Backward");
Serial.println("backward @ ");
}
display.print((int)RPM); display.println(" RPM");
Serial.print((int)RPM); Serial.println(" RPM");
display.display();
}
int i;
void loop() {
delay(50);
myMotor->run(FORWARD);
for (i=0; i<255; i++) {
myMotor->setSpeed(i);
delay(20);
printRPM();
}
for (i=255; i!=0; i--) {
myMotor->setSpeed(i);
delay(20);
printRPM();
}
myMotor->run(BACKWARD);
for (i=0; i<255; i++) {
myMotor->setSpeed(i);
delay(20);
printRPM();
}
for (i=255; i!=0; i--) {
myMotor->setSpeed(i);
delay(20);
printRPM();
}
}
Last edited by dastels on Thu Mar 09, 2023 3:44 pm, edited 1 time in total.
Reason: Add code tags
Reason: Add code tags
- dastels
- Posts: 15662
- Joined: Tue Oct 20, 2015 3:22 pm
Re: dc motor with encoder - example code not working
You said you weren't outputting to a screen. This code outputs to serial as well as a screen.
Dave
Dave
- weatherballoon2023
- Posts: 10
- Joined: Wed Mar 08, 2023 1:33 pm
Re: dc motor with encoder - example code not working
Yes, the goal is to output rpm of the motor in the serial monitor. When we open up the serial monitor after uploading the code, the code does not detect any "setting up" problems (the code states:
Serial.println("MMMMotor party!");
if (!AFMS.begin()) { // create with the default frequency 1.6KHz
// if (!AFMS.begin(1000)) { // OR with a different frequency, say 1KHz
Serial.println("Could not find Motor Shield. Check wiring.");
while (1);
}
Serial.println("Motor Shield found."); Serial.println("Begun");
// turn on motor M1
myMotor->setSpeed(0);
}
"MMMMotor party!", "Motor Shield found." and "Begun" output in the serial monitor, therefore the serial monitor is outputting what the code says and the motor shield is detected, and the motor turns on as the code says) and once we get past this first part of the code with everything so far running properly, although everything is wired correctly (we assume, it seems we have everything right!) once we get to the part of the code that has the encoder data (rpm) outputted to the serial monitor, incorrect rpm values are shown in the serial monitor. There are not even numbers other than 0 rpm! It consistently says in the serial monitor "Direction: forward @ 0 RPM". It does not even say backwards when the motor is spinning backwards.
Is this a problem that the code outputs to 2 places? Do we need to change something in the code so that it only outputs rpm to the serial monitor?
Thanks as always for helping!
Serial.println("MMMMotor party!");
if (!AFMS.begin()) { // create with the default frequency 1.6KHz
// if (!AFMS.begin(1000)) { // OR with a different frequency, say 1KHz
Serial.println("Could not find Motor Shield. Check wiring.");
while (1);
}
Serial.println("Motor Shield found."); Serial.println("Begun");
// turn on motor M1
myMotor->setSpeed(0);
}
"MMMMotor party!", "Motor Shield found." and "Begun" output in the serial monitor, therefore the serial monitor is outputting what the code says and the motor shield is detected, and the motor turns on as the code says) and once we get past this first part of the code with everything so far running properly, although everything is wired correctly (we assume, it seems we have everything right!) once we get to the part of the code that has the encoder data (rpm) outputted to the serial monitor, incorrect rpm values are shown in the serial monitor. There are not even numbers other than 0 rpm! It consistently says in the serial monitor "Direction: forward @ 0 RPM". It does not even say backwards when the motor is spinning backwards.
Is this a problem that the code outputs to 2 places? Do we need to change something in the code so that it only outputs rpm to the serial monitor?
Thanks as always for helping!
- dastels
- Posts: 15662
- Joined: Tue Oct 20, 2015 3:22 pm
Re: dc motor with encoder - example code not working
I'm still confused. Do you have a display connected? I don't think that would cause bad data, though.
it sounds like the interrupt routine isn't running. Is the onboard LED (the #13 LED) flashing when the code's running?
Dave
it sounds like the interrupt routine isn't running. Is the onboard LED (the #13 LED) flashing when the code's running?
Dave
- weatherballoon2023
- Posts: 10
- Joined: Wed Mar 08, 2023 1:33 pm
Re: dc motor with encoder - example code not working
Sorry for the confusion! No display is connected.
I believe the light flashes, but I do not know for sure. I am not able to tell you right now as I do not have access to the project right now. I can tell you tomorrow!
Thanks!
I believe the light flashes, but I do not know for sure. I am not able to tell you right now as I do not have access to the project right now. I can tell you tomorrow!
Thanks!
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: dc motor with encoder - example code not working
We are using an Arduino Uno.
Code: Select all
// Connect to the two encoder outputs!
#define ENCODER_A 12
#define ENCODER_B 11
- weatherballoon2023
- Posts: 10
- Joined: Wed Mar 08, 2023 1:33 pm
Re: dc motor with encoder - example code not working
Thank you so much! Will this issue simply be fixed by deleting the 11 and 12 and replacing it with 2 and 3? I will test tomorrow!
- dastels
- Posts: 15662
- Joined: Tue Oct 20, 2015 3:22 pm
Re: dc motor with encoder - example code not working
You should just need to change the pin that is used for the interrupt (12).
Dave
Dave
- weatherballoon2023
- Posts: 10
- Joined: Wed Mar 08, 2023 1:33 pm
Re: dc motor with encoder - example code not working
That changing the ports didn't work. Could it be something wrong with the encoder itself?
- weatherballoon2023
- Posts: 10
- Joined: Wed Mar 08, 2023 1:33 pm
Re: dc motor with encoder - example code not working
The onboard led is on but it is not blinking
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: dc motor with encoder - example code not working
Did you use the digitalPinToInterrupt function to convert the pin number to the corresponding interrupt number (On Atmega328 processors, they are not the same number).
https://reference.arduino.cc/reference/ ... interrupt/
https://reference.arduino.cc/reference/ ... interrupt/
Normally you should use digitalPinToInterrupt(pin) to translate the actual digital pin to the specific interrupt number. For example, if you connect to pin 3, use digitalPinToInterrupt(3) as the first parameter to attachInterrupt().
- weatherballoon2023
- Posts: 10
- Joined: Wed Mar 08, 2023 1:33 pm
Re: dc motor with encoder - example code not working
Please tell us exactly how to fix it in very simple language
thanks
or if you can just write the code that would be great but write it fast because we need like in 10 minutes max
thanks
or if you can just write the code that would be great but write it fast because we need like in 10 minutes max
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: dc motor with encoder - example code not working
Change:
To:
Code: Select all
attachInterrupt(ENCODER_A, interruptA, RISING)
Code: Select all
attachInterrupt(digitalPinToInterrupt(ENCODER_A), interruptA, RISING)
Please be positive and constructive with your questions and comments.