Visualising Arduino PWM and I/O Values with Processing

Visualising Arduino PWM and I/O Values with Processing

This project is the natural completion of Remotino, and serves to visualize on PC the PWM and I / O values present in Arduino Nano.

  • 1,246 views
  • 0 comments
  • 5 respects

Components and supplies

Apps and online services

About this project

This project is the natural completion of Remotino, and serves to visualize on PC the PWM and I / O values present in Arduino Nano, on the PC video using Processing.

I created a virtual console on a PC, connected to the Arduino Nano USB serial port. Whenever a procedure changes the value of the PWM for the engines, or the status of an output, Nano transmits new values with a simple ASCII code to the PC, which decodes it and displays it.

whit Processing Console
Original Project

Original project on https://create.arduino.cc/projecthub/pautax/rail-road-model-ir-remote-control-remotino-nano-2fe777

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Questo progetto è il completamento naturale di Remotino, e serve a visualizzare su PC I valori di PWM e I/O presenti in Arduino Nano, sul video del PC usando Processing.

Ho creato una console virtuale su PC, connessa con la seriale USB di Arduino Nano. Ogni volta che una procedura cambia valore del PWM per I motori, o lo stato di un Output, Nano trasmette I nuovi valori con una semplce codifica ascii al pc, che lo decodifica e lo visualizza.

Code

tachi_train4Processing
processing source code
/** Example of selecting a particular Serial Port

* pautax: ripete la porta seriale selezionata sull'area nera
* gauge 3 scan continuo

 *  from the list of all possibilities returned
 *  in Serial.list().
 *
 *  Uses showInputDialog box kindly suggested to
 *  me by GoToLoop.  Thank you, GoToLoop! 
*/
 import processing.serial.*;
 import static javax.swing.JOptionPane.*;

Serial myPort;  // Create object from Serial class
String StringFromSerialLine;     // Data received from the serial port
String OldStringFromSerialLine;     // Last data Data received from the serial port
String ExtractStr;   // stringa del valore esempi da "PWM1=20| DIR1=1 | PWM2=0 | DIR2=0 | MOTORON=1" PWM1 vale "20"
int ExtractVal;    //come sopra ma convertito in intero 
int LenSFSL; // LenghtStringFromSerialLine

final boolean debug = true;

Gauge Power1, minute, hour;
int Power1old, minold, hourold;
int Power1_val = 0;

PImage img;
PImage img1;
PImage img2;

void setup(){
  size(790, 600);
  Power1 = new Gauge(250, 0, 255, 25, "Power1"); //(width, begin, end, quotation scale, name gauge)
  minute = new Gauge(250, 0, 255, 25, "Power2");
  hour = new Gauge(250, 0, 255, 25,  "Power3");
  Power1old = 100;  //val can never be 100, first run will always draw
  minold = 100;
  hourold = 100;
  
 

  String COMx, COMlist = "";
/*
  Other setup code goes here - I put this at
  the end because of the try/catch structure.
*/
  try {
    if(debug) printArray(Serial.list());
    int i = Serial.list().length;
    if (i != 0) {
      if (i >= 2) {
        // need to check which port the inst uses -
        // for now we'll just let the user decide
        for (int j = 0; j < i;) {
          COMlist += char(j+'a') + " = " + Serial.list()[j];
          if (++j < i) COMlist += ",  ";
        }
        COMx = showInputDialog("Which COM port is correct? (a,b,..):\n"+COMlist);
        if (COMx == null) exit();
        if (COMx.isEmpty()) exit();
        i = int(COMx.toLowerCase().charAt(0) - 'a') + 1;
      }
      String portName = Serial.list()[i-1];
      if(debug) println(portName);
      myPort = new Serial(this, portName, 115200); // change baud rate to your liking
      myPort.bufferUntil('\n'); // buffer until CR/LF appears, but not required..
    }
    else {
      showMessageDialog(frame,"Device is not connected to the PC");
      exit();
    }
  }
  catch (Exception e)
  { //Print the type of error
    showMessageDialog(frame,"COM port is not available (may\nbe in use by another program)");
    println("Error:", e);
    exit();
  }  
  
  
  
  
  
  
  
  
  // I know that the first port in the serial list on my mac
  // is Serial.list()[0].
  // On Windows machines, this generally opens COM1.
  // Open whatever port is the one you're using.
//  String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
//  myPort = new Serial(this, portName, 115200);  

  
  
//draw grid
// translate(width/2, height/2);
/*B
      for ( int i = 0 ; i < width ; i+=49) {
        for ( int j = 0 ; j < height ; j+=49) {
          //
          line(i, j, i+25, j);
          line(i, j, i, j+25);     
          line(i+25, j, i+25, j+25);
          line(i, j+25, i+25, j+25);
          //line(i, j, 10, 10);
        }
      }
*/




   // spia moton
   fill( 50, 50, 50 ); // colore grigio Drives off
   //strokeWeight( 3 );
   stroke( 255 );
   ellipse( 50, 250, 40, 40 );  
   textSize(18);
   fill(0, 0, 0);
   text("POWER", 17, 295); 

   // spia boost
   fill( 50, 50, 50 ); // colore grigio Drives off
   ellipse( 160, 250, 40, 40 );  
   textSize(18);
   fill(0, 0, 0);
   text("BOOST", 130, 295); 



  //scambio
  img = loadImage( "../scambio.jpg" );
  image( img, 250, 250 );
  image( img, 500, 250 );
  image( img, 250, 425 );
  image( img, 500, 425 );
  text("SCAMBIO 2-1", 270, 360); 
  text("SCAMBIO 4-3", 520, 360); 
  text("SCAMBIO 6-5", 270, 535); 
  text("SCAMBIO 8-7", 520, 535); 

  img1 = loadImage( "../scambio1.jpg" );
  img2 = loadImage( "../scambio2.jpg" );

   //frecce della direzione
   fill( 50, 50, 50 ); // colore grigio Drives off
   
   // indietro 1
   //strokeWeight( 1 );
   beginShape();
   vertex(75,325);
   vertex(75,375);
   vertex(40,350);
   endShape(CLOSE);

   // avanti 1
   beginShape();
   vertex(100,325);
   vertex(100,375);
   vertex(135,350);
   endShape(CLOSE);

   // indietro 2
   beginShape();
   vertex(75,450);
   vertex(75,500);
   vertex(40,475);
   endShape(CLOSE);

   // avanti 2
   beginShape();
   vertex(100,450);
   vertex(100,500);
   vertex(135,475);
   endShape(CLOSE);

   fill(0, 0, 0);
   text("LINEA 1", 40, 400); 
   text("LINEA 2", 40, 525); 

   
}

