LEDs and Pointers

Newbie here,

I have a program coded properly so that when I push a button my my breadboard, 2 leds on it light up, and the time which they were pushed at (that is, the time elapsed since the serial monitor was opened) is displayed on the serial monitor. These times are then recorded into an array, and at the end of the program - after 2 pushes of the button - all recorded results written to the serial monitor.

When the button is pushed, it should send a "HIGH" to the function 'void all_write(int *buttonState)' to tell the LED pins to turn on. If the button is not pushed, the LEDs are off.

I can get the program working using functions of pass by value, but if I try to modify the program to use pass by reference, particularly using "buttonState", I get errors, beginning on line 90: "invalid conversion from 'int' to 'int*'.

I can use pointers in c++, but cannot seem to get it to work in Arduino. Any ideas how to modify my code to make this work how I'm trying to? Just trying to do something basic / simple, that's all.

/*****
 * This program will have 2 LEDs when the button is pressed.
 * 
 * Formating
 * 1.  The timer() function is only used for the serial monitor to display current time
 * 2.  The data is written to an array.  Currently, it is a 2x3 array, with these characteristics:
 * 
 * Columns:
 * 1:  # at which instance button has occured (e.g. 1,2,3...10)
 * 2:  minutes
 * 3:  seconds
 * 
 * When array is eventually printed, it will be in this format:
 * 
 * 1 0 34
 * 2 1 25
 * 
 * You have to know on the program you input it to which column is which, as it is being
 * exported as type int variables.
 *****/

#include <Time.h>

// constants
const int buttonPin = 7; // push button
const int ledPin = 13;  // red
const int ledPin2 = 2; // green

// variables
int *buttonState = LOW;    // variable for reading the pushbutton status
int i = 0, j = 0;// start at cell 0x0 in array
int instances = 1;  // number of times button was pushed

// array for putting instances & time-stamp (min, sec) into, 2x3 array: instances, time
const int rows = 2;
const int columns = 3;
int my_array[rows][columns];

// booleans
bool decision = true;  // end of program

//inputing button state to output of LEDs states
void all_write(int *buttonState)
{
  digitalWrite(ledPin, *buttonState);// = buttonState; // HIGH or LOW, depending what is fed to it
  digitalWrite(ledPin2, *buttonState);// = buttonState; // HIGH or LOW, depending what is fed to it
}
// timer in format: MM:SS
void timer(void)
{
  // minutes
  if (minute() < 10)
  {
    Serial.print("0");
    Serial.print(minute());  
  }
  else
  {
    Serial.println(minute());
  }

  Serial.print(":");

  // seconds
  if (second() < 10)
  {
    Serial.print("0");
    Serial.println(second());  
  }
  else
  {
    Serial.println(second());
  }
}

void setup()
{
  Serial.begin(9600);
  pinMode(buttonPin, INPUT);  // sets pin 7 as an input
  pinMode(ledPin, OUTPUT); // sets pin 13 as an output
  pinMode(ledPin2, OUTPUT); // sets pin 12 as an output
}

void loop()
{

  while (i < rows)  // condition to check for program to run
  {
    // read the state of the pushbutton value:
    buttonState = digitalRead(buttonPin); // is this needed?
    
    if (digitalRead(buttonPin) == HIGH)
    {
      all_write(&buttonState); // both ledPIN and ledPin2 set to HIGH
            
        // display data, instance & time button push occured at  
      Serial.print(instances);
      Serial.print(": ");
      timer();

      // place data into array, cell by cell
      my_array[i][j] =  instances;
      j++; // move to the right by 1 column
      my_array[i][j] = minute();
      j++; // move to the right by 1 column
      my_array[i][j] = second();

      // go to next row of column
      i++; // move down 1 column
      j = 0; // move back to the left most column
      instances++;

    }
    else 
    {
      all_write(&buttonState); // both ledPin and ledPin2 set to LOW  
    }

    delay(250);  // how often loop will run
  } 

  //end of program
  if (decision == true)  // run only once
  {
    Serial.println("Program is over!");
    decision = false;
    all_write(LOW); // both ledPin and ledPin2 set to LOW  

      //print table - use table from c++ program as model using the function command?
    //print_table(my_array, rows, columns);

    Serial.println();
    Serial.println("Show full table:"); //cout << "Show full table: " << "\n" << endl;
    Serial.println("(Note: Raw data is being exported a 2x3 array, with the columns headers as 'Instances', 'Minutes', 'Seconds')");

    for (int i = 0; i < rows; i++)
    {
      for (int j = 0; j < columns; j++)
      {
        Serial.print(my_array[i][j]);
        Serial.print(" ");
      }
      Serial.println("");
    }
    Serial.print("");
  }

}

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

This seems like a pretty simple mistake. Here is line 90:

buttonState = digitalRead(buttonPin); // is this needed?

Variable buttonState is declared as int*. Function digitalRead() returns an int. You have a basic type mismatch that can't be resolved by implicit type-casting, so the compiler throws an error.

I think the code you want is:

*buttonState = digitalRead(buttonPin);

The mystery is why you want to use pointers for this simple task?

This is a problem:

int *buttonState = LOW;    // variable for reading the pushbutton status

That declares a pointer to address zero. You need to declare a variable to point to, you're getting a pointer to something later on when you use &. What is needed here is:

int buttonState = LOW;    // variable for reading the pushbutton status

All this assuming that you're experimenting with pointers for the sake of it, per Grumpy Mike's remark.

The pointers make no sense. You don't need them. If you really insist on using them, then you should make the effort to learn how they work.

The other curious thing, is where you stated in your first post, that you are recording the time when you push the button , "since when the serial monitor was opened ". It's not clear how you are doing this. The time "since the sketch started", is not necessarily the same as the time when the serial monitor was opened.

The time "since the sketch started", is not necessarily the same as the time when the serial monitor was opened.

But if the auto-reset feature is enabled, it is going to be pretty close :wink:

wildbill:
This is a problem:

int *buttonState = LOW;    // variable for reading the pushbutton status

That declares a pointer to address zero. You need to declare a variable to point to, you're getting a pointer to something later on when you use &. What is needed here is:

I'm pretty sure that the compiler does allocate 2 bytes for that just because = LOW is there. Same way as
short *small_vals = { 9,8,7,6,5,4,3,2,1,0 }; // creates a filled array of 10 members pointed to by small_vals

int *buttonState; // here's how to make a problem
*buttonState = LOW; // I wonder if RAM bytes 0 and 1 are important?

GoForSmoke:
// I wonder if RAM bytes 0 and 1 are important?

Meh, plenty more where they came from.

Ok, I made the small modification on line 90 to be;

*buttonState = digitalRead(buttonPin); // is this needed?

But, now line 94,

all_write(&buttonState); // both ledPIN and ledPin2 set to HIGH

gives this error when compiling:

" cannot convert type 'int**' to 'int*' for argument '1' to 'void all_write(int*)' "

Any ideas?

Any ideas?

Yes, don't use the address operator.
If buttonState already is a pointer, you don't want to be taking its address.

The error code is telling you the relevant information:

" cannot convert type 'int**' to 'int*' for argument '1' to 'void all_write(int*)'  "

Argument 1 of function "void all_write(int*)" is supposed to be an int*, but you have passed it an int**. What is an int**? Well, if you think about it:

int x;
int* p = &x;

When you use the & operator, you take the address of the thing following it. So if you do &int, you get int* as the result (a pointer to an int). Now play that out. If &x is an int*, then what is &(&x)? It's an int**. And that's not the data type that your function expects.

In your example, the function expects an int*, which buttonState already is, so there is no need to use the & operator when passing buttonState to the function.