Serial initialisation

edited March 2017 in Arduino

I am trying to write a program in which I can select the serial/com port before I run other code but it does not work.

I know that the for loop works as intented, the print function does print all my available com ports. The text() function does not work and I see that mousePressed or mouseY as used in the if statement do not work. If I just fill in 'true' in the if statement instead it does work.

 import processing.serial.*;

    boolean PIGS_CAN_FLY = true;
    String portName;

    Serial serial;

    void setup() {
      size(500, 500);
      //background(200,0,0);
    }

    void draw() {
       while (PIGS_CAN_FLY == true) {                                              // loop
        for (int i = 0; i < serial.list().length; i++) {                           // for loop runs 'ammount of com ports' times.
          portName = Serial.list()[i];                                             // stuff the COM name in the String 'portName'
          text(portName, 50, 50 + i * 30);                                         // draw the text of the COM port on the screen.  << this does not work
          println(portName);                                                       // tests if portName holds COM ports             << this works

          if (mousePressed && mouseY > 35 + (i * 30) && mouseY < 65 + (i * 30)) {   // if I press on the mouse and if mouse has certain Y value   << this does not work
            serial = new Serial(this, portName, 115200);                            // initialize serial port
            PIGS_CAN_FLY = false;                                                   // escape the while loop
          }
        }
       }

      text("hello world", 100,100);   // shows the escape out of the while loop << never happens
      text(portName, 350, 100);
    }  

Why is it, that no text gets drawn on my display? I have proven that the code does reach the point ánd that the used variable has content.

Why is the if statement immune to my mouse input? If I just use if(mousePressed == true) it still does not do anything when I press a mouse button

How can I do what I want

Tagged:

Answers

  • Answer ✓

    Mouse events get process after each call of draw. YOur while loop is blocking the processing of these events. From another perspective, this is what you have going in your code:

    while(true){ while(PIGS_CAN_FLY == true) {(... REST of the code here)}}

    You will need to rethink your strategy. There is also something odd about opening multiple ports. To clarify, you are showing the available ports and then the user click in a specific port to open it? It would be better to create or use a button object (G4P or controlP5 library).

    Kf

  • ok that helped me alot. I now changed the while loop construction to a switchcase construction and it works fine now. You can test the code if you like.

    case 1 runs the for loop in which I list the com ports and draw them on the screen. If I click on one of the com ports, the program switches to case 2 which initializes the selected com port. Than it switches to case 3 for ever. And this case is essentially my void draw.

    This code is so usefull, expecially for use with laptops where the internal bluetooth modules can occupy COM ports.

    import processing.serial.*;
    
     boolean PIGS_CAN_FLY = true;
     String portName;
     int var = 1;
    
    
     Serial serial;
    
     void setup() {
       size(500, 500);
       background(200,0,200);
     }
    
     void draw() {
       switch(var) {
         case 1:
         for (int i = 0; i < serial.list().length; i++) {                           // for loop runs 'ammount of com ports' times.
           portName = Serial.list()[i];                                             // stuff the COM name in the String 'portName'
           text(portName, 50, 50 + i * 30);                                         // draw the text of the COM port on the screen.  << this does not work
           println(portName);
           if (mousePressed && mouseY > 35 + (i * 30) && mouseY < 65 + (i * 30)) {   // if I press on the mouse and if mouse has certain Y value   << this does not work 
             var++;
             break;
           }
         }
         break;
    
         case 2:
         serial = new Serial(this, portName, 115200);
         text(portName + " initialized", 150, 50);
         delay(2000);
         var++;
         break;
    
         case 3:
         if(serial.available() > 0) {
           int c = serial.read();
           print((char)c);
         }
         break;
       }
    

    }

  • Thxs for sharing!

    Kf

  • @GoToLoop There is a tiny flaw in that code of your link. The serial object called serialPort which is to be used with .read() and .write() is declared in the class when you want to declare in it the main program so you can do serialPort.read() inside void draw which is kinda inpractible.

    And I find the code very unconvenient because you need to plug out/plug in a device for it to work. Besides the code is useless when you want to use an Rs-232 serial DB-9 connection (which I'll be using) or bluetoothmodules which are always shown in the comport list.

    But anyways, it did gave me the following idea:

    Because our machines send out a byte every 0.5 second for the handshaking process, I am going to write code which listens to all com ports for X seconds untill it 'hears' something.

    In the end I will be using this code on a raspberry Pi with a db-9 connecter which has like 30+ ports listed.

    So tnx for sharing ;)

  • That's not my code. Just thought it'd be useful somehow. 8-|

  • well it was usefull, and I did not call it your code but the "code of your link" #:-S Now I have a functioning program which connects to all ports in turn until it receives somethings. It also works when I plug in my demo arduino

  • edited March 2017

    @bask185 could you please post your code?

  • /*  This code will automatically connect to any ACTIVE com port on your computer and monitors it.
        It will keep doing this untill it receives data on a com port.
        case 0, case 1 and case 2 of the switch-case are essentially part of the setup. Apparanyly Void draw must be run for text() function to take effect
    
        it also works if the program is already running and you plug in a device later on
    
        Take note that whatever device you use, must be sending a byte(s) with an interval smaller than 2500ms
    
        I am yet to 'class-erize' so the void draw will only have one single line of code instead this entire switch case, but so far I am not yet succesfull
    */
    
    import processing.serial.*;
    
    int var;
    int serialIndex;
    
    Serial serial;
    
    void setup() {                                                                 // setup displays some basic info on screen
      noStroke();
      size(1024, 768);
      background(30,30, 240);
      textSize(50);
      fill(255);
      text("INITIALIZING, STAND BYE...", 150,100);
      textSize(15);
      text("detected ports", 20, 150);
      for(int i = 0; i<serial.list().length; i++ ){                               
      text(serial.list()[i], 170 ,150 + i * 20);                                  // lists all com ports            
      }
    }
    
    void draw() { // << MAIN LOOP >> //
     switch(var) {
      case 0:
        serial = new Serial(this, serial.list()[serialIndex], 115200);            // makes connection with the first com port on the list
        println("connected to " + serial.list()[serialIndex] + "  ...listening..."); // prints some info to track progress
        fill(30,30,240);
        rect(145, 135,18,633);                                                      // draws blue rectangle to delete the previous red dot
        fill(255,0,0);
        ellipse(150,145 + serialIndex * 20,10,10);                                 // draws a red dot for the com port which is currently being tested
        var = 1;                                                                   // next case
        break;
    
      case 1:
      delay(2500);                                                                // program merely has to wait to receive bytes on this point, program seems to crash if you wait shorter than 2500ms
        if (serial.available() > 0) var = 2;                                      // if a or several bytes are received go to case 2
        else {                                                                    // if not....
          var = 0;                                                                // go back to case 0
          serial.stop();                                                          // break the serial connection
          serialIndex++;                                                          // go to the next com port
          if(serialIndex >= serial.list().length)  serialIndex = 0;               // if we tried all com ports, start again
        }
        break;
    
      case 2:
        println("data received from " + serial.list()[serialIndex]);              // confirms the connection with the com port
        while(serial.available() > 0) serial.read();                              // empties the buffer before going to the last case
        serial.clear();                                                           // I think this does the exact same thing as the line above ;)
        var = 3;                                                                  // go the last and final case
        break;
    
      case 3:
      fill(30,30,240);
      rect(0,0,1024,768);
      fill(255);                                                                 // <<< put here what you would usually put in your void draw
      ellipse(mouseX,mouseY,30,30);
      // main code   the variable var wont be changed so case 3 will be run for ever from here on
    
      break;
     }
    }
    

    P.S. I have not yet tested the red dot and this PC only has 1 com port....

  • @bask185 You say

    Because our machines send out a byte every 0.5 second for the handshaking process, I am going to write code which listens to all com ports for X seconds untill it 'hears' something.

    Do all serial connected machines send out a byte every 0.5 seconds? I didn't know that. Or is it that the machines that you will be using will all send out a byte every 0.5 seconds?

  • Is dat sarcasm -_-"? No when I talk about our machines, I am talking about the machines at my work. Those send out 0x1C every 0.5s and my HMI need to send 0x96 back to it, so the machine knows he has an HMI attached to him.

    But this matters because? This code merely listens to all com ports for 2.5 seconds. That is what it does. So you can use it with whatever device you want, as long as that device will be sending something withing 2.5 seconds.

    The reason why I need this, is because some of the HMI's connected to the machines have more than one com port in the form of rs232 connectors and or bluetooth modules. But only one of the Rs-232 connectors will be connected to the machine. And this will be the only port with activity

    This program will be a part of a GUI application which will launch automatically after booting. Today I added an exception handler to it as well to prevent crashes when attempting to connect to a port which is 'busy'.

Sign In or Register to comment.