Random characters on 16x2 lcd when using a motor

Hi there, this is my first time posting on the forum so feel free to let me know if I have done something incorrectly.

I am having a problem that I get random characters showing up on my 16x2 lcd when spinning a motor using an arduino nano controlling a 2n2222 npn transistor.

It is part of a card dealing machine that involves a servo motor turning around a pack of cards and each time it moves, the motor spins for a short time to push the card off the pile. With just the servo motor and the lcd, everything is working fine, the servo is moving and the number of cards dealt is being kept track of on the lcd. But when I add in the normal motor, within a few seconds of it starting to spin, the characters on the lcd just go random and changing.

Here is the code:

#include <LiquidCrystal.h> //include libraries
#include <Servo.h>

Servo servo; //create object to control the servo

const int rs = 9, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; //set up the pins for the lcd
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

const int motor_pin = 12; //motor pin
const int up_button_pin = 6; //set button input pins
const int down_button_pin = 7;
const int ok_button_pin = 8;

int numPiles = 2; //variable for the number of card piles

void setup() {
  lcd.begin(16, 2); //set up lcd

  servo.attach(10); //attaches servo to pin 10

  servo.write(0); //reset servo position

  pinMode(motor_pin, OUTPUT); //set the motor pin as an output
  pinMode(up_button_pin, INPUT); //initialise buttons as inputs
  pinMode(down_button_pin, INPUT);
  pinMode(ok_button_pin, INPUT);

  lcd.print("Card dealer"); //print a message to the lcd
  delay(2000);
  lcd.clear();
}

void loop() {
  lcd.clear();
  lcd.print("How many piles?"); //ask how many piles of cards are needed on the lcd
  lcd.setCursor(0, 1);
  lcd.print(numPiles);

  while (digitalRead(ok_button_pin) == LOW) { //when the ok button is pressed start dealing, until then check for button presses
    if (digitalRead(up_button_pin) == HIGH and numPiles < 10) { //maximum 10 piles
      numPiles++; //when the up button is pressed change the number of piles by 1
      lcd.setCursor(0, 1); //only change the number of piles on the screen so the rest does not need to be written again
      lcd.print(numPiles);
      lcd.print(" ");
      delay(400); //delay so that it only changes the number by 1 for each short button press
    }
    if (digitalRead(down_button_pin) == HIGH and numPiles > 2) { //minimum 2 piles
      numPiles--; //when the down button is pressed change the number of piles by -1
      lcd.setCursor(0, 1); //only change the number of piles on the screen so the rest does not need to be written again
      lcd.print(numPiles);
      lcd.print(" ");
      delay(400); //delay so that it only changes the number by 1 for each short button press
    }
  }

  lcd.clear(); //tell the user that the cards are starting to be dealt
  lcd.setCursor(0, 0);
  lcd.print("dealing ");
  lcd.print(numPiles); //tell the user how many piles are being dealt
  lcd.print(" piles");

  int numCardsDealt = 0;
  int angle = round(180 / numPiles); //calculate the angle that the servo needs to move between each pile
  int i;

  while (numCardsDealt <= 52) { //repeat until the whole pack has been dealt
    servo.write(0);
    for (i = 0; i < 180; i = i + angle) {
      if (numCardsDealt == 53) { //check if all the cards have been dealt or not
        servo.write(0); //if they have, reset the servo position
        lcd.clear();
        lcd.print("done!"); //tell the user it has finished dealing
        delay(2000);
        return; //exit out of the loop and start again
      }
      servo.write(i); //deal a card
      delay(500); //wait for the servo to get there before dealing a card
      analogWrite(motor_pin, 175); //turn on the motor to deal a card at approx 3/4 speed so the card does not fly too far
      lcd.clear();
      delay(200); //wait for the card to be dealt
      analogWrite(motor_pin, 0); //turn off the motor so only 1 card comes out each time
      delay(500);
      numCardsDealt++; //keep track of how many cards have been dealt
      lcd.clear(); //lcd is cleared each time to try and reduce random characters but this didn't really help
      lcd.print("dealing ");
      lcd.print(numPiles); //tell the user how many piles are being dealt
      lcd.print(" piles");
      lcd.setCursor(0, 1);
      lcd.print("Cards dealt: "); //update the user on how many cards have been dealt
      lcd.print(numCardsDealt);
    }
  }
  servo.write(0); //when the dealing is done tell the user it has finished
  lcd.clear();
  lcd.print("done!");
  delay(2000);
}

I have attached the circuit diagram (made with fritzing) and images of the random characters.

Any help with getting rid of these random characters would be much appreciated.

Thanks,

struan

That motor is going to introduce noise into the system. You need a capacitor across the leads of the motor to help absorb the voltage spikes. Try a 0.1uF (100nF) ceramic disc capacitor.

Read this about the servo:

And read this for the motor:

Thank you so much for your help, I don't have a 100nF ceramic capacitor but I do have a 10nF one, will it still work?

10nF will provide some filtering for the motor, but not much. If that is all you have, try three capacitors for maximum filtering. The link in post #3 shows how to connect them.

Best is to have three 100nF capacitors, though. But we try with what we have. :slight_smile: