Sincronizar la hora de tu netduino


 

Este utilidad  para nuestro Netduino    toma el dato fecha-hora(datetime)   de un servidor  NTP
El código se basa  en http://weblogs.asp.net/mschwarz/archive/2008/03/09/wrong-datetime-on-net-micro-framework-devices.aspx
Código para Netduino-Plus:

using
 System;
using Microsoft.SPOT;

 

using System.Net.Sockets;

 

using System.Net;

 

using Microsoft.SPOT.Hardware;

 

using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using Microsoft.SPOT.Time;

 

namespace NetduinoPlusWebServer

 

{

 

    class TimeHandeler

 

 {

 

     /// Timeserver

 

        /// Local NTP Time

 

        public static DateTime NTPTime(String TimeServer)
     {
          // Find endpoint for timeserver
           IPEndPoint ep = new IPEndPoint(Dns.GetHostEntry(TimeServer).AddressList[0], 123);

 

         // Connect to timeserver

 

        Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

 

          s.Connect(ep);

 

            // Make send/receive buffer

 

         byte[] ntpData = new byte[48];

 

    Array.Clear(ntpData, 0, 48);

 

         // Set protocol version

 

       ntpData[0] = 0x1B;

 

            // Send Request

 

            s.Send(ntpData);

 

            // Receive Time

 

            s.Receive(ntpData);

 

            byte offsetTransmitTime = 40;

 

           ulong intpart = 0;

 

            ulong fractpart = 0;

 

           for (int i = 0; i <= 3; i++)

 

               intpart = (intpart <<  8 ) | ntpData[offsetTransmitTime + i];

 

           for (int i = 4; i <= 7; i++)

 

                fractpart = (fractpart <<  8 ) | ntpData[offsetTransmitTime + i];

 

            ulong milliseconds = (intpart * 1000 + (fractpart * 1000) / 0x100000000L);

 

           s.Close();

 

            TimeSpan timeSpan = TimeSpan.FromTicks((long)milliseconds * TimeSpan.TicksPerMillisecond);

 

           DateTime dateTime = new DateTime(1900, 1, 1);

 

            dateTime += timeSpan;

 

            TimeSpan offsetAmount = TimeZone.CurrentTimeZone.GetUtcOffset(dateTime);
          DateTime networkDateTime = (dateTime + offsetAmount);

 

           return networkDateTime;

 

        }

 

    }

 

}

 

 

Netduino-Plus como webserver interactuando con dispositivos


Hay muchas maneras de controlar la puerta del garaje con su Netduino. En este caso se   modificara un mando de apertura de puerta de garaje  por medio de un OPTOISOLATOR   y este a su vez se conectara a nuestro netduino por medio de uan resistencia en serie. Para enviar comandos a la placa de  Netduino se utilizaran simples  comandos HTTP.

Componentes necesarios para el montaje

  • Abrir puertas de garajes
  • OPTOISOLATOR con el controlador de Darlington – 1 canal.
  • Resistencia de 100 ohmios
  • 33 ohmios resistencia
  • Netduino  Plus

El esquema para la conexión del netudiono  con el abridor de la puerta del garaje es bastante sencillo:

  • Conecte el pin OPTOISOLATOR 1 (ánodo) al pin digital plus Netduino 13
  • Conecte el pin OPTOISOLATOR 2 (cátodo) a un pin de tierra en el signo más Netduino con una resistencia de 33 ohmios en línea.
  • Conectar el pasador optoaislador 3 (emisor) a un lado de la puerta de garaje pulsador con una resistencia de 100 ohmios en línea.
  • Conectar el pasador optoaislador 4 (colector) al otro lado de la puerta garge abridor pulsador.

Explicacion del código 

Primero se inicializa el puerto digital 13 para hablar con el abrepuertas de garaje
Desues se analiza la solicitud http y confirme que el usuario solicitado a la puerta se active con el comando «HTTP: /192.XXX.X.XXX/activatedoor»

Se llama al  método para activar el abridor de puerta de garaje.
Se envia respuesta HTTP.
Se envía una respuesta HTTP – comando no reconocido.
Se  active el método de puerta de garaje
Se  encienda el LED de a bordo para que se envíe el comando de confirmación visual al abrepuertas de garaje
Se  envíe voltaje al pin digital 13 para cerrar el botón en el abrepuertas de garaje
Se espera 1 segundo
Se apagua el LED de a bordo
Se detiene el voltaje en el pin 13

 

Codigo completo

 

public class WebServer : IDisposable
{
private Socket socket = null;
//open connection to onbaord led so we can blink it with every request
private OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
private OutputPort Garage2CarOpener = new OutputPort(Pins.GPIO_PIN_D13, false);

public WebServer()
{
//Initialize Socket class
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//Request and bind to an IP from DHCP server
socket.Bind(new IPEndPoint(IPAddress.Any, 80));
//Debug print our IP address
Debug.Print(Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0].IPAddress);
//Start listen for web requests
socket.Listen(10);
ListenForRequest();
}

public void ListenForRequest()
{
while (true)
{
using (Socket clientSocket = socket.Accept())
{
//Get clients IP
IPEndPoint clientIP = clientSocket.RemoteEndPoint as IPEndPoint;
EndPoint clientEndPoint = clientSocket.RemoteEndPoint;
//int byteCount = cSocket.Available;
int bytesReceived = clientSocket.Available;
if (bytesReceived > 0)
{
//Get request
byte[] buffer = new byte[bytesReceived];
int byteCount = clientSocket.Receive(buffer, bytesReceived, SocketFlags.None);
string request = new string(Encoding.UTF8.GetChars(buffer));
string firstLine = request.Substring(0, request.IndexOf(‘\n’)); //Example «GET /activatedoor HTTP/1.1»
string[] words = firstLine.Split(‘ ‘); //Split line into words
string command = string.Empty;
if( words.Length > 2)
{
string method = words[0]; //First word should be GET
command = words[1].TrimStart(‘/’); //Second word is our command – remove the forward slash
}
switch (command.ToLower())
{
case «activatedoor»:
ActivateGarageDoor();
//Compose a response
string response = «I just opened or closed the garage!»;
string header = «HTTP/1.0 200 OK\r\nContent-Type: text; charset=utf-8\r\nContent-Length: » + response.Length.ToString() + «\r\nConnection: close\r\n\r\n»;
clientSocket.Send(Encoding.UTF8.GetBytes(header), header.Length, SocketFlags.None);
clientSocket.Send(Encoding.UTF8.GetBytes(response), response.Length, SocketFlags.None);
break;
default:
//Did not recognize command
response = «Bad command»;
header = «HTTP/1.0 200 OK\r\nContent-Type: text; charset=utf-8\r\nContent-Length: » + response.Length.ToString() + «\r\nConnection: close\r\n\r\n»;
clientSocket.Send(Encoding.UTF8.GetBytes(header), header.Length, SocketFlags.None);
clientSocket.Send(Encoding.UTF8.GetBytes(response), response.Length, SocketFlags.None);
break;
}
}
}
}
}
private void ActivateGarageDoor()
{
led.Write(true); //Light on-board LED for visual cue
Garage2CarOpener.Write(true); //»Push» garage door button
Thread.Sleep(1000); //For 1 second
led.Write(false); //Turn off on-board LED
Garage2CarOpener.Write(false); //Turn off garage door button
}
#region IDisposable Members
~WebServer()
{
Dispose();
}
public void Dispose()
{
if (socket != null)
socket.Close();
}
#endregion
}