How To Display Data

edited December 2017 in Arduino

I am trying to display some live data from multiple Arduinos that will be sending data via Zigbee to a coordinator, and one of the jobs of the coordinator is to send data into Processing to display in a GUI.

I am able to send data from my coordinator into Processing fine, I have repeated it over the Processing console, and I have dumped one variable into a chart following the ControlP5 chart example. However, not all data that I will be sending would be useful over a chart, the bulk of the data I would just like to display as something like "Temperature: 100". Because this data will be coming from multiple Arduinos, I would also like the group the data like the ControlP5 accordion example if possible.

The data I am sending comes in pairs, with the first data value being an identifier for what the data type is, with the following value being the actual data. My transmission code can support up to 50 useful data points, and I would also like to support up to 50 Arduinos if possible. Is there a way to set up the accordion groups and data text displays dynamically, without having to declare 2500 objects (I'm not sure if object is the correct word here)? The first data point in my transmission states how many points are coming, so I am hoping that could drive some logic in setting up text labels within an accordion. Looking at the ControlP5 example for textlabel, there are two labels shown, and both were declared and set up manually within setup(), which I believe means that they are static, and their value be changed?

Here is my current code. I am just working with 3 manually set up accordion groups (would like to support up to 50), and I am stuck right now with how to display data values in the groups from the Arduino transmission. The data is getting into Processing, I just don't know what to do with it from there. Can anyone help show me how to display a data value from a variable?

Processing code:

/**
 * Simple Read
 * 
 * Read data from the serial port and change the color of a rectangle
 * when a switch connected to a Wiring or Arduino board is pressed and released.
 * This example works with the Wiring / Arduino program that follows below.
 */


import processing.serial.*;
import controlP5.*;

ControlP5 cp5;
Accordion accordion;
Serial myPort;  // Create object from Serial class

boolean firstContact = false;
boolean gotLength = false;
int dataLength = 0;
int dataPosition = 0;
int[] payLoad = new int[102];

void setup() 
{
  size(400, 600);
  String portName = Serial.list()[1];
  myPort = new Serial(this, portName, 9600);

  noStroke();
  smooth();
  gui();
}

void gui()
{
  cp5 = new ControlP5(this);

  // group number 1
  Group g1 = cp5.addGroup("myGroup1")
                .setBackgroundColor(color(0, 64))
                .setBackgroundHeight(150)
                ;

  // group number 2
  Group g2 = cp5.addGroup("myGroup2")
                .setBackgroundColor(color(0, 64))
                .setBackgroundHeight(150)
                ;

   // group number 3
  Group g3 = cp5.addGroup("myGroup3")
                .setBackgroundColor(color(0, 64))
                .setBackgroundHeight(150)
                ;

   // create a new accordion
  // add g1, g2, and g3 to the accordion.
  accordion = cp5.addAccordion("acc")
                 .setPosition(40,40)
                 .setWidth(200)
                 .addItem(g1)
                 .addItem(g2)
                 .addItem(g3)
                 ;

  cp5.mapKeyFor(new ControlKey() {public void keyEvent() {accordion.open(0,1,2);}}, 'o');
  cp5.mapKeyFor(new ControlKey() {public void keyEvent() {accordion.close(0,1,2);}}, 'c');
  cp5.mapKeyFor(new ControlKey() {public void keyEvent() {accordion.setWidth(300);}}, '1');
  cp5.mapKeyFor(new ControlKey() {public void keyEvent() {accordion.setPosition(0,0);accordion.setItemHeight(190);}}, '2'); 
  cp5.mapKeyFor(new ControlKey() {public void keyEvent() {accordion.setCollapseMode(ControlP5.ALL);}}, '3');
  cp5.mapKeyFor(new ControlKey() {public void keyEvent() {accordion.setCollapseMode(ControlP5.SINGLE);}}, '4');
  cp5.mapKeyFor(new ControlKey() {public void keyEvent() {cp5.remove("myGroup1");}}, '0');

  accordion.open(0,1,2);

  // use Accordion.MULTI to allow multiple group 
  // to be open at a time.
  accordion.setCollapseMode(Accordion.MULTI);

  // when in SINGLE mode, only 1 accordion  
  // group can be open at a time.  
  // accordion.setCollapseMode(Accordion.SINGLE);              
}

void draw()
{
  background(200);
  checkData();
}

void checkData()
{  
  //  Check for data on serial port
  if(myPort.available() > 0)
  {
    //  Establish handshake
    if(firstContact == false)
    {
      if(myPort.available() >= 3)
      {
        for(int i = 0; i < 3; i++)
        {
          if(myPort.read() == '+')
          {
            dataPosition++;
          }
        }

        //  Good start to handshake, need to send a byte back
        if(dataPosition == 3)
        {
          myPort.clear();        //  Clear serial port
          myPort.write('A');     //  Send byte that we are ready to receive data
          firstContact = true;   //  Mark that first contact has been made
          dataPosition = 0;      //  Reset dataPosition
        }
        else
        {
          myPort.clear();
          dataPosition = 0;
        }
      }
    }
    //  Handshake established, get actual data
    else
    {
      //  First get data length
      if(gotLength == false)
      {
        if(myPort.available() >= 4)
        {
          dataLength = getLong();
          gotLength = true;
        }
      }
      //  
      else
      {
        if(dataPosition < dataLength + 2)
        {
          if(myPort.available() >= 4)
          {
            payLoad[dataPosition] = getLong();
            dataPosition++;
          }
        }
        else
        {
          firstContact = false;
          gotLength = false;
          dataPosition = 0;
        }

        /*
        //  Display data on terminal for verification
        println(dataLength);
        for(int i = 0; i < (dataLength*2) + 2; i++)
        {
          println(payLoad[i]);
        }
        println("");
        */
      }
    }
  }
}

int getLong()
{
  int val = 0;
  int val1 = myPort.read();
  int val2 = myPort.read();
  int val3 = myPort.read();
  int val4 = myPort.read();

  val = ((val4<<0) + (val3<<8) + (val2<<16) + (val1<<24));

  return val;
}

Arduino Code:

    #include <ProcessingFunctions.h>

    byte dataLength = 10;
    int TRNum = 200;
    byte TRSeg = 2;

    void setup() {
      Serial.begin(9600);  // Open serial port
    }

    void loop() {

      //  These loops set every data point ID to 1 for now just to test
      //  The actual data then will increment after each transmission of the data
      for(int i = 0; i < 1000; i++)
      {
        for(byte j = 0; j < dataLength; j++)
        {
          processingFunction.addToPayload(1, i+j);
        }

        if(processingFunction.sendPayload(dataLength, TRNum, TRSeg))
        {
          //Serial.println("good");
        }
        else
        {
          //Serial.println("fail");
        }

        delay(100);
      }
    }

Thanks for the help!

Answers

  • I'm moving forward with using Textlabel to display information within the groups, but I am unable to get the label to display anything other than String values. It looks like I should be able to use .setValue(float), but I do not see anything unless I use .setValue(String). Has anyone used this successfully before?

  • When the float is ok (is a number), use str() to convert to string first

    Sometimes trim() would help after parsing the data

    Please look at hashMap in the reference- you could add up values for one type of data

  • str(number) works, thanks!

  • if you have multiple arduinos sending data, i'll recomend you to use mqtt protocl, plus, using node red will make the graphics way simpler.

Sign In or Register to comment.