Concurso de fotografía AM

Temática: «Una panorámica de tu acuario».
Ya esta abierto el plazo para presentar fotografías.

Más info
image01

¿Aún no conoces AMA?

Hazte socio de Acuariofilia Madrid Asociación.
CERRADO EL PLAZO DE INSCRIPCIÓN

Más info
image01

Atlas de peces de AM

¡Hemos alcanzado las 800 fichas! Visita nuestro atlas de peces actualizado.

Más info
image01

Cardúmenes y sociabilidad

Nueva actualización de la tabla con una extensa relación de peces, donde podrás conocer qué entorno necesita cada especie, su sociabilidad y si convive o no en cardumen. ¡Pasa a descubrirla!

Mas info
image01
Programación C desde Cero.
Respuestas: 135    Visitas: 47986
#31
(01-01-2016, 03:31 PM)Antonio Castro escribió: Pongamos un ejemplo sencillo:
Código:
int Cont=0;

void setup(){
    int A=10;
    Cont=A;
}

void loop(){
     int B=50;
     Cont=Cont+B;
     Serial.println( Cont);
     B=1000;
     delay(3000);
}

Con esto obtenemos lo siguiente:
160
210
260
310
360
410
...

El programa no hace nada demasiado interesante pero tenemos que intentar descifrar lo que hace y por qué. Se pide explicar algunas cuestiones añadiendo comentarios al programa.

Hay tres variables de tipo entero en el programa.
¿Cuales son variables globales y cuales son variables locales?

¿Parece que B=1000 no hace nada. Por qué?
¿Podríamos haber usado A=1000 en su lugar?

Por favor corrígeme en lo que he fallado...

Código:
int Cont=0;  // variable global que podra se utilizada tanto en el setup como en el loop y se mantendra en la memoria durante todo el tiempo que este en funcionamiento

void setup(){
    int A=10; //esta es una variable local que ¿solo se leerá una vez una vez arranque el sistema?
    Cont=A; //¿entoces cont tiene un valor de 10?
}

void loop(){
     int B=50;//esta es una variable local que ¿leerá el programa cada vez que comience bucle?
     Cont=Cont+B; //cont=¿0 o 10? + B=50 (50 o 60)  aqui me he quedao totalmente (n`´=!pillado
     Serial.println( Cont);
     B=1000;
     delay(3000);
}

no entiendo que hace esta función...Serial.println( Cont);
#32
Si no me equivoco saca por pantalla el contenido de la variable Cont.

Ahora bien me confunde la palabra Serial delante (disculpa los palabros que voy a soltar) ya que parece como si fuera una instancia de una clase, el println un método de esa clase y no veo la declaración de la instancia.

Como no conozco el entorno y bibliotecas que usáis simplemente especulo.
#33
Si Serial.println() envía por el puerto serial (como texto) el valor de Cont para que pueda ser visualizado en el "Monitor Serie", incluyendo un salto de linea.

Aquí os dejé un pequeño ejemplo de como usar el Monitor Serie

Y si RoFran, hay una pequeña errata en el código, ya que antes en el setup() hay que inicializar el puerto serie con Serial.begin(9600); para que funcione la salida.



Pedro, en encabezado defines Cont como entero y con valor 0

En Setup le das el valor 10, que es el de A, como es variable global su valor permanece visible para otras funciones.
(te falta el Serial.begin comentado)

En loop() al comenzar defines B como entero y valor 50

Y das a Cont el valor que tiene (10) mas el de B (50) luego acaba como Cont=60

Nada influye que B posteriormente tenga otros valores, al reiniciarse el loop() volverá a definirse como B=50 ( el C++ tiene forma de evitarlo pero eso es avanzar demasiado, dominemos esto y ya llegaremos al static)

