Arduino Dashboard

New Version: Arduino Dashboard 2.0

The Arduino Dashboard is a PC frontend for the Arduino. It provides controls that usually take  along time to build on a breadboard.

Screenshots

Simple Start: Blink

The blink code for the Arduino Dashboard is rather simple:

void setup() {
  Serial.begin(115200);
}
void loop() {
  // put your main code here, to run repeatedly:
  Serial.println(">LED001.0100.0100.0255.0255.0255<");
  delay(500);
  Serial.println(">LED001.0100.0100.0000.0000.0000<");
  delay(500);
}

You can request 100 LEDs using LED00 to LED99. The 1 after that number tells Dashboard to show the LED, a 0 hides it. The five parameters are seperated by "." for you to handle them easier. The first two parameters tell the Dashboard where to place the LED in x and y from the top left corner. Then we have the three RGB values - yes, it is by default an RGB LED.

So changeing the code to

void loop()
{
  Serial.println(">LED001.0100.0100.0255.0000.0000<");
  delay(500);
  Serial.println(">LED001.0100.0100.0000.0255.0000<");
  delay(500);
  Serial.println(">LED001.0100.0100.0000.0000.0255<");
  delay(500);
}

will make the LED blink in red, green and blue. THis is what you will get:

In addition to the code baove, I have added a few more lines in setup() to tell the Dashboard what board I have and what sketch is running. I also asked for a nice title bar:

Serial.println(">BRD.UNO<");
Serial.println(">IFO.Blink Sketch 1.0.0<");
Serial.println(">TTL1Dashboard Blink Demo<");

Next: Chart Values

A common situation is that I need to look at the input of one on my analog ports. For that I usually use a Serial.println comamnd but then I see the values rushing by. WHy not chart these in a histogram?:

void setup() {
  Serial.begin(115200);
  Serial.println(">HTM001.0000.1200<");
  Serial.println(">HTZ001<");
}
void loop() {
  Serial.print(">HTV001.");
  Serial.print(analogRead(1););
  Serial.println("<");
  delay(50);
}

and I get:

 

 Use Cases

The best way to explain the Dashboard is to show some use cases:

 Make an LED on pin13 blink

For this example, I want to have a checkbox on my dashboard. If it is checked, the LED should be on, if it is unchecked, the LED should be off.

The sketch then needs to send me one Definition String:

>CKB001.0105.0040.Led 13<

The first three letters tell the dashboard that it should start a checkbox (CKB), assign it the index 1 for later reference and position ist at the coordinates (x,y) = (105,40) and give it the label "Led 13". The dots between the values are only there for the programmer to amke the string more readable. The output is the following:

The sketch can be loaded here (from codebender.cc; user mathiaswilhelm2012)

↑top

 change blinking LED

 

↑top

 

Reference Documentation

Currently supported controls are

  • title
  • button
  • checkbox
  • combobox
  • slider
  • label
  • chart

For this, I created a Visual Basic based application that has an empty canvas where I have pre-configured controls to provide button, checkboxe, labels, sliders, combobox and a title bar. The controls can be configured and switched on or off at any time in the arduino sketch. There is no limit on the number of controls as they are created dynamically at run time.

As the tool uses the serial port, a communication through bluetooth is available for free. The basic code for the serial communication is based on the concept introduced by Erik Bartmann in his book "Die elektronische Welt mit Arduino entdecken" (O'ReillY)

The Visual Basic project can be downloaded from the download page

To start with, here is a screenshot of the dashboard and the sketch controling it:

The demo arduino sketch:

#include <MsTimer2.h>

int bufferCount;    // Anzahl der eingelesenen Zeichen
char buffer[80];    // Serial Input-Buffer
char temp[80];
char lastpin=2;
int blinkdelay;
boolean dbOpen = false;
boolean readPort = false;
boolean sglPort = false;
int maxSequence = 1;
int sequence = 0;
int c2chrt = 0;

void setup()
{
  Serial.begin(115200);
  for (int i=2;i<14;i++) {
    pinMode(i,OUTPUT);
  }
  MsTimer2::set(150, t2Isr); // 500 ms period
  MsTimer2::start();
}

void loop()
{
  // do nothing for the GUI handling, serial is done through interrupt
}

void serialEvent(){
  char ch = Serial.read();
  buffer[bufferCount] = ch;
  bufferCount++;
  if(ch == 13){
    evalSerialData();
  }
}

void evalSerialData()
{
  int ptr;
  int val;
  strcpy(temp,"");
  if ((buffer[0]=='>')&&(buffer[bufferCount-2]=='<')) {
    strncat(temp, buffer, bufferCount-1);
    if (strcmp(temp,"SQVERSIONE")==0){
      strcpy(temp,"AC 1.0.0");
    }
    if (strcmp(temp,"SINITE")==0){
      // setup the Dashboard
      Serial.println(">TTL1Dashboard DemoE");
      Serial.println(">BTN001.0020.0040.0080.0025.Click Me<");
      Serial.println(">CKB001.0105.0040.Led 5<");
      Serial.println(">SLD001.0020.0070.0002.0013.0001.Led Swiper<");
      Serial.println(">SLD011.0020.0150.0000.0250.0025.Led Fader<");
      Serial.println(">CBO001.0020.0240.0080.0025<");
      Serial.println(">CBA001.Port A0<");
      Serial.println(">CBA001.Port A1<");
      Serial.println(">CBA001.Port A2<");
      Serial.println(">CBA001.Port A3<");
      Serial.println(">CBA001.Port A4<");
      Serial.println(">CBA001.Port A5<");
      Serial.println(">CBS001.0002<");
      c2chrt = 2;
      Serial.println("SLBL001.0250.0240.0080.0030.0.00E");
      Serial.println("SCKB011.0335.0040.Chart Timeline DataE");
      Serial.println("SCKB021.0105.0240.Show Port DataE");
      dbOpen = true;
    }
    if (strcmp(temp,">GoodBye<")==0){
      // stop the Dashboard
      dbOpen = false;
    }
    if ((buffer[1]=='C')&&(buffer[2]=='K')&&(buffer[3]=='B')){
      ptr = (buffer[4]-48)*10 + (buffer[5]-48);
      if (ptr==0) {
        digitalWrite(5,((buffer[6]-48)==1));
      }
      if (ptr==1) {
        readPort = (buffer[6]-48)==1;
      }
      if (ptr==2) {
        sglPort = (buffer[6]-48)==1;
      }
    }
    if ((buffer[1]=='C')&&(buffer[2]=='B')&&(buffer[3]=='O')){
      ptr = (buffer[4]-48)*10 + (buffer[5]-48);
      c2chrt = buffer[12]-48;
      if ((c2chrt<0) || (c2chrt>5)) c2chrt = 0;
    }
    if ((buffer[1]=='B')&&(buffer[2]=='T')&&(buffer[3]=='N')){
      ptr = (buffer[4]-48)*10 + (buffer[5]-48);
      for (int i=2;i<14;i++) {
        digitalWrite(i,!(digitalRead(i)));
      }
    }
    if ((buffer[1]=='S')&&(buffer[2]=='L')&&(buffer[3]=='V')){
      ptr = (buffer[4]-48)*10 + (buffer[5]-48);
      val = (buffer[6]-48)*1000 + (buffer[7]-48)*100 + (buffer[8]-48)*10 + (buffer[9]-48);
      if (ptr==0) {
        digitalWrite(lastpin,LOW);
        lastpin=val;
        digitalWrite(lastpin,HIGH);
      }
      if (ptr==1) {
        analogWrite(10,val);
      }
    }
  }
  else {
    strcpy(temp,"BadCmd: ");
    strncat(temp, buffer, bufferCount);
    Serial.println(temp);
  }
  bufferCount=0;
}

void t2Isr()
{  
  int led_pin = 13;
  int led_pin2 = 12;
  int ar[6];
  int val;
  char dstr[40];

  switch (sequence) {
  case 0:
    for (int i=0; i<6; i++) {
      ar[i] = analogRead(i) + i * 65;
    }
    sprintf(dstr,"STLViii.%4d.%4d.%4d.%4d.%4d.%4dE",ar[0],ar[1],ar[2],ar[3],ar[4],ar[5]);
    if (readPort) {
      if (dbOpen) {
        Serial.println(dstr);
      }
    }
    break;
  case 1:
    if (sglPort) {
      digitalWrite(led_pin, !digitalRead(led_pin));
      if (dbOpen) {
        val = analogRead(c2chrt);
        Serial.print("SLBV001.");
        Serial.print(millis() % 1000);
        Serial.println("E");
        Serial.print("SCHV001.");
        Serial.print(val);
        Serial.println("E");
      }
    }
  }
  sequence++;
  if (sequence>maxSequence) sequence = 0;
}

The demo code sets all pins 2-13 to output. Pressing the button inverst all pin states, The Led Swiper lights the Led matching the slider position, the Led Fader dims the PWM value of pin 10 and the checkbox controls the state of pin 5. It adds at the end a ComboBox with 6 items. With this combobox, the input for the chart underneath is selected and the checkbox decides if data is plotted or not. The Label next to it shows the actual value plotted. The plot data checkbox enables the filling of the timeline chart on the second tab. In the demo, the analog ports are read and sent to the PC with a value shift to show the differnet lines.

The date and time panels allow sending the actual or a user defined time message to be sent to the arduino. A demo sketch for this is under way.

Protocol

The protocol is rather simple: All commands start with an ">" and end with an "<". In  the sketch above, the GUI is set up using the following lines:

Serial.println("TTL1Dashboard Demo<");
Serial.println(">BTN001.0020.0040.0080.0025.Click Me<");
Serial.println(">CKB001.0105.0040.Led 5<");
Serial.println(">SLD001.0020.0070.0002.0013.0001.Led Swiper<");
Serial.println(">SLD011.0020.0150.0000.0250.0025.Led Fader<");
Serial.println(">CBO001.0020.0240.0080.0025<");
Serial.println(">CBA001.item 0<");
Serial.println(">CBA001.item 1<");
Serial.println(">CBA001.item 2<");
Serial.println(">CBA001.item 3<");
Serial.println(">CBS001.0002<");

Control Definition

These are the commands that define controls on the dashboard.

Title

Format: TTLvlabel
TTL - identifier
v - title visible (0=no, 1=yes)
label - free text for the title banner

Button

Format: BTN##v.llll.tttt.wwww.hhhh.label
BTN - identifier
## - number of button
v - button visible (0=no, 1=yes)
llll - position left of border
tttt - position from border top
wwww.hhhh - width and height of button
label - free text for the button
the "." are only for human readability and have no function

Checkbox

Format: CKB##v.llll.tttt.label
CKB - identifier
## - number of checkbox
v - button visible (0=no, 1=yes)
llll - position left of border
tttt - position from border top
label - free text for the button
the "." are only for human readability and have no function

Slider

Format: SLD##v.llll.tttt.mmmm.xxxx.ssss.label
SLD - identifier
## - number of slider
v - 0=no, 1=yes
llll - position left of border
tttt - position from broder top
mmmm - minimum value for slider
xxxx - maximum value for slider
ssss - tick mark step width
label - free text for the title banner

ComboBox

Format: CBO##v.llll.tttt.wwww.hhhh
## - number of combobox
v - combobox visible (0=no, 1=yes)
llll - position left of border
tttt - position from border top
wwww.hhhh - width and height of combobox
the "." are only for human readability and have no function
Format: CBA##i.ItemToAdd
## - number of combobox to add item to
i - ignored
ItemToAdd - free text used as item text
the "." are only for human readability and have no function

Documentation to come: Label-field

Sending Information

The following commands update defined controls

Receiving Information

The following commands are sent to the Arduino fromthe controls:

Button Pressed

Format: BTN##
BTN - identifier
## - number of button pressed

CheckBox State Change

Format: CKB##s
CKB - identifier
## - number of checkbox
s - state of checkbox (1=on, 0=off)

Slider Value Change

Format: SLV##vvvv
SLV - identifier
## number of slider
vvvv - value of slider

ComboBox Selection Change

Format: CBO##ItemLabel
CBO - identifier
## - number of slider
ItemLabel - text of selected item as defined in the control definition

Serial Log

The serial log echos the commands sent to the arduino and aligned the messages received from the arduino