Arduino Stack Exchange is a question and answer site for developers of open-source hardware and software that is compatible with Arduino. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

This is a segment of an Arduino sketch, that I am trying to understand.

I know that the purpose of the entire code is to control 2 stepper motors linked to their respective drivers which are linked to a Mega 2560, but since I am new to Arduino, I am having problems with some functions.

This is a segment of the code. I am having problems with some statements such as unsigned short FLG = 0; and I cannot make out at all the timer interrupts part.

What does it all mean?

/* The “define” function is NOT A PROGRAMMING STATEMENT. Actually it sets up a macro which causes a text replace to occur before code is compiled. The pre-processor of the IDE will replace the variables such as “stp” to the integer value 22 in the following subsequent sections like the “void setup” function and the “loop” function if they are called. This function helps reduce RAM usage. */

#define stp 22
#define dir 23
#define stp2 26
#define dir2 27
#define EN  24
#define dir_ 25


int i, j, t, X = 0, Y = 0, Z = 0;
// here, the integer is creating variables such as i, j, t
//and also assigning values to some of them such as X, Y and Z.

unsigned short FLG = 0;

unsigned int Speed1 = 0, Speed2 = 0; // creating variables assigning initial values; due to unsinged only positive

int ser_1[3];

int po(int, int);

void setup() {     // You define how your Arduino will be used and set up any pins and communications you will be using. This will run first and only once.

  Serial.begin(9600); // begin the data transmission between Arduino and pc at speed of 9600 bits per sec
  delay(500); // stop for 500 milliseconds

  Serial.println(“hi”); // this will print the word “hi” on the serial monitor window on pc via serial port

  pinMode(stp, OUTPUT); // tells arduino to use digital Pin 22 to output electricity
  pinMode(dir, OUTPUT); // tells arduino to use digital Pin 23 to output electricity
  pinMode(stp2, OUTPUT); // tells arduino to use digital Pin 26 to output electricity
  pinMode(dir2, OUTPUT); // tells arduino to use digital Pin 27 to output electricity
  pinMode(EN, OUTPUT); // tells arduino to use digital Pin 24 to output electricity

  noInterrupts(); // to prevent disruption of timing of codes, disables some functions in the background

  /* To use timers, the built-in timer registers on the AVR chip that store timer settings need to be configured.  There are a number of registers per timer.  Two of these registers –the Timer/Counter Control Registers- hold setup values, and are called TCCRxA and TCCRxB, where x is the timer number (TCCR1A and TCCR1B, etc.).   Each register holds 8 bits, and each bit stores a configuration value. */

  TCCR1A = 0x80; //
  TCCR1B = 0x0A; // Enable reset on compare match, 1:8 clock. don’t understand
  OCR1AH = 0x9C;
  OCR1AL = 0x3F;
  TIMSK1 = (1 << OCIE1A); // enable timer compare interrupt
  interrupts();
}
ISR(TIMER1_COMPA_vect)   // timer compare interrupt service routine
{
  res();
}
share|improve this question
    
It will be better if you also explain about what you are trying to achieve. – dpw yesterday
    
You need to be more specific.What aspect of the line of code don't you understand? What other lines of code are you having trouble with? – sa_leinad yesterday
    
this is C code and you need to look into declaring variables and functions in C to understand the syntax – user17915 yesterday
    
unsigned, short, int etc are variable types, words with the format name(..., ...) are functions, int ser_1[3]; is an array of size 3, #define is not called a "function" and is more like automated copy-paste; for instance, #define stp 22 replaces all the instances of the word "stp" by the number "22" when compiling – user17915 yesterday

I am having problems with some statements such as "unsigned short FLG = 0;"

This is the C and C++ syntax for declaring a variable. The statement means “Let FLG be an unsigned short integer and let it's initial value be zero”. An unsigned short can hold any integer value between 0 and 65535 inclusive.

The Arduino language reference documents the types short and unsigned int but, for a mysterious reason, it does not document unsigned short.

I cannot make out at all the timer interrupts part.

Nobody can unless they know the internals of the AVR timers, which are non trivial but are well covered in the datasheet. It's a thick document, but you only need to study chapters 14: Interrupts and 17: 16-bit Timer/Counter (Timer/Counter 1, 3, 4, and 5).

I recommend you first read the Timers and counters tutorial by Nick Gammon, then go to the datasheet for the most authoritative information.

Edit: Just a comment... I find the program you have posted to be written with poor programming style. More specifically, the section setting the Timer 1 registers would be better written as follows:

TCCR1A = bit(COM1A1);  // set OC1A to LOW on compare match
TCCR1B = bit(WGM12)    // CTC mode, TOP = OCR1A
       | bit(CS11);    // clock at F_CPU / 8
OCR1A  = 40000 - 1;    // period = 40000 prescaled clock cycles
TIMSK1 = bit(OCIE1A);  // enable COMPA interrupt

