Arduino Forum

Using Arduino => Microcontrollers => Topic started by: Wahrani31 on Apr 16, 2016, 09:50 pm

Title: External interrupt on Atmega168
Post by: Wahrani31 on Apr 16, 2016, 09:50 pm
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 !!
(http://www.robot-electronics.co.uk/images/emg30.jpg)
Title: Re: External interrupt on Atmega168
Post by: westfw on Apr 17, 2016, 03:23 am
m168 and m328 have the same interrupt capabilities.
Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on Apr 18, 2016, 08:38 am
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 !!
Title: Re: External interrupt on Atmega168
Post by: westfw on Apr 18, 2016, 11:49 am
Quote
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...
Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on Apr 20, 2016, 07:42 pm
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 ;)
Title: Re: External interrupt on Atmega168
Post by: DrAzzy on Apr 20, 2016, 07:50 pm
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.
Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on Apr 29, 2016, 04:51 pm
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ā€¼


Code: [Select]
//#include <FlexiTimer2.h>
//#include <digitalWriteFast.h>

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++;
  }


Title: Re: External interrupt on Atmega168
Post by: Whandall on Apr 29, 2016, 08:39 pm
Code: [Select]
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 (http://gammon.com.au/interrupts)
Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on Apr 30, 2016, 09:18 pm
Code: [Select]
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 (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

(http://store1.up-00.com/2016-04/146204124307231.jpg)

my new simple code is


Code: [Select]

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  ;)
Title: Re: External interrupt on Atmega168
Post by: Whandall on Apr 30, 2016, 10:08 pm
This is quite strange, please explain why you think you need that.

Code: [Select]
pinMode(1, OUTPUT);     //Dr for M01
pinMode(0, OUTPUT);     //Dr M02


Quote
The outputs are open collector and require pull-ups to whatever signal level is required.
This means it should be

Code: [Select]
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on Apr 30, 2016, 10:14 pm
This is quite strange, please explain why you think you need that.

Code: [Select]
pinMode(1, OUTPUT);     //Dr for M01
pinMode(0, OUTPUT);     //Dr M02


This means it should be

Code: [Select]
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);

Code: [Select]
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"

Code: [Select]
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
Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on Apr 30, 2016, 10:24 pm
The Same results for INPUT_PULLUP mode

(http://store1.up-00.com/2016-04/146204581077612.jpg)
(http://store1.up-00.com/2016-04/146204581071961.jpg)
Title: Re: External interrupt on Atmega168
Post by: Whandall on Apr 30, 2016, 10:49 pm
Code: [Select]
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.

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?

Code: [Select]
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


Quote
...so i need to read 4 interrupts
Probably you don't supply power to the halls, because you believe there are 4 outputs?
Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on Apr 30, 2016, 11:20 pm

no sir i am using a module like this one
(http://cdn.instructables.com/FRJ/7W76/HZDYE1YD/FRJ7W76HZDYE1YD.MEDIUM.jpg)
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
Title: Re: External interrupt on Atmega168
Post by: Whandall on May 01, 2016, 12:38 am
How do you connect the 6 lines from the motor?

(http://www.robot-electronics.co.uk/images/emg30.jpg)

Code: [Select]
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?

Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on May 01, 2016, 02:14 am
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
Title: Re: External interrupt on Atmega168
Post by: Whandall on May 01, 2016, 02:17 am
And the GND of the Arduino is connected to the GND of the power supply?
Title: Re: External interrupt on Atmega168
Post by: westfw on May 01, 2016, 02:40 am

Quote
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?
Title: Re: External interrupt on Atmega168
Post by: cattledog on May 01, 2016, 03:29 am
Code: [Select]
attachInterrupt(0, GestIntCodM01, RISING);
attachInterrupt(1, GestIntCodM02, RISING);


Code: [Select]
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.
Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on May 01, 2016, 10:31 am
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.

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 ?

(http://store2.up-00.com/2016-05/146208827823481.jpg)

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.

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.
Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on May 01, 2016, 10:48 am
i tried to incremant the counter even if the interrupt is received from the first chanel or the second and this is what i got for one motor, '2 X 90' tick

(http://store1.up-00.com/2016-05/146209008804621.jpg)

Thank you every one for encoraging me, i began to lose hope to use PID controller in my robot but with your help i am sure that i will do it soon  ;)
Title: Re: External interrupt on Atmega168
Post by: cattledog on May 01, 2016, 04:12 pm
Please post the latest version of your code.

Is the main problem that the counts go down with increasing speed?


Quote
The Same results for INPUT_PULLUP mode
Are they still in your latest code? The open collector Hall sensors will require some pullups.
The internal pullups may not be strong enough, and you can use external pullups of 4.7K to 5v on pins 2 and 3.
Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on May 01, 2016, 10:27 pm
Please post the latest version of your code.

Is the main problem that the counts go down with increasing speed?


Are they still in your latest code? The open collector Hall sensors will require some pullups.
The internal pullups may not be strong enough, and you can use external pullups of 4.7K to 5v on pins 2 and 3.
Hi mr.cattledog
here is the too last code that i tried
Code: [Select]
//#include <FlexiTimer2.h>
//#include <digitalWriteFast.h>
volatile long a=0;
volatile long 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_PULLUP);
pinMode(3, INPUT_PULLUP);
//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(9600);

}
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++;
  }

befor using internel pull_up, i used 4.7k and 10k and even 39k ohm resistors but alwase the same results
Title: Re: External interrupt on Atmega168
Post by: westfw on May 01, 2016, 10:37 pm

Quote
 if the encoder should return '90 ticks' so they would write '90' instead '360' didn't they ?
It's a combination of the hardware and the software you are using.
It's called a quadrature encoder because it has four states that repeat when you rotate in either direction.  The software has to decode the states to figure out which direction the shaft is turning.  What I'm suspecting is that the motor encoder goes through 360 states per revolution, but the arduino software is "decoding" a full 4-state cycle before it reports a step in one direction or the other.  (probably, you need at least two or four states to determine direction, UNLESS you save the "last known direction" in the driver somewhere.  Since a lot of the arduino applications that use encoders are aimed at user knobs rather than  higher-speed motors, the library probably isn't trying to be a high-performance high-accuracy implementation.
Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on May 02, 2016, 08:32 pm
It's a combination of the hardware and the software you are using.
It's called a quadrature encoder because it has four states that repeat when you rotate in either direction.  The software has to decode the states to figure out which direction the shaft is turning.  What I'm suspecting is that the motor encoder goes through 360 states per revolution, but the arduino software is "decoding" a full 4-state cycle before it reports a step in one direction or the other.
Thank you very much bro, this analysis is logical, but My only problem with the engines is that it does not give me the same number of points for various speeds, and when the speed increase the number of counted ticks decrease.
Title: Re: External interrupt on Atmega168
Post by: Whandall on May 02, 2016, 08:46 pm
The code you show does not produce te output you show.

It blocks on serial with 9600 baud.

You do not have the sligthest chance to see the real counts.

The accesses are still unguarded.

Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on May 02, 2016, 08:58 pm
The code you show does not produce te output you show.

It blocks on serial with 9600 baud.

You do not have the sligthest chance to see the real counts.

The accesses are still unguarded.


But i tried to print results using a fast baud rate "115000" and a slow baud rate "1200" and it shows me the same results
Title: Re: External interrupt on Atmega168
Post by: Whandall on May 02, 2016, 09:20 pm
The code you show does not produce the output you show.
BTW its hard to believe that b never gets incremented.

Code: [Select]
void loop() {
  Serial.print("M01 = ");
  Serial.print(b);
  Serial.print("    M02 = ");
  Serial.println(a);
  Serial.print("\r");
}

The above code can only print ascending numbers, apart from the artefacts that your non-guarding will produce.

Demo for you still unfixed guarding issue
Code: [Select]
void setup() {
  Serial.begin(115200);
  Serial.println(F("wait for error..."));
  // set up Timer 1
  TCCR1A = 0;                        // normal operation
  TCCR1B = bit(WGM12) | bit(CS10);   // CTC, no pre-scaling
  OCR1A =  10999;                    // compare A register value (1000 * clock speed)
  TIMSK1 = bit(OCIE1A);              // interrupt on Compare A Match
}
volatile unsigned long Counter;

ISR(TIMER1_COMPA_vect)
{
  Counter++;
}

void loop() {
  static unsigned long before;
  static unsigned long current;
  //  noInterrupts();
  current = Counter;
  //  interrupts();
  unsigned long differenz = current - before;
  if (differenz > 1) {
    Serial.print(F("from 0x"));
    Serial.print(before, HEX);
    Serial.print(F(" to 0x"));
    Serial.print(current, HEX);
    Serial.print(F(" diff 0x"));
    Serial.println(differenz, HEX);
  }
  before = current;
}
Code: [Select]
wait for error...
from 0x9FF to 0xAFF diff 0x100
from 0xAFF to 0xA01 diff 0xFFFFFF02
from 0x2DFF to 0x2EFF diff 0x100
from 0x2EFF to 0x2E01 diff 0xFFFFFF02
from 0x38FF to 0x39FF diff 0x100
from 0x39FF to 0x3901 diff 0xFFFFFF02
from 0x6BFF to 0x6CFF diff 0x100
from 0x6CFF to 0x6C01 diff 0xFFFFFF02
from 0x6EFF to 0x6FFF diff 0x100
from 0x6FFF to 0x6F01 diff 0xFFFFFF02
from 0x72FF to 0x73FF diff 0x100
from 0x73FF to 0x7301 diff 0xFFFFFF02
from 0x84FF to 0x85FF diff 0x100
from 0x85FF to 0x8501 diff 0xFFFFFF02
from 0x91FF to 0x92FF diff 0x100
from 0x92FF to 0x9201 diff 0xFFFFFF02
Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on May 02, 2016, 09:58 pm
The code you show does not produce the output you show.
BTW its hard to believe that b never gets incremented.
I assure you that it is the same code, i just don't need to read the 2 signals so i removed one chanel signal, that's all. i wanted to compare between values read from the same chanel for various speeds
Title: Re: External interrupt on Atmega168
Post by: cattledog on May 02, 2016, 10:14 pm
Here is how to modify your loop to make the protected copies of the volatile variables.
Declare your protected copies along with the voltatile variables.

Code: [Select]

volatile long a=0;
volatile long b=0;
long copy_a = 0;
long copy_b = 0;


Code: [Select]

void loop() {
 
noInterrupts();
copy_a = a;
copy_b = b;
interrupts();
 
Serial.print("M01 = ");
Serial.print(copy_b);
Serial.print("    M02 = ");
Serial.println(copy_a);
}
Title: Re: External interrupt on Atmega168
Post by: Whandall on May 02, 2016, 10:18 pm
If you want to see signals per revolution, you have to reset the count on each round(*).

Printing the counts as fast as the (blocking!!!!) serial line allows, shows nothing, apart from ascending numbers.

(*) Yes, this reset has to be guarded by noInterrupts/interrupts too, because the fields are multi-byte and volatile.
Title: Re: External interrupt on Atmega168
Post by: Whandall on May 02, 2016, 10:49 pm
You could try to print the counts each second
Code: [Select]
volatile long a = 0;
volatile long b = 0;

void GestIntCodM01() {
  a++;
}
void GestIntCodM02() {
  b++;
}
void setup() {
  Serial.begin(9600);
  pinMode(8, OUTPUT);     //DR M02
  pinMode(9, OUTPUT);     //PWM M01
  pinMode(1, OUTPUT);     //DR M01 ARE YOU SHURE ABOUT PIN 0 AND 1 ???
  pinMode(0, OUTPUT);     //DR M02 ARE YOU SHURE ABOUT PIN 0 AND 1 ???
  pinMode(10, OUTPUT);    //PWM M02
  pinMode(11, OUTPUT);    //DR M02
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  analogWrite(9, 0); analogWrite(10, 75);
  digitalWrite(8, 0); digitalWrite(11, 1);
  digitalWrite(1, 1); digitalWrite(0, 0);
  attachInterrupt(0, GestIntCodM01, RISING);
  attachInterrupt(1, GestIntCodM02, RISING);
}
void loop() {
  static unsigned long lastPrint;
  unsigned long topLoop = millis();

  if (topLoop - lastPrint >= 1000) {
    lastPrint = topLoop;

    noInterrupts();
    long copy_a = a;
    long copy_b = b;
    a = 0;
    b = 0;
    interrupts();

    Serial.print("M01 = ");
    Serial.print(copy_b);
    Serial.print("    M02 = ");
    Serial.println(copy_a);
  }
}
Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on May 04, 2016, 12:12 am
You could try to print the counts each second
Code: [Select]
volatile long a = 0;
volatile long b = 0;

void GestIntCodM01() {
  a++;
}
void GestIntCodM02() {
  b++;
}
void setup() {
  Serial.begin(9600);
  pinMode(8, OUTPUT);     //DR M02
  pinMode(9, OUTPUT);     //PWM M01
  pinMode(1, OUTPUT);     //DR M01 ARE YOU SHURE ABOUT PIN 0 AND 1 ???
  pinMode(0, OUTPUT);     //DR M02 ARE YOU SHURE ABOUT PIN 0 AND 1 ???
  pinMode(10, OUTPUT);    //PWM M02
  pinMode(11, OUTPUT);    //DR M02
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  analogWrite(9, 0); analogWrite(10, 75);
  digitalWrite(8, 0); digitalWrite(11, 1);
  digitalWrite(1, 1); digitalWrite(0, 0);
  attachInterrupt(0, GestIntCodM01, RISING);
  attachInterrupt(1, GestIntCodM02, RISING);
}
void loop() {
  static unsigned long lastPrint;
  unsigned long topLoop = millis();

  if (topLoop - lastPrint >= 1000) {
    lastPrint = topLoop;

    noInterrupts();
    long copy_a = a;
    long copy_b = b;
    a = 0;
    b = 0;
    interrupts();

    Serial.print("M01 = ");
    Serial.print(copy_b);
    Serial.print("    M02 = ");
    Serial.println(copy_a);
  }
}

Thank you Mr.Whandall
i let my robot todey with a friend and i will recuperate it tomorrow to test the code that you provided to me, i hope that this one will work properly,Thank you Sir and I apologize for the disturbance   :smiley-red:   
Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on May 04, 2016, 12:38 am
Here is how to modify your loop to make the protected copies of the volatile variables.
Declare your protected copies along with the voltatile variables.

Code: [Select]

volatile long a=0;
volatile long b=0;
long copy_a = 0;
long copy_b = 0;


Code: [Select]

void loop() {
  
noInterrupts()
copy_a = a;
copy_b = b;
interrupts()
  
Serial.print("M01 = ");
Serial.print(copy_b);
Serial.print("    M02 = ");
Serial.println(copy_a);
}

Thank you too Mr.cattledog i will test the variables copy_a and copy_b and i will provide you with results

The next video shows the first test of my modest robot following a short black line
My_Line_Follower_First_Steps (https://www.dropbox.com/s/04cjq2zvkxwojtw/My_Line_Follower_First_Steps.mp4?dl=0)

Title: Re: External interrupt on Atmega168
Post by: Wahrani31 on May 05, 2016, 01:42 am


Mr.Whandall, yes i am 100% sure about the OUTPUTS to control the motors direction,
however when i implemented your code into my robot i catched just one motor and the other was not moving.. this are the results for 2 different speeds "pwm" when the motor runs for 10 round and the 1 tiks chanels of the encoder are councted, so the results are for the same motor not for 2 motors
(http://store2.up-00.com/2016-05/1462399215462.jpg)
(http://store2.up-00.com/2016-05/1462399215673.jpg)
-------------------------------------------------------------------------------------------------------------------------------------------------
Thank You Very Much Mr.cattledog I got the following ressults using the modification that you told to me and the deffernce b'twin the number of ticks counted for slow and high speed is now Reduced
(http://store2.up-00.com/2016-05/146239921531.jpg)
(http://store2.up-00.com/2016-05/1462399215794.jpg)
I made the motors to run until the ticks counted reach 90 ticks but i had a passing for about 10 or 15 ticks and my motor was doing 1.15 round, but when i diminuate the number of ticks to 80 ticks the motor was doing a perfect 1 round and the arduino counted 92 ticks/rd
(http://store2.up-00.com/2016-05/1462404018661.jpg)

Thank You So Much Sir, You and The Other Memebrs helped me alot.