Pero si en los siguientes bucles del loop() el valor de Cont va a ir variando (es variable global), la primera vez entró como 10, la segunda como 60, 3ª como 110,.....
#34
Tras este ciclo comienza el siguiente bucle pero en segundo paso por el bucle?¿?¿?¿.
Código:
void loop(){
     int B=50;//vuelve a tener un valor de 50
     Cont=Cont+B; //cont en cambio ahora tiene un valor de 60 + 50  total 110
     Serial.println( Cont); //envia el el valor de cont 110 al monitor
     B=1000; //aqui el valor de B es de 1000. //a esto no le veo la utilidad¿?¿?¿?
     delay(3000); paramos 3segundos
}
¿estoy en lo cierto?

si es así ¿que sentido tiene la primera variable global?

y si hubiéramos puesto A=1000
¿no nos habría tomado este valor en el segundo paso por el bucle? cambiando el resultado, por al estar en el setup ¿solo lee este la primera vez o cuando termine el bucle con alguna formula?????
#35
este enlace es una pagina donde te puedes descargar un simulador. Con el tema de mover lo mensajes se ha perdido.
Tenéis que daros de alta con un correo, ya podéis trastear-good.gif
#36
Si es correcto,

Pero no le busques sentidos ocultos, son meros ejemplos de uso de variables sin ningún objetivo más que ese.

El sentido de definir Cont como variable global es que se utiliza y cambia el valor en dos funciones distintas setup() y loop(), si no fuera global, sino que la definieras en una de las funciones, no sería visible por la otra.

A se define en setup() luego es local a setup() y luego carga con su valor a Cont, si pones A=1000; :
Si es en setup() empieza Cont con valor 1000 en vez de 10
Si es en loop() dará error ya que no esta definida, tendrías que poner int A=1000; siendo local en loop() y distinta a la definida en setup(), además solo en setup() se cargo el valor de su A en Cont, en loop() no hay asignación de Cont = A; que cambie el valor de Cont en función del valor de A
#37
(01-01-2016, 08:49 PM)ArturoS escribió: Si es correcto,



El sentido de definir Cont como variable global es que se utiliza y cambia el valor en dos funciones distintas setup() y loop(), si no fuera global, sino que la definieras en una de las funciones, no sería visible por la otra.

A se define en setup() luego es local a setup() y luego carga con su valor a Cont, si pones A=1000; :
Si es en setup() empieza Cont con valor 1000 en vez de 10
Si es en loop() dará error ya que no esta definida, tendrías que poner int A=1000; siendo local en loop() y distinta a la definida en setup(), además solo en setup() se cargo el valor de su A en Cont, en loop() no hay asignación de Cont = A; que cambie el valor de Cont en función del valor de A

Con esto entiendo:
¿que todas las variables hay que definirlas o de forma global antes del setup, o local dentro del loop?
¿Por que al segundo ciclo del bucle daría error, ya que en el setup solo lo lee al inicio?
#38
ya estoy por aquí

las variables siempre tienen que ser definidas.
antes del setup--global
dentro del setup o del loop-----locales


¿estáis utilizando algún temario en especial? o es a libre albedrío
#39
(01-01-2016, 09:03 PM)pedmar escribió: Con esto entiendo:
¿que todas las variables hay que definirlas o de forma global antes del setup, o local dentro del loop?
¿Por que al segundo ciclo del bucle daría error, ya que en el setup solo lo lee al inicio?
Las variables se definen o de forma global fuera de cualquier función o procedimiento, o en la función/procedimiento donde se usen (loop, setup o cualquier otra que se cree)

El error ya te dará al compilar, al detectar que en loop hay una variable A sin definir

Una forma normal de pasar valores de variables para hacer algo son los argumentos de función ejemplo:

Código:
void setup()
{
char arranco = 'S' // defino una variable que uso en setup
//.......
}

void loop()
{
   int a, b, c; // defino variables que uso en loop
    a =5;
    b =12;
    c = sumamelo(a,b);    // llama a a función, c obtendrá el valor 17

   if (c > 32000) {
      int d = 32000;   // defino una variable dentro de un bloque visible solo en el bloque
      c = c - d;
   }
}

int sumamelo (int X, int Y)  // X y Y son variables argumento que recogen el valor pasado
{
   int sumamos;     // tanto X, Y y sumamos son variables locales de la función sumamelo
                 // a X e Y  las podríamos haber llamado "a" y "b" y serian distintas de las usadas en loop
   sumamos = X + Y;
   return sumamos;
}
obviamente esto es un ejemplo, para tal cálculo no hace falta complicarlo tanto, son solo muestras de donde se definen variables
#40
(01-01-2016, 09:35 PM)rodazac escribió: ¿estáis utilizando algún temario en especial? o es a libre albedrío

jajaja -rofl.gif-rofl.gifalgun temario especial.

Yo estoy como el hombre orquesta: con un montón de archivos descargados de la red, a la vez un par de tutoriales de you tube, un simulador, unos folios donde garabateo el programa de arduino y aun así estoy tratando de entender la base de todo este lio -pardon.gif

(01-01-2016, 09:41 PM)ArturoS escribió:
(01-01-2016, 09:03 PM)pedmar escribió: Con esto entiendo:
¿que todas las variables hay que definirlas o de forma global antes del setup, o local dentro del loop?
¿Por que al segundo ciclo del bucle daría error, ya que en el setup solo lo lee al inicio?
Las variables se definen o de forma global fuera de cualquier función o procedimiento, o en la función/procedimiento donde se usen (loop, setup o cualquier otra que se cree)

El error ya te dará al compilar, al detectar que en loop hay una variable A sin definir

Una forma normal de pasar valores de variables para hacer algo son los argumentos de función ejemplo:

Código:
void setup()
{
char arranco = 'S' // defino una variable que uso en setup
//.......
}

void loop()
{
   int a, b, c; // defino variables que uso en loop
    a =5;
    b =12;
    c = sumamelo(a,b);    // llama a a función, c obtendrá el valor 17

   if (c > 32000) {
      int d = 32000;   // defino una variable dentro de un bloque visible solo en el bloque
      c = c - d;
   }
}

int sumamelo (int X, int Y)  // X y Y son variables argumento que recogen el valor pasado
{
   int sumamos;     // tanto X, Y y sumamos son variables locales de la función sumamelo
                 // a X e Y  las podríamos haber llamado "a" y "b" y serian distintas de las usadas en loop
   sumamos = X + Y;
   return sumamos;
}
obviamente esto es un ejemplo, para tal cálculo no hace falta complicarlo tanto, son solo muestras de donde se definen variables

increíble creo que es la primera vez que entiendo o creo entenderte y leer todo el código -laughbounce2.gif -laughbounce2.gif
#41
(01-01-2016, 09:03 PM)pedmar escribió:
(01-01-2016, 08:49 PM)ArturoS escribió: Si es correcto,



El sentido de definir Cont como variable global es que se utiliza y cambia el valor en dos funciones distintas setup() y loop(), si no fuera global, sino que la definieras en una de las funciones, no sería visible por la otra.

A se define en setup() luego es local a setup() y luego carga con su valor a Cont, si pones A=1000; :
Si es en setup() empieza Cont con valor 1000 en vez de 10
Si es en loop() dará error ya que no esta definida, tendrías que poner int A=1000; siendo local en loop() y distinta a la definida en setup(), además solo en setup() se cargo el valor de su A en Cont, en loop() no hay asignación de Cont = A; que cambie el valor de Cont en función del valor de A

Con esto entiendo:
¿que todas las variables hay que definirlas o de forma global antes del setup, o local dentro del loop?
¿Por que al segundo ciclo del bucle daría error, ya que en el setup solo lo lee al inicio?

No, las variables se pueden declarar dentro de cualquier función (locales) o fuera de cualquier función (globales). Todas las declaraciones deben de situarse antes de ser usadas, y por eso suelen colocarse todas al principio, pero se pueden declarar algo más tarde, se puede esperar hasta justo antes de usarse por primera vez para declararlas.

