how to pass a struct to a function in order for it to modify struct members

hi all

thanks in advance for any help

question:
would like to call a function, pass a struct object as a parameter, in order for the function to modify struct members.
Please assist.

***** tried following code but it did not work *****
A/ function definition
void digitalRead ( &relay ) {

B/ calling function
void loop() {
digitalRead( relay );

note: have created another version for this function to access struct members as
relay. as opposed to relay1.

2/
defined global variable relay1 type struct relay
// physical variables
typedef struct {
const int NC_pin = 2; // set relay 1 NC pin
const int NO_pin = 3; // set relay 1 NO pin
const int Coil_pin = 12; // set relay 1 coil pin
bool NC = false, NO = false, Coil = false;
bool bRise = false, bFall = false, bTiming = false;
unsigned long lastDebounceTime = 0; // the last time the input pin was toggled
} relay;
relay relay1;

3/
function
note: when creating a generic function to handle many relays, have modified this function to access object
relay.
as opposed to
relay1.
...
void digitalRead1 ( ) {

if( digitalRead(relay1.NC_pin) && !relay1.NC ) {
relay1.bRise = true;
relay1.lastDebounceTime = millis();
relay1.bTiming = true;
}
else {
relay1.bRise = false;
}

if( !digitalRead(relay1.NC_pin) && relay1.NC ) {
relay1.bFall = true;
relay1.lastDebounceTime = millis();
relay1.bTiming = true;
}
else {
relay1.bFall = false;
}

// read the current button pin state
relay1.NC = digitalRead( relay1.NC_pin );
relay1.NO = digitalRead( relay1.NO_pin );
// If the input changed, due to noise or pressing:

if ( ((millis() - relay1.lastDebounceTime) > debounceDelay) && relay1.bTiming ) {
relay1.bTiming = false;
Serial.println( "***** relay1_NC settled *****" );
Serial.println( relay1.lastDebounceTime );
Serial.println( millis() );
Serial.println( "relay1.NC" );
Serial.println( relay1.NC );
Serial.println( "\n" );

// for testing purpose only
if( relay1.NC ) {
digitalWrite(orangeLED_pin, HIGH);
}
else {
digitalWrite(orangeLED_pin, LOW);
}
}

}

If the function needs to be able to modify the struct, then you must pass either a pointer or reference t the struct. Otherwise, you'll pass a copy, and the function will only be able to modify the copy, and the caller will never be able to see those modifications.

It looks like you are attempting to create a generic construct to handle a number of similar objects, in this case, relays. I’d use the classic C++ class for this (although classes and structs can be nearly identical). The class constructor contains the relay pins. A begin() method does initialisation like pinMode() etc. which cannot be done in the constructor method and create other methods for manipulating the data (handling debouncing times etc.).

You haven’t, incidentally, said what indicated that your own attempts failed but I guess you got compiler errors. If, for example, you use a reference (&) argument, the called routine must have a corresponding pointer argument (*) and then you must use the (->) operator to access struct members.

It might be useful to post complete code between
** **[code]** **
and
** **[/code]** **
. That way we see what the exact issue is :wink: Error messages might also be useful if they happen.

In case of errors, it might be your code, it might also be that the Arduino builder drops a stitch.

6v6gt:
It looks like you are attempting to create a generic construct to handle a number of similar objects, in this case, relays. I’d use the classic C++ class for this (although classes and structs can be nearly identical). The class constructor contains the relay pins. A begin() method does initialisation like pinMode() etc. which cannot be done in the constructor method and create other methods for manipulating the data (handling debouncing times etc.).

You haven’t, incidentally, said what indicated that your own attempts failed but I guess you got compiler errors. If, for example, you use a reference (&) argument, the called routine must have a corresponding pointer argument (*) and then you must use the (->) operator to access struct members.

firstly, thank you to all for the assistance and for the explanation helped to get the arduino high level code working
really appreciate your support
please find below the entire code
I've noticed the digital debounce example did not quite work for me, hence implemented my own debounce
Prefer to stick to struct and have the
void setup() {
function to initialise relay members
A/ define struct variable type relay, and create variable relay1

[color=#222222] [/color]
// physical variables
typedef struct {
  const int NC_pin = 2; // set relay 1 NC pin
  const int NO_pin = 3; // set relay 1 NO pin
  const int Coil_pin = 12; // set relay 1 coil pin
  bool NC  = false, NO = false, Coil = false;
  bool bTiming = false;
  unsigned long lastDebounceTime = 0; // the last time the input pin was toggled
} relay; 
relay relay1;
[color=#222222][b]

B/ setup() function

[color=#222222] [/color]
void setup() {
  Serial.begin(9600);
  while (!Serial);
  pinMode( relay1.NC_pin, INPUT ); // use the relay NC contact as an input    
  pinMode( relay1.NO_pin, INPUT ); // use the relay NO contact as an input  
  pinMode( relay1.Coil_pin, OUTPUT ); // use the LED as an output
  pinMode( orangeLED_pin, OUTPUT ); // use the LED as an output
  // begin initialization
  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");
    while (1); // endless loop
  }
  // set the local name peripheral advertises
  BLE.setLocalName("Aberfeldy");
  // set the UUID for the service this peripheral advertises:
  BLE.setAdvertisedService(aberfeldyService);
  BLE.setDeviceName("Aberfeldy");
  // add the characteristics to the service
  aberfeldyService.addCharacteristic(relay1Characteristic);
  aberfeldyService.addCharacteristic(closeRelay1Characteristic);
  aberfeldyService.addCharacteristic(openRelay1Characteristic);
  // add the service
  BLE.addService(aberfeldyService);
  // clear BLE variables
  relay1Characteristic.writeValue(0);
  closeRelay1Characteristic.writeValue(0);
  openRelay1Characteristic.writeValue(0);
  // start advertising
  BLE.advertise();
  Serial.println("Bluetooth device active, waiting for connections...");
}
[color=#222222][b]

C/ this generic function handles relay struct members

[color=#222222] [/color]
void digitalFetch( relay *relay_x ) {
  if( digitalRead(relay_x->NC_pin) && !relay_x->NC ) {
    relay_x->lastDebounceTime = millis();
    relay_x->bTiming = true;    
  }
  if( !digitalRead(relay_x->NC_pin) && relay_x->NC ) {
    relay_x->lastDebounceTime = millis();
    relay_x->bTiming = true;    
  }
  // read the current button pin state
  relay_x->NC = digitalRead( relay_x->NC_pin );
  relay_x->NO = digitalRead( relay_x->NO_pin );  
  // If the input changed, due to noise or pressing:
  if ( ((millis() - relay_x->lastDebounceTime) > debounceDelay) && relay_x->bTiming ) {
      relay_x->bTiming = false;
      Serial.println( "***** relay_x.NC settled *****" );
      Serial.println( relay_x->lastDebounceTime );
      Serial.println( millis() );
      Serial.println( "relay_x.NC" );
      Serial.println( relay_x->NC );      
      // for testing purpose only
      if( relay_x->NC ) {
        digitalWrite(orangeLED_pin, HIGH);
      }
      else {
        digitalWrite(orangeLED_pin, LOW);    
      }            
  }
}
[color=#222222][b]

D/ void loop()
main function/program

[color=#222222] [/color]
void loop() {
  // poll for BLE events
  BLE.poll();
  BLE_relay1();
  digitalFetch( &relay1 );
}
[color=#222222][b]

6v6gt:
...although classes and structs can be nearly identical...

The ONLY difference between a struct and a class is all members of a struct are public by default while all members of a class are private by default. In every other respect they are identical. You can even derive a class from a struct, and vice-versa, with similar default member access in the derived class or struct.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.