The Eject-A-Bed: Part 2

Now that we have a way of controlling the bed via a Netduino, we need a way of controlling the Netduino.  We thought about different scenarios – hacking into an alarm clock, a phone app, some kind of light sensor, etc…  In all of these scenarios, it made sense to make the Netduino Ethernet aware so I went and bought a new Netduino plus.  The two day wait for Amazon prime reminded me how we have come full-circle with getting our goods.  I am going to re-write the lyrics from the Music Man’s Well’s Fargo Wagon to the Amazon Wagon

O-ho the Am Azon Wagon is a-comin‘ down the street,

Oh please let it be for me!

O-ho the Am Azon Wagon is a-comin’ down the street,

I wish, I wish I knew what it could be!

In any event event, with the Netduino plus, I could send signals to the Netduino to move the bed up and down.  I checked Dan Theyer’s post about how build a solid class to cover Ethernet communications and I checked out this article to get a “Hello World’ Ethernet project up and going.

I decided to start with the ground up happy path using the ‘Hello World’ project.  To that end, I added a socket instance to the project

  1. private static Socket _socket = null;


I then add the SetUpWebServer method like so:

  1. private static void SetUpWebServer()
  2. {
  3.     _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  4.     IPEndPoint ipEndpoint = new IPEndPoint(IPAddress.Any, 80);
  5.     _socket.Bind(ipEndpoint);
  6.     _socket.Listen(10);
  7.     ListenForRequest();
  8. }


And the ListenForRequest like so:

  1. public static void ListenForRequest()
  2. {
  3.     while(true)
  4.     {
  5.         using (Socket clientSocket = _socket.Accept())
  6.         {
  7.             IPEndPoint clientIP = clientSocket.RemoteEndPoint as IPEndPoint;
  8.             EndPoint clientEndPoint = clientSocket.RemoteEndPoint;
  10.             int bytesReceived = clientSocket.Available;
  11.             if (bytesReceived > 0)
  12.             {
  13.                 byte[] buffer = new Byte[bytesReceived];
  14.                 int byteCount = clientSocket.Receive(buffer, bytesReceived, SocketFlags.None);
  15.                 String request = new String(Encoding.UTF8.GetChars(buffer));
  16.                 HandleRequest(clientSocket, request);
  17.                 SendResponse(clientSocket, request);
  19.             }
  20.         }
  21.     }
  22. }

You will notice a lack of  exception handling and threading.  Typically, the _socket.Accept() method should be on the main thread and then handling the message should be done on a separate thread so the _socket can get to listening the next message as fast as possible.  However, since the servo is directly tied to individual messages, I thought it was better to make the entire execution serial.  Plus, I am lazy.

In any event, once the Netduino gets a request, it then needs to adjust the servo:

  1. private static void HandleRequest(Socket clientSocket, String request)
  2. {
  3.     String[] chunkedRequest = request.Split('/');
  4.     String verb = chunkedRequest[0];
  5.     String direction = chunkedRequest[1];
  6.     String amount = chunkedRequest[2];
  7.     Int32 duration = Int32.Parse(amount);
  9.     ActivateServoForBellows(direction, duration);
  10. }


And the actual controlling of the servo we have seen before:

  1. private static void ActivateServoForBellows(String direction, Int32 duration)
  2. {
  4.     if (direction == "UP")
  5.     {
  6.         _servo.Duration = 1250;
  7.     }
  8.     else if (direction == "DOWN")
  9.     {
  10.         _servo.Duration = 1750;
  11.     }
  13.     Thread.Sleep(duration);
  14.     _servo.Duration = 1500;
  15. }

There can be some confusion about the word “duration”.  duration with a little ‘d’ means how long the servo stays in the non-straight position – effectivly how long the bed is moving.  Duration with the big ‘D’ means the location of the servo as it rotates around the center – how far the servo moves.  When I make this ready for prime time, my covering class will fix this ambiguity because I am a big believer in domain-unique language.  I will also be copying much of Dan’s code.

In any event, I also created a response method so the requestor can see something:

  1. private static void SendResponse(Socket clientSocket, String request)
  2. {
  4.     String[] chunkedRequest = request.Split('/');
  5.     String verb = chunkedRequest[0];
  6.     String direction = chunkedRequest[1];
  7.     String amount = chunkedRequest[2];
  8.     Int32 duration = Int32.Parse(amount);
  10.     String response = direction + " : " + amount + " was sent.";
  11.     String header = "HTTP/1.0 200 OK\r\nContent-Type: text;charset=utf-8\r\nContent-Length: " +
  12.         response.Length.ToString() + "\r\nConnection: close\r\n\r\n";
  14.     clientSocket.Send(Encoding.UTF8.GetBytes(header), header.Length, SocketFlags.None);
  15.     clientSocket.Send(Encoding.UTF8.GetBytes(response), response.Length, SocketFlags.None);
  16. }


So now when I send a browser request on my local Ethernet:


And sure enough, we can control the servo with my web browser


And then put together and using the browser in my phone:

Now if there was only a way to speed up the motor so I can launch my kid out of bed in the morning with more force….

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: