Do not know how to assign function argument of Class member function pointer argument ? I2C Scanner hearder and cpp

--I am trying to reuse > I2CScanner.ino -- I2C bus scanner for Arduino

  • 2009,2014, Tod E. Kurt, and incorporate into .h and .cpp file.
    --I am stuck on how to assign the argument in the main program of , method:
    look_for_I2C.scanI2CBus(look_for_I2C.start_address, look_for_I2C.end_address,
    scanFunc);
    --do not known what to put in place to scanFunc to make it works ?
    -- what C++ code principle this involved in solving this ?

--This program will be incorporated later into another codes that will use the first I2C device address found and to read data from it. The foundDeviceFlag is to indicate a device is found and the address will be used.
Both foundDeviceFlag and addr to be used by main program.
scan form address 8 to 119.

/*  ***** Borrowed and based of:
 I2CScanner.ino -- I2C bus scanner for Arduino
 * 2009,2014, Tod E. Kurt, http://todbot.com/blog/
 */
#include <Wire.h>

#include "firstChkI2c.h"

#define WIRE Wire  

class I2CclassNew look_for_I2C;

// ------------------------------------------------
void setup() {
  Serial.begin(9600);
  delay(100);
  WIRE.begin();

  Serial.println("\nI2CScanner ready!");

  Serial.print("starting scanning of I2C bus from addr DEC : ");
  Serial.print(look_for_I2C.start_address, DEC);
  Serial.print(" to ");
  Serial.print(look_for_I2C.end_address, DEC);
  Serial.println("......");

  look_for_I2C.scanI2CBus(look_for_I2C.start_address, look_for_I2C.end_address, scanFunc);
  // do not known what to put in place to scanFunc to make it works ?
}
void loop() {}

====================================================

firstChkI2C.h >>>> below

#include <Arduino.h>
#include <Wire.h>

extern "C" {
#include "utility/twi.h"  // from Wire library, so we can do bus scanning
}
// Scan the I2C bus between addresses from_addr and to_addr.
// On each address, call the callback function with the address and result.
// If result==0, address was found, otherwise, address wasn't found
// (can use result to potentially get other status on the I2C bus, see twi.c)
// Assumes Wire.begin() has already been called

#define WIRE Wire

extern "C" {
#include "utility/twi.h"  // from Wire library, so we can do bus scanning
}

#ifndef FIRSTCHKI2C_H
#define FIRSTCHKI2C_H
class I2CclassNew {
public:
 
  byte addr, result;
  byte start_address = 8;  // lower addresses are reserved to prevent conflicts with other protocols
  byte end_address = 119;  // higher addresses unlock other modes, like 10-bit addressing

  static  int foundDeviceFlag;  //** static
  
   void scanI2CBus(byte from_addr, byte to_addr,
                  void (*callback)(byte address, byte result))  //   pointer to function ??
  { 
    Serial.println("Scanning...");

    byte rc;
    byte data = 0;  // not used, just an address to feed to twi_writeTo()
    for (byte addr = from_addr; addr <= to_addr; addr++) {
      rc = twi_writeTo(addr, &data, 0, 1, 0);
      callback(addr, rc);
      delay(100);
    }
  }  
};
#endif

FirstChkI2c.cpp file below >>

include <Arduino.h>
#include <Wire.h>
#include "firstChkI2c.h"

// Called when address is found in scanI2CBus()

void *scanFunc(byte addr, byte result) {
  Serial.print("addr 0x: ");
  Serial.print(addr, HEX);
  I2CclassNew ::foundDeviceFlag = 0;
  Serial.print((result == 0) ? " found!" : "       ");
  Serial.print((addr % 4) ? "\t" : "\n");
  if (result == 0) {
    I2CclassNew ::foundDeviceFlag = 1;
    Serial.print(" foundDeviceFlag =  ");
    Serial.println(I2CclassNew ::foundDeviceFlag);
    Serial.print((addr % 4) ? "\t" : "\n");
  }
}

