visualization Arduino programm via processing - read serial Input doesnt work

edited March 2017 in Arduino

Hello, Me and a friend are absolute noobs in programming but try to create a bop it like game. To realize the project we are using Arduino and Processing. The Arduino Code runs the time, counts the points, etc. The Arduino part works, but now we want to use processing to visualize everything. Therefore we connect the Arduinoboard via USB to the Computer, but we have serious problems to read the serial data. In the Console we can see there is something in the Buffer, but we cant seperate the data or save it in our proseccing variables!

The question now is, how do we read the serial data correctly, how do we save the data for player 1 in the variable of the processing programm and seperate it from the data of the random number and the data of player2 and vice versa? Is there a better way than our actual code?

Nothing we found on the internet could help us yet, hopefully somebody here can!

Arduino Part:

#define DEBUG 1

         int ledPin = 13;
         int Buzzer = 2;
         int Spieler1Taster1 = 3;
         int Spieler1Taster2 = 4;
         int Spieler1Taster3 = 5;
         int Spieler2Taster1 = 6;
         int Spieler2Taster2 = 8;
         int Spieler2Taster3 = 9;
         int threshold= 800;                                   //the microphone threshold sound level at which the LED will turn on
         int Zufall1 = 10;
         int Zufall2 = 11;
         int Zufall3 = 12;

         int Spieler1Taster1HIGH = 0;
         int Spieler1Taster2HIGH = 0;
         int Spieler1Taster3HIGH = 0;
         int Spieler2Taster1HIGH = 0;
         int Spieler2Taster2HIGH = 0;
         int Spieler2Taster3HIGH = 0;
         int buttonState;
         int ledState = HIGH;
         int zufall = 0;
         int counter1 = 0;
         int counter2 = 0;
         int sample;                                          //the variable that will hold the value read from the microphone each time
         int n = 0;
         int halt = 0;
         int y;
         int counter1x;

unsigned long previousMillis = 99999999999;
unsigned long previousMillis_Reset = 0;
   const long interval = 10000;
   const long interval_Reset = 100;
   const long reset = 3000;

void setup()
{
     Serial.begin(9600);
     pinMode(13, OUTPUT);
     pinMode(12, OUTPUT);
     pinMode(11, OUTPUT);
     pinMode(10, OUTPUT);
     pinMode(9, INPUT);
     pinMode(8, INPUT);
     pinMode(6, INPUT);
     pinMode(5, INPUT);
     pinMode(4, INPUT);
     pinMode(3, INPUT);
     pinMode(2, INPUT);
}
void loop()   
{

     unsigned long currentMillis = millis();

     buttonState = digitalRead(Buzzer);
  if (buttonState == HIGH)                                            
  {
     previousMillis = currentMillis;  
     counter1 = 0;
     counter2 = 0;  
  }
  if ( currentMillis - previousMillis < interval)                     
{
     //Serial.print("Zeit ");
     //Serial.println((currentMillis - previousMillis)/1000);
     digitalWrite(13, HIGH);
     zufall = random(3) + 1;


  if (DEBUG)
  {
     }

     //delay(100);

  if (zufall == 1)        
  {
     digitalWrite(10, HIGH); // set the LED on
     digitalWrite(11, LOW); // set the LED off
     digitalWrite(12, LOW); // set the LED off
  }
  if (zufall == 2)
  {
     digitalWrite(10, LOW); // set the LED on
     digitalWrite(11, HIGH); // set the LED off
     digitalWrite(12, LOW); // set the LED off
  }
  if (zufall == 3)
  {
     digitalWrite(10, LOW); // set the LED on
     digitalWrite(11, LOW); // set the LED off
     digitalWrite(12, HIGH); // set the LED off
  }
  if (zufall == 4)
  {

  }  
     Serial.print("Zufallszahl: ");
     Serial.println(zufall, DEC);


     buttonState = digitalRead(Spieler1Taster1);
  if (buttonState == HIGH)
  {
     Spieler1Taster1HIGH = 1;
  }  
  if (buttonState == LOW && Spieler1Taster1HIGH == 1)
  {
     counter1++;
     Spieler1Taster1HIGH = 0;
  }    

     buttonState = digitalRead(Spieler1Taster2);
  if (buttonState == HIGH)
  {
     Spieler1Taster2HIGH = 1;
  }
  if (buttonState == LOW && Spieler1Taster2HIGH == 1)
  {
     counter1++;
     Spieler1Taster2HIGH = 0;
  }    

     buttonState = digitalRead(Spieler1Taster3);
  if (buttonState == HIGH)
  {
     Spieler1Taster3HIGH = 1;
  }
  if (buttonState == LOW && Spieler1Taster3HIGH == 1)
  {
     counter1++;
     Spieler1Taster3HIGH = 0;
  }

     buttonState = digitalRead(Spieler2Taster1);
  if (buttonState == HIGH)
  {
     Spieler2Taster1HIGH = 1;
  }
  if (buttonState == LOW && Spieler2Taster1HIGH == 1)
  {
     counter2++;
     Spieler2Taster1HIGH = 0;
  }

     buttonState = digitalRead(Spieler2Taster2);
  if (buttonState == HIGH)
  {
     Spieler2Taster2HIGH = 1;
  }
  if (buttonState == LOW && Spieler2Taster2HIGH == 1)
  {
     counter2++;
     Spieler2Taster2HIGH = 0;
  }

     buttonState = digitalRead(Spieler2Taster3);
  if (buttonState == HIGH)
  {
     Spieler2Taster3HIGH = 1;
  }
  if (buttonState == LOW && Spieler2Taster3HIGH == 1)
  {
     counter2++;
     Spieler2Taster3HIGH = 0;
  }
     delay(100);
     Serial.print("Spieler: ");    
     Serial.println(counter1, DEC);
     Serial.print("Spieler2: ");
     Serial.println(counter2, DEC);
     y = 0;                                                                                   //Gewinner Abfrage
     auswerten(zufall);
}
}

  else
  {   
     digitalWrite(13, LOW);
     digitalWrite(10, LOW);
     digitalWrite(11, LOW);
     digitalWrite(12, LOW);
  }




   if (buttonState == HIGH)
{
     long x = (currentMillis);
   if ((x + reset) < currentMillis)
   {
     reset;
     digitalWrite(13, LOW);
     digitalWrite(10, LOW);
     digitalWrite(11, LOW);
     digitalWrite(12, LOW);
     counter1 = 0;
     counter2 = 0;
   }

   if (n = 0)
   {
     x = currentMillis;
     n = 1;
   }

   else
   {
     x = 0;
     n = 0;
   }
   Serial.println (x);
}




}
    int auswerten(int zufall)
{


    int ende  = 0;
    int endex = 0; //endex =  digitalRead(Spieler1Taster1) + digitalRead(Spieler1Taster2) + digitalRead(Spieler1Taster3) + digitalRead(Spieler2Taster1) + digitalRead(Spieler2Taster2) + digitalRead(Spieler2Taster3);
  do
{
  if (zufall == 1 && digitalRead (Spieler1Taster1))
  {
     ende = 1;
  }
  if (zufall == 1 && digitalRead (Spieler2Taster1))
  {
     ende = 1;
  }
  if (zufall == 2 && digitalRead (Spieler1Taster2))
  {
     ende = 1;
  }
  if (zufall == 2 && digitalRead (Spieler2Taster2))
  {
     ende = 1;
  }
  if (zufall == 3 && digitalRead (Spieler1Taster3))
  {
     ende = 1;
  }
  if (zufall == 3 && digitalRead (Spieler2Taster3))
  {   
     ende = 1;
}
}
  while (!ende);

 unsigned long currentMillis = millis();

      if (currentMillis - previousMillis >= interval)
     {
        if (y == 0)
      {
          if (counter1 > counter2)
          {
           Serial.println("Der Gewinner ist Spieler 1");
           y = 1;
          }     
          if (counter1 < counter2)
          {
           Serial.println("Der Gewinner ist Spieler 2");
           y = 1;
          }
          if ((counter1 == counter2) && ((counter1 || counter2) > 0))
          {
          Serial.println("Unentschieden");
          y = 1;
          }    
       }
     }

  return 0;
}

Processing Part:

import processing.serial.*;
  Serial myPort;

  String counter1;
  String counter2;
  String Zufall;


  //Hintergrundbild
  PImage bg;

  int begin;
  int duration = 30;
  int time = 30;

  // Schriftband
  int band1x, band2x;
  int verlosungszeit;
  int Zeitvormittags;
  int Zeitnachmittags;


  float mill = 0;
  int prevSec = 0;

  float Zaehler1;
  float Zaehler2;
  float Zahl;


void setup()
{
//keine Maus
  noCursor();


//Programm Bildschiurmgröße zuweisen
  size(1920, 1080);


//Hintergrundbild größe zuweisen und Bild auswählen
  background(300);
  size(1920, 1080);
  bg = loadImage("pc-kabel.jpg");


  //Bilder pro Sekunde
  frameRate(50);
begin = millis();
  // Schriftband
  band1x = width;
  band2x = band1x + width;
  Zeitvormittags = 13;
  Zeitnachmittags = 17;


  // Zuweisung serielle Schnittstelle
  String portName = Serial.list()[0];
  myPort = new Serial(this, "COM3", 9600);
  myPort.bufferUntil('\n');
println(Serial.list());
}
//Vollbild
     boolean sketchFullScreen()
  {
    return true;
  }

void serialEvent(Serial myPort)
{
  counter1 = myPort.readStringUntil(',');
  counter2 = myPort.readStringUntil(';');
  Zufall = myPort.readStringUntil('!');

  //counter1 = counter1.substring(0, counter1.length() - 1);
  //counter2 = counter2.substring(0, counter2.length() - 1);
  //Zufall = Zufall.substring(0, Zufall.length() - 1);

  Zaehler1 = float(counter1);
  Zaehler2 = float(counter2);
  Zahl = float(Zufall);
}

  void draw()
  {
    //Hintergrundbild ausführen
    background(bg);
  Zeit();
    //Schriftzug ausführen
  Banner();
    //ermpfangene Werte Anzeigen
  Anzeige();
    //Zähler Spieler 1
  //Zähler1();
    //Zähler Spieler 2
  //Zähler2();
}


void Anzeige()
{
  {
  String inBuffer = myPort.readString();
if (inBuffer != null)
{
  println(Zaehler1);
  println(Zaehler2);
  text(Zaehler1, 200, 800); // Text ausgebe
  text(Zaehler2, 1520, 800); // Text ausgeben
}
else
{

}
print(counter1); //print it out in the console
  textSize (50);
  text("Spieler 1", 200, 200);
  text("Spieler 2", 1520, 200);
}
}




            //****** EIGENE FUNKTIONEN ******//
  //Zähler
  void Zeit()
{
  if (time > 0){  
    time = duration - (millis() - begin)/1000;
     textSize(200);
     text(time, 850, 200); // Text ausgeben
}
}

// Schriftband Verlosungstermine
void Banner()
{
  // Zeitbestimmung
  int stunde;
  String morgen;

  morgen = "";
  stunde = hour();
  if(stunde < Zeitvormittags)
    verlosungszeit = Zeitvormittags;
    else
    {
      if(stunde < Zeitnachmittags)
        verlosungszeit = Zeitnachmittags;
        else
        {
        morgen = "morgen ";
        verlosungszeit = Zeitvormittags;
        }
    }

  // Schriftbänder einblenden
  textSize(50);
  fill(92, 172, 238);
  textAlign(LEFT, CENTER);
  text("Nächste Gutscheinverlosung "+ morgen + "um " + verlosungszeit +" Uhr", band1x, 40);
  text("Nächste Gutscheinverlosung "+ morgen + "um " + verlosungszeit +" Uhr", band2x, 40);

  if(band2x < 0 && band1x < 0)
     band1x =  width;

     band1x = band1x - 2;

  if(band1x < 0 && band2x < 0)
     band2x = width;

     band2x = band2x - 2;
}

Answers

  • Please edit your post, select your code and hit ctrl+o to format your code. Make sure there is an empty line above and below your code.

    How to separate the scores from different players? Without looking at your code layout, the concept is that either [1] you tagged the score value to each player (for example, A:50 meaning player A has a score of 50) or another option is to [2] send a data stream with both scores together separated by a known character everytime you want to know the score. Then you read and process the data in the receiving end. An example of this is that if you have two players, then you send 50,33 where the first number is the score for player A and the second is the score for player B and they are separated by a comma character ','.

    Kf

  • edited March 2017

    Hello, thank you for your help! I read the threads and edited the codes as far as I understood:

       // Serial.print(" ");
         Serial.println(zufall);
         Serial.write(",");    
       //  Serial.print(" ");
         Serial.println(counter1);
         Serial.write(";");
       //  Serial.print(" ");
         Serial.println(counter2); 
         Serial.write("!");
    

    we read the serial Port with those lines of the code.

     import processing.serial.*;
          Serial myPort;
    
         String counter1;
         String counter2;
         String Zufall;
    
         // Zuweisung serielle Schnittstelle
          String portName = Serial.list()[0];
          myPort = new Serial(this, "COM3", 9600);
          myPort.bufferUntil('\n');
    
        void serialEvent(Serial myPort)
        {
          counter1 = myPort.readStringUntil(',');
          counter2 = myPort.readStringUntil(';');
          Zufall = myPort.readStringUntil('!');
    

    This should seperate the data as far as I understood?

    Foto

    Foto above is the Layout

    Foto1

    This foto shows an error we get right after starting the game.

    On the layout should be the Score of each Player - Player 1 on the left handside and player 2 on the right. If we press the start button on the arduino board there is flickering a 0 (cant catch it with screenshot) now but in the console there is the Error "Error, disabling serialEvent() for COM3".

    Where could this error come from?

  • Please copy and paste your error below as it is not possible to read your screenshot.

    Kf

  • edited April 2017 Answer ✓

    In your arduino code, don't use println. Use print instead, like this:

      Serial.print(zufall);
      Serial.print(',');    
      Serial.print(counter1);
      Serial.print(',');
      Serial.println(counter2);
    

    and then in your processing:

    import processing.serial.*;
    Serial myPort;
    
    String counter1;
    String counter2;
    String Zufall;
    
    void setup() {
    
      size(300, 300);
      myPort = new Serial(this, "COM3", 9600);
      myPort.bufferUntil('\n');
    }
    
    void serialEvent(Serial myPort)
    {
      String indata = myPort.readStringUntil('\n');
    
      if(indata!=null){
        String[] tokens =split(trim(indata),',');    
        counter1=tokens[0];
        counter2=tokens[1];
        Zufall=tokens[2];
      }  
    }
    

    Kf

  • I changed the part of my code now, but it didn`t work properly. "Error, disabling serialEvent() for COM3" now doesnt appear when I start the game, but it does when I press the buttons for Player 2 and also when the game ends after 30sec when playing with Player 1. For Player 2 Error: Foto2 For Player 1 Error Foto3

    Still "Error, disabling serialEvent() for COM3" . And as you can see in the Screenshots processing doesnt recive the right data from the board.

    import processing.serial.*;
    
      Serial myPort;
      String counter1;                             
      String counter2;
      String Zufall;
    
      int Zaehler1;
      int Zaehler2;
      int Zahl;
    
      myPort = new Serial(this, "COM3", 9600); 
      myPort.bufferUntil('\n');
    
      println(Serial.list());
    
    
    void serialEvent(Serial myPort)
    {
      String indata = myPort.readStringUntil('\n');
    
      if(indata!=null){
        String[] tokens =split(trim(indata),',');    
        Zufall=tokens[0];
        counter1=tokens[1];
        counter2=tokens[2];
      }  
    }
    
    
    void Anzeige()
    {
    //Funktion, wenn Daten übertragen werden
     //   if ( myPort.available() > 0) 
      {  // If data is available,
      //counter1 = myPort.readStringUntil('\n');         // read it and store it in val
      String inBuffer = myPort.readString();
    
    if (inBuffer != null)
    {
      text(Zahl, 900, 800); // Text ausgebe
      println(Zahl);
    
      text(Zaehler1, 200, 300);
      println(Zaehler1);
    
      text(Zaehler2, 1520, 300); // Text ausgeben
      println(Zaehler2);
    } 
    

    If I changed the inBuffer "Zahl" to "Zufall" to take refer to the "inData part you sent in your post I get an error "NullPointerException" void Anzeige()

    {
        //Funktion, wenn Daten übertragen werden
         //   if ( myPort.available() > 0) 
          {  // If data is available,
          //counter1 = myPort.readStringUntil('\n');         // read it and store it in val
          String inBuffer = myPort.readString();
    
        if (inBuffer != null)
        {
          text(Zufall, 900, 800); // Text ausgebe
          //println(Zahl);
    
          text(counter1, 200, 300);
          println(Zaehler1);
    
          text(counter2, 1520, 300); // Text ausgeben
          println(Zaehler2);
        } 
    

    I really apreaciate your help, please be patient with me, this is my first programm ever.

  • Error, disabling serialEvent() for COM3

    There are few posts online that could give you hints of what to try next:

    https://forum.processing.org/two/discussion/9395/solved-error-disabling-serialevent-for-com3

    http://stackoverflow.com/questions/26070466/aurdino-processing-code-error-disabling-serialevent

    http://stackoverflow.com/questions/31392341/processing-code-error-disabling-serialevent-in-aurdino

    http://pulsesensor.proboards.com/thread/298/processing-working-disabling-serialevent-error

    However, in your case the main issue I see is that you are calling Anzeige() in draw(). You are trying to access the data from your port in draw 30fps. You should do this in serialEvent as it is the callback function to retrieve any data that has arrived to the port. Also check for null content before trying to access the data. If you are expecting 3 pieces of data, then after using split(), ensure your array is made of three pieces of data like tokens.length==3

    Kf

  • Thanks dude, i finally got the string in Processing! this **** really grind my gears! We were working on this part for 14 days now! Your code worked well, but I didn't understand it first. I will post my code in a week cause I don't have access to the PC yet, so it might help others.

Sign In or Register to comment.