tinchox3524 / arduino-pinchangeint

Automatically exported from code.google.com/p/arduino-pinchangeint
0 stars 0 forks source link

Mega support for PinChangeInt #2

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Attempt to use PinChangeInt with an Arduino Mega.

I have not attempted to do this yet, but am considering my board options for a 
current project.  How much work is involved to modify this library to work with 
the Mega?

Original issue reported on code.google.com by steve.ha...@gmail.com on 28 Nov 2011 at 7:20

GoogleCodeExporter commented 8 years ago
Unknown at this time.  According to the datasheets, the ATmega2560 is very 
similar to the 328p in terms of its interrupts on Ports B, C, and D, which is 
what this library covers.  However, this has not been tested.  If you are 
willing to try it and report on your results, that would be great.  I have some 
code that I am using for some tests that I can upload here and you can check it 
out.  ...But I will have to modify it to use for the older version of 
PinChangeInt.  Give me a few days.

Original comment by mschw...@gmail.com on 3 Dec 2011 at 5:54

GoogleCodeExporter commented 8 years ago
Try to run this sketch.  Please make one change:  In the quickfunc, add a few 
characters in a print statement, such as:

void quicfunc() {
  qf0=TCNT0;
  Serial.print(" *I* ");
}

Also, set the loop variables so as not to loop too many times.

...You will have to look at the Arduino Mega's pinout, and compare to the 
ATmega2560 pinout, to ensure you are using the correct pin of the correct PORT. 
 The 328p has only ports B, C, and D.  I will include another (unfinished) doc 
I am writing, so you can bone up on the ATmega's interrupt pins.  There's a 
diagram in there that should be helpful.  See if you can find a similar diagram 
for the 2560, and choose your pins carefully to see if they work.

Original comment by m...@schwager.com on 3 Dec 2011 at 6:26

Attachments:

GoogleCodeExporter commented 8 years ago
My apologies, but I do not have the hardware yet at this time.  I appreciate 
your sketch and documentation provided.  At the time of my post, I was 
considering various solutions for my project.  I will study what you have 
provided and post back if I go this route.

Original comment by steve.ha...@gmail.com on 3 Dec 2011 at 2:35

GoogleCodeExporter commented 8 years ago

Original comment by m...@schwager.com on 1 Jan 2012 at 3:52

GoogleCodeExporter commented 8 years ago
I, too, am in need of this library for a Mega for my robot...

I found some info that seems like it would be helpful for supporting the Mega 
on page 346 of the book "Practical Arduino". ( 
http://books.google.com/books?id=iwzo1-zmVXEC&pg=PA346&lpg=PA346&dq=Arduino+pin+
change+interrupt+mega&source=bl&ots=mNfnuSd0b1&sig=kUOeXI3Yy1nYa6-l_dqSpK6amrs&h
l=en&sa=X&ei=btMeT6SGJa2msQKzvcHIDg&ved=0CFcQ6AEwBg#v=onepage&q=Arduino%20pin%20
change%20interrupt%20mega&f=false )

There's also some information on pages 140-142 of "Arduino Internals" 

Original comment by makop...@gmail.com on 24 Jan 2012 at 4:29

GoogleCodeExporter commented 8 years ago
hi, i want to use the mega interrupts. According to the datasheet the current 
code of PinChangeInt will work fine with PORTB, but PCINT15:9 are assigned to 
PJ6:0 (not to PC6:0), PCINT23:16 to PK7:0 (not to PD7:0), and the PCINT15 is 
assigned to PE0 (this interrupt can be ignored). i don't have the mega yet, so 
i can't test the interrupts but in theory are only a few changes. best regards!

juan64bits

Original comment by jgbmtheb...@gmail.com on 20 Feb 2012 at 1:44

GoogleCodeExporter commented 8 years ago
This link
http://code.google.com/p/arduino-pinchangeint/wiki/Usage

states that the ATMega is not supported because

 "The author has no other Arduinos"

If the author(s) send me a private email, I will loan you the use of an ATMEGA 
2560 Arduino so that you can make the pinchangeint library work with it.

How does that sound to you?

Original comment by cappy2...@gmail.com on 22 Feb 2012 at 6:20

GoogleCodeExporter commented 8 years ago
Thank you all for your continued interest.  No promises but with Cappy's help 
maybe we can get Mega support for this thing!

Original comment by m...@schwager.com on 23 Feb 2012 at 6:27

GoogleCodeExporter commented 8 years ago
Any status updates on support for the MEGA? I have a MEGA and I'm willing to do 
the modifications to the library if no one else has completed this task already.

Original comment by markal...@gmail.com on 12 Apr 2012 at 12:34

GoogleCodeExporter commented 8 years ago
No updates.  It's on my radar... but that doesn't mean a whole lot, since I'm 
busy with all sorts of things (work, fatherhood, completing my own Arduino 
project).  Sooooo... if you're offering, well, heck ya!  That would be awesome 
to get more fingers in the pot so to speak and make some progress on it!

Your modifications are welcome and will become part of the regular distribution 
when complete.

Original comment by m...@schwager.com on 12 Apr 2012 at 12:52

GoogleCodeExporter commented 8 years ago
I understand, I have the same responsibilities, but I'm working on a hobby 
robot project with my kids and we are using a MEGA and would love this 
functionality. I have checked out the code and will work on it and submit 
patches. I'm not making any promises on delivery date but should happen in the 
next month or so depending on my schedule. I just didn't want to duplicate 
efforts if someone else was active on the issue. I will keep you updated on my 
progress.

Original comment by markal...@gmail.com on 12 Apr 2012 at 5:29

GoogleCodeExporter commented 8 years ago
Hi Guys,

Any work in progress? I'm also a happy mega owner and willing to put some 
effort into the project.

In order to proceed, can someone decode the comment #6 for me, it seems the 
author already compared the specs, but I cannot really follow it.

Cheers,

T

Original comment by cserveny...@gmail.com on 4 Jun 2012 at 7:06

GoogleCodeExporter commented 8 years ago
Hi,

Please find attach the first-cut patch for the Mega boards.

Here is the list of detailed changes:

Mega and friends are using port B, J and K for interrupts. 

B is working without any modifications.

J is mostly useless, because of the hardware UART. I was not able to get pin 
change notifications from the TX pin (14), so only 15 left. All other pins are 
not connected on the arduino boards.

K controls arduino pin 8-15, working fine.

328/168 boards using C and D.

So in case the lib is compiled with mega target, the C and D will be disabled.
Also you cannot see port J/K with other targets.

For J and K new flags introduced: NO_PORTJ_PINCHANGES and NO_PORTK_PINCHANGES.
Maybe we should have PORTJ_PINCHANGES to enable PJ, because they will be most 
likely unused.

Enjoy!

Original comment by cserveny...@gmail.com on 5 Jun 2012 at 9:37

Attachments:

GoogleCodeExporter commented 8 years ago
Thanks for all the hard work!  I will take a look at it and roll it into the 
usual distribution.  I have been working on my own project so don't have a lot 
of free time right now but I will try to get this in...

Original comment by mschw...@gmail.com on 12 Jun 2012 at 2:16

GoogleCodeExporter commented 8 years ago
You can see that we have the downloads now.  Let me know any feedback you have.

Original comment by m...@schwager.com on 10 Jul 2012 at 2:11

GoogleCodeExporter commented 8 years ago
Hi,

super!

Just don't forget to update the main page: 

"; it has been reported to work just fine on the Nano. It will probably not 
work on the Arduino Mega without some serious updating. "////

Original comment by cserveny...@gmail.com on 10 Jul 2012 at 7:10

GoogleCodeExporter commented 8 years ago
I have changed the front page, but I would still like to get some feedback from 
Mega users.  Thanks.

Original comment by m...@schwager.com on 12 Jul 2012 at 4:34

GoogleCodeExporter commented 8 years ago
Thanks for getting this working with the Mega. I have had excellent success 
with Port K pins (all of them). The only issue I have found is that I am unable 
to get Port J to trigger an interrupt on pin 15.

Original comment by paul.m.w...@gmail.com on 14 Oct 2012 at 5:24

GoogleCodeExporter commented 8 years ago
ATmega 1280 gets frozen when doing PCattachInterrupt or 
PCintPort::attachInterrupt.

No more code than this:

PCintPort::attachInterrupt(4, tryfunc, CHANGE);

Sorry cant help more, Im starting.

Original comment by xkramb...@gmail.com on 28 Nov 2012 at 10:38

GoogleCodeExporter commented 8 years ago
You'll need to check the specs of the 1280, it might have different ports 
available etc...

Also, I think the .h file only mentions 2560, so you'll need to add 1280 for 
your self.

Original comment by cserveny...@gmail.com on 29 Nov 2012 at 8:48

GoogleCodeExporter commented 8 years ago
#20: Thanks, I will check it.

Original comment by xkramb...@gmail.com on 29 Nov 2012 at 8:54

