Make Arduino and PIR motion sensor work in Processing code with Boolean expression

Hey!

I am working on a code, that I will use as a part of an artwork. Basically the code is taking a random word from a text file and putting it on the screen every time the mouse is clicked. This works as you see with a boolean expression (bottom of the code), that turns true every time the mousePressed event happens. The code works perfectly fine, but what I really want it to do is not to make the boolean expression turn true when the mouse is pressed, but when a PIR motions sensor is activated (So that every time the sensor is activated a word will appear on the screen). I have made a set-up with a raspberry pi, an arduino and a PIR motion sensor that i like, but I am stock on how to swap the mousePressed-event with a “sensor-event” and in that way make the arduino and the sensor communicate with processing.

I haven’t worked with arduino or motion sensor before and I have looked at related threads on the site, but it is still not obvious to me how I should do this.

Any ideas on how to make this work?

Thanks

/Jonathan

StringList potential;
String[] words;
String [] randomPotential;
boolean newWord = false;
int index = 0;
float x = 25;
float y = 40;


void setup() {
  size(1280, 720);
  background(0);

  String[] lines = loadStrings("Skabelsesberetningen.txt");
  String  entireplay = join(lines, " ");
  entireplay = entireplay.toLowerCase();
  words = split(entireplay, " ");
  words = splitTokens(entireplay, ":!?/()| "); 

  potential = new StringList();
  potential.append(words);
  potential.shuffle();
  randomPotential = potential.array();

}

void draw() {


  PFont f = createFont("Foundry Flek Grid", 18); 
  if (newWord) {
    int index2 = index++;

    textFont(f);
    text(randomPotential[index2], x, y);

    x += textWidth(randomPotential[index2] + " ");
    noLoop();
  }

  if (x > width-85) {
    x = 25;
    y += 20;
  }
  if (index > 667) { 
    index = 0;
    x = 25;
    y = 40;
    background(0);
    potential.shuffle();
    randomPotential = potential.array();

  }
}


void mousePressed() {
  loop();
  newWord = true;
}

Here is a nice tutorial for communication between Arduino and Processing.

1 Like

Thank you, I will see if this solves it!

Now I have tried in different ways to make the boolean expression turn true when the motion sensor is activated. I havent suceeded yet and maybe someone that understands processing better than me can help me out here? I manage to get the string from the arduino code in the processing console. So the communication between processing and the arduino seems fine. But using the string “val” to make the boolean turn true dosen’t work for me. I have tried to do it with “setState” as you see, but i can’t figure out why it is’t working. I have tried with “serialEvent” as well, but without any luck.

Any expertise here would be helpful!

Thanks

Processing code

import processing.serial.*;
Serial myPort;  // Create object from Serial class
String val;     // Data received from the serial port


StringList potential;
String[] words;
String [] randomPotential;
boolean newWord = false;
int index = 0;
float x = 25;
float y = 40;


void setup() {

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

  size(300, 400);
  background(0);

  String[] lines = loadStrings("Skabelsesberetningen.txt");
  String  entireplay = join(lines, " ");
  entireplay = entireplay.toLowerCase();
  //printArray(entireplay);
  words = split(entireplay, " ");
  words = splitTokens(entireplay, ":!?/()| "); 

  potential = new StringList();
  potential.append(words);
  potential.shuffle();
  randomPotential = potential.array();
}

void draw() {

  {  
    if ( myPort.available() > 0) 
    {  // If data is available,
      val = myPort.readStringUntil('\n');         // read it and store it in val
    } 
    println(val); //print it out in the console
  }


  PFont f = createFont("Foundry Flek Grid", 18); 
  if (newWord) {
    int index2 = index++;
    textFont(f);
    text(randomPotential[index2], x, y);
    x += textWidth(randomPotential[index2] + " ");
    noLoop();
  }

  if (x > width-85) {
    x = 25;
    y += 20;
  }
  if (index > 667) { 
    index = 0;
    x = 25;
    y = 40;
    background(0);
    potential.shuffle();
    randomPotential = potential.array();
  }
}


void setState(String newState) {
  val = newState;
  if (val.equals("Motion detected!")) { 
    loop();
    newWord = true;
  }
}

Arduino code

int ledPin = 13; // choose the pin for the LED

int inputPin = 3; // choose the input pin (for PIR sensor)

int pirState = LOW; // we start, assuming no motion detected

int val = 0; // variable for reading the pin status

void setup() {

pinMode(ledPin, OUTPUT); // declare LED as output

pinMode(inputPin, INPUT); // declare sensor as input

Serial.begin(9600);

}

void loop() {

val = digitalRead(inputPin); // read input value

if (val == HIGH) { // check if the input is HIGH

digitalWrite(ledPin, HIGH); // turn LED ON

if (pirState == LOW) {

// we have just turned on

Serial.println("Motion detected!");

// We only want to print on the output change, not state

pirState = HIGH;

}

} else {

digitalWrite(ledPin, LOW); // turn LED OFF

if (pirState == HIGH) {

// we have just turned of

Serial.println("Motion ended!");

// We only want to print on the output change, not state

pirState = LOW;

}

}

}

Hi @Jonathan_2

I believe that the problem you are facing is due to a small detail.
You arduino code is sending val = Motion detected! using Serial.println()
Your processing code receives it and compares with “Motion detected!”, but the println from arduino also places the ‘\n’ char.
So, if I am not mistaken you can do one of two things:

  1. trim the val String (https://processing.org/reference/trim_.html) on the processing and then compare it
if (trim(val).equals("Motion detected!")) { 
  1. don’t trim and check if the val string contains the string you want:
if (val.contains("Motion detected!")) { 

Try it out and see if it works :slight_smile:

Best regards

Hey!

Thank you very much for the answer! I really believed this would work, but I have tried both solutions and still nothing happens. I still see “Motion detected!” in the console, but the boolean expression dosen’t turn true or with other words I see no words appearing on the screen. If I try to make the boolean turn true just with the mousePressed event it does works. Any other takes on what the problem could be?

Thanks!

/Jonathan

Consider working through a simple example with just bytes first:

https://processing.org/tutorials/electronics/

And then start working with strings later.

:)

Hey Jonathan!

I happened to run into a similar problem with my processing code when combining a sensor input from Arduino to Raspberry pi via serial to turn boolean statement true. Were you lucky to solve this problem in the end? :slight_smile:

@jro, You’re welcome. It’s probably clearer for everyone if you make a new topic. Say what your project is doing, maybe post the code. I and others will be happy to help you.

Hey and thank yoy for replying @RichardDL . Ah, okay, yes of course. I’m new to the forum so that didn’t come to my mind, even though it’s obviously better to have a new separate topic altogether. I’ll make a new one as things process within my sketch, as for now I actually managed to turn a boolean expression true by using a serialEvent in my sketch and by trimming the data received from Arduino serial.

Hey!

I ended up solving the prolem just be simplyfing everything. I did two things:

#First a changed the arduino code so it didn’t write “motion ended” when the signal turned low - only “motion detected” when it turned high.

#Then at the end of the processing code I used SerialEvent to detect if processing registered any signal from the port connected to the arduino. If it did so, my boolean would turn true and in my case write a word on the screen.

Arduino code:

int ledPin = 13; // choose the pin for the LED

int inputPin = 3; // choose the input pin (for PIR sensor)

int pirState = LOW; // we start, assuming no motion detected

int val = 0; // variable for reading the pin status

void setup() {

pinMode(ledPin, OUTPUT); // declare LED as output

pinMode(inputPin, INPUT); // declare sensor as input

Serial.begin(9600);

}

void loop() {

val = digitalRead(inputPin); // read input value

if (val == HIGH) { // check if the input is HIGH

digitalWrite(ledPin, HIGH); // turn LED ON

if (pirState == LOW) {

// we have just turned on

Serial.println("Motion detected!");

// We only want to print on the output change, not state

pirState = HIGH;

}

} else {

digitalWrite(ledPin, LOW); // turn LED OFF

if (pirState == HIGH) {

// we have just turned of

// We only want to print on the output change, not state

pirState = LOW;

}

}

}

Processing code:

import processing.serial.*;
Serial myPort;  // Create object from Serial class
String val;     // Data received from the serial port


StringList potential;
String[] words;
String [] randomPotential;
boolean newWord = false;
int index = 0;
float x = 100;
float y = 40;


void setup() {
  //delay(5000);
  String portName = Serial.list()[1]; //change the 0 to a 1 or 2 etc. to match your port
  myPort = new Serial(this, portName, 9600);

  //size(1200, 900);
  fullScreen();
  background(0);

  String[] lines = loadStrings("Genesis.txt");
  String  entireplay = join(lines, " ");
  entireplay = entireplay.toLowerCase();
  //printArray(entireplay);
  words = split(entireplay, " ");
  words = splitTokens(entireplay, ":!?/()|«» "); 

  potential = new StringList();
  potential.append(words);
  potential.shuffle();
  randomPotential = potential.array();
  printArray(randomPotential);
  
 
}

void draw() {

  if ( myPort.available() > 0) 
  {  // If data is available,
    val = myPort.readStringUntil('\n');         // read it and store it in val
  }
  println(val); 

  PFont f = createFont("Foundry Flek Grid", 18); 
  if (newWord) {
    int index2 = index++;
    textFont(f);
    text(randomPotential[index2], x, y);
    x += textWidth(randomPotential[index2] + " "); // x bliver positionen efter de nye ord + mellemrum
    noLoop();
  

  }



  if (x > width-170) { // SKAL JO EGENTLIG SIGE HVIS SLUTNINGN AF ORDET må fikse den her ting, problemer med himmelhvælvingen. der bliver også lidt mærkelig mellemrum af og til. må være i teksten det skal fikses
    x = 100;
    y += 20;
    
  
  }
  

  if (index > 876) { 
    index = 0;
    x = 100;
    y = 40;
    background(0);
    potential.shuffle();
    randomPotential = potential.array();
  }
}



void serialEvent(Serial myPort) {  
  loop();
  newWord = true;
}
1 Like