External interrupt on Atmega168

Hi every one

I'm trying to control 2 dc motor EMG30 12v using my arduino uno borad, m'y 2 motors have built-in encoder so i need to read 4 interrupts and the simple atmega328 have only 2 external INTerrupts My question is, do the ATmega168 have more configured external interrupts or it has only 2 just like atmega328, because i found in the datasheet of the atmega168 ("just 2 External interrupt") and ("pin change interrupt request") and can't indursent the difference betwin

Thank you so Much !!

m168 and m328 have the same interrupt capabilities.

Ok thank you, so this means that i can only use the 2 external interrupts INT0 INT1 or i still can use the External “pin change interrupts” in my original arduino uC wich is ATmega328, sorry but i’m still getting confused about this point. Thank you so much !!

i can only use the 2 external interrupts INT0 INT1 or i still can use the External "pin change interrupts"

Both the m168 and m328 have 2 "external interrupts" that will give you an interrupt on (highly configurable) events on two particular pins. They both ALSO have "pin change interrupts" which provide one interrupt per PORT when any of the (masked) pins changes in any way. You would have to do additional work in software to decode pin-change interrupts so you knew exactly which pins changed in which direction (if that were important to know.)

I'm not familiar enough with encoder interfacing to understand what is actually required for that. It seems unlikely that you would actually need two interrupts per motor; I suspect that was just a lazy but clever implementation...

Ok now will search for pin change INTs programming in arduino or i will have to write my code in atmel uC language. Thank you so much that helpe me alot, i appreciate it ;)

PCINTs should work for this. They're a bit less intuitive than normal interrupts, and you'll need to use direct port manipulation, but it's not bad...

I would avoid using PCINT libraries - I think they tend to add more complexity rather than remove it.

The ATmega2560 (used in mega2560 board) has 8 external interrupts - though I think this can be done with PCINTs no problem.

Yes that's what i will do, now i have an other problem, my hall encoder has 360 points per round so i should count 360 coder ticks per round but what i count is just 90 ticks/round i dont know if my code is wrong or the arduino is missing some interrupts Thank's For Help‼

//#include 
//#include  

int ra=0,rb,a=0,b=0;
void setup() {
  // put your setup code here, to run once:
pinMode(8, OUTPUT);     //DR M02
pinMode(9, OUTPUT);     //PWM M01
pinMode(1, OUTPUT);     //DR M01
pinMode(0, OUTPUT);     //DR M02
pinMode(10, OUTPUT);    //PWM M02
pinMode(11, OUTPUT);    //DR M02
pinMode(2, INPUT);
pinMode(3, INPUT);
//analogWrite(9, 165);analogWrite(10, 73);
//analogWrite(9, 20);analogWrite(10, 30);
analogWrite(9,0);analogWrite(10, 75);
digitalWrite(2, 1);digitalWrite(3, 1);
digitalWrite(8, 0);digitalWrite(11, 1);
digitalWrite(1, 1);digitalWrite(0, 0);
attachInterrupt(0, GestIntCodM01, RISING);
attachInterrupt(1, GestIntCodM02, RISING);
Serial.begin(115200);

}
void loop() {
  
  //rb=digitalRead(15);
  // put your main code here, to run repeatedly:
         
//else ra=0;
//if(rb==1) b++;
Serial.print("M01 = ");Serial.print(b);
//Serial.print("\r");
Serial.print("    M02 = ");Serial.println(a);
Serial.print("\r");
//Serial.print("b = ");Serial.println(b);
}
void GestIntCodM01()
{
  a++;
  }
  void GestIntCodM02()
{
  b++;
  }
int ra=0,rb,a=0,b=0;

What lousy names for global variables. :'(

Integers for counts that start with zero and only increment?

a and b are accessed by ISRs, they have to be defined volatile and must be accessed guarded by noInterrups/interrupts.

http://gammon.com.au/interrupts

Whandall: int ra=0,rb,a=0,b=0;

What lousy names for global variables. :'(

Integers for counts that start with zero and only increment?

a and b are accessed by ISRs, they have to be defined volatile and must be accessed guarded by noInterrups/interrupts.

http://gammon.com.au/interrupts

Thank's for your remark, i changed the type of variables a,b and delated the useless variables but i still have the same result which is 90 ticks for one round and if i increase the motor's speed the arduino count less points 70 or 60 for the maximum speed

|500x378

my new simple code is

volatile long a=0;
volatile long b=0;
void setup() {
pinMode(8, OUTPUT);     //L298 Direction pin for M02
pinMode(9, OUTPUT);     //PWM for M01
pinMode(1, OUTPUT);     //Dr for M01
pinMode(0, OUTPUT);     //Dr M02
pinMode(10, OUTPUT);    //PWM M02
pinMode(11, OUTPUT);    //Dr M02
pinMode(2, INPUT);
pinMode(3, INPUT);
analogWrite(9,0);analogWrite(10, 75);    //Motors speed
digitalWrite(2, 1);digitalWrite(3, 1);       //Pull-up resistor dor encoder sensors
digitalWrite(8, 0);digitalWrite(11, 1);
digitalWrite(1, 1);digitalWrite(0, 0);
attachInterrupt(0, GestIntCodM01, RISING);
attachInterrupt(1, GestIntCodM02, RISING);
Serial.begin(115200);

}
void loop() {
Serial.print("M01 = ");Serial.print(b);
Serial.print("    M02 = ");Serial.println(a);
Serial.print("\r");
}
void GestIntCodM01()
{
  a++;
  }
  void GestIntCodM02()
{
  b++;
  }