GoogleCodeExporter commented 8 years ago
xkrambler, the 1280 and the 2560 should be identical regarding PinChangeInt. 
And the code supports it:

#if defined __AVR_ATmega2560__ || defined __AVR_ATmega1280__ || defined 
__AVR_ATmega1281__ || defined __AVR_ATmega2561__ || defined __AVR_ATmega640__

I think you should attach your code to your posting, and also tell us what 
board you are using.  That will help. Thanks.

Original comment by m...@schwager.com on 29 Nov 2012 at 2:55

GoogleCodeExporter commented 8 years ago
Hi all,
Is there any magic with pins 8 and 9?

I am using a Mega2560 and my interrupts are not firing.  I do know that the 
bits are flipping because digitalRead() shows that they are changing state..  I 
am driving the pins with a TLC3072 comparator, so it is (remotely) possible 
that the comparator is ringing / oscillating. This would not be visible on 
digitalRead() but should cause multiple interrupts to fire.

sample code:

[code]
// pins for comparator (quadrature decoding)
#define CH_A_DIGITAL 8
#define CH_B_DIGITAL 9

void quadrature_decode_A () {
  Serial.println("ChA interrupt..\n");
}

void quadrature_decode_B () {
  Serial.println("ChB interrupt..\n");
}

void setup() {
  // set up interrupt handler for gross quadrature decoding
  pinMode(CH_A_DIGITAL, INPUT); digitalWrite(CH_A_DIGITAL, HIGH);
  PCintPort::attachInterrupt( CH_A_DIGITAL, &quadrature_decode_A, CHANGE);

  pinMode(CH_B_DIGITAL, INPUT); digitalWrite(CH_B_DIGITAL, HIGH);
  PCintPort::attachInterrupt( CH_B_DIGITAL, &quadrature_decode_B, CHANGE);
}
[/code]

Doesn't matter if I set the change state to RISING, FALLING, or CHANGE. It 
doesn't trigger on any of them.

Original comment by orly.and...@gmail.com on 5 Apr 2013 at 6:12

GoogleCodeExporter commented 8 years ago
Just an uneducated guess: afaik they are the UART ports TX3/RX3, maybe some 
settings needs to be flipped so this port will also receive triggers. 
I was not able to get interrupts there either.

Cheers,

T

Original comment by cserveny...@gmail.com on 5 Apr 2013 at 8:27

GoogleCodeExporter commented 8 years ago
Hm. So which pins can I safely use? (there are a lot of them!) I'd rather 
rewire my prototype than muck around with the code..

Original comment by orly.and...@gmail.com on 5 Apr 2013 at 11:14

GoogleCodeExporter commented 8 years ago
B is working without any modifications.

J is mostly useless, because of the hardware UART. I was not able to get pin 
change notifications from the TX pin (14), so only 15 left. All other pins are 
not connected on the arduino boards.

-- This is what I mentioned.

K controls arduino pin 8-15, working fine.

-- This should work using my patch in the above comment. I don't know whether 
it is already merged or not.

Original comment by cserveny...@gmail.com on 5 Apr 2013 at 1:14

GoogleCodeExporter commented 8 years ago
Do not Serial.print() from inside an interrupt. Serial uses interrupts and your 
code will fail.

Set up some global volatile bool or uint8_t, one for each interrupt routine. 
Have them increment with each interrupt. Check their value in loop(), and print 
at that time.

Go to the Usage wiki page and see my example.

If it stil doesn't work, then there may be a problem with the code. But by 
using Serial.print() in the interrupt, we can't say anything about it. I'm sure 
it will fail.

Original comment by m...@schwager.com on 5 Apr 2013 at 1:37

GoogleCodeExporter commented 8 years ago
I actually didn't have those prints in there.. I was just updating a global 
variable. But the variable wasn't updating so I added the print's to see if the 
function was getting called..

Original comment by orly.and...@gmail.com on 5 Apr 2013 at 9:07

GoogleCodeExporter commented 8 years ago
Ok took out the Serial.print in the interrupt. Still no luck.

I am using SPI (heavily) in this code - hardware SPI, not bit-banging SPI.  
Could that affect the interrupt code?

Original comment by orly.and...@gmail.com on 6 Apr 2013 at 11:31

GoogleCodeExporter commented 8 years ago
SPI should not affect the code. I am working on a project that uses PinChange 
Interrupts, SPI (using the Arduino's SPI library), and I2C (using the I2C 
library by Wayne Truchess).

Unfortunately I don't have a Mega to test with, so I'm dependent upon the good 
graces of Mega owners to come to my rescue on this one. If you have the time 
and inclination it would be helpful to turn on some debugging and write a 
really simple program like my example, then use a pushbutton switch to verify 
if PORT B is actually working.

Original comment by m...@schwager.com on 8 Apr 2013 at 12:43

GoogleCodeExporter commented 8 years ago
Hi,

How can I know which pins can I use with PinChangeInt on the MEGA?
For instance I use pin 8 to 13 to read a 6 channels radio receiver but the 
ports 8 and 9 don't work.

Thanks

Original comment by romain.g...@gmail.com on 1 Sep 2013 at 4:29

GoogleCodeExporter commented 8 years ago
Hello,

I want to use Pin 6 on the Mega (PH3), is it possible?

Original comment by gus...@gmail.com on 28 Jan 2014 at 10:17

GoogleCodeExporter commented 8 years ago
As far as I recall only port J,K,B supports pin change. 

It is written in the datasheet of Atmel Mega 2560.

cheers,

T

Original comment by cserveny...@gmail.com on 28 Jan 2014 at 10:45

GoogleCodeExporter commented 8 years ago
I have solved your Port J issues:
  J is mostly useless, because of the hardware UART. I was not able to get pin change notifications from the TX pin (14), so only 15 left. All other pins are not connected on the arduino boards.

