Using an Arduino LDR Sensor to switch backgrounds in Processing - arduino

Using a LDR sensor for Arduino, I want to switch between two gif backgrounds in Processing depending on the intensity of light that the LDR senses. My Arduino set-up works and I can see a range of numbers in the Serial Monitor depending on the amount of light shined on the sensor - however I'm having trouble in Processing with making the switch between backgrounds. This is my first project combining Arduino with Processing so please forgive me if I've made any super obvious mistakes.
Arduino Code
int sensorPin = A0; // select the input pin for LDR
int sensorValue = 0; // variable to store the value coming from the sensor
void setup() {
Serial.begin(9600); //sets serial port for communication
}
void loop() {
sensorValue = analogRead(sensorPin); // read the value from the sensor
Serial.println(sensorValue); //prints the values coming from the sensor on the screen
delay(100);
}
Processing Code
//loads gif library for background
import gifAnimation.*;
Gif batmanGotham;
Gif batmanLair;
//loads Arduino
import processing.serial.*;
Serial myPort;
int sensorValue = 0;
void setup() {
size(1067, 800); //size of canvas
batmanGotham = new Gif(this, "background.gif"); //set gif
batmanGotham.play();
batmanLair = new Gif(this, "batman_lab.gif"); //set second gif
batmanLair.play();
String portName = "/dev/cu.usbmodem14201";
myPort = new Serial(this, portName, 9600);
myPort.bufferUntil('\n');
}
void draw() {
}
void serialEvent (Serial myPort) {
if (sensorValue > 300) {
image(batmanLair, 0, 0); //lays down gif background
} else {
image(batmanGotham, 0, 0); //lays down gif background
}
}

You forgot to read data from the serial port, try adding the following line on your serialEvent() routine:
byte[] buffer = new byte[2];
sensorValue = myPort.readBytes(buffer);
at the very beginning.
As you see you have to recover data from the buffer yourself. The event is triggered automatically whenever there is something to read but you have to take is yourself from there and store it or process it.
You should be reading two bytes at a time to account for the size of the int you are sending from your Arduino.

Marcos is right, through you will be sending more than two bytes.
Let's assume you're sending 1023, that is actually 4 characters (bytes) + another new line (from println).
You can draw continuously and simply update the image based on the data read, ideally with some error checking:
//loads gif library for background
import gifAnimation.*;
Gif batmanGotham;
Gif batmanLair;
//loads Arduino
import processing.serial.*;
Serial myPort;
int sensorValue = 0;
void setup() {
size(1067, 800); //size of canvas
batmanGotham = new Gif(this, "background.gif"); //set gif
batmanGotham.play();
batmanLair = new Gif(this, "batman_lab.gif"); //set second gif
batmanLair.play();
String portName = "/dev/cu.usbmodem14201";
try{
myPort = new Serial(this, portName, 9600);
myPort.bufferUntil('\n');
}catch(Exception e){
println("error opening serial port: double check the cable is connected, the portName is right and SerialMonitor anything else trying to access the port is closed");
e.printStackTrace();
}
}
void draw() {
if (sensorValue > 300) {
image(batmanLair, 0, 0); //lays down gif background
} else {
image(batmanGotham, 0, 0); //lays down gif background
}
}
void serialEvent (Serial myPort) {
try{
String rawString = myPort.readString();
if(rawString != null && rawString.length() > 0){
// remove newline
rawString = rawString.trim();
// parse value
sensorValue = int(rawString);
}
}catch(Exception e){
println("error parsing serial data");
e.printStackTrace();
}
}
If you want to keep the Processing Serial part simpler, you can do the threshold logic on arduino and simply send a single byte to Processing, like 1 or 0 depending on which image you want to display:
int sensorPin = A0; // select the input pin for LDR
int sensorValue = 0; // variable to store the value coming from the sensor
void setup() {
Serial.begin(9600); //sets serial port for communication
}
void loop() {
sensorValue = analogRead(sensorPin); // read the value from the sensor
if(sensorValue > 0){
Serial.print('1');
}else{
Serial.print('0');
}
delay(100);
}
Then in Processing:
//loads gif library for background
import gifAnimation.*;
Gif batmanGotham;
Gif batmanLair;
//loads Arduino
import processing.serial.*;
Serial myPort;
boolean showLair;
void setup() {
size(1067, 800); //size of canvas
batmanGotham = new Gif(this, "background.gif"); //set gif
batmanGotham.play();
batmanLair = new Gif(this, "batman_lab.gif"); //set second gif
batmanLair.play();
String portName = "/dev/cu.usbmodem14201";
try{
myPort = new Serial(this, portName, 9600);
}catch(Exception e){
println("error opening serial port: double check the cable is connected, the portName is right and SerialMonitor anything else trying to access the port is closed");
e.printStackTrace();
}
}
void draw() {
// read 1 char
if(myPort != null && myPort.available() > 0){
char fromArduino = myPort.read();
showLair = (fromArduino == '1');
}
// update content
if (showLair) {
image(batmanLair, 0, 0); //lays down gif background
} else {
image(batmanGotham, 0, 0); //lays down gif background
}
}

