XY-160D motor driver not communicating with Nano

I'm trying to use a XY-160D motor driver to control a DC motor with encoder. I tested the encoders first and I know they work, but I can't get the Arduino to control the motor through the motor driver. I'm using a Nano 33 IoT. The motor is a JGY-370 12VDC.

For your viewing pleasure, here is a schematic I made of my set up:
Schematic

And the code I'm using:

#include "thingProperties.h"

#define ENCA 2
#define ENCB 3
#define PWM 5
#define IN1 6
#define IN2 10

int pos = 0;

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1000);
  pinMode(ENCA, INPUT);
  pinMode(ENCB, INPUT);
  attachInterrupt(digitalPinToInterrupt(ENCA), readEncoder, RISING);
  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);

  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
  */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
}

void loop() {
  ArduinoCloud.update();
  // Your code here
  setMotor(1,40,PWM,IN1,IN2);
  delay(1000);
  Serial.println(pos);
  Serial.println("TEST1");
  setMotor(-1,40,PWM,IN1,IN2);
  delay(1000);
  Serial.println(pos);
  Serial.println("TEST2");
  setMotor(0,40,PWM,IN1,IN2);
  delay(1000);
  Serial.println(pos);
  Serial.println("TEST3");
}

void setMotor(int dir, int pwmVal, int pwm, int in1, int in2){
  analogWrite(pwm,pwmVal);
  if(dir == 1){
    digitalWrite(in1,HIGH);
    digitalWrite(in2,LOW);
  }
  else if(dir == -1){
    digitalWrite(in1,LOW);
    digitalWrite(in2,HIGH);
  }
  else{
    digitalWrite(in1,LOW);
    digitalWrite(in2,LOW);
  }  
}

void readEncoder() {
  int b = digitalRead(ENCB);
  if (b > 0) {
    pos++;
  }
  else {
    pos--;
  }
}

/*
  Since DoorMotor is READ_WRITE variable, onDoorMotorChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onDoorMotorChange()  {
  // Add your code here to act upon DoorMotor change
}

I found this website that gives a specific example with this motor driver and an Arduino, and I can't see anything obviously wrong with what I'm doing and what they're doing, save for my motor has an encoder and theirs doesn't. That website also shows the complete layout of the driver board. The motor driver is capable of controlling 2 motors, I only have one. I've tried moving both the motor outputs between Motor1 and Motor2 and same with the signal cables, and nothing happens. The motor doesn't receive power at all. I've tried different digital pins (5, 6, and 10 are just the most recent troubleshooting effort) to no avail.

I think it must be an issue with how I've connected things to the driver, but I've triple checked everything and I can't just figure it out. I know my code is running and the function to control the motor is activating, but getting lost somewhere along the line. Any help is appreciated and thanks in advance.

The 5v out of the driver board should NOT be connected to the Vin on the Arduino but to the 5Volt line ! :roll_eyes:

I don't understand, isn't the Vin from the Nano 5V? It's being powered by a USB and the light on the driver is on, so everything seems kosher, no? What do you mean by the 5 volt line?

suggest you investigate the data sheet for details of the power supply requirement paticularly the Nano >>https://docs.arduino.cc/hardware/nano-33-iot

I think you're referring to this:

NOTE: Arduino Nano 33 IoT only supports 3.3V I/Os and is NOT 5V tolerant so please make sure you are not directly
connecting 5V signals to this board or it will be damaged. Also, as opposed to Arduino Nano boards that support 5V
operation, the 5V pin does NOT supply voltage but is rather connected, through a jumper, to the USB power input.

I think you're saying I need to have the 5V from the motor driver going to +5V on the Arduino, which requires the jumper to be bridged on the back? Instead of having it come from Vin. I'm still confused on why Vin lit up the LED though, indicating it had power

yes the Vin+ pin is for supply input , it does not supply Output unless you bridge the USB to it. then you must power the system thru the USB either with a computer USB or a 5Volt USB type charger / power supply.

I think you should have logic-level shifters between the Nano and the driver module, as the Nan033-IoT is not tolerant to 5Volt levels.

This weekend I'll solder the jumper and rewire as you suggest and give it another try (pending other options that may arise).

The data sheet for the motor driver says it can be powered with 5V or 3.3V. Could I maybe power the encoders and the motor driver with 3.3 at the same time and not even touch 5V?

If I do power the motor driver control circuit with 5V, how do I know it's sending signal back to the Nano at a dangerous 5V? Could it be throttled to 3.3V baked into the circuit because that's the lowest that it needs?

Yeah, that would work, feed the driver board 3.3V instead of 5V .
you'd have to check the data sheet to ensure the Nano Vreg can supply enough current , the optocouplers shouldn't draw excess especially at the lower voltage. Good luck. :neutral_face:

Thank you, I'll give it a go. The data sheet for the motor driver doesn't mention what current it needs, just a ceiling. So I'll just try it with 3.3V and if it works it works, if not I'll use the 5V on the Arduino and get a logic level shifter between them.

I connected the 3.3V and still can't get it to work. The power indicative LEDs on the motor driver and the encoders are on, so both are getting power. The program runs and doesn't turn the motor at all. Here is the updated schematic:

Screenshot 2022-02-06 162104

I haven't touched the code as far as the motor control, but I did test some other aspects. So even though I didn't change any code for this aspect, I'll still post the most recent because it's what I did the most recent test with.



#include "thingProperties.h"

#define ENCA 2
#define ENCB 3
#define PWM 5
#define IN1 6
#define IN2 10

int pos = 0;

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1000);
  pinMode(ENCA, INPUT);
  pinMode(ENCB, INPUT);
  attachInterrupt(digitalPinToInterrupt(ENCA), readEncoder, RISING);
  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);

  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
  */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
}

void loop() {
  ArduinoCloud.update();
  // Your code here
  
//This uses the scheduler to turn the LED on at a set time and duration every day. Use to toggle the door open
//and close every day at a specific time.
  
//   if(schedule_variable.isActive()){
// digitalWrite(LED_BUILTIN, HIGH);
// }
// // whenever the job is "not active", turn off the LED
// else{
// digitalWrite(LED_BUILTIN, LOW);  
// }

//Tests the motor door toggle variable, turns LED on and off when the slider is on and off.
  /*if(door_Motor){
  Serial.println("Motor True");
  digitalWrite(LED_BUILTIN, HIGH);
  } else {
   digitalWrite(LED_BUILTIN, LOW);
   Serial.println("Motor False");
  }*/
  
  setMotor(1,40,PWM,IN1,IN2);
  delay(1000);
  Serial.println(pos);
  Serial.println("TEST1");
  setMotor(-1,40,PWM,IN1,IN2);
  delay(1000);
  Serial.println(pos);
  Serial.println("TEST2");
  setMotor(0,40,PWM,IN1,IN2);
  delay(1000);
  Serial.println(pos);
  Serial.println("TEST3");
}

void setMotor(int dir, int pwmVal, int pwm, int in1, int in2){
  analogWrite(pwm,pwmVal);
  if(dir == 1){
    digitalWrite(in1,HIGH);
    digitalWrite(in2,LOW);
  }
  else if(dir == -1){
    digitalWrite(in1,LOW);
    digitalWrite(in2,HIGH);
  }
  else{
    digitalWrite(in1,LOW);
    digitalWrite(in2,LOW);
  }  
}

void readEncoder() {
  int b = digitalRead(ENCB);
  if (b > 0) {
    pos++;
  }
  else {
    pos--;
  }
}



