Pages: [1]   Go Down
Author Topic: Taking the next big step.... Pointers!!!  (Read 6111 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
I'm trying to setup a menu system, controlled via a struct.
Which i can then access, and the code know what parameter i want and how i want to display it.
I have the code working with a constant "2" which i can quite happily read.
What i want to be able to do is read a variable from the code,
ie counter or LEDON.  then have a routine point to that variable, read it and output it.
I have been told that points will help me, but i've tried playing with some examples but with no success!

Can anyone point me in the right direction please?
P.S. this is my first steps with pointers so wish me luck!

Pete
Logged

Huntsville, Alabama, USA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 327
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pete,

I'm not sure what you're trying to do, but here are some pointer examples:
Code:
void my_function()
{
    int sum;

    add_numbers(1,2,&sum);    // &sum means a pointer to 'sum'
    // at this point, 'sum' should have a value of 3.
}

void add_numbers(int num1,int num2,int *sum)
// 'int *sum' means that the third parameter is a pointer to an integer
{
    *sum = num1 + num2;   // store the result in the int pointed to by 'sum'
}

Is that what you were looking for?

-Mike
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Mike,
Thanks for trying to help!
Your code works brilliantly but i can't get it to work with with the use of a struct which hopefully should hold the address of the variable, and when i come to print the variable out onto the serial port all i have to do is point to it.
But i dont know how to put the address into the struct and even more inportantly how to get it out!!!
The code below shows you what i am trying to do, the second variable record_type.two should ideally hold the variable address and in the main loop all i want to be able to do is point to it.
Does this make things a little clearer?
Thanks

Pete

Quote
// Parameters   
typedef struct
{
  char one[10];
  int two;
  int three;
}  
record_type;
record_type record[8];
char inByte = 0;         // incoming serial byte



void setup(){
  Serial.begin(9600);
  record[0] = (record_type) {"ADC1",2,3  };
  record[1] = (record_type) {"ADC2",3,6  };
  record[2] = (record_type) {"ADC3",4,9  };
  record[3] = (record_type) {"data",5,9  };
  establishContact();  // send a byte to establish contact until receiver responds

}
void loop(){



  if (Serial.available() > 0) {
    inByte = Serial.read();    
    if (inByte == 'A'){
      Serial.print(inByte);
      //Serial.print(",");
      for (int a=0; a<3; a++){
        Serial.print(",");        
        Serial.print(record[a].one);
      }
      Serial.println();
    }
    {
      if (inByte =='B'){
        Serial.print(inByte);

        for (int a=0; a<3; a++){  
          Serial.print(",");
          Serial.print(record[a].one);
          Serial.print(",");
          Serial.print(record[a].two);
          Serial.print(",");
          Serial.print(record[a].three);
          Serial.print(",");  
        }
        Serial.println();
      }
      delay (1000);
    }


  }
}
void establishContact() {
  while (Serial.available() <= 0) {
    Serial.println("A");   // send an initial string
    delay(300);
  }
}

« Last Edit: December 04, 2009, 08:21:30 am by psfletcher » Logged

Huntsville, Alabama, USA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 327
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pete,

Sorry, but I'm still not sure I understand why you want to use a pointer inside your struct.  Your code should work fine the way it stands.  There is a more conventional way to initialize the contents of your structure, though:
Code:
typedef struct
{
  char one[10];
  int two;
  int three;
}  
record_type;
record_type record[8] = {
    {"ADC1",2,3},
    {"ADC2",3,6},
    {"ADC3",4,9},
    {"data",5,9}
    };

If you want to have a pointer in a structure, you can declare it this way:
Code:
typedef struct
{
  char one[10];
  int *two;
  int three;
}  
record_type;
But you'll also have to change the way you initialize it:
Code:
record_type record[8] = {
    {"ADC1",(int *)NULL,3},
    {"ADC2",(int *)NULL,6},
    {"ADC3",(int *)NULL,9},
    {"data",(int *)NULL,9}
    };
You could also initialize the pointers to point to global or static ints in your program, or you could fill in the pointers in your program.

You can also pass a pointer to the whole structure into a function.  Using your original structure, without any embedded pointers:
Code:
typedef struct
{
  char one[10];
  int two;
  int three;
}  
record_type;
record_type record[8] = {
    {"ADC1",2,3},
    {"ADC2",3,6},
    {"ADC3",4,9},
    {"data",5,9}
    };

void this_func()
{
    int i;
    for (i = 0; i < 4; ++i)
      that_func(&record[i]);
}

void that_func(record *r)
{
    Serial.println(r->one);
    Serial.println(r->two);
    Serial.println(r->three);
    r->two = r->two + 1;      // increment value of 'two' element
}
Passing a pointer to a struct allows you to look at and change elements of that structure.  The notation "r->one" is shorthand for "(*r).one".

Regards,

-Mike
Logged

Huntsville, Alabama, USA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 327
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pete,

Sorry, but I'm still not sure I understand why you want to use a pointer inside your struct.  Your code should work fine the way it stands.  There is a more conventional way to initialize the contents of your structure, though:
Code:
typedef struct
{
  char one[10];
  int two;
  int three;
}  
record_type;
record_type record[8] = {
    {"ADC1",2,3},
    {"ADC2",3,6},
    {"ADC3",4,9},
    {"data",5,9}
    };

If you want to have a pointer in a structure, you can declare it this way:
Code:
typedef struct
{
  char one[10];
  int *two;
  int three;
}  
record_type;
But you'll also have to change the way you initialize it:
Code:
record_type record[8] = {
    {"ADC1",(int *)NULL,3},
    {"ADC2",(int *)NULL,6},
    {"ADC3",(int *)NULL,9},
    {"data",(int *)NULL,9}
    };
You could also initialize the pointers to point to global or static ints in your program, or you could fill in the pointers in your program.

You can also pass a pointer to the whole structure into a function.  Using your original structure, without any embedded pointers:
Code:
typedef struct
{
  char one[10];
  int two;
  int three;
}  
record_type;
record_type record[8] = {
    {"ADC1",2,3},
    {"ADC2",3,6},
    {"ADC3",4,9},
    {"data",5,9}
    };

void this_func()
{
    int i;
    for (i = 0; i < 4; ++i)
      that_func(&record[i]);
}

void that_func(record *r)
{
    Serial.println(r->one);
    Serial.println(r->two);
    Serial.println(r->three);
    r->two = r->two + 1;      // increment value of 'two' element
}
Passing a pointer to a struct allows you to look at and change elements of that structure.  The notation "r->one" is shorthand for "(*r).one".

Regards,

-Mike
Logged

The Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

As far as I understand the OP he wants to be able to display the contents of a variable via a menu-system. The current examples all have fixed values (2,3,4,5).

I think what he is looking for is something like:

Code:

// integer variables to be set and altered througout the code
int a=0;
int b=0;

// menu
record_type record[8] = {
// first item: show a
  { "Show A", &a, 3 }
...

The second part of the record structure should contain the address of the integer to show.

Regards,
Frank
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Frank and Mike,
yes Frank your spot on!
Out of interest how should i be defining the struct? int *A or just int A.
(using your example)

Thanks

Pete
Logged

The Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Since you want to store a pointer to an int: int *A. With int A you'd be creating an int itself.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Frank,
Thanks for your reply!
So i have amended the code, (I'm only using static variables at the moment to prove a point)

At the serial.print command, how should i be telling the compliar i want it to print out the value at this address?

This must be the last peice to the puzzle! - Made even more fun as i am using structs smiley-wink

Thanks

Pete

Code:
// Parameters  
typedef struct
{
  char one[10];
  int *two;
  int three;
}  
record_type;
record_type record[8];
char inByte = 0;         // incoming serial byte

int num1 = 125;
int num2 = 120;
int num3 = 135;
int num4 = 145;

void setup(){
  Serial.begin(9600);
  record[0] = (record_type) {"ADC1",&num1,3  };
  record[1] = (record_type) {"ADC2",&num2,6  };
  record[2] = (record_type) {"ADC3",&num3,9  };
  record[3] = (record_type) {"data",&num4,9  };
  establishContact();  // send a byte to establish contact until receiver responds

}
void loop(){



  if (Serial.available() > 0) {
    inByte = Serial.read();    
    if (inByte == 'A'){
      Serial.print(inByte);
      //Serial.print(",");
      for (int a=0; a<3; a++){
        Serial.print(",");        
        Serial.print(record[a].one);
      }
      Serial.println();
    }
    {
      if (inByte =='B'){
        Serial.print(inByte);

        for (int a=0; a<3; a++){  
          Serial.print(",");
          Serial.print(record[a].one);
          Serial.print(",");
          Serial.print(record[a].two);
          Serial.print(",");
          Serial.print(record[a].three);
          Serial.print(",");  
        }
        Serial.println();
      }
      delay (1000);
    }


  }
}
void establishContact() {
  while (Serial.available() <= 0) {
    Serial.println("A");   // send an initial string
    delay(300);
  }
}
Logged

UK
Offline Offline
Faraday Member
**
Karma: 16
Posts: 2883
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

To access what a pointer points to, you need to dereference the pointer, and the dereference operator is the asterisk '*'.

Thus, if you've got
Code:
int a = 3;
int* pa = &a;
//
//
//
Serial.print (*pa);
Logged

Per Arduino ad Astra

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Groove,
Thanks for your help!
I'm using a struct to hold the data and printing out the information from this struct
Code:
Serial.print(record[a].two);
How do i add * to this line to tell the serial.print command that it holds an address?
Thanks again!
Pete
Logged

UK
Offline Offline
Faraday Member
**
Karma: 16
Posts: 2883
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
Serial.print(*(record[a].two));

(I can never remember the association rules for pointers, so I always play safe and bracket)
Logged

Per Arduino ad Astra

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Cool thanks!
With the code i have above do you think i will have any problems with Null Pointers?
As the varaible are defined before they are used, i dont think i will, but a second opinion would be nice!
Thanks

Pete
Logged

UK
Offline Offline
Faraday Member
**
Karma: 16
Posts: 2883
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
With the code i have above do you think i will have any problems with Null Pointers

If you have null pointers and you dereference them, you will have problems. Always.
However, if you're certain you have initialised all the pointers, then you should be OK.

Don't forget, if you're worried about null pointers, you can always test for them, not so uninitialised ones!
« Last Edit: December 09, 2009, 09:18:04 am by GrooveFlotilla » Logged

Per Arduino ad Astra

Pages: [1]   Go Up
Jump to: