Go Down

Topic: Arduino Mega JSON REST interfaces (for HTML GUIs) (Read 18534 times) previous topic - next topic


Oct 26, 2012, 11:57 am Last Edit: Jun 06, 2013, 09:13 pm by llukkari Reason: 1
I have been writing a paper for school about how JSON REST interfaces can be used to build HTML5 GUIs for microcontroller systems.

I mated two Arduino libraries Webduino and aJson and was able to create somewhat automatized  CRUD.

Online version of the paper can be found here:

I also made two examples.

A back-end for TodoMVC: https://github.com/lasselukkari/Todo

Weather Station:

The idea is that Arduino serves an index page that contains references to JavaScript and CSS that are loaded from another server:


Hi llukkari!

It seems very interresting. As soon as I'll have some spare time I'd like to try your code. Would it be possible to have an example about how to manage some of the PIN's status (something like ON/OFF).

Also, I'd want to ask you what do you think about using a database in the middle and just querying the database to show the status of the Arduino PIN's (the values and the status of the PIN's would be pushed into the database using 2 services: one on the arduino and one listener on the webserver that registers all into the DB at a predefined time range).

The use of the database will avoid "overloading" with requests the Arduino board


Would it be possible to have an example about how to manage some of the PIN's status (something like ON/OFF).

I have an 8-channel relay board and I have been planning to write an example how it could be used as a timer controlled by a web gui. I'll send you a pm once I get it done and uploaded to github.


Hi llukkari,

this sound really interesting, I've build something similar using the board just as AJAX/JSON server and loading the page locally from the device (smartphone or PC). The original files was attached in this post.

If you are planning to develop a web interface for a remote control of relays or similars, you may think about an integration with the home automation project Souliss, so that from a single point interface you may control many devices over your home. In the project there is now an Android interface.

If you are interested in, have a look at www.souliss.net or search for Souliss into that forum.


Souliss - Open-source Distributed Home Automation with Arduino and Android

Follow at @soulissteam



Would it be possible to have an example about how to manage some of the PIN's status (something like ON/OFF).

I have an 8-channel relay board and I have been planning to write an example how it could be used as a timer controlled by a web gui. I'll send you a pm once I get it done and uploaded to github.

Thanks a lot !!!


Dec 19, 2012, 10:44 am Last Edit: Dec 19, 2012, 01:07 pm by llukkari Reason: 1

Would it be possible to have an example about how to manage some of the PIN's status (something like ON/OFF).

I have an 8-channel relay board and I have been planning to write an example how it could be used as a timer controlled by a web gui. I'll send you a pm once I get it done and uploaded to github.

Thanks a lot !!!

I'm sorry that it has taken so long.

Here is a simple example how to control LOW/HIGH status of a pin.

Settings are saved after eatch change and loaded when the progrmam starts.

Source: https://github.com/lasselukkari/PinToggle/blob/master/pintoggle.ino
Code: [Select]

#include "SPI.h"
#include "Ethernet.h"
#include "SD.h"
#include "aJSON.h"
#include "WebServer.h"

//define range of pins you want to control
#define FROM_PIN 55
#define TO_PIN 58

byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };

WebServer webserver("", 80);
aJsonObject* pins;
File file;

void indexCmd(WebServer &server, WebServer::ConnectionType type, char *, bool) {
if (type != WebServer::HEAD) {
P(helloMsg) =
"<!DOCTYPE html>\n<html lang=\"en\">\n"
"\t<meta charset=\"utf-8\">\n"
"\t<title>Pin Toggle</title>\n"
"\t<link href=\"http://www.cs.helsinki.fi/u/ljlukkar/pincontrol/css/style.css\" rel=\"stylesheet\">\n"
"\t<link href=\'http://fonts.googleapis.com/css?family=Open+Sans+Condensed:700,300\' rel=\'stylesheet\' type=\'text/css\'/>\n"
"<div class=\"container\">\n"
"\t<div id=\"pin-list\">\n"
"<script src=\"http://www.cs.helsinki.fi/u/ljlukkar/pincontrol/js/jquery.min.js\"></script>\n"
"<script src=\"http://www.cs.helsinki.fi/u/ljlukkar/pincontrol/js/lodash.min.js\"></script>\n"
"<script src=\"http://www.cs.helsinki.fi/u/ljlukkar/pincontrol/js/lib/backbone-min.js\"></script>\n"
"<script src=\"http://www.cs.helsinki.fi/u/ljlukkar/pincontrol/js/models/pin.js\"></script>\n"
"<script src=\"http://www.cs.helsinki.fi/u/ljlukkar/pincontrol/js/collections/pins.js\"></script>\n"
"<script src=\"http://www.cs.helsinki.fi/u/ljlukkar/pincontrol/js/views/pins.js\"></script>\n"
"<script src=\"http://www.cs.helsinki.fi/u/ljlukkar/pincontrol/js/views/app.js\"></script>\n"
"<script src=\"http://www.cs.helsinki.fi/u/ljlukkar/pincontrol/js/app.js\"></script>\n</body>\n"

// this method is performed before the reguest is prosessessed and default responce is generated
// server.setPreventDefault(true); disables the default prosessing and responce once
void switchBeforeResposeCmd(WebServer &server, WebServer::ConnectionType type, char * tail, bool tailComplete,
aJsonObject ** collection, aJsonObject ** model) {
if (type == WebServer::PUT) {
if (model != NULL) {
pinMode(aJson.getObjectItem(*model, "pin")->valueint, (bool) aJson.getObjectItem(*model, "low")->valuebool);


// this method is performed after the responce is sent so it doens't block it anymore
void switchAfterResposeCmd(WebServer::ConnectionType type, aJsonObject ** collection, aJsonObject ** model) {
pinMode(53, OUTPUT);

if (SD.exists("pin.txt")) {

file = SD.open("pin.txt", FILE_WRITE);
aJson.print(&**collection, file);

void setup() {
pinMode(53, OUTPUT);

if (!SD.begin(4)) {
Serial.println("SD initialization failed!");

if (SD.exists("pin.txt")) { //load settings file if found
file = SD.open("pin.txt");
pins = aJson.parse(file);

aJsonObject* current = pins->child;

while (current) {
pinMode(aJson.getObjectItem(current, "pin")->valueint,
(bool) aJson.getObjectItem(current, "low")->valuebool);
current = current->next;

} else { //if not found populate dta
pins = aJson.createArray();

for (int i = FROM_PIN; i < TO_PIN + 1; i++) {
pinMode(i, LOW);
pinMode(i, OUTPUT);
aJsonObject* pin = aJson.createObject();
aJson.addItemToObject(pin, "id", aJson.createItem(i - FROM_PIN + 1));
aJson.addItemToObject(pin, "pin", aJson.createItem(i));
aJson.addItemToObject(pin, "low", aJson.createItem(false));
aJson.addItemToArray(pins, pin);

//add binding to webserver and set actions
webserver.addJSONBinding("pins", &pins);
webserver.setBeforeRequest("pins", &switchBeforeResposeCmd);
webserver.setAfterRequest("pins", &switchAfterResposeCmd);



for (byte i = 0; i < 4; i++) {
if (i < 3) {

void loop() {

Dummy UI: http://www.cs.helsinki.fi/u/ljlukkar/pincontrol/


Jan 05, 2013, 01:45 pm Last Edit: Jan 05, 2013, 06:07 pm by llukkari Reason: 1
I made a another example.

This time the UI is controlling RC switches like these:


  • Controll cheap 433mHz AC switches with arduino and web UI

  • No computer needed as a mediator

  • Multipurpose JSON REST interface

  • Teach devices to arduino by pushing the remote controller buttons

  • Remote controller actions are tracked by the arduino

  • Timers

  • Settings saved to a SD card

Dummy test UI: http://www.cs.helsinki.fi/u/ljlukkar/rcswitch



Hi llukkari,

I am trying to do a project very similar to your weather station project.  However I do not have access to a remote server that can host css or javascript. 

My project box will be located in some remote wooded areas that do not have cell phone coverage or internet access.  The project box has an Arduino, Ethernet shield and a wifi router used to create a local network.  My project would require the javascript files for graphing to be hosted on the Arduino.

Have you tried to do this project with the css and javascript files embedded on the arduino somehow?  Do you have any suggestions on how that might be done?




I understand you will have a local network, and that the Arduino is connected to this via WiFi?

On this local network do you have a file server, maybe even a NAS hard drive (networked hdd)?
If so, then you can store your javascript and css files on this.
In your index html fie on your Arduino, just point to those as external resources.

Or if you have a local web server, then you can set it up to serve from there and have the client request data direct from the Arduino or have the Arduino push data to the server database.

I haven't had the Arduino serve up files such as html, css or js from the onboard SD card, but I believe it can be done albeit slowly and some care is needed around how you do this.

There are many ways to do this, so hopefully one of these ways might provide you with an idea.
Keep us informed if you can, I'd like to see how you progress.

Take a look at my site, in my signature. I am actively developing it at present, up until 2:30am this morning working out SQL commands.

Kind regards,


Files can be served off of an SD card like below, including picture and .js files. Not terribly fast, but so far seems to work.

Code: [Select]

//zoomkat 1/25/13
//SD server slider test code
//open serial monitor to see what the arduino receives
//address will look like when submited
//for use with W5100 based ethernet shields
//put the servosld.htm, slider.js, bluev_sl.gif,
//and bluev_bg.gif on the SD card
//files at http://web.comporium.net/~shb/servoslider.htm page

#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = {
  192, 168, 1, 102 }; // ip in lan
byte gateway[] = {
  192, 168, 1, 1 }; // internet access via router
byte subnet[] = {
  255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port
String readString;


void setup(){


  // disable w5100 while setting up SD
  Serial.print("Starting SD..");
  if(!SD.begin(4)) Serial.println("failed");
  else Serial.println("ok");

  Ethernet.begin(mac, ip, gateway, gateway, subnet);



void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {
          //store characters to string
          readString += c;
        //if HTTP request has ended
        if (c == '\n') {

          Serial.println(readString); //print to serial monitor for debuging

          client.println("HTTP/1.1 200 OK"); //send new page
          if(readString.indexOf("servosld") >=0) {
          client.println("Content-Type: text/html");
          client.println(); }

          if(readString.indexOf("slider") >=0) {
          client.println("Content-Type: application/x-javascript");
          client.println(); }
          if(readString.indexOf("bluev") >=0) {
          client.println("Content-Type: image/gif");
          client.println(); }

          if(readString.indexOf("servosld") >=0) {
            File myFile = SD.open("SERVOSLD.HTM");
            if (myFile) {
              while (myFile.available()) {

          if(readString.indexOf("slider") >=0) {
            File myFile = SD.open("slider.js");
            if (myFile) {
              while (myFile.available()) {

          if(readString.indexOf("bluev_sl") >=0) {
            File myFile = SD.open("bluev_sl.gif");
            if (myFile) {
              while (myFile.available()) {

          if(readString.indexOf("bluev_bg") >=0) {
            File myFile = SD.open("bluev_bg.gif");
            if (myFile) {
              while (myFile.available()) {

          //stopping client


Google forum search: Use Google Search box in upper right side of this page.
Why I like my 2005 Rio Yellow Honda S2000  https://www.youtube.com/watch?v=pWjMvrkUqX0


Jan 26, 2013, 11:45 am Last Edit: Jan 26, 2013, 12:24 pm by llukkari Reason: 1

Hi llukkari,

Have you tried to do this project with the css and javascript files embedded on the arduino somehow?  Do you have any suggestions on how that might be done?


You could probably use the sd card. In my hydrobot project, http://www.cs.helsinki.fi/u/ljlukkar/hydrobot/,  I was able to use quite large csv files. I can't see any reason why it wouldn't work for other files as well.

You should try to set the http Cache-Control header so that the browser caches the responce and doesn't request it again.

Backbone.js, the MV* framework I have used in all the examples, is one of the most light weight out of them all.


Hi,  I really am interested in your hydrobot project.  Will you be posting the code for that.  I want to attemt to use it in my system.


Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131