Expresate

Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:

pinguino y else if
 
Avisos
Vaciar todo

pinguino y else if

10 Respuestas
3 Usuarios
0 Reactions
4,007 Visitas
bastian
Respuestas: 384
Topic starter
(@bastian)
Ardero
Registrado: hace 18 años

Hola!

Antes que nada, pido perdón si el post no está el el foro correcto, pero es que soy un indeciso y no sabia en que categoría ponerlo... microcontroladores, programación... 😳 😳

Estoy haciendo mis pinitos con pinguino y el entorno de desarrollo me tiene "crujientito" (casi quemao). Se que tiene bugs (muchos) en los define. Gracias al blog de Uvanov, me he enterado que en breve (si breve dos veces bueno) saldrá la beta 8 corrigiendo estos fallos. Pero es que esta ultima me ha dejado muerto 😯 😯 😯

Resulta que si haces un programa con:
//Si los sensores están sobre blanco ==> AVANZA RECTO
if ( (digitalRead(CNY_ED)== BLANCO) && (digitalRead(CNY_EI)== BLANCO) )
{
TonServo[SERVO_D]=AVANCE_D;
TonServo[SERVO_I]=AVANCE_I;
}

else if ( (digitalRead(CNY_ED)== NEGRO) && (digitalRead(CNY_EI)== BLANCO) ) //Si el sensor derecho toca negro ==> GIRO A DERECHAS
{
TonServo[SERVO_D]=STOP_D; //Podemos girar sobre el eje con ATRAS_D
TonServo[SERVO_I]=AVANCE_I;
}

//Si el sensor derecho toca negro ==> GIRO A IZQUIERDAS
else if ( (digitalRead(CNY_ED) == BLANCO) && (digitalRead(CNY_EI)== NEGRO) )
{
TonServo[SERVO_D]=AVANCE_D;
TonServo[SERVO_I]=STOP_I; //Podemos girar sobre el eje con ATRAS_I
}

else //si los sensores están sobre negro ==> PARAMOS
{
TonServo[SERVO_D]=STOP_D;
TonServo[SERVO_I]=STOP_I;
}


Resulta que me da error al compilar
C:Pinguino Beta 7source/user.c:158: syntax error: token -> '{' ; column 3

C:Pinguino Beta 7source/user.c:167: syntax error: token -> 'else' ; column 5
error while compiling file C:Pinguino Beta 7examplesEjemplos DavidProgramas DesafioSigueLinea_2sensoresEXT

Tras muchas vueltas al código me voy al archivo user.c a ver que ha traducido y me encuentro que los else if me los traduce por elseif (tojunto) y claro el sdcc dice que si quieres arroz Catalina.
elseif(( digitalread(11)==FALSE)&&( digitalread(9)==TRUE))
{
TonServo[3]=1300;
TonServo[2]=2100;
}
elseif(( digitalread(11)==TRUE)&&( digitalread(9)==FALSE))
{
TonServo[3]=500;
TonServo[2]=1300;
}
else {
TonServo[3]=1300;
TonServo[2]=1300;
}

De momento la única solución que he encontrado es poner el if en la siguiente linea del else.. y así parece que tira.
else
if ( (digitalRead(CNY_ED) == BLANCO) && (digitalRead(CNY_EI)== NEGRO) )
{
TonServo[SERVO_D]=AVANCE_D;
TonServo[SERVO_I]=STOP_I; //Podemos girar sobre el eje con ATRAS_I
}

Solo quiero saber si le ha pasado a alguien más y que solución ha tomado, y si alguien más sabe de sorpresitas como esta.

Salu2!


Responder
9 respuestas
victorblue
Respuestas: 64
(@victorblue)
Trusted Member
Registrado: hace 17 años

En realidad no leo 6 veces. Al ser mutuamente excluyentes las condiciones de los if else, en el momento que se cumple una las demás no se comprueban y por tanto no se leen. Por eso no puedo darle al robot una orden en el primer if y la contraria en el tercero, por lo menos no en la misma ejecución del bucle.En cuanto a las funciones de lectura, no tengo por que utilizarlas... puedo acceder directamente a los registros del puerto con PORTBbits.RBx.

No es del todo cierto. Yo te estaba comentando el peor caso. Es decir, tu código con ifs anidados, si los sensores leen negro, antes de meterse en el último else tendrá que evaluar todas las concicionales de los ifs. En el mejor de los casos solo evaluará una condicional y se meterá en el bloqe asociado al primer if. De todas maneras, como supongo que el digitalRead lo que hará es leer el valor de un registro ( que se actualizará cada cierto tiempo), no creo que importe mucho.