I am developing on a custom board based around the ATMEGA1280 that has two 
rotary encoders. The first is comes in on PB5 and PB6 (with a switch on PB7), 
the second is on PJ2 and PJ3 (with a switch on PJ4.) I am using the latest 
version of the AdaEncoder library (https://code.google.com/p/adaencoder/) and 
have no problems out of the box with my first encoder.

On my second encoder I would get interrupts no problem from the PJ2 line 
(PCINT11) but not from PJ3 (PCINT12), but I could read the appropriate value 
directly from the line so I know that it is configured correctly.

I narrowed the issue down to a discrepancy between the ATMEGA1280s mapping of 
the Port J pin bit locations as returned by digitalPinToBitMask() and the 
locations used by the PCMSK1 register. Bit 0 of PCMSK1 is for PCINT8 (PE0) 
*not* for PJ0 (PCINT9). PJ0 is bit 1 of this field.

When your code attempts to enable the interrupts for pins 14 and 15, it was 
actually enabling PCINT8 and PCINT9, not PCINT9 and PCINT10 like you wanted. 
The same thing was happening to me. I wanted to enable PCINT11 and PCINT12, but 
was instead only enabling PCINT10 and PCINT11.

To fix the issue I have added a public uint8_t to the PCintPin class called 
arduinoPin that is assigned the value of the arduinoPin parameter that is 
passed into the addPin function. Then in the enable function where you used to 
do:
   portPCMask |= p->mask;

I now do:
   if (digitalPinToPort(p->arduinoPin) == 10)   // port PJ==10 
   {
      portPCMask |= (p->mask) << 1;
   }
   else
   {
      portPCMask |= p->mask;
   }

This should properly reference all PCINTs for the ATMEGA regardless of what 
port they are on (B, E, and K are all properly indexed for their PCMSKn 
registers by the digitalPinToBitMask() function.)

Original comment by jrhelb...@gmail.com on 3 Jun 2014 at 9:47

Attachments:

GoogleCodeExporter commented 8 years ago
Hi, 

This is a bug in arduino, right? Would you care to create an issue for them, 
because such workarounds are very dangerous! 

cheers,

Tamas

Original comment by cserveny...@gmail.com on 4 Jun 2014 at 7:24

GoogleCodeExporter commented 8 years ago
Thanks, guys! I will dig into this; I have only just been reading the thread 
and need to study this a moment to understand the situation. But you certainly 
have found something very useful!

Original comment by m...@schwager.com on 4 Jun 2014 at 11:51

GoogleCodeExporter commented 8 years ago
I don't believe this is a big in Arduino... The digitalPinToBitMask() function 
is working as it should (It provides the correct bitmask for all other 
registers - ie PJ0 *is* bit 0 of the PINJ register as well as probably every 
other register on this chip.)

The problem here is how atmel set up the PCINTxx assignments. PCINTs on Port B 
and K work great because their "port/pin mapping" correlates perfectly with 
their PCMSKx mapping (ie. PB0 is bit 0 of the PINB register as well as bit 0 of 
the PCMSK0 register (PCINT0), PK0 is bit 0 of the PINK register as well as bit 
0 of the PCMSK2 register (PCINT16). Even PE0 works out - it is bit 0 of PINE 
register, and it is bit 0 of PCMSK1.

Port J is thrown off because PJ0 is bit 0 of the PINJ register, but it is bit 1 
of the PCMSK1 register(PCINT9).

If Atmel had started Port J with PCINT8 instead of PCINT9, the 
digitalPinToBitMask() function would work perfectly here as well.

As best as I can tell this issue only applies to the PCMSK1 register, and as 
such only applies to a library that works directly with PC Interrupts.

Original comment by jrhelb...@gmail.com on 4 Jun 2014 at 2:53

GoogleCodeExporter commented 8 years ago
JRHelbert,
I agree with you... it's not a bug in Arduino. The digitalPinToBitMask() 
function provides the correct bitmask for all PORT registers... that is its 
job; there is no digitalPinToPCMSKBitMask() function. It was the assumption 
that this function reflected the contents of the PCMSKx registers that 
eventually bit us.

Based on your code, I am producing an update to the library. I will have it out 
by the end of this weekend, I hope. I am actually working on the ooPinChangeInt 
code right now... the regular pinChangeInt should follow shortly.

Thanks again for a great find... and fix!

Original comment by m...@schwager.com on 17 Jun 2014 at 11:20

GoogleCodeExporter commented 8 years ago
I am putting the code up on Github: See 
https://github.com/GreyGnome/PinChangeInt

Original comment by m...@schwager.com on 18 Jun 2014 at 4:54

GoogleCodeExporter commented 8 years ago
The code is up. Sorry it took so long, life gets in the way of hobbies. I 
didn't change the code exactly as you did, JR. And I added the code for the 
detachInterrupt() function. This section remains untested, but I think it's 
good. Please check it out and let me know one way or the other, if you can.

Thanks.

Original comment by m...@schwager.com on 29 Jul 2014 at 4:25

GoogleCodeExporter commented 8 years ago
Great lib, thank you very much!!
I tried to use it on a Arduino Mega and it worked on Pin 10 to 15.
But it does not work on any other pin. 

I would like to use PCI on Pin 0 (Rx) to waik my Mega from low-Power sleeping 
when reciving Serial Data! (It will not be able to read the first coupple bytes 
on Serial correct, but I will keep the Mega idel for some seconds to be able to 
read the data that follow.)

How can I add the PCI for Pin0 and is it possible to "enable" the other Pins on 
the Mega as well? 

Thank you for you assistance!
Best regrads Johannes

PS: please find attached my test code for Mega

Original comment by Johannes...@googlemail.com on 9 Jun 2015 at 8:31

Attachments:

GoogleCodeExporter commented 8 years ago
There's a couple of issues here. First, this is old code so I see a few 
problems with it. pinMode needs to be INPUT_PULLUP instead of INPUT, otherwise 
the state of the input at any time is unknown- the input impedance of the 
transistors allows the voltage to be just noise. The input is said to "float". 
See http://forum.arduino.cc/index.php?topic=26629.0 . Second, you have set pin 
0 as input but there are Serial.print() statements in the code. Nothing can 
ever get printed. This is why using pin 0 and 1 is so difficult- strange things 
happen. Can you use another pin for this? Any of the External Interrupt pins 
will work. I think the Pin Change interrupt pins work too. Finally, the library 
itself is deprecated http://en.wikipedia.org/wiki/Deprecation . Would you like 
to try the new library EnableInterrupt? Here for information: 
https://github.com/GreyGnome/EnableInterrupt/wiki . Here to download: 
https://bintray.com/greygnome/generic/EnableInterrupt/view

Original comment by m...@schwager.com on 11 Jun 2015 at 11:44

GoogleCodeExporter commented 8 years ago
Thank you for the update and link to the new lib. I didn't found that before.
I quick tested the AllPins2560 Example of the 0.5 Version on a Mega and all PCI 
did work. Thank you very much! Great work! Imo it should be integrated into the 
standard Arduino IDE Examples.

Original comment by Johannes...@googlemail.com on 14 Jun 2015 at 8:55

GoogleCodeExporter commented 8 years ago
PS: To be able to wake my Mega from sleeping when an Serial message is received 
(since PCI on Pin 0(Rx) is not integrated) I just connect Pin 0 (Rx) to one of 
the other PCI-Pins, so the Controller is been waked. No need to integrate Pin0 
itself! :) 

Original comment by Johannes...@googlemail.com on 14 Jun 2015 at 9:01