/arduino-api

Arduino library for real-time logging and streaming data to online plotly graphs

Primary LanguagePython

Real-time Graphing and Data Logging

The easiest and fastest way to plot and share data on the Arduino.

Real-time Plotting with Arduino and Plotly

Plotly's Arduino libraries connects Arduinos to plotly's beautiful online graphing tool for real-time, interactive data logging and graphing. It's free, open source, and your graphs and data are entirely online.

Here is an example of a real-time graph: http://plot.ly/~streaming-demos/6/

Super easy

#include <WiFi.h>
#include <plotly_wifi_streaming.h>

#define num_traces 2
// Sign up to plotly here: https://plot.ly
// View your API key and stream tokens in your settings: https://plot.ly/settings
char *streaming_tokens[num_traces] = {"your_plotly_stream_token", "another_plotly_stream_token"};
plotly graph = plotly("your_plotly_username", "your_plotly_api_key", streaming_tokens, "your_plotly_filename", num_traces);

void setup() {

  Serial.begin(9600);

  wifi_connect();

  // Initialize a streaming graph in your plotly account
  graph.init();
  // Initialize plotly's streaming service
  graph.openStream(); 
}

void loop() {
  // now let's stream data to plotly, giddyup!
  graph.plot(millis(), analogRead(A0), tokens[0]);
  graph.plot(millis(), analogRead(A1), tokens[1]);
}

5 Minute Quickstart

If you're working on the Yún, click on the plotly_yun folder for separate instructions.

If you're device isn't internet connected, you can still connect to plotly over serial. Click on the plotly_streaming_serial folder for separate instructions.

  1. Sign up to plotly: https://plot.ly.

  2. Download and uncompress the latest plotly release: https://github.com/plotly/arduino-api/releases.

  3. Place the appropriate library your Arduino libraries folder. On a Mac, this is in ~/Documents/Arduino/libraries/:

  4. Open up the Arduino IDE. If your using WiFi and haven't upgraded your firmware, use the IDE version 1.0.3.

  5. Load up one of the examples from this repository. Fill in your plotly username, API key, stream tokens, and filename. You can find your API key and stream tokens here: https://plot.ly/settings. It'll look something like:

    char *tokens[] = {"ab4kf5nfdn","kdf5bn4dbn"};
    plotly graph("anna.lyst","ab4kftunvd", tokens, "arduino graph");

    (those are fake keys and tokens)

  6. Upload the program.

  7. Open up your Serial Monitor. You'll see an output like:

    ... Attempting to connect to WPA network...
    ... Connected to network
    ... Attempting to connect to plotly's REST servers
    ... Connected to plotly's REST servers
    ... Sending HTTP Post to plotly
    ... Sent message, plotly's response:
    ... A-ok from plotly, All Streams Go!
    ... View your streaming plot here: https://plot.ly/~streaming-demos/6
    ... Connecting to plotly's streaming servers...
    ... Connected to plotly's streaming servers
    ... Initializing stream
    ... Done initializing, ready to stream!
    
  8. Grab the URL that was printed out, view your graph in your browser, and celebrate! The graph and data is saved in your plotly account, so you can view it in your plotly file list here: https://plot.ly/plot. You can view, edit, and share your graphs while data is streaming to them in real-time. Everybody that views the graph will see the exact same data at the same time (try it out yourself: open your graph in two different browser windows).

Usage and Docs

Usage, Your Data Rights, and Private Graphs

When you make a graph on plotly, you retain the rights to your content (see our terms here). You also control whether your graphs are public or private. Public plotting is free; for a lot of private use, you can get a Premium or Organizational plan (see http://plot.ly/plans). It's just like GitHub.

By default, anyone can view the graphs at the unique URL. To make the graphs private, so that only you can see them when your logged in, set world_readable to false:

  plotly graph = plotly("your_plotly_username", "your_plotly_api_key", streaming_tokens, "your_plotly_filename", num_traces);
  graph.world_readable = false;

Time stamping

By default, plotly assumes that x is millis() and automatically converts the x to a real-time timestamp with the timezone "America/Montreal" on the server. To disable this, set convertTimestamp to false, e.g.

  plotly graph = plotly("your_plotly_username", "your_plotly_api_key", streaming_tokens, "your_plotly_filename", num_traces);
  void setup(){
    graph.convertTimestamp = false;
  }

To change the timezone, set timeZone to one of the strings in here: Accepted Timezone Strings.txt, e.g.

  plotly graph = plotly("your_plotly_username", "your_plotly_api_key", streaming_tokens, "your_plotly_filename", num_traces);
  void setup(){
    graph.timezone = "Africa/Abidjan";
  }

Adjusting the number of points plotted at a time

By default, your real-time graph will graph the 30 most recent points at a time. To adjust this, set the member variable maxpoints to something else, e.g.

  plotly graph = plotly("your_plotly_username", "your_plotly_api_key", streaming_tokens, "your_plotly_filename", num_traces);
  void setup(){
    graph.maxpoints = 200;
  }

Editing the live graph

Plotly graphs can be edited while data is streaming to them. Every aspect of the graph is configurable: you can add a second y-axis, turn the graphs into subplots, change the colors, update the title, change the chart type, etc. To get started, just open up the graph in your list of files here: https://plot.ly/plot or click Save and Edit on the public view of your graph that the serial monitor printed out (e.g. http://plot.ly/~streaming-demos/6/).

Multiple Viewers

Everybody who looks at your streaming graph sees the exact same data, at the exact same time. Give it a try yourself: open up a graph in two different browser windows.

Overwriting or Appending Data

By default, the initialization of your graph (graph.init();) overwrites the existing graph with your new data. This is the perfect option for development: when you re-run your script, a fresh new graph is created. However, when you run your Arduino for an extended period of time, the Arduino may reset itself, which would in turn reset the graph and remove the existing data. To prevent this from happening, you can use the fileopt "extend", which will append your new data to the existing data in the graph.

So, for running your Arduino for a very long time, you should add

graph.fileopt = "extend"; // Remove this if you want the graph to be overwritten on initialization

to your setup() loop, i.e.

void setup() {
  Serial.begin(9600);

  startEthernet();

  bool success;
  graph.maxpoints = 500;
  graph.fileopt = "extend"; // Remove this if you want the graph to be overwritten
  success = graph.init();
  while(!success){
    Serial.println(F("Error initializing graph, trying again."));
    delay(5000);
    success = graph.init();
  }
  graph.openStream();
}

Logging and Debugging

The parameter log_level sets how debugging information is printed out over serial. For troubleshooting, set log_level to 0, i.e.

void setup(){
  Serial.begin(9600);
  startEthernet();
  
  graph.log_level = 0;
  
  success = graph.init();
  if(!success){while(true){}}
  graph.openStream();
}

Set log_level to 4 if you want nothing to be printed out on serial.

Docs

class plotly(char *username, char *api_key, char* stream_tokens[], char *filename, int nTraces);

Public Member Functions

  • bool plotly.init()

    Creates an empty graph in your plotly account that will get streamed to. This is done by making an API call to plotly's REST service. Returns true if initialization was successful, false otherwise.

  • void plotly.openStream()

    Opens a TCP connection to plotly's streaming service. The stream is uniquely identified by the stream_tokens.

  • void plotly.closeStream()

    Closes the TCP connection to plotly's streaming service.

  • void plotly.reconnectStream()

    Reopens the connection to plotly's streaming service if not connected.

  • void plot(unsigned long x, int y, char *token)

    Plots (x, y) to the streaming graph.

  • void plot(unsigned long x, float y, char *token)

    Plots (x, y) to the streaming graph.

Public Member Parameters

  • int plotly.log_level (Default 2)

    Determines which messages are printed over serial. Levels are:

    • 0: Debugging
    • 1: Informational
    • 2: Status
    • 3: Errors
    • 4: Quiet
  • bool plotly.dry_run

    If True, then no calls are made to Plotly's servers.

  • int plotly.maxpoints (Default 30)

    Determines the number of points to plot at a time. Valid from 1 to 200000.

  • bool plotly.convertTimestamp (Default true)

    If true, the Plotly assumes that x is milliseconds since program start (millis()) and automatically converts these values into a timestamp.

  • char *plotly.timeZone (Default: "America/Montreal")

    The timezone to convert the timestamps if plotly.convertTimestamp=true. A list of the accepted timezones are in this repo: Accepted Timezone Strings.txt

  • bool plotly.world_readable (Default: true)

    If true, then your graph is publicly viewable and discoverable by unique url. If false, then only you can view the graph.

  • char *plotly.fileopt (Default "overwrite")

    Either "extend" or "overwrite".

    If "overwrite", then when the graph is initialized (during plotly.init()), the existing graph is overwritten with a new one. This means that the existing data in the graph will be removed. This option is good for development, when you want a fresh graph to appear everytime you run your script.

    If "extend", then the existing data is kept when the graph is initialized (during plotly.init()), and the new data is appended onto the existing data. This option is good for when you are running your device for an extended period of time, for if the Arduino resets (which may happen every few hours) then the existing data in the graph is not removed.

Projects

Contributing Notes

The wifi, ethernet, gsm, and cc3000 libraries and examples are 95% identical and so are automatically generated from template files in the plotly_dev folder. We use Mako, one of Python's templating libraries to generate these files. To run, do:

$ python render.py

Get in touch