Code Monkey home page Code Monkey logo

arduino-plotter's Introduction

arduino-plotter

arduino-library-badge

Plotter is an Arduino library for easy graphing on host computer via serial communication


Features:

  • Continuous multi-variable plots against time
  • 2-variable "x" vs "y" plots
  • Display multiple graphs within single resizable window
  • Support for any data type that can be cast to a double
  • Simply pass a reference to your variables when the graph is added, no need to update each value explicitly
  • Control number of data points displayed on each graph
  • Auto-scaling to fit all data on graph
  • Configurable line color per variable
  • Stand-alone listener application, written with Processing, is provided

Plotter Preview


Extremely easy usage:

#include "Plotter.h"

double x; // global variables
Plotter p; // create plotter

void setup()
{
  p.Begin(); // start plotter
  
  p.AddTimeGraph( "Some title of a graph", 1500, "label for x", x ); // add any graphs you want
}

void loop()
{
  x = 10*sin( 2.0*PI*( millis() / 5000.0 ) ); // update your variables like usual

  p.Plot(); // plot all current data -- usually called within loop()
}

See the Wiki for more information:

Home
Quickstart
Documentation

arduino-plotter's People

Contributors

cjuette avatar devinaconley avatar per1234 avatar robbertkl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

arduino-plotter's Issues

enhancement / recording data to text file for further analysis

Hello @devinaconley
I modified your "listener" source code attached below to be able, by pressing the space key, to toggle time-stamped recording of all variables on hard disk, in a date&time-stamped CSV - text file. first line gives the names of the variables stored in the file.
rgds

/*

This listener is the main processing script that corresponds to the Arduino Plotter
library for Arduino. This driver script handles serial port information and manages a
set of Graph objects to do the actual plotting.

The library stores and handles all relevant graph information and variable references,
and transfers information via the serial port to a listener program written with the
software provided by Processing. No modification is needed to this program; graph placement,
axis-scaling, etc. are handled automatically.
Multiple options for this listener are available including stand-alone applications as well
as the source Processing script.

The library, these listeners, a quick-start guide, documentation, and usage examples are
available at:

https://github.com/devinaconley/arduino-plotter


Arduino Plotter Listener Modified PhDV61 : On-off recording in a text file for excel off-line analysis)
v2.2.1
https://github.com/devinaconley/arduino-plotter
by Devin Conley

*/

import processing.serial.*;
import java.util.Map;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

// FLAG FOR DEBUG MODE
final boolean DEBUG = false;

//CONSTANTS
final char OUTER_KEY = '#';
final int MARGIN_SZ = 20; // between plots
final int BG_COL = 75; // background
final int PORT_INTERVAL = 5000; // time to sit on each port
final int CONNECT_TIMEOUT = 2000; // force timeout on connecting to serial port
final int BAUD_RATE = 115200;

final HashMap<String, Integer> COLORMAP = new HashMap<String, Integer>()
{
{
put( "red", color( 255, 0, 0 ) );
put( "green", color( 0, 255, 0 ) );
put( "blue", color( 0, 0, 255 ) );
put( "orange", color( 255, 153, 51 ) );
put( "yellow", color( 255, 255, 0 ) );
put( "pink", color( 255, 51, 204 ) );
put( "purple", color( 172, 0, 230 ) );
put( "cyan", color( 0, 255, 255 ) );
}
};

// Setup and config Globals
int h;
int w;
int numGraphs;
String configCode = "This will not be matched!";
String lastLabels = "Also will not be matched";
boolean configured = false;
int lastConfig;
int lastPortSwitch;
int portIndex;
Serial port;
ArrayList graphs;

// variables to create file name, and manage recording ( see keypressed at the bottom ). The space bar will toggle ON-OFF simultaneous recording in a text file during graph display
PrintWriter output;
int d = day(); // Values from 1 - 31
int m = month(); // Values from 1 - 12
int y = year(); // 2003, 2004, 2005, etc.
int sec = second(); // Values from 0 - 59
int min = minute(); // Values from 0 - 59
int hr = hour(); // Values from 0 - 23
boolean Recording=false; // We do NOT record initially. Only pressing the space bar will toggle recording. Esc to get out will flush the outstanding data to file.

