Streaming Arduino Data to a Browser without Flash or Java

This post describes an older method for connecting sensors to a web browser. You can learn about a newer, more robust method using Web Bluetooth in this Under the Hood article from our fall 2017 @Concord newsletter.

Here at the Concord Consortium we are very interested in making sensors that are easy to use in the classroom or embedded directly into rich online curriculum. We’ve done some work in the past using applets as an intermediary to read data from commercial sensors and displaying them in lightweight graphs in the browser. When we think of fun, hackable, multi-probe sensors, though, we naturally think of Arduinos — we are open-source geeks after all.

In thinking of ways to display Arduino data in a browser with the minimum amount of fuss, we considered both our existing applet technique and using the new HID capabilities of the Arduino Unos. But while we will probably still find uses for both strategies, it occurred to Scott Cytacki, our Senior Developer, that we could simply use the common Ethernet Shields (or the new Arduino Ethernets) to send the data directly to the browser.

With this idea, it was quick work to hack the Arduino Server example to send JSON values of the analog pins and create a webpage that would rapidly poll the Arduino for data. So here is the first example that I wrote in about 70 lines of code (including the Arduino sketch) usable on any Ethernet-capable Arduino on any browser:

  1. Upload the tiny server sketch to your Arduino
  2. Plug in your ethernet shield, connect the Arduino to your computer with an ethernet cable and wait about 30 seconds for the Arduino server to boot up
  3. Optionally connect a sensor to pin A0. (The demo below is scaled for a L35 temperature sensor, but you don’t need it — you might need to rescale the graph by dragging on the axis to see the plot, though)
  4. Click the “Start Reading” button below

You should see your Arduino data filling up the graph. If not, wait another 20 seconds to ensure the server is fully booted and click the “play” button at the top right to start it again.

Wow, that was actually pretty easy!

I created the slightly more complicated example below reads data from all six analog pins, applies an optional conversion, and graphs any one of the data streams. If you were already reading data above, you don’t need to do anything new, just hit the button:

Direct link to stand-alone version

We think this is really cool, and we can’t wait to come up with new ways to integrate this into online content. Why not feed the temperature data into the HTML5 version of Molecular Workbench we’re developing under our new grant from Google.org, for instance, and see the atoms speed up as the temperature increases? Or set up an online classroom where students across the globe can take environmental readings and easily upload and pool their data?

Even by itself, the example above (perhaps expanded further by an interested reader) makes a great workbench for developing on an Arduino — much better than watching the raw Serial Out panel. And of course all the programming can happen in your friendly JavaScript environment, instead of needing to keep recompiling code and uploading it to your Arduino as you iterate.

Technical details:

  • This Arduino Sketch creates a server running on http://169.254.1.1, which is a private local IP that will automatically try to not conflict with other servers, allowing for easier connection without a DHCP server. The sketch then returns JSON data using the JSON-P technique of calling back a function, which allows us to make cross-domain requests.
  • Click on the tabs at the tops of the embedded jsFiddle examples to see the source code for streaming data to the webpage, or fork and edit any of the examples yourself.
  • The graphs are creating using D3.js, and make use of the simple-graph library created by Stephen Bannasch.