It is still obscure if you don't know the timer, but using explicit bit names instead of pure numbers makes things a lot easier when you refer to the datasheet. Also, there is no point in setting each byte of OCR1A in a different statement: it only makes things harder to read.

share|improve this answer

I'm assuming you don't mean "all" when you ask "what does it all mean?" I also assume that the comments are from you - in which case you've done reasonably well!

/* The “define” function is NOT A PROGRAMMING STATEMENT... */

True, #define isn't a programming statement that produces code: it's a way of defining a symbol that you can use in the rest of the code, both for explanation purposes and ease of changing: without having to search for all copies of 22 - and then decide if this particular 22 is for that pin or not.

unsigned short FLG=0;

int is 16 bits in the Arduino, but in some systems it's 32 (and in others 64). short is (practically) always 16 bits regardless of system, so many programmers use short when they know they definitely want a 16-bit integer. unsigned merely means that it can never go negative - which allows the variable to hold higher values (0 to 65,535 instead of -32,768 to 32,767).

int ser_1[3];

This is an array of 3 ints called ser_1, which can be accessed as ser_1[0], ser_1[1] and ser_1[2]. In C, all arrays start at 0. Why use an array? It makes it possible to use another variabe to say which ser_1 you want: e.g. ser_1[i]. If i is 2, you get the last one.

int po(int,int);

This says that there will be a function called po that takes two int values, processes them, and returns an int result.

noInterrupts(); // to prevent disruption of timing of codes, disables some functions in the background

Pretty much. An interrupt can happen at any time: the CPU will stop executing the main program, execute the interrupt code, then resume where it left off in the main program. Sometimes that's a bad thing! If the interrupt code is going to change something that this code needs to stay the same (or vice versa!), then Bad Things can happen. To prevent that, you can turn off interrupts temporarily with this function, and turn them on again later with interrupts() (which you'll see below).

/* To use timers, the built-in timer registers on the AVR chip that store timer settings need to be configured.  There are a number of registers per timer.  Two of these registers –the Timer/Counter Control Registers- hold setup values, and are called TCCRxA and TCCRxB, where x is the timer number (TCCR1A and TCCR1B, etc.).   Each register holds 8 bits, and each bit stores a configuration value. */

 TCCR1A = 0x80; // 
 TCCR1B = 0x0A; // Enable reset on compare match, 1:8 clock. don’t understand

OK, this is complicated:

  • By default, a timer simply counts from 0 to 65,535 (maximum 16 bit value), then resets and starts again.
  • How quickly? One 'tick' is the system clock, so very quickly! But you can "pre-scale" that with a divisor. In this case, they're using a divisor of 8, so the timer will "tick" an eighth as fast.
  • You can configure the timer to interrupt when it resets, so that special code will execute on a timed basis.
  • You can also tell it that if at any time it hits a certain number to also interrupt (Compare Match) - that's two different interrupts.
  • You can also tell it that when it hits that Compare number, to reset back to 0 and start counting again. That means that the timer will interrupt more often.

OCR1AH = 0x9C;
OCR1AL = 0x3F;

These stand for "Output Compare Register 1A High" and "Output Compare Register 1A Low" - a 16 bit value that is 0x9C3F (37839 decimal). If you divide the system clock by that number, (and a further 8 for the pre-scaler), you'll find out how often it interrupts.

interrupts();

This turns on interrupts again.

ISR(TIMER1_COMPA_vect)   // timer compare interrupt service routine
{
res();
}

This is the code that executes every timer interrupt. I don't know what res() does.

share|improve this answer

Here is some explanation :

TCCR1A = 0x80; //OC1 will cleared on compare match
TCCR1B = 0x0A; //Turn on CTC mode --> it means the interrupt counter will reset to 0, and causing the interrupt happen again and again.
               //Divide clock 1:8 (prescaler)
OCR1AH = 0x9C;
OCR1AL = 0x3F; //compare value = 0x9C3F = 39999
TIMSK1 = (1<<OCIE1A); // the micro will jump to the Output Compare A Interrupt vetor upon compare match.

Overall, this setup will make your program do whatever you put in the Interrupt Service Routine ISR(TIMER1_COMPA_vect){...do whatever here...}

The interrupt interval is =

(OCR1A+1) × prescaler ÷ F_CPU

(39999+1) × 8 ÷ 16.000.000 = 0.02 sec

as for res(); and unsigned short FLG; I dont know what that is, since its probably your own creation (not from arduino libs)

You can found more detailed explanation here and here

share|improve this answer
    
The interval is (OCR1A+1) × prescaler ÷ F_CPU = 2 ms. – Edgar Bonet yesterday
    
Ah my bad. wrong calculation. thanks – dpw yesterday
    
@EdgarBonet - Did you mean 20 ms or 2 ms? The calculation, with the numbers supplied, gives 20ms. – Greenonline yesterday
2  
@Greenonline: My mistake: I typed 3999 instead of 39999 in my calculator. The correct value is indeed 20 ms. – Edgar Bonet yesterday

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.