Interrupts on pins > 22 not working

Hello,

I have a very simple program that reads a several motor encoders (about 12000 ints per second). One ISR per interrupt pin.

The issue is that it works fine on pins 2..13, but pins 23 onwards don't catch the input from the encoders.

Each ISR only increments a counter... ISR_A increments counterA, and so on.

Tried just changing encoder0pinX initialization, say from 23 to 5, and works fine, but as said, on pins 23 onwards, no input.

const byte encoder0pinB = 23;
const byte encoder0pinC = 24;
const byte encoder0pinD = 25;

void wheelSpeed_FR()
{
durationFR++;
}

void wheelSpeed_RL()
{
durationRL++;
}

void wheelSpeed_RR()
{
durationRR++;
}

setup()
{
...

attachInterrupt(encoder0pinB, wheelSpeed_FR, CHANGE);
attachInterrupt(encoder0pinC, wheelSpeed_RL, CHANGE);
attachInterrupt(encoder0pinD, wheelSpeed_RR, CHANGE);
}

Any clues?... I've spent hours looking at this, but can't figure out what's going on... I'm using 1.5.7 for mac. Checked winterrupts.h, and seems good... portD handlers included.

I'm setting pin modes as INPUT. Also tried INPUT_PULLUP, but didn't make a difference.

Appreciate your responses.
i

Just using a grounded jumper wire and touching it to pins 23, 24 and 25 works OK here:
(open serial monitor for status)

const byte encoder0pinB = 23;
const byte encoder0pinC = 24;
const byte encoder0pinD = 25;
volatile unsigned long durationFR;
volatile unsigned long durationRL;
volatile unsigned long durationRR;

void setup()
{
  Serial.begin(115200);
  pinMode(encoder0pinB, INPUT_PULLUP);
  pinMode(encoder0pinC, INPUT_PULLUP);
  pinMode(encoder0pinD, INPUT_PULLUP);
  attachInterrupt(encoder0pinB, wheelSpeed_FR, CHANGE);
  attachInterrupt(encoder0pinC, wheelSpeed_RL, CHANGE);
  attachInterrupt(encoder0pinD, wheelSpeed_RR, CHANGE);
}

void loop() {
  Serial.print ("durationFR ");
  Serial.print (durationFR);
  Serial.print ("  durationRL ");
  Serial.print (durationRL);
  Serial.print ("  durationRR ");
  Serial.println (durationRR);
  Serial.println();
  delay(1000);
}

void wheelSpeed_FR()
{
  durationFR++;
}

void wheelSpeed_RL()
{
  durationRL++;
}

void wheelSpeed_RR()
{
  durationRR++;
}

Do you have the specifications of the encoder?
Is it compatible with 3.3V?
Does it require external pullup resistors and what value?

Hi,

Thanks for your answer!... I will check the encoder documentation. It's an ESCAP 16.

What I don't understand is that if I just change the initialization of the variables (same code, same wire, same encoder, same board, but different pin), then things start working. Tried also different motors, but the behaviour is the same.

Is there any difference between different pins?... I will try to drive the pin with something different than the encoder, and see what happens.

Thanks again!

Hmmm... Tried on 40, 41, 42..46, and it's fine there!... Still can't figure out why 23..28 not good ?¿?

Forgot to say that I have a BT Shield, but for this test, I am not initializing it, or including any library header files in the test sketch.

Well, working on 40 onwards is good for my purposes, but would be good to know why the other pins don't see the changing wave from the encoder.

Hmmm... Tried on 40, 41, 42..46, and it's fine there!... Still can't figure out why 23..28 not good ?¿?

pins 23-28 = PA[14-15] and PD[0-3] is pin group 2 with higher current source/sink capabilities.
pins 40-46 = PC[8-9] PA19, PC[17-19] is on pin group 3 with lower current source/sink capabilities.
The only anomaly is that pin 43 (PA20) on pin group 2 and it still works. Are you sure?

You know, anything more than 3.6V on these pins and it's game over.

