I’m a complete noob to linux and raspberry pi so forgive me if this is a simple question.
I have a project that I’m using that needs to run 4 DC motors so I got a 18v7 motor controller to try to use one before buying 3 more. I saw that I could chain a bunch of them together using TTL serial and so far that’s the plan. How do I go about interfacing with multiple motor controllers on the Pi’s GPIO pins?
Or are there other options like using the USB ports on the Pi or having the Pi go through an Arduino?
You can see connection diagrams and find a description that explains how to connect multiple Simple Motor Controllers (SMCs) to a microcontroller for TTL serial control under the “Daisy Chaining” section of the Simple Motor Controller user’s guide, which you can find under the Resources tab of its product page. Your chain of SMCs should connect to the Raspberry Pi’s hardware serial pins. The Pololu Protocol (which is described under the “Binary Commands” section of the guide) explains how to send commands to individual boards when they are daisy-chained together .
Hey thanks a bunch for the info.
I ended up ordering a set of four 18v15 motor controllers. My project’s motors needed a bit more current than I originally had planned.
Anyway, I have the circuit built with the Pi and the motor controllers. The motor controllers are all daisy chained to the TX and GND pins of the Pi. I’m going for the simple route for the time being, without the error codes and the like.
Now… the real question is how do I go about using the software available on the Pi to send out the binary commands?
Would it be easier to have an arduino act as an interface between the Pi and the motor controllers? I have the Arduino example code running just fine for one controller, I’m going to try to test the daisy chaining via Arduino within the next few days.
We have a cross-platform c and bash script example that show how to use TTL serial. You can find those under the “Sample Code” section of the Simple Motor Controller’s user’s guide, which you can find under the “Resources” tab of its product page. Other languages might be more accessible (for example, a lot of tutorials for the Raspberry Pi use Python); we don’t have any such examples, but you might be able to find general guides for using serial ports on the RPi by searching the Internet.
As for whether or not to use an Arduino, that is probably going to depend on the specifics of how you plan to control your motors. Also, I am not sure how you plan to communicate between your Arduino and RPi, but TTL serial is a common interface you could use to communicate between the two, so once you have learned how to use that interface with the RPi, you might not need the Arduino at all.
By the way, I just noticed I didn’t answer your question about controlling a Simple Motor Controller (SMC) from an RPi over USB. Yes, you can do that; the SMC provides a virtual serial port when connected via USB, which you can use to control it (as far as the software on the Raspberry Pi is concerned, this will be very similar to using a TTL serial port).
Hi thanks again for your help.
You can tell that I’m a newbie with Linux because I didn’t even realize that the script that I was using to talk to the Raspberry Pi terminal was Bash. Anyway, I’m still running into a few problems with trying to control the motor controllers individually.
I tried using the Bash script sample code that you have but unfortunately nothing happened. I even gave the DEVICE variable the name of the Raspberry Pi TTL serial port (its address is here: /dev/ttyAMA0) but still nothing happened. Is this maybe due to the fact that the bash script never sends a 0xAA byte to the motor controller as shown in section 6.2.1 of the User’s Guide.
As an alternative to this, I ended up typing commands directly to the terminal and used printf to send them to the tty serial port. This allowed me to successfully send commands to the motor controller. Below is what I typed into the terminal for a forward speed of 2048 and then 50% braking speed with comments:
stty -F /dev/ttyAMA0 19200 #establish communications and baud rate with motor controller
printf "\xAA" > /dev/ttyAMA0 #write the 0xAA byte to the motor controller to sync baud rate with motor controller
printf "\x83" > /dev/ttyAMA0 #write 0x83 to exit safe start mode
printf "\x85" > /dev/ttyAMA0 #write 0x85 to establish forward direction of motor
printf "\x0 > /dev/ttyAMA0 #write speed byte 1 (result of 2048 % 32)
printf "\x64" > /dev/ttyAMA0 #write speed byte 2 (result of 2048/32)
printf "\x92" > /dev/ttyAMA0 #write braking byte 0x92 to the motor controller
printf "\x16" > /dev/ttyAMA0 #write braking speed byte for 50% braking speed
However, I tried hooking up 2 motor controllers in the way that the wiring diagram on section 4.2 of the users guide says. I got the 2 motor controllers to behave exactly alike when sending the above commands.
However, I would like to have individual control of each motor controller. Trying to use the Pololu Protocol commands on section 6.2.1 of the users guide to do the same thing as the above code resulted in no action from either of my two motor controllers. Is there something I’m doing wrong?
The purpose of sending the 0xAA byte is for the Simple Motor Controller (SMC) to auto-detect the baud rate. If the SMC is configured to auto-detect the baud rate, it will be waiting for that command byte. Can you save the settings file for both of your SMCs by selecting File->Save Settings File… in the Simple Motor Control Center and post it here? That way we can see how you have both of your SMCs are configured.
For independent control, you would need to change the device numbers for each SMC and use the Pololu protocol (or Mini SSC protocol). (The Compact protocol does not specify a device number, so all SMCs will respond.) You can change the device number through the Simple Motor Control Center under the “Serial Settings” tab.
Can you post the exact code that you are trying to run here, so we can see what is causing the issue in your code?
The Pololu protocol command sequence should looks something like this (using default device number 0x0D or 13):
printf "\xAA\x0D\x03" > /dev/ttyAMA0 #exit safe start mode
printf "\xAA\x0D\x05\x00\x64" > /dev/ttyAMA0 #establish forward direction of motor
printf "\xAA\x0D\x12\x16" > /dev/ttyAMA0 #motor brake
By the way, I noticed that you are missing an extra 0 and closing double-quotes on this line
printf "\x0 > /dev/ttyAMA0 #write speed byte 1 (result of 2048 % 32). It is probably a typo, but just in case, zeros should be expressed as “\x00”.