For a relatively complex project I am working on, I need to use multiple communication protocols, and I am getting lost as to what I can do with the devices I have to deal with. Here’s an oversimplified diagram of the elements:
Each board has to read its encoders values and run PID loops for 2 motors.
The baby-O has to send its encoders values to the SVP1284, and receive target values from it as well.
The SVP1284 would have to read its encoders and run the PID loops as well, but also “control” the Baby-O and keep track of all 4 encoders values. Additionally, it has to be able to communicate with a PC (through USB) to send all encoders values in realtime and get new target values.
Baby-O has to send/receive through SPI AND control 2 motors - seemingly not possible using HW SPI since PB3 is used for motor control. MSPIM of USART seems like it would be a perfectly viable option to communicate with the encoders without conflict with motor control, but then how do I communicate with the SVP1284?
SVP1284 also has to communicate with the encoders through SPI, but its SPI is already used by the auxiliary MCU (which is needed in order to have PC USB communication). However, it has 2 USART, so technically I could use one for MSPIM and the other to communicate with the Baby-O.
The whole loop has to run at a minimum of 60Hz, including receiving data from PC, controlling Baby-O, reading encoders, running PID loops (2 per boards) and sending back data to PC
I could potentially get by my communication protocol conflict problem by using the PWM of the AS5048A instead of the SPI interface, but then I’d lose some precision (12-bit vs 14-bit), which I’d rather not do…
So, what is the best way to have the Baby-O do SPI, control motors and communicate with the SVP? Would software SPI be a viable solution to free up the USART and keep the speed consistent? The AS5048A uses 16-bit words, so at 60Hz it means I need to read close to 2000-bit/sec through SPI and send them through USART at the same time (or very close), while running 2 PID control loops for the motors… Is that too much for the Baby-O?
And on the SVP1284 side, same reading through SPI, with the added bi-directional data exchange with the Baby-O and a PC through USB, adding LCD display, buttons functionality, motor controls…
Been reading Atmel and AMS Datasheets and several application notes, and still very confused. On the Atmel site I see the the 328P has 2 SPI and the 1284P has 3, I’m not sure what that means - do they refer to the SPI registers? It’s a very ambitious project for me, and before I start getting too deep I want to know if the hardware I have can handle it.
Sorry, it’s a lot of questions - any help and pointers would be greatly appreciated!
I suggest that you try to simplify this design to only have one microcontroller board if possible; I think that will eliminate a lot of troubles and annoyances. The Orangutan SVP has two free PWM outputs provided by Timer 0 so you should be able to control four motors from it. The mbed might also be a good choice.
Doing software SPI communication as the master is pretty easy; there are no tight timing requirements. You should be able to use the functions in the OrangutanDigital and OrangutanTime of the Pololu AVR C/C++ Library to implement master SPI and read data from the sensors. That would leave the Baby Orangutan’s UART free to communicate with the SVP.
I think 60 Hz will be tough. That means you need to do two USB I/O operations on the computer every 16.6 ms. Typically those I/O operations take a few milliseconds to complete. Also, the virtual COM ports for the Orangutan SVP are implemented the standard way using USB bulk endpoints, which do not provide any kind of promise about how quickly the data will be transferred. If you happened to be using a USB flash drive at the same time, you might see your system stop performing the way you would like it to.
Assuming your sensors are capable of it, you should be able to achieve a 500 kHz or faster software SPI frequency with your Baby Orangutan, which means transferring the 16-bit word would take just 32 microseconds. For reference, we use software SPI to program the Orangutan SVP and I think we achieved 1500 kHz using carefully optimized assembly, and we did on a PIC processor running at only 12 MHz compared to the Baby Orangutan’s 20 Mhz.
I’m not sure what page you saw that on, but each of those chips has a dedicated SPI module, along with USARTs that can be used in SPI mode. So you could say the 328P has 2 SPIs in some sense if you count the SPI module and the USART. You could say the 1284P has 3 SPIs in some sense if you count the SPI module and the two USARTs.
Yes, this sounds like a difficult project. You are probably going to want a logic analyzer or oscilloscope so you can see how exactly the timing is working out. As always, I recommend starting with something simple and adding small pieces onto it as you go.
Hi David - thanks for the prompt and thorough reply!
Agreed, but unfortunately I need to have 2 MCU, since the project is modular; the “head” part can operate in standalone mode (Baby-O alone, with 2 motors and 2 encoders). Also, for the purpose of the prototype, I’d like to use the devices I have in hand - not buying additional motor drivers and/or microcontrollers.
The 14-bit encoder requires the value to be read with a period of 600us or more in order to get a new angle position, so let’s call it 2ms to read both encoders with a safe margin. Still within my requirements, but I was worried that throwing in USART (send those 2 angle values, and get 2 new target values), and running 2 solid PID loops for motor control could slow me down a bit…
Yeah… I figured the USB communication would be the main bottleneck here. However, the system will operate in standalone mode - no PC connection - most of the time. So I suppose I could afford slower speed when connected, for the time being. Also, wouldn’t a RS232-TLL converter allow me to achieve faster speeds, by losing the USB overhead? What would be the best way to ensure fast and reliable communication with a PC? This is the last thing I’ll implement, as there’s more work on the software/plugin end to be done…
USB is 100-1000x faster than TTL, if you have proper USB support in the microcontroller. For example, the Arduino Leonardo can do USB in hardware (at 12 Mbit/s) and can receive the USB packets while interrupts are disabled and it’s running other things.
I don’t know how much freedom you have in selection of hardware – if you already have the devices on your sketch, this might not be very helpful.
I’ve found that turning ATtinys (84A or 85) into peripherals by running a small amount of custom code on them, and communicating with SPI, is quite convenient. An ATtiny84A can be turned into a 4-channel quadrature decoder with SPI interface, for example, and could easily read at > 20 kHz input, running on its built-in 8 MHz resonator.
You could then hook that up to a Arduino Leonardo Nano (which has 7-ish channels of PWM) or similar, to actually drive all four motors. The Nano can then receive commands through USB, either by emulating a serial port, or by just running custom firmware that you can talk directly to – look for the “LUFA” library for the AVR, and the “libusb” library or “WinUSB” API for the PC.
Hey jwatte, thanks for chiming in!
Of course, USB sustained data transfer speed is an order of magnitude faster than UART - which is already much faster than what I need to transfer at. My concern is the frequency and timing at which transfers can be operated… In my case, I would need to send and receive a packet at least 60 times per seconds, and at as regular of an interval as it is possible to achieve.
At this point, I really want to use what I have and not buy more - spent enough already! I have a Baby-O, an SVP1284, a Cerb40 and two mini maestro in hands, and will try to make the best out of them…
The device is a 4 DOF (to be expanded to 7) camera motion control, and needs high precision and repeatability. I’m still wondering if I can get more reliable timing on the data packets exchanged by connecting to a serial port instead of USB?
The original USB bus ran at 1,000 packets per second, but USB 2.0 splices that in 8 – you can do 8,000 separate bulk transfer packets per second on the USB bus. Talking from my Raspberry Pi to my Leonardo clone, I easily do 2,000 per second.
I doubt it, but the only way to know for sure is to try it for real
I find that, when super-smooth timing is needed, adding some buffering and a separate clock for play-out is usually a good solution. Thus, you would send commands to the controller saying “at time T, start moving to position P” and you would send it about a frame ahead of the estimated time T. You’d also keep reading back the time that the controller thinks it is, so you can properly schedule further commands.
Yes. The throughput of USB is great, but the latency of doing I/O in a multi-tasking OS could make this application difficult. Also, your PC might occasionally be busy doing something else for 50 ms and not even run your program during that time. It would be much better if your application allowed buffering up the incoming USB data from the SVP and handling it in batches.