Cómo llamar a la función de anulación en respuesta a la recepción de datos en serie (Arduino)

2

Soy nuevo en Arduino, y estoy tratando de descifrar este código. Hay varias funciones de anulación a las que estoy intentando llamar en respuesta a la recepción de datos en serie (el Monitor muestra "Ingrese una función válida para llamar"), pero supongo que no sé cómo.

typedef void (* Caller)();
Caller FuncCall[] = {a, b, c};
String func_list[] = {"a","b","c"}; //correspond to functions in FuncCall, order matters.

"a", "b" y "c" son 3 funciones separadas que se escriben más adelante en el código.

¿Me estoy perdiendo algo aquí? Puedo elaborar si es necesario.

    
pregunta M.Y.

4 respuestas

2

El Monitor de serie no es más que una ventana que muestra los datos de serie enviados a la PC. ¿Está diciendo que está pasando caracteres al ATMega328 y está llamando a ciertas funciones en función de lo que envía?

Pero en cuanto a tu pregunta:

typedef void (* Caller)()

Es un typedef para un puntero de función void* (con tipo de nulo) con el nombre de Called .

Caller FuncCall[] = {a, b, c);

Se evaluará en tiempo de compilación para:

void (* Caller)() FuncCall[] = {a, b, c);

Que es esencialmente una matriz de punteros de función void* .

No estoy seguro de lo que quieres decir con void a() , pero para usar los punteros de función debes inicializarlos para que apunten a funciones. Considere el siguiente ejemplo:

void printFunc(){
    printf("Print Test\n");
}

int main(){
    void (*functionPtr)();
    functionPtr = &printFunc; //functionPtr points to the address of printFunc()
    functionPtr();
    return 0;
}

Considere el siguiente código:

#include <SoftwareSerial.h>

/* These are function prototypes - required by the compiler */
void a();
void b();
void c();

typedef void (* Caller)();
Caller FuncCall[] = {&a, &b, &c}; //initialize addresses for pointers 
//String func_list[] = {"a","b","c"}; //this is a terrible way to do this
char func_list[] = {'a', 'b', 'c'};   //use this instead - if you wish


void setup(){
    Serial.begin(9600);
}

void a(){
    Serial.println("Called Function: a\n");
}

void b(){
    Serial.println("Called Function: b\n");
}

void c(){
    Serial.println("Called Function: c\n");
}

void loop(){
    if(Serial.available())
        switch(Serial.read()){
            case 'a':           //this could also be func_list[0], if you want
                FuncCall[0]();
                break;

            case 'b':
                FuncCall[1]();
                break;

            case 'c':
                FuncCall[2]();
                break;

            default:
                Serial.println("There was an error\n");
                break;
    }
}

Donde simplemente envías a Arduino un carácter (a, b, o c) a través de el Monitor de serie . Puedes hacer la implementación tan complicada como quieras. Por ejemplo, podría tener análisis e indexación de cadenas en la matriz, como se sugiere, pero la implementación anterior no podría ser más sencilla de lo que yo sé.

    
respondido por el sherrellbc
1

Debe indicar que desea acceder a lo que apunta el puntero.

Agregue un asterisco delante del puntero y paréntesis a su alrededor.

 (*FuncCall[0])();
    
respondido por el CountZero
0

Parece que la intención es buscar una cadena entrante en func_list[] , convirtiéndose en un valor de índice si se encuentra, y luego usar ese índice para obtener la entrada correspondiente en FuncCall[] , y llamar a esa función.

Una vez que tenga i , el índice del nombre de la función, la llamada se vería así:

(FuncCall[i])();

Además, tenga en cuenta que tiene un error tipográfico en su inicializador para FuncCall: el paren de cierre debe ser una llave.

    
respondido por el Dave Tweed
0

De un comentario:

  

Estoy intentando llamar a las funciones fuera del código (es decir, en el   espacio de entrada de texto en el monitor serie)

Whoa there ... no puedes recopilar funciones escritas en C en un búfer y luego "ejecutarlas". Tendría que compilar un compilador, un ensamblador, un enlazador, etc. en el programa Arduino para realizar sus funciones en tiempo de ejecución. C es un lenguaje compilado (no un interpeted).

Las construcciones en su pregunta simplemente le permiten llamar a funciones, que estaban disponibles en tiempo de compilación, con firmas compatibles "dinámicamente" en tiempo de ejecución, al acceder a ellas a través de una matriz. Esta es una forma en que a veces se implementan las funciones de "devolución de llamada".

    
respondido por el vicatcu

Lea otras preguntas en las etiquetas