Setup pin input_pullup che nel loop hanno valori inaspettati

Buongiorno. Ho scritto un piccolo softwarino che mi dovrebbe consentire di leggere in fase di setup quali sono i PIN che voglio siano di INPUT, e i PIN che vogliono fungano da output.
Questo è il codice del setup.

//MAPPING PIN
typedef struct
{
    int numPin;
    int typePin;
    String message;
}  record_pin;
record_pin pins[9];


Serial.println("setup pin");
  //ABILITO I PIN IN BASE A COME SONO STATI CONFIGURATI
  int numCellMessage = (int)eeprom_pin1_message;
  for(int i = 0; i < 9; i++){
    String message ="";
    int numCell = (int)eeprom_pin1;
    numCell += i;
    //Serial.println(numCell);
    pin[0] = getAddressIpMqtt(numCell);
    //Serial.println(pin[0]);
    int nPin = i+1;
    if(pin[0] == 1){
      //Serial.println("PIN numero " + String(nPin) + " OUTPUT"); 
      message = read_String(numCellMessage);
      pinMode(getPinMapping(nPin), OUTPUT);
    }else if(pin[0] == 0){
      //Serial.println("PIN numero " + String(nPin) + " INPUT");
      pinMode(getPinMapping(nPin), INPUT_PULLUP);
    }
    digitalWrite(getPinMapping(nPin), LOW);
    digitalWrite(getPinMapping(nPin), LOW);
    digitalWrite(getPinMapping(nPin), LOW);
    delay(50);
    //POPOLO L ARRAY DI STRUTTURA DATI PER POTER POI AVERE IL MAPPING COMPLETO DI TUTTI I PIN GIà PRONTO
    pins[i] = {getPinMapping(nPin), pin[0], message}; 
    //
    numCellMessage += 15;
  }
  
}

Nel codice creo un array in cui inserisco un oggetto in cui inserisco il numero del PIN, il suo tipo 0= input, 1 = output.

Nel loop invece ho scritto questo codice:

int sizePins = (sizeof(pins) / sizeof(pins[0]));
  for(int i = 0; i < sizePins; i++){
    record_pin p = pins[i];
    if(p.typePin == 0){//PIN DI INPUT IO DEVO VERIFICARE SE STA CAMBIANDO QUALCOSA
      int sensorValue = digitalRead(p.numPin);
      Serial.println(String(p.numPin) + " " + sensorValue);
      if (sensorValue == HIGH) {
        //Serial.println("mando una notifica push");
        //digitalWrite(13, LOW);
      }
    }
    //Serial.println("num pin " + String(p.numPin) + " tipo pin " + String(p.typePin) + " message: " + p.message);
    delay(1000);
  }

int getPinMapping(int idPin)
{
  switch (idPin) {
    case 1: return 16;
    case 2: return 5;
    case 3: return 4;
    case 4: return 14;
    case 5: return 12;
    case 6: return 13;
    case 7: return 0;
    case 8: return 2;
    case 9: return 15;
    default : return -1;
      // Qui sai che x è > 0 && < 4
      break;
  }
}

Il risultato aprendo la conesole, è il seguente, non so per quale motivo ma i PIN 4,12 hanno sempre valore HIGH (1) anche se ad arduino non ho collegato assolutamente nulla. Mentre per i pin 15 e 16 il valore è 0 come mi aspetterei.

Mi sapete aiutare?

getAddressIpMqtt(); restituisce i seguenti valori (2, 8, 4, 6)

Utilizzo per il momento una Wemos D1 come board

Beh, devo studiare meglio il codice, ma la prima cosa che devi fare è togliere di mezzo le "String".

Poi se non ci descrivi come sono definiti i byte nella EEPROM e non ci mostri la definizione di record_pin e pins[] le funzioni getPinMapping(), read_String(), e getAddressIpMqtt() penso sia difficilino darti una mano....

docdoc:
Beh, devo studiare meglio il codice, ma la prima cosa che devi fare è togliere di mezzo le "String".

Poi se non ci descrivi come sono definiti i byte nella EEPROM e non ci mostri la definizione di record_pin e pins[] le funzioni getPinMapping(), read_String(), e getAddressIpMqtt() penso sia difficilino darti una mano....

