Go Down

Topic: Help with Scoping (Read 513 times) previous topic - next topic

BriPSmith

Oct 28, 2011, 01:02 pm Last Edit: Oct 28, 2011, 01:47 pm by AWOL Reason: 1
Just started with the Arduino, finding 'scoping' a bit of an issue, usually code via assembler or Basic. So my problem is that I'm trying to write/convert a library for product I already have using a PIC, and I can't for the life of me sort out scoping errors. I have an ISR I want to place in the library but it produces a scoping error for the variables it uses. I also get scoping errors when I try to initialize variables in the .cpp, especially arrays either empty or filled with values.

Any help or guidance would be gratefully received, copy of files below:

Copy of sketch:
Code: [Select]
//EGamer tester for Library

//Includes
#include <avr/pgmspace.h>
#include <Egamer.h>

Egamer Eg;

//Setup Vars
volatile int Trac = 0;
//Screen variables
byte Display[8];
byte MatCol[] = {40,0,8,24,16,32,48,56};
byte Backg[24];
byte TxtLayer[8];
byte Xpos = 0;
byte Ypos = 0;

//Setup constants
const byte Splash[] PROGMEM = {31,21,21,0,255,129,133,199};

//Main setup function
void setup()
{
 Eg.Config();

 //eGamer Splash Screen
 for (int i = 0; i < 8; i++){
   Display[i] = pgm_read_byte(&Splash[i]);
 }
 
 delay(1000);
}


//ISR here
ISR(TIMER1_COMPA_vect)
{
   PORTD = Display[Trac];
   PORTC = MatCol[Trac];
   Trac++;
   Trac &= B00000111;
}

//Main loop
void loop()
{
 
 for (int i = 0; i < 8; i++){
   Display[i] = ~Display[i];
 }
 
 delay(1000);


}


Copy of the .h file
Code: [Select]
/*
eGamer.h - Library for the eGamer Shield
Created by Brian P Smith, 26.08.11.
*/

#ifndef Egamer_h
#define Egamer_h
#include "WProgram.h"

class Egamer {

public:

 void Config(void);

private:

};

#endif


Copy of the .cpp file
Code: [Select]
/*
eGamer.cpp - Library for the eGamer Shield
Created by Brian P Smith, 26.08.11.
*/

#include "WProgram.h"
#include "Egamer.h"

extern "C"
{
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
}

void Egamer::Config(void)
{

 //Setup ports for the display, buttons, joystick & audio
 //PortD = Row data - 76543210
 DDRD = B11111111;
 //PortC = Column + Buttons - xxCBAxba
 pinMode(A0, INPUT);
 pinMode(A1, INPUT);
 pinMode(A2, INPUT);
 pinMode(A3, OUTPUT);
 pinMode(A4, OUTPUT);
 pinMode(A5, OUTPUT);
 //PortB = Joystick +6 Audio - xxACuldr
 DDRB = B00110000;

 //Basic interrupt system
   // Disable interrupts while setting registers
   cli();
   // Reset control registers
   TCCR1A = 0;
   TCCR1B = 0;
   TCNT1 = 0;
   // Interrupt every 16000000/256/400Hz, 1 column per call
   OCR1A = 150;
   // Clear Timer on Compare Match (CTC) Mode
   bitSet(TCCR1B, WGM12);
   // Prescaler x1024
   //bitSet(TCCR1B, CS10);
   //bitSet(TCCR1B, CS11);
   bitSet(TCCR1B, CS12);
   // Use system clock for Timer/Counter2
   //bitClear(ASSR, AS2);
   // Reset Timer/Counter2 Interrupt Mask Register
   //TIMSK1 = 0;
   // Enable Output Compare Match A Interrupt
   bitSet(TIMSK1, OCIE1A);
   // Enable interrupts once registers have been updated
   sei();

}


Moderator edit: Code boxes instead of quotes to remove spurious italics.
BPS

PaulS

That's everything but the error messages...

BriPSmith

Ok, if I put the ISR into the .cpp file and the the arrays Display[8] and MatCol[8], the error I get is Display not known in this scope, ditto for MatCol. I have tried to follow a couple of examples but always have the same problem that any variables or arrays identified in the .h and created in the .cpp file always give scoping errors. Is there a specific method to set them up, I'm ok with the idea of private and public but I feel I'm missing something that different to my usual environments.

The ISR have tried to add the the .cpp is:
Code: [Select]
ISR(TIMER1_COMPA_vect)
{
    PORTD = Display[Trac];
    PORTC = MatCol[Trac];
    Trac++;
    Trac &= B00000111;
}


The error that I get is:
Quote

C:\Program Files\Arduino\arduino-0022\libraries\Egamer\Egamer.cpp: In function 'void __vector_11()':
C:\Program Files\Arduino\arduino-0022\libraries\Egamer\Egamer.cpp:60: error: 'Display' was not declared in this scope
C:\Program Files\Arduino\arduino-0022\libraries\Egamer\Egamer.cpp:60: error: 'Trac' was not declared in this scope
C:\Program Files\Arduino\arduino-0022\libraries\Egamer\Egamer.cpp:61: error: 'MatCol' was not declared in this scope


If I try to add them to the .h file and create them in the .cpp, I get the same error, I must be missing a connection between the two files in how variables are identified and subsequently created.

Thanks
BPS

PaulS

#3
Oct 28, 2011, 09:19 pm Last Edit: Oct 28, 2011, 09:22 pm by PaulS Reason: 1
Quote
I have tried to follow a couple of examples but always have the same problem that any variables or arrays identified in the .h and created in the .cpp file always give scoping errors.

This statement is incompatible with declaring variables in the sketch. In your example, you are declaring the variables Display and MatCol in the sketch.

The sketch is in a completely different file, so if you want to reference them in the class (not a good idea, by the way), you need an extern statement in the source or header file that tells the compiler that these variables are defined in another file. The linker will then resolve where they are really defined.

Better, though, would be to define a reference to them in the class, and have the sketch call a method of the class to define the actual arrays to use.

A library should not have/require intimate knowledge of the calling code.

Edit: Skip a bunch of that stuff above. I reread the code, and I see that you are writing code to define the behavior of an ISR in an external (to the sketch) file. Not a great idea, in my opinion.

A sketch should use a library like a black box. Having the library, not the sketch, own the interrupt handler violates that separation, in my opinion.

BriPSmith

From your comments I would be better keeping the ISR in the sketch but have it call a method in the library and have the two arrays defined in the library? The only problem I have encountered here is define variables in a library, I assume in the .h file I define as a name and create, dimension and assign values in the .cpp file? Thanks for the guidance I think I'm seeing how it fits together.
BPS

PaulS

Quote
From your comments I would be better keeping the ISR in the sketch but have it call a method in the library and have the two arrays defined in the library?

Yes.

Quote
The only problem I have encountered here is define variables in a library, I assume in the .h file I define as a name and create, dimension and assign values in the .cpp file?

The variable is defined (given a type, size, and name) in the header file. It is assigned values in the in the source file.

BriPSmith

Thanks PaulS, I think I might be able to crack this issue now, I'll let you know how I get on later in the week.
BPS

Go Up