void setup()
{
// Canvas
size( 1430, 830 );
surface.setResizable( true );
h = height;
w = width;
frameRate(20); // 20 (50ms) instead of 50 frames/s = 4ms

// Serial comms
while ( Serial.list().length < 1 )
{
text( "No serial ports available. Waiting...", 20, 20 );	
delay( 100 );
}
portIndex = 0;
lastPortSwitch = millis();
attemptConnect( portIndex );

// creating a "time-stamped" file name  : "listeneryyyy-mm-dd hh.mm.ss.txt" including a full date to be able to recover files easilyt later...
String sd = str(y) + "-" + nf(m,2) + "-" + nf(d,2) + " " + nf(hr,2) + "." + nf(min,2) + "." + nf(sec,2);
output = createWriter("listener"+sd+".txt"); 
output.print(" time(ms), "); // Write the legend to the first line of text file

}

void draw()
{
//PLOT ALL
try
{
background( BG_COL );

if ( configured )
{	    
    for( int i = 0; i < graphs.size(); i++ )
    {
	graphs.get(i).Plot();
    }
}
else
{
  // Continue to scan ports if not configuring
    text( "Scanning serial ports... (" + Serial.list()[portIndex] + ")", 20, 20 );
    
    if ( millis() - lastPortSwitch > PORT_INTERVAL )
    {	// Go to next port		
	portIndex++;
	if ( portIndex >= Serial.list().length )
	{
	    portIndex = 0;
	}
	
	logMessage( "Trying next port... index: " + portIndex + ", name: " + Serial.list()[portIndex],
		    true );
	
	attemptConnect( portIndex );
    }
}
// Resize if needed
if ( h != height || w != width)
{
    h = height;
    w = width;
    float[][] posGraphs = setupGraphPosition( numGraphs );
    for ( int i = 0; i < numGraphs; i++ )
    {
	graphs.get(i).Reconfigure( posGraphs[i][0], posGraphs[i][1], posGraphs[i][2], posGraphs[i][3] );
    }
}
}
catch ( Exception e )
{}

}

void serialEvent( Serial ser )
{
// Listen for serial data until #, the end of transmission key
try
{
String message = ser.readStringUntil( OUTER_KEY );
if ( message == null || message.isEmpty() || message.equals( OUTER_KEY ) )
{
return;
}

JSONObject json = parseJSONObject( message );

if ( json == null )
{
    return;
}		

// ********************************************************* //
// ************* PLOT SETUP FROM CONFIG CODE *************** //
// ********************************************************* //

String tempCode = "";
boolean config = false;
if ( json.hasKey( "ng" ) && json.hasKey( "lu" ) )
{
    tempCode = Integer.toString( json.getInt( "ng" ) ) + Integer.toString( json.getInt( "lu" ) );
    config = true;
}

// If config code has changed, need to go through setup again
if ( config && !configCode.equals( tempCode ) )
{
    lastPortSwitch = millis(); // (likely on the right port, just need to reconfigure graph layout)
    
    // Check for size of full transmission against expected to flag bad transmission
    numGraphs = json.getInt( "ng" );
    
    JSONArray jsonGraphs = json.getJSONArray( "g" );
    
    if ( jsonGraphs.size() != numGraphs )
    {
	return;
    }

    configured = false;
    String concatLabels = "";
    
    // Setup new layout
    float[][] posGraphs = setupGraphPosition( numGraphs );
  
    graphs = new ArrayList<Graph>();
  
    // Iterate through the individual graph data blocks to get graph specific info
    for ( int i = 0; i < numGraphs; i++ )
    {
	JSONObject g = jsonGraphs.getJSONObject( i );
	
	String title = g.getString( "t" );
	boolean xvyTemp = g.getInt( "xvy" ) == 1;
	int maxPoints = g.getInt( "pd" );
	int numVars = g.getInt( "sz" );
	String[] labelsTemp = new String[numVars];
	int[] colorsTemp = new int[numVars];

	concatLabels += title;

	JSONArray l = g.getJSONArray( "l" );
	JSONArray c = g.getJSONArray( "c" );

	for ( int j = 0; j < numVars; j++ )
	{   
	    labelsTemp[j] = l.getString( j );
    output.print(labelsTemp[j]); // Write the legend to the first line of text file
    if (j < numVars-1)  output.print(", ");
	    colorsTemp[j] = COLORMAP.get( c.getString( j ) );
	    if ( colorsTemp[j] == 0 )
	    {
		logMessage( "Invalid color: " + c.getString( j ) + ", defaulting to green.", true );
		colorsTemp[j] = COLORMAP.get( "green" );
	    }
	    concatLabels += labelsTemp[j];
	}

output.println("");

	if ( xvyTemp )
	{
	    numVars = 1;
	}
	
	// Create new Graph
	Graph temp = new Graph( this, posGraphs[i][0], posGraphs[i][1], posGraphs[i][2], posGraphs[i][3],
				xvyTemp, numVars, maxPoints, title, labelsTemp, colorsTemp );
	graphs.add( temp );
    }
    
    // Set new config code
    if ( concatLabels.equals( lastLabels ) ) // Only when we're sure on labels
    {
	configCode = tempCode;
	lastConfig = millis();
	logMessage( "Configured " + graphs.size() + " graphs", false ); 
    }
    lastLabels = concatLabels;
    logMessage( "Config code: " + configCode + ", Label config: " + concatLabels, true );
}
else
{
    // Matching a code means we have configured correctly
    configured = true;
      
    // *********************************************************** //
    // ************ NORMAL PLOTTING FUNCTIONALITY **************** //
    // *********************************************************** //
    int tempTime = json.getInt( "t" );
  
    JSONArray jsonGraphs = json.getJSONArray( "g" );

    for ( int i = 0; i < numGraphs; i++ )
    {
    	JSONArray data = jsonGraphs.getJSONObject( i ).getJSONArray( "d" );
	    double[] tempData = new double[ data.size() ];

    if (Recording) output.print(millis() + ", ");
	    // Update graph objects with new data
	    for ( int j = 0; j < data.size(); j++ )
	    {
	    tempData[j] = data.getDouble( j );
    if (Recording)  
      {
       output.print(str((float)tempData[j]));
       if (j < data.size()-1)  output.print(", ");
      } 
	    }
	    graphs.get( i ).Update( tempData, tempTime );
    if (Recording) output.println("");
    }

 }
}

catch ( Exception e )
{
logMessage( "Exception in serialEvent: " + e.toString(), true );
}

}

