Is there an alternative to analogInputToDigitalPin?

Im going through some arduino code and I was wondering if their is comparable command to analogInputToDigitalPin

some code… (related to OSC port)

void routeAnalog(OSCMessage &msg, int addrOffset ){
  //iterate through all the analog pins
  for(byte pin = 10; pin < NUM_ANALOG_INPUTS; pin++){
    //match against the pin number strings
    int pinMatched = msg.match(numToOSCAddress(pin), addrOffset);
    if(pinMatched){
        //if it has an int, then it's a digital write
        if (msg.isInt(0)){
        pinMode(analogInputToDigitalPin(pin), OUTPUT);
        digitalWrite(analogInputToDigitalPin(pin), (msg.getInt(0) > 0)? HIGH: LOW);
        } //otherwise it's an analog read
        else if(msg.isFloat(0)){
        analogWrite(pin, (int)(msg.getFloat(0)*255.0f));
#ifdef BOARD_HAS_ANALOG_PULLUP
    //with a pullup?
        else if (msg.fullMatch("/u", pinMatched+addrOffset)){
            //set the pullup
            pinMode(analogInputToDigitalPin(pin), INPUT_PULLUP);

            //setup the output address which should be /a/(pin)/u
            char outputAddress[9];
            strcpy(outputAddress, "/a");
            strcat(outputAddress, numToOSCAddress(pin));
            strcat(outputAddress,"/u");
            strcat(outputAddress,"/u");
            //do the analog read and send the results
            bundleOUT.add(outputAddress).add((int32_t)analogRead(pin));
        } //else without a pullup   
#endif
        else {
            //set the pinmode

            pinMode(analogInputToDigitalPin(pin), INPUT);
            //setup the output address which should be /a/(pin)
            char outputAddress[6];
            strcpy(outputAddress, "/a");
            strcat(outputAddress, numToOSCAddress(pin));
            //do the analog read and send the results
            bundleOUT.add(outputAddress).add((int32_t)analogRead(pin));
        }
    }
  }
}

@lightx, this analogInputToDigitalPin() is nothing more than this

// taken from https://github.com/CNMAT/OSC/blob/master/OSCBoards.h
#ifndef analogInputToDigitalPin
#define analogInputToDigitalPin(p)  ((p < 12) ? (p) + 54 : -1)
#endif

For the Core this could be easily be adapted this way

// if I interpret the Arduino pin mapping correctly,
// this should be the Core's equivalent
#ifndef analogInputToDigitalPin
// since D0..D7 = 0..7 and A0..A7 = 10..17
#define analogInputToDigitalPin(p)  ((p < 8) ? (p) + 10 : -1)
// or #define analogInputToDigitalPin(p)  ((p >= 0 && p < 8) ? (p) + 10 : -1)
#endif
1 Like

@lightx, you will have to modify OSCBoards.h and add a section for the Core to define that function to suit the Core. The purpose of the function is to map a physical pin to its interrupt mask reference, something not required on the Core since pin numbers are the same as pin interrupt masks. To do this, you will need something like this:

            #if defined (SPARK)

            #ifndef LED_BUILTIN
            #define LED_BUILTIN  13
            #endif
    
            #ifndef NUM_DIGITAL_PINS
            #define NUM_DIGITAL_PINS 8
            #endif
            #ifndef NUM_ANALOG_INPUTS
            #define NUM_ANALOG_INPUTS 8
            #endif

            #ifndef analogInputToDigitalPin
            int analogInputToDigitalPin(int i)
            {
                switch(i)
                {
                    case 0: return A0;
                    case 1: return A1;
                    case 2: return A2;
                    case 3: return A3;
                    case 4: return A4;
                    case 5: return A5;
                    case 6: return A6;
                    case 7: return A7;
                }
           }
           #endif  //Spark

You’ll have to check my logic and make sure I got the settings right but that’s the general idea. :smile:

1 Like

@peekay123 's solution is the more sophisticated and more general one (due to the #ifdef SPARK preproc directives), but to keep it compatible to the original, you might have to add a return -1; as last statement of the function - otherwise you might get an error because not all code paths return a value.
Or you go with the #define-version of my previous post, which does the same.


Apart from the answer to your question about analogInputToDigitalPin you’d have to rethink the whole logic of routeAnalog().
e.g. this for(byte pin = 10; pin < NUM_ANALOG_INPUTS; pin++) would never run if NUM_ANALOG_INPUTS evaluates to 8.

2 Likes

@ScruffR, good catch! The code is very Arduino-centric so things like that will have to be adapted for the Core using conditional compiles. :smile:

2 Likes

thanks @ScruffR and @peekay123

I’ll go over all of this after the turkey event. Ill update then.