Tanto setup(), como loop() son funciones normales en lo que respecta a declaraciones de variables. Las variables que se declaran dentro de setup() existe solo dentro de la ejecución de setup(), las que se declaren dentro de loop() solo existirán dentro de la función loop() mientras esta se esté ejecutando y dentro de una función que se llame funciónDePrueba() las variables que se declaren en ella solo existirán dentro de esa función mientras se esté ejecutando.

Las variables que son especiales son las variables globales porque no se declaran en el interior de ninguna función y son accesibles permanentemente desde cualquier función. Las locales son propias de cada función y en eso setup() y loop() son funciones normales y las variables que se declaren en ellas son locales.

Podemos hacer una función que muestre el valor de todas las variables globales, pero no podemos hacer una función que muestre ninguna variable local de otras funciones.

Código:
int Cont=0; // cont es variable global
int X=1;
int Y=2;

void MuestroVarGlobales(){
    Serial.print("Cont="); Serial.println(Cont);
    Serial.print("X="); Serial.println(X);
    Serial.print("Y="); Serial.println(Y);
        Serial.println();
}

void OtraFuncion(){
    int H;
    H=1;
    int I;
    I=2;
    int J;
    J=3;
}


void setup(){
    int A=10; // variable local
    Cont=A;
    MuestroVarGlobales();
}

// hemos perdido la variable A
// pero su valor se guardó en Cont  que es una variable global

void loop(){
     int B=50;
     Cont=Cont+B;
     B=1000;
     MuestroVarGlobales();
     delay(3000);
}

El programa compila sin problemas y la salida de ese programa sería la siguiente:

Cont=160
X=1
Y=2

Cont=210
X=1
Y=2

Cont=260
X=1
Y=2

Cont=310
X=1
Y=2

Cont=360
X=1
Y=2

Cont=410
X=1
Y=2

[...]

Es importante pillar el concepto de variable global y variable local.

Seguramente habría resultado más legible

Código:
void OtraFuncion(){
    int H;
    int I;
    int J;

    H=1;
    I=2;
    J=3;
}

O incluso

Código:
void OtraFuncion(){
    int H,I,J;

    H=1;
    I=2;
    J=3;
}

Pero no es obligatorio poner todas las declaraciones al principio.
Solo es obligatorio que la declaración esté colocada antes de su uso.
Si lo hacemos al revés el compilador dará error.
#42
con la salida me has descolocado Confused

creia que funcionaba de otra manera¿¿¿¿ no hace las funciones empezando desde

int Cont=0; // cont es variable global
int X=1;

y a continuación el resto de las funciones, hasta llegar a void loop, donde ¿hace un bucle infinito dentro del loop? -pardon.gif
#43
Creo pedmar que tu duda tiene que ver con una cosa que me mosqueaba a mi ayer: ¿Un setup y un loop?

En C se pueden declarar distintas funciones pero tienen que ser llamadas para que se ejecuten. Setup y loop son dos funciones más pero muy especiales de arduino. La funcion principal, main (que no la ves), las llama a la primera una vez y a la segunda en cada iteración de un bucle infinito.

El resto de funciones, si no son llamadas no se ejecutan. Para el caso del ejemplo de Antonio la funcion MuestroVarGlobales es llamada dentro de setup y loop. Es en esas llamadas cuando se ejecuta. Sin embargo OtraFuncion no es llamada en ningún momento y, por tanto, no se ejecuta.

Digamos que las funciones son plantillas de qué hacer.

Por si quieres profundizar sobre lo del main, setup y loop:http://www.qmbecanada.com/?p=720
#44
Pedro tienes razón, la primera salida tiene que ser

Cont=10
X=1
Y=2

que es la que corresponde a la llamada a MuestroVarGlobales(); desde setup()

Lo que habrá pasado es que Antonio ha debido tardar unos segundos en abrir el serial monitor, y como no hay ningún delay previo, ya el bucle iba por Cont =160, que es lo que ha empezado a pintar




No nos liemos esto es Arduino no C++, "digamos que" está basado en pero tiene esas diferencias.

Aquí no hay función main, al iniciarse el programa se ejecuta la función setup() y finalizada esta se ejecuta loop()

