Motor control with TA8428K

Hi all.

I'm a teacher learning to program I have watched some great videos on Youtube and done a few projects involving LEDs and small motors.

Last week my son challenged me to use and arduino to get his old radio shack RC truck going again.

I plan to use an HC-06 bluetooth adapter for now. Probably it will have a shorter range than is desirable, but it will work for the purpose.

I have been able to use the HC-06 to control the car using relays for controlling forward and backward motion, but with the power and speed this thing has On/Off control is not good enough.

I replaced the six wire servo with a regular servo and I think I have figured out how to do the steering but haven't put that into the sketch yet.

I found a brushed motor controller TA8428K.

I have done a lot of reading and watching motor control videos but can't find instructions for this particular controller. It it is missing the "enable" pin that every other one has.

I used instructions from this lesson and this lesson to try and patch together a sketch that would work.

I thought I was doing ok editing the code until I got to the very last row. This row says I have to use the enable pin to control motor speeds. I was hoping to use an analog input on pins 1&2 to control speed and rotation of the motor, pretty much like a transistor would.

Can anybody tell me if I'm on the right track with this or if I'm completely out of it here. I'm here to learn so anything goes.

I took out all reference to motor B and to the enable pins because my controller does not have them. I got hung up on the last one on the last sentence. Don't know what to do with it.

/*  
 
 
 DroneBot Workshop 2017
 http://dronebotworkshop.com
*/
 // Edited by Jonathan Waldner on Nov.2017 for a relay and a TA8428 Motor driver.
 
// Motor A

int in1 = 8;
int in2 = 7;

char BluetoothData; // the Bluetooth data received 



// Joystick Input

int joyVert = A0; // Vertical  

// Motor Speed Values - Start at zero

int MotorSpeed1 = 0;

// Joystick Values - Start at 512 (middle position)

int joyposVert = 50;


void setup()

{
 Serial.begin(9600);   // Start Serial Monitor
 

 // Set all the motor control pins to outputs

 pinMode(in1, OUTPUT);
 pinMode(in2, OUTPUT);

  
 // Start with motors disabled and direction forward
 
 // Motor A
 
 digitalWrite(in1, HIGH);
 digitalWrite(in2, LOW);
 

}

void loop() {

 if (Serial.available()){
 
 {
   BluetoothData=Serial.read(joyVert); //Get Joystick Vertical position from bluetooth
 }


 // Determine if this is a forward or backward motion
 // Do this by reading the Verticle Value
 // Apply results to MotorSpeed and to Direction

 if (joyposVert < 50)
 {
   // This is Backward

   // Set Motor A backward

   digitalWrite(in1, LOW);
   digitalWrite(in2, HIGH);

  
   //Determine Motor Speeds

   // As we are going backwards we need to reverse readings

   joyposVert = joyposVert - 50; // This produces a negative number
   joyposVert = joyposVert * -1;  // Make the number positive

   MotorSpeed1 = map(joyposVert, 0, 50, 0, 100);

 }
 else if (joyposVert > 50)
 {
   // This is Forward

   // Set Motor A forward

   digitalWrite(in1, HIGH);
   digitalWrite(in2, LOW);

 

   //Determine Motor Speed

   MotorSpeed1 = map(joyposVert, 52, 100, 0, 48);

 }
 else
 {
   // This is Stopped

   MotorSpeed1 = 0;

 }
 
 


 // Adjust to prevent "buzzing" at very low speed
 {

 if (MotorSpeed1 < 8)MotorSpeed1 = 0;

 // Set the motor speeds

 analogWrite(enA, MotorSpeed1);

}[code]

[/code]

To make it easier for people to help you please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum

Your code is too long to make sense of as it is.

I have used the TA8428K in some model train controllers. It needs a PWM signal on one pin for FWD and on the other pin for REV. For that reason it may be different from the examples you have been looking at. For example the L298 is often controlled by applying PWM to the enable pin and using IN1 an IN2 for direction.

...R

Robin2:
To make it easier for people to help you please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum

Your code is too long to make sense of as it is.

I have used the TA8428K in some model train controllers. It needs a PWM signal on one pin for FWD and on the other pin for REV. For that reason it may be different from the examples you have been looking at. For example the L298 is often controlled by applying PWM to the enable pin and using IN1 an IN2 for direction.

...R

Ok. Thanks I edited my first post to reflect the code. I tried going back to edit it right after I posted it but the forum will only allow me to make one post every five minutes. It's a bit of a pain right now.

Ok so if I need PWM for on both those pins, then code will be very different. I will look for examples and see if I can put something together.

Thanks for updating the code. However your program is not complete and I am not sure what it missing.

It looks to me like this

 if (Serial.available()){
 {
   BluetoothData=Serial.read(joyVert); //Get Joystick Vertical position from bluetooth
 }

should be

 if (Serial.available()){
     BluetoothData=Serial.read(joyVert); //Get Joystick Vertical position from bluetooth
 }

i.e. one less {

But that is not the only problem.

In any case, to control the TA8428K you need something like this

if (direction == 'F') {
	analogWrite(motorPinA, 0);
	analogWrite(motorPinB, motorSpeed);
}
else {
	analogWrite(motorPinB, 0);
	analogWrite(motorPinA, motorSpeed);
}

Note that it turns off one pin before turning on the other. I can't recall if the chip would be damaged by turning on both at the same time.

...R

Robin2:
Thanks for updating the code. However your program is not complete and I am not sure what it missing.

It looks to me like this

 if (Serial.available()){

{
  BluetoothData=Serial.read(joyVert); //Get Joystick Vertical position from bluetooth
}



should be


if (Serial.available()){
    BluetoothData=Serial.read(joyVert); //Get Joystick Vertical position from bluetooth
}



i.e. one less {

But that is not the only problem.

In any case, to control the TA8428K you need something like this


if (direction == 'F') {
analogWrite(motorPinA, 0);
analogWrite(motorPinB, motorSpeed);
}
else {
analogWrite(motorPinB, 0);
analogWrite(motorPinA, motorSpeed);
}




Note that it turns off one pin before turning on the other. I can't recall if the chip would be damaged by turning on both at the same time.

...R

Can you explain how to get the direction 'F' ? Please?

These seem to be the relevant bits of code

 if (joyposVert < 50)
 {
   // This is Backward
 // ........
 }
 else if (joyposVert > 50)
 {
   // This is Forward

...R

Yes I got that part, but you put an F into the code and it seemed to be recognized as a command it turned blue) why is that? Is it a standard thing that is built in? Or do I need to translate for arduino somehow? I have been reading through a bunch of tutorials and will continue to do so. If you know of one that covers this let me know please.

Jonathan

When I try to compile, it gives me an error at this line:

   BluetoothData=Serial.read(joyposVert); //Get Joystick Vertical position from bluetooth

/ta8428k_Relayathan.ino: In function 'void loop()':
ta8428k_Relayathan:64: error: no matching function for call to 'HardwareSerial::read(int&)'
BluetoothData=Serial.read(joyposVert); //Get Joystick Vertical position from bluetooth.

Right now my code looks like this:

int in1 = 10;   //Reverse motor
int in2 = 11;   //Forward Motor
int tx=1;       //Bluetooth TX
int rx=0;       //Bluetooth RX


char BluetoothData; // the Bluetooth data received 



// Joystick Input

int joyVert = A0; // Vertical  

// Motor Speed Values - Start at zero

int MotorSpeed1 = 0;

// Joystick Values - Start at 512 (middle position)

int joyposVert = 50;    //Digital joystick goes from 0-100. 50 is center


void setup()

{
  Serial.begin(9600);   // Start Serial Monitor
  

  // Set all the motor control pins to outputs

  pinMode(in1, OUTPUT);     //Turns revere motor pin into output
  pinMode(in2, OUTPUT);     //Turns forward motor pin into output
  pinMode( tx, OUTPUT);     //TX for Bluetooth
  pinMode(rx, INPUT);       //RX for Bluetooth
  
 
   
  // Start with motors disabled and direction forward
  
  // Motor A
  
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  
 
}

void loop() {

  if (Serial.available()){
    BluetoothData=Serial.read(joyposVert); //Get Joystick Vertical position from bluetooth
  }


  // Determine if this is a forward or backward motion
  // Do this by reading the Verticle Value
  // Apply results to MotorSpeed and to Direction
  {
  if (joyposVert < 50)
  {
    // This is Backward

    // Set Motor A backward
    
if (direction == 'F') {
  analogWrite(motorPinA, 0);
  analogWrite(motorPinB, motorSpeed);
}
else {
  analogWrite(motorPinB, 0);
  analogWrite(motorPinA, motorSpeed);
}
    //Determine Motor Speeds

    // As we are going backwards we need to reverse readings

    joyposVert = joyposVert - 50; // This produces a negative number
    joyposVert = joyposVert * -1;  // Make the number positive

    MotorSpeed1 = map(joyposVert, 0, 50, 0, 100);

  }
  else if (joyposVert > 50)
  {
    // This is Forward

    // Set Motor A forward

   

    analogWrite(in1, MotorSpeed1);  // added for PWM motor controler. 

    //Determine Motor Speed

    MotorSpeed1 = map(joyposVert, 52, 100, 0, 48);

  }
  else
  {
    // This is Stopped

    MotorSpeed1 = 0;

  }
  
  


  // Adjust to prevent "buzzing" at very low speed
  {

  if (MotorSpeed1 < 8)MotorSpeed1 = 0;

  // Set the motor speeds



}

jonawadl:
Yes I got that part, but you put an F into the code and it seemed to be recognized as a command it turned blue) why is that?

Ignore the colour.

Have you created a variable called "direction"?

What I had in mind was that you would do something like this

if (joyposVert < 50)
 {
   // This is Backward
   direction = 'R';
 // ........
 }
 else if (joyposVert > 50)
 {
   // This is Forward
   direction = 'F';

...R

Ok I was able to make some progress, I think, but I still have errors that won't go away. It keeps telling me direction was not declared in the scope.

/*  
  L298N Motor Control Demonstration with Joystick
  L298N-Motor-Control-Demo-Joystick.ino
  Demonstrates use of Joystick control with Arduino and L298N Motor Controller
  
  DroneBot Workshop 2017
  http://dronebotworkshop.com
*/
  // Edited and modified by Jonathan Waldner on Nov.2017 for a relay and a TA8428 Motor driver.
  
// Motor A

int R = 10;   //Reverse motor
int F = 11;   //Forward Motor
int tx=1;       //Bluetooth TX
int rx=0;       //Bluetooth RX


char BluetoothData; // the Bluetooth data received 



// Joystick Input

int joyVert = A0; // Vertical  

// Motor Speed Values - Start at zero

int MotorSpeed1 = 0;

// Joystick Values - Start at 512 (middle position)

int joyposVert = 50;    //Digital joystick goes from 0-100. 50 is center


void setup(){


  Serial.begin(9600);   // Start Serial Monitor
  

  // Set all the motor control pins to outputs

  pinMode(R, OUTPUT);     //Turns revere motor pin into output
  pinMode(F, OUTPUT);     //Turns forward motor pin into output
  pinMode(tx, OUTPUT);     //TX for Bluetooth
  pinMode(rx, INPUT);       //RX for Bluetooth
  
 
   
  // Start with motors disabled and direction forward
  
  // Motor A
  
  digitalWrite(F, HIGH);
  digitalWrite(R, LOW);
  
 
}

void loop() {

  if (Serial.available()){
    BluetoothData=Serial.read(); //Get Joystick Vertical position from bluetooth
  }


  // Determine if this is a forward or backward motion
  // Do this by reading the Verticle Value
  // Apply results to MotorSpeed and to Direction
  

if (joyposVert < 50)
 
   // This is Backward
   direction = 'R';
 // ........
 }
 else if (joyposVert > 50)
 {
   // This is Forward
   direction = 'F';

}
    //Determine Motor Speeds

    // As we are going backwards we need to reverse readings

    joyposVert = joyposVert - 50; // This produces a negative number
    joyposVert = joyposVert * -1;  // Make the number positive

    MotorSpeed1 = map(joyposVert, 0, 50, 0, 100);

  
    //Determine Motor Speed

    MotorSpeed1 = map(joyposVert, 52, 100, 0, 48);

  }
  else
  {
    // This is Stopped

    MotorSpeed1 = 0;

  }
  
  


  // Adjust to prevent "buzzing" at very low speed
  {

  if (MotorSpeed1 < 8)MotorSpeed1 = 0;

  // Set the motor speeds



}

The list of errors I have now is here.

/Users/jonathanawaldner/Documents/Arduino/ta8428k_Relayathan/ta8428k_Relayathan.ino: In function 'void loop()':
ta8428k_Relayathan:76: error: 'direction' was not declared in this scope
direction = 'R';
^
/Users/jonathanawaldner/Documents/Arduino/ta8428k_Relayathan/ta8428k_Relayathan.ino: At global scope:
ta8428k_Relayathan:79: error: expected unqualified-id before 'else'
else if (joyposVert > 50)
^
ta8428k_Relayathan:89: error: 'joyposVert' does not name a type
joyposVert = joyposVert - 50; // This produces a negative number
^
ta8428k_Relayathan:90: error: 'joyposVert' does not name a type
joyposVert = joyposVert * -1; // Make the number positive
^
ta8428k_Relayathan:92: error: 'MotorSpeed1' does not name a type
MotorSpeed1 = map(joyposVert, 0, 50, 0, 100);
^
ta8428k_Relayathan:97: error: 'MotorSpeed1' does not name a type
MotorSpeed1 = map(joyposVert, 52, 100, 0, 48);
^
ta8428k_Relayathan:99: error: expected declaration before '}' token
}
^
exit status 1
'direction' was not declared in this scope

That first error. Direction was not declared in this scope confuses me.

How do I declare it? i thought it might be looking for which pin to lift for R and F but that evidently is not it.

C/C++ requires the type of every variable to be defined before the variable can be used. That's why these lines are at the top of your program

int R = 10;   //Reverse motor
int F = 11;   //Forward Motor
int tx=1;       //Bluetooth TX
int rx=0;       //Bluetooth RX


char BluetoothData; // the Bluetooth data received

You need to add a line

char direction;

or

char direction = 'F';

if you want to initialize the variable with the value 'F'

You are missing a { at the end of this line

if (joyposVert < 50)

to define the group of lines of code that the IF applies to

It would probably be a good idea to have a look at a beginners tutorial on C/C++. Teachers should always be a few pages further on in the text book than the students :slight_smile:

...R

It would probably be a good idea to have a look at a beginners tutorial on C/C++. Teachers should always be a few pages further on in the text book than the students :slight_smile:

...R

Oh, I know that all right. That's why I'm doing this now instead of after Christmas when I need to teach it. :).

I have read about designating characters. But the way you present it here leaves me with a question.

If I can say:

char direction;

and I can say

char direction = 'F';

In the first case I have a direction but no character behind it. Would I not still need to make another statement about 'F' and 'R'. I'll read that section again in the android tutorial. Excuse me for using this space to post my thoughts but I need to air them to give you a chance to correct the errors in my thoughts.

jonawadl:
Would I not still need to make another statement about 'F' and 'R'.

Yes.

But the initial value might be set somewhere else - perhaps after you have checked an input switch. For example you may not know when writing the program whether the motor will be starting in Forward or Reverse.

I don't mean to sound unkind but Christmas is very very close. Starting the course at Easter would give you more chance to get on top of the subject. Expect some of the kids in class to know as much as you about it (even if you defer until Easter) and to pose hard, but sensible questions.

The other challenge you will face is being asked to debug silly mistakes (or not-so-silly mistakes) in the students' programs "Hey mister, it don't work" and that requires a lot of familiarity with programming.

...R

That is fair. What I am teaching will not fall directly after Christmas either way and it will be one small program for a specific purpose. Mostly our focus will be on a specific set of code. Our school will be participating in a small local robot games. Some have expressed interest in going wireless for the sumo challenges. We have one student who programmed a line follower last year so I will be working together with him. It's a small group of about 6-8 students depending on interest level.

So not a full blown course a little workshop to get their bot going. I know that's gonna be challenging enough though. That's why I'm on it.

Sounds like fun.

...R

Ok. I did some reading and work on this on my own. I have the errors down to some unqualified-id before else issues. I think it's got something to do with { missing, but I can't find it. Can somebody help me spot this?

My code looks like this now. I still don't have anything in for the servo, but I do have the servo working on a discrete sketch. I'm hoping I can put it in here later.

/*  
  L298N Motor Control Demonstration with Joystick
  L298N-Motor-Control-Demo-Joystick.ino
  Demonstrates use of Joystick control with Arduino and L298N Motor Controller
  
  DroneBot Workshop 2017
  http://dronebotworkshop.com
*/
  // Edited and modified by Jonathan Waldner on Nov.2017 for a relay and a TA8428 Motor driver.
  
// Motor A

int in1 = 10;   //Reverse motor
int in2 = 11;   //Forward Motor
int tx=1;       //Bluetooth TX
int rx=0;       //Bluetooth RX



void setup(){




  Serial.begin(9600);   // Start Serial Monitor
  

  // Set all the motor control pins to outputs

  pinMode(in1, OUTPUT);     //Turns revere motor pin into output
  pinMode(in2, OUTPUT);     //Turns forward motor pin into output

  
  pinMode(tx, OUTPUT);     //TX for Bluetooth
  pinMode(rx, INPUT);       //RX for Bluetooth
  
  }

void loop() {
  
      char BluetoothData; // the Bluetooth data received 
      char direction;   // This will tell program which direction to turn motor. 
   
       // Joystick Input
   
       int joyVert = A0; // Vertical  
   
       // Motor Speed Values - Start at zero
   
       int motorSpeed1 = 0;

       // Joystick Values - Start at 512 (middle position)

       int joyposVert = 50;    //Digital joystick goes from 0-100. 50 is center

    
  if (Serial.available()) {
    while (Serial.available()) {
    joyVert = Serial.read(); // Read Joystick input
  
  
   }
if (joyVert < 49) {

   // This is Backward
   direction = 'R';
 // ........
 }
 else if (joyVert > 51)
 {
   // This is Forward
   direction = 'F';
  }
}
{
    //Determine Motor Speeds

    // As we are going backwards we need to reverse readings

    joyVert = joyVert - 50; // This produces a negative number
    joyVert = joyVert * -1;  // Make the number positive

    motorSpeed1 = map(joyVert, 0, 460, 0, 255);
  
    //Determine Motor Speed

    motorSpeed1 = map(joyposVert, 52, 100, 0, 48);

}
  else
  {
    // This is Stopped

    motorSpeed1 = 0;

  }
  
  if (direction == 'F') {
  analogWrite(motorPinA, 0);
  analogWrite(motorPinB, motorSpeed);
}}
else {
  if (direction == 'R') {
  analogWrite(motorPinB, 0);
  analogWrite(motorPinA, motorSpeed);
}


  // Adjust to prevent "buzzing" at very low speed
  {

  if (motorSpeed1 < 8)motorSpeed1 = 0;

  // Set the motor speeds



}

If you use the AutoFormat tool it will lay your code out consistently so that you can see where there are unmatched braces.

On line 101 you have }} and I think there should only be }. I think there is another error also.

In any case never put more than one } on any line.

...R

OK, according to Arduino IDE. I created a set of code that makes sense. In real life ... not yet. My code compiled finally without a problem.

however, nothing happens when I try it out.

I'm guessing it has to do with the bluetooth data its receiving and what it is doing with it.

The app I'm using for my android phone is from Keuwl software. I'm using a joystick pad that sends 0-100 from bottom of throw to top.

It is preceding the signal with an X or a Y depending on Horizontal throw or Vertical throw.

Probably I need to add and X somewhere in my code. For now I'm stuck will be doing further reading.

/*
  L298N Motor Control Demonstration with Joystick
  L298N-Motor-Control-Demo-Joystick.ino
  Demonstrates use of Joystick control with Arduino and L298N Motor Controller

  DroneBot Workshop 2017
  http://dronebotworkshop.com
*/
// Edited and modified by Jonathan Waldner on Nov.2017 for a relay and a TA8428 Motor driver.

// Motor A

int in1 = 10;   //Reverse motor
int in2 = 11;   //Forward Motor
int tx = 1;     //Bluetooth TX
int rx = 0;     //Bluetooth RX



void setup() {




  Serial.begin(9600);   // Start Serial Monitor


  // Set all the motor control pins to outputs

  pinMode(in1, OUTPUT);     //Turns revere motor pin into output
  pinMode(in2, OUTPUT);     //Turns forward motor pin into output


  pinMode(tx, OUTPUT);     //TX for Bluetooth
  pinMode(rx, INPUT);       //RX for Bluetooth

}

void loop() {

  char BluetoothData; // the Bluetooth data received
  char direction;   // This will tell program which direction to turn motor.

  // Joystick Input

  int joyVert = X0; // Vertical

  // Motor Speed Values - Start at zero

  int motorSpeed1 = 0;

  // Joystick Values - Start at 512 (middle position)

  int joyposVert = 50;    //Digital joystick goes from 0-100. 50 is center


  if (Serial.available()) {
    while (Serial.available()) {
      joyVert = Serial.read(); // Read Joystick input


    }
    if (joyVert < 49) {

      // This is Backward
      direction = 'R';
      // ........
    }
    else if (joyVert > 51)
    
      // This is Forward
      direction = 'F';
    }

    {
      //Determine Motor Speeds

      // As we are going backwards we need to reverse readings

      joyVert = joyVert - 50; // This produces a negative number
      joyVert = joyVert * -1;  // Make the number positive

      motorSpeed1 = map(joyVert, 0, 460, 0, 255);

      //Determine Motor Speed

      motorSpeed1 = map(joyposVert, 52, 100, 0, 48);

    }
    {
    if (joyVert = 50)
    
      // This is Stopped

      motorSpeed1 = 0;

    }

    if (direction == 'F') {
      analogWrite(in2, 0);
      analogWrite(in1, motorSpeed1);
    }
    else {
      if (direction == 'R') {
        analogWrite(in1, 0);
        analogWrite(in2, motorSpeed1);
      }


      // Adjust to prevent "buzzing" at very low speed
      {

        if (in1 < 8)motorSpeed1 = 0;

        // Set the motor speeds

      }
    }
      }

The code in Reply #18 mentions BluetoothData on line 41 but that is all. There does not seem to be any code to receive data from a bluetooth device.

It is a good idea (i.e. essential IMHO) to include Serial.print() statements in your code so you can see that the actual values are in the variables. Maybe they are not what you think.

It is also a good idea to break your code into short single purpose functions as that allows you to test the parts separately. Have a look at Planning and Implementing a Program

...R