I'm trying to use this code, but it seems that it might be "out-dated".

edited January 2017 in Arduino

This is the code I am trying to run in Processing 3.0.1 but it doesn't seem to work. It might be optimized for an older version of Processing, but I'm new to this software and don't exactly know how to use it. Please help, I need this to work for a school project.

 /*
  Fiber Optic Grapher - Used with Processing
  Developed/Edited by Arduino and iScience
  More info at instructables.com
*/

import processing.serial.*;

 Serial Port;
 int xPosition = 1;

 void setup () {
 size(600, 300);        

//Serial Port Manager
 println(Serial.list());

 Port = new Serial(this, Serial.list()[0], 9600);
 Port.bufferUntil('\n');

 // set background:
 background(0);

 }
 void draw () {

 }

 void serialEvent (Serial Port) {

 String inString = Port.readStringUntil('\n');

 if (inString != null) {
   inString = trim(inString);
   float inByte = float(inString); 
   inByte = map(inByte * 3 + 250, 0, 1023, 0, height);

   // draw line:
   stroke(500,0,0);
   line(xPosition, height - inByte, xPosition,height - inByte);

   if (xPosition >= width) {
     xPosition = 0;
     background(0); 
   } 
   else
     xPosition++;
 }
 }

Answers

  • Please format your code. Edit post, select code and hit ctrl+o. Ensure there is an empty line above and below your code.

    Previous related posts: https://forum.processing.org/two/search?Search=readStringUntil

    For example: https://forum.processing.org/two/discussion/comment/85287/#Comment_85287

    Kf

  • Okay kfrajer, the code is now formatted correctly.

  • Also, line 36 gives me an error message that says NaN

  • Add the following code btw lines 35 and 36: println("Received: "+inString+" "+inByte); and tell us what you get.

    Also, could you clarify why you are multiplying and adding those extra factors in line 36? You are mapping from 0 to 1024 which says your data has a 10 bit resolution. If you multiply/add extra factors, then you will have to adjust your mapping range accordingly. This last point shouldn't give you any errors but it is more of a side note.

    Kf

  • Do not use any drawing commands outside the "Animation Thread"!!! [-X
    Use the example from this link as a model for your code:
    https://forum.Processing.org/two/discussion/14534/myport-available-always-0#Item_1

  • I got this message when (really before anything else was added) I tried running the graph: println(Serial.list());

    Message: Type String[] of the last argument to method println(Object...) doesn't exactly match the varying parameter type. Cast to Object[] to confirm the non-varargs invocation, or pass individual arguments of type Object for a varargs invocation.

  • That is merely a warning, not an error! :-@

  • kfrajer, the new input you suggested allowed me to receive data, but it does not graph. What should I do to make the graph work?

  • @Franco_Maranon

    What change did you implement at the end?

    Your line 40 is not right. Try this instead: line(xPosition, 0, xPosition,height - inByte);

    Not sure if this will be enough without seeing your new code.

    Kf

  • edited January 2017

    This is the updated code:

        /*
          Fiber Optic Grapher - Used with Processing
          Developed/Edited by Arduino and iScience
          More info at instructables.com
        */
    
        import processing.serial.*;
    
         Serial Port;
         int xPosition = 1;
    
         void setup () {
         size(600, 300);        
    
        //Serial Port Manager
         println(Serial.list());
    
         Port = new Serial(this, Serial.list()[0], 9600);
         Port.bufferUntil('\n');
    
         // set background:
         background(0);
    
         }
         void draw () {
    
         }
    
         void serialEvent (Serial Port) {
    
         String inString = Port.readStringUntil('\n');
    
         if (inString != null) {
           inString = trim(inString);
           float inByte = float(inString); 
           println("Received: "+inString+" "+inByte);
           inByte = map(inByte * 3 + 250, 0, 1023, 0, height);
    
           // draw line:
           stroke(500,0,0);
           line(xPosition, 0, xPosition,height - inByte);
    
           if (xPosition >= width) {
             xPosition = 0;
             background(0); 
           } 
           else
             xPosition++;
         }
         }
    

    Still no graph though.

  • edited January 2017

    the new input you suggested allowed me to receive data

    You were not receiving data before? What did you change? Is this referring to another post?

    Can you elaborate about the nature of your receive data? What Arduino, input type and sensor device are you using to collect data? What does the following factors mean: 3 and 250 ininByte = map(inByte * 3 + 250, 0, 1023, 0, height);

    As @GoToLoop mention before, you need to move any drawing function into your draw():

    Kf

    String inString;
    
    void draw () {
    
      if(inString=="")
      return;
    
      inString = trim(inString);
      float inByte = float(inString);    
      inByte = map(inByte * 3 + 250, 0, 1023, 0, height);
      println("Received: "+inString+" "+inByte);
      // draw line:
      stroke(500, 0, 0);
      line(xPosition, 0, xPosition, height - inByte);
    
      if (xPosition >= width) {
        xPosition = 0;
        background(0);
      } else
        xPosition++;
    }
    
    void serialEvent (Serial Port) {
    
      inString = Port.readStringUntil('\n');
      if (inString == null) {
        inString="";
      }
    }
    
  • edited January 2017

    So when I click run, I get data that reads:

    Received: 1023, 1023.0
    Received: 1022, 1022.0
    Received: ... 
    

    Like so. I have a photo-resistor connect to an arduino uno which is running a code to collect the intensity of light felt by the resistor every millisecond. I have another arduino uno, powered by batteries, running a program to make an LED light up. The photo-resistor collects the intensity of the LED via a fiber optic cable channeling the light from the LED to the resistor. The graph is supposed to give me the intensity reading (more intense = bigger amplitude, less intense due to bending = smaller amplitude).

    I'm not sure what the factors 3 and 250 are supposed to do because I downloaded this code from someone who made it 5 years ago. Taking them out still gives me no graph though. Here's the URL of the post I got made project from: http://www.instructables.com/id/How-to-Send-Data-by-Light-Fiber-Optics/?ALLSTEPS

    Finally, where should I insert your recommended code?

  • I was not receiving data before, but now I do. As the photo-resistor recognizes that the light signal gets more intense, the data reads smaller numbers, like so: Received: 948, 948.0

  • Before you move into making graphs, it is important to ensure the system is working and that your read out is proper. For that, you need to make sure you are using the proper components and settings - voltage, resistors proper to operate with your photosensor and diodes. Do you have the reference of your photosensor? You can get the spec sheet of it. It should tell you what should be the output range and that is the efficiency in the visible spectrum (aka. what color is more effective in detecting)

    The previous code and println output wasn't in the right position. Here next should give you a bit more info. One of the first test i will do if I were you, a sanity check, is to watch the received data from the arduino. Then cover the photosensor with your hand and then uncover it in order to see if the values received from your arduino changes.

    Then you need to run the following sketch (Assuming your arduino code is proper)

    NOTE: Untested code...

    Kf

    /*
      Fiber Optic Grapher - Used with Processing
      Developed/Edited by Arduino and iScience
      More info at instructables.com
    */
    
    import processing.serial.*;
    
     Serial Port;
     int xPosition = 1;
    String inString;
    
     void setup () {
       size(600, 300);  
       stroke(500, 0, 0); 
       strokeWeight(3);     
    
      //Serial Port Manager
       println(Serial.list());
    
       Port = new Serial(this, Serial.list()[0], 9600);
       Port.bufferUntil('\n');
    
       // set background:
       background(0);     
     }
    
    
    void draw () {
    
      if(inString=="")
        return;
    
      inString = trim(inString);
      float inByte = float(inString);    
      inByte = map(inByte * 3 + 250, 0, 1023, 0, height);
      println("Received: "+inString+" "+inByte);
    
      // draw line:
      line(xPosition, 0, xPosition, height - inByte);
    
      if (xPosition >= width) {
        xPosition = 0;
        background(0);
      } else
        xPosition++;
    }
    
    void serialEvent (Serial Port) {
    
      inString = Port.readStringUntil('\n');
      if (inString == null) {
        inString="";
      }
    }
    
  • edited January 2017

    No effect. I got this message: Exception in thread "Animation Thread" java.lang.NullPointerException at processing.core.PApplet.trim(PApplet.java:8455) at sketch_170121a.draw(sketch_170121a.java:52) at processing.core.PApplet.handleDraw(PApplet.java:2399) at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1527) at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:316)

  • Actually, now it's working. However the graph still doesn't make a proper graph. It's more like a red line progressing along the top the graphing region.

  • edited January 2017

    Exception in thread "Animation Thread" java.lang.NullPointerException at processing.core.PApplet.trim(PApplet.java:8455) at sketch_170121a.draw(sketch_170121a.java:52) at processing.core.PApplet.handleDraw(PApplet.java:2399) at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1527) at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:316)

    This only showed up when I enabled debug.

  • Debug option in Processing? Not sure what that would do in your case.

    Not sure why trim would throw an error either. What is important is to see if your sensor is responding todifferent changes in the light environment. Are you running both boards simultaneously? Just focus in the receiver board and make sure the data it receives makes sense. What does your println output?

    Kf

  • The receiver is responding to different light intensities (the closer the LED is the lower the number will be, and both numbers are different). Here's an example: Received: 990 944.28156 Received: 989 943.4018

    I'm not sure what you mean by "what does your println output" means.

  • I'm not sure what you mean by "what does your println output" means.

    In my last post, I am referring to line 37: println("Received: "+inString+" "+inByte);

    Now you say the code is working but you don't see any changes in the graph. If this is true, then the ball is in your court. There is little it can be done to figure it out how to make it work. You have all the information. The question is, do you have the proper setup of your circuit design? You say the the receiver responds differently with different light intensities. How big is the difference? What is the range of your data reported by your arduino? After you figure out the range, then you need to modify line 36: inByte = map(inByte * 3 + 250, 0, 1023, 0, height) This is the line that plots the data. Do you understand how the map() function works?

    Kf

  • My range is, for the weakest intensity is 1023, and for the strongest is about 940

  • Okay, so the graph works now. Only thing is that there is a lot of blank space. It looks like this: Capture

  • edited January 2017

    Also took out the factor 3 and 250 from the previous code. How could I move the graph more to the center?

  • To map a range (data y values) another range (screen y values), you can use map():

  • Answer ✓

    Base in your observed range, then you should modified your code as shown in the next lines:

    inByte = map(inByte, 900, 1023, 0, height/2.0);                //LINE 36
    
    line(xPosition, height/2.0, xPosition, height/2.0 - inByte);  //LINE 40
    

    Kf

  • edited January 2017

    SUCCESS!!!!!!!! THANK YOU GUYS SO MUCH!!!!! I COULDN'T HAVE COMPLETED THIS WITHOUT YOU, @Kfrajer, @GoToLoop, AND @jeremydouglass.

  • There is something odd in this final solution. Checking the arduino specs http://www.arduino.org/products/boards/arduino-uno

    You are probly using one of the analog inputs which provides 10 bit resolution (A decimal range of 0 to 1023 which is mapping 0 to 5V). However, your signal range is from 900 to 1023. Here I quote:

    Uno has 6 analog inputs, labeled A0 through A5, each of which provide 10 bits of resolution (i.e. 1024 different values). By default they measure from ground to 5 volts, though is it possible to change the upper end of their range using the AREF pin and the analogReference() function.

    Kf

Sign In or Register to comment.