please advise me because I am unsure what to do -thanks

x
first, please edit your first post and split the text (your question) from the code using code tags.

A question usually ends with a question mark.

1 Like

i think the primary problem is you defined "scanFunc" as a function returning a "void *" when is should just be "void"

additional problems

  • "scanFunc" was defined in firstChkI2C.cpp, but there is no declaration of it in you main code where it is used
  • "scanFunc" references foundDeviceFlag e times, but i don't see a definition for it

and please post code using the </> icon. click the icon and past the code into the highlighted area

Thanks for taking your time to look into this.
Code reposed.
I am learning coding. Please clarify for me and advise me what to do to correct my mistake.

Do you want to add a I2C Scanner function to your class ?
Please don't use the code that needs utility/twi.h, that is not compatible with other boards. You could have picked any other I2C Scanner. A I2C Scanner does not need other functions, it is just a single for-loop that outputs some text.

Do you want a callback function when something is found ?

It would help if you edit your first post (again) and make the text readable. Can you also make the function names readable. When I read your post, then I'm stumbling over "my1stchkI2C" and what are the * • // ??????? >> doing ?

yes, my code was messy !.
Tidied up, hope it helps
also updated the question to state my program objectives

  • For my learning of coding . I still would like to learn what to put in place of look_for_I2C.scanI2CBus(look_for_I2C.start_address, look_for_I2C.end_address, scanFunc);
    // do not known what to put in place to scanFunc to make it works ?
  • what are the reason - will work and mine failed

*thanks

???

It is probably me, but I still don't understand what you want.

This is a I2C Scanner in a class:

#include <Wire.h>

class MyClass
{
public:
  I2C_Scanner()
  {
    for( int i=1; i<=127; i++)
    {
      Wire.beginTransmission(i);
      int error = Wire.endTransmission();

      if( error == 0)
      {
        Serial.print( "I2C Device found at 0x");
        if( i<0x10)
          Serial.print( "0");
        Serial.print( i, HEX);
      }
    }
  }
};

MyClass myObject;

void setup()
{
  Serial.begin(115200);
  myObject.I2C_Scanner();
}

void loop() {}

Why would you want to scan a smaller range of I2C addresses ? That is like going to a grocery store and you may only buy things that are between 2 and 3 dollars.
Do you want to test a single I2C address ?

Like to scan form address 8 to 119.
For the present time use - what ever device first detected will be selected , the foundDeviceFlag will be set- accessible from the main program.
Also the corresponding scanned ID address to be used by another program task to collect the data from the I2C device.

tried by changing void(* callback) to void callback :- error compile

" Compilation error: 'scanFunc' was not declared in this scope"

Updated this post descriptions and for problem clarifications.

I'm not sure if I like a 'foundDeviceFlag' in the Class itself, so I go only a little further:

#include <Wire.h>

class MyClass
{
public:
  int I2C_Scanner( int startAddress, int endAddress)
  {
    for( int i=startAddress; i<=endAddress; i++)
    {
      Wire.beginTransmission(i);
      int error = Wire.endTransmission();

      if( error == 0)
      {
        return( i);
      }
    }
    return( -1);
  }
};

MyClass myObject;

void setup()
{
  Serial.begin(115200);
  int i2cAddress = myObject.I2C_Scanner( 0x60, 0x70);

  if( i2cAddress == -1)
  {
    Serial.print( "Nothing found");
  }
  else
  {
    Serial.print( "I2C Device found at 0x");
    if( i2cAddress<0x10)
      Serial.print( "0");
    Serial.print( i2cAddress, HEX);
  }
}

void loop() {}

The scanning function returns the found I2C Address or -1 if nothing is found.
It could return a boolean variable and the I2C Address could be a parameter "by reference".

???

Thanks, I will incorporate your suggestion and make the program simpler. I think I over complicated it !

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