Is there any difference between different pins?... I will try to drive the pin with something different than the encoder, and see what happens.

Good idea (but it might be too late).

Great idea!... Thanks.

I'm going to do tonight a more exhaustive check on which pins work and which don't, but

  • 22 deffinetly works,
  • 23-28 deffinetly don't work
  • 40, 41 deffinetly work
  • 2-10 work too

Not sure now about 43, but will let you know.

In any case, I had the encoders connectred to 40 and 41 for quite a while, no burning smell or anything that indicated the SAM was getting fried.

I will check the voltage on the encoder pins, but according to the encoder documentation, the square signal amplitude should be just a bit less than 5V, but of course, being a square signal (50% pulse width), the average current should be much lower than driving the pin with a 5V continuous signal....

That might be why I haven't fried the chip, or why pins in group 2 with higher current requirements didn't sense the pulses?¿?

Thanks again!

Just saw something else in the documentation for the encoder:

"Output: 2-3 channels, square wave in quadrature, optional reference, 4 to 512 pulses per revolution, TTL and CMOS compatible."

Don't really know if this is significant, or not...

If you've hooked a 5V encoder up to a Due without current-limiting resistors, I can pretty much guarantee you have damaged the input circuitry on the Due. And, no, you won't see, feel or smell anything. 5V peripherals CANNOT be directly connected to the Due.

Regards,
Ray L.

inaki_ba:
Just saw something else in the documentation for the encoder:

"Output: 2-3 channels, square wave in quadrature, optional reference, 4 to 512 pulses per revolution, TTL and CMOS compatible."

Don't really know if this is significant, or not...

inaki_ba:
Just saw something else in the documentation for the encoder:

"Output: 2-3 channels, square wave in quadrature, optional reference, 4 to 512 pulses per revolution, TTL and CMOS compatible."

Don't really know if this is significant, or not...

Sounds as typical non-english native translation, no offence.
Just wonder what is this "optional reference".
To me "TTL" means +5V system, but "CMOS compatible" is pretty vague.
In reality one should look at real schematic of the ARM / Due I/O , if there is such thing in ATmel hundred + pages of documentation.This "high current source / sink" needs some foundation / description.

And just to make sure - it is an OPTICAL and not MECHANICAL (switched contacts) encoder and with its OWN power, right?

Vaclav:
Sounds as typical non-english native translation, no offence.
Just wonder what is this "optional reference".
To me "TTL" means +5V system, but "CMOS compatible" is pretty vague.
In reality one should look at real schematic of the ARM / Due I/O , if there is such thing in ATmel hundred + pages of documentation.This "high current source / sink" needs some foundation / description.

And just to make sure - it is an OPTICAL and not MECHANICAL (switched contacts) encoder and with its OWN power, right?

The "optional reference" would typically be a once-per-rev index pulse with its own dedicated output signal.

Regards,
Ray L.

Hi Ray,

I've read through tones of discussions around pull-up resistors to 3.3V between 5V and 3.3V devices. I guess the Due internal pullups would protect those pins? Please correct me if wrong.

Vaclav,

I think it's a magento-resistance encoder (neither optical or mechanical). It definetly gets its own power.

Thanks!
Inaki

No, pullup resistors are the worst possible thing to do. Pullup resistors CANNOT protect a pin against over-voltage. What you need is series resistors to drop the voltage, and limit current, to a safe level for the Due. On the order of 200-300 ohms.

Regards,
Ray L.

I've read through tones of discussions around pull-up resistors to 3.3V between 5V and 3.3V devices. I guess the Due internal pullups would protect those pins? Please correct me if wrong.

The only "protection" the internal pullups might offer is preventing oscillations on otherwise floating and high impedance inputs. It is good practice to at least configure unused inputs to enable the internal pullup resistors.

A search of the complete datasheet (1467 pages) does not turn up any hits for the word "diode".

There are NO internal ESD protection diodes on the SAM3X. The maximum voltage an I/O pin can tolerate is 3.6V. An external series resistance alone will not protect the voltage level from exceeding 3.6V.