23 thoughts on “Streaming Arduino Data to a Browser without Flash or Java

  1. This is fantastic. The display you have designed looks really great. We have been working on developing open source hardware science instruments (probeware) for education with the Arduino and have been thinking along the same lines of using a web browser approach as well as a simple GUI. We hadn’t thought of using the Arduino ethernet shield though – this approach will make the Arduino even more accessible in the classroom.

  2. > James Bahr wrote:
    > Can this be used across the internet? Or is it restricted to local networks only?
    The simple server sketch linked above would only work connected directly to the computer, because it assignes itself a local IP, http://169.254.1.1.
    However, you can certainly just plug the Arduino into your router and change the IP settings in the sketch to make it accessible from the internet, but you would either need to use a static IP address or use DHCP to find a dynamic IP address. The problem with the latter option is that you would need to know the new IP address in order to connect to it, so this wouldn’t be an easy permanent solution, but would be suitable for testing.
    Once the Arduino is connected to the internet, it would work exactly as before, except that you probably wouldn’t be able to poll it several times a second as I do in the examples above, due to network latencies.
    There are a number of resources that can be found online for learning how to connect an Arduino to the internet, such as this one, and there’s a DHCP library for obtain network configurations.

  3. Great work this is a neat way to display data. But, (always a but) I want to make the data collection a remote self contained element, and use a wireless router to transmit the data. The setup I have now is a takeoff of one of the WEBDUINO examples. The only fault it has is having to redraw (reload) the page with each update. I plan to gather temperature data, digital states, and some data gathered from a CARRIER 4 zone HVAC control system, If there is info on how this can be accomplished, please let me know.
    Mike Brian

  4. > The only fault it has is having to redraw (reload) the page with each update.
    Using the JSON-P pattern above should make it possible for you to update the data without reloading the page each time.
    You can look at my library here: https://github.com/sfentress/ArduinoEthernetCom
    Or you can just update the sketch you are using to return data in a JSON-P format. The basic idea is simply that you load in the page from the Arduino as a new script and evaluate it with each update. When the script loads, it calls a method with all the updated data values.

  5. I have the data and will look at reworking my project as you suggested. The one important detail is using a wireless router.? Routers are so cheap these days it would seem a shame to not use them.

  6. what does it mean if i get this when browsing to the above mentioned IP address? I assume i actually do need a sd card plugged in?
    arduinoEthernetComCallback(‘{“A0″: 1023,”A1″: 718,”A2″: 543,”A3″: 468,”A4″: 358,”A5”: 324}’)

    1. Hi Andrew,
      That’s actually exactly what you would expect to see if you browse directly to the IP address that the Arduino-server is running on. The data is showing the actual voltage value (scaled from 0 to 1023) on each of the pins. You’ll notice that if you refresh the page, the numbers will change slightly, depending on if you have floating voltages.
      What the graph does, and the other examples above, is to very rapidly poll that page to get streaming data. This way you can have a graph or anything else on a webpage that uses real-time Arduino data. There is no need for an SD card.
      If you’re seeing that data when visiting the IP address, everything should be working, so try hitting the “Start” button on the second example above. You should see the data coming in and being graphed (although note that the scaling of the graph may be way off depending on what values you are getting).

  7. i not really understand the step.
    can you explain more detail? like explain step by step.
    after i follow the step u give below:
    [Upload the tiny server sketch to your Arduino
    Plug in your ethernet shield, connect the Arduino to your computer with an ethernet cable and wait about 30 seconds for the Arduino server to boot up
    Optionally connect a sensor to pin A0. (The demo below is scaled for a L35 temperature sensor, but you don’t need it — you might need to rescale the graph by dragging on the axis to see the plot, though)
    Click the “Start Reading” button below]
    but i cant get function
    it function.
    so is it need to make use of wampserver, download some plugin to support?

    1. Hi Jack,
      This demo does not need any other software running on your computer. It does require a modern browser, though — preferably Chrome or Firefox.
      Are you able to upload the sketch to your Arduino? And did you plug an Ethernet cable between the Arduino and your computer? Then did you turn the Arduino on and wait 30 seconds before pressing the “Start Reading” button?
      If, after 30 seconds, nothing shows when you press Start Reading, can you see anything at this link: http://169.254.1.1 (with the Arduino on and still plugged into your computer with the Ethernet cable)?

      1. >>I apologize for my mistake.
        >> before that i was connected to router but not computer.
        For connecting to computer is successfully.
        >>but now i got one question to ask .
        >> is it this thing can work with router?
        because recently i was work on router and ethernet shield. try to view the data over different network and monitor.

        1. Hi Jack,
          Great that you got it working!
          For connecting it to a router, take a look at my answer to James Bahr above. There are also a number of other pages on the web that discuss finding your Arduino across the network — it sounds like you were already doing some of that. You would need to change the sketch and change the code that finds the IP address, but the code that gets and draws the data can probably be the same.

  8. Hello I tried using the above method in polling for data from m web server but it didn’t really work. I created a webpage which has the java script data for getting the arduino data with the ip address and callback. The ip address outputs the data from the arduino similar to the one above but the webpage does not seem to poll the data from the arduino’s ip address using the json call back technique.

    1. Hi Michael,
      Did you try using your Arduino in the examples above, on this web page? Were you able to get it working here, before trying on your own site?
      I would trouble-shoot first by looking in the browser console. Do you see the request for data being made every 250ms? Does it return anything when it makes the request? If you go to http://169.254.1.1/ do you see the data?

  9. Hi,
    I am trying to get this to work for myself on XAMP, i am using your jsfiddle files and when i load the .html webpage the text and button gets loaded but the graph (.css) does not, it does not seem to load the graph file, what could i be doing wrong? very new to html and css so forgive me if its a silly question.
    Thanks

    1. Hi Mairtin,
      It looks like the reference to the graph script in the two examples was bad — GitHub changed the way you can refer to scripts directly (it has to be rawgithub.com/…, instead of raw.github.com/…). I have now fixed the reference to the graph script in the examples. Does it work for you now?

      1. Hi,
        I just changed it there but still doesnt work, but i think ive realized what is going wrong.
        I want to simulate what you have but the references are pointing to web pages and i am trying to simulate it on my own private network (arduino, router, and xamp on my pc) which is not connected to the internet.
        Can i just import the d3 and graph?if so which files should i import and what should my “src” be?
        Thanks

        1. Certainly if you are trying to do everything locally, with no connection to the internet, you’ll need to have all the files accessible locally. You could simply download d3.js and the other references.
          I would take it in smaller steps first, though. Are you able to get the data from the Arduino, ignoring the graph? You could use this example here, if it’s not immediately clear to you how to remove the graph: http://sfentress.github.io/ArduinoEthernetCom/example.html
          After you get that working locally, yes, you should just be able to copy all the resources, change the references to them as necessary, and it should all work locally.

        2. Also, if you’re unsure which files you need to create copies of: if you open the developer console (in Chrome: View->Developer->Developer Tools), click the Network tab, and reload the page, you should see all missing files in red. Find the files, place them in your local folder, and change the urls of the scripts in your local version.

          1. Hi,
            Thanks a million for the help, I had the example without the graph working.
            But what i did was i downloaded the d3.js and simple-graph.js and changed the src to the directory the files are in.
            And thanks for telling me about the developer tools i did not know it existed, im using firefox but its in the same place as chrome. It was showing up some errors in the simple-graph and it was was simply adding the src for jQuery and removing .svg’ from the ‘d3.svg.mouse’ in simple-graph and it works.
            Oh yea the graph was coming out with weird lines after above so i added the for the style sheet at the top and lines are perfect.
            P.S. Thought id add this description if any amature like myself is trying to do this as well.
            Thanks

  10. If you assign an address on your local IP range (often 192.168.1.x so maybe 192.168.1.111 easy to remember) and then forward this through your router. Most modern home routers make this really easy now, so follow their help page. Then either from the router or using “whats my ip” in google, find your public IP. Remember, if you turn off your router, your public IP will change!
    (there are methods for having pseudo static IPs too)
    You should look carefully at the security of making holes in your router. but this can be up and running and tested from your phone in less than five minutes. (turning LEDs on and off from your phone is endless fun!)
    Really nice article Sam.
    I’ve been playing with UDP and sending commands and data back and forward, I host host the webpage on a local PC. Using datagrams allows me to get data, and send data, i.e. change IPs etc. Very powerful, very subtle once the base code is in place. I use a database of commands to draw the web pages dynamically for each device, revealing only the available commands to the user.
    But I may employ your principles for a project at work in the server room.

Comments are closed.