dc motor with encoder - example code not working

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
weatherballoon2023
 
Posts: 10
Joined: Wed Mar 08, 2023 1:33 pm

dc motor with encoder - example code not working

Post by weatherballoon2023 »

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

User avatar
dastels
 
Posts: 15659
Joined: Tue Oct 20, 2015 3:22 pm

Re: dc motor with encoder - example code not working

Post by dastels »

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

User avatar
weatherballoon2023
 
Posts: 10
Joined: Wed Mar 08, 2023 1:33 pm

Re: dc motor with encoder - example code not working

Post by weatherballoon2023 »

We are using an Arduino Uno. We are using the exact code given on the link on the product page:

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();
  }
}
Thanks for your reply and let us know if you need more answers to your questions!
Last edited by dastels on Thu Mar 09, 2023 3:44 pm, edited 1 time in total.
Reason: Add code tags

User avatar
dastels
 
Posts: 15659
Joined: Tue Oct 20, 2015 3:22 pm

Re: dc motor with encoder - example code not working

Post by dastels »

You said you weren't outputting to a screen. This code outputs to serial as well as a screen.

Dave

User avatar
weatherballoon2023
 
Posts: 10
Joined: Wed Mar 08, 2023 1:33 pm

Re: dc motor with encoder - example code not working

Post by weatherballoon2023 »

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!

User avatar
dastels
 
Posts: 15659
Joined: Tue Oct 20, 2015 3:22 pm

Re: dc motor with encoder - example code not working

Post by dastels »

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

User avatar
weatherballoon2023
 
Posts: 10
Joined: Wed Mar 08, 2023 1:33 pm

Re: dc motor with encoder - example code not working

Post by weatherballoon2023 »

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!

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: dc motor with encoder - example code not working

Post by adafruit_support_bill »

We are using an Arduino Uno.

Code: Select all

// Connect to the two encoder outputs!
#define ENCODER_A   12
#define ENCODER_B   11
Using an UNO, you will not be able to get interrupts on those pins. Pins 2 and 3 are the only interrupt pins available on Atmega-328-based boards like the UNO: https://reference.arduino.cc/reference/ ... interrupt/

User avatar
weatherballoon2023
 
Posts: 10
Joined: Wed Mar 08, 2023 1:33 pm

Re: dc motor with encoder - example code not working

Post by weatherballoon2023 »

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!

User avatar
dastels
 
Posts: 15659
Joined: Tue Oct 20, 2015 3:22 pm

Re: dc motor with encoder - example code not working

Post by dastels »

You should just need to change the pin that is used for the interrupt (12).

Dave

User avatar
weatherballoon2023
 
Posts: 10
Joined: Wed Mar 08, 2023 1:33 pm

Re: dc motor with encoder - example code not working

Post by weatherballoon2023 »

That changing the ports didn't work. Could it be something wrong with the encoder itself?

User avatar
weatherballoon2023
 
Posts: 10
Joined: Wed Mar 08, 2023 1:33 pm

Re: dc motor with encoder - example code not working

Post by weatherballoon2023 »

The onboard led is on but it is not blinking

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: dc motor with encoder - example code not working

Post by adafruit_support_bill »

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/
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().

User avatar
weatherballoon2023
 
Posts: 10
Joined: Wed Mar 08, 2023 1:33 pm

Re: dc motor with encoder - example code not working

Post by weatherballoon2023 »

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

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: dc motor with encoder - example code not working

Post by adafruit_support_bill »

Change:

Code: Select all

attachInterrupt(ENCODER_A, interruptA, RISING)
To:

Code: Select all

attachInterrupt(digitalPinToInterrupt(ENCODER_A), interruptA, RISING)

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”