/*
  Since DoorMotor is READ_WRITE variable, onDoorMotorChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onDoorMotorChange()  {
  // Add your code here to act upon DoorMotor change
}


/*
  Since ScheduleVariable is READ_WRITE variable, onScheduleVariableChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onScheduleVariableChange()  {
  // Add your code here to act upon ScheduleVariable change
}

Any help would be appreciated

Well oil beef h****d
I've had a look at the circuits etc etc and nothing is glaringly obvious.
Do you have a multi-meter ?? to check a few voltages.
I would be inclined to temporarily disconnect the motor and encoder and use a 12Volt lamp across the motor driver outputs (as a load) .
Run a minimal code to test the driver operation initially and the progress from there . Try this modified test code:`[code]

/*==========================================================================
//  Author      : Handson Technology
//  Project     : Arduino Uno with H-Bride 7A Motor Driver
//  Description : XY160D 7A high Power H-Bridge motor Driver Module
//  Source-Code : H-Bride-7A-Motor-CTR.ino
//  Program: Control 2 DC motors using L298N H Bridge Driver
//==========================================================================

  ******************modified 7/2/2022 for test purposes  *****************
*/

const byte IN1 = 6;  // these to match pin #'s  provided on circuit
const byte IN2 = 10;
const byte ENA = 5;
/*
const int IN3=8;
const int IN4=7;
   const int ENB=9;
*/
void setup()
{
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(ENA, OUTPUT);
  /*
  pinMode(IN4, OUTPUT);
  pinMode(IN3, OUTPUT);
   pinMode(ENB, OUTPUT);
    */
}

void loop() {
  Motor1_Brake();
  // Motor2_Brake();
  delay(100);
  Motor1_Forward(200);
  // Motor2_Forward(200);
  delay(1000);
  Motor1_Brake();
  // Motor2_Brake();
  delay(100);
  Motor1_Backward(200);
  // Motor2_Backward(200);
  delay(1000);
}

void Motor1_Forward(int Speed)
{
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  analogWrite(ENA, Speed);
}

void Motor1_Backward(int Speed)
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  analogWrite(ENA, Speed);
}
void Motor1_Brake()
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
}
/*
void Motor2_Forward(int Speed)
{
     digitalWrite(IN3,HIGH);
     digitalWrite(IN4,LOW);
     analogWrite(ENB,Speed);
}

void Motor2_Backward(int Speed)
{
     digitalWrite(IN3,LOW);
     digitalWrite(IN4,HIGH);
     analogWrite(ENB,Speed);
}
void Motor2_Brake()
{
     digitalWrite(IN3,LOW);
     digitalWrite(IN4,LOW);
}
*/

[/code]`

I do have a multimeter, I can try that test this weekend.

However, I am also tempted to just buy another board?

This is the board used in the example video so I can't screw it up, it's all on video and it's pretty cheap.

Personally I don't see the point , however Pololu are well regarded and there are advantages in their boards ( they also have a single for 1.8-5v logic level control) . unsure of the example video referred to .
Good luck , I would try with a simple control code to establish a controllable setup before expanding to the IoT codes . :thinking:

Did you get this working? I've recently used that motor controller successfully with an Arduino Due. Its output pins are 3.3v so I had to run 3.3v to the +5v pin on the XY-160D or it wouldn't work. The Nano output pins are 5V so you shouldn't have that problem.

That said, I think you should check the following things:

  1. I don't see anywhere in your code where you set the IN1, IN2, and ENA1 pins to output mode. If you don't do that, digitalwrite won't push power to those pins. Make it's in your "thingProperties.h" but without seeing that who knows.
  2. Don't use the PWM function at first. Just write a 1 to the ENA1 pin.
  3. Get a multimeter. Check that ENA1 is 5V, 5V on the 5V pin, 0 on the ground pin, 5V on IN1, 0 on IN2 (or vice versa for those two).
  4. If the values were right on 3, continue with your multimeter. Check the +12 in and ground in on the motor power lines. Check the output motor lines.
  5. If you're showing power on the motor output lines, try a different motor.

This is a pretty solid driver I think. I have it running a solar tracker with a good size motor on it and no problems.