Advice on controlling two motor controllers through arduino

I am working on wheelchair project two of 24v12 controllers are to be attached to arduino and controlled through programming through ttl interfaces i have seen arduino example and i am perfectly controlling one controller. I am not very good at coding i just want to control two controllers in the similar fashion as i am controlling one of them which means that both of them will be attached to arduino and through programming m gona drive both motors at the same time then i will use ‘if else’ conditions to make program up but the major issue is to move both motors through controllers at the same time
I dont know if this could be done by defining another pin into that code or some thing else but the below code from arduino example is runnig fine i just need a bit add on to add another controller (i know the connections) with the code to control motor i will be very thankful for help
#include <NewSoftSerial.h>
#define rxPin 3 // pin 3 connects to SMC TX (not used in this example)
#define txPin 4 // pin 4 connects to SMC RX
NewSoftSerial mySerial = NewSoftSerial(rxPin, txPin);

// required to allow motors to move
// must be called when controller restarts and after any error
void exitSafeStart()
{
mySerial.print(0x83, BYTE);
}

// speed should be a number from -3200 to 3200
void setMotorSpeed(int speed)
{
if (speed < 0)
{
mySerial.print(0x86, BYTE); // motor reverse command
speed = -speed; // make speed positive
}
else
{
mySerial.print(0x85, BYTE); // motor forward command
}
mySerial.print((unsigned char)(speed & 0x1F), BYTE);
mySerial.print((unsigned char)(speed >> 5), BYTE);
}

void setup()
{
// initialize software serial object with baud rate of 38.4 kbps
mySerial.begin(38400);

// the Simple Motor Controller must be running for at least 1 ms
// before we try to send serial data, so we delay here for 5 ms
delay(5);

// if the Simple Motor Controller has automatic baud detection
// enabled, we first need to send it the byte 0xAA (170 in decimal)
// so that it can learn the baud rate
mySerial.print(0xAA, BYTE); // send baud-indicator byte

// next we need to send the Exit Safe Start command, which
// clears the safe-start violation and lets the motor run
exitSafeStart(); // clear the safe-start violation and let the motor run
}

void loop()
{
setMotorSpeed(3200); // full-speed forward
delay(1000);
setMotorSpeed(-3200); // full-speed reverse
delay(1000);
}

Hello.

[quote=“talha”]I am working on wheelchair project two of 24v12 controllers are to be attached to arduino and controlled through programming through ttl interfaces i have seen arduino example and i am perfectly controlling one controller. I am not very good at coding i just want to control two controllers in the similar fashion as i am controlling one of them which means that both of them will be attached to arduino and through programming m gona drive both motors at the same time then i will use ‘if else’ conditions to make program up but the major issue is to move both motors through controllers at the same time
I dont know if this could be done by defining another pin into that code or some thing else but the below code from arduino example is runnig fine i just need a bit add on to add another controller (i know the connections) with the code to control motor i will be very thankful for help[/quote]
Your post is really hard to read without punctuation!

If you want to control two motors on the same serial lines, you need to use the Pololu protocol (the example from the user’s guide uses the compact protocol). The two protocols are very similar, so it shouldn’t be hard for you to modify the example code. For example, the Pololu protocol version of the setMotorSpeed() function would be:


void setMotorSpeed(int speed, unsigned char deviceId) 
{
  mySerial.print(0xAA, BYTE); // first byte of Pololu protocol
  mySerial.print(deviceId, BYTE); // determine which controller gets the command

  if (speed < 0) 
  { 
    mySerial.print(0x06, BYTE); // Pololu protocol version of motor reverse command 
    speed = -speed; // make speed positive 
  } 
  else 
  { 
    mySerial.print(0x05, BYTE); // Pololu protocol version of motor forward command 
  } 
  mySerial.print((unsigned char)(speed & 0x1F), BYTE); 
  mySerial.print((unsigned char)(speed >> 5), BYTE);
}

To turn a compact protocol command into a Pololu protocol command, you need to first send the byte 0xAA followed by the device ID of the controller you are sending the command to. Next you send the same bytes as you would if you were using the compact protocol, except you must clear the most significant bit of the compact protocol’s command byte. This might sound complicated, but the command documentation in section 6.2.1 should make it a lot clearer.