// Helper method to calculate bounds of graphs
float[][] setupGraphPosition( int numGraphs )
{
// Determine orientation of each graph
int numHigh = 1;
int numWide = 1;
// Increase num subsections in each direction until all graphs can fit
while ( numHigh * numWide < numGraphs )
{
if ( numWide > numHigh )
{
numHigh++;
}
else if ( numHigh > numWide+1 )
{
numWide++;
}
else if ( height >= width )
{
numHigh++;
}
else
{
// Want to increase in high first
numHigh++;
}
}

float[][] posGraphs = new float[numGraphs][4];

float subHeight = round( h / numHigh );
float subWidth = round( w / numWide );

// Set bounding box for each subsection
for(int i = 0; i < numHigh; i++)
{
for (int j = 0; j < numWide; j++)
{
    int k = i * numWide + j;
    if ( k < numGraphs )
    {
	posGraphs[k][0] = i*subHeight + MARGIN_SZ / 2;
	posGraphs[k][1] = j*subWidth + MARGIN_SZ / 2;
	posGraphs[k][2] = subHeight - MARGIN_SZ;
	posGraphs[k][3] = subWidth - MARGIN_SZ;
    }
}
}

return posGraphs;

}

void attemptConnect( int index )
{
// Attempt connect on specified serial port
if ( index >= Serial.list().length )
{
return;
}
String portName = Serial.list()[portIndex];
logMessage( "Attempting connect on port: " + portName, false );

// Wrap Serial port connect in future to force timeout
ExecutorService exec = Executors.newSingleThreadExecutor();
Future<Serial> future = exec.submit( new ConnectWithTimeout( this, portName, BAUD_RATE ) );    

try
{
// Close port if another is open
if ( port != null && port.active() )
{
    port.stop();
}

// Do connect with timeout
port = future.get( CONNECT_TIMEOUT, TimeUnit.MILLISECONDS );

lastPortSwitch = millis(); // at end so that we try again immediately on invalid port
logMessage( "Connected on " + portName + ". Listening for configuration...", false );
}
catch ( TimeoutException e )
{
future.cancel( true );
logMessage( "Timed out.", true );
}
catch ( Exception e )
{
logMessage( "Exception on connect: " + e.toString(), true );	
}

exec.shutdownNow();

}

// Callable class to wrap Serial connect
class ConnectWithTimeout implements Callable
{
private final PApplet parent;
private final String portName;
private final int baudRate;

public ConnectWithTimeout( PApplet parent, String portName, int baud )
{
this.parent = parent;
this.portName = portName;
this.baudRate = baud;
}

@Override
public Serial call() throws Exception
{
return new Serial( this.parent, this.portName, baudRate );
}     

}

// Logger helper
void logMessage( String message, boolean debugOnly )
{
if ( DEBUG || !debugOnly )
{
String level = debugOnly ? "DEBUG" : "STATUS";
println( "[Time: " + millis() + " ms]" + "[" + level + "] " + message );
}
}

void keyPressed() {
if (key==ESC) // to exit listener
{
output.flush(); // Writes the remaining data to the file
output.close(); // Finishes the file
exit(); // Stops the program
}
else if (key==' ') // to toggle record - otehr keys can be implemented to do other things
Recording=!Recording;
}

Unable to locate Plotter.h when running on RPI

When attempting to run the plotter on a Raspbian RPI 3 the Arduino IDE keeps returning an Error compiling message. Claiming that it is unable to locate "Plotter.h", saying that there is no such file or directory and terminating the program. Any help in resolving this issue would be greatly appreciated.

Listener opens just a grey screen

Hi, just found out your code. It seems awesome! The only issue is that it doesnt work for me.

I'm using a Windows 10 machine with Arduino IDE 1.8.13 and an arduino uno.

At first I thought that I was messing something up on my code, but then i tried using the "quick_start" example and its the same.
The listener exe opens but I can only see the whole window in a light grey color. Tried running it as an admin and nothing changes.

I unistalled my java and then reinstalled and nothing.

Thanks!

Captura de pantalla 2021-04-16 141415

Document serialization format

Hey, it would be awesome if there was a short wiki page on the serialization format so one could write a different frontend (e.g. browser based). Thanks for your work!

Fixed axis limits and scaling of graphs

Currently all scaling is done automatically. This also means that a user must estimate time-scale by setting number of points displayed.

Want to allow a user to optionally specify explicit axis limits or scaling of a graph.

Add debugging console to listener

Provide debugging alternative since the serial port has been hi-jacked. Expose function to allow messages to be sent through plotter library and display on listener

Modify dotted lines to continuous lines

Thank you for sharing your very useful code.

Instead of having dotted lines being plotted, I prefer continuous lines.
I modifed this section of your code accordingly as follows :

// Do actual data plotting

// 1 - Is the rolling buffer full of data ?

if ( this.currPoints < this.maxPoints ) // Not yet

for ( int i = 0; i < this.numVars; i++ )
{
    this.parent.stroke( this.colors[i] );
    for ( int j = 0; j < this.currPoints-1; j++ )
    {
	this.parent.line( (float)(this.posX + (this.data[j][i][0]*xScale - xOffset)), (float)(this.posY + yOffset - data[j][i][1]*yScale),
                    (float)(this.posX + (this.data[j+1][i][0]*xScale - xOffset)), (float)(this.posY + yOffset - data[j+1][i][1]*yScale) );
    }
}	

else // 2 YES, roll-back did start continuous plotting must be done in two halves

{
for ( int i = 0; i < this.numVars; i++ )
{
this.parent.stroke( this.colors[i] );
for ( int j = this.index ; j < this.maxPoints-1; j++ )
{
this.parent.line( (float)(this.posX + (this.data[j][i][0]*xScale - xOffset)), (float)(this.posY + yOffset - data[j][i][1]*yScale),
(float)(this.posX + (this.data[j+1][i][0]*xScale - xOffset)), (float)(this.posY + yOffset - data[j+1][i][1]*yScale) );
}
}
for ( int i = 0; i < this.numVars; i++ )
{
this.parent.stroke( this.colors[i] );
for ( int j = 0; j < this.index-1; j++ )
{
this.parent.line( (float)(this.posX + (this.data[j][i][0]*xScale - xOffset)), (float)(this.posY + yOffset - data[j][i][1]*yScale),
(float)(this.posX + (this.data[j+1][i][0]*xScale - xOffset)), (float)(this.posY + yOffset - data[j+1][i][1]*yScale) );
}
}

}

Use line for smoother graphs

for ( int j = 0; j < this.currPoints; j++ )

Hi, just an quick&dirty idea, I don't know if there are any caveats using this. For me it worked:

`for ( int j = 0; j < this.currPoints; j++ )
{
float x1 = (float)(this.posX + (this.data[j][i][0]*xScale - xOffset));
float y1 = (float)(this.posY + yOffset - data[j][i][1]*yScale);

    // Skip the first 2 pixels otherwise you will see lines between first and last pixel
    if (j > 0 && x1 > this.posX + 2) {          
      float x2 = (float)(this.posX + (this.data[j-1][i][0]*xScale - xOffset));          
      float y2 = (float)(this.posY + yOffset - data[j-1][i][1]*yScale);
      this.parent.line(x1, y1, x2, y2);
    } else {
      this.parent.point(x1, y1);
    }

}`

This makes the graph rendering smoother if you wish rendering interpolation between the data points.

This is just some kind of contribution. Thank you for this outstanding library and for making it free for all of us! :)

Code Does Nothing...

I updated my windows before starting to use Arduino for a project. I'm not sure why, but the code doesn't do anything for me. The code Don't open a window or graph. I wanted to show the difference in voltage/resistance when using a specific sensor and plot a graph. The quick setup still gave me no results. Additionally, when I open the Serial monitor it starts filling lines with symbols such as "��6���q��p@�*", and it goes on, Filling the whole Serial Monitor screen infinitely.

I downloaded the library because I couldn't use the Serial Plotter. The Plotter used to be under Tools on the IDE (built-in). Is there a way to quickly use the info (numbers) received in the Serial Monitor and Plot it in a Windows 11, 2.0.0-Beta12 Arduino IDE?

If anyone knows what to do, I'll appreciate it. If any extra info is needed, I'll be glad to provide it.

Problems_Github_Plotter

Bar graphs

Looking for a good working codes for Arduno and Processing sides to support plot of FFT results in live bar graph style (normally 128 dots).

Save data option

Add option to freeze listener and write out data to csv. Could also be a record option to save info over longer time period

Unable to get this to properly plot analogue input values

Really excited when I found this, so much potential. Examples work fine but I cannot get a clean line plotting the analog inputs of my NANO.

The display I get clearly shows the voltages on the analogue pin, and the correct ranges, but I can't get a clean line. See attachments showing Listener.exe (Windows 10 64bit PC) window before and after auto scaling. I have changed the points to plot (500,1000,5000) - it just changes the refresh rate not the plotted line. I have tried adding delays in the loop - only the refresh rate changes..

Your examples work fine but I noticed they seem to use a 'timebase' of 5000 for their calculations. My analog input won't change rapidly - more likely to vary over a number of seconds, minutes or hours though quick reads in succession should give the same value resulting in a horizontal line.

What can I do to solve this

#include <Plotter.h>

float Vout;  // Analogue voltage
Plotter p;


#define SIG A4
#define CONTROL 10


void setup() {

  pinMode(CONTROL,OUTPUT);
  digitalWrite(CONTROL,HIGH);

  // now start the plotter

  p.Begin();

  p.AddTimeGraph( "Ion Chamber Vout", 5000, "Vout", Vout);
}

void loop() 
{
  Vout=5.0*analogRead(SIG)/1023.0;
  p.Plot();
}

plotter2
plotter1

No serial output

Hi, I hope I'm putting this in the right place.

I am using an ESP32 in platformio and I am trying to use the provided examples (after including the arduino.h library as is required in platformio). I have also installed the listener application (32 bit, because 64 bit version did not seem to work for me) and java runtime environment.

The plotter says scanning for serial ports ... (COM10), so I assume it is working properly and found the only active com port. However, no data is shown at all. Also opening a terminal in platformio does not even show any raw data coming through. The example does compile and flash succesfully to the board. So somehow the board is not generating any serial output.

My platform.ini file is configured the following:
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200

Another strange thing I encountered is that I cannot even get any Serial.println() commands to work, it only starts working if I remove the Plotter p; statement.

I already tried different boards but have the same issue, they do all work with different sketches so I doubt its a hardware issue. I also tried using v2.3.0 instead of the latest 2.3.3 version of plotter, but also no luck there.

I am quite lost so I hope someone can point me in the right direction of whats going wrong here. Am I missing any other dependency for this library to function properly?

Listener Configuration Error

When the listener tries to configure itself, it does not increment portIndex, and does not proceed beyond Port 0.

MacOS Catalina: listener.app dies after some seconds

Hello, I have checked the issue #7, since I had the same message (it complained about a damaged file) and after executing the line proposed in the issue in the terminal, the listener.app opens, nothing appears (no window, no messsage) and after some seconds it exits. I cannot figure out what is happening.

I have checked the gatekeeper, in my configuration I can open executables from any developer, so this should not be the issue. Any ideas? Thanks

Serial Plotter (Tools Menu) not fully working

I used the Arduino Library manager to install the library but it didn't install the listener.
I copied the listener folder from your website and placed it in the Plotter library folder (2 files Graph.java and listener.pde ). That allowed the Serial Plotter window to open. One I set the baud rate to 115200 it drew some axes and a grid but it didn't show any values being plotted. The windows Listener.exe worked ok.

Obviously I'm missing something but what?

Thanks

Command line

It would be good to add a simple command line in the listener to send characters or commands for the control of the target

Why strictly Java 8 is needed?

Please just document this is tested on JVM 8 but let people to run which ever version they want. Probably this will even run fine with JVM 17

Invalid messages with too many plots

Hey Devin,

first of all: Thank you for this great and easy to use plotting-system, it makes working with real-time-sensor-evaluation so much easier!

However I recently experienced a small issue (I have a solution already, but let me first motivate):

I'm working on an Arduino Uno. I was trying to plot four TimeGraphs with 4 (or 5) variables each, all complete with title and label descriptions. Everything compiled fine, however nothing was being transmitted (TX LED not lit up).
I commented out to plots, and indeed, now the TX LED was lit up. However, when I started the listener-application, all I got was a gray screen after it connected to the serial port.

I took a look at the transmitted serial data, and as it turned out, some of the data of the description line (the one with the names of the graphs and everything) was dropped. This resulted in a syntax error in the resulting JSON-String, since also a " was dropped.

After some more trying out I found out that this was a memory-error - my small AtMega had simply run out of memory, and so some stuff was just dropped. So this is probably more an optimization request, than a bug-report.

What I did to fix my issue was the following. In Plotter.h and Plotter.cpp:

  • I replaced the usage of String with const char *. Since you were only using String as a container anyways, this was no issue. String needs a bit more memory than const char *.

  • I split up the Serial.print()-statements. I had to do this anyway, because concatenation doesn't work that way with const char *. But this would also probably lead to some improvements if you decide to keep String, because the String-concatenation in the print()-calls (using "+") also takes a bunch of memory.

    You can do the splitting up by just replacing every occurence of "" + " with ""); Serial.print(" and every occurence of " + "" with "); Serial.print("".

After those two changes, everything worked again - nothing got dropped, and all plots were displayed like they should.

Let me know what you think, if you want I can also prepare a pull-request. Thanks again for the great library!

Compile Error in Arduino Due

I am Getting following error while compiling program in Arduino Interface for Arduino Due Board :-

Arduino: 1.8.0 (Windows 7), Board: "Arduino Due (Programming Port)"

C:\Users\Shourya\Documents\Arduino\libraries\Plotter\Plotter.cpp: In member function 'void Plotter::Graph::Plot(bool)':

C:\Users\Shourya\Documents\Arduino\libraries\Plotter\Plotter.cpp:244:45: error: 'dtostrf' was not declared in this scope

dtostrf( wrappers[i].GetValue(), 1, 7, val );
^

exit status 1
Error compiling for board Arduino Due (Programming Port).

Please look into the matter.

Can not install

In the Arduino IDE, I can use the Serial Plotter to see a live display of the variables values as the program runs. I also use Veusz graph plotting software to graph the data after the run is over. Veusz is much better at graphing than the Arduino IDE. Veusz also has a feature to collect data from a file every 0.1 sec (and other). I would like to be able to do the same thing in PlatformIO. Is this possible? I can use an external Terminal program. But how do I get a live plot.

platformio lib install 850
Does not work.

Processing 3.5.3 is installed.
Arduino-plotter 2.3.3 is installed. Plotter 2.3.3 is installed.
SerialPlot v0.10.0 is installed

However, when I try to run the arduino-plotter example I get the message

src\main.cpp:2:21: fatal error: Plotter.h: No such file or directory
The following commands do not work.

platformio lib install 850

platformio lib install "Plotter"

pio lib install "Plotter"

This sounds like three paragraphs and three apps.

Processing and Listener

Arduino IDE

SerialPlot

I am not sure this is correct.

Can you please elaborate?

How to Add arduino plotter sketch with another sketch

I want to monitor electrical parameters in real time. I have the following code with emon arduino sketch, I want to plot graph with the data from it usig arduino plotter, How to do that. The following code is below.
`#include <EmonLib.h>

// EmonLibrary examples openenergymonitor.org, Licence GNU GPL V3

#include "EmonLib.h" // Include Emon Library
EnergyMonitor emon1; // Create an instance

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

emon1.voltage(2, 10000, 1.7); // Voltage: input pin, calibration, phase_shift
emon1.current(1, 500); // Current: input pin, calibration.
}

void loop()
{
emon1.calcVI(20,2000); // Calculate all. No.of half wavelengths (crossings), time-out
emon1.serialprint(); // Print out all variables (realpower, apparent power, Vrms, Irms, power factor)

float realPower = emon1.realPower; //extract Real Power into variable
float apparentPower = emon1.apparentPower; //extract Apparent Power into variable
float powerFActor = emon1.powerFactor; //extract Power Factor into Variable
float supplyVoltage = emon1.Vrms; //extract Vrms into Variable
float Irms = emon1.Irms; //extract Irms into Variable
}`

NaN on vertical axis

Using V2.3.3 downloaded today (ZIP file).
I'm not sure if this is the same problem reported before (#19) but it relates to my previous issue #23.
If I only change the loop() code from this:-

void loop() 
{
 Vout=5.0*analogRead(SIG)/1023.0;
 p.Plot();
}

To this:-

void loop() 
{
 float Vnew=5.0*analogRead(SIG)/1023.0;
 if (Vout==Vnew) Vout=Vnew+.0001;
 p.Plot();
}

Then Listener.exe shows NaN on the vertical axis and no values are plotted. This was done to try to avoid consecutive values being the same (in case the NaN was caused by the previously reported bug #19)

quick_start.ino not working

Hi,

i just found your programm - very cool.

Two points:
1.
When i ran the quick_start.ino on an esp32 i had to removep.Begin();. Otherwise it does not print anything out or show in your listener application.

When i add some Serial.println("whatever"); after the plot command it does not work.
Is this your intention?

Thanks!

quick_start.ino

/*
  ===========================================================================================
  Example used in Quick-Start
  -------------------------------------------------------------------------------------------
  Plotter
  v2.3.0
  https://github.com/devinaconley/arduino-plotter
  by Devin Conley
  ===========================================================================================
*/

#include "Plotter.h"

double x;

Plotter p;

void setup()
{
    p.Begin();

    p.AddTimeGraph( "Some title of a graph", 1500, "label for x", x );
}

void loop() {
    x = 10*sin( 2.0*PI*( millis() / 5000.0 ) );

    p.Plot(); // usually called within loop()
}

some bugs in the listener, and some refactoring

Hello Devin:

I have been hacking on your plotter software toward using the graph to display information from an old but high-precision digital multimeter.

I noticed the large update yesterday and decided to share some of my code just to make you aware that I'm working on it.

Because I wouldn't want you to try and merge any of this code yet, I have saved what I have as a gist, here.

I am sure some of the stuff in there will meet with annoyance (the spacing, and the debugging lines). And other stuff will meet with a better response (the refactoring attempts). There is a lot of potential for refactoring yet, so I'll keep you updated.

Thanks,
Drew

listener.exe crashes immediately

When I run the listener.exe it crashes immediately. I downloaded the windows 64 bit stand-alone listener.
This is the first part of the log file it makes after crashing:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000007110b5db, pid=10316, tid=0x0000000000003a64
#
# JRE version: Java(TM) SE Runtime Environment (8.0_291-b10) (build 1.8.0_291-b10)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.291-b10 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [jSSC-2.8.dll+0xb5db]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

Serial port printing symbols

Hi,

i'm relatively new to arduino so apologies for any newbie mistakes.

i've been trying to use the plotter library with an arduino uno to visualize analog readings from pressure sensors. however, upon trying even the simplest quickstart example code, the serial monitor will first print out some proper values, before starting to rapidly print random symbols: (below is the output from uploading the quickstart code)

{"t":0,"ng":1,"48833446]}]}# {"t6434464]}]}# {"t":129,"g":[{"d":[1.61397123]}]}# {"t":132,"g":[{"d":[1.65116453]}]}# {"t":135,"g":[{"d":[1.68833446]}]}# {"t":138,"g":[{"d":[1⸮S⸮@�� '>�⸮�K⸮$⸮,�⸮t⸮"⸮H⸮x�⸮⸮K ⸮�⸮⸮>��⸮�⸮q⸮ڲ⸮H⸮⸮⸮H⸮�⸮⸮�%[ ⸮f⸮⸮⸮-$�<�⸮�⸮,⸮⸮}⸮�⸮Z⸮а⸮�⸮,⸮9⸮⸮⸮!Z$⸮⸮⸮⸮⸮0⸮)0=mƎ-�⸮-צ%⸮⸮N⸮p⸮⸮i⸮�⸮⸮/⸮=S⸮=⸮�⸮⸮T⸮⸮X⸮Q⸮nƑ⸮E�⸮�⸮o�[Z�[^⸮ڧ⸮�⸮o�⸮O⸮ �P -K/KO/[ ⸮H⸮sJ⸮=,⸮⸮-V⸮Rq⸮^M⸮⸮)շ⸮շ⸮5I⸮4H⸮$S⸮⸮⸮%⸮⸮tt⸮X⸮R^�
⸮�⸮:⸮8J⸮9,⸮⸮-⸮p⸮⸮-W⸮⸮⸮�⸮⸮^⸮T[�⸮Z⸮⸮⸮⸮⸮Tn⸮T⸮⸮X⸮U,⸮X[�{+⸮=d��⸮⸮⸮"⸮⸮⸮⸮&⸮⸮ ⸮<⸮$⸮x⸮,�V⸮⸮)⸮�-Sjʇ�⸮.=⸮⸮}⸮z=�⸮⸮��⸮⸮/⸮⸮�⸮H⸮$� ⸮C�⸮⸮X⸮],$�⸮⸮⸮⸮x8)⸮=,� J�mV�*⸮j,q⸮,m�,⸮⸮⸮HM<⸮ ⸮⸮І �⸮C5ݦX�⸮ڇXX⸮|⸮⸮-⸮=)⸮⸮-�⸮⸮���I(,⸮%�I⸮T=��!M��[�⸮-⸮⸮-⸮⸮-⸮⸮KƍN⸮⸮,u�,⸮M⸮O}5S⸮겧⸮]⸮=W⸮o⸮⸮⸮⸮^⸮R�[ %�⸮:⸮8=-�⸮-֧J֏I⸮⸮⸮%⸮K⸮ۚ⸮⸮⸮zy⸮⸮$⸮o�⸮O⸮& P�[5⸮⸮⸮q⸮8[�¬�⸮,�Ҭ ⸮(-⸮⸮-th,pB,u⸮,⸮�⸮D�<I⸮,⸮$⸮O⸮S⸮��� '�⸮�*�⸮,mZ,⸮m⸮1�}⸮ ⸮⸮Җ ��C⸮⸮⸮X�R�⸮X^⸮||⸮-⸮⸮)8*⸮⸮( ⸮P⸮&=⸮$y⸮⸮=�H⸮⸮ڳ⸮ִH⸮$M�⸮C%⸮⸮⸮�⸮$⸮VZ[+-I�ˬ�)�⸮⸮5⸮�-⸮J⸮�⸮⸮H⸮⸮�⸮⸮⸮6�⸮�⸮�⸮⸮Ц ��o⸮�[J/KN/⸮ i⸮�,⸮⸮⸮ �⸮⸮OR⸮o⸮⸮⸮⸮f ��$t⸮⸮$$⸮x⸮p8)08)⸮�RI⸮-zR⸮⸮⸮⸮�⸮⸮⸮⸮⸮�⸮⸮⸮⸮⸮⸮⸮⸮�⸮o�⸮O⸮ �T

i tried running the listener despite this, but the listener is just stuck at "attempting connect on port: COM4" (COM4 is my arduino uno port.).
I am really stuck as to what i am doing wrong, any advice would be greatly appreciated.

Thanks in advance!

Can't make listener work

I am trying to view just simple changes in resistance in real time for a presentation I am giving tomorrow, and I can't seem to make this work. I am using Atom PlatformIO with an arduino 101, and am using the following code:

#include "Arduino.h"
#include "Plotter.h"

double rVal = 10e3; // Known resistor value.
int iPin = A2;   // Pin our input is connected to.
double vIn = 5;   // Input voltage corrected for loss.
Plotter p; // Global Plotter variable
double out; // Global output variable
double resistance;

void setup()
{
  // put your setup code here, to run once:
  p = Plotter();          // Initialize Plotter
  p.AddTimeGraph( "Resistance", 500, "Resistance", resistance);

void loop()
{
  // put your main code here, to run repeatedly:
  out = analogRead(iPin);            // Our output voltage
  resistance = (out * vIn) / (vIn - out);  // The resistance between leads
  p.Plot();
}

However when I open the Listener app it switches off between displaying
screen shot 2017-03-31 at 5 01 02 pm
and
screen shot 2017-03-31 at 5 01 10 pm.

I am running Mac OS Sierra
Any advice?

Does not run on Ubuntu 20.04 LTS

matthijs@Latitude:~/Downloads/arduino-plotter-listener-linux64$ ./listener
java.lang.UnsatisfiedLinkError: Can't load library: /usr/lib/jvm/java-11-openjdk-amd64/lib/libawt_xawt.so
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2630)
at java.base/java.lang.Runtime.load0(Runtime.java:768)
at java.base/java.lang.System.load(System.java:1837)
at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2442)
at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2498)
at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2694)
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2648)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:830)
at java.base/java.lang.System.loadLibrary(System.java:1873)
at java.desktop/java.awt.Toolkit$3.run(Toolkit.java:1399)
at java.desktop/java.awt.Toolkit$3.run(Toolkit.java:1397)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.desktop/java.awt.Toolkit.loadLibraries(Toolkit.java:1396)
at java.desktop/java.awt.Toolkit.(Toolkit.java:1429)
at processing.core.PApplet.runSketch(PApplet.java:10310)
at processing.core.PApplet.main(PApplet.java:10211)
at listener.main(listener.java:434)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.