I love it when a plan comes together

by david 3. September 2014 20:17

So recently, several of the different things I have been messing about with have come together. This was always in the back of my mind, but I didn't really know how long it was going to take. Recently, I have been working on:

  • building my own webserver (dweb)
  • cross-compiling for Linux on a TP-Link router (with OpenWrt)
  • ...and my own experimental programming language (H2D2)

Now I have bean able to bring all that together, what it means is that I can run H2D2 programs on my little TP-Link router. At the moment, I'm doing it through jQuery Ajax calls. So the programs are sent to the router with an HTTP POST from an ajax request, the router runs the program remotely and then returns the output back to the browser. Nice.

Here is a screenshot showing it all in action:

Woo-hoo... it works! Oh, and apologies for the partial ASCII Mandelbrot, I really can’t help it. The next experiment will probably be to do what H2D2 was actually designed for, namely to run a program partially on the router and then finish off the same program instance on some other platform. Then, I should be able to bounce a single program between the router, a Raspberry Pi and a desktop, which will be a neat trick.

Music by numbers - more notes

by david 31. August 2014 12:16

I blogged before about building a Raspberry Pi music player by numbers thingy and I said that I’d mention some more details about the software used. I did write up the notes, but then forgot to post it on the blog, so here goes, better late than never…

I had already mentioned the USB Message Board linux driver and the MP3 player that I used. The USB Message Board also requires the libusb-1.0-dev package to be installed, like this:

sudo apt-get install libusb-1.0-0-dev

But before I got that far, I needed an OS … and I wanted a version that wouldn’t corrupt the filesystem on the SD card if I just switched the power off at the mains. I have ended up running something called IPE - Industrial Perennial Environment of which I’m using the R1 edition, which is based on Raspbian. It seems to work a treat: I don’t need to worry about clean shutdowns, the filesystem runs in read-only mode. The R2 version of IPE looks even better, but for the time being I’ve stuck with the Raspbian derived version which is more familiar to me.

It goes without saying, that the webserver I used to provide the web-based API was my own dweb lightweight webserver which seems to have done the job very well.

I also wanted the Raspberry Pi to offer its own WiFi hotspot, for which I followed these instructions. After that I also followed this advice and disabled ifplugd for the wireless lan.

So … putting those things together and with a simple C program, I have:

  • a version of Raspbian which can be powered off without a safe shutdown
  • a Raspberry Pi which operates a WiFi hotspot with a DHCP server
  • an MP3 player which shows the track number on an LED display
  • a web based user interface and API

Normally, I just use Safari on my iPhone to call up a song over WiFi, but I added a numeric keypad as a backup, in case of WiFi interference or other problems. I’m sure that I could really go to town and make a much more complicated wireless MP3 player out of this … but what I have just seems to work perfectly, so at the moment I’m leaving it well alone.

Remoting into a Raspberry Pi

by david 9. June 2012 23:40

The little LCD TV I tested the Raspberry Pi with wasn't very good, so I wondered if it was possible to remote into the Raspberry Pi from another machine. I found that this is no problem when I looked here. So I tried the following commands:

sudo apt-get install tightvncserver
tightvncserver

...on the Raspberry Pi and it worked perfectly. Then with a copy of the TightVNC client running on my windows machine, I can access the Raspberry Pi remotely. This is awesome.

I used that approach to do more testing of my simple C# webserver, so here I am testing the webserver in TightVNC ... and also checking that the page is being served over my network to the PC in internet explorer:

...and finally, here is the Raspberry Pi serving the same test page to my iPhone:

OK, that all seems to work. I've just got to figure out what to do next now.

Unexpected Pi

by david 8. June 2012 22:13

A very kind colleague of mine has lent me his Raspberry Pi, so that I can have a little play with it. Here it is being hooked up on my workbench:

I used the standard Debian 'squeeze' image, since that's what I've been messing about with recently. After checking that I had internet access, I went off and installed the mono runtime, like this:

sudo apt-get update
sudo apt-get install mono-runtime

...after doing that I ran the C# webserver example that I had already written - and it works a treat! I didn't compile the code on the Raspberry Pi, I simply copied the exe file over and ran it with the mono command. The code was compiled in monodevelop running on Debian in VirtualBox.

Anyway, here is another photo, taken when I was first cheking that I could get online. Umm, I need to tidy up in here again.

More reports will follow I'm sure...

Raspberry Pi Preparations

by david 29. May 2012 22:46

I am currently in the queue to receive a Raspberry Pi. Apparently my machine is about 5 weeks away. So I have decided that I should begin making some preparations. I have downloaded an ISO image of Debian "squeeze" (the version with the LXDE desktop). So at least I should know my way round the OS in advance.

After installing the Debian ISO on a virtual machine, the first thing that I did was install the monodevelop IDE which I don't think will actually work on the Raspberry Pi ... but should enable me to try some things out and then just compile them from the command line on the Pi (hopefully).

Monodevelop seemed to work like a charm on Debian, so I grabbed my C# webserver example to try out some code.

Amazingly, the only real thing that I had to change was add the following delegate declaration:

public delegate TResult Func<in T1, out TResult>(T1 arg1);

...apart from that the code worked without any changes. Here is a screenshot of it all working:

So I am hopeful that I will be able to run my little slimline webserver on my Raspberry Pi when it arrives.

Simple C# Web Server

by david 1. April 2012 17:28

During my lunchbreak the other day I wondered how hard it would be to write a simple webserver in C#. Surely with all the toys in the .net framework these days it should be pretty easy? So I decided to give it a go and see what happens. The aim was to write a simple class that recieves a delegate to a method which is responsible for the page content, everything else could be taken care of by the class I'm writing. That way the server can serve whatever page(s) you like, but you just need to write a simple method that returns a string with some html in it. Of course, with this approach the HttpListener is our friend and does much of the hard stuff. Here it is in action running on my Iconia tablet:

The webserver running

It took me about 30 minutes to get it working. After taking the code home and tidying it up a bit, this is what now I have:

using System;
using System.Net;
using System.Threading;
using System.Linq;
using System.Text;
 
namespace SimpleWebServer
{
    public class WebServer
    {
        private readonly HttpListener _listener = new HttpListener();
        private readonly Func<HttpListenerRequeststring> _responderMethod;
 
        public WebServer(string[] prefixes, Func<HttpListenerRequeststring> method)
        {
            if (!HttpListener.IsSupported)
                throw new NotSupportedException(
                    "Needs Windows XP SP2, Server 2003 or later.");
 
            // URI prefixes are required, for example 
            // "http://localhost:8080/index/".
            if (prefixes == null || prefixes.Length == 0)
                throw new ArgumentException("prefixes");
 
            // A responder method is required
            if (method == null)
                throw new ArgumentException("method");
 
            foreach (string s in prefixes)
                _listener.Prefixes.Add(s);
 
            _responderMethod = method;
            _listener.Start();
        }
 
        public WebServer(Func<HttpListenerRequeststring> method, params string[] prefixes)
            : this(prefixes, method) { }
 
        public void Run()
        {
            ThreadPool.QueueUserWorkItem((o) =>
            {
                Console.WriteLine("Webserver running...");
                try
                {
                    while (_listener.IsListening)
                    {
                        ThreadPool.QueueUserWorkItem((c) =>
                        {
                            var ctx = c as HttpListenerContext;
                            try
                            {
                                string rstr = _responderMethod(ctx.Request);
                                byte[] buf = Encoding.UTF8.GetBytes(rstr);
                                ctx.Response.ContentLength64 = buf.Length;
                                ctx.Response.OutputStream.Write(buf, 0, buf.Length);
                            }
                            catch { } // suppress any exceptions
                            finally
                            {
                                // always close the stream
                                ctx.Response.OutputStream.Close();
                            }
                        }, _listener.GetContext());
                    }
                }
                catch { } // suppress any exceptions
            });
        }
 
        public void Stop()
        {
            _listener.Stop();
            _listener.Close();
        }
    }
}

All the work is done on background threads, which will be automatically cleaned up when the program quits.  Example use of this code is pretty simple, like this:

class Program
{
    static void Main(string[] args)
    {
        WebServer ws = new WebServer(SendResponse, "http://localhost:8080/test/");
        ws.Run();
        Console.WriteLine("A simple webserver. Press a key to quit.");
        Console.ReadKey();
        ws.Stop();
    }
 
    public static string SendResponse(HttpListenerRequest request)
    {
        return string.Format("<HTML><BODY>My web page.<br>{0}</BODY></HTML>"DateTime.Now);    
    }
}

I'm even considering using this code to build a little DALIS aware test server, so that I can run DALIS programs without hosting anything in IIS... even better I could run a couple of them and bounce DALIS programs between them.


EDIT:This little bit of code has proved quite popular, and recently I have been asked if it has been released under any particular license. Since it was such a small bit of code and just an evolution of the MSDN documentation found here, I didn't really think about a license for it. But I am happy to share this code, so to make the situation clear I'm releasing it under the MIT License.


PDP-11 webserver

by david 1. April 2011 22:39

I thought that the simplest application for my PDP-11 / WiFly combo would be to serve up some basic web pages.  So I've been tinkering around with some C code to make that work.  The HTTP protocol is not too hard once you get those CRLFs in the right places...  So here is a screenshot of my PDP-11 serving it's first webpage to my iPhone:

PDP serving webpage to iPhone

I'm pretty happy with that.  For the moment I'll ignore the fact that when you exit the webserver program it crashes RT-11.  I've probably made some stupid typo.  But whilst the program is running, it seems to work OK.  SMTP is next on my list, I want to send mail from my PDP.

About the author

David

I'm a C# developer having worked with .Net since it was in beta.  Before that I mainly worked in C and C++.  I have been developing commercial software for more than 20 years.  I also mess around with microprocesors, but that's just for fun.  I live near Cambridge, England and work for one of the departments at Cambridge University.

Tag cloud