For my final project, I’m going to build something for this Zoom era. I get a lot of migraines and sometimes just need to put my head down during classes/meetings…but, I don’t want to fall asleep!
This contraption aims to detect when the user has put their head down and gently remind them to stay present. The user also will have the option to display the text of what is being said.
The Arduino program:
Input: when has the user put their head down. I will use either an ultrasonic sensor or use this Capacitor Sensor library to create a sensor using foil inside the pillow.
Output: gentle sound using piezo buzzer depending on input in Processing program, also sends signal to Processing program that user has put head down
(I would also like to explore creating vibrations as output but am not sure how to do this)
The Processing program (p5.js):
Input: signal from Arduino that user has put head down, speech of class/meeting, time interval user wants to be reminded at
Output: display text of class/meeting, sends signal to Arduino of when to create sound/vibrations
Considerations:
The p5 program will have an alert: the user should only display the transcript if there is consent from the other participants in the Zoom call (ex: meeting is being recorded). The program will also not save the text anywhere and will be cleared from the screen after a certain time.
The P5 speech library I wanted to use (Thanks Aaron for the rec!) seems to be better than expected at recognizing names that aren’t typically used in English (it recognized a lot of my friends’ names and mine when I experimented), but it will definitely not be perfect, so I’m not sure whether to proceed with the name recognition alarm feature.
So for this project, we will be using an Arduino Uno Board and an SR-04 Ultrasonic sensor, a breadboard, and a few wires. So this game is built upon the midterm game that I have created previously, Drowning Diver. But this time around, the game is controlled with an ultrasonic sensor that feels the distance between whatever is put in front of it. When sensor is covered it goes up, when user puts his fingers away that cover sensor the diver goes down and drowns))
To be honest, I really wanted to make a game using screen. Last lesson when we were having a group discussion of our ideas, Alima has mentioned that we have a so-called screen that can display on it. That was the time when I got so excited to working with it, but immediately that idea backfired.
const int trigPin=11;
int echoPin=10;
int safezone=10;
//int dpin=13;
void setup()
{
pinMode(trigPin,OUTPUT);
pinMode(echoPin,INPUT);
//pinMode(dpin,OUTPUT);
//digitalWrite(dpin,LOW);
Serial.begin(9600);
}
void loop()
{
long duration,cm; //DECLARE VARIABLES TO STORE SENSOR O/P
digitalWrite(trigPin,LOW); //MAKE THE TRIG PIN LOW
delayMicroseconds(2); //WAIT FOR FEW MICROSECONDS
digitalWrite(trigPin,HIGH); //NOW SET THE TRIG PIN
delayMicroseconds(5); //WAIT FOR FEW MICROSECONDS UNTIL THE TRIG PULSE IS SENT
digitalWrite(trigPin,LOW); //MAKE THE TRIG PIN LOW AGAIN
duration=pulseIn(echoPin,HIGH); //MAKE ECHO PIN HIGH AND STORE THE BOUNCED PULSE IN VARIABLE DURATION
cm=microsecondsToCentimeters(duration);
long inch= cm/2.54;
//if(cm<safezone)
//{
//digitalWrite(dpin,HIGH);
Serial.println(cm);
//delay(500);
//digitalWrite(dpin,LOW);
//}
}
long microsecondsToCentimeters(long microseconds) //SPEED OF SOUND IS 29 uSEC PER CM
{
return microseconds/29/2; //THE PULSE TRAVELS FROM THE SENSOR AND AGAIN COMES BACK SO WE DIVIDE IT BY 2 TO TAKE ONLY HALF OF THE TOTAL DISTANCE
}
For this extra credit project, I wanted to test my knowledge of the handshake between processing and arduino and so I came up with a space shooter game. It is a pretty basic game in which the space ship has to shoot the incoming meteoroids and if it shoots 10 of them the game is over.
Processing
The processing part is basically the interface of the game, which includes the start screen, the space ship, the asteroid and the whole shooting mechanism and also the end screen.
The game starts with the start screen in which the player clicks within a box to start playing.
The code basically spawns random sizes of asteroids, that fall at random speeds too. If the player is able to shoot 10 asteroids, the game is over and the player is prompted to either restart the game or click on game over to return to the start screen.
Processing Code:
import processing.serial.*;
Serial myPort;
ArrayList<Asteroid> asteroids = new ArrayList<Asteroid>(); //gives the list of asteroids
Player player; //player object
boolean shoot = false; // ensures that the player only shoots when commanded
ArrayList<Player.Bullet> bullets = new ArrayList<Player.Bullet>(); //bullet list
float timer = 0;
float timerlength = 4000;
boolean game_over = false;
boolean start = false;
int count = 0;
int currentButtonState = 0;
int prevButtonState = 0;
float mover = width/2;
void setup()
{
size(1280, 960);
imageMode(CENTER);
//asteroids.add(new Asteroid(random(width*0.25, width*0.75), 0, int(random(1, 3)))); //initialising the list of asteroids to spawn in between the roads of the game
player = new Player();
printArray(Serial.list());
String portname=Serial.list()[6];
println(portname);
myPort = new Serial(this,portname,9600);
myPort.clear();
myPort.bufferUntil('\n');
}
void draw()
{
PImage bg;
bg = loadImage("space.jpeg");
bg.resize(int(width),int(height));
background(bg); //background is the top down view of a road
if (start == false)
{
textAlign(BASELINE);
rectMode(CENTER);
fill(255);
stroke(230,153,0);
rect(width/2,height/2,700,500,10);
rect(width/2, height/2,680,480,10);
fill(0);
textSize(50);
text("Welcome", 480, 410);
fill(255);
rect(625,580,600,100,10);
fill(0);
text("Click to Play", 420, 610);
if ((mouseX >= 325 && mouseX <= 925) && (mouseY >= 530 && mouseY <= 630) && (mousePressed == true))
{
start = true;
}
}
else{
if(game_over == false)
{
Player_Mechanics();
Asteroid_Mechanics();
Shoot();
Mover();
if( millis() > timer)
{
asteroids.add(new Asteroid(random(width*0.25, width*0.75), 0, int(random(1, 3)))); //initialising the list of asteroids to spawn
timerlength = random(1000,5000);
timer = millis() + timerlength;
}
}
else{
textAlign(BASELINE);
rectMode(CENTER);
fill(255);
stroke(230,153,0);
rect(width/2,height/2,700,500,10);
rect(width/2, height/2,680,480,10);
fill(0);
textSize(50);
stroke(0);
text("Game Over!", 420, 410);
fill(255);
rect(625,580,600,100,10);
fill(0);
text("Restart", 420, 610);
if ((mouseX >= 325 && mouseX <= 925) && (mouseY >= 530 && mouseY <= 630) && (mousePressed == true))
{
game_over = false;
count = 0;
}
if ((mouseX >= 325 && mouseX <= 925) && (mouseY >= 330 && mouseY <= 430) && (mousePressed == true))
{
start = false;
}
}
}
}
void serialEvent(Serial myPort){
String s=myPort.readStringUntil('\n');
s=trim(s);
if (s!=null){
println(s);
int values[]=int(split(s,','));
if (values.length==3){
currentButtonState=(int)values[0];
prevButtonState=(int)values[1];
mover = map(values[2], 0, 1023, player.size/2, width-player.size/2);
}
}
myPort.write("\n");
}
void Player_Mechanics()
{
player.drawPlayer(); //draws the Player on Screen
for(int i =0; i< bullets.size(); i++)
{
bullets.get(i).draw_Bullet();
bullets.get(i).shoot_Bullet(); //if bullets are present, draws them and shoots them
if(bullets.get(i).bullet_posY_1 < 0 )
bullets.remove(i); //removes the bullet once they are out of frame
}
}
void Asteroid_Mechanics()
{
for (int i = 0; i < asteroids.size(); i++)
{
asteroids.get(i).drawAsteroid();
asteroids.get(i).moveAsteroid(); //draws and moves asteroids on screen
if(asteroids.get(i).posY > height + asteroids.get(i).size)
asteroids.remove(i); //removes the asteroids once they are out of frame
if( bullets.size() > 0 && asteroids.size() > 0 )
{
for(int j=0; j<bullets.size(); j++)
{
if( bullets.size() > 0 && asteroids.size() > 0 )
{
if(asteroids.get(i).vicinty_check(bullets.get(j).bullet_posX,bullets.get(j).bullet_posY_2))
{
asteroids.remove(i); //destroys the asteroid and removes it once bullet touches it
count++;
}
}
}
}
}
if (count == 10){
game_over = true;
}
}
void keyPressed()
{
if (key == ' ')
{
asteroids.add(new Asteroid(random(width*0.25, width*0.75), 0, int(random(1, 3)))); //spawns an asteroid
}
if (key == 'a')
{
player.moveLeft(); //player goes left
}
if (key == 'd')
{
player.moveRight(); //player goes right
}
if (key == 'f')
{
bullets.add(player.new Bullet(0)); //shoots bullets
}
}
void Shoot()
{
if (currentButtonState == 1 && prevButtonState == 0) {
bullets.add(player.new Bullet(0));
println("cheeky");
}
}
void Mover()
{
player.posX = mover;
}
class Asteroid {
float posX;
float posY;
int speed = (int)random(2,6);
int size;
PImage asteroid;
Asteroid(float x, float y, int s)
{
posX = x;
posY = y;
size = s*100;
asteroid = loadImage("asteroid_brown.png");
imageMode(CENTER);
}
void drawAsteroid()
{
asteroid.resize(size, 0);
image(asteroid, posX, posY); //resizes and draws the asteroid
}
void moveAsteroid()
{
posY += speed; //moves the asteroid
}
boolean vicinty_check(float x, float y)
{
if ((x < posX+size/2 && x > posX-size/2) && (y < posY+size/2 && y > posY-size/2)) //checks if anything exists in the vicintiy of the asteroid's body
return true;
else
return false;
}
}
class Player {
public float posX = width/2;
public float posY = height-100;
PImage player;
int movement=20;
int size =100;
Player()
{
player = loadImage("Spaceship_tut.png");
imageMode(CENTER);
}
void drawPlayer()
{
player.resize(size, 0);
pushMatrix();
translate(posX, posY);
//rotate(radians(270));
image(player, 0, 0);
popMatrix(); //resizes and rotates the image of the player on screen so that it is appropriate for the game
}
void moveLeft()
{
if (posX > size/2)
posX -= movement; //player moves left
}
void moveRight()
{
if (posX < width-size/2)
posX += movement; //player moves right
}
class Bullet { //nested bullet class in player class
float bullet_posX = posX ;
float bullet_posY_1 = posY - size/2;
float bullet_size = size * 0.1;
float bullet_posY_2 = posY - size/2 - bullet_size;
int bullet_speed = 20;
Bullet(float y)
{
bullet_posY_1 -= y;
bullet_posY_2 -= y; //assigns intial position to bullet
}
void draw_Bullet()
{
stroke(102,255,102);
strokeWeight(6);
line(bullet_posX, bullet_posY_1, bullet_posX, bullet_posY_2); //draws a line for a bullet
}
void shoot_Bullet()
{
bullet_posY_1 -= bullet_speed;
bullet_posY_2 -= bullet_speed; //moves bullet
}
}
}
Arduino
The Arduino part involves the controls for the game in which the potentiometer is used to move the spaceship around and the push button is used to shoot the missiles from the spaceship.
Arduino Code:
int buttonPin = 2;
int prevButtonState = LOW;
void setup() {
pinMode(buttonPin, INPUT);
Serial.begin(9600);
Serial.println("0,0");
}
void loop() {
while (Serial.available()) {
if (Serial.read() == '\n') {
int currentButtonState = digitalRead(buttonPin);
delay(1);
Serial.print(currentButtonState);
Serial.print(',');
Serial.print(prevButtonState);
Serial.print(',');
prevButtonState = currentButtonState;
int mover = analogRead(A0);
delay(1);
Serial.println(mover);
}
}
//Serial.println(sensor);
}
Circuit:
Videos:
This is the video of me showing the way the game works:
This is a video of me actually playing the game:
Difficulties:
In certain instances, I felt that the button was not responding in the way I wanted it to but I believe that is primarily because I hadn’t plugged it well or the communication of information was slow.
Overall:
This project was actually really fun and it made me feel so cool to create my own joystick for my game. This has also motivated me quite a lot for my final project which I am really looking forward to!
This week we were given the option of creating a game with the Arduino and I decided to continue with my favorite Processing game thus far, my F1 simulator. I wanted to make a controller that would be integrated into the game.
Game Controller:
There are three main inputs in a car (a simplified automatic one anyways), steering, gas, and acceleration. My game already had these inputs but steering was in essence binary (full left, neutral, full right). I decided that analog input could make for much more fun steering and in addition to gas/brake buttons I could make a F1 car controller.
For the steering I used the potentiometer. I had to rework all my code for how the car was steered as it was no longer left or right, but rather any value from full left to full right and anywhere in-between. I ended up checking which way the potentiometer was facing and mapping the annual acceleration of the car off of this.
I also added a brake and gas button. These were super easy to implement as they behaved exactly the same as if I was pressing the up or down arrow in the keyboard controls so all I had to was change to binary values if they were on or off.
Finally I wanted something a bit extra than just inputs, also outputs that could make the player feel more like they were in a car. I decided to add two LEDs, a green one that would light up when pressing the gas, and a red one that would light up when braking, or flash when the car crashed like hazard lights. This allowed me to try the no delay blinking code as well.
Circuit
Code
Arduino Code
const int brakeLed = 5;
const int forwardLed = 4;
const int forwardButton = 2;
const int brakeButton = 3;
const int sensorPin = A0;
int forward = 0;
int brake = 0;
int crash = 0;
long timer = 0;
int timerLength = 500;
bool onOff = false;
void setup() {
Serial.begin(9600);
Serial.println("0,0");
pinMode(brakeLed, OUTPUT);
pinMode(forwardLed, OUTPUT);
pinMode(forwardButton, INPUT);
pinMode(brakeButton, INPUT);
}
void loop() {
while (Serial.available()) {
forward = Serial.parseInt();
brake = Serial.parseInt();
crash = Serial.parseInt();
if (Serial.read() == '\n') {
if (crash) {
if (millis() > timer) {
onOff = !onOff;
digitalWrite(brakeLed, onOff);
digitalWrite(forwardLed, LOW);
timer = millis() + timerLength;
}
}
else{
digitalWrite(forwardLed, forward);
digitalWrite(brakeLed, brake);
}
int forwardToggle = digitalRead(forwardButton);
delay(1);
int brakeToggle = digitalRead(brakeButton);
delay(1);
int steeringInput = analogRead(sensorPin);
delay(1);
Serial.print(forwardToggle);
Serial.print(',');
Serial.print(brakeToggle);
Serial.print(',');
Serial.println(steeringInput);
}
}
}
Processing Code
import processing.sound.*;
//======= Global variables ========
int gameMode = 0; //0 is main menu, 1 select your car, 2 running game, 3 crash, 4 controls menu, 5 credits
Team teams[] = new Team[10];
int teamSelector = 0; //Which team from array is selected
int[][] teamDict = {{7, 0, 7, 0, 0}, {8, 1, 8, 0, 1}, {5, 2, 5, 0, 2}, {4, 3, 4, 0, 3}, {0, 4, 0, 0, 4}, {2, 5, 2, 1, 0}, {1, 6, 1, 1, 1}, {6, 7, 6, 1, 2}, {9, 8, 9, 1, 3}, {3, 9, 3, 1, 4}}; //Dictonary containing index of car sprite, associated team image sprite index, team name index, menu row, menu col
//====== Team Selection Menu Variables
PImage teamMenuImg;
//====== Trak Menu Variables
// PImage track[][] = new PImage[10][10]; //For tile system
//float tileWidth = 2560; //For tile system
PImage map;
float trackScale = 1; //What percent of original size should track be drawn
//====== Main Game Variables
float rotation = PI; //Current angle
float speed = 0; //Current speed
float maxSpeed = 500; //Max speed on the track
float sandMaxSpeed = 20; //Max speed off the track
float posX = -4886.6123; //0,0 is top left of track , values increase negative as they are reversed
float posY = -1254.3951;
float acceleration = 5; //How fast the car speeds up on track
float sandAcceleration = 1; //How fast the car speeds up in sand
float brakeDeacceleration = 10; //How quick the car stops when braking on track
float coastDeacceleration = 2; //How quick the car stops when no power
float sandDeacceleration = 15; //How quick the car stops in sand
float angularAcceleration = PI/20; //How fast the car turns
boolean reverse = false;
float carScale = 0.3; //What percent of original size should car be drawn
//Keyboard inputs
boolean forward = false;
boolean brake = false;
boolean left = false;
boolean right = false;
//Sound
SoundFile accSound;
float accSoundAmp = 0;
float soundRate = 0.5;
//Timing
int passedTime; //How long has passed since saved time mark
int savedTime; //Savea time to start timer
boolean activeTimer = false; //Set to false, becomes active when crossing start line or false if reversed over
int bestTime = -1;
//Menu files
PImage controls;
PImage credits;
//Main menu variables
int numButtons = 3;
int activeButton = 0; // 0 for start, 1 for controls, 2 for credits
int buttonWidth = 200;
int buttonHeight = 100;
int buttonSpacing = 50;
int buttonYOffset = 100;
String buttonContent[] = {"Start Game","Controls","Credits"};
float buttonX;
float buttonY;
//Arduino game control variables
import processing.serial.*;
Serial myPort;
boolean crash = false;
void setup() {
fullScreen();
//Set up the team array
//=======================================================================================
PImage[] carSprites;
PImage[] teamSprites;
String[] nameArray = {"McLaren F1 Team",
"Scuderia AlphaTauri Honda",
"Mercedes-AMG Petronas F1 Team",
"ROKiT Williams Racing",
"Haas F1 Team",
"BWT Racing Point F1 Team",
"Scuderia Ferrari",
"Alfa Romeo Racing ORLEN",
"Aston Martin Red Bull Racing",
"Renault F1 Team"
};
//Alfa Romeo, Red Bull, Racing Point, Haas, Mclaren, Mercedes, AlphaTauri, Ferrari, Renault, Williams
//Set sprite sheets
carSprites = getCarSpriteSheet("SpriteSheetCars.png"); //Load the car sprite sheet into sprites
teamSprites = getTeamSpriteSheet("Teams.png"); //Load the team sprite sheet into sprites
//Set teams array with appropiate info
for (int i = 0; i < 10; i++) {
Team newTeam = new Team();
newTeam.setName(nameArray[teamDict[i][2]]); //Set team name
newTeam.setCarImg(carSprites[teamDict[i][0]]); //Set team img
newTeam.setTeamImg(teamSprites[teamDict[i][1]]); //Set team car img
teams[i] = newTeam;
}
//=======================================================================================
//Load menu imgs
teamMenuImg = loadImage("Teams.png");
controls = loadImage("Controls.png");
credits = loadImage("Credits.png");
//=======================================================================================
//Load map
map = loadImage("Track.png");
//=======================================================================================
//Load sound
accSound = new SoundFile(this, "acc.wav");
accSound.loop();
accSound.amp(accSoundAmp);
accSound.rate(soundRate);
//Start lap timer
savedTime = millis();
//Start serial communication with controller
String portname=Serial.list()[1];
myPort = new Serial(this,portname,9600);
myPort.clear();
myPort.bufferUntil('\n');
}
void draw() {
//Main Gamemode Control selector
switch(gameMode) {
case 0:
mainMenu();
break;
case 1:
teamMenu();
break;
case 2:
runGame();
break;
case 3:
crash();
break;
case 4:
controls();
break;
case 5:
credits();
break;
}
}
//When all game cariables need to be reset to start status
void resetVariables(){
accSound.amp(0);
forward = brake = right = left = false;
activeTimer = false;
speed = 0;
gameMode = 0;
posX = -4886.6123; //0,0 is top left of track , values increase negative as they are reversed
posY = -1254.3951;
rotation = PI;
crash = false;
}
void serialEvent(Serial myPort){
String s=myPort.readStringUntil('\n');
s=trim(s);
if (s!=null){
println(s);
int values[]=int(split(s,','));
if (values.length==3){
if(values[0] == 1 && values[1] == 1){
forward = false;
brake = false;
}
else if (values[0] == 1){
forward = true;
}
else if (values[1] == 1){
brake = true;
}
else if (values[0] == 0 && values[1] == 0){
forward = false;
brake = false;
}
int steering = values[2];
//Turn left
if(steering > 1023/2){
left = true;
right = false;
angularAcceleration = map(values[2],1023/2,1023,0, PI/20);
}
else if(steering < 1023/2){
left = false;
right = true;
angularAcceleration = map(values[2],1023/2,0,0, PI/20);
}
}
}
println(crash);
myPort.write(int(forward)+","+int(brake)+","+int(crash)+"\n");
}
In our previous post, Maaz and I mentioned that we would be using Processing and Arduino together to make a game for our final project which would be similar to Tetris. However, both of us were not very satisfied with how we were using the sensors in our game. We thought we could find some ways to better utilize the Arduino components. Additionally, after the discussion session on Monday, we were pretty sure that we had to make tweaks to the game play.
We now have a new version of our game. This version is very different from Tetris but it uses most of the sensors in the same way as the previous version did. The distance sensor continues to be the most important resistor, while we have added a few new features. This version is an NYUAD-themed game, in which the player playing the game sees certain objects falling down the screen. These objects will be of two categories: objects which the player should catch and objects which the player should avoid. The player controls the game using the breadboard which has the distance sensor mounted on it (the entire things acts as a “remote control”). Towards the right and left of the remote control will be a frame (made of cardboard for instance). The two sides of this frame represent the endpoints of the game screen, and they help us determine how far the distance sensor (and hence the remote control) is from one end of the screen. Using this “remote control”, the player’s position can also be displayed on the screen for the player to figure out how close/far away they are from objects that are to be caught/avoided.
The ground rules of the game are as the following:
Just like in the previous version of our game, this version will have multiple levels of varying difficulty. We plan to have four levels corresponding to four academic years, with each succeeding level harder than the previous one.
The player has to maintain two metrics of performances: academic performance and well-being. There are certain objects that are beneficial and objects that are harmful to a performance. You need to catch the good objects (which will increase your performance) and avoid the bad ones (which will decrease your performance).
Initially, both performances start at 50% and you need to take them both to 100% to finish the year and advance to the next academic year. If either of the performances reaches to 0, you fail the year.
If you fail, you are presented with 3 options:
You can either restart college (restarting the entire game)
Or you can restart the academic year (restarting that particular level)
Or you can drop out (exiting the game)
If you finishing all four academic years, you win the game (congrats on graduating)
You will be given a diploma and introduced to “other games” (Career, Graduate schools, might be coming soon (no they aren’t, we are not doing those for real))
Arduino – Processing communication
Distance sensor is implemented as a remote control:
The Arduino program calculates how far the remote control is from a vertical surface
The distance is sent to Processing which will map the distance into the player’s horizontal coordinate
An icon representing the player’s position on the Processing screen is updated accordingly
Processing will check for collision with items. If there is a collision, a signal is sent to Arduino to play a sound on the buzzer
When the player is presented with a screen that has options (for example, the starting screen can have Instructions, Start game, the ending screen can have Restart college, Restart the year, Drop out), the player can use the potentiometer on the Arduino to traverse the options and press a button when the desired option is selected to proceed.
Processing receives the signal from the potentiometer and maps it to a range to decide which option is currently selected by the player and communicates this back to the player by highlighting the option.
Two tricolor LEDs on the Arduino are used to communicate the player’s current performances, one to represent academic performance and the other to represent well-being. If the player’s performance in either is fulfilled (reaches 100), the LED(s) turns green; if performance is adequate, the LED(s) turns blue/yellow (?); and if performance is low (approaching 0), the LED(s) turns red.
Exercise 3: The photoresistor affected the wind direction and each time the ball bounced on Processing, I wrote to the serial to communicate to Arudino that the LED should light up. I originally used a photoresistor, but it felt a bit clunky. I still find the response in the wind vector kind of slow but find the movement more intuitive than the potentiometer.
Arduino Code:
int phot = A0;
int led = 2;
int bounce = 0;
int pastVal;
int val;
void setup() {
Serial.begin(9600);
Serial.println("0,0");
pinMode(led, OUTPUT);
pinMode(phot, INPUT);
val = analogRead(phot);
pastVal = val;
}
void loop() {
while (Serial.available()) {
bounce = Serial.parseInt();
if (bounce == 1) {
digitalWrite(led, HIGH);
} else {
digitalWrite(led, LOW);
}
if (Serial.read() == '\n') {
val = analogRead(phot);
if (pastVal != val) {
if (val >= 34) {
Serial.println(1);
} else {
Serial.println(-1);
}
pastVal = val;
}
else {
Serial.println(0);
}
}
}
}
Processing Code:
PVector velocity;
PVector gravity;
import processing.serial.*;
Serial myPort;
PVector position;
PVector acceleration;
PVector wind;
float drag = 0.99;
float mass = 50;
float hDampening;
int bounce = 0;
void setup() {
size(640,360);
noFill();
position = new PVector(width/2, 0);
velocity = new PVector(0,0);
acceleration = new PVector(0,0);
gravity = new PVector(0, 0.5*mass);
wind = new PVector(0,0);
hDampening=map(mass,15,80,.98,.96);
String portname=Serial.list()[2];
myPort = new Serial(this,portname,9600);
myPort.clear();
myPort.bufferUntil('\n');
}
void draw() {
background(255);
velocity.x*=hDampening;
applyForce(wind);
applyForce(gravity);
velocity.add(acceleration);
velocity.mult(drag);
position.add(velocity);
acceleration.mult(0);
ellipse(position.x,position.y,mass,mass);
if (position.y > height-mass/2) {
velocity.y *= -0.9; // A little dampening when hitting the bottom
position.y = height-mass/2;
bounce = 0;
}
}
void applyForce(PVector force){
// Newton's 2nd law: F = M * A
// or A = F / M
PVector f = PVector.div(force, mass);
acceleration.add(f);
}
void keyPressed(){
if (key==' '){
mass=random(15,80);
position.y=-mass;
velocity.mult(0);
}
}
void serialEvent(Serial myPort){
String s=myPort.readStringUntil('\n');
s=trim(s);
if (s!=null) {
int windVal = int(s);
println(windVal);
if (wind.x >= -1 || wind.x <= 1) {
wind.x = windVal;
}
}
if (round(velocity.y) < 0) {
bounce = 1;
} else {
bounce = 0;
}
myPort.write(bounce + "\n");
}
For my midterm project i have several ideas, which i can implement using atduino and processing .
The first idea is a “therapy app” . It will include different options and modes for different aims. Like relax or otherwise focusing.
The second idea is some sort of the game travelling story, where you can make some exercises( small interactive games) to continue and reach the end of the story. The theme i’m gonna choose is ecology to pay audience attention to a problems are happening now.
Exercise 1: make something that uses only one sensoron arduino and makes the ellipse in processing move on the horizontal axis, in the middle of the screen, and nothing on arduino is controlled by processing.
PROCESSING_EXERCISE 1
import processing.serial.*;// serial object library
Serial myPort; //local serial object from serial library
int xPos=0;
int yPos=0;
void setup(){
size(960,720);
printArray(Serial.list());
String portname=Serial.list()[2]; //link processing to serial port
println(portname);
myPort = new Serial(this,portname,9600);
myPort.clear();
myPort.bufferUntil('\n');
}
void draw(){
background(255);
ellipse(xPos,height/2,30,30);
}
void serialEvent(Serial myPort){
String s=myPort.readStringUntil('\n'); //strips data of serial port
s=trim(s);
if (s!=null){
println(s);
int value=int(s);
// locates position of ellipse using potentiometer
xPos=(int)map(value,0,1023,0, width);
}
myPort.write("\n");
}
ARDUINO_EXERCISE 1
void setup() {
//initialize the serial port and data upload
Serial.begin(9600);
Serial.println("0");
}
void loop() {
//capture data in arduino
int sensor= analogRead(A0);
//put data in the serial port
while (Serial.available()) {
if (Serial.read() == '\n') {
delay(1);
//prints the value
Serial.println(sensor);
}
}
}
Exercise 2: make something that controls the LED brightness from processing.
PROCESSING_EXERCISE 2
import processing.serial.*;
Serial myPort;
int xPos=0;
int Sensor=0;
boolean Red=false;
boolean Green=false;
void setup(){
size(960,720);
printArray(Serial.list());
String portname=Serial.list()[2];
println(portname);
myPort = new Serial(this,portname,9600);
myPort.clear();
myPort.bufferUntil('\n');
}
void draw(){
background(255);
ellipse(mouseX,mouseY,30,30);
if ((mouseX >= 400) && (mouseY >= 600)) {
Red =true;
} else Red = false;
if ((mouseX <= 400) && (mouseY <= 600)){
Green =true;
}
else Green = false;
}
void serialEvent(Serial myPort){
String s=myPort.readStringUntil('\n');
s=trim(s);
if (s!=null){
println(s);
int values[]=int(split(s,','));
if (values.length==2){
xPos=(int)map(values[0],0,1023,0, width);
}
}
myPort.write(int(Red)+","+int(Green)+"\n");
print("0,0");
}
ARDUINO_EXERCISE 2
int left = 0;
int right = 0;
void setup() {
Serial.begin(9600);
Serial.println("0,0");
pinMode(2, OUTPUT);
pinMode(5, OUTPUT);
}
void loop() {
while (Serial.available()) {
right = Serial.parseInt();
//left = Serial.parseInt();
if (Serial.read() == '\n') {
digitalWrite(2, right);
//digitalWrite(5, left);
int sensor = analogRead(A0);
delay(1);
//int LDRPIN = analogRead(A1);
//delay(1);
Serial.print(sensor);
//Serial.print(',');
//Serial.println(LDRPIN);
}
}
}
Exercise 3: take the gravity wind example and make it so every time the ball bounces one led lights up and then turns off, and you can control the wind from one analog sensor.
PROCESSING_EXERCISE 3
import processing.serial.*;
Serial myPort;
int xPos=0;
int Sensor=0;
boolean Red=false;
boolean Green=false;
PVector velocity;
PVector gravity;
PVector position;
PVector acceleration;
PVector wind;
float drag = 0.99;
float mass = 50;
float hDampening;
void setup(){
size(640,360);
printArray(Serial.list());
String portname=Serial.list()[1];
println(portname);
myPort = new Serial(this,portname,9600);
myPort.clear();
myPort.bufferUntil('\n');
noFill();
position = new PVector(width/2, 0);
velocity = new PVector(0,0);
acceleration = new PVector(0,0);
gravity = new PVector(0, 0.5*mass);
wind = new PVector(0,0);
hDampening=map(mass,15,80,.98,.96);
}
void draw(){
background(255);
if (!keyPressed){
wind.x=0;
velocity.x*=hDampening;
}
applyForce(wind);
applyForce(gravity);
velocity.add(acceleration);
velocity.mult(drag);
position.add(velocity);
acceleration.mult(0);
ellipse(position.x,position.y,mass,mass);
if (position.y > height-mass/2) {
velocity.y *= -0.9; // A little dampening when hitting the bottom
position.y = height-mass/2;
Red = true;
}
else { Red = false;
}
}
void serialEvent(Serial myPort){
String s=myPort.readStringUntil('\n');
s=trim(s);
if (s!=null){
println(s);
int values[]=int(split(s,','));
if (values.length==2){
xPos=(int)map(values[0],0,1023,0, width);
// yPos=(int)map(values[1],0,1023,0, height);
}
}
myPort.write(int(Red)+","+int(Green)+"\n");
print("0,0");
}
void applyForce(PVector force){
// Newton's 2nd law: F = M * A
// or A = F / M
PVector f = PVector.div(force, mass);
acceleration.add(f);
}
void keyPressed(){
if (keyCode==LEFT){
wind.x=-1;
}
if (keyCode==RIGHT){
wind.x=1;
}
if (key==' '){
mass=random(15,80);
position.y=-mass;
velocity.mult(0);
}
}
ARDUINO_EXERCISE 3
int left = 0;
int right = 0;
void setup() {
Serial.begin(9600);
Serial.println("0,0");
pinMode(2, OUTPUT);
// pinMode(5, OUTPUT);
}
void loop() {
while (Serial.available()) {
right = Serial.parseInt();
left = Serial.parseInt();
if (Serial.read() == '\n') {
digitalWrite(2, right);
// digitalWrite(5, left);
int sensor = analogRead(A0);
//delay(1);
//int LDRPIN = analogRead(A1);
delay(1);
Serial.print(sensor);
//Serial.print(',');
//Serial.println(LDRPIN);
}
}
}
Arduino and Processing have numerous capabilities allowing them to connect to one another. Thus, this assignment presents these factors with three tasks my partner, Hamad, and I were instructed to follow.
Plan:
Go over what we touched upon in class and reference from numerous videos around the internet to explore the multiple ways possible to get to the goal desired.
Code:
Task 1:
ARDUINO & PROCESSING:
Task 2:
ARDUINO:
//INITIALIZE VARIABLE
float var;
//ARDUINO AND PROCESSING COMMUNICATION SETUP
void setup()
{
Serial.begin(9600);
//GET ONLY 1 INPUT - BRIGHTNESS
Serial.println("0");
pinMode(2, OUTPUT);
}
//MAIN FUNCTION
void loop()
{
while (Serial.available())
{
//GET PROCESSING VARIABLE
var = Serial.parseInt();
if (Serial.read() == '\n')
{
//GIVE LED BRIGHTNESS
analogWrite(2, var);
Serial.println(var);
}
}
}
PROCESSING:
//LINK TO ARDUINO
import processing.serial.*;
Serial myPort;
//INITIALIZE VARIABLES
int xPos = 0;
float var;
void setup()
{
size(960, 720);
printArray(Serial.list());
String portname=Serial.list()[0];
println(portname);
myPort = new Serial(this, portname, 9600);
myPort.clear();
myPort.bufferUntil('\n');
}
void draw()
{
background(255);
ellipse(xPos, height/2, 30, 30);
//GET X POSITION
float var1 = mouseX;
//MAP WIDTH TO BRIGHTNESS
var = map(var1, 0, width, 0, 255);
}
void serialEvent(Serial myPort)
{
String s=myPort.readStringUntil('\n');
s = trim(s);
if (s != null)
{
println(s);
int value = int(s);
if (value >= 0) {
xPos = (int)map(value, 0, 1023, 0, width);
}
}
//SEND BACK MAPPED X VALUE TO ARDUINO
myPort.write(var+ "\n");
}
Task 3:
ARDUINO:
//INITIALIZE VARIABLES
int left = 0;
int right = 0;
int var = 0;
//VARIBALES & LED SETUP
void setup()
{
Serial.begin(9600);
Serial.println("0,0");
pinMode(2, OUTPUT);
}
void loop()
{
while (Serial.available())
{
//STORES LED VALUE FROM PROCESSING
var = Serial.parseInt();
Serial.println(var);
if (Serial.read() == '\n')
{
//TURN LED ON IF BALL TOUCHES GROUND
if (var == 1)
{
digitalWrite(2, HIGH);
}
}
//GET VALUES FROM POTENTIOMETER
int sensor = analogRead(A0);
delay(1);
Serial.println(sensor);
}
}
PROCESSING:
//LINK PROCESSING TO ARDUINO
import processing.serial.*;
Serial myPort;
//INITIALIZE VARIABLES
PVector velocity;
PVector gravity;
PVector position;
PVector acceleration;
PVector wind;
float drag = 0.99;
float mass = 50;
float hDampening;
int potValue; //variable from the potentiometer
int led = 0; //variable to change to switch the led off
//REGULATIONS
void setup()
{
size(640, 360);
noFill();
position = new PVector(width/2, 0);
velocity = new PVector(0, 0);
acceleration = new PVector(0, 0);
gravity = new PVector(0, 0.5*mass);
wind = new PVector(0, 0);
hDampening=map(mass, 15, 80, .98, .96);
}
//ARDUINO INTERACTION
void draw()
{
background(255);
if (!keyPressed)
{
//MOVE CIRCLE BASED ON POTENTIOMETER INPUT
wind.x = potValue;
velocity.x*=hDampening;
}
applyForce(wind);
applyForce(gravity);
velocity.add(acceleration);
velocity.mult(drag);
position.add(velocity);
acceleration.mult(0);
ellipse(position.x, position.y, mass, mass);
if (position.y > height-mass/2)
{
velocity.y *= -0.9;
position.y = height-mass/2;
}
}
void applyForce(PVector force)
{
// Newton's 2nd law: F = M * A
// or A = F / M
PVector f = PVector.div(force, mass);
acceleration.add(f);
}
void keyPressed()
{
if (keyCode==LEFT)
{
wind.x=-1;
}
if (keyCode==RIGHT)
{
wind.x=1;
}
if (key==' ')
{
mass=random(15, 80);
position.y=-mass;
velocity.mult(0);
}
}
void serialEvent(Serial myPort)
{
String s = myPort.readStringUntil('\n');
s=trim(s);
if (s != null) {
int value = int(s);
potValue = (int)map(value, 0, 1023, 0, width*.01);
}
//TURN LED ON IF BALL TOUCHES GROUND
if (round(velocity.y) < 0)
{
led = 1;
myPort.write(int(led)+ "\n");
}
}