Pages: [1] 2 3   Go Down
Author Topic: Gadget para desconectar un ascensor  (Read 4874 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Muy buenas,

Estoy haciendo un proyecto que tiene que desconectar un ascensor a una determinada hora y dias y que lleva un menu para poder configurar la hora, los dias a desconectar, etc.

Conectare un RTC a arduino para saber la hora y el dia y segun hora y el dia conectare/desconectare el ascensor.

Lo que tiene que hacer arduino es lo siguiente:

Muestro hora y fecha
Leo Hora
Leo Dia
Si dia y hora laborables entonces //Hora desde 7.30 hasta 17.50
Desactivo Stop
Desactivo Led
Sino si hora es igual o mas grande a 17.50 y dias es laborable entonces //Empiezo proceso de desconexion
Espero puertas cerrar
Llamo planta 4
Espero ascensor llegue
Activo Stop
Activo Led
Sino //dias de fiesta o horas no laborables. Realmente este caso no se necesita porque de serie el rele de stop y el led estan activados
Activo rele Stop
Activo led

Hasta aqui todo bien. Luego pense en diseñar un menu para poder configurar la hora, fecha y dias de fiesta.

Ahora es cuando llega el problema. Yo necesito que el proceso principal (de ahora en adelante el proceso de desconexion) se ejecute siempre, pero si estoy dentro del menu y estoy esperando una entrada valida el programa se me queda parado y el proceso de desconexion no se ejecuta hasta que no se salga del bucle que espera.

Entonces empezé a buscar y vi que habia el multitasking, las interrupciones, etc. He pensado unas cuantas opciones para poder solucionar esto y lo que me gustaria es que les echarais un ojo y me dijerais que opinais (si me dais nuevos puntos de vista mejor que mejor)

Aqui pongo las opciones que se me han ocurrido (he tenido en cuenta que cuando el proceso de desconexion esta llegando a su hora no se pueda acceder al menu)

Soluciones a interferencia entre de los procesos desconexion y menu

OPCION 01: A 10 o 20 min desconexión no poder entrar en menú. Si se entra en los bucles de espera de datos a los 2 minutos se saldra automaticamente. Problema --> si voy viajando entre menús menos de dos min por cada uno puedo pasarme de la hora de desconexión

OPCION 02: Debería ser que si a las 17.50 no se ha podido iniciar lo intente cada 10 min. Tiene que haber una variable que guarde si la desconexión/conexión se ha realizado. Con esto juntamente que no se puede estar esperando una entrada mas de dos min me aseguro que el proceso de desconexión se ejecute siempre

OPCION 03: Interrupciones: creo que si la interrupción se encarga de la desconexión, mirando cada x tiempo la hora y si llega la hora se ejecuta el p desconexión. El p menú estaria en el principal. Pero esto no se como hacerlo

OPCION 04: En el bucle principal pongo condición de entrar en menú que se apriete la tecla asterisco y que no sean 10 o 20 min antes de la hora de conex/descon. En los bucles de espera de datos hago lo mismo. Si son 10 o 20 min antes se sale del bucle. Haciendo que se cierren los procesos hasta llegar al principal que entonces ira directamente al proceso desconexion

OPCION 05: En cada bucle que espere entrada de tecla se llama al proceso desconexion. Con esto me aseguro que aunque este en espera a que el usuario introduzca un dato el proceso de desconexion se lleva a cabo. Hay que tener en cuenta de que el proceso de desconexión sea autónomo (no haga falta que se le envien variables), porque sino se convierte en un lio tener que llevar las variables hasta el bucle de espera para pasárselas al proceso desconexion.

Bueno he intentado exponerlo lo más claro posible y espero que se entienda. También quiero daros las gracias por el tiempo que le dediqueis y un saludo smiley-grin
Logged

Offline Offline
Jr. Member
**
Karma: 3
Posts: 88
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Has llegado al punto que todos llegamos alguna vez ¿cómo demonios hago que el micro ejecute dos cosas a la vez?
Merecería un apartado esencial en todas las introducciones a microcontroladores.

La idea es que tienes un bucle principal de "baja prioridad" corriendo para gestionar por ej el menú.
Por otro lado tienes un conjunto de interrupciones que "interrumpen" el flujo de ese bucle para atender de forma inmediata sucesos de alta prioridad, una vez procesados, retornan al bucle principal donde lo dejaban.
Logged

0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1413
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

es decir, mirate el ejemplo blinkwithoutdelay jeje
Logged

* Si preguntas, pon el código de tu programa, hace mucho mas fácil ayudarte. Y me ahorro un mensaje pidiendo que lo hagas.
* Si consigues solucionar tu problema, dedica unos minutos a explicar en tu post como lo conseguiste para beneficio de todos.
* Cambia el 'Subject' de tu hilo y añade 'SOLUCIONADO' cuando hayas llegado a una solución al problema que planteaste.
* Utiliza un 'Subject' para tu hilo que explique de que va el hilo.
Si estas empezando:
* Comienza a usar Arduino
* Guías de iniciación a Arduino
* Ejemplos
* Referencia del Lenguaje
* Conceptos básicos
Guia de usuario de arduino
Tutoriales en Ingles
Si necesitas que alguien te escriba el código: http://www.freelancer.com/  o esta  http://www.guru.com/

Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Muchas gracias a los dos por contestar.

Como bien dices, jray, he llegado (en un proyecto que pensaba que seria sencillito) a un apartado de nivel elevado de los micros. Me he estado mirando las interrupciones, los RTOS y la programacion cooperativa (creo que se llama así).

Estoy barajando la posibilidad de solucionar el problema de dos maneras:

Con las interrupciones, y asi aprendo sobre este tema

Controlando el tiempo de espera de entrada de datos, limitandolo a dos minutos. Entonces si son las 17.50 (que es la hora en que se tiene que iniciar el proceso de desconexion) y estoy en el menú, a los dos minutos se cerraran los bucles de esperera de datos finalizando asi el proceso del menu. Entonces el proceso de desconexion se activa si ha pasado de las 17.50. Que aunque no se active justo a las 17.50 no pasa nada. Puede ser a las 18 o a las 19. Lo critico es que se active.

Sergegsx me miro el ejemplo este qu eme comentas

Muchas graicas

Un saludo smiley-grin
Logged

Madrid
Offline Offline
Sr. Member
****
Karma: 5
Posts: 481
Life isn't about finding yourself, life is about creating yourself!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yo iría a por la programación cooperativa.
Teóricamente con este método o con cualquier RTOS se crea aplicaciones con mas confiables  si haces un buen estudio completo de tus funciones y los requerimientos en términos de tiempo puedes tener ticks de μ-segundos.

En esta web http://chrisbarlow.wordpress.com/tag/time-triggered-architecture/ tienes un ejemplo para AVR y Arduino.
« Last Edit: January 25, 2013, 05:40:08 am by yOPERO » Logged

Engineering is the art of
making what you want from
things you can get.

     

[SOLUCIONADO]

Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Muchas gracias yOPERO, me lo miro smiley-grin
Logged

Spain
Offline Offline
God Member
*****
Karma: 25
Posts: 958
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ahora es cuando llega el problema. Yo necesito que el proceso principal (de ahora en adelante el proceso de desconexion) se ejecute siempre, pero si estoy dentro del menu y estoy esperando una entrada valida el programa se me queda parado y el proceso de desconexion no se ejecuta hasta que no se salga del bucle que espera.

Entonces empezé a buscar y vi que habia el multitasking, las interrupciones, etc. He pensado unas cuantas opciones para poder solucionar esto y lo que me gustaria es que les echarais un ojo y me dijerais que opinais (si me dais nuevos puntos de vista mejor que mejor)

Yo opino que os complicais en tonterias...  

Como siempre, ataca el problema de la zona mas baja, tu problema es:
    -"que si espera una entrada valida en el menu se queda parado"  pues no esperes!

Emplea las interrupciones para detectar pulsaciones o haz un barrido cada 200ms para detectar si al estar dentro del menu ha pulsado alguna tecla. A ti te da igual que desde que pulsa la tecla pase 250ms hasta que tu lo detectes, que mas da si al final el interface humano y su interaccion es lo que mas maniobra y posibilidades te deja...

Como si tiene que esperar 1 segundo desde que pulsa la tecla a ser detectada...  tu mientras ocupa el arduino en lo importante.

Con un simple circuito RC mantienes la pulsacion (la entrada a 1) aunque suelte la tecla, pero ya te digo, emplea interrupcion para eso y miesntras ves ejecutando el programa que te interesa, dedica solo x milisegundos a realizar el resto, a nivel percepcion de la persona que lo usa ni se entera.

No se si he dejado claro por donde tirar...

Tambien queda otra que parece se nos olvida cuando hablamos de varias tareas a la vez y demas...

Emplea dos micros, que un puñetero atmega 328 te cuesta menos de 3 euros, asi puedes emplear uno para una cosa y otro para otra, mas simple imposible.

¿porque la limitacion a no tener recursos, quedarte sin memoria, quedarte sin pines por menos de 3 euros que te cuesta otro micro?

Que hablamos de unidad por ascensor, no de miles de unidades...

Asi fabricas un Dual-Core  smiley-lol

Logged

CUIDADO !! MIS POST NO SON APTOS PARA MENORES. SI ERES MENOR DE 14 AÑOS DEBES DE LEERLOS ACOMPAÑADO DE UN ADULTO

Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Heke, realmente no entiendo mucho a que te refieres. Creo que dices que haga barridos cada x milisegundos para detectar si pulsan una tecla. Sino se pulsa el proceso desconexion se sigue ejecutando y cuando se realiza la pulsación se actua en consecuencia.

No enteiendo que es un circuito RC y para que necesito mantener la pulsación:

Con un simple circuito RC mantienes la pulsacion (la entrada a 1) aunque suelte la tecla, pero ya te digo, emplea interrupcion para eso y miesntras ves ejecutando el programa que te interesa, dedica solo x milisegundos a realizar el resto, a nivel percepcion de la persona que lo usa ni se entera.

Lo de utilizar dos atmega lo habia pensado, pero acabo de empezar con todo esto y plantearme colocar un atmega haria que el proyecto tardase aun mucho mas en acabar, pero estoy de acuerdo en que por menos de 3 euros tienes otro procesador con su memoria y es una buena solución.
Pero también creo que lo que intento hacer tampoco es tan complicado para requerir de otro procesador, pero claro eso solo es lo que creo.

Agradezco mucho tu post smiley-grin
Logged

Euskadi
Offline Offline
God Member
*****
Karma: 16
Posts: 721
Arduinotarrak
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola,
no sé qué interfaz utilizas para configurar. Tomando como ejemplo el keypad (4x3) del Playground, yo lo enfocaría así
Code:
void loop()
{
   activar_desactivar();
   configurar();
}
Para configurar, pondría un carácter de inicio de configuración ('#'), y un carácter de final de configuración ('*'), de suerte que si llega un '#' entra en la rutina de configuración, y no sale de las misma hasta que llegue el '*'

int configurar()
{
  char key = keypad.getKey();

  if (key = '#')
  {
     // se inician rutinas de configurar: for(;smiley-wink{}
     // leer todo lo que llega, configurar
     // hasta que llegue el carácter '*'
     if(key == '*')
        return 1;
  }
  else
     return 0;
}

¿Cuánto puede tardar la configuración? Uno, dos, tres minutos?  En el peor de los casos, se realizaría el activado/desactivado con tres  minutos de retraso. ¿Sería crítico eso?
En la función de configuración podrías añadir una comprobación de hora, y poner un mensaje de aviso "para de configurar, que llega la hora!"



Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola,

En mi opinión, el consejo que te han dado de leer el ejemplo de blinking without delay y tratar de entenderlo, creo que buena dirección. Es la base para poder entender todo lo demás.

Al final, el control a "tiempo real" es algo relativo, ya que depende de la dinámica (inercia) de tu sistema a controlar. Si vas a controlar la temperatura de una habitación pueden pasar minutos hasta que tu control actue y no es un problema. Pero si vas a un proceso químico, pueden ser milisegundos.

Lo que te están intentando explicar, es que si tu código es suficientemente rápido como para atender a cada una de las tareas, estarás cumpliendo tus requisitos. Ten en cuenta que una pulsación de un botón dura en orden de ms, es decir, tu micro es capaz de leer el estado de esa entrada, pero también de seguir ejecutando muchas otras cosas más. A parte que siempre puedes "alargar" dichas pulsaciones como te han explicado usando hardware adicional.
Por poner un ejemplo, si una pulsación a una tecla, son XX ms, a un micro le da tiempo a hacer muchas cosas y todavía el usuario sigue con el dedo en el pulsador.

Ahora bien, para poder hacer ésto hay diferentes formas de resolverlo. Aunque usando interrupciones puede darte muchos dolores de cabeza ya que si no tienes cuidado, puedes perder el control de tu aplicación.
Si te fijas como has descrito tu aplicación, es una secuencia. Si hay cierto evento, hago una determinada acción. Hacerte un diagrama de flujo de tu aplicación, creo que te ayudará a "visualizar" tu problema. Yo usaría una máquina de estados como método de programación. Dichos eventos que has comentado (pulsación de teclas, que sea determinada hora/fecha, etc) serán los que determinen el flujo de tu programa.

Lo que quiero decir, que si tu código hace un ciclo completo (leer entradas -> realizar código -> actualizar salidas -> volver a empezar) en menos tiempo que el tiempo necesario para atender a tu tarea más rápida, no tendrás ningún problema.
Los delay() son tus peores enemigos y ninguna función que realices tiene que tener código bloqueante. Por ejemplo, quedarse esperando con código que bloquea a que el usuario pulse un botón, o que se reciba cierto caracter por al puerto serie, o enviar por puerto serie y quedarse esperando a que se envie toda la cadena (esto lo hacían antes las funciones de Arduino, pero lo han modificado desde la versión 1.0), etc.

Saludos,


Igor R.
« Last Edit: January 27, 2013, 07:13:35 am by Igor R » Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Curro92, esto que me comentas es una opción que he tenido en cuenta. Si hago que el tiempo de espera a que el usuario es un tiempo limitado (para controlar que no se quede esperando un dato indefinidamente), cuando acabe de configurar tengo que hacer que se inicie el proceso de desconexion, siempre y cuando se haya llegado a la hora de ejecución. Pero si la hora de desconexion son las 17.50, realmente a mi no me importa que se inicie el proceso a las 18.30 (por decir una hora), siempre y cuando se inicie.

El asunto aqui es que esta solución (que es valida) no me permite aprender cosas más complicadas como los RTOS, interrupciones, etc. Siempre que hago un proyecto intento hacerlo de una manera para que pueda aprender cosas nuevas.

Igor R, he leido tus posts sobre interrupciones y multitarea. Lei uno (creo que lo escribistes en 2009) sobre como encender dos leds a diferentes frecuencias utilizando la funcion millis() y lo encontre muy muy interesante. He visto que esta función es muy potente y como bien dices me he dado cuenta que el delay() es una función que a primera vista parece muy práctica pero no la veo muy elegante para programar.

Voy a leerme con atención todo lo que me habeis comentado y intentar entenderlo todo. Y ralmente me gustaria poder programar este "gadget" de la forma más eficiente posible (dentro de unas limitaciones, claro)

Muchas gracias a todos por ir contestado smiley-grin

Un saludo
Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yo he diseñado un controlador que tiene una interface de usuario con una pantalla gráfica + botonera, la cual el usuario puede configurar diferentes setpoints, test, visualizar alarma, elegir de una BBDD módelos del aparato al que se le está haciendo el test, ...mientras el usuario navega por los menus, por detrás se siguen haciendo las cosas sin parar. Por eso te digo que lo que cuentas, se puede hacer sin ningun problema. En realidad hace muchas más cosas, como puede ser control de slew rates cuando cambias el target para no hacer cambios bruscos, tonos de alarma, la salida son mensajes CAN, control del disparo de una luz estroboscópica, y un largo etc (todas las tareas se realizan sin pararse cuando el usuario está navegando por el menu).

La forma que lo hice es creando una máquina de estados sencilla basada en tabla de transiciones (me cree mi propia librería para ello) la cual compartí en https://github.com/IgorReal/SECUduino/tree/master/FSM%20Library ó http://arduino.cc/forum/index.php/topic,75826.0.html
Puedes buscar más info en google : "event driven state machine".

Pero como te digo, hay muchas formas de resolver el mismo problema. Yo te cuento mi experiencia, y las ventajas que encuentro son:
- La sencillez: no usas sistemas de otros que sean dificiles de entender y/o requieren más tiempo estudiartelos que la aplicación en sí que tienes que realizar. Por no decir la dificultad que puede tener cambiar algo.
- Depurar es muy sencillo, por ejemplo, tengo una modificación a esa librería original para que me saque por puerto serie en el estado en el que me encuentro y el evento recibido.
- Puedes guardar en la memoria no volatil el estado en el que te encuentras por si se va la corriente. Es muy fácil tener el control de tu aplicación de nuevo después de un "apagón".
- Toda la lógica es una tabla de transición guardada en memoria de programa.
- Flexibilidad: cambiar el flujo de tu programa, es simplemente cambiar dicha tabla de transiciones.
- Leer el código aunque haya pasado mucho tiempo, es sencillo, ya que se resume en leerte la tabla de transición y luego ver lo que hace la función de cada estado.
- Aunque la limitación es que hay que tener en cuenta que es similar a un sistema cooperativo, la función realizada en cada estado tiene que durar menos que el tiempo de refresco que necesite la tarea más rápida. Para que de tiempo a leer eventos externos -> actualizar estados -> realizar las funciones de dichos estados y volver a empezar. Aunque el flujo de tu programa no va controlado por tiempo, si no por eventos.


Saludos,


Igor R.
« Last Edit: January 27, 2013, 09:59:19 am by Igor R » Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Muy buenas,

Igor R, como me has aconsejado estoy mirándome las maquinas de estado finito. Por lo que he visto es una solución perfecta para muchos proyectos desarrollados con microcontroladores y por lo que me dijiste para el mio también. Además me gusta porque así para hacer futuros proyectos de mayor embergadura me ira de perlas.

Por cierto buscando sobre las maquinas de estado finito me he encontrado con un término un tanto curioso, código espaguetti. Al parecer es el tipo de código que siempre he usado, plantear un problema y programar a "pelo" para ir solucionandolo. El término espaguetti se debe a algo? es que me ha parecido curioso que le llamen así y no entiendo el motivo.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Igor R estoy buscando sobre FSM y event driver machine, y cuando pongo en el google event driven machine me salen todo de resultados de QP. Por lo que he visto es un software para crear máquinas de estado para el arduino y por la de resultados que salen veo que es bastante famoso. Tu lo conoces? tienes alguna opinión sobre este software?

Tambien te queria pedir si sabes de alguna web, video, pdf, lo que sea, que expliquen como realizar de inicio a fin un proyecto en arduino con fsm, a modo de ejemplo. Es que me he estado mirando la teoria de las fsm pero no se como llevarlo al mundo arduino.

Si me puedes dirigir en la buena dirección te lo agradezco mucho

un saludo smiley-grin
Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

No he trabajado con QP. Tengo un libro por aquí de su autor que explica todas las tripas (es en C++). El problema es que necesitas tiempo para estudiartelo, ya que es como si programases en otro lenguaje de programación, con sus reglas, etc. Lo mismo que si usas un RTOS... y no tengo tiempo!! smiley-wink

Ya depende de lo que quieras hacer, valorar si te merece la pena usarlo...

Existen muchos ejemplos por la red. En el link que te he puesto del foro, hice 3 ejemplos usando mi librería y hay un pdf también.
Luego también puedes encontrar uno básico, es este otro que escribí de un miniprotocolo serie  http://real2electronics.blogspot.co.uk/2009/10/linksys-arduino.html
Ten en cuenta, que hay muchas maneras de hacer tu máquina de estados. Empieza por hacerte una básica con estructuras if().
Este ejemplo no contempla que le lleguen otros caracteres entre medio, etc. Lo que hace es encender el led de la placa si le llegan el comando S1F y apagarlo si le llega S0F


Code:
//Mini protocolo serie
//Igor Real

int luz1= 13;
int el1;
int estado=0;
byte dato_recibido;

void setup() {
   pinMode(luz1, OUTPUT);
   pinMode(12, OUTPUT);
   digitalWrite(12,LOW);
   Serial.begin(9600);
}

void loop()
{
  //trama a recibir --> S1F o S0F
  //S inicio
  //1 ENCENDIDO Y 0 APAGADO
  //F fin
  while (Serial.available() > 0)
  {
    //Significa que has recibido algo y lees el primer byte
    dato_recibido=Serial.read();
    if (dato_recibido=='S' && estado==0){
      estado=1;
    }
    if (((dato_recibido=='1')||(dato_recibido=='0')) && estado==1){
      estado=2;
      if (dato_recibido=='1')  el1=1;
      if (dato_recibido=='0')  el1=0;
    }
    if (dato_recibido=='F' && estado==2){
      estado=0;
      digitalWrite(luz1,el1);
      if (el1==0)  Serial.println("APAGADO");
      if (el1==1)  Serial.println("ENCENDIDO");
    }
    
  }
}


Lo tienes que pensar así:
- Si estoy en el estado 0 y recibo una S => voy al estado 2
- Si estoy en el estado 2 y recibo un 1 u 0 => asigno el valor a mi variable y voy al estado 3
....

Luego de ahí puedes pasar a otro tipo de máquinas que están creadas con tabla de transiciones; ó hacerte que cada estado tenga condición de entrada, salida y mientras está activado; ó que se puedan realizar acciones en las transiciones, etc.... cuanto más lo compliques, te estarás creando una especie de  "lenguaje de programación" nuevo, para que se me entienda, ya que tendrás que aplicar reglas a tu código para que te funcione adecuadamente.

Pensarlo para tu display+botonera, pues lo mismo... Piensa que cada estado muestras la pantalla al usuario, entonces te vas dibujando el diagrama de flujo:
- si estoy en el menu principal, y el usuario aprieta el botón "derecho", paso al segundo menu, etc.
- si estando en el segundo menu, deja apretado por más de 3 segundos el botón de aceptar, entonces hago ....

Esto hará que si tienes algun día que meter un menú nuevo entre medio (por poner un ejemplo), no tengas que cambiar todo tu código ó te vuelvas loco. Por ejemplo, algo típico cuando empiezas, es hacerte una variable según tus pulsaciones/submenus vas haciendo +/-1, +/-10, +/-100...  según en el nivel de menu en el que te encuentras. Entonces llamás a funciones según el valor de esa variable (por ejemplo usando un select case).
Lo haces, estás todo contento, y se te ocurre que ahora entre medio de tus menús, quieres meter uno más...ohhh no!!!  entonces es cuando te das cuenta que programar así es bastante ineficiente... (en mi opinión). Por no decir leer el código cuando ha pasado mucho tiempo y no te acuerdas de lo que hiciste....

Espero que te sirva,

Saludos,


Igor R.


Nota.- Lo he puesto muchas veces por el foro, pero por una más...uno de los mejores libros de microcontroladores y gratis! No es para atmel, pero es en C, así que no hay mucho problema... http://www.tte-systems.com/books/pttes
« Last Edit: January 29, 2013, 03:27:21 pm by Igor R » Logged


Pages: [1] 2 3   Go Up
Jump to: