Nuevo sensor M2M Wigwag


Wigwag han creado un sensor y un paquete de centro que hace que la automatización y la ejecucion en  sus dispositivos conectados  sea cada vez mas tangible.¿ Pero será su interfaz  la receta para la adopción del consumidor de  Internet de las cosas?

 wigwagsensor

El hogar conectado que viene, es una experiencia inconexa pues para conseguir algo para encender o interactuar con otros dispositivos conectados requiere una aplicación especifica   . ¿Quieres encender sus luces Hue? Hay una aplicación para eso. Por desgracia, es un ser diferente la aplicación que abre los seguros de las puertas conectadas.

Esto tiene que cambiar, y ese cambio está llegando. Hay una gran cantidad de proyectos de SmartThings a Mobiplug a ifttt para ayudar a que los dispositivos conectados tan dispares qeu converjan en una sola interfaz de usuario: wigwag . Este proyecto Kickstarter (de una empresa con sede en Austin, Texas) permite crear el mismo tipo de dispositivos que los usuarios de IFTTT estarán familiarizados.

El proyecto ofrece un relé, que es esencialmente un concentrador inalámbrico que puede hablar con Wi-Fi y el estándar de automatizacion domestica  X10. También hay un sensor que puede detectar una amplia variedad de entradas de temperatura, luz ambiental, humedad, movimiento y más.

El otro componente es una salida de las luces de LED en una tira de 2,5-metros. La idea es que cuando el sensor detecta los cambios físicos puede decir el relé para realizar una acción basada en la web, como el envío de un texto o un correo electrónico o apagar las luces encendido o apagado. Y por supuesto, hay un servicio basado en la nube que soporta todo.

La aplicación también funciona con otros dispositivos conectados dentro de la casa para que pueda utilizar otros dispositivos como las bombillas Hue o el Belkin Wemo como entradas y salidas. Como alguien que puede pasar unas horas jugando con diferentes dispositivos  ifttt  conectados, este tipo de proyectos parece un juguete maravilloso que va a costar alrededor de $ 119 para el paquete más pequeño a $ 579 para un paquete para toda la casa.

wigwag

No estoy seguro si este es el modelo adecuado para el hogar conectado para la mayoría de la gente, ya que la construcción de las recetas podría ser intimidante para algunas personas, pero podría ayudar a las empresas de los consumidores a entender cómo construir ecosistemas conectados dentro de la casa.

Estas plataformas “Maverick”, como el sensor de hilo y SmartHubs paquete de sensores casa están permitiendo que los primeros usuarios e  experimentar con M2M , pero este tipo de opciones abiertas pueden no ser las  adecuadas para el usuario medio. Plataformas como IFTTT que ayudan a vincular el mundo físico y virtual a través de fáciles dispoistivos pueden ser un buen puente. Lo divertido de wigwag es que se está proporcionando a la vez una plataforma  “rebelde”, con su sensor y la caja de relés, pero también está permitiendo a los usuarios de un panel de control más intuitivo a la IFTTT.

Fuente aqui

Anuncios

Cómo configurar el entorno de desarrollo de Android


 Hay muchas maneras de desarrollar para Android, existindo tantas  opciones que a veces es un poco intimidante la configuración de su entorno por lo que desde estas lineas se persigue el objetivo de  ofrecer instrucciones paso a paso para instalar y configurar el entorno de desarrollo de Android para Windows.

Medio Ambiente / herramientas: Esta es la configuración que  Greg  Zimmer  ha elegido utilizar:

  • Ventanas (estoy usando Windows 7, pero cualquier sabor de las ventanas a hacer)
  • Eclipse IDE para desarrolladores de Java (v3.5 Galileo)
  • Plataforma Java (JDK 6 Update 18)
  • Android SDK Herramientas, Revisión 4

Paso 1. Instalar Eclipse IDE
El autor Optó por usar el Eclipse IDE para desarrolladores de Java (v3.5 Galileo). Puede descargar el aquí

  • Este es un archivo zip y no requiere instalación. Sólo tienes que copiar la carpeta de Eclipse en el directorio de programas

Paso 2: Instalación de la plataforma Java (JDK 6 Update 18)

  • Seleccione la plataforma
  • Ahora ejecute la instalación de JDK. No he cambiado ninguna de las opciones de instalación predeterminadas. Cuando se haya completado continúe con el paso 3.

Paso 3: Descargue el Android SDK Herramientas, Revisión 4

  • Esto no requiere instalación. Simplemente descomprimir y copiar los archivos. Puede instalar el paquete en cualquier lugar, pero recuerde que usted pone como tendrá que hacer referencia a él en Eclipse. Da la casualidad que lo instale dentro de mi carpeta eclipse.

Paso 4: Configurar el SDK de Android 

  • Lanzamiento “SDK Setup.exe” ubicado en la carpeta de instalación del SDK de Android “
  • Pulse “Cancel” en la pantalla “Elegir paquetes a instalar” diálogo
  • Seleccione “Configuración” en el panel izquierdo
  • Marque “Fuerza https:// … fuentes que descargar usando http://”
  • Pulse el botón “Guardar y Aplicar”
  • Seleccione “Paquetes disponibles” en el panel izquierdo
  • Seleccione “Documentación” (en la parte superior de la lista)
  • Seleccione “USB Driver Package, rev 3 (en la parte inferior de la lista)
  • Y a continuación, seleccione cualquier plataforma que desea desarrollar. Puede seleccionar todo (prepárate para una larga descarga) o puede seleccionar solamente la platfrom para tu teléfono. El Nexus One utiliza 2,1 y el Droid de Verizon utiliza 2.0.1.
  • Marque “Aceptar todo” y pulse “Instalar Aceptado”
  • Cuando haya terminado presione “Close”
  • Ahora vamos a crear un dispositivo virtual (AVD)
  • Seleccione “dispositivos virtuales” en el panel izquierdo
  • Seleccione “Nuevo …”
  • Cree el siguiente nuevo dispositivo virtual de Android
    • Nombre: Android2.1
    • Objetivo: Android 2.1 API Level 7 (o que nunca API ha instalado)
    • Tarjeta SD Tamaño: 4000 MiB para 32000MiB (16000 MiB muestra)
    • Deje el resto a la configuración predeterminada
  • Pulse el botón “Create AVD”. Ten paciencia puede tardar unos minutos para crear su nueva AVD.
  • Cierre la configuración de SDK.

Paso 5: Configurar Eclipse
(Estas instrucciones son para la versión de Eclipse Galileo. Consulta esta página para obtener instrucciones si ha descargado la versión de Eclipse Ganymede) 

  • Lanzamiento Eclipse por primera vez. Se le preguntará dónde desea a su carpeta de espacio de trabajo que se encuentra.
    • He utilizado la ubicación predeterminada.
    • Marque “Usar esto como el valor por defecto y no volver a preguntar” por lo que no tiene que responder a esta pregunta cada vez.
    • Pulse el botón “OK”.
  • Seleccione “Help> Install New Software …”
  • Pulse el botón “Agregar …”
  • Complete la información Agregar Sitio
    • Nombre: Android
    • Ubicación: https://dl-ssl.google.com/android/eclipse/
    • Pulse el botón “OK”

Si se produce un error no utilice SSL. cambiar la ubicación de “https://dl-ssl.google.com/android/eclipse/” a “http://dl-ssl.google.com/android/eclipse/”

  • Después de realizar una conexión y herramientas disponibles se recuperan ampliar “Herramientas de Desarrollo” y selecciona “Android DDMS” y “Herramientas de desarrollo de Android”
  • Pulse el botón “Siguiente”
  • Pulse el botón “Siguiente” de nuevo.
  • Seleccione “Acepto los términos del acuerdo de licencia”
  • Usted puede recibir una advertencia de seguridad sobre el contenido sin firmar. Pulse el botón “OK”
  • Listo. Ahora debe reiniciar Eclipse.
  • Después de reiniciar tenemos que decirle a Eclipse que copiamos el “SDK Android” en el paso 3.
  • Seleccione “Windows> Preferencias”
  • Seleccione “Android” en el panel izquierdo. Después de seleccionar “Android”, recibirá un error. Esto se debe a que no está configurado todavía. Estamos estableciendo que hasta ahora.
  • Para el SDK Location, vaya a donde ha instalado el SDK.
  • Pulse el botón “OK”
  • Aparecerá un cuadro de diálogo. Si desea enviar los datos de uso de Google dejarla marcada, otra desactivarlo y pulse el botón “Continuar”. Este cuadro de diálogo a veces puede quedar atrapado debajo de su ventana. Minimizar Eclipse si usted no lo ve.

!!Ahora está listo para crear su primera aplicación.!

Fuente  Greg Zimmer

Construccion de una app con Android que interactua con Netduino


Esta es una guía  paso a paso  planteada  a modo de completo tutorial, que le llevará a través de todo el proceso paso a paso. El autor Greg Zimmers   ha  incluido una aplicación Android de trabajo se puede utilizar “tal cual” o usarlo como punto de partida y mejorarlo.

 

 

Vamos a empezar. Abra Eclipse y empezar un proyecto nuevo. Si necesita ayuda para configurar el entorno de desarrollo, el autor también ha creado un detallado paso a paso guía. Aquí hay un enlace.

Cómo configurar el entorno de desarrollo de Android:

Crear un nuevo proyecto
Proyecto: Garage Door App
Construir objetivo: He orientado Android 2.3.1, pero creo que el código se ejecutaría tan bajo como 1.6. Así que si su teléfono no sea inferior v2.3.1 seleccionar la API apropiada
Nombre de la aplicación: App Garage Door
Nombre del paquete: com.acm.blog.example.garagedoorapp
Seleccione “Crear actividad:” y el nombre “MainActivity”
Min versión SDK: 9 (de nuevo si la orientación es menor API ajustar este número al nivel de la API correspondiente)
.

Se compone de tres controles:

  • Un botón de la puerta del garaje abierta.
  • Un botón de la puerta del garaje cercano.
  • Y por último, un indicador de estado que nos permitirá saber si la puerta está abierta o cerrada. También programé, así que cuando se toca la pantalla gráfica de la aplicación comprobará la puerta y actualizar el estado.

 


Paso 1: Crear el diseño mediante la edición del archivo main.xml ya creado para nosotros. Si Eres nuevo en Android el diseño puede ser un poco confuso. Aquí hay una explicación completa del archivo de diseño.

A partir de la línea 1 y terminando en la línea 19 es un “diseño lineal” que abarca todo el trazado. Se especifica que la orientación es vertical. Como los nuevos controles se añaden aparecen en la parte inferior. También establecemos el fondo de nuestro aluminio pulido gráfico.
Líneas 2-4 son un diseño lineal con un TextView para “Garage Door Opener”. Envolví el TextView en una disposición lineal, de modo que pude centro con android: Gravedad = “center_horizontal”
He utilizado un diseño de marcos en las líneas 5-12 para que yo pueda controles de capa en la parte superior de uno al otro. Yo quería que la barra de progreso para ser el punto muerto de nuestra condición gráfico.
Líneas 6-8 es nuestro gráfico de estado que se centra en la propiedad android: Gravedad = “center_horizontal”
Líneas 9-11 es la barra de progreso que mostramos al hacer nuestras llamadas de servicio web en un subproceso en segundo plano. También centrada.
Líneas 13-18 es una disposición lineal (fuera del marco de lo que aparece por debajo de ella). Esta disposición lineal se ajusta a apilar los controles horizontalmente con la siguiente propiedad android: orientation = “horizontal”. Tenemos dos botones de imagen en este diseño.

Main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<linearlayout android:background="@drawable/background" android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
  <linearlayout android:gravity="center_horizontal" android:layout_height="wrap_content" android:layout_width="fill_parent" android:orientation="horizontal">
   <textview android:id="@+id/textView1" android:layout_height="wrap_content" android:layout_width="wrap_content" android:paddingtop="4dip" android:text="Garage Door Opener" android:textcolor="#cc6600" android:textsize="20dip"></textview>
  </linearlayout>
  <framelayout android:gravity="center_horizontal" android:layout_height="wrap_content" android:layout_width="fill_parent" android:orientation="horizontal" android:paddingtop="35dip">
   <linearlayout android:gravity="center_horizontal" android:layout_height="wrap_content" android:layout_width="fill_parent" android:orientation="horizontal" android:paddingtop="35dip">
    <imageview android:gravity="center_horizontal" android:id="@+id/Status_ImageView" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/status_unknown"></imageview>
   </linearlayout>
   <linearlayout android:gravity="center_horizontal" android:layout_height="wrap_content" android:layout_width="fill_parent" android:orientation="horizontal" android:paddingtop="80dip">
    <progressbar android:id="@+id/progressBar1" android:layout_height="wrap_content" android:layout_width="wrap_content" android:visibility="invisible"></progressbar>
   </linearlayout>
  </framelayout>
  <linearlayout android:gravity="center_horizontal" android:layout_height="wrap_content" android:layout_width="fill_parent" android:orientation="horizontal" android:paddingtop="80dip">
    <imagebutton android:background="#00000000" android:contentdescription="info" android:id="@+id/OpenButton" android:layout_height="wrap_content" android:layout_width="wrap_content" android:paddingright="10dip" android:src="@drawable/open_button" android:tag="dooclosed">
     </imagebutton>
    <imagebutton android:background="#00000000" android:contentdescription="info" android:id="@+id/CloseButton" android:layout_height="wrap_content" android:layout_width="wrap_content" android:paddingright="10dip" android:src="@drawable/close_button">
     </imagebutton>
  </linearlayout>
</linearlayout>
 

 

Paso 2: Antes de que codificamos nuestra actividad vamos a crear una clase de ayuda para hacer las llamadas HTTP al Netduino.
Haga clic derecho sobre el nombre del proyecto y seleccione New> Class
El nombre de “WebService.java”. Ahora vamos a ir a través del código.
La línea 2 se hará una constante de cadena que contiene la dirección IP Netduino

1
2
3
4
public class WebService {
 private final String WEBSERVICE_URL = "http://192.168.0.153/";
  ...
  ...
  • La línea 3 declara una HttpClient vamos a utilizar para hacer las llamadas HTTP
1
2
3
4
public class WebService {
 private final String WEBSERVICE_URL = "http://192.168.0.153/";
 private HttpClient client;
 ...
  • Crear un constructor y en ella una instancia nuestra HttpClient
2
3
4
5
6
...
    public WebService(){
        client = new DefaultHttpClient();
    }
  ...
  • Crear un método privado que llama al servicio web y analiza le vuelta
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
private String MakeHTTPCall(String method){
  HttpGet get = new HttpGet(WEBSERVICE_URL + method);
  try {
   // Create a response handler
            ResponseHandler<string> responseHandler = new BasicResponseHandler();
            String responseBody = client.execute(get, responseHandler);
            return responseBody;
  } catch (IOException e) {       // -|
   e.printStackTrace();       // |--> Oops something went wrong!
  } catch (Exception e) {        // |
   e.printStackTrace();       // -|
  }
  return "failed";         //Return "failed" if we encounter an error
 }
</string>
  • Crear una nueva HTTP GET que pasa en la URL del servicio web y el nombre del método
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
private String MakeHTTPCall(String method){
  HttpGet get = new HttpGet(WEBSERVICE_URL + method);
  try {
   // Create a response handler
            ResponseHandler<string> responseHandler = new BasicResponseHandler();
            String responseBody = client.execute(get, responseHandler);
            return responseBody;
  } catch (IOException e) {       // -|
   e.printStackTrace();       // |--> Oops something went wrong!
  } catch (Exception e) {        // |
   e.printStackTrace();       // -|
  }
  return "failed";         //Return "failed" if we encounter an error
 }
</string>
  • Instantiate a new BasicResponseHandler to parse our webservice return into a string
  • Create a String variable to hold the return and call execute on the HttpClient
  • We pass in the HttpGet variable and the response handler
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
private String MakeHTTPCall(String method){
  HttpGet get = new HttpGet(WEBSERVICE_URL + method);
  try {
   // Create a response handler
            ResponseHandler<string> responseHandler = new BasicResponseHandler();
            String responseBody = client.execute(get, responseHandler);
            return responseBody;
  } catch (IOException e) {       // -|
   e.printStackTrace();       // |--> Oops something went wrong!
  } catch (Exception e) {        // |
   e.printStackTrace();       // -|
  }
  return "failed";         //Return "failed" if we encounter an error
 }
</string>
  • Devolver el resultado de la llamada HTTP GET. Nos envolvemos la llamada HTTP en tratar captura.
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
private String MakeHTTPCall(String method){
  HttpGet get = new HttpGet(WEBSERVICE_URL + method);
  try {
   // Create a response handler
            ResponseHandler<string> responseHandler = new BasicResponseHandler();
            String responseBody = client.execute(get, responseHandler);
            return responseBody;
  } catch (IOException e) {       // -|
   e.printStackTrace();       // |--> Oops something went wrong!
  } catch (Exception e) {        // |
   e.printStackTrace();       // -|
  }
  return "failed";         //Return "failed" if we encounter an error
 }
</string>
WebService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class WebService {
 private final String WEBSERVICE_URL = "http://192.168.0.153/";
 private HttpClient client;
    public WebService(){
        client = new DefaultHttpClient();
    }
    public String IsGarageDoorOpen(){
     for(int i = 0; i < 5; i++){
         String s = MakeHTTPCall("checkdoor");
      if(s.equals("failed") == false)
       return s; //Got a response return result
     }
     return "failed"//Oh well we tried 5 times without success
 }
 public String ActivateGarageDoor(){
  for(int i=0; i < 5; i++){
   String s = MakeHTTPCall("activatedoor");
      if(s.equals("failed") == false)
       return s; //Got a response return result
  }
  return "failed";
 }
 
 private String MakeHTTPCall(String method){
  HttpGet get = new HttpGet(WEBSERVICE_URL + method);
  try {
   // Create a response handler
            ResponseHandler<string> responseHandler = new BasicResponseHandler();
            String responseBody = client.execute(get, responseHandler);
            return responseBody;
  } catch (IOException e) {       // -|
   e.printStackTrace();       // |--> Oops something went wrong!
  } catch (Exception e) {        // |
   e.printStackTrace();       // -|
  }
  return "failed";         //Return "failed" if we encounter an error
 }
}
</string>

 

Paso 3: Vamos a editar nuestra actividad principal.
La línea 2 es nuestra barra de progreso le mostrará mientras comprobamos el estado de la puerta del garaje en un subproceso en segundo plano. Siempre es una buena idea para que el usuario sepa cuando la aplicación está funcionando en segundo plano.
La línea 3 es un ejemplo de nuestra ImageView vamos a utilizar para visualizar el estado de la puerta del garaje.
La línea 4 es una instancia de nuestra clase auxiliar de servicios web.

1
2
3
4
public class MainActivity extends Activity {
 private ProgressBar progressBar1;
 private ImageView status;
 private WebService ws;

Ahora vamos a añadir un poco de código al método onCreate

En la línea 9 pasamos de la barra de título de la ventana.
Línea 12 instanciar la barra de progreso.
Línea 13 del ImageView que estamos usando para visualizar el estado de la puerta del garaje.
Las líneas 14 a 19 establecen el on click oyente para que podamos comprobar el estado de la puerta del garaje cuando alguien toca la imagen de estado. Nos alguien hace clic en el ImageView ejecutamos un AsyncTask para comprobar la puerta del garaje en un subproceso en segundo plano.
Línea 20 instanciar nuestra ImageButton Abrir.
Las líneas 21 a 26 establecen el oyente haga clic en el botón Abrir. Cuando se hace clic en el botón de apertura activamos la puerta del garaje con una AsyncTask en un subproceso en segundo plano.
Líneas 27-33 es el mismo para el botón Cerrar.
Líneas 34-48 Creamos un Timer para comprobar el estado de la puerta del garaje cada quince minutos más en un subproceso en segundo plano.

@Override

 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
  setContentView(R.layout.main);
  ws = new WebService();
  progressBar1 = (ProgressBar) findViewById(R.id.progressBar1);
  status = (ImageView) findViewById(R.id.Status_ImageView);
  status.setOnClickListener(new OnClickListener() {     
     public void onClick(View v) {      // Check garage door
      new CheckGarageDoorAsync().execute();   // when status
                 // image clicked
     }
    });
  ImageButton openButton = (ImageButton) findViewById(R.id.OpenButton);
  openButton.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View arg0) {
    new ActivateGarageDoorAsync().execute();
   }
  });
  ImageButton closeButton = (ImageButton) findViewById(R.id.CloseButton);
  closeButton.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View arg0) {
    new ActivateGarageDoorAsync().execute();
   }
  });
  final Handler handler = new Handler();
  Timer t = new Timer();
  t.scheduleAtFixedRate(new TimerTask() {
   @Override
   public void run() {
    handler.post(new Runnable() {
     public void run() {
      Log.d("z", "check garage door");
      setUI(ws.IsGarageDoorOpen());
     }
    });
   }
  }, 0, 900000);
  new CheckGarageDoorAsync().execute();
 }
}

 líneas 56-92 es un método que establece nuestra interfaz de usuario en función del estado de la puerta del garaje. Si la puerta del garaje está abierta desactivamos el botón de apertura y ajuste la pantalla a “Abrir”, y por supuesto, si está cerrado el contrario.

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
private void setUI(String mode) {
  if (mode.equals("Open")) {
   ImageButton o = (ImageButton) findViewById(R.id.OpenButton);
   o.setImageResource(R.drawable.open_button_alt); // Open button
               // depressed
   o.setEnabled(false);        // Disable open button
   ImageButton c = (ImageButton) findViewById(R.id.CloseButton);
   c.setImageResource(R.drawable.close_button);  // Closed button up
   c.setEnabled(true);        // Enable close button
   ImageView status = (ImageView) findViewById(R.id.Status_ImageView);
   status.setImageResource(R.drawable.status_open); // Set status
                // graphic
  } else if (mode.equals("Closed")) {
   ImageButton o = (ImageButton) findViewById(R.id.OpenButton);
   o.setImageResource(R.drawable.open_button);  // Open button up
   o.setEnabled(true);        // Enable open button
   ImageButton c = (ImageButton) findViewById(R.id.CloseButton);
   c.setImageResource(R.drawable.close_button_alt); // Close button
                // depressed
   c.setEnabled(false);         // Disable close button
   ImageView status = (ImageView) findViewById(R.id.Status_ImageView);
   status.setImageResource(R.drawable.status_closed);// Set status
                 // graphic
  } else {
   ImageButton o = (ImageButton) findViewById(R.id.OpenButton);
   o.setImageResource(R.drawable.open_button_alt);  // Open button
                // depressed
   o.setEnabled(false);         // Disable open button
   ImageButton c = (ImageButton) findViewById(R.id.CloseButton);
   c.setImageResource(R.drawable.close_button_alt); // Close button
                // depressed
   c.setEnabled(false);         // Disable close button
   ImageView status = (ImageView) findViewById(R.id.Status_ImageView);
   status.setImageResource(R.drawable.status_unknown);// Set status
                  // graphic
  }
 }
private void setUI(String mode) {
  if (mode.equals("Open")) {
   ImageButton o = (ImageButton) findViewById(R.id.OpenButton);
   o.setImageResource(R.drawable.open_button_alt); // Open button
               // depressed
   o.setEnabled(false);        // Disable open button
   ImageButton c = (ImageButton) findViewById(R.id.CloseButton);
   c.setImageResource(R.drawable.close_button);  // Closed button up
   c.setEnabled(true);        // Enable close button
   ImageView status = (ImageView) findViewById(R.id.Status_ImageView);
   status.setImageResource(R.drawable.status_open); // Set status
                // graphic
  } else if (mode.equals("Closed")) {
   ImageButton o = (ImageButton) findViewById(R.id.OpenButton);
   o.setImageResource(R.drawable.open_button);  // Open button up
   o.setEnabled(true);        // Enable open button
   ImageButton c = (ImageButton) findViewById(R.id.CloseButton);
   c.setImageResource(R.drawable.close_button_alt); // Close button
                // depressed
   c.setEnabled(false);         // Disable close button
   ImageView status = (ImageView) findViewById(R.id.Status_ImageView);
   status.setImageResource(R.drawable.status_closed);// Set status
                 // graphic
  } else {
   ImageButton o = (ImageButton) findViewById(R.id.OpenButton);
   o.setImageResource(R.drawable.open_button_alt);  // Open button
                // depressed
   o.setEnabled(false);         // Disable open button
   ImageButton c = (ImageButton) findViewById(R.id.CloseButton);
   c.setImageResource(R.drawable.close_button_alt); // Close button
                // depressed
   c.setEnabled(false);         // Disable close button
   ImageView status = (ImageView) findViewById(R.id.Status_ImageView);
   status.setImageResource(R.drawable.status_unknown);// Set status
                  // graphic
  }
 }

 

Líneas 97-117 Creamos un AsyncTask para comprobar el estado de la puerta del garaje. El uso de un AsyncTask permite el hacer una llamada http en un subproceso en segundo plano por lo que nuestra aplicación no se convierta en un-sensible y geneate un error “ANR”. Si se realiza una tarea de largo en el hilo de interfaz de usuario y el usuario pulsa una tecla y no hay respuesta dentro de 5 segundos Android generará un mensaje de error ANR solicita al usuario que esperar o para cerrar. Nunca se debe realizar una llamada de red en el subproceso de interfaz de usuario. Ponemos en práctica tres métodos de la AsyncTask.

OnPreExecute (). Esto se realiza en el subproceso de interfaz de usuario. Nos dirigimos en la barra de progreso que indica que estamos comprobando la puerta.
doInBackground (). Esto se lleva a cabo en un subproceso de fondo. En este método, comprobamos el estado de la puerta del garaje llamando a nuestro método IsGarageOpen en nuestra clase de servicio web. A continuación, pasamos los resultados de OnPostExecute () método.
OnPostExecute (). Esto se realiza en el subproceso de interfaz de usuario. Este método establece los controles basados ​​en el estado de la puerta del garaje.

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
private class CheckGarageDoorAsync extends AsyncTask<void, string[]="" void,=""> {
  @Override
  protected void onPreExecute() {
   setUI("Unkown");            // While we check disable all buttons and clear status display
   progressBar1.setVisibility(View.VISIBLE); // Display progress bar
  }
 
  @Override
  protected String[] doInBackground(Void... arg0) {
   String r = ws.IsGarageDoorOpen();    // Make webservice call to check
              // garage door
   return new String[] { r };      // Return result
  }
 
  @Override
  protected void onPostExecute(String[] result) {
   progressBar1.setVisibility(View.INVISIBLE); // Hide progress bar
   setUI(result[0]);        // Pass result to setUI method to sync the UI
  }
 
 }
</void,>

 

Líneas 122-161 Creamos otra AsyncTask para activar la puerta del garaje. Aquí está la clase MainActivity completa.

MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
public class MainActivity extends Activity {
 private ProgressBar progressBar1;
 private ImageView status;
 private WebService ws;
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
  setContentView(R.layout.main);
  ws = new WebService();
  progressBar1 = (ProgressBar) findViewById(R.id.progressBar1);
  status = (ImageView) findViewById(R.id.Status_ImageView);
  status.setOnClickListener(new OnClickListener() {     
     public void onClick(View v) {      // Check garage door
      new CheckGarageDoorAsync().execute();   // when status
                 // image clicked
     }
    });
  ImageButton openButton = (ImageButton) findViewById(R.id.OpenButton);
  openButton.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View arg0) {
    new ActivateGarageDoorAsync().execute();
   }
  });
  ImageButton closeButton = (ImageButton) findViewById(R.id.CloseButton);
  closeButton.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View arg0) {
    new ActivateGarageDoorAsync().execute();
   }
  });
  final Handler handler = new Handler();
  Timer t = new Timer();
  t.scheduleAtFixedRate(new TimerTask() {
   @Override
   public void run() {
    handler.post(new Runnable() {
     public void run() {
      Log.d("z", "check garage door");
      setUI(ws.IsGarageDoorOpen());
     }
    });
   }
  }, 0, 900000);
  new CheckGarageDoorAsync().execute();
 }
 /*
  * Set UI components Garage Open Open button is disabled Close button is
  * enabled Status graphic - OPEN Garage Closed Open button is enabled Close
  * button is disabled Status graphic - Closed Garage Unknown Open button is
  * disabled Close button is disabled Status graphic - black
  */
 private void setUI(String mode) {
  if (mode.equals("Open")) {
   ImageButton o = (ImageButton) findViewById(R.id.OpenButton);
   o.setImageResource(R.drawable.open_button_alt); // Open button
               // depressed
   o.setEnabled(false);        // Disable open button
   ImageButton c = (ImageButton) findViewById(R.id.CloseButton);
   c.setImageResource(R.drawable.close_button);  // Closed button up
   c.setEnabled(true);        // Enable close button
   ImageView status = (ImageView) findViewById(R.id.Status_ImageView);
   status.setImageResource(R.drawable.status_open); // Set status
                // graphic
  } else if (mode.equals("Closed")) {
   ImageButton o = (ImageButton) findViewById(R.id.OpenButton);
   o.setImageResource(R.drawable.open_button);  // Open button up
   o.setEnabled(true);        // Enable open button
   ImageButton c = (ImageButton) findViewById(R.id.CloseButton);
   c.setImageResource(R.drawable.close_button_alt); // Close button
                // depressed
   c.setEnabled(false);         // Disable close button
   ImageView status = (ImageView) findViewById(R.id.Status_ImageView);
   status.setImageResource(R.drawable.status_closed);// Set status
                 // graphic
  } else {
   ImageButton o = (ImageButton) findViewById(R.id.OpenButton);
   o.setImageResource(R.drawable.open_button_alt);  // Open button
                // depressed
   o.setEnabled(false);         // Disable open button
   ImageButton c = (ImageButton) findViewById(R.id.CloseButton);
   c.setImageResource(R.drawable.close_button_alt); // Close button
                // depressed
   c.setEnabled(false);         // Disable close button
   ImageView status = (ImageView) findViewById(R.id.Status_ImageView);
   status.setImageResource(R.drawable.status_unknown);// Set status
                  // graphic
  }
 }
 /*
  * Check the garage door on background thread with an AsyncTask
  */
 private class CheckGarageDoorAsync extends AsyncTask<void, string[]="" void,=""> {
  @Override
  protected void onPreExecute() {
   setUI("Unkown");            // While we check disable all buttons and clear status display
   progressBar1.setVisibility(View.VISIBLE); // Display progress bar
  }
  @Override
  protected String[] doInBackground(Void... arg0) {
   String r = ws.IsGarageDoorOpen();    // Make webservice call to check
              // garage door
   return new String[] { r };      // Return result
  }
  @Override
  protected void onPostExecute(String[] result) {
   progressBar1.setVisibility(View.INVISIBLE); // Hide progress bar
   setUI(result[0]);        // Pass result to setUI method to sync the UI
  }
 }
 /*
  * Activate the garage door on a background thread with an AsyncTask
  */
 private class ActivateGarageDoorAsync extends
   AsyncTask<string, string,="" string[]=""> {
  @Override
  protected void onPreExecute() {
   setUI("Unkown");        // While we check disable all buttons and clear
              // display graphic
   progressBar1.setVisibility(View.VISIBLE); // Display progress bar
  }
  @Override
  protected String[] doInBackground(String... arg0) {
   String start = ws.IsGarageDoorOpen();
   String r = ws.ActivateGarageDoor();   // Activate garage door
   for (int i = 0; i < 60; i++) {     // Give the door up to 1 minute to
              // close/open
    try {
     Thread.sleep(1000);     // Pause for 1 second
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    r = ws.IsGarageDoorOpen();     // Check the door status
    if (r.equals(start) == false && r.equals("failed") == false)
     break;         // The door is done opening/closing
   }
   return new String[] { r };      // Return the status of garage
  }
  @Override
  protected void onProgressUpdate(String... values) {
  }
  @Override
  protected void onPostExecute(String[] result) {
   progressBar1.setVisibility(View.INVISIBLE);
   setUI(result[0]);
  }
 }
}
</string,></void,>

 

Usted puede obtener todo el código fuente del proyecto aquí

Para aprender a construir el hardware necesario para supervisar y controlar la puerta del garaje leer el posot del propio autort aquí.

Fuente Greg Zimmers

Sistema de alarma casera utilizando Netduino Plus (proyecto HomeAlarmPlus)


Se trata de un sistema de monitoreo de alarma simple con Netduino Plus y un panel de alarma típico. Esta aplicación podría ser usado en conjunción con los PC5010 Digital Security Controls (DSC) del panel de control del sistema de seguridad PowerSeries y sensores. Probado con. NET Micro Framework 4.2 (QFE1 y qfe2).

El objetivo de este proyecto es utilizar capacidades de Netduino Plus para controlar el sistema de alarma y reportar las actividades de cualquier detector del sensor de movimiento / por correo electrónico (utilizando protocolo simple de transferencia de correo (SMTP)), un servidor web local y Pachube (ahora Cosm).

Advertencia

Este código contiene información relacionada con un típico sistemas de alarma. Por favor, tenga en cuenta que este procedimiento puede anular la garantía. Cualquier sistema de alarma de cualquier tipo puede ser comprometido deliberadamente o puede fallar al operar como se espera por una variedad de razones.

El autor, Gilberto García, no se hace responsable de los fallos del sistema, tales como: instalación inadecuada, el conocimiento criminal, el acceso de intrusos, la falta de energía, falta de baterías reemplazables, el compromiso de Radio Frecuencia (Wireless) los dispositivos, los usuarios del sistema, detectores de humo, de movimiento detectores, dispositivos de alarma (sirenas, campanas, bocina), líneas telefónicas, falta de tiempo, falta de componentes, pruebas insuficientes, la seguridad y los seguros (propiedad o seguro de vida).

 Hardware
  • Tarjeta Micro SD
  • Adaptador de tarjeta SD
  • 3mm diodo emisor de luz (LED) verde por zona de alarma y detector de movimiento.
  • 330 ohmios para cada LED.
  • Resistencia 5600 ohmios por zona de alarma y detector de movimiento.
  • Schottky diodo por zona de alarma. Schottky diodo debe tener una baja caída de tensión como el SBR10U40CT.
  • Sparkfun ProtoScrewShield (sku: DEV-09729). Otros escudos que trabajarán son: Proto-Screwshield (Wingshield) kit de Adafruit o WingShield Industries.
  • Conexion WiFi  via WiFly Shield o  un adaptador WiFi .  Testado  con Netgear WNCE3001 , IOGEAR GWU627 y adap tadorMIFI de Telefónica.

OPcional

LED verde con soporte)

Conector Panel impermeable (RR-211300-30)

Cable USB 2.0 tipo A macho a un macho (10 pies o más). Se utiliza para acceder al Netduino Plus tabla en el panel de alarma.
200 Vatios / 350 VA UPS (APC System UPS BE350G o similar).
Botón de reset externo Empuje.
Arduino Proto Shield R3. Más espacio para los componentes adicionales. Mouser Electronics y otros.
LCD 16×2  3.3V para Netduino o 5V para Arduino.
Interruptor DPDT (o éste de Mouser Electronics) para la selección de voltaje LCD.

Circuito
El diagrama realizado con la herramienta Fritzing siguiente muestra cómo el Netduino plus, LEDs y las zonas de alarma (o detector de movimiento) están conectados. LCD circuitos de referencia de Szymon Kobalczy.

HomeAlarmPlus connection diagram (basic circuit) Rev-
HomeAlarmPlus connection diagram (basic circuit) RevA
HomeAlarmPlus connection diagram (enhanced circuit) RevG
Zone/Sensor connection

Tenga en cuenta que una o más zonas consisten en lo siguiente:
a) 1 contacto normalmente abierto y 1 contacto NC con fin de línea (EOL) resistencia.
b) Doble circuito de EOL, 1 Contacto normalmente cerrado con 5.6kohm EOL resistencia y diodo Schottky. Esto hará que la protección necesaria para la Netduino o Arduino.
c) Cada zona de tierra debe ser conectado a la ProtoScrewShield GND.
Netduino / ProtoScrewShield Pin
descripción
A0 Zona # 1
Zona A1 # 2
A2 Zona # 3
A3 Zona # 4
Sensor A4 # 1 [Detector de movimiento]
Zona de LED D2 # 1
D3 Zona LED # 2
D4 Zone LED # 3
D5 LED Zona # 4
D6 o D7 Sensor LED # 1 [Detector de movimiento]

AlarmCircuit_schem

Opciones Web Server

 

 

Opciones
descripción
Page / Root
/ open Abrir último archivo en la tarjeta SD.
/ files Lista sdcard en la tarjeta SD.
/ su superusuario. Muestra opciones adicionales.
/ Pachube muestra la actividad Pachube por zona / Datastream.
/ sobre los créditos de aplicación y versión.
/ delete-confirmar ¿Eliminar último archivo en la tarjeta SD [Ventana de confirmación].
/ delete-última Borrar el último archivo en la tarjeta SD [ninguna ventana de confirmación].
/ diagnóstico por ahora, muestra la memoria disponible en Netduino y las fuerzas para despejar el recolector de basura.
Código
Archivo config.ini debe copiarse en el directorio raíz de la tarjeta SD. La finalidad de este fichero es la de personalizar los parámetros en la tarjeta SD y evitar una mínima modificación del código fuente. Archivos CSS (header_style.css y table_style.css) deben ubicarse en WebResources carpeta.

 

microSD directory structure

Config.ini content:

01 ;AlarmByZones - Programmed for Netduino by Gilberto García - 5/9/2012 
02 ;Feel free to customize this file with your own definitions. 
03 ;[NETDUINO_PLUS_HTTP_PORT] HTTP server port. 
04 ;[ALARM_ZONES] should match with ACTIVE_ZONES constant defined in AlarmByZones.cs and Definitions.cs . 
05 ;[SENSORS] should match with MOTION_SENSORS constant defined in AlarmByZones.cs and Definitions.cs . 
06 ;[USE_EMAIL] Activate/Deactivate email option. Y or N arguments expected. 
07 ;[EMAIL_FREQ] Email frequency in minutes when the alarm/sensor is active.  
08 ;       This will define EMAIL_FREQUENCY in ConfigDefault.cs . 
09 ;[STORE_LOG] Saves alarm/sensor log. Y or N arguments expected. 
10 ;[STORE_EXCEPTION] Saves Netduino exceptions. Y or N arguments expected. 
11 ;[USE_PACHUBE] Activate/Deactivate Pachube option. Y or N arguments expected. 
12
13
14
15 [NETDUINO_PLUS_HTTP_PORT] 
16 8080 
17 [ALARM_ZONES] 
18 Zone1=FIRST FLOOR - Living room windows, Dining room windows, Porch (sliding doors), Garage door access. 
19 Zone2=SECOND FLOOR - Master Bedroom and Bathroom Windows. 
20 Zone3=FIRST FLOOR - Master Bedroom windows. 
21 Zone4=SECOND FLOOR - Bedroom 2 and bathroom windows. 
22 [SENSORS] 
23 Sensor1=Main door access 
24 [USE_EMAIL] 
25
26 [EMAIL_FREQ] 
27 10 
28 [STORE_LOG] 
29
30 [STORE_EXCEPTION] 
31
32 [USE_PACHUBE] 
33

 

Architecture of AlarmByZones (main)

Declaration

01 /// <summary> 
02  /// Alarm zones (Analog Input) 
03  /// </summary> 
04  static SecretLabs.NETMF.Hardware.AnalogInput[] Zones = newSecretLabs.NETMF.Hardware.AnalogInput[Alarm.User_Definitions.Constants.ACTIVE_ZONES]; 
05  /// <summary> 
06  /// Alarm zones LEDs (Digital Output) 
07  /// </summary> 
08  static Microsoft.SPOT.Hardware.OutputPort[] AlarmLeds = newMicrosoft.SPOT.Hardware.OutputPort[Alarm.User_Definitions.Constants.ACTIVE_ZONES]; 
09  /// <summary> 
10  /// Motion detector sensors (Analog Input) 
11  /// </summary> 
12  static SecretLabs.NETMF.Hardware.AnalogInput[] Sensors = newSecretLabs.NETMF.Hardware.AnalogInput[Alarm.User_Definitions.Constants.MOTION_SENSORS]; 
13  /// <summary> 
14  /// Motion detector LEDs (Digital Output) 
15  /// </summary> 
16  static Microsoft.SPOT.Hardware.OutputPort[] MotionLeds = newMicrosoft.SPOT.Hardware.OutputPort[Alarm.User_Definitions.Constants.MOTION_SENSORS]; 
17  /// <summary> 
18  /// Gets the total elapsed time measured by the current instance of each alarm zone. 
19  /// </summary> 
20  static System.Diagnostics.Stopwatch[] stopwatchZones = newStopwatch[Alarm.User_Definitions.Constants.ACTIVE_ZONES]; 
21  /// <summary> 
22  /// Gets the total elapsed time measured by the current instance of each motion detector sensor. 
23  /// </summary> 
24  static System.Diagnostics.Stopwatch[] stopwatchSensors = newStopwatch[Alarm.User_Definitions.Constants.MOTION_SENSORS]; 
25  /// <summary> 
26  /// Flag for detected zones when trigger. 
27  /// </summary> 
28  static bool[] detectedZones = newbool[Alarm.User_Definitions.Constants.ACTIVE_ZONES]; 
29  /// <summary> 
30  /// Flag for detected sensors when is trigger. 
31  /// </summary> 
32  static bool[] detectedSensors = newbool[Alarm.User_Definitions.Constants.MOTION_SENSORS]; 
33  /// <summary> 
34  /// Email 
35  /// </summary>    
36  /// <example> SMTPClient.Email("mail.gmx.com", 587, "[email protected]", "[email protected]", "user password");  
37  /// </example> 
38  static SMTPClient.Email email = newSMTPClient.Email(Alarm.UserData.Email.host, Alarm.UserData.Email.port, 
39    Alarm.UserData.Email.From, Alarm.UserData.Email.To, Alarm.UserData.Email.smtpPassword); 
40  /// <summary> 
41  /// SD Card Event Logger 
42  /// </summary> 
43  public static EventLogger SdCardEventLogger = newEventLogger(); 

Delegates 

1 /// <summary> 
2 /// Monitor zones delegate 
3 /// </summary> 
4 public delegate void MonitorZonesDelegate(); 
5 /// <summary> 
6 /// Monitor motion sensor delegate 
7 /// </summary> 
8 public delegate void MonitorMotionSensorDelegate(); 

Main 

01 public static void Main() 
02
03   Zones[0] = newSecretLabs.NETMF.Hardware.AnalogInput(SecretLabs.NETMF.Hardware.NetduinoPlus.Pins.GPIO_PIN_A0); 
04   Zones[1] = newSecretLabs.NETMF.Hardware.AnalogInput(SecretLabs.NETMF.Hardware.NetduinoPlus.Pins.GPIO_PIN_A1); 
05   Zones[2] = newSecretLabs.NETMF.Hardware.AnalogInput(SecretLabs.NETMF.Hardware.NetduinoPlus.Pins.GPIO_PIN_A2); 
06   Zones[3] = newSecretLabs.NETMF.Hardware.AnalogInput(SecretLabs.NETMF.Hardware.NetduinoPlus.Pins.GPIO_PIN_A3); 
07   AlarmLeds[0] = newMicrosoft.SPOT.Hardware.OutputPort(Pins.GPIO_PIN_D2,false);       
08   AlarmLeds[1] = newMicrosoft.SPOT.Hardware.OutputPort(Pins.GPIO_PIN_D3, false); 
09   AlarmLeds[2] = newMicrosoft.SPOT.Hardware.OutputPort(Pins.GPIO_PIN_D4, false); 
10   AlarmLeds[3] = newMicrosoft.SPOT.Hardware.OutputPort(Pins.GPIO_PIN_D5, false); 
11   Sensors[0] = newSecretLabs.NETMF.Hardware.AnalogInput(SecretLabs.NETMF.Hardware.NetduinoPlus.Pins.GPIO_PIN_A4); 
12   MotionLeds[0] = newMicrosoft.SPOT.Hardware.OutputPort(Pins.GPIO_PIN_D7, false); 
13   MonitorZonesDelegate monitorZones = newMonitorZonesDelegate(MonitorZones); 
14   MonitorMotionSensorDelegate monitorMotion = newMonitorMotionSensorDelegate(MonitorSensors); 
15   //based on a post by Valkyrie-MT 
17   Console.DEBUG_ACTIVITY("Setting NTP-time"); 
18   SetTime(); 
19   SdCardEventLogger.parseConfigFileContents(Alarm.User_Definitions.Constants.ALARM_CONFIG_FILE_PATH); 
20   InitArrays(); 
21   Console.DEBUG_ACTIVITY(Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0].IPAddress); 
22   SdCardEventLogger.SDCardAccess(); 
23   new Thread(Alarm.ProtoScrewShield_LED.Blink).Start();       
24   new Thread(Alarm.WebServer.startHttp).Start(); 
25   if (Alarm.ConfigDefault.Data.USE_PACHUBE) 
26   
27     Pachube.PachubeLibrary.InitPachubleLibrary(SdCardEventLogger.IsSDCardAvailable(), Alarm.ConfigDefault.Data.STORE_EXCEPTION); 
28     new Thread(Pachube.PachubeLibrary.PachubeConnect).Start(); 
29   
30   while (true
31   
32     Debug.Print("Memory available: " + Debug.GC(true)); 
33     monitorZones(); 
34     monitorMotion(); 
35     Thread.Sleep(Alarm.Common.Alarm_Constants.ALARM_DELAY_TIME); 
36   
37

Main Methods 

001 /// <summary> 
002 /// Loops thru each alarm zone 
003 /// </summary> 
004 static void MonitorZones() 
005
006   for (int i = 0; i < Zones.Length; i++) 
007   
008     int vInput = Zones[i].Read(); 
009     float volts = ((float)vInput / 1024.0f) * 3.3f; 
010     string strZoneDescription = "N/A"//If zone description is not found on SD Card N/A is default description. 
011     Console.DEBUG_ACTIVITY("Zone " + (i + 1).ToString() + ": Volts: " + volts); 
012     //format:                //Zone number, voltage 
013     Pachube.PachubeLibrary.statusToPachube = i == 0 ? (i + 1).ToString() + "," + volts : (i + 1).ToString() + "," + volts +"\r\n" + Pachube.PachubeLibrary.statusToPachube; 
014     AlarmLeds[i].Write(volts >= 3); 
015     //elapsed seconds 
016     double eSeconds = stopwatchZones[i].ElapsedSeconds; 
017     //elapsed minutes 
018     double eMinutes = stopwatchZones[i].ElapsedMinutes; 
019     Console.DEBUG_ACTIVITY("stopwatch[" + i.ToString() + "] = " + eSeconds.ToString() + " seconds"); 
020     Console.DEBUG_ACTIVITY("stopwatch[" + i.ToString() + "] = " + eMinutes.ToString() + " minutes\n"); 
021     if (volts >= 3 ) 
022     
023       /* 
024        Case #1: 
025         !detectedZones[i] = not triggered before. This is the first time in this cycle and first email to send. 
026        Case #2: 
027         detectedZones[i] && eMinutes >= EMAIL_FREQUENCY = triggered before and time is up for sending another email.            
028        */
029       if (!detectedZones[i] || (detectedZones[i] && eMinutes >= Alarm.ConfigDefault.Data.EMAIL_FREQUENCY)) 
030       
031         if (Alarm.Common.Alarm_Info.zoneDescription.Count>0) 
032         
033           if(Alarm.Common.Alarm_Info.zoneDescription.Contains("Zone" + (i + 1).ToString())) 
034           
035             strZoneDescription = (string)Alarm.Common.Alarm_Info.zoneDescription["Zone" + (i + 1).ToString()]; 
036           
037         
038         string info = "Zone " + (i + 1).ToString() + " " + strZoneDescription; 
039         stopwatchZones[i] = Stopwatch.StartNew(); 
040         detectedZones[i] = true
041         email.SendEmail("Alarm Trigger!", info); 
042         Alarm.Common.Alarm_Info.sbActivity.AppendLine("<tr>");
043         Alarm.Common.Alarm_Info.sbActivity.AppendLine("<td><center>" + DateTime.Now.ToString() + "</center></td> ");
044         Alarm.Common.Alarm_Info.sbActivity.AppendLine("<td><center> Zone " + (i + 1).ToString() + "</center></td>");
045         Alarm.Common.Alarm_Info.sbActivity.AppendLine("<td><center>" + strZoneDescription + "</center></td>");
046         Alarm.Common.Alarm_Info.sbActivity.AppendLine("</tr>");             if (Alarm.ConfigDefault.Data.USE_PACHUBE) 
047         
048           //supress timer and update Pachube with new status 
049           Pachube.PachubeLibrary.forceUpdate = true
050         
051         if (SdCardEventLogger.IsSDCardAvailable() && Alarm.ConfigDefault.Data.STORE_LOG) 
052         
053           SdCardEventLogger.saveFile(DateTime.Now.ToString("d_MMM_yyyy--HH_mm_ss") + ".log", info, "Log"); 
054         
055       
056     
057     else
058     
059       detectedZones[i] = false
060     
061   
062
063 /// <summary> 
064 /// Loops thru each sensor 
065 /// </summary> 
066 static void MonitorSensors() 
067 {   
068   for (int i = 0; i < Sensors.Length; i++) 
069   
070     int vInput = Sensors[i].Read(); 
071     float volts = ((float)vInput / 1024.0f) * 3.3f; 
072     string strSensorDescription = "N/A"//If sensor description is not found on SD Card N/A is default description. 
073     Console.DEBUG_ACTIVITY("Sensor " + (i + 1).ToString() + ": Volts: " + volts); 
074     MotionLeds[i].Write(volts >= 3); 
075     double eSeconds = stopwatchSensors[i].ElapsedSeconds; 
076     double eMinutes = stopwatchSensors[i].ElapsedMinutes; 
077     Console.DEBUG_ACTIVITY("stopwatch[" + i.ToString() + "] = " + eSeconds.ToString() + " seconds"); 
078     Console.DEBUG_ACTIVITY("stopwatch[" + i.ToString() + "] = " + eMinutes.ToString() + " minutes\n"); 
079     if (volts >= 3) 
080     
081       /* 
082        Case #1: 
083         !detectedZones[i] = not triggered before. This is the first time in this cycle and first email to send. 
084        Case #2: 
085         detectedZones[i] && eMinutes >= EMAIL_FREQUENCY = triggered before and time is up for sending another email.            
086        */
087       if (!detectedSensors[i] || (detectedSensors[i] && eMinutes >= Alarm.ConfigDefault.Data.EMAIL_FREQUENCY)) 
088       
089         if (Alarm.Common.Alarm_Info.sensorDescription.Count > 0) 
090         
091           if(Alarm.Common.Alarm_Info.sensorDescription.Contains("Sensor" + (i + 1).ToString())) 
092           
093             strSensorDescription = (string)Alarm.Common.Alarm_Info.sensorDescription["Sensor" + (i + 1).ToString()]; 
094           
095         
096         string info = "Sensor " + (i + 1).ToString() + " " + strSensorDescription; 
097         stopwatchSensors[i] = Stopwatch.StartNew(); 
098         detectedSensors[i] = true
099         email.SendEmail("Alarm Trigger!", info); 
100         Alarm.Common.Alarm_Info.sbActivity.AppendLine("<tr>");
101         Alarm.Common.Alarm_Info.sbActivity.AppendLine("<td><center>" + DateTime.Now.ToString() + "</center></td> ");
102         Alarm.Common.Alarm_Info.sbActivity.AppendLine("<td><center> Sensor " + (i + 1).ToString() + "</center></td>");
103         Alarm.Common.Alarm_Info.sbActivity.AppendLine("<td><center>" + strSensorDescription + "</center></td>");
104         Alarm.Common.Alarm_Info.sbActivity.AppendLine("</tr>"); 
105         if (Alarm.ConfigDefault.Data.USE_PACHUBE) 
106         
107           //supress timer and update Pachube with new status 
108           Pachube.PachubeLibrary.forceUpdate = true
109         
110         if (SdCardEventLogger.IsSDCardAvailable() && Alarm.ConfigDefault.Data.STORE_LOG) 
111         
112           SdCardEventLogger.saveFile(DateTime.Now.ToString("d_MMM_yyyy--HH_mm_ss") + ".log", info, "Log"); 
113         
114       
115     
116     else
117     
118       detectedSensors[i] = false
119     
120   
121
122 /// <summary> 
123 /// Synchronize Netduino time with NTP Server 
124 /// </summary> 
125 public static void SetTime() 
126
128   Extension.SetFromNetwork(DateTime.Now, new TimeSpan(-5, 0, 0)); 
129
130 /// <summary> 
131 /// Initializes stopwatch and alarms/sensors arrays 
132 /// </summary> 
133 private static void InitArrays() 
134
135   for (int i = 0; i < Alarm.User_Definitions.Constants.ACTIVE_ZONES; i++) 
136   
137     stopwatchZones[i] = Stopwatch.StartNew(); 
138     detectedZones[i] = false
139   
140   for (int i = 0; i < Alarm.User_Definitions.Constants.MOTION_SENSORS; i++) 
141   
142     stopwatchSensors[i] = Stopwatch.StartNew(); 
143     detectedSensors[i] = false
144   
145

 

Cosm, formerly Pachube, Alarm Console

Final Product

LCD and WiFi Internet Adapter
Alarm Panel with Netduino Plus, LCD and WiFi Internet Adapter

 

Comentarios comunidad Netduino

http://forums.netduino.com/index.php?/topic/4202-home-alarm-system-using-netduino-plus-homealarmplus-project/

Repositorio código fuente
https://github.com/ferraripr/HomeAlarmPlus

Video

YouTube video

Fuente Gilberto García

Netduino 2 Firmware v4.3.0 (beta 1)


Versión: 4.3.0 Beta 1 (versión 4.3.0.0 beta 1) 

Este firmware requiere el uso del . NET Micro Framework SDK v4.3 y Netduino 4.3.0.0 SDK . 

Con este firmware, tendrá los siguientes recursos disponibles para el código: 
192KB flash 
60KB RAM 

Este firmware incluye las siguientes actualizaciones: 
1. . NET MF qfe2 4.2 y 4.3 correcciones de errores 

Este firmware no incluye: 
1. SecretLabs.NETMF.Hardware.Diagnostics.dll. Esto se añadirá en la próxima versión. 

Este firmware también incluye las actualizaciones anteriores: 
1. Corrección de error: Configuración SPI reloj de ralentí elevada Ahora apoyado 
2. Ahora compatible con el legado SecretLabs AnalogInput y clases de PWM 
3. Corrección de errores: SPI selección de chip momento corregida 
4. Corrección de errores: PWM de frecuencia corregida 
5. Nuevo: más fiable reiniciar durante la implementación 
6. Adicional de corrección de errores I2C – pines ve obligado a la configuración adecuada 

Para encontrar la versión actual del firmware Netduino: 
1. Ir al menú Inicio> Programas> Microsoft. NET Micro Framework 4.3> MFDeploy 
3. Conecte su Netduino a su PC usando un cable Micro USB. 
4. En la sección de dispositivos en la parte superior, seleccione USB en vez de serie. Su Netduino debe aparecer en la lista desplegable, si no, seleccionarlo. 
5. Seleccione el menú Destino, opción de funciones de dispositivos. 
6. En la casilla de salida, encontrar el valor de “SolutionReleaseInfo.solutionVersion”. Esta es la versión del firmware. 

Para actualizar el firmware: 
1. Separe su Netduino 
2. Pulse y mantenga pulsado botón de su Netduino mientras que enchufarlo vía USB, lo que lo pondrá en modo bootloader. 
3. Borrar el firmware de su Netduino utilizando el Tester STDFU v3.0.1 aplicación 
> A. Seleccione la pestaña “Protocolo” 
> B. Pulse el botón “Crear desde Map” 
> C. Seleccione el botón de opción “Borrar” 
> D. Pulse el botón “Go” 
> E. Espere a que el proceso de borrado para completar 
4. Flash en el archivo adjunto. DFU con el Demostrador DfuSe v3.0.2 ST aplicación (incluido con STDFU Tester) 
> A. Localice el panel “Actualizar o Verificar Acción” (panel inferior derecho) 
> B. Pulse el botón “Elegir …” y seleccione el archivo adjunto DFU 
> C. Marque la opción “Verificar después de la descarga” 
> D. Pulse el botón “Actualizar”. Tomará unos minutos para actualizar su Netduino. 
> E. Desconecte y vuelva a conectar el Netduino (apagar y encender) o pulse “Agregar el modo DFU” 

Fuente:Chris Walker

 Licencia Creative Commons
solo-electronicos por Carlos Rodriguez Navarro se encuentra bajo una Licencia Creative Commons Atribución-NoComercial-CompartirIgual 3.0 Unported.

Implementar un watch-dog con Netduino


¿Qué pasa si usted crea su propia aplicación Netduino, y un error lo  detiene de forma inesperada?
Primera respuesta: no hay problema, estoy en frente del depurador, y voy a tener el seguimiento de la pila completa de la excepción.
Segunda respuesta: es una pesadilla! Estoy en vacaciones de fin de semana, y mi sistema de rociadores basado en  Netduino se ha colgado de modo que tengo que pedirle  a mi vecino que resetee mi Netduino

Obviamente estamos interesados ​​en la segunda respuesta, o-mejor-la forma de evitar, como situación.

Cuando el hardware está dañado o el software está libre de errores, no hay muchas maneras de rescatar el control de la placa. Sin embargo, hay muchas, muchas situaciones donde nuestra placa funciona perfectamente (tal vez por semana) sin ningún problema en absoluto y tn pronto se mueve “en el lugar”, el primer problema que ocurre…
Dado que ninguno de utilización gustaría ser despertar a las 3 am para una parada del sistema, u obligarnos a volver a casa porque el rociador basado con Netduino no funciona correctamente, entonces podríamos hacer cumplir la fiabilidad mediante la adición de un así llamado “perro guardián”.
Es una forma muy sencilla de proteger el sistema de paradas no deseadas y  nos resuelve toda esta problematica pues  una buena práctica de programación, junto con un buen hardware, es el deber-tiene redundancia para la mayoría de la fiabilidad de cualquier sistema.

WatchDog externo

No sé quién inventó este nombre WatchDog … “perro guardián” … pero suena claro (al menos para mí) que hay dos temas diferentes:
  • el perro, que es el controlador;
  • la casa está vigilada por el perro.
Ahora, el sistema que falla potencial es la casa, y el perro vive respeto “externa” de la casa.
Eso es obvio, ya que si el sistema se bloquea se podría hacer la misma en el rescate?
Es tan obvio, que muchas personas están pidiendo una solución de software pura, tal vez usando un hilo separado como un controlador.
Hay taaaan muchas situaciones que pueden obtener un MCU para colgar, que llevarían a alguien de inmediato a una solución externa.
Algunos ejemplos:
  • sub o sobre-temperatura;
  • picos de tensión (tanto por encima de la oferta y por debajo del suelo);
  • fuerte ruido en general (especialmente cuando los cables largos están conectados directamente a los pernos de MCU);
  • errores de software;
  • la inestabilidad de hardware (por ejemplo, el cristal se detiene oscilante);
  • muchos otros.
Podría haber usado un chip personalizado para un perro guardián. El chip Atmel del Netduino incrusta un perro guardián, pero no ha sido impulsado por el firmware.
En su lugar, me gustaría mostrar un circuito muy simple diseñado por Mario Vernari , cuyo objetivo es principalmente intentar resolver este problema en particular.

Usaremos un simple contador: el 74HC4060 . Es un contador binario de 14 etapas, que incrusta también un oscilador RC básica. Todo esto para obtener una re-activable, de largo periodo del temporizador.
La palabra “timer” llama inmediatamente en mi mente la increíble ” 555 “chip: una obra maestra en el diseño del hardware de los ’70. BTW, tenemos un tiempo de reacción relativamente largo: al menos varios segundos.Eso es porque el Netduino tarda un par de segundos para completar el proceso de restablecimiento completo, entonces debemos tener en cuenta la lentitud del programa. Un organismo de control normales reacciona en milésimas de segundo, mientras que aquí estamos considerando docena de segundos, tal vez más. Durante un largo tiempo como el 555-temporizador normal no es confiable, porque se basa en la carga de los condensadores. Además, necesitaríamos un gran condensador bonita.
El 74HC4060 es mucho más simple para tiempos largos. Me desconecté el oscilador de frecuencia de alrededor de 60 Hz, que es el uso de:
  • Rt = 2.7k
  • Ct = 100n
Nota: consulte las 74HC4060 especificaciones.
Entonces, opté por la salida de la 10 ª etapa (es decir, Q9) como “tiempo de espera de señal”, que desencadena el reinicio Netduino después de unos 10 segundos. Ahora, diez etapas binarias producen una división de frecuencia de 1024 (= 2 ^ 10), ¿por qué 60 Hz dividido por 1024 no cede 10 segundos, pero 20?
Debido a que el reinicio ocurre tan pronto la salida Q9 resulta alta, que es después de sólo la mitad del tiempo total.

Así que, ¿cuál es el papel de la Netduino, tener miedo de poner a cero desde el 74HC4060?
Bueno, sí … el programa se ejecuta en el Netduino debe “refrescar” constantemente el contador, por lo que no será nunca llegar al Q9 alta. Básicamente tenemos que cualquiera de las salidas Netduino generando un impulso positivo a corto, que tiene que reiniciar el contador. Hasta la aplicación Netduino está funcionando correctamente, el pulso se mantendrá el contador en un valor relativamente bajo, y Q9 nunca le des alta. Por cierto, cuando el programa se cuelga, no hay generación de impulsos más reset, y el contador se puede ejecutar para alcanzar el Q9 alta. Esa señal se restablecerá la Netduino.

Un programa de prueba simple.

El programa siguiente se utiliza como una prueba para el organismo de control.
Esto hace que el LED intermitente durante un período determinado, a continuación, genera una excepción. Eso es un “bug” simulado, que en realidad cuelga todo el tablero. Bajo tales circunstancias, usted tiene sólo dos opciones: pulsar el botón “reset”, o desconecte y conecte la alimentación nuevamente. Dado que ninguno de ellos es adecuado funcionamiento para un contexto remoto, nos introducimos un poco de “ayuda”, que “presione el botón de reinicio para nosotros”.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
namespace NetduinoWatchdog
{
    public class Program
    {
        public static void Main()
        {
            //define the led port
            var led = new OutputPort(Pins.ONBOARD_LED, false);
            //just a long loop to make the led blinking
            for (int i = 0; i < 1000; i++)
            {
                //call the critical section
                Freezer(i);
                //wait for a while, then toggle the led status
                Thread.Sleep(100);
                led.Write(
                    !led.Read()
                    );
            }
        }
        static void Freezer(int count)
        {
            //this is just to simulate an unexpected event
            if (count == 20)
                throw new Exception();
            //keep the dog awaken
            Watchdog();
        }
        //define the watchdog port
        static OutputPort wdt = new OutputPort(Pins.GPIO_PIN_A5, false);
        static void Watchdog()
        {
            //generate a positive pulse to reset the external counter
            wdt.Write(true);
            wdt.Write(false);
        }
    }
}

Esta claro que el código, se centra principalmente el circuito externo mediante el 74HC4060 por lo que una fuente similar colgará cada vez que se inice este programa por lo que no tiene sentido en un contexto real. Una aplicación más realista debería ser mucho más “a prueba de excepción-libre”, y tal vez ser capaz de “corregirse” en un cierto fracaso. Por ejemplo, considere la posibilidad de su aplicación está escribiendo un archivo en la tarjeta SD, pero el usuario saque la tarjeta. Es un poco difícil de escribir un procedimiento a prueba de balas que escribe los datos sin ninguna excepción. Sin embargo, una vez que el Netduino se ha restablecido, puede analizar la presencia en SD, y evitar cualquier operación relacionada

Fuente  Mario Vernari

Licencia Creative Commons
solo-electronicos por Carlos Rodriguez Navarro se encuentra bajo una Licencia Creative Commons Atribución-NoComercial-CompartirIgual 3.0 Unported.

Presentaciones remotas con PowerPoint


La característica Difundir presentación de diapositivas en PowerPoint 2010 permite a los presentadores compartir una presentación con cualquier persona, en cualquier lugar, mediante la Web mejorando la calidad   gráfica de la presentación  respecto  a otros sistemas 
Basicamente   se  envía un vínculo (dirección URL) a la audiencia por correo electrónico  y todos los invitados pueden ver de forma simultánea la presentación en el explorador.
Durante la difusión, se puede pausar la presentación , reenviar la dirección URL a los asistentes o cambiar a otra aplicación sin interrumpir la difusión ni mostrarles su escritorio a los asistentes.
Tipos de difusion 
 La característica Difundir presentación de diapositivas requiere un servicio de red que hospede la presentación. Puede elegir entre dos servicios:

  • Servicio de difusión de PowerPoint. Este servicio está disponible para cualquier persona con una identificación de Windows Live y es una buena solución para ofrecer la presentación a una audiencia que está fuera de la organización. Cualquier persona en Internet podrá obtener acceso a la dirección URL para una presentación hospedada en este servicio.
  • Un servicio de difusión proporcionado por su organización, hospedado en un servidor con las aplicaciones web de Microsoft® Office instaladas. Para usar este servicio, el administrador del sitio debe configurar un sitio de difusión y los miembros de la audiencia deben tener acceso a ese sitio.

Preparacion
Éstas son algunas cuestiones para tener en cuenta antes de difundir la presentación:
  • Conexión a Internet     Para poder usar esta característica, debe estar conectado a Internet o tener acceso a un sitio de difusión en un servidor con las aplicaciones web de Office instaladas.
  • Exploradores admitidos     La característica de difusión de presentaciones se puede ver en Internet Explorer, Firefox y Safari para exploradores Mac.
  • Límites de tamaño de archivos     Es posible que el servicio que utiliza imponga un límite para el tamaño de archivos para las presentaciones difundidas.
  • Características admitidas de PowerPoint     Cuando se difunde la presentación en línea, se modifican algunas características de PowerPoint:
  • Cualquier transición en la presentación se muestra como transición con efecto Desvanecer en el explorador.
  • Los protectores de pantalla y los correos electrónicos emergentes pueden ocasionar molestias a la audiencia que está viendo la presentación con diapositivas.
  • El audio (sonidos, narración) no se transmite a la audiencia mediante el explorador.
  • No pueden agregar anotaciones manuscritas ni marcas en la presentación durante su difusión.
  • Si sigue un hipervínculo a un sitio web desde la presentación, los asistentes solo pueden ver la última diapositiva que se mostró en la presentación original.
  • Si reproduce un vídeo en la presentación, el explorador no se lo muestra a la audiencia.
  • PRIVACIDAD:   Atención  culalquier persona que tenga el vínculo a la presentación puede verla. Si un miembro invitado de la audiencia reenvía el vínculo a otra persona, esa otra persona también puede ver la presentación, siempre y cuando tenga acceso al servicio.
  • Difundir una presentación

    Para difundir una presentación, siga este procedimiento:
    1. En la ficha Presentación con diapositivas en el grupo Iniciar presentación con diapositivas, haga clic en Difundir presentación de diapositivas.
    Difundir presentación de diapositivas en el grupo Iniciar presentación con diapositivas de la ficha Presentación con diapositivas en PowerPoint 2010.
    Se abre el cuadro de diálogo Difundir presentación de diapositivas.
    Cuadro de diálogo Difundir presentación de diapositivas
    1. Siga uno de estos pasos:
      • Si desea hospedar la presentación en el servicio que aparece en Servicio de difusión, vaya al paso siguiente.
      • Si desea utilizar algún otro servicio para que hospede la presentación con diapositivas, haga clic en Cambiar servicio de difusión. En Elija un servicio de difusión, seleccione el servicio que desea usar. Para obtener más información acerca de los servicios de difusión, consulte Elegir un servicio de difusión.
     NOTA   Si no encuentra el servicio que desea usar, seleccione Agregar nuevo servicio y luego, en el cuadro de diálogo Agregar servicio de difusión, escriba la dirección de red del servicio que desea usar y haga clic enAgregar.
    1. Después de seleccionar el servicio de difusión, haga clic en Iniciar difusión. PowerPoint crea una dirección URL para la presentación.
    Cuadro de diálogo Difundir presentación de diapositivas con una dirección URL para una presentación.
    PowerPoint crea una dirección URL única para la presentación.
    1. Para enviar la dirección URL de la presentación a la audiencia, siga uno de estos pasos:
      • Para enviar la dirección URL de la presentación por correo electrónico, haga clic en Enviar por correo electrónico.
      • Para copiar el vínculo, haga clic en Copiar vínculo.
    2. Cuando la audiencia reciba la URL de la presentación, haga clic en Iniciar presentación con diapositivaspara comenzar la difusión.
    Una presentación difundida tal como se ve en el explorador
    La audiencia sigue la presentación en el explorador mientras usted la presenta en PowerPoint 2010.
    1. Cuando termine la presentación y si está listo para finalizar la difusión, presione ESC para salir de la vista Presentación y haga clic en Finalizar difusión.
    Al difundir una presentación en PowerPoint 2010, aparece la ficha Difundir.
    Después de comenzar a difundir una presentación, aparece la ficha Difundir en la cinta de PowerPoint 2010.

    Presentaciones remotas con POWERPOINT 97

    Con PowerPoint 97 tambien  es posible hacer una presentación remota, si bien el proceso es algo mas engorroso. En el caso de varios equipos remotos que estén en la misma red o bien conectados a Internet, se puede mostrar una presentación como moderador de forma que en los demás equipos se mostrara la ppt  como   audiencia (sin participación en la misma). 

    Para mostrar una presentación remotamente, el moderador tendrá que estar en contacto  ( por ejemplo por vozip o telefonía ) con los usuarios que van a actuar como audiencia porque le tendrán que dar algunos datos (como nombre de equipo o dirección IP en caso de estar conectados por Internet). Una vez que estén  todos en contacto , el moderador debe ir a Herramientas/Presentación remota en PowerPoint 97 con la presentación abierta. En el primer paso del asistente, le preguntara como va a actuar, si como moderador o como audiencia (tendrá que indicarle que como moderador). 

    En el momento en que se pulsar el botón Siguiente del asistente, los demás usuarios ya podrán arrancar PowerPoint 97 (sin ninguna presentación abierta) e ir a Herramientas/Presentación remota y en el primer paso del asistente solo les permitirá actuar como audiencia. 

    Acto seguido a los usuarios que se conecten como audiencia, el asistente les dará el nombre del equipo propio. En caso de que esten en la misma red que el moderador, este sera el nombre que le tengan que comunicar al moderador. En caso de que estén en distintos dominios y conectados por Internet, tendrán que darle la direccion IP al moderador. 

    Una vez que el moderador conozca la identidad de todos los usuarios que van a visualizar la presentación cada usuario, debe terminar el asistente y el equipo se quedara en modo de espera buscando la señal del equipo moderador. 

    El moderador, en el paso Detalles de conexión del asistente, debera insertar el nombre de los equipos de los usuarios de audiencia (o las direcciones IP en caso de que esten en Internet) en el cuadro de dialogo del asistente. 

    Una vez que todos los equipos estén en modo de espera, y siempre después de todos los usuarios de audiencia, el moderador puede terminar el asistente. En ese momento, el equipo del moderador entrara en la red a buscar a los demas equipos que estan en espera. En el momento en que se encuentren los equipos, en las pantallas de los equipos de audiencia aparecerá la presentación y en la pantalla del moderador aparecerán varias ventanas, una con la presentacion y otras con herramientas para controlarlas. En ese momento, el moderador puede iniciar la presentación que se mostrara en los demás equipos. 

    Fuente   Microsoft   y  aqui 
    Licencia Creative Commons
    solo-electronicos por Carlos Rodriguez Navarro se encuentra bajo una Licencia Creative Commons Atribución-NoComercial-CompartirIgual 3.0 Unported.