Sorry if i didn't uderstand very well your idea & thak you for traying to help me ;)

This is quite strange, please explain why you think you need that.

pinMode(1, OUTPUT);     //Dr for M01
pinMode(0, OUTPUT);     //Dr M02

The outputs are open collector and require pull-ups to whatever signal level is required.

This means it should be

pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);

Whandall: This is quite strange, please explain why you think you need that.

pinMode(1, OUTPUT);     //Dr for M01
pinMode(0, OUTPUT);     //Dr M02

This means it should be

pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(1, OUTPUT);     //Dr for M01
pinMode(0, OUTPUT);     //Dr M02

This outputs are to change the direction of the motors using the H bridge "L298"

pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);

sincerely this is the first time i heard about "INPUT_PULLUP" mode.. i will try it now and i will be back.. Thank's

The Same results for INPUT_PULLUP mode

|416x500 |352x500

Wahrani31: pinMode(1, OUTPUT);    //Dr for M01 pinMode(0, OUTPUT);    //Dr M02

This outputs are to change the direction of the motors using the H bridge "L298"

Attaching hardware to the serial pins (0 and 1) on Mega/Uno/Nano is not the best idea if you want to use serial I/O.

Wahrani31: sincerely this is the first time i heard about "INPUT_PULLUP" mode..

Maybe you should read the documentation of the functions you are using (here: pinMode).

How did you connect the motor?

Connector

The EMG30 is supplied with a 6 way JST  connector (part no PHR-6) at the end of approx 90mm of cable as standard. 
The connections are:
Wire colour         Connection
Purple (1)      Hall Sensor B Vout
Blue (2)        Hall sensor A Vout
Green (3)       Hall sensor ground
Brown (4)       Hall sensor Vcc
Red (5)         + Motor
Black (6)       - Motor

Wire colours are from the actual cable.
The hall sensors accept voltages between 3.5v and 20v.
The outputs are open collector and require pull-ups to whatever signal level is required.
On the MD25 they are powered from 12v and pulled up to 5v for the signals.

specification

Rated voltage       12v
Rated torque        1.5kg/cm
Rated speed        170rpm
Rated current       530mA
No load speed       216
No load current         150mA
Stall Current          2.5A
Rated output        4.22W
Encoder counts per output shaft turn        360

...so i need to read 4 interrupts

Probably you don't supply power to the halls, because you believe there are 4 outputs?

no sir i am using a module like this one |500x333 and vcc of Hall sensor is driven out from the same module in the 5v output and the tow outputs for the direction are attached to the Enable PINs in the module

How do you connect the 6 lines from the motor?

D2 Purple (1)       Hall Sensor B Vout
D3 Blue (2)         Hall sensor A Vout
?? Green (3)        Hall sensor ground
?? Brown (4)        Hall sensor Vcc
HB Red (5)      + Motor
HB Black (6)        - Motor

Green and Brown are connected to?

The gree pin is connected to the GND of the L298 and the brown is connected to the VCC which is a 5V DC suplay

And the GND of the Arduino is connected to the GND of the power supply?

my hall encoder has 360 points per round so i should count 360 coder ticks per round but what i count is just 90 ticks/round

Are you sure that "360 points" doesn't become "90 ticks" once you run it through quadrature decoding?

attachInterrupt(0, GestIntCodM01, RISING);
attachInterrupt(1, GestIntCodM02, RISING);
void GestIntCodM01()
{
  a++;
  }
  void GestIntCodM02()
{
  b++;
  }

westfw is correct. Selection of one pin Rising will read only one in four of the quadrature transitions. It will not handle a change in direction either. You have a choice of 90,180, 360 counts per revolution. What do you require?

You will need to read the state of the other encoder pin to determine direction.

Whandall: And the GND of the Arduino is connected to the GND of the power supply?

Yes Sir all the components have a common GND to reach the full speed of motor.

westfw: Are you sure that "360 points" doesn't become "90 ticks" once you run it through quadrature decoding?

in the datasheet i have found this, i think if the encoder should return '90 ticks' so they would write '90' instead '360' didn't they ?

|500x256

cattledog: It will not handle a change in direction either. You have a choice of 90,180, 360 counts per revolution. What do you require? You will need to read the state of the other encoder pin to determine direction.

For me sir, 90 ticks/rd is totaly enough but the probleme is that i get it just if i run in the slowest speed and when i increas the speed the ticks counted decrease so i can never calculate the real speed in this case, for now i don't need to detect the direction of the mototrs i want just define the speed.

cattledog: westfw is correct. Selection of one pin Rising will read only one in four of the quadrature transitions.

so, i have to connect the 2 chanel of the encoder and incremant my counter "a" even if the interrupt come from chanel A or B to detect all the ticks is this right.