El problema de inconsistencia que te planteaba es que imagines que hay dos "hebras" de ejecución en el micro, o los digitalread se actualizan a través de interrupciones programadas en un timer. Si no almacenas las lecturas en variables auxiliares antes de la evaluación de los ifs, podrías estar dándole órdenes "equivocadas" al robot: Si ocurre una interrupción para actualizar los valores de los sensores justo en mitad de la evaluación de los ifs en cascada, te podrías estar dejando

Ya sé que es un poco rebuscado pero pasar, puede pasar... Utiliza un switch, que es más claro de entender.

¿Y por qué no implementas la tabla de verdad con vectores? Así te ahorras los condicionales. En tu caso es muy fácil:

//Tabla de verdad
LD LI | SERVOD SERVOI
=========================
B B | AV_D AV_I
N B | STOP_D AV_I
B N | AV_D STOP_I
N N | STOP_D STOP_I

// Codigo: vd y vi son vectores que almacenan la tabla de verdad

VD=AV_D
VD[N]=STOP_D

VI=AV_I
VI[N]=STOP_I

// Mirando la tabla de verdad es fácil ver la relación entre el estado de los sensores y la orden a dar a los servos.
SERVOD=VD[LD];
SERVOI=VI

  • ;

    Saludos,


  • Responder
    bastian
    Respuestas: 384
    Topic starter
    (@bastian)
    Ardero
    Registrado: hace 18 años

    Hola victorblue!

    Como ya te he dicho antes, se trata de un ejemplo para un siguelineas de lo más sencillito... no hay threads, no hay actualización de datos por interrupción y por lo tanto no hay necesidad de variables... solo necesitaba un código que reflejase todos los posibles casos para que fuese "facil de entender" y es lo que escribí. Repito que no me importaba la eficiencia del código, solo su legibilidad.Si no utilizo nada de eso es por esa única razón.

    Ademas puestos a simplificar, el siguiente código hace lo mismo, sin vectores, sin threads, sin variables, sin else if, tablas de verdad y sin nada de nada, solo con ocho lineas de código:

    if (digitalWrite(CNY_ED)) //sensor derecho detecta blanco
    TonServo[SERVO_D]=AVANCE_D;
    else
    TonServo[SERVO_D]=STOP_D;
    if (digitalWrite(CNY_EI)) //sensor Izquierdodetecta blanco
    TonServo[SERVO_I]=AVANCE_I;
    else
    TonServo[SERVO_I]=STOP_I;

    Salu2!


    Responder
    victorblue
    Respuestas: 64
    (@victorblue)
    Trusted Member
    Registrado: hace 17 años

    Bueno, en el mio con 6 tienes bastante, lo que te ponía arriba de tabla de verdad era para que vieras por qué asignaba esos valores. Además te aseguro que el código máquina generado de un IF ... else es más complejo que el de una simple asignación, pues hay que evaluar las condicionales y generar dos saltos condicionales.... 😮 😮 😮

    Haz la prueba. Te lo digo yo que me tuve que tragar maravillosas asignaturas como teoria de automatas y lenguajes formales y la siempre incomprendida procesadores de lenguajes (en la que aprobaba un 5% de los presentados....).


    Responder
    bastian
    Respuestas: 384
    Topic starter
    (@bastian)
    Ardero
    Registrado: hace 18 años

    Hola victorblue!

    Mira de verdad que te agradezco las aportaciones, pero esta discusión no tiene sentido... tu código es mucho más eficiente y el mio es más "didáctico". Y te repito que la finalidad del mismo era que la gente a la que les explicaba el ejemplo no tuviese el menor problema en entender el código. De hecho, la finalidad del post era informar y ser informado sobre los bugs de un entorno de programación.Por lo visto parece que me explico peor de lo que creía. 😉

    Una cosa, no cometas el error de pensar que eres el único que ha estudiado...

    Salu2!


    Responder
    victorblue
    Respuestas: 64
    (@victorblue)
    Trusted Member
    Registrado: hace 17 años

    Touché 😀 😀 Es verdad, será esto de la crisis que está uno más sensible de lo normal ....

    Saludos


    Responder
    Página 2 / 2
    Compartir: