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