Array di funzioni ed ingressi multipli

Ciao a tutti, dopo un paio di anni di prove, ricerche, fallimenti... sono riuscito a creare questo array di funzioni dove vengono richiamate, in base agli ingessi, delle subroutine. Ho un problema pero'.... certi ingressi sono on ed off ciclicamente, per esempio pointer 12 ha input 4 e 5 , 4 e' pulsante HIGH LOW , 5 continuo HIGH. Succede che quando input 4 e' LOW si attiva la subroutine del pointer 8
Come posso fare ad evitare l'esecuzione di pointer non espressamente chiamati?
Grazie per suggerimenti

// Array puntatore funzioni
void (*actions[64][2])() = {
  {Act1, nullptr},//0 input
  {Act2, nullptr},//1
  {Act3, nullptr},//2 input 3
  {nullptr, nullptr},//3
  {Act4, nullptr},//4 input 4
  {nullptr, nullptr},//5
  {Act5, nullptr},//6  input 3,4
  {nullptr, nullptr},//7
  {Act6, nullptr},//8 input 5  
  {nullptr, nullptr},//9
  {Act7, Act3},//10  input 3,5
  {nullptr, nullptr},//11
  {Act8, Act4}, //12 input 4,5
  {nullptr, nullptr},//13
  {Act5, Act9}, //14  input 3,4,5
  {nullptr, nullptr},//15
  {Act10, nullptr},//16  input 6
  {nullptr, nullptr},//17
  {Act3, Act11},//18 input 3,6
  {nullptr, nullptr},//19
  {Act4, Act12}, //20 input 4,6
  {nullptr, nullptr},//21
  {Act5, Act13}, //22 input 3,4,6
  {nullptr, nullptr},//23
  {nullptr, nullptr},//24 
  {nullptr, nullptr},//25
  {nullptr, nullptr},//26
  {nullptr, nullptr},//27
  {nullptr, nullptr},//28
  {nullptr, nullptr},//29
  {nullptr, nullptr},//30
  {nullptr, nullptr},//31
  {Act17, nullptr},//32 input 7
  {nullptr, nullptr},//33
  {Act3, Act14}, //34  input 3,7
  {nullptr, nullptr},//35
  {Act4, Act15}, //36  input 4,7
  {nullptr, nullptr},//37
  {Act5, Act16},//38 input 3,4,7
  {nullptr, nullptr},//39
  {nullptr, nullptr},//40
  {nullptr, nullptr}, //41
  {nullptr, nullptr},//42
  {nullptr, nullptr},//43
  {nullptr, nullptr},//44
  {nullptr, nullptr},//45
  {nullptr, nullptr},//46
  {nullptr, nullptr},//47
  {nullptr, nullptr},//48
  {nullptr, nullptr},//49
  {nullptr, nullptr},//50
  {nullptr, nullptr},//51
  {nullptr, nullptr},//52
  {nullptr, nullptr},//53
  {nullptr, nullptr},//54
  {nullptr, nullptr},//55
  {nullptr, nullptr},//56
  {nullptr, nullptr},//57
  {nullptr, nullptr},//58
  {nullptr, nullptr},//59
  {nullptr, nullptr},//60
  {nullptr, nullptr},//61
  {nullptr, nullptr},//62
  {nullptr, nullptr}//63

};

void cond() { // Funzione condizione

  uint8_t signalStates = PIND; // Leggi gli stati dei segnali utilizzando la manipolazione diretta del port

  int status = (~signalStates >> 2) & 0b00111111; // Codifica gli stati in un singolo intero
//  Serial.print("Stato: "); // Stampa il testo "Stato: "
// Serial.println(status); // Stampa lo stato attuale
  if (previousStatus != status) { // Verifica se lo stato attuale è diverso dallo stato precedente
    // CRGB::Black;         ////test 04072024 // Commento di test
    //  FastLED.show();      ////test 04072024 // Commento di test
//    FastLED.clear();   ////originale // Cancella la matrice di LED
    previousStatus = status; // Aggiorna lo stato precedente
  }
  // Chiama la funzione corrispondente
  for (auto& func : actions[status]) { // Itera sulle funzioni associate allo stato attuale
    if (func) { // Verifica se la funzione è valida
      func(); // Chiama la funzione
    }
  }
  typedef struct { // Definizione di una struttura per memorizzare i valori di stato
    long  int Time_blink; // Tempo di blink
    long  int Time_hold; // Tempo di hold
  } StatusValues; // Nome della struttura

  int statusMap[] = { // Mappa degli stati
    2, 4, 6, 10, 12, 14, 18, 20, 22, 34, 36 // Valori degli stati
  };

  StatusValues statusValues[11] = { // Valori di stato
    {2408, 150000}, // 2    241500 // Valori per lo stato 2 testato tempi e sincro ok
    {2408, 150000}, // 4 // Valori per lo stato 4 testato tempi e sincro ok
    {2400, 150000}, // 6 // Valori per lo stato 6 testato tempi e sincro ok
    {1400, 20000}, // 10 // Valori per lo stato 10
    {1400, 20000}, // 12 // Valori per lo stato 12 testato tempi e sincro ok
    {2400, 150000}, // 14 // Valori per lo stato 14
    {1400, 200000}, // 18 // Valori per lo stato 18
    {1400, 200000}, // 20 // Valori per lo stato 20
    {1400, 200000}, // 22 // Valori per lo stato 22
                                                     // {1400, 200000}, // 24 // Valori per lo stato 24
    {1400, 200000}, // 34 // Valori per lo stato 34
    {1400, 200000} // 36 // Valori per lo stato 36
  };

  //int Time_blink, Time_hold; // Commento di variabili
  int idx = -1; // Indice per la ricerca nella mappa degli stati
  for (int i = 0; i < sizeof(statusMap) / sizeof(statusMap[0]); i++) {//modificato sizeof(statusMap[11] con sizeof(statusMap[0]
    if (status == statusMap[i]) {
      idx = i;
      break;
    }
  }
  if (idx != -1) {
    Time_blink = statusValues[idx].Time_blink;
    Time_hold = statusValues[idx].Time_hold;
  }
}

ciao,

mi sa di "gestione menù su display/video" ...dico la mia...un ingresso digitale può essere "alto" o "basso"...se lo stato di un singolo ingresso non è sufficiente a definire cosa si deve fare si devono definire e verificare altre condizioni... magari anche definire e valutare i passaggi di stato della funzione...magari una ricerca su "macchina a stati finiti" qui nel forum potrebbe aiutare...

non mi e' molto chiaro cosa mi vuoi dire.
Io penso che mi manchi qualcosa nella
void cond();

se 4 cambia...cambia anche la variabile "status"...quindi vai a verificare che input sono alti e ti trovi che 5 è alto...ecco che pointer 8, che verifica solo stato di input 5, viene eseguito.

ti serve un'altra discriminante...

eh...lo so..... e' che non ne ho altre da usare come condizione univoca. Ci penso un po' su'.

una discriminante potrebbe se una funzione è in esecuzione...un terzo puntatore che parte nullo su cui salvi la funzione in esecuzione e che "resetti" quando finito...quindi esegui una funzione solo se questo è nullo...spero di essermi spiegato...e che possa funzionare...ma ripeto...uno sguardo a "macchine a stati finiti" qui nel forum potrebbe aprire nuovi orizzonti...

PS: oppure ogni funzione ritorna uno stato e quindi sai se sei uscito o meno...

Ma il problema è che l ingresso 5 è usato anche in un altro stato. Quindi riconosce la condizione dell altro stato. Inoltre, quando input 4 è LOW, non ho la condizione per lo stato che richiede input high 4 e 5. Credo di essere un po in confusione. È ora di fare uno stacco fino a quando non si accende un neurone.

nessun altro ha qualche consiglio.... da propormi uno spunto di approccio diverso?

Sì, io

Troppo complicato e con troppo poche spiegazioni

Riparti da capo e, stavolta, decidi gli stati e la logica del programma 'prima' di scriverlo

Comunque: auguri

Sei gentile,grazie.

Io sono d'accordo con C1P8, poche informazioni, sinceramente trovo miracoloso che andreaber sia riuscito a darti dei consigli.

Inoltre scritto così quel pezzo, senza un allineamento è complicato leggere i vari stati dei commenti, almeno scriverlo così:

void (*actions[64][2])() = {
  {Act1   , nullptr},         //0  input
  {Act2   , nullptr},         //1
  {Act3   , nullptr},         //2  I=3
  {nullptr, nullptr},         //3
  {Act4   , nullptr},         //4  I=4
  {nullptr, nullptr},         //5
  {Act5   , nullptr},         //6  I=3,4
  {nullptr, nullptr},         //7
  {Act6   , nullptr},         //8  I=5  
  {nullptr, nullptr},         //9
  {Act7   , Act3},            //10 I=3,5
  {nullptr, nullptr},         //11
  {Act8   , Act4   },         //12 I=4,5
  {nullptr, nullptr},         //13
  {Act5   , Act9   },         //14 I=3,4,5
etc.

Secondo me serve vedere il codice che utilizza questo array in base agli input.

Dunque forse sono io che non vedo dove salvi queste variabili, oppure manca del codice. Sicuramente non sapendo altro, questa porzione di codice non fa nulla di utile poiché le variabili sono locali e non esistono più al termine della funzione cond().

Attualmente se per 2 o più cicli di loop consecutivi PIND ha lo stesso valore verrà eseguita sempre la stessa funzione.
C'è da vedere anche cosa c'è collegato ai 6 pin di porta D.
In mancanza del quadro complessivo tutto appare misterioso. :face_with_monocle:

Ciao.

Ciao, grazie per la risposta.... ma io voglio che siano locali e che di conseguenza finiscano al termine della cond(). Intendo dire che la funzione cond(), tramite l'array, controlla lo stato degli ingressi e aggiorna lo stato. Il problema e' che ci sono delle condizioni che richiedono 2 ingressi (uno sempre HIGH 5, l'altro invece intermittente HIGH, LOW 4). Quando quest'ingresso diventa LOW 4, lo stato cambia (essendoci solo 1 ingresso HIGH) di conseguenza nell'array viene abilitato lo stato dove mi trovo l ingresso 5 HIGH) . cond() è nel void loop.
Forse non sono chiaro, scusate.

Per carità, era solo per capire. Se ti vuoi concentrare solo su questo dettaglio posso dire solo che ciò è normale dal mio punto di vista.
(decimale) {esadecimale}
Supponiamo che PIND abbia questo valore:
PIND vale 0b11001100 (204) {cc}
allora status vale 0b0001100 (12) {0c}

Mentre se PIND vale 220
PIND vale 0b11011100 (220) {dc}
allora status vale 0b0001000 (8) {08}

Non possiamo aspettarci un comportamento differente.

Ciao.

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