9 July 2012

Simple Arduino Serial Communication (Part 2)

In Stages 1 to 5 , we experimented with the Serial Monitor on the Arduino IDE to transmit data to the Arduino and receive data from the Arduino. We performed simple Serial communication of data in both directions.

We then moved from transmitting a String of characters to the more difficult task of transmitting a double or a float.

Finally, we used the Serial monitor to receive sensor data from our Arduino, and played with a couple of Arduino functions.

We will now look at replacing the Serial Monitor with a much more exciting program such as "Processing" which is a free Open Source program that interfaces very easily with the Arduino. It can be downloaded here.

We will use a few processing scripts to bring our Arduino Sensor projects to life !


Stage 6: A simple Processing Sketch: BLINK


Arduino IDE vs Processing IDE




While the processing IDE looks very similar to the Arduino IDE, it is important that you realise that the Processing sketch will run on your computer, and NOT on the Arduino. In fact, you do not even need an Arduino to run a Processing sketch. And that is exactly what we are going to do: Run a Processing sketch without an Arduino.

Parts Required



  • A computer
  • Processing IDE

  • Once you have downloaded and installed the Processing IDE onto your computer, open the program and copy the following sketch into it, and then press the play button. This is different from the Arduino IDE, in that we do not have to upload it to anything, as it will be running from the computer.

    Processing Sketch

    
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    
    
    /* Stage 6: Simple Processing Blink Sketch
       Created by ScottC on the 8/7/2012 
       http://arduinobasics.blogspot.com/   */
       
    /* Setup the color variables and switching mechanism */
       color Red=color(255,0,0);
       color White=color(255,255,255);
       Boolean mySwitch=true;
       
    
    /* The setup function only runs once */
    
       void setup(){
       /* Set the size of the window using size(width,height) */
          size(400,400);
       }
       
     /* The draw function will refresh screen only after it has
        processed all functions within it. Which is why I needed
        a switch to swap between the red and the white background
        The draw() function will run in an endless loop. */
        
        void draw(){
           blink(mySwitch);     //Call to blink function
           delay(2000);         //The blinking speed (2 secs)
        }
       
       
     /* The blink function switches the background from red to white
         or from white to red. */
         
        void blink(Boolean swtch){
        /* If swtch is true, make the background red
           otherwise make it white */
           if(swtch){
             background(Red);     // red
           }else {           
             background(White);   // white
           }
        /* Toggle mySwitch between true and false */  
           mySwitch=!mySwitch;       
       }
    


    Things to Try


    1. Change the White background to a black background

    2. Insert on line 9: color Black=color(0,0,0);
      Change line 38: background(Black);


    3. Increase the blink rate to 1 second

    4. Change line 25: delay(1000);
      WARNING : Do not increase the speed too much, it may cause an epileptic fit.



    Now that wasn't too hard I hope.
    And if you want a very good site to learn Processing have a look at these


  • The official Processing reference library
  • Official Processing Tutorials
  • Getting started with Processing
  • Daniel Shiffman's Processing Examples and Tutorials




  • Stage 7: Arduino and Processing Unite.


    So how do we get our Arduino to interface with our computer? Well, if the Serial Monitor on the Arduino IDE is not good enough, then you could use any program that is capable of Serial communication. Fortunately, Processing is one of those programs, but you could use C++, Java, Python, Microsoft Excel (using VBA), VB.Net, Gobetwino or some other programming language.

    Two programs will be created: One will be uploaded to the Arduino using the Arduino IDE, and the other will run on the computer. In this example we will use Processing as the program that will run on the computer.

    Enter the following sketch into the Arduino IDE and upload it to the Arduino. It serves to generate a random number between 0 and 400 every 200msec and will send it to the computer via the USB cable , using Serial communication.

    Arduino Sketch


     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    /* Stage 7: Simple Arduino Serial Random Number Generator
    Written by ScottC on 09/07/2012
    http://arduinobasics.blogspot.com/
    */
    
      void setup(){
        Serial.begin(9600);      //Begin Serial Communication
      }
    
      void loop(){
        Serial.println(random(1,1000)); //Send Random # to computer
        delay(200);                    //Delay 200ms between values.
      }
    


    Instructions

    Once the program has been uploaded to the Arduino, we will want to make sure that it is performing to expectations before moving onto the Processing script.

    Open the Arduino Serial Monitor and make sure that you see a bunch of random numbers scrolling down the page. If not, then go back over your code and try again. Once you see the random numbers, then it is safe to move on to the next step.




    Processing

    The following Processing script will display the Random numbers being sent from the Arduino in the Processing IDE debug window. This particular script is very much like a simplified Arduino Serial Monitor, and it will show you that the Processing Script is successfully communicating with the Arduino.


    Processing Sketch

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    /* Some of the Serial code was adapted from Tom Igoe's example
       on this site: http://processing.org/reference/libraries/serial/Serial.html
       and http://processing.org/reference/libraries/serial/serialEvent_.html
       
       The rest of this Processing code was written by ScottC on 11/07/2012
       http://arduinobasics.blogspot.com/
    */
    
    
    import processing.serial.*; /* Needed for Serial Communication */
    
    /* Global variables */
    Serial comPort;
    String [] comPortList;
    String comPortString;
    
    /*--------------------------------------------------*/
    
    void setup(){
      size(100,100);            /* Set the size of the window  */
      background(0);            /* Set the background to black */
      
      
      /* Get the available com ports. If there is at least one
         com port available, then start communicating on it.
         If there are more than one com ports available, we will
         only open the first one (i.e. comPortList[0])
         The bufferUntil('\n'); statement will generate a serial Event
         when it reads a carriage return */
         
      comPortList = Serial.list();  
      if(comPortList.length>0){
        comPort = new Serial(this, comPortList[0], 9600);
        comPort.bufferUntil('\n');
      }
    }
    
    /*--------------------------------------------------*/
    
    void draw(){
      /* The serialEvent function will update the display */
    }
    
    /*--------------------------------------------------*/
    
    void serialEvent(Serial cPort){
      comPortString = cPort.readStringUntil('\n');
      if(comPortString != null) {
        comPortString=trim(comPortString);
        
        /* Print to the Debug screen in Processing IDE */
        println(comPortString);
      }
    }
    


    When you run the Processing script, a little black window will appear. This is the Processing Graphics window, which is normally where all the action takes place. However in the sketch above, this window does nothing. Instead we make use of the black Debug window which is part of the Processing IDE (below the code window). If everything went to plan, you should see random numbers scrolling down in a similar fashion to the Arduino Serial monitor. Here is an example of what it should look like.





    Things to Try


    1. If you are having problems with COM port selection. Then have a look at the COM port being used on the Arduino IDE to upload sketches to the Arduino. Processing generally uses the same COM port. So make sure to close the Arduino Serial Monitor before running the Processing Sketches.



    The image above shows that I am currently using COM PORT 6 on my computer to upload Arduino Sketches. In the Processing sketch on line 32-35, I had this code:

    32
    33
    34
    35
      if(comPortList.length>0){
        comPort = new Serial(this, comPortList[0], 9600);
        comPort.bufferUntil('\n');
      }
    



    We can change line 33 to get Processing to use COM port 6 exclusively. We do this by replacing comPortList[0] with "COM6", as seen below:

    32
    33
    34
    35
      if(comPortList.length>0){
        comPort = new Serial(this, "COM6", 9600);
        comPort.bufferUntil('\n');
      }
    







    Stage 8 : Arduino and Processing - Random Font Project


    Arduino and Processing are speaking to each other by this stage, and we will keep our original Arduino Sketch to produce random numbers for us. Sure, we don't actually need the Arduino to do this for us, because Processing is more than capable of doing this itself, but we are building up towards an interactive sketch, so lets just go through the motions.

    Just in case your mouse scroll wheel doesn't move upwards, here is the Arduino Sketch again:

    Arduino Sketch


     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    /* Stage 8: Simple Arduino Serial Random Number Generator
    Written by ScottC on 09/07/2012
    http://arduinobasics.blogspot.com/
    */
    
      void setup(){
        Serial.begin(9600);      //Begin Serial Communication
      }
    
      void loop(){
        Serial.println(random(1,1000)); //Send Random # to computer
        delay(100);                    //Delay 100ms between values.
      }
    


    Upload the Arduino sketch to the Arduino, and then put the following code into the Processing IDE:

    Processing Sketch




    The output of this sketch should look something like this:





    For stages 9 and above: Click Here


    22 comments:

    1. Thanks a lot for the useful information, I would like to know about sending the text file containing numbers. Can you please throw some light on it.

      ReplyDelete
    2. I will eventually blog about the process of reading text files and sending to Arduino. I have actually blogged about this before, but will build up to it in the later stages of this tutorial.

      ReplyDelete
    3. Like this very much!

      Now here is my question. Like to get arduino data (voltage measurements with very fast updates) to be displayed on the computer in a colourful barograph with some text underneath. The higher the number (eg voltage) the more intense the colour (eg red). In other words taking the serial arduino data and having a nice display on the PC.

      Thoughts?

      ReplyDelete
      Replies
      1. Hi Stefan,

        Have a look at one of my other projects:
        http://arduinobasics.blogspot.com/2012/11/arduinobasics-hc-sr04-ultrasonic-sensor.html

        Sounds similar to what you describe, but using an ultrasonic sensor instead.
        Some of my other tutorials also include a bar graph type display.
        The easiest way I find to do this kind of stuff is through the Processing program.

        Hope this helps.
        Scott

        Delete
    4. It's really helpful. Thanks a lot. Waiting for the next part.

      ReplyDelete
      Replies
      1. Thanks for the feedback Anonymous,
        Am studying at the moment - so will not get to the next part (for at least another month). But I will get to it. Thank you.

        Delete
    5. Hi Thaslim -
      I deleted your comment due to the large amount of text you pasted into it.
      These types of questions are always best posted on the Arduino Forum:
      http://arduino.cc/forum/

      However, I noticed that you seemed to have omitted some important code, especially in the include# statement. And also the pins you are choosing to use to communicate with the shield. Have a look at this site - http://www.seeedstudio.com/wiki/GPRS_Shield_V1.0

      it may help you get on the right track. I don't have a GPRS shield or an Arduino Mega, which is why I have directed you to the sites mentioned above.


      Regards
      Scott

      ReplyDelete
    6. Hi, I'm a beginner starting to explore the possibilities of Arduino. How can we store the data received through the serial communication?

      ReplyDelete
      Replies
      1. You have two options that I know of. You could act on the Serial data in real time or you can use one of the many Shields that have an SD card slot, and store the data onto the SD card.

        Delete
    7. Stage 7 processing line 47 faults whenever I try to run the processing program. It reports The function readStringUntil(char) does not exist. Any suggestions. I'm a complete noob.

      ReplyDelete
      Replies
      1. Hi Anonymous,

        This function was left out of the most recent version of Processing.
        It will be fixed on the next version.
        https://github.com/processing/processing/issues/2174

        However as described on that site, there is a work-around that you can use.

        replace line 47 with
        comPortString = new String(cPort.readBytesUntil('\n'));

        Note the change : readBytesUntil instead of readStringUntil
        And is surrounded by a new String(...);

        See if that works for you.


        Delete
    8. suppose u have loop running in draw() will the loop get paused for serialevent() to be executed??

      ReplyDelete
      Replies
      1. Best way to find out is to set up an experiment and see what happens.
        Here is a link to SerialEvent on the Arduino website.

        Delete
    9. i have tried a project on arduino in which as i rotate potentiometer the data is to be sended to processing monitor but as i don't rotating potentiometer then also i'm getting some fixed range random values and while turning potentiometer as well.

      ReplyDelete
    10. This is really the most helpful ever which I found in the internet. The authors of the compiler-software of the arduino have not only created a wonderful compiler. With this peace of software processing plus arduino's terminal including the arduino as target is the best workbench ever found in live. In 1982 I learned to program 8080 systems in machine code - we had nothing else - later came basic and C, thank you so much for the tutorial - I'm 71 years old, but this gets me feeling like 20 years younger :-)

      ReplyDelete
      Replies
      1. Thanks for that comment - made my day !!

        Delete
    11. These tutorials are really great !!!
      Nevertheless the sketch in stage 8 seems to run on my computer and arduino, but it doesn't produce the expected output on Processing Graphic Window.
      Same thing in stage 11. The background does not change from red to green (line 45).
      What's wrong?

      ReplyDelete
      Replies
      1. What output are you getting ?
        What operating system are you using?
        What version of Processing?

        Delete
      2. Hi Scott,
        I already have sent you the answers, but I didn't use the reply-button. So I'll send it again.
        - no output, the Graphic Window remains black.
        - my OS: Windows Version 6.1.7601
        - processing 3.1.1

        Another problem that I found on my computer:

        void setup(){
        background(0);
        }
        int i=0;

        void draw(){
        for (i=0;i<300;i++){
        fill(i,0,0);
        rect(40,40,20,20);
        println(i);
        delay(20);
        }
        }

        The rectangle in the for-loop should change it's colour smoothly. But it doen't.
        If I don't use the for-loop, it does.
        I don't understand this.

        Delete
      3. Ok - I have updated stage 8.
        The problem relates to the version of Processing. In order to get these tutorials to run properly - you will have to use an older version of processing, or update the code to comply with the newer version. However - stage 8 should now work for you.
        Drawing within the SerialEvent method is no longer supported - so you can see what I have done to fix this in the updated code above.

        As for your example above - you will either need to use the redraw() function, or increment the i variable with every loop of the draw funtion (i.e. you will need to get rid of the for-loop). The frame only updates/refreshes once it gets to the end of the draw() function, so what you are doing in code is updating the colour of the rectangle every 20ms (behind the scenes), but updating the display only after the for-loop finishes.

        You can fix it this way:

        int i=0;

        void setup(){
        background(0);
        }


        void draw(){
        fill(i,0,0);
        rect(40,40,20,20);
        println(i);
        delay(20);
        i++;
        if(i>254){
        i=0;
        }
        }

        Delete
    12. Hi Scott,

      Your tutorials are very good, but when I run the Random Font Selector program on Processing 3.2.3, nothing happens!

      ReplyDelete
      Replies
      1. Try the 32-bit version of Processing ??

        Delete

    Feel free to leave a comment about this tutorial below.
    Any questions about your particular project should be asked in the ArduinoBasics forum.

    Comments are moderated due to large amount of spam.