void draw(){
  
  /*
  Power1_val++;
  if (Power1_val > 59){
      Power1_val = 0;
  }
  */
    
 // drw3gauge();
     
  if ( myPort.available() > 0) 
  {  // If data is available,
     StringFromSerialLine = myPort.readStringUntil('\n');         // read it and store it in StringFromSerialLine
  } 
  
  if (StringFromSerialLine != null) {
  
    if (StringFromSerialLine != OldStringFromSerialLine){
       println(StringFromSerialLine); //print it out in the console
       OldStringFromSerialLine = StringFromSerialLine; //save
       
       LenSFSL = StringFromSerialLine.length();
       //ora si decodificano i valori
       //estrae valore di PWM1 da stringa tipo "PWM1=20| DIR1=1 | PWM2=0 | DIR2=0 | MOTORON=1"
       if (LenSFSL > 3){
           ExtractStr =  StringFromSerialLine.substring(0, 4);
           print("LenSFSL ");
           println(LenSFSL);

           switch(ExtractStr) {

             case "PWM1": 
                print(", ExtractStr ");
                print(ExtractStr);
                print(", Trovato PWM1 ");  // 
                ExtractStr =  StringFromSerialLine.substring(5);
                print(", ExtractStr ");
                print(ExtractStr);
                ExtractVal = Integer.parseInt(ExtractStr.trim());                
                //ExtractVal = int(ExtractStr);
                print(" , ExtractVal ");
                println(ExtractVal);  // 
                Power1_val = ExtractVal;               
              break;

             case "MOTN": 
                print(", ExtractStr ");
                print(ExtractStr);
                print(", Trovato MOTN ");  // 
                ExtractStr =  StringFromSerialLine.substring(5);
                print(", ExtractStr ");
                print(ExtractStr);
                ExtractVal = Integer.parseInt(ExtractStr.trim());                
                //ExtractVal = int(ExtractStr);
                print(" , ExtractVal ");
                println(ExtractVal);  // 
                if (ExtractVal == 0){
                   fill( 50, 50, 50 ); // colore grigio Drives off
                } else {
                   //fill( 255, 0, 0 ); // colore rosso Drives on
                   fill( 0, 255, 0 ); // colore verde Drives on
                }
                //strokeWeight( 3 );
                stroke( 255 );
                ellipse( 50, 250, 40, 40 ); 
              break;



             case "Boos": 
                print(", ExtractStr ");
                print(ExtractStr);
                print(", Trovato Boost ");  // 
                ExtractStr =  StringFromSerialLine.substring(5);
                print(", ExtractStr ");
                print(ExtractStr);
                ExtractVal = Integer.parseInt(ExtractStr.trim());                
                //ExtractVal = int(ExtractStr);
                print(" , ExtractVal ");
                println(ExtractVal);  // 
                if (ExtractVal == 0){
                   fill( 50, 50, 50 ); // colore grigio Drives off
                } else {
                   fill( 255, 0, 0 ); // colore rosso boost on
                   //fill( 0, 255, 0 ); // colore verde Drives on
                }
                //strokeWeight( 3 );
                stroke( 255 );
                ellipse( 160, 250, 40, 40 );  
              break;

             //PROCESSA GLI SCAMBI
             case "RLON":
                //strokeWeight( 3 );
                print(", ExtractStr ");
                print(ExtractStr);
                print(", Trovato RLON ");  // 
                ExtractStr =  StringFromSerialLine.substring(5);
                print(", ExtractStr ");
                print(ExtractStr);
                ExtractVal = Integer.parseInt(ExtractStr.trim());                
                //ExtractVal = int(ExtractStr);
                print(" , ExtractVal ");
                println(ExtractVal);  // 
                if (ExtractVal == 0){
                  image( img1, 250, 250 );
                }
                if (ExtractVal == 1){
                  image( img2, 250, 250 );
                }
                if (ExtractVal == 2){
                  image( img1, 500, 250 );
                }
                if (ExtractVal == 3){
                  image( img2, 500, 250 );
                }

                if (ExtractVal == 4){
                  image( img1, 250, 425 );
                }
                if (ExtractVal == 5){
                  image( img2, 250, 425 );
                }
                if (ExtractVal == 6){
                  image( img1, 500, 425 );
                }
                if (ExtractVal == 7){
                  image( img2, 500, 425 );
                }
              break;
              
             //processa le direzioni frecce gialle
             case "DIR1": 
                //strokeWeight( 3 );
                print(", ExtractStr ");
                print(ExtractStr);
                print(", Trovato DIR1 ");  // 
                ExtractStr =  StringFromSerialLine.substring(5);
                print(", ExtractStr ");
                print(ExtractStr);
                ExtractVal = Integer.parseInt(ExtractStr.trim());                
                //ExtractVal = int(ExtractStr);
                print(" , ExtractVal ");
                println(ExtractVal);  // 

                if (ExtractVal == 1){
                   println("Avanti 1");  // 
                   fill( 10, 3, 255 ); // colore grigio Drives off
                   beginShape();
                   vertex(100,325);
                   vertex(100,375);
                   vertex(135,350);
                   endShape(CLOSE);

                   fill( 50, 50, 50 ); // colore grigio Drives off   
                   // indietro 1 grigio
                   beginShape();
                   vertex(75,325);
                   vertex(75,375);
                   vertex(40,350);
                   endShape(CLOSE);

                
                }
                if (ExtractVal == 0){
                   println("Indietro 1");  // 
                   fill( 255, 255, 0 ); // colore grigio Drives off
                   // indietro 1
                   beginShape();
                   vertex(75,325);
                   vertex(75,375);
                   vertex(40,350);
                   endShape(CLOSE);

                   fill( 50, 50, 50 ); // colore grigio Drives off
                   // avanti 1
                   beginShape();
                   vertex(100,325);
                   vertex(100,375);
                   vertex(135,350);
                   endShape(CLOSE);   
                }
              break;





//DIR1=1   avanti    DIR1=0 indietro



              //default:
              //println("Zulu");   // Does not execute
              //break;
            }   // switch(ExtractStr)
         } // if (LenSFSL > 3)
       } // if (StringFromSerialLine != OldStringFromSerialLine)
       
  } //if (StringFromSerialLine != null)
  
  
  //-------------------------------------------------

  
  
  
  
  drw3gauge();

}


void drw3gauge(){
  //to save resource, only redraw when time has changed
  if (Power1_val != Power1old){
    Power1.update(Power1_val);
    pushMatrix();
    translate(530, 10);
    Power1.display();
    popMatrix();
    Power1old = Power1_val;
  }
  if (minute() != minold){
    minute.update(minute());
    pushMatrix();
    translate(270, 10);
    minute.display();
    popMatrix();
    minold = minute();
  }
  if (hour() != hourold){
    //time received is 24 hour notation, gauge has scale of 12
    if (hour() <= 11){
      hour.update(hour());
    } else {
      hour.update(hour()-12);
    }
    pushMatrix();
    translate(10, 10);
    hour.display();
    popMatrix();
    hourold = hour();
  }
}

class Gauge{
  PVector gsize;  //width & height gauge
  PVector gscale;  //start & end value scale
  PVector gneedle; //length & angle needle
  int gsteps;
  float gline;
  String gname;
   
  Gauge(float tempx, float templow, float temphigh, float templine, String tempname){
    float gwidth = tempx;
    float gheight = 26*tempx/35;
    float glow = templow;
    float ghigh = temphigh;
    gline = templine;
    gname = tempname;
    gsteps = int(temphigh - templow) + 1;
    gsize = new PVector(gwidth, gheight);
    gscale = new PVector(glow, ghigh);
    gneedle = new PVector(5*gsize.y/8, map(second(), 0, 59, radians(35), radians(145)));
  }
 
  void display(){
    noStroke();
    //backcover
    fill(50);
    rect(0, 0, gsize.x, gsize.y);
    fill(255);
    textAlign(CENTER);
    textSize(14);
    text(gname, gsize.x/2, 15);
    //scale
    stroke(255, 200);
    //strokeWeight(2);
    for (int i = 0; i < gsteps; i++){
      pushMatrix();
      translate(gsize.x/2, 11*gsize.y/12);
      rotate(PI + map(i, gscale.x, gscale.y, radians(35), radians(145)));
      if (i%gline == 0){
        line(gneedle.x-5, 0, gneedle.x+5, 0);
        translate(gneedle.x+10, 0);
        rotate(HALF_PI);
        textSize(9);
        text(i, 0, 0);
      } else {
        point(gneedle.x, 0);
      } 
      popMatrix();
    }
    noStroke();
    //needle
    stroke(255, 0, 0);
    //strokeWeight(3);
    pushMatrix();
    translate(gsize.x/2, 11*gsize.y/12);
    rotate(PI + gneedle.y);
    line(0, 0, gneedle.x, 0);
    popMatrix();
    noStroke();
    //frontcover
    fill(150, 180);
    rect(0, 4.5*gsize.y/6, gsize.x, 1.5*gsize.y/6);
    fill(255, 0, 0);
    ellipseMode(CENTER);
    ellipse(gsize.x/2, 11*gsize.y/12, 10, 10);
  }
 
  void update(float tempgval){
    float gvalue = tempgval;
    gneedle.y = map(gvalue, gscale.x, gscale.y, radians(35), radians(145));
  }
} 

Schematics

the job
Job fvkpj6daa8

Comments

Similar projects you might like

Visualising sensor data using Arduino and Processing

Project tutorial by sowmith mandadi

  • 43,438 views
  • 3 comments
  • 39 respects

Scaling an Image in Processing with Ultrasonic Sensor

Project tutorial by Najad

  • 1,088 views
  • 0 comments
  • 12 respects

How to Control 2WD Robot Wirelessly Through Processing

Project tutorial by Ahmed Ibrahim Ahmed

  • 1,715 views
  • 2 comments
  • 13 respects

6x6x6 LED Cube with Processing App

Project tutorial by AdiOdi

  • 538 views
  • 0 comments
  • 2 respects

Ultrasonic Rangefinder with Processing

Project showcase by TEAM DIY

  • 7,160 views
  • 3 comments
  • 16 respects

Proyecto: Arduino + Processing + Bluetooth HC-05

Project showcase by victruino

  • 4,316 views
  • 0 comments
  • 4 respects
Add projectSign up / Login