Related

How do I get Arduino to communicate with Processing?

I wanted to make my Arduino communicate with Processing.
On Arduino, I use the code taken from the Processing site (Example 1A):
int switchPin = 4; // Switch connected to pin 4
void setup()
{
pinMode(switchPin, INPUT); // Set pin 0 as an input
Serial.begin(9600); // Initialize serial communications at a 9600 baud rate
}
void loop()
{
if (digitalRead(switchPin) == HIGH) // If switch is ON,
// send 1 to Processing
{
Serial.write(1);
}
else
{ // If the switch is not ON,
Serial.write(0); // send 0 to Processing
}
delay(100);
}
While in Processing I use this code:
import processing.serial.*;
Serial myPort; // Create object from Serial class
String val = "0"; // Data received from the serial port
void setup()
{
size(200, 200);
frameRate(10);
String portName = Serial.list()[0]; // Change the 0 to a 1, 2,
// etc. to match your port.
myPort = new Serial(this, portName, 9600);
}
void draw()
{
if (myPort.available() > 0)
{
// If data is available,
val = myPort.readStringUntil('\n'); // Read it and store it in val
}
background(255);
if(val.equals("0"))
{
fill(0);
}
else
{
fill(204);
}
rect(50, 50, 100, 100);
}
The program gives me the error NullPointerException on line 22 in the Processing program.
How can I solve it?
There is a delay in the communication and it is possible that the first time when the draw function is called, the serial port doesn't send any data, and the value received is null. That might be the reason you get the NullPointerException.
Try this:
void draw()
{
while (myPort.available() > 0)
{
// If data is available,
val = myPort.readStringUntil('\n'); // Read it and store it in val
}
background(255);
if(val != null)
{
if(val.equals("0"))
{
fill(0);
}
else
{
fill(204);
}
}
rect(50, 50, 100, 100);
}

How to send a number over serial to an arduino?

I'm trying to send a number value over serial to an Arduino to control an Individually Addressable LEDstrip. Using the Arduino IDE "Serial Monitor" I'm able to send a number to the light strip with no issue. However when i try to do it externally by reading from a text file in processing it doesn't go through.
After some debugging I can see that Processing has the number right and its stored in the variable. However the lightstip will only ever light up on led, instead of the number given.
Processing Code:
import processing.serial.*;
import java.io.*;
Serial myPort; // Create object from Serial class
void setup()
{
size(200,200); //make our canvas 200 x 200 pixels big
String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
myPort = new Serial(this, portName, 9600);
}
void draw()
{
while(true) {
// Read data from the file
{
String[] lines = loadStrings("Lifenumber.txt");
int number = Integer.parseInt(lines[0]);
println(number);
myPort.write(number);
delay(5000);
}
}
}
Arduino Code:
if ( Serial.available()) // Check to see if at least one character is available
{
char ch = Serial.read();
if(index < 3 && ch >= '0' && ch <= '9'){
strValue[index++] = ch;
}
else
{
Lnum = atoi(strValue);
Serial.println(Lnum);
for(i = 0; i < 144; i++)
{
leds[i] = CRGB::Black;
FastLED.show();
delay(1);
}
re = 1;
index = 0;
strValue[index] = 0;
strValue[index+1] = 0;
strValue[index+2] = 0;
}
}
What I want the program to do is read a number from a text file and light up that number of LEDs on the 144led lightstrip.
Here are a couple of comments on your code that should help make improvements in the future. It's important to form good coding habits early on: it will make your life so much easier (I'm speaking a mostly self taught programmer that started with flash so I know what messy and hacky is ;) )
import processing.serial.*;
//import java.io.*; // don't include unused imports
Serial myPort; // Create object from Serial class
void setup()
{
size(200,200); //make our canvas 200 x 200 pixels big
String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
// handle error initialising Serial
try{
myPort = new Serial(this, portName, 9600);
}catch(Exception e){
println("Error initializing Serial port " + portName);
e.printStackTrace();
}
}
void draw()
{
// don't use blocking while, draw() already gets called continuously
//while(true) {
// Read data from the file
//{
// don't load the file over and over again
String[] lines = loadStrings("Lifenumber.txt");
int number = Integer.parseInt(lines[0]);// int(lines[0]) works in Processing, but the Java approach is ok too
println("parsed number: " + number);
if(myPort != null){
myPort.write(number);
}
// don't use blocking delays, ideally not even in Arduino
//delay(5000);
//}
//}
}
Here's a version of the Processing code that loads the text file, parses the integer then sends it to serial only once (if everything is ok, otherwise basic error checking should reveal debug friendly information):
import processing.serial.*;
Serial myPort; // Create object from Serial class
void setup()
{
size(200,200); //make our canvas 200 x 200 pixels big
String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
// handle error initialising Serial
try{
myPort = new Serial(this, portName, 9600);
}catch(Exception e){
println("Error initializing Serial port " + portName);
e.printStackTrace();
}
// Read data from the file
try{
String[] lines = loadStrings("Lifenumber.txt");
int number = Integer.parseInt(lines[0]);
println("parsed number: " + number);
// validate the data, just in case something went wrong
if(number < 0 && number > 255){
println("invalid number: " + number + ", expecting 0-255 byte sized values only");
return;
}
if(myPort != null){
myPort.write(number);
}
}catch(Exception e){
println("Error loading text file");
e.printStackTrace();
}
}
void draw()
{
// display the latest value if you want
}
// add a keyboard shortcut to reload if you need to
Your strip has 144 leds (less than 255) which fits nicely in a single byte which is what the Processing sketch sends
On the Arduino side there's nothing too crazy going on, so as long as you validate the data coming in should be fine:
#include "FastLED.h"
#define NUM_LEDS 64
#define DATA_PIN 7
#define CLOCK_PIN 13
// Define the array of leds
CRGB leds[NUM_LEDS];
int numLEDsLit = 0;
void setup() {
Serial.begin(9600);
Serial.println("resetting");
LEDS.addLeds<WS2812,DATA_PIN,RGB>(leds,NUM_LEDS);
LEDS.setBrightness(84);
}
void loop() {
updateSerial();
updateLEDs();
}
void updateSerial(){
// if there's at least one byte to read
if( Serial.available() > 0 )
{
// read it and assign it to the number of LEDs to light up
numLEDsLit = Serial.read();
// constrain to a valid range (just in case something goes funny and we get a -1, etc.)
numLEDsLit = constrain(numLEDsLit,0,NUM_LEDS);
}
}
// uses blacking delay
void updateLEDs(){
// for each LED
for(int i = 0; i < 144; i++)
{
// light up only the number of LEDs received via Serial, turn the LEDs off otherwise
if(i < numLEDsLit){
leds[i] = CRGB::White;
}else{
leds[i] = CRGB::Black;
}
FastLED.show();
delay(1);
}
}
Adjust the pins/LED chipsets/etc. based on your actual physical setup.

Sending two arrays to Arduino from Processing

I'm trying to pass multiple variables (n number of strings and n number of ints) from processing to my Arduino. I found this tutorial online and managed to send a single value. Now I have two arrays that both need to be accessed by the Arduino filesTypes[] and filesSizes[]. filesTypes[] consists of a 3 char long strings while fileSizes[] is an array of different integers.
Here is my Processing code:
import processing.serial.*;
Serial myPort; // Create object from Serial class
String[] fileTypes;
int[] fileSizes;
String[][] lines;
void setup()
{
size(200,200); //make our canvas 200 x 200 pixels big
String portName = Serial.list()[1]; //change the 0 to a 1 or 2 etc. to
match your port
myPort = new Serial(this, portName, 9600);
launch( sketchPath("") + "/test.bat");
}
void draw() {
if (mousePressed == true)
{ //if we clicked in the window
txtToStrg();
myPort.write('1'); //send a 1
txtToStrg();
} else
{ //otherwise
myPort.write('0'); //send a 0
}
}
void txtToStrg(){
String[] lines = loadStrings("list.txt");
fileTypes = new String[lines.length];
fileSizes = new int[lines.length];
for (int i = 0 ; i < lines.length; i++) {
if(lines[i] != null) {
String[] splitLine = split(lines[i], ' ');
fileTypes[i] = splitLine[0];
fileSizes[i] = int(splitLine[1]);
println(fileTypes[i] + " = " + fileSizes[i]);
}
}
}
And here my Arduino code:
char val; // Data received from the serial port
int ledPin = 4 ; // Set the pin to digital I/O 13
void setup() {
pinMode(ledPin, OUTPUT); // Set pin as OUTPUT
Serial.begin(9600); // Start serial communication at 9600 bps
}
void loop() {
if (Serial.available())
{ // If data is available to read,
val = Serial.read(); // read it and store it in val
}
if (val == '1')
{ // If 1 was received
digitalWrite(ledPin, HIGH); // turn the LED on
} else {
digitalWrite(ledPin, LOW); // otherwise turn it off
Serial.print(val);
}
delay(10); // Wait 10 milliseconds for next reading
}
If a pass anything but a char it stops working.

Making a Game With Arduino and Processing

I am trying to form a two player game which requires an audio reflex to a visual. by using littebits sound trigger for sound input and littbits arduino to connect it to the computer. But I am new to this and don't know how to connect arduino to processing and use the input from sound trigger to effect the score when a black square appears.
here is my code in processing and a sample arduino code I have taken from littlebits website and tried to modify a little.
thanks in advance!
float dice;
int playerOne = 0; //player 1 score (left paddle)
int playerTwo = 0; //player 2 score (right paddle)
boolean oneWins = false;
boolean twoWins = false;
void setup(){
size(500, 500);
smooth();
noStroke();
frameRate(2.5);
}
void draw() {
background(255);
showGUI();
dice = random(0, 3);
if (dice < 1.000001 && dice > 0.1){
fill ((0), (255), (0));
ellipse (250,250,100,100);
} else if (dice < 2.000001 && dice > 1.000001){
rectMode(RADIUS);
fill ((255), (0), (0));
rect (250,250,50,50);
} else if (dice < 3.000000 && dice > 1.000000){
rectMode(RADIUS);
fill ((0), (0), (255));
rect (250,250,50,50);
} else if (dice < 0.1){
rectMode(RADIUS);
fill(0);
rect(250,250,50,50);
}
}
----------arduino------
void setup() {
Serial.begin(9600); //Establish rate of Serial communication
establishContact(); //See function below
}
void loop() {
if (Serial.available() > 0) {
int inByte = Serial.read();
int leftTrigger = analogRead(A0);
Serial.print(leftTrigger, DEC);
Serial.print(",");
int rightTrigger = analogRead(A1);
Serial.println(rightTrigger, DEC);
}
}
void establishContact() {
while (Serial.available() <= 0) {
Serial.println("hello");
delay(300);
}
}
You need two pieces of code for this to work: one on the Arduino that sends commands, and one for Processing to receive and parse those commands.
I haven't used the littlebits modules, but here's a button example from this very detailed tutorial.
Arduino code:
int switchPin = 4; // switch connected to pin 4
void setup() {
pinMode(switchPin, INPUT); // set pin 0 as an input
Serial.begin(9600); // start serial communication at 9600bps
}
void loop() {
if (digitalRead(switchPin) == HIGH) { // if switch is ON,
Serial.print(1, BYTE); // send 1 to Processing
} else { // if the switch is not ON,
Serial.print(0, BYTE); // send 0 to Processing
}
delay(100); // wait 100 milliseconds
}
And the matching Processing code:
import processing.serial.*;
Serial port; // create object from Serial class
int val; // data received from the serial port
void setup() {
size(200, 200);
frameRate(10);
// open the port that the board is connected to
// and use the same speed (9600bps)
port = new Serial(this, 9600);
}
void draw() {
if (0 < port.available()) { // if data is available,
val = port.read(); // read it and store it in val
}
background(255); // set background to white
if (val == 0) { // if the serial value is 0,
fill(0); // set fill to black
} else { // if the serial value is not 0,
fill(204); // set fill to light gray
}
rect(50, 50, 100, 100);
}
Notice that the Arduino sends a value that Processing looks for and interprets. You can also look at the PhysicalPixel example from the Arduino IDE for an example on sending data from Processing to Arduino.

Using Arduino light sensor value to jump video on Processing

My project is to create a robot Arduino flower with two sensors: light and pressure, that opens and closes according to the values in those two sensors, and at the same time plays different videos through Processing according to those values.
I've been having a really hard time passing on the value from the analog sensors in Arduino too processing. This is what I have so far:
Arduino
#include <Servo.h>
Servo myservo;
int pressure = 0;
int light = 1;
int pre;
int val;
void setup()
{
Serial.begin(9600);
myservo.attach(2);
}
void loop() {
pre = analogRead(pressure);
pre = map(pre, 918, 1023, 255, 0);
val = analogRead(light);
val = map(val, 0, 255, 0, 127);
Serial.print(val, DEC);
/*if (val>50) {
Serial.print(1);
}
else {
Serial.print(0);
}*/
myservo.write(val);
}
Processing
import processing.video.*;
import processing.serial.*; //arduino
Serial myPort; // Create object from Serial class
int val;
Movie movie;
void setup() {
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
size(640, 360);
background(0);
movie = new Movie(this, "transit.mov");
movie.loop();
}
void movieEvent(Movie m) {
m.read();
}
void draw() {
val = myPort.read();
println(val);
//if (movie.available() == true) {
// movie.read();
//}
image(movie, 0, 0, width, height);
if (val==49) {
movie.jump(1);
}
}
For now I'm just trying to make the video react to the light sensor, but haven't been able. All I get from the Processing readings is 48. The motor reacts fine to the sensors.
What output do you get from a simpler Processing sketch like this? What output would you expect?
import processing.serial.*;
Serial myPort; // The serial port
void setup() {
// List all the available serial ports
println(Serial.list());
// Open the port you are using at the rate you want:
myPort = new Serial(this, Serial.list()[0], 9600);
}
void draw() {
while (myPort.available() > 0) {
int inByte = myPort.read();
println(inByte);
}
}
Also, why is your map function in your Arduino code pre = map(pre, 918, 1023, 255, 0); using 250 and 0 as your lower bound and upper bound respectively? That seems backwards. Should it not read pre = map(pre, 918, 1023, 0, 255);?

Resources