The Due's SAM3X does have 39Ω series resisters embedded on all I/O pins. This is referred to as ODT (On-Die Termination) providing impedance matching to the PCB tracks and reducing EMI and ringing on fast signals.

SAM3X Datasheet

Hi Ray,

I've read through tones of discussions around pull-up resistors to 3.3V between 5V and 3.3V devices. I guess the Due internal pullups would protect those pins? Please correct me if wrong.

Vaclav,

I think it's a magento-resistance encoder (neither optical or mechanical). It definetly gets its own power.

Thanks!
Inaki

Apologiesfor my previous post (double posted).

dlloyd:
A search of the complete datasheet (1467 pages) does not turn up any hits for the word "diode".

There are NO internal ESD protection diodes on the SAM3X. The maximum voltage an I/O pin can tolerate is 3.6V. An external series resistance alone will not protect the voltage level from exceeding 3.6V.

I spent over 20 years designing chips very similar to the SAM3X. I can assure you it absolutely DOES have ESD protection diodes. Nobody in their right mind would design such a chip without it, and few foundries would even be willing to fabricate such a chip without a waiver of any guarantees on yield.

However, ESD protection, and over-voltage protection are very different things. The diodes have limited current capability, and in the presence of over-voltage, they WILL be destroyed. Series resistors can be used to prevent this, by limiting the current flowing into the pin from an external 5V signal to a level that the diodes can safely tolerate. Somewhere on the Atmel website is a white paper that discusses this in great detail.

Bottom line - series resistors that limit the current to a few mA WILL protect the chip.

Regards,
Ray L.

After testing, I now agree that there is some very weak protection ... the weakest I've seen. What are the specifications for current?

Bottom line - series resistors that limit the current to a few mA WILL protect the chip.

Maybe extend its life ... to what?
It's impossible to use series resistors for protection on the Due and not exceed Atmel's maximum voltage ratings.

⦿ Oscilloscope probe
⊡ Pin

Test 1:

5V ⊡——100K╱╲╱╲╱╲——⦿ 4.58V

5V ⊡——100K╱╲╱╲╱╲——⦿——⊡ 3.65V, 9.3 µA (Pin 22)

Test 2:

5V ⊡—— 47K╱╲╱╲╱╲——⦿ 4.81V

5V ⊡—— 47K╱╲╱╲╱╲——⦿——⊡ 3.68V, 24.0 µA (Pin 22)

Test 3:

5V ⊡—— 10K╱╲╱╲╱╲——⦿ 4.99V

5V ⊡—— 10K╱╲╱╲╱╲——⦿——⊡ 3.75V, 124 µA (Pin 22)

Test 4:

5V ⊡—— 2.4K╱╲╱╲╱╲——⦿ 5.02V

5V ⊡—— 2.4K╱╲╱╲╱╲——⦿——⊡ 3.85V, 0.49 mA (Pin 22)

Looks to me like it's working just fine, and limiting the pin voltage to ~3.6V, exactly as it's supposed to. If you're expecting to measure exactly 3.6V, you won't. It's the CURRENT into the pin that matters, not the external voltage.

The protection diodes can safely handle several mA. I seem to recall 6-8mA, but don't quote me on that. I don't recall the exact spec, but if you do some searching on the Atmel site, you'll eventually find the same white paper I did that give the specs for the ESD diodes on the SAM, straight from an Atmel engineer. Series resistors was Atmels recommended solution, if level shifters were not practical. Their recommended value was a few hundred ohms. I've been using Dues this way for some time, with zero problems, using 220 ohm series resistors. Not a single failure.

As long as the resistors are large enough to keep the max current below the safe level for the diodes, there is ZERO impact on chip life.

Find the information oh the Atmel site....

Regards,
Ray L.

There is this paper on zero crossing detector that recommends clamp diode be kept under 1mA.

Atmel AVR182 Zero Cross Detector.pdf (95.1 KB)

IBIS_models_SAM3X

SAM3X8E_LQ144_IBIS.pdf (739 KB)