Ho aggiornato il codice. Il codice restituito da read_String() restituisce solo stringhe che però se leggi il codice, non vengono utilizzate per il momento. Spero di essere stato un pò più esaustivo

Ok, già un po' meglio, ma avevi scritto "Il risultato aprendo la conesole, è il seguente" ma non hai inserito alcun output della console, puoi postarlo?

i pin 4 e 12 hanno sempre valore alto anche se ad arduino non ho collegato assolutamente nulla.

E' quello il problema: sono ad altissima impedenza, perciò possono stare indifferentemente a livello alto o basso. Basta un po' di umidità tra un pin ad alta impedenza e qualcosa a +5V per portarlo a livello alto.

docdoc:
Ok, già un po' meglio, ma avevi scritto "Il risultato aprendo la conesole, è il seguente" ma non hai inserito alcun output della console, puoi postarlo?

Scusami, ma sostanzialmente ad ogni ciclo for, i pin 0,4,12 che io ho scelto di impostare come pin di input sono sempre a valore HIGH.

Nella wemos D1 i pin 0,4,12 corrispondono ai pin denominati D8, D4, D6.

Come posso risolvere questo problema ?

Ho impostato nello stesso modo i pin 15 (D10), 16 (D2) i quali hanno sempre stato LOW; se provo a dargli 5V, allora lo stato cambia ad HIGH come mi aspetterei anche dai pin D4 D6 D8

E' quello il problema: sono ad altissima impedenza, perciò possono stare indifferentemente a livello alto o basso. Basta un po' di umidità tra un pin ad alta impedenza e qualcosa a +5V per portarlo a livello alto.

quindi come si risolve questo ?

bircastri:
Ho aggiornato il codice. Il codice restituito da read_String() restituisce solo stringhe che però se leggi il codice, non vengono utilizzate per il momento. Spero di essere stato un pò più esaustivo

Un poco, si, ma ancora non so cosa contengano eeprom_pin1_message e eeprom_pin1 e come sia la getAddressIpMqtt().

Datman:
E' quello il problema: sono ad altissima impedenza, perciò possono stare indifferentemente a livello alto o basso. Basta un po' di umidità tra un pin ad alta impedenza e qualcosa a +5V per portarlo a livello alto.

Lui li ha impostati tutti con INPUT_PULLUP, non sono in alta impedenza quindi mi pare normale che siano HIGH anche senza nulla connesso. Ma il problema è un altro:

bircastri:
Ho impostato nello stesso modo i pin 15 (D10), 16 (D2) i quali hanno sempre stato LOW

Intanto non ho ben capito quale sia la tua codifica dei pin, anche perché vedo questo:

int getPinMapping(int idPin)
{
  switch (idPin) {
    case 1: return 16;
    case 2: return 5;
    case 3: return 4;
    case 4: return 14;
    case 5: return 12;
    case 6: return 13;
    case 7: return 0;
    case 8: return 2;
    case 9: return 15;
    default : return -1;
      // Qui sai che x è > 0 && < 4
      break;
  }
}

questa tua "anomala" mappatura secondo me ti fa confondere, perché se lo scopo di questa funzione è quella che ti dia il corrispondente pin GPIO del WeMos dato il numero di pin di Arduino, di fatto il tuo pin 1 sarebbe il D2 (GPIO16), il pin 2 il D3 (GPIO5), e così via fino al D10 (GPIO15)

Detto questo, tu parli del "pin 15 (D10)" e del "pin 16 (D2)". Ebbene, devi ricordare che su queste board le GPIO 0, 2 e 15 hanno un ruolo particolare nel boot e sulle WeMos (come in quasi tutte le altre schede simili credo) GPIO 0 e 2 hanno una resistenza in pullup mentre GPIO15 in pull-down. Dato che a seconda del produttore le resistenze di pull-up/down possono andare da 2 a 10k Ohm, modificare questo comportamento potrebbe pregiudicare il funzionamento del boot quindi ti direi se possibile di mappare diversamente i pin della tua codifica per utilizzare altri pin GPIO. Puoi usare i GPIO 0 e 2 eventualmente, basta che lasci stare GPIO15.
Per il GPIO16 (D2) non so dirti, ma verifica prima bene il discorso mappature, poi controlla i cablaggi e fatti stampare su seriale come stai impostando i pin.

ciao ti ringrazio per la risposta. Io ho utilizzato questa immagine per impostare il mio mapping.

In sostanza io voglio poter impostare tramite salvataggio su eeprom i 9 pin digitali (dirgli pin1, è un input, pin2 è un output e cosi via). Dal momento che nelle WEMOS, se scrivi digitalRead(1), in realtà non stai leggendo il pin 1 perchè c'è un mapping diverso, allora ho creato questo metodino in cui se gli chiedo il pin 1, mi dovrebbe restituire il PIN 1 Wemos.

Questo è quanto.

Adesso mi spieghi per favore come posso risolvere, e se il mapping che ho trovato io è corretto o meno ?

bircastri:
In sostanza io voglio poter impostare tramite salvataggio su eeprom i 9 pin digitali (dirgli pin1, è un input, pin2 è un output e cosi via). Dal momento che nelle WEMOS, se scrivi digitalRead(1), in realtà non stai leggendo il pin 1 perchè c'è un mapping diverso, allora ho creato questo metodino in cui se gli chiedo il pin 1, mi dovrebbe restituire il PIN 1 Wemos.

Allora, provo a spiegarmi meglio.

Intanto fare una "tua" codifica è ovviamente legittimo, tanto più se questa numerazione la usi come indice di un array (nel tuo caso l'indirizzo in EEPROM), basta che questo non ti causi confusione di nomi.
Per dire, quando ci parli di "pin 2" a quel punto non si capisce se parli della TUA codifica, del GPIO2 WeMos o del pin D2 di Arduino. Se parli del GPIO dell'ESP specifica sempre "GPIOx", se parli del pin Arduino specidica sempre "Dx".

Sulle WeMos hai però già dei simboli che fanno questo: scrivendo "D" seguito dal numero di pin Arduino hai il valore del GPIO da usare. Ad esempio scrivere:
pinMode(D2, INPUT);
equivale a:
pinMode(16, INPUT);
in quanto D2 corrisponde al GPIO16, grazie a queste costanti predefinite nel suo core:

static const uint8_t D0   = 3;
static const uint8_t D1   = 1;
static const uint8_t D2   = 16;
static const uint8_t D3   = 5;
static const uint8_t D4   = 4;
static const uint8_t D5   = 14;
static const uint8_t D6   = 12;
static const uint8_t D7   = 13;
static const uint8_t D8   = 0;
static const uint8_t D9   = 2;
static const uint8_t D10  = 15;
static const uint8_t D11  = 13;
static const uint8_t D12  = 12;
static const uint8_t D13  = 14;
static const uint8_t D14  = 4;
static const uint8_t D15  = 5;

Inoltre ti consiglio di usare indici che partano sempre da 0 e non da 1, per cui anche quella funzione "getPinMapping()", incompleta, la puoi buttare al ces.. nel cestino, perché potrebbe diventare semplicemente un array (tra l'altro di byte, è inutile usare 2 byte invece di 1):
byte gpio[16] = { D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15 };
Nel tuo caso se hai bisogno solo di 9 pin, iniziare da D2 e saltando D10 (come detto, GPIO15 non lo usare) avrai:
byte gpio[9] = { D2, D3, D4, D5, D6, D7, D8, D9, D11 };
Per cui il tuo pin 0 sarà D2 ossia GPIO16, il pin 1 sarà D3 ossia GPIO5, e così via. Se vuoi mantenere l'indice 1 come primo pin, ti basta lasciare un valore vuoto e definire 10 elementi:
byte gpio[10] = { 0, D2, D3, D4, D5, D6, D7, D8, D9, D11 };

Detto questo, automaticamente avrai evitato il problema del pullup sul GPIO15, e reso più leggibile e logico il tutto.

Adesso mi spieghi per favore come posso risolvere, e se il mapping che ho trovato io è corretto o meno ?

Tra il precedente messaggio e questo ho cercato di spiegarti le cose per fartele capire, ma ho l'impressione che tu abbia preso "a scatola chiusa" quel progettino ma tu non sappia nulla di WeMos D1 o ESP8266 perché il discorso del GPIO15 è abbastanza noto...

Quindi cosa fare (o NON fare) te l'ho detto, ora però sta a te metterci qualcosa di tuo...