Visualizing ADXL345 Accelerometer Output In Windows Forms From Raspberry PI 2

26. September 2016 21:21

C# Raspberry Pi Windows  0 Comments

I have been playing a lot with Raspberry PI and Python these days and have also started a side project to create robot car controller with a Xbox 360 wireless controller. I am planning to controller a robot car using a custom interface from my Windows machine. Initially I tried with PyQt but I dropped the idea for now as Python is not my primary expertise and it will take some time for me to learn the basics and get into some serious coding. Controlling something remotely or visualizing the information from your device on the UI is always better. For a proof of concept I built a Windows Forms application which will request the output from Raspberry PI over TCP and then visualize it on the UI using a wonderful chart library that I found today. There is a slight change in the Python code as I have to transmit readings from Raspberry PI over TCP so my Windows Forms application can read the output and utilize it to visualize it.

Raspberry PI Python Application

Reading the ADXL345 output is fairly simple and you can do this without any problem by using Adafruit's ADXL345 Python library. This library will get you started in a jiffy and you will have your readings. I am not going into the details about the different features of the library I am using and ADXL345. The only thing you will have to do is to wire ADXL345 to your Raspberry PI and fire the example code you got from Adafruit's repository from Github. If you have set it up correctly this, you will see X, Y, Z values on your terminal. If the terminal displays 0s for all the three axis then there is something wrong with the wiring (assuming you are using the example code). This is how your writing should be like.

Now I have made slight changes in the code so that I can send the data over TCP. I have created a simple TCP server which exposes Raspberry PI through IP address and a port number. This is the complete code for reading values from ADXL345.
import Adafruit_ADXL345
import socket

HOST = "192.168.1.8"
PORT = 50007

accel = Adafruit_ADXL345.ADXL345()

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()

while 1:
    data = conn.recv(1024)

    if data.strip() == "adxl":
        x, y, z = accel.read()
        data = 'X:' + str(x) + '|Y:' + str(y) + '|Z:' + str(z)
        conn.send(data)
In the code, you can see that I am not just transmitting the readings just like that. I only transmit when there is a request from another application is there to get the readings. This is a good approach as I don't the PI to transmit the readings even if nobody is requesting it. I am sending a single string as a response which I am going to read at my Windows Forms application and use it.
You need to change the IP address and port number according to your Pi's configuration.
Once this is done you can then execute the script from the terminal by firing the below command
sudo python adxl.py

This is it from Raspberry PI side. Let's take a look from the Windows side now.

Windows Forms Application

This will be a simple Windows Forms application which will connect to the Raspberry PI using the Pi's IP address and the port on which the server is running. The Windows Form application is also a TCP client which sends a request to Raspberry PI for the updated readings from ADXL345. As I mentioned above in the Python code that the readings are not just being transmitted but a client has to send a request to to get the readings.

Let's get started with the visualizing part. While was searching for a perfect charting library, I came across this wonderful library called Live Charts. This library is open-source, easy to use, has lots of awesome charts and a very robust documentation and moreover it supports Windows Forms as well as on WPF applications. I highly recommend you to look at the examples to get the idea about this library.

As usual, I will be using Nuget command to install the library.

PM> Install-Package LiveCharts.WinForms
You also have to add the custom controls in the toolbox. You can follow the steps here to add the Live Charts control in the toolbox. In the design mode, choose the Cartesian Chart control from the toolbox and add it to the form. After adding the control to the form, I have dock it to the top of the form so I can utilize the lower section of the form to display the readings in numbers. Here is how my form looks like in design mode.
After the designing for the form is complete, I can initialize the chart to display the readings from Raspberry PI. The chart require few things to be setup before it can start displaying the data correctly. The accelerometer I am using is a 3-axis accelerometer and therefore it is going to send me readings for 3 axis i.e X, Y and Z. This means I will be needing 3 line series to visualize the information from accelerometer. To have 3 line series display the data I have to use CharValues class which will let me display the readings in the line series. As I have to update my chart when I request the new readings from Raspberry PI, I have to use ObservableValue type. The ObservableValue will make sure that whenever there is a change in the value, it gets reflected in the chart and therefore keeping the chart always up to date.
public ChartValues<ObservableValue> Values_X { get; set; }
public ChartValues<ObservableValue> Values_Y { get; set; }
public ChartValues<ObservableValue> Values_Z { get; set; }
Because I am going to make request to the server running on my Raspberry PI and request for the ADXL345 readings, I have to create a TCP client in order to do so.
Socket server;
IPEndPoint ipEndPoint;
byte[] data;
When the application is loaded, I want to make connection to Raspberry PI by using it's IP address and port number on which the server is running on. To do this I will add the below code to the constructor of my application.
data = new byte[1024];

ipEndPoint = new IPEndPoint(
                IPAddress.Parse("192.168.1.8"), 50007);

server = new Socket(AddressFamily.InterNetwork,
               SocketType.Stream, ProtocolType.Tcp);

try
{
    server.Connect(ipEndPoint);
}
catch (SocketException)
{
    MessageBox.Show("Unable to connect to server.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    return;
}

The above code is self-explanatory as I am just connecting to Raspberry PI.

In the form load event, I have to initialize chart values and add 3 line series to my CartesianChart for X, Y and Z axis respectively. In my case the name of the Cartesian Chart is ADXLViz.

Values_X = new ChartValues<ObservableValue>();
Values_Y = new ChartValues<ObservableValue>();
Values_Z = new ChartValues<ObservableValue>();

ADXLViz.Series.Add(new LineSeries
{
    Values = Values_X,
    Title = "X",
    StrokeThickness = 4,
    PointGeometrySize = 0,
    DataLabels = true
});

ADXLViz.Series.Add(new LineSeries
{
    Values = Values_Y,
    Title = "Y",
    StrokeThickness = 4,
    PointGeometrySize = 0,
    DataLabels = true
});

ADXLViz.Series.Add(new LineSeries
{
    Values = Values_Z,
    Title = "Z",
    StrokeThickness = 4,
    PointGeometrySize = 0,
    DataLabels = true
});

Play around with different properties in the LineSeries class and set the output that suits your need or your eye. Notice the Values properties in the LineSeries class which holds the value which is received from Raspberry PI.

I am requesting the readings from Raspberry PI every 500ms and to do this I am using a Timer class. This is easy to use and configure. Just drag and drop the Timer control from the toolbox. In the properties change the Interval property to 500 and Enabled to True. After this I set the Tick event which will request the new readings every 500ms.

string stringData;
server.Send(Encoding.ASCII.GetBytes("adxl"));
data = new byte[1024];
int recv = server.Receive(data);
stringData = Encoding.ASCII.GetString(data, 0, recv);
string[] adxl = stringData.Replace(" ", "").Split('|');

Values_X.Add(new ObservableValue(Convert.ToDouble(adxl[0].Split(':')[1])));
Values_Y.Add(new ObservableValue(Convert.ToDouble(adxl[1].Split(':')[1])));
Values_Z.Add(new ObservableValue(Convert.ToDouble(adxl[2].Split(':')[1])));

if (Values_X.Count > 10) Values_X.RemoveAt(0);
if (Values_Y.Count > 10) Values_Y.RemoveAt(0);
if (Values_Z.Count > 10) Values_Z.RemoveAt(0);

X_Label.Text = Convert.ToString(adxl[0].Split(':')[1]);
Y_Label.Text = Convert.ToString(adxl[1].Split(':')[1]);
Z_Label.Text = Convert.ToString(adxl[2].Split(':')[1]);
The stringData variable holds the response or reading which is received from Raspberry PI. If you check the Python code above you will see that the response is being sent in a single string called data. I am splitting the string here and extracting the values and setting it to ChartValues<ObservableValue> object. This will render all the 3 line series chart and update it with the readings received from PI. But the problem here will be that in few minutes the chart will be hard to see due to lot of data congestion in chart. In order to overcome this problem, I have removed the first value from all the 3 line series when the chart displays more than 10 values. You can change the value from 10 to whatever suits you.
The overall idea of building this application is to see whether it is possible or easy to communicate from Raspberry PI apart from using frameworks like WebioPI or Flask. The complete source code for Raspberry PI and Windows Forms application is available on Github along with Fritzing sketch file and additional instructions to install the dependencies.
 No Rating

Building Angular 2 App With Web API And .NET Core

21. May 2016 18:45

.NET Core ASP.NET MVC  0 Comments

Setting up the new Angular 2 app with Web API and .NET core is easy but can be a bit tricky. The older beta releases of Angular 2 works fine as there are not many files to refer and to work with. When I started using Angular 2 it was in RC1 and the way the files are being referenced in the app is bit different than the older versions of Angular 2. I don't want to repeat these steps again and again so I put up a Github repo for this seed project. You clone it and hit F5 and you will have your Angular 2 app with Web API.

At the time of writing this post I am using .NET Core version 1.0.0-preview1-002702. The complete seed project is available on GitHub.
Here is how I did it. Select ASP.NET Core Web Application (.NET Core). I have installed the new .NET Core RC2. Name the project as you like.
Select the Web API project template.
After the project creation is successfull. The first thing is to create a Views folder. The folder structure is like the same like it is for MVC application. This is how the folder structure looks like.
Because its a a Web API project, by default it will not render the views and therefore we have to add some dependencies in project.json file.
"Microsoft.AspNetCore.StaticFiles": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Mvc.TagHelpers": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Mvc.WebApiCompatShim": "1.0.0-rc2-final"
The project.json file is different than that of the older version of the .NET Core. You will see the difference when you see it.
Next we set the routes for the views we have in the Startup.cs file.
app.UseMvc(routes =>
{
    routes.MapRoute("default",
                    "{controller=Home}/{action=Index}/{id?}");

    routes.MapWebApiRoute("defaultApi",
                          "api/{controller}/{id?}");
});
The routes are now set and you can run the application and check if you can see the view or not. Once that is set, let start adding the support for Angular. Here is the list of the files which we need to add.
tsconfig.json file

Add the below code to the file and save it.
{
  "compilerOptions": {
    "target": "es5",
    "module": "system",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false,
    "rootDir": "wwwroot",
    "outDir": "wwwroot",
    "listFiles": true,
    "noLib": false,
    "diagnostics": true
  },
  "exclude": [
    "node_modules"
  ]
}
typings.json file

Add a blank .json file and name it typings.json

Add below lines to the typings.json file.
{
  "ambientDependencies": {
    "es6-shim": "registry:dt/es6-shim#0.31.2+20160317120654",
    "jasmine": "registry:dt/jasmine#2.2.0+20160412134438"
  }
}
As per the official Angular documentation, we will stick with NPM to fulfill the client-side dependencies. Start with adding new npm Configuration File. The content of the NPM file is almost the same, but I made few changes as per my requirement. Here is the complete configuration file.
{
  "name": "Angular2WebAPI-Seed",
  "version": "1.0.0",
  "scripts": {
    "postinstall": "typings install"
  },
  "license": "ISC",
  "dependencies": {
    "@angular/common": "2.0.0-rc.1",
    "@angular/compiler": "2.0.0-rc.1",
    "@angular/core": "2.0.0-rc.1",
    "@angular/http": "2.0.0-rc.1",
    "@angular/platform-browser": "2.0.0-rc.1",
    "@angular/platform-browser-dynamic": "2.0.0-rc.1",
    "@angular/router": "2.0.0-rc.1",
    "@angular/router-deprecated": "2.0.0-rc.1",
    "@angular/upgrade": "2.0.0-rc.1",

    "lodash": "4.12.0",
    "systemjs": "0.19.27",
    "es6-shim": "^0.35.0",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.0.0-beta.6",
    "zone.js": "^0.6.12",
    "angular2-in-memory-web-api": "0.0.7",
    "bootstrap": "^3.3.6"
  },
  "devDependencies": {
    "gulp": "3.9.1",
    "concurrently": "^2.0.0",
    "typescript": "^1.8.10",
    "typings": "^0.8.1"
  }
}
Notice the postinstall section in the npm configuration file. In this section we are installing the types required by our Angular 2 application. Now we can start setting up the Angular stuff in the wwwroot folder. Create an app and js folder inside this folder. Inside app folder create a new .ts file (TypeScript file). Here is the folder structure looks like in the wwwroot folder.
You can see a system.config.js file is the same as you can see the Angular quickstart guide. I just have map the paths for the dependencies so that can be loaded without any problem. The main.ts file will be the main bootstrapper and app.component.ts file is the component file which will render the content on the page. At this point running the application will fail and it will give you several warnings and errors. To resolve that we need to add the references and we can do this easily by using a gulp file. The gulp file will automate the copying of dependencies in the wwwroot folder and ease our task. 
The content of the gulp file in this case looks like this.
/// <binding BeforeBuild='default' />

var _ = require('lodash');
var gulp = require('gulp');

var js = [
    'node_modules/zone.js/dist/zone.min.js',
    'node_modules/systemjs/dist/system.js',
    'node_modules/reflect-metadata/Reflect.js',
    'node_modules/es6-shim/es6-shim.min.js'
];

var map = [
    'node_modules/es6-shim/es6-shim.map',
    'node_modules/reflect-metadata/reflect.js.map',
    'node_modules/systemjs/dist/system.js.map'
];

var folders = [
    'node_modules/@angular/**/*.*',
    'node_modules/rxjs/**/*.*'
];

gulp.task('copy-js', function () {
    _.forEach(js, function (file, _) {
        gulp.src(file)
       .pipe(gulp.dest('./wwwroot/js'))
    });
});

gulp.task('copy-map', function () {
    _.forEach(map, function (file, _) {
        gulp.src(file)
        .pipe(gulp.dest('./wwwroot/js'))
    });
});

gulp.task('copy-folders', function () {
    _.forEach(folders, function (folder) {
        gulp.src(folder, { base: 'node_modules' })
            .pipe(gulp.dest('./wwwroot/js'))
    });
})

gulp.task('default', ['copy-js', 'copy-map', 'copy-folders']);
Notice the very first line in the file above. We want to execute the task on every time before the build is triggered. The gulp file will only be copying the required files to the js folder and other unnecessary files will not be required. After the task is executed here is the how the final directiry structure will look like under wwwroot.
Depending on the selector you have in your component, you need to add the selector to your view. In my case the selector is app, hence add <app></app> in your Index.cshtml file.

After you set up the index page, there is one more thing that you have to do is to set the launch URL.

The URL may change and differ as per your API endpoint. Press F5 to run the application.

Currently rated 5.0 by 7 people

Dev Buzz #3 - Bookmarks

29. April 2016 13:51

Devbuzz  0 Comments

 No Rating

Parsing Markdown Using Custom TagHelper In ASP.NET MVC 6

30. November 2015 21:01

.NET Core ASP.NET MVC  0 Comments

Previous versions of MVC allows us to write HtmlHelpers which does a pretty good job then and they are doing it now as well. But in MVC 6, the ASP.NET team has introduced TagHelpers.

Parsing Mardown in .NET is way too simple than one can imagine. Thanks to Stackoverflow's MardownSharp and Karlis Gangis's CommonMark.NET. I use CommonMark.NET as it provides a much faster parsing than other libraries. The blogging platform I use is a custom blogging engine I wrote in MVC4. The post content is saved in HTML which makes my raw HTML way to messy when compared to simple markdown syntax. I have no plans to change the way it is right now, but for the other simple application which is quite similar to notes taking or blogging apps, I would like to save the content in markdown.

I will start with a simple implementation of this custom TagHelper and then then we can look into the other ways to enhance it. Here is how easy it is to create your custom TagHelper.

Create a new class file MarkdownTagHelper.cs. Inside the file, rename the class name to match the file name or you can change the name way you like. In my case I am keeping the class name as same as the file name.

Pay attention to the name of the custom TagHelper. By design, compiler will remove the word TagHelper from the class name and the rest of the name will become your custom TagHelper name.

The next step is to inherit our class with TagHelpers class. Every custom TagHelper will inherit this class. Just like the UserControl class when creating a custom user control. The TagHelper provide us two virtual methods, Process and a ProcessAsync method which we will be going to override to implement our custom logic for our custom markdown TagHelper. The first parameter is the TagHelperContext which holds the information about the current tag and the second parameter is TagHelperOutput object represents the output being generated by the TagHelper. As we need to parse the markdown in our razor view pages, we need to add reference of CommonMark.Net library. Use the below Nuget command to add it to your current project.

Install-Package CommonMark.Net

Till here this is how the code will look like.

So now we have our custom TagHelper that will let us parse the markdown. But to use it in our views we need to opt-in for this TagHelper in the _ViewImports.cshtml file. To enable your custom TagHelper just type in like this:

@addTagHelper "*, WebApplication1"

Your custom tag helper would have been turned purple in color on the view page. It is similar to the line above it where @addTagHelper is importing all the TagHelpers from the given namespace. If you are not interested in opting-in for all the TagHelpers in the given namespace then make use of the @removeTagHelper to disable the TagHelpers you don’t need. For this I want all the tag helpers I have created to be a part of the application and hence the * symbol.

In your view, where you want to use this just type in <markdown> and inside this tag you should have your markdown. To test it, you can view the any raw file in Github and copy the text. I am using README.md from CommonMark.NET and it rendered perfectly.

Caution: When copy-pasting the markdown code from anywhere to your view make sure that you do not have a whitespace in the front of the line. This is only applicable when you are working with the in-line markdown. Here is the screenshot with comparison.

Hit F5 and see the markdown tag helper in action. Below is the output I get.

This is the simplest of all. Now let’s add some prefix to our custom TagHelper. To add a custom tag prefix to the TagHelper, we just need to pay a visit to _ViewImports.cshtml file again and add a new line like so:

@tagHelperPrefix "blog-"

After adding the above line in the file, go to the view page where you have used your custom TagHelper and you can notice that the <markdown> tag isn’t purple anymore. This is because we now have to add a custom tag-prefix that we just defined in the _ViewImports.cshtml file. Change it from <markdown> to <blog-markdown> and it is purple again.

By design, the TagHelper will take <markdown> as a tag to be processed. But it can be easily ignored by using the HtmlTargetElement attribute at the top of the class and allow the use of another name rather than <markdown>. This does not mean that you cannot use <markdown> but instead you can also use the custom TagHelper with the name specify in this attribute.

Now let’s add some attributes to my markdown TagHelper. Let’s try to add a url attribute which will help user to render the markdown on the view from a remote site like Github. To add an attribute, simply add a new public property of type string and call it url. When you create a public property in the TagHelper class it is automatically assumed it is an attribute. To make use of this property, my view now simply say this:

<blog-markdown url="https://raw.githubusercontent.com/Knagis/CommonMark.NET/master/README.md">
</blog-markdown>

The url attribute value is being read by the TagHelper which in turn read the whole string of markdown from Github and render the HTML on the page. Let’s focus again on TargetElement attribute for a while. Consider a scenario where you don’t want your custom TagHelper to render or work if the attributes are not passed or missing. This is where HtmlTargetElement attribute comes into picture. If I don’t want my TagHelper to work if the url parameter is missing then you can simple write your HtmlTargetElement attribute like so:

[HtmlTargetElement("markdown", Attributes = "url")]

Notice the Attributes parameter. The Attributes parameter allows you to set the name of all the attributes which should be processed by your TagHelper or else the TagHelper will not work. For instance, if I just use the <markdown> TagHelper but did not pass the url attribute, the TagHelper will not execute and you will see the raw markdown code. My requirement is to have this TagHelper working with or without the use of url attribute. I can comment out or remove the HtmlTargetElemen attribute or just remove the Attributes parameter to get going.

Here is the complete MarkdownTagHelper.cs:

using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace WebApplication1.TagHelpers
{
    //[HtmlTargetElement("markdown", Attributes = "url")]
    public class MarkdownTagHelper : TagHelper
    {
        //Attribute for our custom markdown
        public string Url { get; set; }

        private string parse_content = string.Empty;

        //Stolen from: http://stackoverflow.com/questions/7578857/how-to-check-whether-a-string-is-a-valid-http-url
        private bool isValidURL(string URL)
        {
            Uri uriResult;
            return Uri.TryCreate(URL, UriKind.Absolute, out uriResult)
                && (uriResult.Scheme.ToLowerInvariant() == "http" || uriResult.Scheme.ToLowerInvariant() == "https");
        }

        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            if (context.AllAttributes["url"] != null)
            {
                string url = context.AllAttributes["url"].Value.ToString();
                string webContent = string.Empty;
                if (url.Trim().Length > 0)
                {
                    if (isValidURL(url))
                    {
                        using (HttpClient client = new HttpClient())
                        {
                            webContent = await client.GetStringAsync(new Uri(url));
                            parse_content = CommonMark.CommonMarkConverter.Convert(webContent);
                            output.Content.SetHtmlContent(parse_content);
                        }
                    }
                }
            }
            else
            {
                //Gets the content inside the markdown element
                var content = await output.GetChildContentAsync();

                //Read the content as a string and parse it.
                parse_content = CommonMark.CommonMarkConverter.Convert(content.GetContent());

                //Render the parsed markdown inside the tags.
                output.Content.SetHtmlContent(parse_content);
            }
        }
    }
}

I found the full TagHelper feature in MVC 6 a lot more convenient and powerful. I hope you like it as well.

 No Rating

Free E-Book: 52 Tips & Tricks to Boost .NET Performance from Redgate

26. November 2015 08:21

Musings  0 Comments

A super awesome free e-book from our friends at RedGate.

  • 52 tips from the .NET community for boosting performance in your applications.
  • Learn the secrets of your fellow developers and read advice from MVPs and other experts.
  • Covers .NET and ASP.NET, database access, memory usage, and more...

Download Now

 No Rating

Visit blogadda.com to discover Indian blogs Computers Blogs