Section 6.6 of the SMC user’s guide has more information on daisy chanining multiple controllers on the same serial line. Don’t forget to assign your two controllers different device IDs!

- Ben

i have done some research after ur reply. first of all i m really sorry abt my punctuation mistakes. now if i assume two device id’s as “0x0D” and “0x0B” and write two set motor speed functions, will it work?
like dis

void setMotorSpeed(int speed, unsigned char deviceId)
{
mySerial.print(0xAA, BYTE); // first byte of Pololu protocol
mySerial.print(0x0D, BYTE); // determine which controller gets the command

if (speed < 0)
{
mySerial.print(0x06, BYTE); // Pololu protocol version of motor reverse command
speed = -speed; // make speed positive
}
else
{
mySerial.print(0x05, BYTE); // Pololu protocol version of motor forward command
}
mySerial.print((unsigned char)(speed & 0x1F), BYTE);
mySerial.print((unsigned char)(speed >> 5), BYTE);
}
and

void setMotorSpeed1(int speed1, unsigned char deviceId1)
{
mySerial.print(0xAA, BYTE); // first byte of Pololu protocol
mySerial.print(0x0B, BYTE); // determine which controller gets the command

if (speed < 0)
{
mySerial.print(0x06, BYTE); // Pololu protocol version of motor reverse command
speed = -speed; // make speed positive
}
else
{
mySerial.print(0x05, BYTE); // Pololu protocol version of motor forward command
}
mySerial.print((unsigned char)(speed & 0x1F), BYTE);
mySerial.print((unsigned char)(speed >> 5), BYTE);
}
void loop()
{
setMotorSpeed(3200); // full-speed forward for 0x0D controller
setMotorSpeed(-3200); // full-speed reverse for 0x0D controller
setMotorSpeed1(3200); // full-speed reverse for 0x0B controller
setMotorSpeed1(-3200); // full-speed reverse for 0x0B controller
}
and then call both function in “void loop” portion will it be ok ?
for the connections i will be connect them as the daisy chain will it be ok ?

Thank you for using punctuation in your last post; it definitely helps! I have one more request, however: please use code tags around your code to make it more readable.

If you write two functions, you don’t need the deviceId argument (notice how you’re not actually using it anywhere). What you’re doing will work, but I prefer my approach, mainly because it results in less duplicate code. If your two controllers have device IDs of 0xb (11) and 0xd (13) and you use my setMotorSpeed() function, your main loop could be:

void loop()
{
  setMotorSpeed(3200, 0xb);  // full-speed forward for controller 0xb
  setMotorSpeed(3200, 0xd);  // full-speed forward for controller 0xd

  delay(2000);  // wait for 2 seconds

  setMotorSpeed(-3200, 0xb);  // full-speed reverse for controller 0xb
  setMotorSpeed(-3200, 0xd);  // full-speed reverse for controller 0xd

  delay(2000);  // wait for 2 seconds
}

The delays are important. The setMotorSpeed() function only takes around a millisecond to execute, which means your delay-free version of loop() is commanding your motors to alternate between full-speed forward and full-speed reverse every few milliseconds. I don’t think this is the behavior you want.

- Ben

ok from ur code it is clear that two controllers of different device ids can be controlled by single function but a bit of confusion remains that we are gona assign particular device id to particular controller. As the two controllers are daisy chained which one will be 0xd and which one of them will be 0xb . In which part of code the specified device id will be assigned to specified controller

You cannot use the serial interface to set the device ID. You should individually connect each SMC to your computer via USB and use the Simple Motor Control Center software to change the the controller’s device ID and any other settings you want to configure.

- Ben

well ok thats what i understand that the device id’s are set by connecting the controller direct to computer through pololu software and USB interface.And once the device ID is set the controller will run without its connection to the computer. Means if i burn the code to arduino,connect controllers to it and remove it form the computer and attach power supply for motor controllers and arduino it will work perfectly fine … am I right ?

