PDA

View Full Version : [Question(s)] Encoder Board / Microcontroller



metaform3d
08-23-2008, 03:36 PM
I'm mentally specing out a project and I'm looking for some advice on what sort of electronics I can use. I want to drive 3 motors with encoders for distance, and three more motors with encoders or pots for angle. They all have to operate together in a coordinated fashion so I'd like to put them all under the control of a microcontroller, and then send high-level serial commands and get cooked results back.

The Arduino Diecimila is looking like a promising candidate. It has 6 PWM outputs to drive all 6 motors (probably through two Scorpion HX ESCs), and 3 of the analog inputs could be used for sensing motor rotation (10 bits over 380 degrees should give better than 0.5 degree accuracy). The problem is the encoders. The Diecimila has only two interrupt inputs, so I don't think I can use it directly to track three encoders. It appears that two of the remaining analog pins can be used for I2C communication with a separate board, but what board?

So my questions are 1) is my understanding of the Diecimila correct in terms of the problem I'm trying to solve; 2) is there anything that will track three encoders and send the results to the Diecimila (single encoders are probably OK since I'm driving the motors and know what direction they are turning); and 3) where do I find the encoder hardware itself? Just knowing how to form the query would help -- I can't seem to find anything anywhere, even the Trossen shop.

Or perhaps there's a different controller I should be considering. I was drawn to the Diecimila because of its simple but very expressive programming language, and its relatively low price.

lnxfergy
08-23-2008, 08:49 PM
It would appear that the Arduino libraries only use the 2 hardware external interrupt pins - but ---- the ATMEGA168 that it is based on actually has way more than 2 interrupt pins - its just that the rest are sorta multiplexed together. Each port (B,C, or D) on the 168 has its own interrupt vector, and any individual pin can be configured to be an interrupt trigger, after the interrupt triggers you have to read the corresponding register to see which pin(s) triggered. That said, there are three ports, add in your original 2 interrupt pins, and you can have 5 interrupts without any sort of register checking...

Of course, this would require some coding that is ATmega168 specific, and wouldn't be as easy as the Arduino libraries. But it is doable. My XR-B3 uses these softer external interrupts for the wheel encoders (since on the mega324 the timers are tied to the same pins as the external interrupts and I already need all the timers).

If you are interested I can dig you up some code examples for using those interrupts (I use AVR-GCC, the underlying compiler for Arduino environment, so making it work wouldn't be hard at all)

-Fergs

metaform3d
08-24-2008, 12:40 AM
If you are interested I can dig you up some code examples for using those interrupts (I use AVR-GCC, the underlying compiler for Arduino environment, so making it work wouldn't be hard at all)That would be very thoughtful, thank you. The sticking point for me is that I'm not at all comfortable hacking electronics. If you think it could work using the same hardware then it could be interesting. Ideally I'd like to try to use off-the-shelf microcontroller boards, and the fact that the Arduino tools had sort-of pre-digested the grisly bits of the software was a selling point for me as well.

lnxfergy
08-24-2008, 07:22 PM
Even with a product like the Arduino, eventually you will find something that is slightly harder to do. The built in libraries accomplish a lot of work for you, but eventually most people will want to do something a little more exotic - take the leap, it's fun...

Anyways, here is some sample code:

// Quick example of using pin change interrupts
// This shows how to use Digital Pin 4 (PCINT18/PD2) as an interrupt

#include <avr/interrupt.h>

// we need to remember that the Arduino environment uses different pin numbers
// than the ATMEGA168 itself.

void setup(){
// Make digital 4 (PCINT18/PD2) an input
pinMode(4, INPUT);

// this is ATMEGA168 specific, see page 70 of datasheet

// Pin change interrupt control register - enables interrupt vectors
// Bit 2 = enable PC vector 2 (PCINT23..16)
// Bit 1 = enable PC vector 1 (PCINT14..8)
// Bit 0 = enable PC vector 0 (PCINT7..0)
PCICR |= (1 << PCIE2);

// Pin change mask registers decide which pins are enabled as triggers
PCMSK2 |= (1 << PCINT18);

// enable interrupts
interrupts();
}

void loop(){
// do nothing...
}

// we have to write our own interrupt vector handler..
ISR(PCINT2_vect){
// this code will be called anytime that PCINT18 switches
// (hi to lo, or lo to hi)
}A few references you may want:
http://www.arduino.cc/en/Hacking/PinMapping168 - the pin mapping for arduino pin numbers
http://www.atmel.com/dyn/resources/prod_documents/doc2545.pdf - the datasheet for the ATMEGA168 (the actual processor on the Arduino).

Hope some of this helps, let me know if you have any Q's.
-Fergs

LinuxGuy
08-24-2008, 07:45 PM
Of course, this would require some coding that is ATmega168 specific, and wouldn't be as easy as the Arduino libraries.
Adding an IFDEF ENDIF around the processor specific code should do the trick. :happy:

Now there is the Sanguino (http://sanguino.cc) too, based on the Atmega644P. I like the Sanguino (http://sanguino.cc/), even though the Atmega644P is a 40 pin DIP, because it does not multiplex as many functions, like I2C and SPI, with other functions I want to use or need.

8-Dale

metaform3d
08-26-2008, 11:52 AM
Thanks for the code and the references, Fergs; that's a great help. So I guess with three interrupts I could read the encoders directly...

Can anyone point me to a source for single-channel encoders?

lnxfergy
08-26-2008, 03:27 PM
6 motors? 3 with distance encoding and 3 with angle? I'm guessing this is some omni-directional platform so that each wheel has a drive motor and an angle motor above it, eh?

Ok, to give any suggestion on encoders, I'm gonna need a little bit more information: What are these encoders doing exactly: what motors/wheels are looking at, what accuracy do you need for the encoders? If you haven't spec'd a motor/wheel/etc, what sort of weight is this thing carrying, and what diameter wheel would you be looking at?

A few other pointers: You mentioned using a pot for an angle measurement on three of the motors, can these be just regular hobby servos? Reason I bring this up, is that one thing I would be worried about is I/O ports. You may run out quickly with the arduino: 6 PWM channels, 3 AtoD channels, 3 for encoders, 2 for serial, etc...

-Fergs

metaform3d
08-26-2008, 06:18 PM
6 motors? 3 with distance encoding and 3 with angle? I'm guessing this is some omni-directional platform so that each wheel has a drive motor and an angle motor above it, eh?Well played, sir! Well played. Yes, a three-wheeled omni-directional platform I'm cleverly calling an omni-plat.

The number of ports definitely may be an issue -- that's why I was trying to spec it out. The Diecimila has 6 analog ports so that's no problem. Serial is pins 0 and 1. PWM is on 3, 5, 6, 9, 10, 11. Interrupts are on 2 & 3. So there's the problem: I can't use pin 3 for interrupt and PWM. Perhaps your code could be modified to accept interrupts on say 2, 4 & 7.

It's intended to carry a pretty big load. For wheels I'm planning to use 98mm razor scooter wheels with bearings. I'd coat the drive shaft of the motor with rubber and press it against the perimeter of the wheel to transfer power. The wheels are fairly tacky so I think that will work, and it will give me another gearing ratio.

I can't use hobby servos for rotation both because of the torque required to turn those tacky (but small footprint) wheels, and because I want to turn each more than 360 degrees.