How to send multiple PWM values from Processing to Arduino?

edited November 2017 in Arduino

Hi all,

For a while I've been looking to control several banks of LED lights independently by using a GUI with a couple sliding bars. The idea is by moving each sliding bar around, the PWM value of the corresponding LED bank would change and the LEDs would get brighter or darker. Through this forum and other resources I have been able to accomplish this with one slider bar and one bank of LEDs. However, I am struggling to scale this project up because I don't know how to send and read multiple PWM values from several slider bars. I've seen some people mentioning splitting up the communication into several bits and then reading each bit in Arduino to correspond to each LED bank. I do not know how to accomplish this with the slider bars though. If you do have a solution, please by thorough. My Processing and Arduino code is below (currently aimed at using 2 slider bars for 2 corresponding LED banks), thanks in advance.

Processing

import controlP5.*;

import processing.serial.*;

ControlP5 cp5;

Serial port;

PFont font, font2;


int Brightness_1 = 0;

int Brightness_2 = 0;

void setup() 
{

 size(450, 200);

 String portName = Serial.list()[0];

 port = new Serial(this, "COM9", 9600);

  cp5 = new ControlP5(this);

 font = createFont("calibri light", 20);

 font2 = createFont("calibri light", 12);

  cp5.addSlider("Brightness_1", 0, 255, 0, 50, 125, 255, 12)
     .setPosition(50,125)
     .setSize(255,12)
     .setRange(0,255)
     .setFont(font);

  cp5.addSlider("Brightness_2", 0, 255, 0, 50, 125, 255, 12)
     .setPosition(50,125)
     .setSize(255,12)
     .setRange(0,255)
     .setFont(font);
}

void draw() 
{
  background(200, 10, 30);
  fill(100, 0, 150);
  textFont(font);

  text(Brightness_1, 25, 50);

  port.write(Brightness_1);

  port.write(Brightness_2);



}

Arduino

int incomingData;

void setup()
{

pinMode(4, OUTPUT);   //set pin4 as output 

pinMode(5, OUTPUT);   //set pin5 as output 

//pinMode(6, OUTPUT);   //set pin6 as output

Serial.begin(9600);

}

void loop()
{
if(Serial.available())

 {
    incomingData = Serial.read();

    analogWrite(4, incomingData);

    analogWrite(5, incomingData);

      }


  }

Answers

  • Check previous related posts:

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

    For instance:

    https://forum.processing.org/two/discussion/24307/how-do-i-receive-multiple-values-through-processing-from-the-arduino-serial-monitor/p1

    In our case, you are sending data from processing to your Arduino. Check the reference for the write() function:

    https://processing.org/reference/libraries/serial/Serial_write_.html

    As you can see, there are a couple of things you could do: string manipulation or bit shifting manipulation. I will stick to the first one as it is the most straight forward.

    Processing code (partial):

    void draw() 
    {
      background(200, 10, 30);
      fill(100, 0, 150);
      textFont(font);
    
      String strOut=char(Brightness_1)+","+char(Brightness_2)+'\n';     
      port.write(strOut); 
    }
    

    Is this code I am assuming both fields that we are sending have 8 bit resolution (aka. their range is from 0 to 255, inclusive). Then, I am always sending to the arduino the value of both sliders. Notice I am not sending the numeric value but the char equivalent (see https://processing.org/reference/charconvert_.html) as it technically could hold a value from 0 to 255 without any problems. You could send numeric values instead of the char equivalent. However, you will need to adapt your code in the arduino side to handle this type of data. Going back to my example and sending char values, your ino code will look like this:

    String str;  (Global scope)
    
    if(Serial.available() > 0) {
         str = Serial.readStringUntil('\n');
         val1=str.charAt(0);
         //Remember: char at position 1 is the "," character
         val2=str.charAt(2);
    
        analogWrite(4, val1.toInt()); 
        analogWrite(5, val2.toInt());
    

    More at: https://www.arduino.cc/reference/en/language/variables/data-types/stringobject/

    Kf

  • Kf, Thanks you so much for all your help so far. Everything you said made sense and I inputed the code. However, the one problem I'm having is with the arduino code reading in the values. The following section is not doing as intended:

         val1=str.charAt(0);
    
         val2=str.charAt(2);
    
        analogWrite(4, val1.toInt()); 
        analogWrite(5, val2.toInt());
    

    The "val1.toInt()" does not seem to work. The specific error says: "request for member 'toInt' in 'val1', which is of non-class type 'int'". So I did the following and ran it to understand a bit better:

     str = Serial.readStringUntil('\n');
        val1=str.charAt(0);
        val2=str.charAt(1);
        Serial.println(val1);
        Serial.println(val2);
       analogWrite(4, val1);
       analogWrite(5, val2);
    

    Now, when I go into the Arduino Serial Monitor and input for example "11", the code reads that as two ASCII characters and converts to Decimal values which are "49" (Decimal value of ASCII character "1" is 49). So, the Serial Monitor spits out 49, 49 and writes a PWM value of 49 to each LED output. I believe the problem has something to do with the lines: val1=str.charAt(0); but I'm not totally sure. Also, this code is reading in 1 character for each PWM, but I believe it would have to read in 3 characters for each PWM in order for there to be the max value of 255.

Sign In or Register to comment.