Making a Game With Arduino and Processing - arduino

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.

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);
}

Using an Arduino LDR Sensor to switch backgrounds in Processing

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
}
}

Can I temporarily disable Arduino Serial data receive?

I am working on a project and I encountered some problems.
I am using a DHT11 temperature sensor, an Arduino Uno and a TFT LCD display 2.2-inch model ITDB02-2.2.
What I want my project to do is to use 2 functioning modes for the sensor that I can select from the keyboard at the beginning of the program(one which is normal and one which will be used on special occasions)(so I need serial communication).
I noticed that the screen does not function if I start a serial communication at any rate so I used Arduino Serial.begin(9600) and Serial.end() for the mode selecting part of the program.
THE PROBLEM: My Arduino is still sending data through serial port even if I ended the serial communication and is looking like this:
I found out that Serial.end() function does not shut off serial communication but just the rate of communication. I am curious if you have any idea that I can use in order to get rid of the extra data, to neglect it before the computer receives it.
I`m stuck. I thought that interruptions would be a solution but they are not as far as I researched on the internet.
My ARDUINO CODE:
#include <SimpleDHT.h>
#include <UTFT.h>
UTFT myGLCD(ITDB22,A5,A4,A3,A2);
SimpleDHT11 dht11;
// Declare which fonts we will be using
extern uint8_t BigFont[];
//dht sensor data pin
int dataPinSensor1 = 12;
char mode;
int del;
void setup()
{
Serial.begin(9600);
Serial.print("Select functioning mode");
mode=SensorModeSelect(mode);
Serial.end();
pinMode(12, INPUT);
}
void loop()
{
if(mode=='1') {
FirstFuncMode(dataPinSensor1);
}
if(mode=='2') {
SecondFuncMode(dataPinSensor1,del);
}
delay(10);
}
char SensorModeSelect(char in)
{
char mode='0';
while(mode=='0') {
if(Serial.available() > 0) {
mode=Serial.read();
}
}
if (mode == '1') {
Serial.print("\nMOD1 SELECTED: press t key to aquire data \n");
}
if (mode == '2') {
Serial.print("\nMOD2 SELECTED: press q if you want to quit auto mode \n");
Serial.print("Select the data aquisition period(not smaller than 1 second) \n");
}
return mode;
}
int DataAqPeriod()
{
int del=0;
while(del==0) {
while(Serial.available() > 0) {
//Get char and convert to int
char a = Serial.read();
int c = a-48;
del *= 10;
del += c;
delay(10);
}
}
del*=1000;
return del;
}
void FirstFuncMode(int dataPinSensor1)
{
byte temperature = 0;
byte humidity = 0;
int err = SimpleDHTErrSuccess;
bool DispCond=false;
Serial.begin(9600);
delay(1500);
if (Serial.read() == 't' ) {
DispCond=true;
//read temperature and compare it with an error value
if((err = dht11.read(dataPinSensor1, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
Serial.print("unreliable measurement or unselected functioning mode");
}
byte f = temperature * 1.8 + 32;
Serial.print((int)temperature);
Serial.print(" *C, ");
Serial.print((int)f);
Serial.print(" *F, ");
Serial.print((int)humidity);
Serial.println(" H humidity");
delay(1500);
}
Serial.end();
if(DispCond==true) {
//Setup the LCD
myGLCD.InitLCD();
myGLCD.setFont(BigFont);
//print value on LCD
displayNoInit((int)temperature,(int)humidity);
}
}
void SecondFuncMode(int dataPinSensor1,int del)
{
bool q=false;
byte temperature = 0;
byte humidity = 0;
int err = SimpleDHTErrSuccess;
Serial.begin(9600);
del=DataAqPeriod();
Serial.end();
//Setup the LCD
myGLCD.InitLCD();
myGLCD.setFont(BigFont);
while(q==false) {
Serial.begin(9600);
//read temperature and compare it with an error value
if((err = dht11.read(dataPinSensor1, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
Serial.print("unreliable measurement or unselected functioning mode \n");
}
float f = temperature * 1.8 + 32;
Serial.print((int)temperature);
Serial.print(" *C, ");
Serial.print((int)f);
Serial.print(" *F, ");
Serial.print((int)humidity);
Serial.println(" H humidity");
delay(del);
if(Serial.read() == 'q')
q=true;
Serial.end();
displayNoInit((int)temperature,(int)humidity);
delay(10);
}
}
void displayNoInit(int temperature,int humidity)
{
//effective data display
myGLCD.clrScr();
myGLCD.setColor(255, 255, 0);
myGLCD.setBackColor(10,10,10);
myGLCD.print(" Temperature ", CENTER, 10);
myGLCD.setColor(254, 254, 254);
myGLCD.printNumI(temperature, CENTER, 45);
myGLCD.setColor(255, 255, 0);
myGLCD.print("C ", RIGHT, 45);
myGLCD.print("Relative Hum.", CENTER, 90);
myGLCD.setColor(204, 245, 250);
myGLCD.printNumI(humidity, CENTER, 120);
myGLCD.print("%", RIGHT, 120);
}
You are correct in the definition that Serial.end() does not disable the serial monitor, only the interrupts. After calling Serial.end() you can disable the serial monitor like so.
#include <avr/io.h>
// Save status register, disable interrupts
uint8_t oldSREG = SREG;
cli();
// Disable TX and RX
cbi(UCSRB, RXEN);
cbi(UCSRB, TXEN);
// Disable RX ISR
cbi(UCSRB, RXCIE);
// Flush the internal buffer
Serial.flush();
// Restore status register
SREG = oldSREG;

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.

Arduino SoftwareSerial connection with LinkSprite Jpeg Camera

So we're having trouble connecting the Arduino Uno to the LinkSprite camera, we've been using the LinkSprite sample code with a few print statements added
#include < SoftwareSerial.h >
/* Linksprite */
byte incomingbyte;
SoftwareSerial mySerial(4, 5); //Configure pin 4 and 5 as soft serial port
long a = 0x0000, j = 0, k = 0, count = 0; //Read Starting address
uint8_t MH, ML;
boolean EndFlag = 0;
void SendResetCmd();
void SendTakePhotoCmd();
void SendReadDataCmd();
void StopTakePhotoCmd();
void setup() {
Serial.begin(38400);
mySerial.begin(38400);
Serial.print("Serial began\n");
}
void loop() {
SendResetCmd();
Serial.print("Reset Command Sent\n");
Serial.print(mySerial.available());
Serial.print("\n");
while (mySerial.available() > 0) {
incomingbyte = mySerial.read();
Serial.print(incomingbyte, HEX);
} //After reset, wait 2-3 second to send take picture command
Serial.print("Delay Ended\n");
SendTakePhotoCmd();
Serial.print("Take Photo Command Sent\n");
while (mySerial.available() > 0) {
Serial.print("Checking Available Bytes\n");
incomingbyte = mySerial.read();
}
byte a[32];
Serial.print("Byte array intialized\n");
while (!EndFlag) {
Serial.print("Entering While loop\n");
j = 0;
k = 0;
count = 0;
SendReadDataCmd();
Serial.print("Read Command Sent\n");
delay(250);
Serial.print("Delay Ended\n");
Serial.print(mySerial.available());
Serial.print("\n");
while (mySerial.available() > 0) {
incomingbyte = mySerial.read();
Serial.print("Incoming Byte Read\n");
k++;
if ((k > 5) && (j < 32) && (!EndFlag)) {
Serial.print("Byte Added to Array\n");
a[j] = incomingbyte;
if ((a[j - 1] == 0xFF) && (a[j] == 0xD9)) { //Check if the picture is over
Serial.print("End Flag");
EndFlag = 1;
}
j++;
count++;
}
}
for (j = 0; j < count; j++) {
if (a[j] < 0x10)
Serial.print("0");
Serial.print("Picture Printing\n");
Serial.print(a[j], HEX);
Serial.print(" ");
} //Send jpeg picture over the serial port
Serial.println();
delay(10000);
}
Serial.print("Picture Complete");
while (1);
}
//Send Reset command
void SendResetCmd() {
mySerial.write(0x56);
mySerial.write(byte(0x00));
mySerial.write(0x26);
mySerial.write(byte(0x00));
}
//void SetImageSizeCmd()
//{
//mySerial.write(0x56);
//mySerial.write(byte(0x00));
//mySerial.write(0x31);
//mySerial.write(0x05);
//mySerial.write(0x04);
//mySerial.write(0x01);
//mySerial.write(byte(0x00));
//mySerial.write(0x19);
//mySerial.write(0x22);
//}
//void SetBaudRateCmd()
//{
//mySerial.write(0x56);
//mySerial.write(byte(0x00));
//mySerial.write(0x24);
//mySerial.write(0x03);
//mySerial.write(0x01);
//mySerial.write(0xAE);
//mySerial.write(0xC8);
//
//}
//Send take picture command
void SendTakePhotoCmd() {
mySerial.write(0x56);
mySerial.write(byte(0x00));
mySerial.write(0x36);
mySerial.write(0x01);
mySerial.write(byte(0x00));
}
//Read data
void SendReadDataCmd() {
MH = a / 0x100;
ML = a % 0x100;
mySerial.write(0x56);
mySerial.write(byte(0x00));
mySerial.write(0x32);
mySerial.write(0x0c);
mySerial.write(byte(0x00));
mySerial.write(0x0a);
mySerial.write(byte(0x00));
mySerial.write(byte(0x00));
mySerial.write(MH);
mySerial.write(ML);
mySerial.write(byte(0x00));
mySerial.write(byte(0x00));
mySerial.write(byte(0x00));
mySerial.write(0x20);
mySerial.write(byte(0x00));
mySerial.write(0x0a);
a += 0x20; //address increases 32£¬set according to buffer size
}
void StopTakePhotoCmd() {
mySerial.write(0x56);
mySerial.write(byte(0x00));
mySerial.write(0x36);
mySerial.write(0x01);
mySerial.write(0x03);
}
`
The code basically sends a take picture command to the camera and then reads the HEX values that the camera sends and saves the values in an array. We know the camera works because we tested it on another device.
The problem initially was, the values that we were getting from the camera aren't correct. The EndFlag in the while loop is never toggled because the HEX values that indicate the end of a JPEG values (FF and D9) are never read so it never breaks from the while loop. Now, the terminal doesn't print anything until the camera is disconnected, then all the values seem to get flushed to the screen and the command mySerial.available() returns 0 meaning that there is nothing in the serial read buffer.
I compared your code with the example sketch provided from the manufacturer and figured out that your initialization procedure differs from the original. In the official sample code they first connect to the camera on 115200 serial baudrate, tells camera to change it's baudrate to 38400 and then they connect to camera again but with different speed - 38400 baud.
In your code I see that you are connecting on 38400 baud speed in the beginning. However, the camera is operating at a different speed and this explains why you get garbage instead of valid data. I recommend that you perform the correct initialization procedure, as described in the example:
void setup()
{
Serial.begin(38400);
mySerial.begin(115200);
delay(100);
SendResetCmd();
delay(2000);
SetBaudRateCmd(0x2A);
delay(500);
mySerial.begin(38400);
delay(100);
Serial.println("initialization done.");
}
Also, uncomment SetBaudRateCmd() function as it's used in the initialization procedure.

Resources