Trigger an image in interactive installation “sensor input cannot be resolved as a variable”

Hello,

I am currently working on an interactive canvas installation, where conductive ink is the Capsense input and the out is an image or gif that is projected onto the canvas via a projector linked to a laptop.

This is a visual explaining the idea.

I have successfully connected the sensor input (conductive ink) to processing and got the serial communication to print using this code.

However, when trying to trigger an image I don’t know how to write the if/ else if statement as Processing keeps saying “sensor input cannot be resolved as a variable”.

Any suggestions would be appreciated :grinning:

Thank you in advance.

code for arduino:


#include <CapacitiveSensor.h>


CapacitiveSensor Sensor = CapacitiveSensor(4, 2);


long val;
int pos;
#define led 13

void setup()
{
Serial.begin(9600);
pinMode(led, OUTPUT);
}

void loop()
{

val = Sensor.capacitiveSensor(30);
Serial.println(val);

}

else if (val >= 1000 && pos == 1)


}

delay(10);
}



**code for processing:** 

//import the Serial library so can read from arudino input via serial communication
import processing.serial.*; 

// the number 10 is ASCII for linefeed (end of serial.println), 
//later we will look for this to break up individual messages
int end = 10;    
String serial;   // declare a new string called 'serial' 
Serial port;  // The serial port, this is a new instance of the Serial class (an Object)

PImage zom;

void setup() {
  
  //serial reading code
  // initializing the object by assigning a port and baud rate (must match that of Arduino)
  // you may need to change the number in [] to match which serial port your arduino is connected to
  port = new Serial(this, Serial.list()[6], 9600); 
  
  // function from serial library that throws out the first reading, 
  // in case we started reading in the middle of a string from Arduino
  port.clear();  
  
  // function that reads the string from serial port 
  // until a println and then assigns string to our string variable (called 'serial')
  serial = port.readStringUntil(end); 
  
  // initially, the string will be null (empty)
  serial = null; 
  
  
  size (1000,1000);
  zom = loadImage("zom1.jpg");
 
  
}

void draw() {
  
  //if there is data coming from the serial port read it/ store it
  while (port.available() > 0) { 
    serial = port.readStringUntil(end);
  }
  
  //if the string is not empty, do this
  if (serial != null) {  
        //capsense Input form Arduino, each value is seperated and split depending on the ','
        //and then saved in seperate cells of the array so we can access each 
        String[] SensorInput = split(serial, ','); 
       //can help to print these to console at this point to check it's working
       println(SensorInput);
       
  }
  
  if (SensorInput >= 1000){
    
   zom = loadImage("zom1.jpg"); 
   
  background(0);
  }
}

1 Like

pls check out the structure used here:
https://processing.org/reference/libraries/serial/serialEvent_.html

String[] SensorInput= split(serial, ‘,’);
if (SensorInput >= 1000){

a string array can not be compared with a number
as you not send “,” by arduino ( possibly later make longer CSV lines )
you can try

if ( int(SensorInput[0]) >= 1000)
1 Like

thank you i’ll try this !

okay i tried this and this is the code still comes up as sensor input cannot be resolved as a variable:




//import the Serial library so can read from arudino input via serial communication
import processing.serial.*; 

// the number 10 is ASCII for linefeed (end of serial.println), 
//later we will look for this to break up individual messages
int end = 10;    
String serial;   // declare a new string called 'serial' 
Serial port;  // The serial port, this is a new instance of the Serial class (an Object)

PImage zom;

void setup() {
  
  //serial reading code
  // initializing the object by assigning a port and baud rate (must match that of Arduino)
  // you may need to change the number in [] to match which serial port your arduino is connected to
  port = new Serial(this, Serial.list()[6], 9600); 
  
  // function from serial library that throws out the first reading, 
  // in case we started reading in the middle of a string from Arduino
  port.clear();  
  
  // function that reads the string from serial port 
  // until a println and then assigns string to our string variable (called 'serial')
  serial = port.readStringUntil(end); 
  
  // initially, the string will be null (empty)
  serial = null; 
  
  
  size (1000,1000);
  zom = loadImage("zom1.jpg");
 
  
}

void draw() {
  
  //if there is data coming from the serial port read it/ store it
  while (port.available() > 0) { 
    serial = port.readStringUntil(end);
  }
  
  //if the string is not empty, do this
  if (serial != null) {  
        //capsense Input form Arduino, each value is seperated and split depending on the ','
        //and then saved in seperate cells of the array so we can access each 
        String[] SensorInput = split(serial, ','); 
       //can help to print these to console at this point to check it's working
       println(SensorInput);
       
  }
  
 {     
  if (int(SensorInput[0]) >= 500);
  
  image(zom, 0,0, 500, 500);
  
 background(0);
 }
}

1 Like

pls can you edit your posts and format the code?
use the

</>   code tag

ok i show you my version for

  • processing IDE 3.5.3 / JAVA mode
  • arduino IDE 1.8.9 nightly
    running on Raspberry Pi 3B+ / Raspbian OS

Arduino:

#include <CapacitiveSensor.h>
// http://playground.arduino.cc/Main/CapacitiveSensor

CapacitiveSensor cs_4_2 = CapacitiveSensor(4, 2);   // (byte sendPin, byte receivePin)
long val_cs_4_2;

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ;  // for LEONARDO needed
  }
  Serial.println("0,0,<Arduino is ready>");   // as you expect CSV line and use first value as number
  // cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF);     // turn off autocalibrate on channel 1 - just as an example
}

void loop() {
  val_cs_4_2 = cs_4_2.capacitiveSensor(30);
  Serial.print(val_cs_4_2);                           // -2 is timeout
  Serial.println(",0,");
  delay(10);
}

Processing:

// https://discourse.processing.org/t/help-with-code-please/8800  // kll cleaned version
import processing.serial.*;                             //import the Serial library so can read from arudino input via serial communication
Serial port;                                            // The serial port, this is a new instance of the Serial class (an Object)
String inserial;                                        // declare a new IN string called ‘serial’
int lf = 10;                                            // the number 10 is ASCII for linefeed (end of serial.println),
String[] SensorInput = {"0", "0"};                      // splitted CSV line to string array
PImage zom;
int val_cs_4_2;

void setup() {
  size (500, 500);  //1000,1000
  printArray(Serial.list()); 
  port = new Serial(this, Serial.list()[6], 9600); 
  port.clear();
  zom = loadImage("zom1.jpg");
}

void draw() {
  background(200);
  image(zom, 0, 0, 500, 500);
  if (val_cs_4_2 >= 1000)   background(0);                     // reset screen
  if (val_cs_4_2 == -2)     text("sensor problem", 10, 20);    // warning
}

void serialEvent(Serial p) { 
  inserial = p.readStringUntil(lf);
  if (inserial != null) {                                // if the string is not empty, do this
    SensorInput = split(inserial, ',');                  // capsense Input form Arduino, each value is seperated and split depending on the ‘,’ //and then saved in seperate cells of the array so we can access each
    printArray(SensorInput);                             // can help to print these to console at this point to check it’s working
    val_cs_4_2 = int(SensorInput[0]);                    // the first is our sensor
  }
} 


but i get the “-2” timeout as no hardware “sensor” connected.

1 Like

thank you soooo much!! i’ll try this and get back to you :grin:

Hello,

I tried this but it still did not trigger the image when the touch sensor was activated. Have you any idea what else I could attempt. Also I don’t have the Leonardo Board I have the arduino UNO.

Thank you

can you show the sensor print out by processing?
do you get anything but not reach the limit 1000?

when you upload the code to arduino UNO ( should be same in that respect )
did you start the monitor and check the raw data send from arduino?
pls print and show here.

Hello!

So I have managed to sort the code out to trigger an animation this past week, I’ll share that code now. I now need to trigger multiple animations.

Arduino Code:

#include <CapacitiveSensor.h>


CapacitiveSensor Sensor1 = CapacitiveSensor(4, 2); 



long val1;

int pos;
long threshold = 2000;
#define led 13

void setup()
{
Serial.begin(9600);
pinMode(led, OUTPUT);
}

void loop()

{
{

val1 = Sensor1.capacitiveSensor(30);

if (val1 >= threshold){ // comparing sensor read to threshold
Serial.println(1);

}
else { 
  Serial.println(0);
  }
//Serial.println(val);

delay(50);
}

Processing Code:

import processing.serial.*;



import processing.video.*;
Serial myPort;  // Create object from Serial class
int val = 1;    // Data received from the serial port

String inData = "";
int THRESHOLD = 0;
boolean playing = false;
Movie movie;



void setup() {
  
 
 size(1080, 720);
 frameRate(23.98);
 
 //movie refers to animations 
 
 movie = new Movie(this, "transparent.mp4");

 //speed of animations 
 
 movie.speed(1);
 movie.pause();
 

 
 // print serial ports 
 printArray(Serial.list());

// port communication

 String COM1 = Serial.list()[15]; //change the 0 to a 1 or 2 etc. to match your port
 myPort = new Serial(this, COM1, 9600);


}

void movieEvent(Movie movie) {
 movie.read();
}

void draw() {
  
  background(0); 
}

{
  // code for movie - first animation 
  
 if ( myPort.available() > 0) {  // If data is available,
        try { 
           inData = myPort.readStringUntil('\n');
           if ( inData == null ) {
              throw new Exception("Error reading: "+inData);
           }
           else
             inData = inData.trim();
           val = Integer.parseInt(inData);
           if (val > THRESHOLD) { //If the sensor is touched play movie 1
             if (!playing) {
               
               movie.play();       // display movie1 
               playing = true;
             }
             }
             else{
             if (playing) {
               playing = false;
             }
           }
      } catch (Exception ex) {
        //println("Exception:"+ex.toString()+" Data:"+inData);
      }
      //println(">"+inData+" -> "+val+"<");
      println(inData);
 } 


 image(movie, 0, 0, 580, 790);
 
}

MULTIPLE ANIMATION CODE:

Arduino Code:

#include <CapacitiveSensor.h>


CapacitiveSensor Sensor1 = CapacitiveSensor(4, 2); 
CapacitiveSensor Sensor2 = CapacitiveSensor(4,6);       
CapacitiveSensor Sensor3 = CapacitiveSensor(4,8); 


long val1;
long val2;
long val3;
int pos;
long threshold = 2000;
#define led 13

void setup()
{
Serial.begin(9600);
pinMode(led, OUTPUT);
}

void loop()

{
{

val1 = Sensor1.capacitiveSensor(30);

if (val1 >= threshold){ // comparing sensor read to threshold
Serial.println(1);

}
else { 
  Serial.println(0);
  }
//Serial.println(val);

delay(50);
}



{
  
val2 = Sensor2.capacitiveSensor(30);

if (val2 >= threshold){ // comparing sensor read to threshold
Serial.println(2);

}
else { 
  Serial.println(0);
  }
//Serial.println(val);

delay(50);

}


{

val3 = Sensor3.capacitiveSensor(30);

if (val3 >= threshold){ // comparing sensor read to threshold
Serial.println(3);

}
else { 
  Serial.println(0);
  }
//Serial.println(val);

delay(50);
}

}

Processing Code:


import processing.serial.*;



import processing.video.*;
Serial myPort;  // Create object from Serial class
int val1 = 1;    // Data received from the serial port
int val2 = 2;    // Data received from the serial port
int val3 = 3;   // Data received from the serial port
String inData = "";
int THRESHOLD = 0;
boolean playing = false;
Movie movie;
Movie movie1;
Movie movie2;
Movie movie3;


void setup() {
  
 
 size(1080, 720);
 frameRate(23.98);
 
 //movie refers to animations 
 
 movie1 = new Movie(this, "transparent.mp4");
 movie2 = new Movie(this, "Mushroom clouds.mp4");
 movie3 = new Movie(this, "Mouth smoke.mp4");
 
 //speed of animations 
 
 movie1.speed(1);
 movie1.pause();
 
 movie2.speed(1);
 movie2.pause();
 
 movie3.speed(1);
 movie3.pause();
 
 // print serial ports 
 printArray(Serial.list());

// port communication

 String COM1 = Serial.list()[15]; //change the 0 to a 1 or 2 etc. to match your port
 myPort = new Serial(this, COM1, 9600);


}

void movieEvent(Movie movie) {
 movie.read();
}

void draw() {
  
  background(0); 
}
{
  // code for movie1 - first animation 
  
 if ( myPort.available() > 0) {  // If data is available,
        try { 
           inData = myPort.readStringUntil('\n');
           if ( inData == null ) {
              throw new Exception("Error reading: "+inData);
           }
           else
             inData = inData.trim();
           val1 = Integer.parseInt(inData);
           if (val1 > THRESHOLD) { //If the sensor is touched play movie 1
             if (!playing) {
               
               movie1.play();       // display movie1 
               playing = true;
             }
             }
             else{
             if (playing) {
               playing = false;
             }
           }
      } catch (Exception ex) {
        //println("Exception:"+ex.toString()+" Data:"+inData);
      }
      //println(">"+inData+" -> "+val+"<");
      println(inData);
 } 


 image(movie1, 0, 0, 580, 790);
 
}

{

  
  // code for movie2 -  second animation mushroom clouds
  
 if ( myPort.available() > 0) {  // If data is available,
        try { 
           inData = myPort.readStringUntil('\n');
           if ( inData == null ) {
              throw new Exception("Error reading: "+inData);
           }
           else
             inData = inData.trim();
           val1 = Integer.parseInt(inData);
           if (val2 > THRESHOLD) { //If the sensor is touched play movie 2
             if (!playing) {
               
               movie2.play();       // display movie1 
               playing = true;
             }
             }
             else{
             if (playing) {
               playing = false;
             }
           }
      } catch (Exception ex) {
        //println("Exception:"+ex.toString()+" Data:"+inData);
      }
      //println(">"+inData+" -> "+val+"<");
      println(inData);
 } 


 image(movie2, 50, 0, 580, 790);
 
}

{

  
  // code for movie3 -  third animation Mouth smoke
  
 if ( myPort.available() > 0) {  // If data is available,
        try { 
           inData = myPort.readStringUntil('\n');
           if ( inData == null ) {
              throw new Exception("Error reading: "+inData);
           }
           else
             inData = inData.trim();
           val3 = Integer.parseInt(inData);
           if (val3 > THRESHOLD) { //If the sensor is touched play movie 3
             if (!playing) {
               
               movie3.play();       // display movie1 
               playing = true;
             }
             }
             else{
             if (playing) {
               playing = false;
             }
           }
      } catch (Exception ex) {
        //println("Exception:"+ex.toString()+" Data:"+inData);
      }
      //println(">"+inData+" -> "+val+"<");
      println(inData);
 } 


 image(movie3, 100, 0, 580, 790);
 
}


i understand that you now want

  • print a line after each sensor reading
  • and do the threshold in arduino already.
    so the expected data stream would be like?
0
0
3
0
0
0
2
0

but the code for the multiple sensor in processing
to have the

 if ( myPort.available() > 0) {

3 times i doubt.
it should be one time only and analyze the string.
untested idea:

import processing.serial.*;
import processing.video.*;

Serial myPort;  // Create object from Serial class
int play = 0, val;    // Data received from the serial port (int )
String inData = "";
boolean playing = false;
Movie movie1, movie2, movie3;

void setup() {
  size(1080, 720);
  movie1 = new Movie(this, "transparent.mp4");
  movie2 = new Movie(this, "Mushroom clouds.mp4");
  movie3 = new Movie(this, "Mouth smoke.mp4");
  //speed of animations 
  movie1.speed(1);
  movie1.pause();
  movie2.speed(1);
  movie2.pause();
  movie3.speed(1);
  movie3.pause();

  printArray(Serial.list());             // print serial ports 
  String COM1 = Serial.list()[15];       // port communication //change the 0 to a 1 or 2 etc. to match your port
  myPort = new Serial(this, COM1, 9600);
}

void draw() {
  background(0);
    if ( play == 1 )  image(movie1, 0, 0, 580, 790);
    if ( play == 2 )  image(movie2, 0, 0, 580, 790);
    if ( play == 3 )  image(movie3, 0, 0, 580, 790);
}

void serialEvent(Serial p) { 
  inData = p.readStringUntil('\n');
  if (inData != null) {                                // if the string is not empty, do this
    println(inData);
    inData = inData.trim();
    val = Integer.parseInt(inData);
    if ( val == 0 ) ;  // ignore
    if ( val == 1 ) startM1();
    if ( val == 2 ) startM2();
    if ( val == 3 ) startM3();
  }
} 

void startM1() {
  if (!playing) {
    movie1.play();       // display movie1 
    playing = true;
    play = 1;
  }
}
void startM2() {
  if (!playing) {
    movie2.play();       // display movie2 
    playing = true;
    play = 2;
  }
}
void startM3() {
  if (!playing) {
    movie3.play();       // display movie3
    playing = true;
    play = 3;
  }
}

the logic you want is?
you can start a ( other ) movie only if
playing == false
i not see where you set this??

I haven’t set playing == false anywhere, I will try the code.

Okay I tried the code for processing you’ve written it so much clearer and the values 0-3 do come up in processing. My issue now is there is no video being shown when I go to press any sensor. I will check over the code and see if there is something missing. I think it may have to do with the if statements not referring to the values:

if ( val > 0) ; 
movie1.play();
playing = true; 
play = 1; 

else if ( val = 0); 
movie1.pause;
playing = false; 

Would this be correct?

Thank you so much

you did not answer my question,
what is the idea / start logic,
and the “playing” variable.

you can for a test just disable that line ( and the corresponding // } )

if you want wait until “all” songs/movies finished,
and then enable start a new one,
the code is ok, but miss one part, where you check if
all movies finished set
playing = false;

but as you now come up with the

movie1.pause;
playing = false; 

would mean every touch stops the running movie and start the other one.
( but you can not use the
if ( val == 0 )
)
more like

void startM1() {
//  if (!playing) {
    movie1.play();       // display movie1
    movie2.pause();
    movie3.pause();
//    playing = true;
    play = 1;
//  }
}