Cualquier función que se defina/o de librería para ser ejecutada ha de ser llamada por el setup() o por el loop(), o desde alguna función secundaria llamada desde las anteriores.

No es objeto de este post ponerse a profundizar en el código de las librerías incorporadas por defecto en la instalación ni en el funcionamiento interno del compilador.
#45
(02-01-2016, 04:18 PM)ArturoS escribió: Pedro tienes razón, la primera salida tiene que ser

Cont=10
X=1
Y=2

que es la que corresponde a la llamada a MuestroVarGlobales(); desde setup()

Lo que habrá pasado es que Antonio ha debido tardar unos segundos en abrir el serial monitor, y como no hay ningún delay previo, ya el bucle iba por Cont =160, que es lo que ha empezado a pintar




No nos liemos esto es Arduino no C++, "digamos que" está basado en pero tiene esas diferencias.

Aquí no hay función main, al iniciarse el programa se ejecuta la función setup() y finalizada esta se ejecuta loop()

Cualquier función que se defina/o de librería para ser ejecutada ha de ser llamada por el setup() o por el loop(), o desde alguna función secundaria llamada desde las anteriores.

No es objeto de este post ponerse a profundizar en el código de las librerías incorporadas por defecto en la instalación ni en el funcionamiento interno del compilador.

Lo que ocurre es que estoy usando Arduino Pro Micro y no he tenido cuidado. He ido muy rápido y se me escapó ese detalle. El Arduino Pro Micro hace cosas raritas porque no tiene un procesador dedicado para el puerto Serial.

Yo he trabajado mucho con Arduino Pro Mini. En total en tres tandas he terminado comprando 30 paquetes de 10. Solo tengo un par de adaptadores USB-FTDI y con uno que tengo enchufado en el cable USB me sobra. El otro lo tengo de repuesto.
Como ya dije me va de maravilla con Arduino Pro Mini.

Es verdad que Arduino Pro Micro es más potente en cuanto a SRAM, pero es rarito.

Fijaros que en el programa no he abierto el puerto Serial. Tendría que haber hecho lo siguiente.

Serial.begin(9600);
while(!Serial); // Esto es solo para Arduino Micro. Se queda esperando a que se complete la inicialización del puerto Serial

El caso es que yo no iniciarlizarlo el puerto Serial de ninguna forma y el Arduino por su cuenta y riesgo decide abrir el puerto cuando el programa ya lleva un tiempo funcionando.

Otra cosa, yo uso trazas mucho y en Arduino Pro Mini no me da problemas. En Arduino Pro Micro, me obliga a abril el puerto Serial o sino se bloquea.

Se puede usar y con un poco de programación se puede hacer que funcione como uno quiere, pero ahora que estoy practicando con este cacharrito me preocupa que pueda llegar a bloquearse el puerto serie por un problema de recepción debido a interferencias o algo.

En Arduino Pro Mini el adaptador USB_FTDI lleva su propio procesador.

No todo es malo. Es muy importante que tenga mñas SRAM y un puerto serial pese a esos inconvenientes puede ofrecer algunas ventajas.

Hasta que no se usa mucho un cacharrito no hay forma de hacerse una idea de cuales son sus putos fuertes y sus puntos débiles.

Para el proyecto de un programador se podrá usar tanto Pro Mini como Pro Micro, pero salvo que necesitemos un programa muy grande (y no es el caso) yo veo ventajas de seguridad y comodidad de uso en el Pro Mini.

No es una opinión totalmente objetiva porque me encanta Arduino Pro Mini.

El Pro Mini con el adaptador USB-FTDI es parecidísimo al Arduino UNO que es el más estandar y eso lo hace todo más fácil.

A mí me ha costado encontrar información sobre ciertas cosas de Arduino Pro Micro y de Arduino Leonardo, y no me ha parecido un tema sencillo, pero yo pongo el link para que el que tenga el nivel suficiente lo investigue.

http://www.robotpark.com/Robotpark-LEONA...troller-En

Usuarios navegando en este tema: 2 invitado(s)


Salto de foro: