× Interface and Application Programming Group Project Choosing my wand FabISP Milling the board

Mohit Ahuja's Fabacademy 2021

Interface and Application Programming

In this week we were supposed to experiment with different interfaces of our input or output boards. My work for this week is fairly limited due to my pending work from previous weeks. But I will try to find the time to experiment with other interfacing techniques.I experimented with Processing as well as a little bit with Python.

Group Project

Before we began experimenting, our local instructor, Aditi Ma'am gave us a brief introduction to MIT AppInventor and Processing, and I gave a brief overview of Scratch with Python. The results of this week's group assignments are given below.

Group Assignment

Familiar Turf

I have actually made some interfaces in Processing in the past and integrated it with Arduino, so for this week, I decided to make a simple graph plotter for my Hello Echo board made in Electronic Design Week. The goal was to make the software to simply plot a sine wave generated by the Arduino and sent over the Serial monitor.

For that, I took the reference of the Arduino code made for the embedded programming week, and added some code to calculate the value of sine and sent that over the Serial port.

This is the code that I uploaded to my Hello Echo World Board:

#include "SoftwareSerial.h"
float i = 0;
SoftwareSerial mySerial(2, 1); // RX, TX

void setup() {
  mySerial.begin(4800);
}

void loop() { // run over and over
  float val = sin(i);
  mySerial.println(val);
  i+=0.0314;
}

Code for sending the values of Sine(x) over Serial

This is the output of the program in the Arduino IDE's Serial Plotter

To make the interface in Processing, I dug around on the internet a little bit to find some inspiration for the code and found this code on the Arduino.cc website: Graph


  // Graphing sketch

  // This program takes ASCII-encoded strings from the serial port at 9600 baud
  // and graphs them. It expects values in the range 0 to 1023, followed by a
  // newline, or newline and carriage return

  // created 20 Apr 2005
  // updated 24 Nov 2015
  // by Tom Igoe
  // This example code is in the public domain.

  import processing.serial.*;

  Serial myPort;        // The serial port
  int xPos = 1;         // horizontal position of the graph
  float inByte = 0;

  void setup () {
    // set the window size:
    size(400, 300);

    // List all the available serial ports
    // if using Processing 2.1 or later, use Serial.printArray()
    println(Serial.list());

    // I know that the first port in the serial list on my Mac is always my
    // Arduino, so I open Serial.list()[0].
    // Open whatever port is the one you're using.
    myPort = new Serial(this, Serial.list()[0], 9600);

    // don't generate a serialEvent() unless you get a newline character:
    myPort.bufferUntil('\n');

    // set initial background:
    background(0);
  }

  void draw () {
    // draw the line:
    stroke(127, 34, 255);
    line(xPos, height, xPos, height - inByte);

    // at the edge of the screen, go back to the beginning:
    if (xPos >= width) {
      xPos = 0;
      background(0);
    } else {
      // increment the horizontal position:
      xPos++;
    }
  }

  void serialEvent (Serial myPort) {
    // get the ASCII string:
    String inString = myPort.readStringUntil('\n');

    if (inString != null) {
      // trim off any whitespace:
      inString = trim(inString);
      // convert to an int and map to the screen height:
      inByte = float(inString);
      println(inByte);
      inByte = map(inByte, 0, 1023, 0, height);
    }
  }


						

When I tried the code given in the link above without any modifications, I obtained the following result:

So after seeing the above screenshots, you might be thinking what I was thinking, there is no output. But if you zoom and enhance, you'll see that there is actually a short line showing up in the bottom of the screen.

This is happening because the code basically takes the input from the serial monitor, and maps it to the pixels, and since the sine(x) function gives an output between 1 and -1, the program converts it to a pixel of value one when the value of the sine(x) function is greater than 0.5 and zero for all other values of sine(x). I fixed this in the next version of the code, which multiplies the value of sin(x) by 200 and also adds 200 to the output so that the negative values can also be displayed.

// Graphing sketch

// This program takes ASCII-encoded strings from the serial port at 9600 baud
// and graphs them. It expects values in the range 0 to 1023, followed by a
// newline, or newline and carriage return

// created 20 Apr 2005
// updated 24 Nov 2015
// by Tom Igoe
// modified 12 May 2021
// by Mohit Ahuja
// This example code is in the public domain.

import processing.serial.*;

Serial myPort;        // The serial port
int xPos = 1;         // horizontal position of the graph
float inByte = 0;

void setup () {
// set the window size:
size(800, 500);

// List all the available serial ports
// if using Processing 2.1 or later, use Serial.printArray()
println(Serial.list());
// I know that the first port in the serial list on my Mac is always my
// Arduino, so I open Serial.list()[0].
// Open whatever port is the one you're using.
myPort = new Serial(this, Serial.list()[1], 4800);

// don't generate a serialEvent() unless you get a newline character:
myPort.bufferUntil('\n');

// set initial background:
background(0);
}

void draw () {
// draw the line:
stroke(127, 34, 255);
line(xPos, height, xPos, height - inByte);
// at the edge of the screen, go back to the beginning:
if (xPos >= width) {
  xPos = 0;
  background(0);
} else {
  // increment the horizontal position:
  xPos++;
}
}
void serialEvent (Serial myPort) {
// get the ASCII string:
String inString = myPort.readStringUntil('\n');

if (inString != null) {
  // trim off any whitespace:
  inString = trim(inString);
  // convert to an int and map to the screen height:
  inByte = (float(inString)*200) +200;
  println(inByte);
  inByte = map(inByte, 0, 1023, 0, height)+100;
}
}

This was the output of the above code:

But I wanted to see a single line output of the curve, so I modified the code to display the same sine curve twice, with the second curve coloured black to match the background and hence make it appear as if there is a single line. This is the code for that:


// This program takes ASCII-encoded strings from the serial port at 9600 baud
// and graphs them. It expects values in the range 0 to 1023, followed by a
// newline, or newline and carriage return

// created 20 Apr 2005
// updated 24 Nov 2015
// by Tom Igoe
// modified 12 May 2021
// by Mohit Ahuja
// This example code is in the public domain.

import processing.serial.*;

Serial myPort;        // The serial port
int xPos = 1;         // horizontal position of the graph
float inByte = 0;

void setup () {
  // set the window size:
  size(800, 500);

  // List all the available serial ports
  // if using Processing 2.1 or later, use Serial.printArray()
  println(Serial.list());
  // I know that the first port in the serial list on my Mac is always my
  // Arduino, so I open Serial.list()[0].
  // Open whatever port is the one you're using.
  myPort = new Serial(this, Serial.list()[1], 4800);

  // don't generate a serialEvent() unless you get a newline character:
  myPort.bufferUntil('\n');

  // set initial background:
  background(0);
}

void draw () {
  // draw the line:
  stroke(127, 34, 255);
  line(xPos, height, xPos, height - inByte);
  stroke(0);
  line(xPos, height, xPos, (height - inByte)+2);
  // at the edge of the screen, go back to the beginning:
  if (xPos >= width) {
    xPos = 0;
    background(0);
  } else {
    // increment the horizontal position:
    xPos++;
  }
}
void serialEvent (Serial myPort) {
  // get the ASCII string:
  String inString = myPort.readStringUntil('\n');

  if (inString != null) {
    // trim off any whitespace:
    inString = trim(inString);
    // convert to an int and map to the screen height:
    inByte = (float(inString)*200) +200;
    println(inByte);
    inByte = map(inByte, 0, 1023, 0, height)+100;
  }
}

And this is the output of the above code:

By using the above concept of overlapping shapes, I made a different, fun interpretation of the code by overlaying multiple graphs of different colors all measuring the same value. Here is the code that I wrote for that:


// Graphing sketch

// This program takes ASCII-encoded strings from the serial port at 9600 baud
// and graphs them. It expects values in the range 0 to 1023, followed by a
// newline, or newline and carriage return

// created 20 Apr 2005
// updated 24 Nov 2015
// by Tom Igoe
// This example code is in the public domain.

import processing.serial.*;

Serial myPort;        // The serial port
int xPos = 1;         // horizontal position of the graph
float inByte = 0;

void setup () {
  // set the window size:
  size(400, 300);

  // List all the available serial ports
  // if using Processing 2.1 or later, use Serial.printArray()
  println(Serial.list());

  // I know that the first port in the serial list on my Mac is always my
  // Arduino, so I open Serial.list()[0].
  // Open whatever port is the one you're using.
  myPort = new Serial(this, Serial.list()[1], 4800);

  // don't generate a serialEvent() unless you get a newline character:
  myPort.bufferUntil('\n');

  // set initial background:
  background(0);
}

void draw () {
  // draw the line:
  stroke(127, 34, 255);
  line(xPos, height, xPos, height - inByte);
    stroke(250,100,100);
  line(xPos, height+20, xPos, height - inByte+20);
      stroke(100,250,100);
  line(xPos, height+40, xPos, height - inByte+40);
        stroke(250,250,100);
  line(xPos, height+60, xPos, height - inByte+60);
  // at the edge of the screen, go back to the beginning:
  if (xPos >= width) {
    xPos = 0;
    background(0);
  } else {
    // increment the horizontal position:
    xPos++;
  }
}

void serialEvent (Serial myPort) {
  // get the ASCII string:
  String inString = myPort.readStringUntil('\n');

  if (inString != null) {
    // trim off any whitespace:
    inString = trim(inString);
    // convert to an int and map to the screen height:
    inByte = float(inString);
    println(inByte);
    inByte = map(inByte, 0, 1023, 0, height)*200+200;
  }
}
						

And this is what the output of that code looks like:

This was a pretty satisfying result, but I wanted more features. Features such as the ability to change the baud rate of the monitor, or to be able to select the com port that i want from a list of available devices, or the ability to control the size of the graph being displayed. So I looked around on the internet some more. And I found this page: Serial Port selection in a Processing Application

Here is the unmodified code from the website:


/*------------------------------------------------------------------------------------
   Program:     port_select

   Description: Allows a serial port to be selected and connected to graphically.
                Has the following buttons:
                Up         - scrolls up through the serial port list 
                Down       - scrolls down through the serial port list
                Connect    - connects to the selected serial port
                Disconnect - disconnects from the serial port allowing a new serial
                             port to be connected to
                Refresh    - refreshes the list of serial ports. Useful if a new
                             serial device is connected to the PC after this app-
                             lication is started
                
   Purpose:     Allows the serial port to be selected within an application instead
                of hard-coding the port number
                
   Hardware:    Can be used to connect to Arduino or other serial devices
   
   Software:    Developed using Processing 2.2.1 (processing.org)
                Uses the Button class from:
                http://blog.startingelectronics.com/a-simple-button-for-processing-language-code/
                
   Date:        21 July 2015   Author:   W.A. Smith, http://startingelectronics.org
   
------------------------------------------------------------------------------------*/

import processing.serial.*;

Serial serial_port = null;        // the serial port

// serial port buttons
Button btn_serial_up;              // move up through the serial port list
Button btn_serial_dn;              // move down through the serial port list
Button btn_serial_connect;         // connect to the selected serial port
Button btn_serial_disconnect;      // disconnect from the serial port
Button btn_serial_list_refresh;    // refresh the serial port list
String serial_list;                // list of serial ports
int serial_list_index = 0;         // currently selected serial port 
int num_serial_ports = 0;          // number of serial ports in the list

void setup() {
  // set the window size
  size (640, 480);
  
  // create the buttons
  btn_serial_up = new Button("^", 140, 10, 40, 20);
  btn_serial_dn = new Button("v", 140, 50, 40, 20);
  btn_serial_connect = new Button("Connect", 190, 10, 100, 25);
  btn_serial_disconnect = new Button("Disconnect", 190, 45, 100, 25);
  btn_serial_list_refresh = new Button("Refresh", 190, 80, 100, 25);
  
  // get the list of serial ports on the computer
  serial_list = Serial.list()[serial_list_index];
  
  //println(Serial.list());
  //println(Serial.list().length);
  
  // get the number of serial ports in the list
  num_serial_ports = Serial.list().length;
}

void mousePressed() {
  // up button clicked
  if (btn_serial_up.MouseIsOver()) {
    if (serial_list_index > 0) {
      // move one position up in the list of serial ports
      serial_list_index--;
      serial_list = Serial.list()[serial_list_index];
    }
  }
  // down button clicked
  if (btn_serial_dn.MouseIsOver()) {
    if (serial_list_index < (num_serial_ports - 1)) {
      // move one position down in the list of serial ports
      serial_list_index++;
      serial_list = Serial.list()[serial_list_index];
    }
  }
  // Connect button clicked
  if (btn_serial_connect.MouseIsOver()) {
    if (serial_port == null) {
      // connect to the selected serial port
      serial_port = new Serial(this, Serial.list()[serial_list_index], 9600);
    }
  }
  // Disconnect button clicked
  if (btn_serial_disconnect.MouseIsOver()) {
    if (serial_port != null) {
      // disconnect from the serial port
      serial_port.stop();
      serial_port = null;
    }
  }
  // Refresh button clicked
  if (btn_serial_list_refresh.MouseIsOver()) {
    // get the serial port list and length of the list
    serial_list = Serial.list()[serial_list_index];
    num_serial_ports = Serial.list().length;
  }
}

void draw() {
  // draw the buttons in the application window
  btn_serial_up.Draw();
  btn_serial_dn.Draw();
  btn_serial_connect.Draw();
  btn_serial_disconnect.Draw();
  btn_serial_list_refresh.Draw();
  // draw the text box containing the selected serial port
  DrawTextBox("Select Port", serial_list, 10, 10, 120, 60);
}

// function for drawing a text box with title and contents
void DrawTextBox(String title, String str, int x, int y, int w, int h)
{
  fill(255);
  rect(x, y, w, h);
  fill(0);
  textAlign(LEFT);
  textSize(14);
  text(title, x + 10, y + 10, w - 20, 20);
  textSize(12);  
  text(str, x + 10, y + 40, w - 20, h - 10);
}

// button class used for all buttons
class Button {
  String label;
  float x;    // top left corner x position
  float y;    // top left corner y position
  float w;    // width of button
  float h;    // height of button
  
  // constructor
  Button(String labelB, float xpos, float ypos, float widthB, float heightB) {
    label = labelB;
    x = xpos;
    y = ypos;
    w = widthB;
    h = heightB;
  }
  
  // draw the button in the window
  void Draw() {
    fill(218);
    stroke(141);
    rect(x, y, w, h, 10);
    textAlign(CENTER, CENTER);
    fill(0);
    text(label, x + (w / 2), y + (h / 2));
  }
  
  // returns true if the mouse cursor is over the button
  boolean MouseIsOver() {
    if (mouseX > x && mouseX < (x + w) && mouseY > y && mouseY < (y + h)) {
      return true;
    }
    return false;
  }
}

					

And this is what I get upon executing the code:

The code works very well, with the up and down buttons used for choosing the relevant com port and the connect disconnect button working as expected. The one missing link was to control the baud rates at which the serial plotter operates. I added that by taking bits and pieces from the existing code. I also added a section where a user can input an amplification factor that will be applied to the graph display. This is what the final code looks like after I made the changes:


// Graphing sketch

// This program takes ASCII-encoded strings from the serial port at 9600 baud
// and graphs them. It expects values in the range 0 to 1023, followed by a
// newline, or newline and carriage return

// created 20 Apr 2005
// updated 24 Nov 2015
// by Tom Igoe
// updated 19 May 2021
// by Mohit Ahuja 
// This example code is in the public domain.

import processing.serial.*;

Serial serial_port;        // The serial port
int xPos = 1;         // horizontal position of the graph
float inByte = 0;

// serial port buttons
Button btn_serial_up;              // move up through the serial port list
Button btn_serial_dn;              // move down through the serial port list
Button btn_serial_connect;         // connect to the selected serial port
Button btn_serial_disconnect;      // disconnect from the serial port
Button btn_serial_list_refresh;    // refresh the serial port list
Button btn_baud_up;
Button btn_baud_dn;
Button btn_baud_sel;

String baud[]={"300", "400", "1200", "2400", "4800", "9600", "19200", "38400", "57600", "74880", "115200", "230400"};
String baudrate = baud[4];
int baud_index = 0;

String typing = "";                // Variable to store text currently being typed
String saved = "";                 // Variable to store saved text when return is hit

String serial_list;                // list of serial ports
int serial_list_index = 0;         // currently selected serial port 
int num_serial_ports = 0;          // number of serial ports in the list

int connected =0;
int factor=1;
int h=300;

void setup () {
  // set the window size:
  size(700, 700);

  // create the buttons
  btn_serial_up = new Button("^", 140, 10, 40, 20);
  btn_serial_dn = new Button("v", 140, 30, 40, 20);
  btn_serial_connect = new Button("Connect", 190, 10, 80, 40);
  btn_serial_disconnect = new Button("Disconnect", 280, 10, 80, 40);
  btn_serial_list_refresh = new Button("Refresh", 370, 10, 100, 40);

  btn_baud_up = new Button("^", 140, 60, 40, 20);
  btn_baud_dn = new Button("v", 140, 80, 40, 20);

  // get the list of serial ports on the computer
  serial_list = Serial.list()[serial_list_index];

  // List all the available serial ports
  // if using Processing 2.1 or later, use Serial.printArray()
  println(Serial.list());

  // get the number of serial ports in the list
  num_serial_ports = Serial.list().length;

  // set initial background:
  background(0);
}

void mousePressed() {
  // up button clicked
  if (btn_serial_up.MouseIsOver()) {
    if (serial_list_index > 0) {
      // move one position up in the list of serial ports
      serial_list_index--;
      serial_list = Serial.list()[serial_list_index];
    }
  }
  // down button clicked
  if (btn_serial_dn.MouseIsOver()) {
    if (serial_list_index < (num_serial_ports - 1)) {
      // move one position down in the list of serial ports
      serial_list_index++;
      serial_list = Serial.list()[serial_list_index];
    }
  }
  // Connect button clicked
  if (btn_serial_connect.MouseIsOver()) {
    if (serial_port == null) {
      // connect to the selected serial port
      serial_port = new Serial(this, Serial.list()[serial_list_index], Integer.valueOf(baudrate));

      // don't generate a serialEvent() unless you get a newline character:
      serial_port.bufferUntil('\n');

      connected=1;

      fill(0);
      rect(10, 100, 480, 20);
      fill(255);
      text(serial_list+" connected at "+baudrate+" baudrate and amplification "+saved, 10, 115);
    }
  }
  // Disconnect button clicked
  if (btn_serial_disconnect.MouseIsOver()) {
    if (serial_port != null) {
      // disconnect from the serial port
      serial_port.stop();
      serial_port = null;
      connected=0;
      fill(0);
      rect(10, 100, 480, 20);
      fill(255);
      text(serial_list+" diconnected", 10, 115);
    }
  }
  // Refresh button clicked
  if (btn_serial_list_refresh.MouseIsOver()) {
    // get the serial port list and length of the list
    serial_list = Serial.list()[serial_list_index];
    num_serial_ports = Serial.list().length;
  }
  // up button clicked
  if (btn_baud_up.MouseIsOver()) {
    if (baud_index > 0) {
      // move one position up in the list of serial ports
      baud_index--;
      baudrate = baud[baud_index];
    }
  }
  // down button clicked
  if (btn_baud_dn.MouseIsOver()) {
    if (baud_index < (baud.length - 1)) {
      // move one position down in the list of serial ports
      baud_index++;
      baudrate = baud[baud_index];
    }
  }
}
void draw () {
  // draw the buttons in the application window
  btn_serial_up.Draw();
  btn_serial_dn.Draw();
  btn_serial_connect.Draw();
  btn_serial_disconnect.Draw();
  btn_serial_list_refresh.Draw();

  btn_baud_up.Draw();
  btn_baud_dn.Draw();

  // draw the text box containing the selected serial port
  DrawTextBox(serial_list, 10, 10, 120, 40);
  DrawTextBox(baudrate, 10, 60, 120, 40);

  int indent=18;
  fill(255);
  rect(10, 135, 400, 20);
  fill(0);
  text("Amplification factor: " + typing, indent, 150);

  stroke(50, 50, 255);
  line(0, height-h-100, width, height-h-100);
  stroke(50, 50, 255);
  line(0, height-h, width, height-h);
  stroke(50, 50, 255);
  line(0, height-h+100, width, height-h+100);

  // draw the line:
  if (connected==1) {
    stroke(255);
    line(xPos, height, xPos, height - inByte);
    stroke(0);
    line(xPos, height+2, xPos, height - inByte+2);

    stroke(50, 50, 255);
    line(0, height-h-100, width, height-h-100);
    stroke(50, 50, 255);
    line(0, height-h, width, height-h);
    stroke(50, 50, 255);
    line(0, height-h+100, width, height-h+100);

    // at the edge of the screen, go back to the beginning:
    if (xPos >= width) {
      xPos = 0;
      background(0);
    } else {
      // increment the horizontal position:
      xPos++;
    }
  }
}

void serialEvent (Serial serial_port) {
  // get the ASCII string:
  String inString = serial_port.readStringUntil('\n');
  if (inString != null) {
    // trim off any whitespace:
    inString = trim(inString);
    // convert to an int and map to the screen height:
    inByte = float(inString);
    inByte = map(inByte, 0, 1023, 0, 1000*factor)+h;
    println(inByte);
  }
}

void keyPressed() {
  // If the return key is pressed, save the String and clear it
  if (key == '\n' ) {
    saved = typing;
    factor=Integer.valueOf(saved);
    // A String can be cleared by setting it equal to ""
    typing = "";
    fill(0);
    rect(10, 100, 480, 20);
    fill(255);
    text(serial_list+" connected at "+baudrate+" baudrate and amplification "+saved, 10, 115);
  } else if (key==BACKSPACE) {
    typing = typing.substring( 0, typing.length()-1 );
  } else switch(key) {
  case '1':
  case '2':
  case '3':
  case '4':
  case '5':
  case '6':
  case '7':
  case '8':
  case '9':
  case '0':
    // Otherwise, concatenate the String
    // Each character typed by the user is added to the end of the String variable.
    typing = typing + key;
    break;
  }
}

// function for drawing a text box with title and contents
void DrawTextBox(String str, int x, int y, int w, int h)
{
  fill(255);
  rect(x, y, w, h);
  fill(0);
  textAlign(LEFT);
  textSize(12);  
  text(str, x + 10, y + 15, w - 20, h - 10);
}

// button class used for all buttons
class Button {
  String label;
  float x;    // top left corner x position
  float y;    // top left corner y position
  float w;    // width of button
  float h;    // height of button

  // constructor
  Button(String labelB, float xpos, float ypos, float widthB, float heightB) {
    label = labelB;
    x = xpos;
    y = ypos;
    w = widthB;
    h = heightB;
  }

  // draw the button in the window
  void Draw() {
    fill(218);
    stroke(141);
    rect(x, y, w, h, 10);
    textAlign(CENTER, CENTER);
    fill(0);
    text(label, x + (w / 2), y + (h / 2));
  }

  // returns true if the mouse cursor is over the button
  boolean MouseIsOver() {
    if (mouseX > x && mouseX < (x + w) && mouseY > y && mouseY < (y + h)) {
      return true;
    }
    return false;
  }
}
						

This is how the interface works:

This is the window that greets you when you first start the program.

This is how everything works:

I connected the plotter with COM6, which is the name of the COM port to which the FTDI Breakout board is connected. After that I typed the amplification factor that I wanted. We don't need to click anywhere to start typing. Make sure that the number is a positive integer. Also pressing the backspace button without typing anything will lead to the program hanging up. So don't do that:

After that you may press enter to set the amplification factor. You will see a message confirming your selections as shown below:

After setting all the parameters, I clicked on the Connect button, which made the code display the output in the following way:

To test the Disconnect button, I clicked on it, and as expected, the graph stopped. Also there is a message display that informed me that the COM6 port has been disconnected as seen below:

Just for fun, I tried to change the amplification factor to 50 and then reconnect with the port, and this was the output:

I uploaded a code to the hello echo world board that sends 0 when the button on the board is pressed, and 1 when it is not pressed. Here's the program:


/*
  Software serial multple serial test

  Receives from the hardware serial, sends to software serial.
  Receives from software serial, sends to hardware serial.

  The circuit:
   RX is digital pin 10 (connect to TX of other device)
   TX is digital pin 11 (connect to RX of other device)

  Note:
  Not all pins on the Mega and Mega 2560 support change interrupts,
  so only the following can be used for RX:
  10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69

  Not all pins on the Leonardo and Micro support change interrupts,
  so only the following can be used for RX:
  8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).

  created back in the mists of time
  modified 25 May 2012
  by Tom Igoe
  based on Mikal Hart's example

  This example code is in the public domain.

*/
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 1); // RX, TX

void setup() {
  mySerial.begin(4800);
  pinMode(3, INPUT_PULLUP);
}

void loop() { // run over and over
  float val = digitalRead(3);
  mySerial.println(val);
}
						

Here is a video of the interface in action with the button input program

To convert this Processing sketch into an executable interface, I did the following:

I start by clicking on File>Export Application

In the new window that opens up, I selected the operating system(Windows), I seleced the Embed Java option and then I clicked on Export.

In the directory where your program is located, you will see two new folders appear, one folder has the 32-bit version of your application and the other folder has the 64 bit version, as it can be seen from the name of the folders:

I opened the 64 bit folder and ran the exe file there, which immediately started the program as expected:

I wanted to link the file of this software in my repository, but unfortunately, when I archived the 64 bit application and checked its size, i found out that it was 80MB in size, which is way above the limit of the size of files that are allowed to be uploaded to the repository per push. So I went back to the Export Application command within Processing and deselected the Embed Java option. This reduced the size of the exported application significantly, as the archived folder is now ~4MB. The only issue is that now users will have to install Java before running the application Here is the linked application:

Serial_Plotter the app

Using Python

The Arduino code


/*
  Software serial multple serial test

  Receives from the hardware serial, sends to software serial.
  Receives from software serial, sends to hardware serial.

  The circuit:
   RX is digital pin 10 (connect to TX of other device)
   TX is digital pin 11 (connect to RX of other device)

  Note:
  Not all pins on the Mega and Mega 2560 support change interrupts,
  so only the following can be used for RX:
  10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69

  Not all pins on the Leonardo and Micro support change interrupts,
  so only the following can be used for RX:
  8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).

  created back in the mists of time
  modified 25 May 2012
  by Tom Igoe
  based on Mikal Hart's example

  This example code is in the public domain.

*/
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 1); // RX, TX

void setup() {
  mySerial.begin(4800);
  pinMode(3, INPUT_PULLUP);
}

void loop() { // run over and over
  float val = digitalRead(3);
  mySerial.print(val);
}
					

Downloading Thonny Python IDE

Using Python


import serial
import time
arduino = serial.Serial(port='COM6', baudrate=4800, timeout=.1)
def readdata():
    data = arduino.readline(4)
    return data
while True:
    value = readdata()
    print(value) # printing the value

					

Running the program

As you can see in the screenshot below, there is a series of ones that is being sent by the board. This is because the button is connected to 5V via internal pullup.

As soon as the button is pressed, the output becomes zero. This is because the button pin is now connected to GND directly..