Your sequence of steps is right: first configure the SMCs from a computer via USB, then disconnect them from USB and wire them up to your Arduino, your motors, and an appropriate power supply. (Note that you can keep the controllers connected to your PC even while they’re wired up for serial control from the Arduino, which would allow you to monitor what they are trying to do in response to commands from the Arduino.)

However, there are plenty of ways to make mistakes while trying to complete these steps (e.g. wiring problems, buggy code, inadequate power supply, motors that require more power than the controllers can deliver, etc.), so I can’t say that it will work “perfectly fine” for you. All I can say is that it is possible to control two appropriately sized motors with two Simple Motor Controllers via serial commands from an Arduino.

- Ben

i have started from basics. i have connected one motor with and a push button with arduino. The push button is attached to pin 8 of arduino board. my requirement is that when i press the button the motor should run at given speed in the argument and it should stop when i release the button.i ran the following code

#include <NewSoftSerial.h>  
#include <LiquidCrystal.h>
const int buttonPin = 8;     // the number of the pushbutton pin
     
#define rxPin 3  // pin 3 connects to SMC TX  (not used in this example)
#define txPin 6 // pin 6 connects to SMC RX  
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
NewSoftSerial mySerial =  NewSoftSerial(rxPin, txPin);  
     
// required to allow motors to move  


void setMotorSpeed(int speed)  
{  
  mySerial.print(0x83, BYTE);
  if (speed < 0)  
  {  
    mySerial.print(0x86, BYTE);  // motor reverse command  
    speed = -speed;  // make speed positive  
 }  
  
  else 
  {  
    mySerial.print(0x85, BYTE);  // motor forward command  
  }  
  mySerial.print((unsigned char)(speed & 0x1F), BYTE);  
  mySerial.print((unsigned char)(speed >> 5), BYTE);  
}  

int buttonState = 0; 


   
void setup()    
{
 
  // initialize the LED pin as an output:

  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);   // initialize software serial object with baud rate of 38.4 kbps
  mySerial.begin(38400);
  
   
  // if the Simple Motor Controller has automatic baud detection
  // enabled, we first need to send it the byte 0xAA (170 in decimal)
  // so that it can learn the baud rate
  mySerial.print(0xAA, BYTE);  // send baud-indicator byte
}  
   
void loop()  
{
  buttonState = digitalRead(buttonPin);  
 if (buttonState == HIGH) 
 {  
 setMotorSpeed(300);
 }
else if(buttonState == LOW)//(buttonState == LOW)
{
setMotorSpeed(0);
}
else{}

}

now push button is not running fine when i press it or release it the movement of motor is not fine… it shows jerks to start and it doesnt stops properly. what i mean is that the button is working but not as fine as it should work, may be some mistake in code??

Can you describe how you have your button connected? I suspect you are missing a crucial pull-up.

- Ben

the push button has two terminals one is connected to pin 8 of digital ports of arduino and second one is connected to ground and it works fine if i connect led across it instead of motors.(means it works fine in simple code from arduino examples)

You are having problems because the pushbutton pin is floating (i.e. the input state is undefined) when the button is not pressed. If your button connects the pin to ground, you need an external pull-up resistor on your input to give it a default high state when the button is unpressed, or you can enable the Arduino’s internal pull-up resistor on that pin. The latter method is probably easier since all you need to do is call:

digitalWrite(buttonPin, HIGH);

right after you set buttonPin as an input in setup().

- Ben

Hi I was working with one controller and it was working fine power supply and connections (main) are fine. I ran another controller and it was also working fine. then i gave 13 device number to one of them and 11 to second of them and daisy chained them shown in file attached and ran the following code

#include <NewSoftSerial.h>  
#include <LiquidCrystal.h>
#define rxPin 3  // pin 3 connects to SMC TX  (not used in this example)
#define txPin 6 // pin 6 connects to SMC RX  

NewSoftSerial mySerial =  NewSoftSerial(rxPin, txPin);  
int sensorPin = 0;     
// required to allow motors to move  


  
  void setMotorSpeed(int speed, unsigned char deviceId) 
{
  mySerial.print(0xAA, BYTE); // first byte of Pololu protocol
  mySerial.print(deviceId, BYTE); // determine which controller gets the command

  if (speed < 0) 
  { 
    mySerial.print(0x06, BYTE); // Pololu protocol version of motor reverse command 
    speed = -speed; // make speed positive 
  } 
  else 
  { 
    mySerial.print(0x05, BYTE); // Pololu protocol version of motor forward command 
  } 
  mySerial.print((unsigned char)(speed & 0x1F), BYTE); 
  mySerial.print((unsigned char)(speed >> 5), BYTE);
  
}  
   
void setup()    
{
  // initialize software serial object with baud rate of 38.4 kbps
  mySerial.begin(38400);
 // lcd.begin(16, 2);
  
 
  // the Simple Motor Controller must be running for at least 1 ms
  // before we try to send serial data, so we delay here for 5 ms
  delay(5);
   
  // if the Simple Motor Controller has automatic baud detection
  // enabled, we first need to send it the byte 0xAA (170 in decimal)
  // so that it can learn the baud rate
  mySerial.print(0xAA, BYTE);  // send baud-indicator byte
}  
   
void loop()  
{

//setMotorSpeed(300, 0xb);  // full-speed forward for controller 0xb
 setMotorSpeed(400, 0xd);  // full-speed forward for controller 0xd

  delay(2000);  // wait for 2 seconds

 // setMotorSpeed(-300, 0xb);  // full-speed reverse for controller 0xb
  setMotorSpeed(-400, 0xd);  // full-speed reverse for controller 0xd

  delay(2000);  // wait for 2 seconds
}

the code was uploaded through arduino .the code did’nt gave error and uploading was successful but it was not doing anything
can u help plzzCircuit …docx (14.6 KB)

What do you mean when you say that using each controller independently was “working fine”? What code were you using that was working with the individual controllers? I recommend you get each controller individually working with Pololu protocol commands before you try daisy chaining them together. Also, your .docx circuit document looks really strange when I open it with Open Office. Can you just post a screenshot of it?

- Ben

the code given arduino examples was used with individual controllers and they were working according to code
and i have uploaded new file i hve only showed the connection i used
crcuit.pdf (19.6 KB)

Please post a simple Arduino sketch that works individually with each of your motor controllers.

- Ben

It is simple connection arduino’s GND is connected to motor controllers GND and arduino 's one digital pin is connected to RX of motor controller and the code in arduino expamples is burned through USB interface of arduino to computer . The motor starts moving and as I change value of speed in “setmotorSpeed” argument ,the speed of motor varies the same
Thanks

Is this forum poster you or someone who is working on your project with you? If so, then you are using an Arduino Mega (something you didn’t mention in this thread), which has multiple UARTs. Maybe the simplest solution is to use a different UART for each controller (i.e. no daisy-chaining) and just run the example code, which you say is already working.

I still think you should be able to get the Pololu protocol working with daisy-chained units, but I think you are not troubleshooting your problem very well or following my instructions, which is making it difficult to help you.

By the way, if that other post is you or someone posting on your behalf, please do not start multiple forum threads for the same problem.

- Ben

hi Ben
By the grace of God and your full support i am able to control both motors with controllers. The whole setup with sensors is working fine as per requirement. Actually i was using power supplies in which current and voltage could be varied manually now i want to use portable battery which should be fitted on wheel chair and should be able to drive two 12 volts motors I just want a recommendation of DC battery can u give me suggestions

I’m glad to hear you have things working. Do you know what you were originally doing wrong?

As far as batteries go, you should select something with the appropriate voltage that can deliver enough current to satisfy your system’s peak demands without experiencing a substantial dip in voltage. You should also consider how long you need your system to be able to run between recharges. Given this and your system’s average current draw, you should be able to compute the minimum capacity you require for your batteries. If your project involves a wheel chair, my suggestion is to try a wheelchair battery. If your load is significantly lower than that of a typical motorized wheelchair, you also might consider battery packs used for RC applications (search for NiMH or NiCD sub-c packs like this).

Good luck with your project!

- Ben