Sergiy Baydachnyy

Blog about technologies

Archive for February 2015

Internet if Things: How to create a simple Web server (part 2)

leave a comment »

Last time I promised to show how to create a simple Web server on Galileo board. Since we have Windows on Galileo there can be several ways to create a simple web server but, finally, I found just one “stable” way to do it – sockets (WinSock 2.2 library). Additionally, I found one more way which doesn’t require development at all but first things first.

Since I am a .NET developer, I started my research with some libraries, which could help me to avoid sockets and not require using the Win32 API a lot. According to the samples presented by Microsoft, there is a way to use C++ Rest SDK and node.js. But both of them don’t have official support of Galileo boards. Windows image for Galileo contains subset of desktop Win32 API, so, there is no guarantee that these SDKs work fine or will work fine in future releases.

For example, if you are going to use C++ Rest SDK, you should download version 2.2 but current version 2.4 will not work. Version 2.2 uses WinHTTP API in some classes, which is not supported in Galileo image as well. That’s why I didn’t have a chance to use http_listener there.

The same situation with node.js. I did all recommended things with user32.dll but the latest version of node.js simply didn’t work. If I have some time I will try to find the solution of the problem there but I needed to find a simple way to launch Web server without spending much time.

That’s why I decided to use Winsock API which is a common part of all modern Windows images. But before I show my Web server, I want to discuss one more thing – httpsrv.exe.

If you had a chance to use the Galileo Watcher, you saw several menu items in context menu there and one of these items was “Web Browser Here”:

clip_image001

This menu allows you to launch a browser, which opens a web page on th Galileo board with several links there. It uses an IP address of the board and port 80 there. So, it’s easy to understand that Galileo contains a web server by default. If you launch Telnet and run tlist command you will find that there is httpsrv.exe process.

clip_image003

This process is a simple web server, which is part of Windows mini image. It’s not easy to find something about this server but I found that it maps c:\Windows\System32\Web folder as a Web server directory. In fact there is a simple page and several applications which are initiated by the page:

clip_image005

So, I simply changed a page and added a link to my own application, which contains just one line of code:

#include <iostream>

int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "<body>Hello from Web <a href=http://microsoft.com>Microsoft</a></body>";
return 0;
}

Thanks to httpsrv I got a chance to run my own application and use output stream as a source for outgoing web page. This approach is very simple. In fact you can create two applications: the first one implements logic of your project and use some local files for data storage, the second one should read stored data and generate output stream for web page. Thanks to that you should not think about your own implementation of a web server at all. It was so easy that I lost all desire to use sockets but I had promised it last time. So, if you finally decided to implement your own server I will show the socket approach as well. Pay special attention that httpsrv uses port 80, so, if you want to use your own server using the port, you need to shutdown httpsvr or start httpsrv using other port.

In order to use Winsock API I decided to use existing code with some modifications. MSDN Samples allowed only one request and tried to make something with this request. In case of Web server, you need to allow many requests, so I used a simple while operator there. Additionally, I changed all printf to Log function.

#include "arduino.h"
#undef UNICODE

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>

#pragma comment (lib, "Ws2_32.lib")

#define DEFAULT_BUFLEN 1024
#define DEFAULT_PORT "8080"

int __cdecl main(void)
{
WSADATA wsaData;
int iResult;

SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;

struct addrinfo *result = NULL;
struct addrinfo hints;

int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;

iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
Log("WSAStartup failed with error: %d\n", iResult);
return 1;
}

ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;

iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
Log("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}

ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
Log("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}

iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
Log("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}

freeaddrinfo(result);

while (true)
{
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
Log("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
}

ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
Log("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
}

iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0)
{
Log("Bytes received: %d\n", iResult);

char ret[] = "Hello World";
iSendResult = send(ClientSocket, ret, sizeof(ret), 0);
if (iSendResult == SOCKET_ERROR)
{
Log("send failed with error: %d\n", WSAGetLastError());
}
Log("Bytes sent: %d\n", iSendResult);
}
else if (iResult == 0)
Log("Connection closing...\n");
else
{
Log("recv failed with error: %d\n", WSAGetLastError());
}

iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
Log("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
}

closesocket(ClientSocket);
}

return 0;
}

This code is not ideal because it accepts all requests, doesn’t generate the right response (like HTTP/1.0 200 OK…..) and it doesn’t support multithreading. But it works, it doesn’t depend on any third-party library, doesn’t require dancing with a tambourine and you can use it as a starting point for your server.

Advertisements

Written by Sergiy Baydachnyy

02/18/2015 at 6:01 AM

Posted in IoT

Tagged with

IoT: How to integrate two boards

leave a comment »

In the previous posts I described some features of Galileo 2 board but there are still some scenarios, which may not be implemented on Galileo 2 boards only. For example, Galileo doesn’t have GPU, so you cannot use Galileo to output video. But there are several micro boards in the market like Raspberry Pi board, which supports GPU, HDMI output and allows to use camera as well. So, on the one hand we have a good solution with the Intel inside processor but on the other hand we still have some scenarios when we need to use several boards there. So, in this post I decided to show how to integrate two boards.

I used the Netduino and Galileo boards but this approach will work for Raspberry PI and Arduino as well. The idea is in using TX/RX pins, which are implemented in the most boards and allow to make serial communications. In fact, TX/RX pins is the same like COM1.

In order to test TX/RX pins I decided to build something like this

image

The idea of the project is too simple: we will use Galileo board in order to get input from two buttons and thanks to them we are going to control two leds, which are connected to Netduino. Because we use Netduino compatible boards, we can find TX/RX pins connected to pins 0 and 1. One of this pins is used for sending data and the second one – for receiving. So we should connect pin 0 (Galileo) to pin 1 (Netduino) and pin 1 (Galileo) to pin 0 (Netduino).

The code of our applications is pretty simple. In case of Arduino you can use the following example:

public class Program
{
public static void Main()
{
// write your code here
OutputPort ledRed = new OutputPort(Pins.GPIO_PIN_D8,false);
OutputPort ledYellow = new OutputPort(Pins.GPIO_PIN_D9,false);
SerialPort serial = new SerialPort(SerialPorts.COM1,9600,
Parity.None, 8, StopBits.One);
serial.Open();

while(true)
{
if (serial.CanRead)
{
int b=serial.ReadByte();
char c = (char)b;
switch(c)
{
case 'r':
ledRed.Write(true);
break;
case 'y':
ledYellow.Write(true);
break;
case 'f':
ledRed.Write(false);
break;
case 'h':
ledYellow.Write(false);
break;
}
}
}
}
}

This code just get the commands from serial port and switch on or switch of the leds.

In case of Galileo, you can use the following code:

#include "stdafx.h"
#include "arduino.h"

int _tmain(int argc, _TCHAR* argv[])
{
return RunArduinoSketch();
}

int but1 = 8;
int but2 = 9;
bool flag1 = false;
bool flag2 = false;

void setup()
{
Serial.begin(CBR_9600, Serial.SERIAL_8N1);
pinMode(but1, INPUT);
pinMode(but2, INPUT);
}

void loop()
{
if ((digitalRead(but1) == HIGH) && (!flag1))
{
Serial.write('r');
flag1 = true;
Sleep(1000);
}
if ((digitalRead(but2) == HIGH) && (!flag2))
{
Serial.write('y');
flag2 = true;
Sleep(1000);
}
if ((digitalRead(but1) == HIGH) && (flag1))
{
Serial.write('f');
flag1 = false;
Sleep(1000);
}
if ((digitalRead(but2) == HIGH) && (flag2))
{
Serial.write('h');
flag2 = false;
Sleep(1000);
}
}

I used sleep there in order to avoid several inputs from one button click there.

Finally I run my project:

image

In our case we used Galileo for sending data. But if you want to write some code which will able to receive some data you should add the following preprocessor directive to C/C++ configuration properties: SERIAL_EVENT; Additionally you should implement serialEvent method, which is called if some data is available.

You can use TX/RX pins in order to communicate with PC as well. In order to do it you can but UART->USB adapter which costs around 6 dollars (use just two pins there).

image

Written by Sergiy Baydachnyy

02/17/2015 at 10:11 PM

Posted in IoT

Tagged with

My first experience with 3D printer

with one comment

clip_image002

Last week, thanks to BizSpark program, finally, we got a 3D printer for the Launch Academy. Since I am a Technical Evangelist in Vancouver I got an exclusive offer to understand what is it and how can we use it for different projects. Frankly speaking we had a 3D printer in Ukrainian office but I have never touched it because in Ukraine I never had a chance to buy something, like motors and controllers at http://robotshop.ca/, Amazon or Fry’s Electronic and that printer wasn’t very valuable for me at that time. But today I need much stuff like propellers for my drone, wheels for micro robots, boxes for microcontrollers and sensors etc.

So, last Tuesday, I got a package and started my way in 3D experience. In this post I am going to share several learnings, which I got during my first steps.

It’s not very complex thing

There are several technologies, which are used in 3D printers today. For example in medicine area you can find some printers, which use powder or photopolymers and are based on Selective Laser Sintering or Stereo Lithography technologies. But today, the most common technology for innovators and hobbyists is Fused Deposition Modeling or Fused Filament Fabrication. This technology works by laying down material in layers. It can use plastic or metal to create a thing, layer by layer

In my case I have a Makerbot Mini 3D printer, which looks like a small box without any complex things inside. Because it was a new one, it required 6-9 steps in order to assemble it but I was not required to use any instruments.

clip_image004

3D printer is not a very complex thing in sense of software as well. It contains software, which allows to use G-Code to print your things layer by layer. In any case, before printing something, you need to update your printer. In case of Makerbot I used Makerbot Desktop tool. This tool is not just updated in (?) my printer but it’s required to load and unload filament there.

Windows 8.1 drivers

It’s very important to buy a printer, which supports drivers for Windows. Makerbot is such a printer, so it supports Plug and Play experience.

If your printer doesn’t support Windows 8.1 drivers, you will have much more steps to print your things. Usually you should convert your 3D model to STL format and use some slicer tools in order to set some settings and slice your model. Additionally, the tools should generate G-Code for the printer. But in case of Windows 8.1 compatible printers, driver can do many things for you. It allows you to use common tools for printing and you even can implement printing experience in your application. If you want to create an application, which will print something, you can download 3D printing SDK and find several examples there. You can use the following link in order to download the sdk.

Additionally, SDK contains some documents, which describe how to create your own driver. So, if you assembled your own printer or want to help the community, you can use 3D printing SDK in order to build a driver as well.

Tools

As I mentioned earlier, 3D printing SDK for Windows contains some samples about how to implement 3D printing experience in your applications. But if you are going to start printing right now you can install already prepared application for your – 3D Builder. You can find this application in the Window Store and it allows to create, modify, fix and print your models. Of course, you can use Maya or 3D Max in order to create a new model but I don’t have experience with it. So, I decided to use 3D builder.

clip_image006

Additionally, 3D Builder allows to use Kinect to scan real objects.

clip_image008

If you downloaded Makerbot desktop tool, you will find it valuable as well. Of course, it doesn’t support any features which help to modify your model but it allows to understand your printer status and estimate printing time.

clip_image010

Where to find some stuff

No matter what printer model you have I would like to recommend to visit site http://www.thingiverse.com/. It contains a lot of free models, which you can use for your experiments.

clip_image012

Usually you can find STL file there. So, you can print it directly or use them to create new models in 3D Builder.

Some tips

I found that my printer is too noisy. So, if you are going to print something at home – find a good place for it. Additionally, it requires much time to print things. For example, in order to print a trinket, it will spend more than hour but for a drone propeller it spent 3 hours.

Before starting printing, remove all garbage from the printing area. Usually you can find some filament there because it accumulated there during heating process etc. If it happened right before printing, you can use Makerbot desktop in order to pause the process. Usually, it’s not very dangerous to put your hands inside.

Use 3D builder to change orientation of your things. Sometimes your things are not stable during printing process due to wrong orientation. Think some time before starting the process.

Use raft and support features. It requires additional printing time but it’s easy to remove raft and it really helps.

Summary

3D printers are very popular today and they allow to bring your ideas to real world with less cost. Today, you can find many utilities, APIs and models, which are ready for 3D printers. At the same time, 3D printers are not very expensive like several years ago. In any case, if you still don’t have your own 3D printer, you can visit one of the place for innovators and startups – in many cases you will find many 3D printers there. And today I would like to announce 3D printer availability at Launch Academy in Vancouver.

image

Written by Sergiy Baydachnyy

02/17/2015 at 10:05 PM

Posted in Microsoft

Tagged with

Internet of Things: What about C# there?

leave a comment »

In my post about Galileo we used C++ language in order to build some code. But what about C# and is there a way to use management language in micro devices based on different types of microcontrollers? So, this post I decided to devote to C# language.

First of all you need to understand that there is no way to use C# for Arduino boards. Of course, Arduino is very popular today but there are many different solutions in the market as well. Some of these solutions are Netduino, Raspberry PI and Galileo. Today, you can find much more different boards but these microcontrollers have better support, community and popularity. So, let’s discuss all these boards and try to understand if there is a place for C# and .NET Framework.

I am going to start with Netduino boards. You can find many different models using the following link. I would recommend Netduino Plus 2, which is the most advanced board there but it’s not important right now because all these boards run .NET Micro Framework and allow to use C# there.

clip_image002

.NET Micro Framework is an open source platform, which is developed for low memory devices with limited amount of resources. In fact, .NET Micro Framework could be run on devices with 64 kilobytes memory that is very important for cheap and really small devices. .NET Micro Framework has a very interesting story. Probably, it was announced too early, about 9 years ago and since that time, .NET Micro Framework supported many different microcontrollers. Today, the most popular microcontrollers are Netduino 2 and Netduino Plus 2, which are Arduino compatible. It’s very important right now because it’s easy to find many different stuff for Arduino. At the same time there are special controllers for people, who don’t have enough knowledge in electronics – Netduino Go and Gadgeteer. These two boards allow to use plug and play modules to create your own prototype fast.

In my case I decided to buy Netduino Plus 2 board and make some small projects there. And of course, if you have a board you will need to install some stuff to your computer like: .NET Micro Framework SDK, Tools for Visual Studio and board specific SDK. In case of Netduino Plus 2 I would recommend the following steps there:

· Update Netduino firmware – when I bought the board I found that it has version of .NET MF less than 4.3. But if you have older version of firmware on your board you will not be able to use the latest version of SDKs. How to update firmware you can find in Arduino forum.

· Install .NET Micro Framework SDKs and tools for Visual Studio – you can find the package using the following link;

· Install Netduino SDK – you can download it there;

In any case, before download something, check the latest versions of SDKs and firmware.

Once you install all needed software, you can use USB -> micro USB cable in order to connect it to PC. You can use this cable in order to provide power to Netduino board. Using Visual Studio you can create an application based on special templates for Netduino boards and you can start to use C# and many classes from .NET Micro Framework and Arduino there. Visual Studio supports not just deployment of applications to Netduino but debugging and Intellisense system as well. So, you developer experience should look like common Windows platform experience. It’s really cool.

clip_image004

The second board, which allows to use C# there is Raspberry PI board. This board is not compatible with Arduino but it’s very popular because there is not just CPU but GPU as well. The board contains HDMI output and you can connect it to TV sets, projectors etc. And you still may use many sensors from Arduino world because Raspberry supports the same voltage. Frankly speaking, Raspberry doesn’t support Visual Studio or any special tools for Windows developers but Raspberry is designed for full version of Linux operation system. You can find many different Linux edition for Raspberry but in any case you need to work with Linux. But as you know, there is an open source version of .NET Framework – Mono. So, you still can use C# and .NET framework features there.

In my research I decided to use Raspbian image based on Debian Wheezy. Somebody told me that it’s very popular and it was the first in the list of images. Of course, for Windows developers it’s not easy to understand, how to use this image but I just connected my board to TV Set, using HDMI cable and plugin keyboard and mouse there. Thanks to Edimax WiFi adapter and WiFi Config tool in the image, I easily setup Internet connection there and got IP address. Once you get Internet connection, you need to run one more command, using LXTerminal:

sudo apt-get install xrdp

This command will activate remote desktop on your board. It’s time to disconnect your board from TV, keyboard and mouse because you may use Remote desktop right now.

In the next step, you need to run to more commands to install Mono runtime:

$ sudo apt-get update

$ sudo apt-get install mono-runtime

Thanks to Mono runtime you are ready to launch you C# application but you still don’t have tools. So, finally, in order to install Mono Develop, you can use the following command:

sudo apt-get install monodevelop

Now, you ready to run Mono Develop and launch your applications.

clip_image006

Frankly speaking, I am not sure if you will get much happiness while developing something on Raspberry directly. It’s not a very productive environment and it’s better to use your PC to create code and just use Raspberry to compile and launch it. While it’s interesting to create Windows Form applications on Raspberry usually you are interested in PINs there. In order to use pins from C# and make real micro solutions you will need to download RaspberryPI.NET library, which you can find using the link.

And a few words about Galileo. Officially Microsoft doesn’t support .NET Framework on Galileo boards. According to official FAQ there is a chance to see Windows Runtime or something like this soon:

Q: Will you support C#/WinRT/.NET/Node/JS… ?
A: For this first preview release, we’re focusing on C++ and Arduino compatibility. In future iterations, our intent is to support the Universal App model announced at Build.

But I found that many people already tried to make some research around Mono and Galileo board as well. For example, you can check this post in order to find some instructions about it.

Written by Sergiy Baydachnyy

02/17/2015 at 9:56 PM

Posted in IoT

Tagged with

Internet of Things: How to create a simple Web server (part 1)

leave a comment »

Today you can find many different boards in the market which have Ethernet socket or support Ethernet/Wi-Fi/3G shields. So, connection to Internet is a trivial task. I already mentioned several Azure services which you can use in order to send messages, store your data and analyze it. But I found that there are still some scenarios when customers don’t want to connect their devices to Internet. At the same time they still need access to data using phones, laptops etc. using local network without any special infrastructure. In this case there is a task, which requires to have a simple web server. Of course, you can try to create any type of server (not just Web) but in most cases it’s easy to use Web browser to get access to your data. It’s not very hard to implement several methods inside your IoT solution, which will prepare HTML output based on existing data. But what about Web server?

In order to do my research I decided to use Netduino and Galileo boards. In this post I will show code for Netduino in .NET and in the next post I am going to discuss more complex code for Galileo.

Because Netduino uses .NET Micro Framework, it’s easy to use already prepared classes, which will help to implement our code. The most important class there is HttpListener and you can find it in System.Http assembly which is not included to your references by default. This class allows to start listening HTTP request. In fact you can implement the following code inside your Main method:

var httpListener = new HttpListener("http", 80);

httpListener.Start();

while(true)
{
var context = httpListener.GetContext();
var buffer = Encoding.UTF8.GetBytes("<html><body>" + DateTime.Now + "</body></html>");
context.Response.ContentLength64 = buffer.Length;
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
context.Close();
}

We just created an object of HttpListener type using http protocol and port 80 and initiated listening thanks to Start method there. In order to get request from users we should call GetContext method, which will be waiting for request. Once we have a request we can get information about Uri, parameters etc. and create a response. In our case we send back a simple Html document.

If you test this code, probably, it will work but there are two problems:

· This code will work fine just for one user and if you have several requests, probably, your board will go down;

· Usually you need to do something and not just listening to a request. If you leave this implementation, you won’t have a place to put device’s logic there;

So, we need to update our code using threads. In order to avoid the first problem you can generate your HTML and send response in separate thread and there will be a separate thread for each request. At the same time you can start listening in separate thread as well. This approach will allow you to start listening and return to application’s logic. So, my code looks like this:

new Thread(() =>
{
var httpListener = new HttpListener("http", 80);
httpListener.Start();
while (true)
{
var context = httpListener.GetContext();
new Thread(() =>
{
var buffer = Encoding.UTF8.GetBytes("<html><body>" +
DateTime.Now + "</body></html>");
context.Response.ContentLength64 = buffer.Length;
context.Response.OutputStream.Write(buffer, 0,
buffer.Length);
context.Close();
}).Start();
}
}).Start();

while(true)
{
//your logic
}

If you have some time your can rewrite this code using delegates approach.

Finally, I want to share the code which shows how to get ip address of your board. It will help you to reach your board using Web browser:

NetworkInterface ni;
while (true)
{
ni = NetworkInterface.GetAllNetworkInterfaces()[0];

if (ni.IPAddress != "0.0.0.0") break;
Debug.Print("Waiting for an IP Address...");
Thread.Sleep(1000);
}
Debug.Print(ni.IPAddress.ToString());

Next time we will use sockets in order to show how to build Web server on Galileo.

Written by Sergiy Baydachnyy

02/13/2015 at 8:34 AM

Posted in IoT

Tagged with