line() not drawing anything.

edited September 2015 in Library Questions

Hi. I am pretty new to processing so bear with me for silly mistakes.I am trying to draw a trace of data received on serial port. I am able to receive it but i am not able to draw in using line. It just seems to not respond. The code is following which is derived form code i found online

import processing.serial.*;

Serial myPort;  // Create object from Serial class
float val, screen_increment, old_x=0, old_y=0;      // Data received from the serial port
String inString;  // Input string from serial port


void setup() 
{

  size(1000, 600);
  String portName = Serial.list()[2];//Set the Serial port COM    
  myPort = new Serial(this, portName, 9600);//Set up the serial port
  myPort.bufferUntil('\n');//read in data until a line feed, so the arduino must do a println
  background(208,24,24);//make the background that cool blood red
}//setup

void draw()
{
//nothing in here, this is kind of like the void loop in arduino
}

void serialEvent(Serial myPort) { //this is called whenever data is sent over by the arduino

  inString = myPort.readString();//read in the new data, and store in inString
  inString = trim(inString);//get rid of any crap that isn't numbers, like the line feed
  val = float(inString);//convert the string into a number we can use

  val=map(val,0,4096,0,600);

  strokeWeight(5);//beef up our white line
  stroke(255, 255, 255);//make the line white

  //drawing the line
  println(old_x,old_y,screen_increment,600-val);
  line(old_x, old_y, screen_increment, 600-val);


  //store the current x, y as the old x,y, so it is used next time
  old_x = screen_increment;
  old_y = 600-val;

  //increment the x coordinate,  you can play with this value to speed things up
  screen_increment=screen_increment+2;

  //this is needed to reset things when the line crashes into the end of the screen
  if(screen_increment>(1000)){
    background(208,24,24); //refresh the screen, erases everything
    screen_increment=-50; //make the increment back to 0, 
    //but used 50, so it sweeps better into the screen
    //reset the old x,y values
  old_x = -50;
  old_y = 0;

  }

}

SInce i have added a println the output of the code println(old_x,old_y,screen_increment,600-val); is following which seems correct to me

    0.0 0.0 0.0 302.9297
    0.0 302.9297 2.0 303.8086
    2.0 303.8086 4.0 300.29297
    4.0 300.29297 6.0 297.36328
    6.0 297.36328 8.0 295.60547
    8.0 295.60547 10.0 294.87305
    10.0 294.87305 12.0 294.14062
    12.0 294.14062 14.0 294.87305
    14.0 294.87305 16.0 296.77734

All I see is blank red screen

Please Help

Answers

  • edited September 2015
    • Processing's sketch is run by the "Animation" Thread.
    • All drawings to the canvas should happen under that Thread only.
    • Modifying the canvas under some other Thread is prone to rendering bugs.
    • Callback serialEvent() is run by the "Serial" Thread instead.
    • It should be focused on collecting read data only. It's not a place to "draw" anything!"
    • Staying too much there may slowdown its data capture too! :-SS
  • Your drawing commands stroke, strokeWeight and line should be inside the draw method, they should not be in the serialEvent method.

    The draw method is executed ~60 times a second. Each time it is executed it draws a 'frame' which is displayed immediately after the end of the draw method is reached.

  • I modified the code as follows it starts to draw some lines. I tries to control draw functions execution using noLoop() and redraw() since i don't want it to go at an arbitrary rate . But the logic i implemented is all messed up. It seems the draw is not executed immediately after I call the redraw() function. Am I thinking correctly

    void draw()
    
    {  if(screen_increment>(1000)){
      background(208,24,24); //refresh the screen, erases everything
        screen_increment=-10; //make the increment back to 0, 
        //but used 50, so it sweeps better into the screen
        //reset the old x,y values
        old_x = -10;
        old_y = 0;
      }
    
      draw_the_line();
    //nothing in here, this is kind of like the void loop in arduino
    }
    
    void serialEvent(Serial myPort) { //this is called whenever data is sent over by the a
        noloop();
    
    
      inString = myPort.readString();//read in the new data, and store in inString
      inString = trim(inString);//get rid of any crap that isn't numbers, like the line feed
      val = float(inString);//convert the string into a number we can use
    
      val=map(val,0,4096,0,600);
      //store the current x, y as the old x,y, so it is used next time
      //println("in the event loop" ,old_x,old_y,screen_increment,600-val);
    
      redraw();
      old_x = screen_increment;
      old_y = 600-val;
    
    
      //increment the x coordinate,  you can play with this value to speed things up
      //screen_increment=screen_increment+1;
    
    
    }
    void draw_the_line(){
      strokeWeight(3);//beef up our white line
      stroke(255, 255, 255);
      println("in the redraw loop" ,old_x,old_y,screen_increment,600-val);
      line(old_x, old_y, screen_increment, 600-val);
      screen_increment=screen_increment+1;
      noLoop();
      }
    

    The output now becomes somewhat strange as following

    in the redraw loop 12.0 310.4004 12.0 310.4004
    in the redraw loop 13.0 309.66797 13.0 309.66797
    in the redraw loop 14.0 308.20312 14.0 308.20312
    in the redraw loop 15.0 305.85938 15.0 305.85938
    in the redraw loop 16.0 302.7832 16.0 302.7832
    in the redraw loop 17.0 299.70703 17.0 299.70703
    in the redraw loop 18.0 297.36328 18.0 297.36328
    in the redraw loop 19.0 295.16602 19.0 295.16602
    in the redraw loop 20.0 293.5547 20.0 293.5547
    

    This is obviously wrong since (x1,y1) is equal to (x1,x2) Any Suggestions

  • edited September 2015
    • I can't grasp what is the job of each of those variables, sorry.
    • What I know is that both Threads are accessing/modifying them at the same time sometimes!
    • It means that the order they are read/written is unpredictable.
    • Declaring those multi-Thread variables as volatile may help a lil'. But doesn't fix the situation!
    • When we call redraw() or assign true to variable redraw: redraw = true;, at the 1st window of opportunity, also depending on frameRate(), function draw() is called.
    • That's why it's recommended to place redraw() at the end of any function.
    • B/c the time draw() is actually invoked after redraw() is unpredictable too. :P
    • As last advise, please use setup() to place those configurations which don't change afterwards.
    • Like size(), smooth(), noLoop(), strokeWeight(), stroke(), etc. *-:)
  • ThankYou for the answer. I implemented a small mutex to get the work done. Its just so many places i found the same code i thought it should work without much interefrence

  • edited September 2015
    • Rather than implementing any synchronized mutexes, you should ask yourself why would you need to modify any variable under 2 Threads.
    • That is, why would you "need" to reassign variables screen_increment, old_x & old_y inside both draw() & eventSerial()?
    • If they were modified under 1 Thread only, you wouldn't need to make your code more complex.
    • In most cases, more than 1 Thread can read a variable at the same time w/o any problems.
Sign In or Register to comment.