Final Version for Final Project Documentation : Shamma & Theyab

WEATHER PATIO 


 


ARDUINO & PROCESSING

Done By : Shamma & Theyab

 


MOTIVE:

In the UAE, the weather is constantly sunny and we do not spend much time outdoors. Now that it's winter time, it is the norm to hang out in the desert or spend family time and gatherings out in the backyard.This project is a miniature of what could be used as a shade from the rain during rainy days while still being able to enjoy the sun on sunny days. When the temperature rises, like it does on most days in the UAE, the fan turns on to cool down the temperature. In the absence of light, at night for instance which is when most gatherings happen, the light will turn on to provide a more heart-warming ambience.

PROJECT SUMMARY:

The project is a smart outdoor cover that we called the weather patio . It has the following different features. First, the system will detect if it’s raining, and if it is then it will close the rollable roof. Second, the system measures the temperature and if the temperature is very high, it will turn on a fan. Last, but not least, it detects if it’s night time and turns on the lights when it’s dark. 

SYSTEM I/O:

Input:

- Rain Sensor

- Temperature Sensor

- Light Sensor

Output:

-Servo or DC Motor

-Fan DC

-LED Strip with relay




DESCRIPTION OF EACH INPUT/OUTPUT ON ARDUINO & WHAT IT WILL SEND/RECEIVE FROM PROCESSING  :

Input Arduino:

        1. Rain sensor to detect if it’s raining
        2. Temperature sensor to detect the ambient temperature.
        3. Light sensor to detect the light in the area.

 

Output Arduino:

        • Motor (servo or DC) to close and open the roof top
        • Fan to cool down the temperature
        • LED strip or bulb to add light during the night

 

Basically, all the inputs will send the data to the processing in order to be visualized on the processing screen. That allows monitoring of the temperature, rain existence and light in the area. Thus, all the outputs of the Arduino will receive control from the processing , as the system we are building is automatic using the Arduino code with processing code integrated.

DESCRIPTION OF PROCESSING & WHAT IT WILL SEND/RECEIVE TO ARDUINO:

Processing is used for one main reasons:

-   Monitor the values given by the temperature sensor and other sensors. Provides interactive visualizations of the output in order to capture the essence of the experience.



PROCEDURE:

RAIN FALL SENSOR:
The rain sensor detects water that comes short circuiting the tape of the printed circuits.

The sensor acts as a variable resistance that will change status : the resistance increases when the sensor is wet and the resistance is lower when the sensor is dry.

Connection:

Arduino –> Comparator

5V –> VCC

GND –> GND

DO –> D4

AO –> A0

Blueled ->pin 3

A blue LED is connected to show the presence of rain. If it’s raining, the blue LED will turn on, if it’s not raining the blue LED is off.

Code of Rain Sensor :

//RAINFALL SENSOR CODE
const int capteur_D = 4;
const int capteur_A = A0;
int blueled=2;
int val_analogique;
void setup()
{
pinMode(capteur_D, INPUT);
pinMode(capteur_A, INPUT);
pinMode(blueled, OUTPUT);
Serial.begin(9600);
}
void loop()
{
if(digitalRead(capteur_D) == LOW)
{
Serial.println("Digital value : wet");
delay(10);
digitalWrite(blueled,HIGH);
}
else
{
Serial.println("Digital value : dry");
delay(10);
digitalWrite(blueled,LOW);
}
val_analogique=analogRead(capteur_A);
Serial.print("Analog value : ");
Serial.println(val_analogique);
Serial.println("");
delay(1000);
}
LIGHT SENSOR:
LDR light dependent resistor to have an automatic light turn on when it’s dark.


Connection

LDR: one side to 5V, other pin to analog pin A1 and to a 4.7K resistor connected to GND.

Output: LED on pin 3

Code with LDR:

const int capteur_D = 4;
const int capteur_A = A0;
int blueled=2;//for rain
int val_analogique;
int LDRsensorPin=A1;
int LDRsensorValue = 0;
int greenled = 3;//green light for ldr
void setup()
{
pinMode(capteur_D, INPUT);
pinMode(capteur_A, INPUT);
pinMode(blueled, OUTPUT);
pinMode(greenled, OUTPUT);
Serial.begin(9600);
}

void loop()
{
if(digitalRead(capteur_D) == LOW)
{
Serial.println("Digital value : wet");
delay(10);
digitalWrite(blueled,HIGH);
}
else
{
Serial.println("Digital value : dry");
delay(10);
digitalWrite(blueled,LOW);
}
val_analogique=analogRead(capteur_A);
Serial.print("Analog value : ");
Serial.println(val_analogique);
Serial.println("");
LDRsensorValue = analogRead(LDRsensorPin);
if(LDRsensorValue < 600)
{
Serial.println("LED light on");
digitalWrite(greenled,HIGH);Serial.println(LDRsensorValue);
//delay(1000);
}
else {digitalWrite(greenled,LOW);Serial.println(LDRsensorValue);}
delay(1000);
TEMPERATURE SENSOR & FAN:

We need a temperature sensor DS18B20 with a 4.7kohm resistor for input, as output we have a dc fan.

           If the temperature is high the fan will turn on.

           If the temperature is low the fan is off.

           Digital pin used is pin 5 for the temperature sensor

           Red led is to show if the temp above the limit.

           Redled is on pin 6

Code :

//code for temperature sensor
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS temppin //pin in 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
void setup()
{
pinMode(redled, OUTPUT);
Serial.begin(9600);
//code for tempqrature
sensors.begin();
}
void loop()
{
/********************************************************************/
//temperature sensor
sensors.requestTemperatures(); // Send the command to get temperature readings
Serial.println("Temperature is: ");
celsius = sensors.getTempCByIndex(0);
Serial.print(celsius);
if(celsius>baselinetemp)digitalWrite(redled,HIGH);
else digitalWrite(redled,LOW);
}
STEPPER MOTOR :
The stepper motor used is a 5 V motor with a Stepper Motor with Driver (28BYJ-48 5V DC).

A stepper motor, much like a DC motor has a rotating permanent magnet propelled by stationary electrical magnets, however the motion is divided into a number of steps around the rotation of the rotating magnet. It does so by having several teeth on the rotating magnet that line up with specific locations around the stationary charged magnets. When voltage is supplied to a specific magnet or specific sequence of magnets the motor will rotate, or step to that position and hold.

Stepper motors can spin like a regular DC motor, however they can also stop on a position like a servo motor.

Code is using the library Stepper.h :

#include <Stepper.h>
// Define number of steps per rotation:
const int stepsPerRevolution = 2048;
// Wiring:
// Pin 8 to IN1 on the ULN2003 driver
// Pin 9 to IN2 on the ULN2003 driver
// Pin 10 to IN3 on the ULN2003 driver
// Pin 11 to IN4 on the ULN2003 driver
// Create stepper object called 'myStepper', note the pin order:
Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);
void setup() {
// Set the speed to 5 rpm:
myStepper.setSpeed(5);
// Begin Serial communication at a baud rate of 9600:
Serial.begin(9600);
}
void loop() {
// Step one revolution in one direction:
Serial.println("clockwise");
myStepper.step(stepsPerRevolution);
delay(500);
// Step one revolution in the other direction:
Serial.println("counterclockwise");
myStepper.step(-stepsPerRevolution);
delay(500);
}

Code Explanation:

The Stepper.h Arduino library is included in the first step of the project. On the website, you may learn more about this library.
// Include the Arduino Stepper.h library:
#include <Stepper.h>

 

 

Then we estimated how many steps it takes the motor to complete one rotation. We'll use the motor in full-step mode in this example. This translates to 2048 steps to complete a 360-degree rotation (see motor specifications above).
// Define number of steps per rotation:
const int stepsPerRevolution = 2048;

 

 

The next step is to build a new instance of the Stepper class, which represents a specific stepper motor that is attached to the Arduino. The function Stepper(steps, pin1, pin2, pin3, pin4) is used for this, where steps is the number of steps per revolution and pin1 through pin4 are the motor's pins. Set the pins in the following order to acquire the right step sequence: 8, 10,9,11.
// Create stepper object called 'myStepper', note the pin order:
Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);

We labeled the stepper motor 'myStepper' in this example, but you could call it 'z motor' or 'liftmotor' instead. For example ,
Stepper liftmotor = Stepper(stepsPerRevolution, 8, 10, 9, 11);
Multiple stepper motor objects with distinct names and pins can be created. This makes it simple to control two or more stepper motors at once. 

With the function, you may specify the speed in rpm in the setup by having
setSpeed(rpm).

 

 

 At 5 V, a 28byj-48 stepper motor's maximum speed is around 10-15 rpm.
void setup() {
// Set the speed to 5 rpm:
myStepper.setSpeed(5);
// Begin Serial communication at a baud rate of 9600:
Serial.begin(9600);
}

 

 

We just call the step(steps) function in the loop part of code, which rotates the motor a certain number of steps at a speed defined by the function below
setSpeed(rpm)

 

 

Passing a negative value to this function causes the motor to spin in the opposite direction.
void loop() {
// Step one revolution in one direction:
Serial.println("clockwise");
myStepper.step(stepsPerRevolution);
delay(500);
// Step one revolution in the other direction:
Serial.println("counterclockwise");
myStepper.step(-stepsPerRevolution);
delay(500);
}

 

Source Used : 

28byj-48-stepper-motor-arduino-tutorial




ASSEMBLY:

After having each sensor as input and component as outputs, we put everything together to assemble the project. For the processing code we based our code on the professors code :

https://github.com/aaronsherwood/introduction_interactive_media/blob/master/arduinoExamples/serialExamples/04_sendMultipleToProcessing/04_sendMultipleToProcessing.ino

In order to send multiple values from the Arduino to processing, we kept the handshake and we read the values.

CONNECTION:

The stepper Motor is connected to the cover that should close when it rains. In order to have the motor control the cover we assumed the cover has a roller controller like the one found in normal curtains. So, we designed the controller that could be fitted into the stepper motor and to the cable of the roller curtain. Once the stepper motor turns clockwise, it will close the cover and if it turns anti clockwise it will open the cover
The reference to have the piece for the roller curtain is on this tutorial found below ...

https://circuitdigest.com/microcontroller-projects/arduino-based-roller-blinds-project-to-automate-and-control-window-curtains-using-nodemcu-and-stepper-motor

PROCESSING PROCEDURE :

After getting feedback from the professor, we changed the processing code entirely to have a more interactive animation. The code changed the display from a value display to an interactive animation display. In order to do the new code we used snippets of code from the open processing website.
The 4 screen parts are:

- Sun

- Moon

- Rain

- Thermometer

Below are the Code for Each Part:

RAIN:

int nb=750; // number of drops
int maxDrops =1000;
int minDrops=500;
int h,h1;
Drop[] drops=new Drop[maxDrops];

void setup(){
  size(900,625,P3D);
  smooth();
  frameRate(30);
  h = abs(height/3);
  h1=h*2;
  for (int i = 0; i < maxDrops; i++){
    drops[i] = new Drop(int(random(width)),-int(random(height*2)),(int)map((h+int(random(h1))),height*.35,height,0,height),1280); 
  }

}

void draw(){
  gradient();
  for (int i=0;i<nb;i++){
    drops[i].fall();
  }
}

void gradient(){
  noStroke();
  beginShape(QUADS);
  fill(188,190,192); 
  vertex(0,0); 
  vertex(width,0);
  fill(0,5,10); 
  vertex(width,height); 
  vertex(0,height);
  endShape(); 
}

class Drop{
  int x,y,d,z,onde,d1,oldY;
  float acc;
  boolean s;

  Drop(int x,int y, int z, int d){
    this.x=x;
    this.y=y;
    this.d=d;
    this.z=z;
    onde=0;
    d1=d;
    acc=0;
    oldY=y;
  }

  void fall(){
    if(y>0)acc+=0.2;
    stroke(200,200,200,map(z,0,height,0,255));
    strokeWeight(2);
    if (y<z){
      y=int(y+4+acc);
      line(x,oldY,x,y);
      oldY=y;
    }
    else{
      noFill();
      stroke(175,175,175,175-map(onde,0,d,0,255));
      strokeWeight(map(onde,0,d,0,4));
      d=d1+(y-height)*4;
      ellipse(x,y,onde/5,onde/20);
      onde=onde+7;
      if(onde>d){
        onde=0;
        acc=0;
        x=int(random(width));
        y=-int(random(height*2));
        oldY=y;
        d=d1;
      }
    }
  }
}

SUNNY DAY:

void setup() {
    size( 600, 600 );
    smooth();
}

void draw() {
    
    background( 51 ); //resents background color to dark gray
    int rbound = 200; //default
    
    fill( 255, 246, 64 ); //yellow
    stroke( 255, 246, 64 ); //yellow
    strokeWeight( 5 );
    int twinkle = 80; //distance change in ray length
    //float radius=200; //radius of rays
    float radius;
    int numPoints=130; //number of rays
    float angle=TWO_PI/(float)numPoints;
    
    //create rays
    for(int i=0;i<numPoints;i++)
    {
        radius = rbound - (int)random( 0, twinkle );
        line(300,300,radius*sin(angle*i)+300,radius*cos(angle*i)+300);
    } 
    
    //ellipse( 300, 300, 200, 200 ); //sun

    //face
    stroke( 51 ); //dark gray
    strokeWeight( 4 );
   
        arc( 250, 300, 40, 30, PI, TWO_PI ); //left eye
        arc( 350, 300, 40, 30, PI, TWO_PI ); //right eye
    arc( 300, 335, 100, 70, PI/6, 5*PI/6 ); //mouth

}

NIGHT SKY:

float phaseNum=2;
int index = 0;
PFont f;

void setup() {
  size(500,500);
  background(0);
  noStroke();
}

void draw(){
  fill(0,random(170,200));
  rect(0,0,width,height);
  drawMoon();
  {drawShadow((width/2)-(phaseNum*35),height/2);} 
}


void drawMoon(){
    for(int i=1; i<50; i++) {
      fill(245,10);
      ellipse(width/2, height/2,200-i*5,200-i*5);
      ellipse(width/2, height/2,150,150);
    }
}

void drawShadow(float x, float y) {
    for(int i=1; i<50; i++) {
      fill(0,80);
      ellipse(x, y,180-i*5,180-i*5);
    }
}

THERMOMETER:

Challenges faced :

The challenges faced are mostly the changes that we had to do for the processing code. As we first wrote a code that displays the values of the sensors, then after the feedback, we changed the code into animation which is interactive with the sensor output. So glad we did that as it made our project come all together. The project was a learning curve as we spent a lot of time working on the mechanism of the moveable roof, and on the processing code to display the interactive animation.

IMAGES OF OUR PROCEDURE :

The 3D printer that we used to print the pieces we made 


 

The journey of making our brainstorming session come into reality by putting the hardware of Arduino to processing connection.

In the above image, we only 3D printed a different piece that would be for our roof just cause we though it would look more aesthetic and is more practical when putting it together. 

Later, we designed the house out of plexi, on which we attached a motor. Then we connected the motor to a lever which is the white part and that lifts the roof. Through coding in Arduino, we can rotate the roof in terms if lifting and lowering. Another thing is that we attached a fan to the house to be used with the temperature sensor. The control box found is where we kept all the sensors. In addition, we added a double relay connected to the led strip and the fan to control them, as these components require a higher voltage power. The final prototype looks like a house with a moveable roof, a fan, a light, and sensors to control them. The animation part is reflected on an iPad that we placed inside the house, and the way it is being displayed is by using the application: TeamViewer which basically mirrors the laptop screen while having our processing code running in full screen on the laptop.
Enjoy the doll sized house we built which allows you a full experience.

We created a manual that we will attach in our project table to aid with the user friendly experience

We used iMovie app to edit the video and got the bar video from YouTube. The first background picture wasfrom google images and the rest of the footage was taken by me and Theyab. We also added a free audio from YouTube (took the audio only from the video) for the background music and added to that my own voiceover after recording it on a voice note app using the add audio feature. Then, adding all the texts was easy since there is an option for text on iMovie and I have set the duration for every clip as we saw appropriate. Later, for the video within the picture (when speaking about the input sensors), we used the picture within picture option on the iMovie app. At last, we just wanna say that we are grateful and proud of what we were able to accomplish and present to our upcoming community in the IM End of Semester Show !

Final VIDEO FOR WEATHER PATIO :




PROCESSING FULL CODE:

//import Serial communication library
import processing.serial.*;
//init variables
Serial myPort;
int tempC;
int tempF;
int yDist;
int rainstatus;
int[] tempHistory = new int[100];
int ldrvalue;

//code for rain
int nb=750; // number of drops
int maxDrops =1000;
int minDrops=500;
int h,h1;
Drop[] drops=new Drop[maxDrops];
//moon code
float phaseNum=2;
int index = 0;
PFont f;


void setup()
{
//set the size of the window
fullScreen();
// size(1000,800,P3D);
 printArray(Serial.list());
 String portname=Serial.list()[3];
 println(portname);
 
//init serial communication port
 myPort = new Serial(this, portname, 9600);
 myPort.clear();
 myPort.bufferUntil('\n');
//fill tempHistory with default temps
 for(int index = 0; index<100; index++)
 tempHistory[index] = 0;
 
 //rain code
 smooth();
  frameRate(30);
  h = abs(height/3);
  h1=h*2;
  for (int i = 0; i < maxDrops; i++){
    drops[i] = new Drop(int(random(width)),-int(random(height*2)),(int)map((h+int(random(h1))),height*.35,height,0,height),1280); 
  }
  f = createFont("Arial",20);
}

void draw()
{thermometer();
 //dark 
 
 if(ldrvalue<400){
 //moon code
 background(0);
  noStroke();
 fill(255,255,255);
 //rect(475,120,220,150);
 fill(0,random(170,200));
  rect(0,0,width,height);
  drawMoon();
  {drawShadow((width/2)-(phaseNum*35),height/2);} 
  thermometer();
 }
 //sun
 else{sun();thermometer();}
 
 if(rainstatus==1){
   //rain code
  gradient();
  for (int i=0;i<nb;i++){ drops[i].fall();}
 }
 //else sun();
 
 
} 

void serialEvent(Serial myPort){

  String s=myPort.readStringUntil('\n');

  s=trim(s);

  if (s!=null){

    int values[]=int(split(s,','));

    if (values.length==3){

     // tempC=(int)map(values[0],0,1023,0, width);
tempC=values[0];
ldrvalue=values[1];
      rainstatus=values[2];

    }
      println(tempC,ldrvalue,rainstatus);

  myPort.write('0');

}

  }
  
  //code for rain screen
  
void gradient(){
  noStroke();
  beginShape(QUADS);
  fill(188,190,192); 
  vertex(0,0); 
  vertex(width,0);
  fill(0,5,10); 
  vertex(width,height); 
  vertex(0,height);
  endShape(); 
}

class Drop{
  int x,y,d,z,onde,d1,oldY;
  float acc;
  boolean s;

  Drop(int x,int y, int z, int d){
    this.x=x;
    this.y=y;
    this.d=d;
    this.z=z;
    onde=0;
    d1=d;
    acc=0;
    oldY=y;
  }

  void fall(){
    if(y>0)acc+=0.2;
    stroke(200,200,200,map(z,0,height,0,255));
    strokeWeight(2);
    if (y<z){
      y=int(y+4+acc);
      line(x,oldY,x,y);
      oldY=y;
    }
    else{
      noFill();
      stroke(175,175,175,175-map(onde,0,d,0,255));
      strokeWeight(map(onde,0,d,0,4));
      d=d1+(y-height)*4;
      ellipse(x,y,onde/5,onde/20);
      onde=onde+7;
      if(onde>d){
        onde=0;
        acc=0;
        x=int(random(width));
        y=-int(random(height*2));
        oldY=y;
        d=d1;
      }
    }
  }
}

//sun
void sun() {
    
    background( 51 ); //resents background color to dark gray
    int rbound = 200; //default
    
    fill( 255, 246, 64 ); //yellow
    stroke( 255, 246, 64 ); //yellow
    strokeWeight( 5 );
    int twinkle = 80; //distance change in ray length
    //float radius=200; //radius of rays
    float radius;
    int numPoints=130; //number of rays
    float angle=TWO_PI/(float)numPoints;
    
    //create rays
    for(int i=0;i<numPoints;i++)
    {
        radius = rbound - (int)random( 0, twinkle );
        line(width/2, height/2,radius*sin(angle*i)+width/2,radius*cos(angle*i)+height/2);
    } 
    
    //ellipse( 300, 300, 200, 200 ); //sun

    //face
    stroke( 51 ); //dark gray
    strokeWeight( 4 );
   
        arc( (width/2)-50, height/2, 40, 30, PI, TWO_PI ); //left eye
        arc( (width/2)+50, height/2, 40, 30, PI, TWO_PI ); //right eye
    arc( (width/2), height/2+35, 100, 70, PI/6, 5*PI/6 ); //mouth

}
//code moon

void drawMoon(){
    for(int i=1; i<50; i++) {
      fill(245,10);
      ellipse(width/2, height/2,200-i*5,200-i*5);
     ellipse(width/2, height/2,150,150);
    }
}

void drawShadow(float x, float y) {
    for(int i=1; i<50; i++) {
      fill(0,80);
      ellipse(x, y,180-i*5,180-i*5);
    }
}

void thermometer(){
//fill background in gray
 //background(211,211,211);

 fill (227,227,227);
 //smooth();

 //build thermostat
 rectMode(CORNER);
 rect (50, 50, 20, 200);
 ellipse (60, 270, 40, 40);

 //build quicksilver reservoir
 fill(255, 0, 0);
 ellipse (60, 270, 20, 20);

 //quicksilver
 float thermometer_value = map(tempC,0,50,200,0);
 rect(57, 57 + thermometer_value, 6, (200 - thermometer_value));

 //define stroke
 stroke (255,0,0);
 strokeWeight(2);

 //draw font
 textFont(f,20);
 text ( "Temp", 35, 330);
 text ( "(" + tempC + "C)", 35, 360);
}

 

ARDUINO FULL CODE :

const int capteur_D = 4;

const int capteur_A = A0;

int blueled=2;//for rain

int val_analogique;

int LDRsensorPin=A1;

int LDRsensorValue = 0;

int greenled = 3;//green light for ldr

int redled=6;

int temppin=5;

int baselinetemp=25;

int ldrvaluelimit=400;

int celsius=0;

bool closed=false;
int raining=0;
//code for stepper motor

#include <Stepper.h>

const int stepsPerRevolution = 500;//2048;

Stepper myStepper(stepsPerRevolution, 8, 10,9, 11);

 

 

//code for temperature sensor

#include <OneWire.h>

#include <DallasTemperature.h>

#define ONE_WIRE_BUS temppin //pin in 4

OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

 

void setup()

{

  pinMode(capteur_D, INPUT);

  pinMode(capteur_A, INPUT);

  pinMode(blueled, OUTPUT);

  pinMode(greenled, OUTPUT);

  pinMode(redled, OUTPUT);

 

myStepper.setSpeed(10);

 

  Serial.begin(9600);

  //code for tempqrature

  sensors.begin();

//handshake

  Serial.println("0,0");

}

 

void loop()

{

  /********************************************************************/

  //rain sensor

if(digitalRead(capteur_D) == LOW)

  {

   // Serial.println("Digital value : wet");
   raining=1;
    delay(10);

    digitalWrite(blueled,HIGH);

    if(!closed){//Serial.println("close: turn counterclockwise"); 

    myStepper.step(stepsPerRevolution);

    delay(1000);

    closed=true;  }

  }

else

  {raining=0;
    //Serial.println("Digital value : dry");

    delay(10);

    digitalWrite(blueled,LOW);

   if(closed){

    //Serial.println("open: turn clockwise"); 

    myStepper.step(- stepsPerRevolution);

    delay(1000);

    closed=false;}

  }

val_analogique=analogRead(capteur_A);
 //Serial.println("Analog value for rain sensor : ");

//Serial.print(val_analogique);

// Serial.println("");

delay(500);

/********************************************************************/

//ldr sendor


 LDRsensorValue = analogRead(LDRsensorPin);

if(LDRsensorValue < ldrvaluelimit)

{

  /// Serial.println("LED light on");

   digitalWrite(greenled,HIGH);//Serial.print(LDRsensorValue);

   //delay(1000);

}

else {digitalWrite(greenled,LOW);//Serial.println("LED light off,LDR value:");Serial.print(LDRsensorValue);
}

 

/********************************************************************/

//temperature sensor

sensors.requestTemperatures(); // Send the command to get temperature readings

//Serial.println("Temperature is: ");

 celsius = sensors.getTempCByIndex(0);

if(celsius>baselinetemp)digitalWrite(redled,HIGH);

else digitalWrite(redled,LOW);

 

 

  delay(1000);

//processing code

Serial.print(celsius);
Serial.print(',');
Serial.print(LDRsensorValue);
Serial.print(',');
Serial.println(raining);
/*/
if(Serial.available()>0){
char state = Serial.read ( );    // Reading the data received and saving in the state variable

if(state == '1')             // If received data is '1', then turn on LED

{ 

digitalWrite (greenled, HIGH); 

}  

if (state == '0') {     // If received data is '0', then turn off led

digitalWrite (greenled, LOW);

} 

} 

delay(50);

 */   

  }

 




 REFERENCES:

https://create.arduino.cc/projecthub/MisterBotBreak/how-to-use-a-rain-sensor-bcecd9

https://create.arduino.cc/projecthub/SURYATEJA/automatic-street-light-controller-27159f

https://randomnerdtutorials.com/guide-for-ds18b20-temperature-sensor-with-arduino/

https://www.aranacorp.com/en/control-a-stepper-motor-with-arduino/

https://osoyoo.com/2017/07/10/arduino-lesson-stepper-motor/

https://www.makerguides.com/28byj-48-stepper-motor-arduino-tutorial/

https://github.com/aaronsherwood/introduction_interactive_media/blob/master/arduinoExamples/serialExamples/04_sendMultipleToProcessing/04_sendMultipleToProcessing.ino

https://circuitdigest.com/microcontroller-projects/arduino-based-roller-blinds-project-to-automate-and-control-window-curtains-using-nodemcu-and-stepper-motor

https://openprocessing.org/sketch/368990/

https://kavasmlikon.wordpress.com/2011/11/23/processing-how-to-create-real-time-info-graphics-with-sensor-data-from-pachube/

https://openprocessing.org/sketch/106168/

https://openprocessing.org/sketch/51775/#

 

Final Project Progress : Shamma & Theyab

WEATHER PATIO 


 


ARDUINO & PROCESSING

Done By : Shamma & Theyab

 


PROJECT SUMMARY:

The project is a smart outdoor cover that we called the weather patio . It has the following different features. First, the system will detect if it’s raining, and if it is then it will close the rollable roof. Second, the system measures the temperature and if the temperature is very high, it will turn on a fan. Third, it detects if it’s night time and turns on the lights when it’s dark. Fourth, it displays all the values on a screen. Last, but not least, it allows for manual control from processing on a screen, so the roof , the fan and the light can be turned on manually using the screen controls.

SYSTEM I/O:

Input:

- Rain Sensor

- Temperature Sensor

- Light Sensor

Output:

-Servo or DC Motor

-Fan DC

-LED Strip with relay

 




DESCRIPTION OF EACH INPUT/OUTPUT ON ARDUINO & WHAT IT WILL SEND/RECEIVE FROM PROCESSING  :

 

Input Arduino:

        1. Rain sensor to detect if it’s raining
        2. Temperature sensor to detect the ambient temperature.
        3. Light sensor to detect the light in the area.

 

Output Arduino:

        • Motor (servo or DC) to close and open the roof top
        • Fan to cool down the temperature
        • LED strip or bulb to add light during the night

           

Basically, all the inputs will send the data to the processing in order to be visualized on the processing screen. That allows monitoring of the temperature, rain existence and light in the area. Thus, all the outputs of the Arduino will receive control from the processing , as the system we are building will be controlled manually using the screen of processing or automatically using the Arduino code.

DESCRIPTION OF PROCESSING & WHAT IT WILL SEND/RECEIVE TO ARDUINO:

Processing is used for two main reasons:

-   Monitor the values given by the temperature sensor and other sensors.

-   Allow for manual control of the outputs. As we will add buttons on the screen to be able to turn on/off the outputs when we need regardless of the value.

The manual control is needed as sometimes even it is not raining we might want to close the roof top. Or even turn on / off the fan regardless if it’s too hot, even turn on and off the light regardless of the time of the day.




PROCEDURE:

RAIN FALL SENSOR:
The rain sensor detects water that comes short circuiting the tape of the printed circuits.

The sensor acts as a variable resistance that will change status : the resistance increases when the sensor is wet and the resistance is lower when the sensor is dry.

Connection:

Arduino –> Comparator

5V –> VCC

GND –> GND

DO –> D4

AO –> A0

Blueled ->pin 3

A blue LED is connected to show the presence of rain. If it’s raining, the blue LED will turn on, if it’s not raining the blue LED is off.

Code of Rain Sensor :

//RAINFALL SENSOR CODE
const int capteur_D = 4;
const int capteur_A = A0;
int blueled=2;
int val_analogique;
void setup()
{
  pinMode(capteur_D, INPUT);
  pinMode(capteur_A, INPUT);
  pinMode(blueled, OUTPUT);
  Serial.begin(9600);
}
void loop()
{
if(digitalRead(capteur_D) == LOW) 
  {
    Serial.println("Digital value : wet"); 
    delay(10); 
    digitalWrite(blueled,HIGH);
  }
else
  {
    Serial.println("Digital value : dry");
    delay(10); 
    digitalWrite(blueled,LOW);
  }
val_analogique=analogRead(capteur_A); 
 Serial.print("Analog value : ");
 Serial.println(val_analogique); 
 Serial.println("");
  delay(1000);
}
LIGHT SENSOR:
LDR light dependent resistor to have an automatic light turn on when it’s dark.


Connection

LDR: one side to 5V, other pin to analog pin A1 and to a 4.7K resistor connected to GND.

Output: LED on pin 3

Code with LDR:

const int capteur_D = 4;
const int capteur_A = A0;
int blueled=2;//for rain
int val_analogique;
int LDRsensorPin=A1;
int LDRsensorValue = 0;
int greenled = 3;//green light for ldr
void setup()
{
  pinMode(capteur_D, INPUT);
  pinMode(capteur_A, INPUT);
  pinMode(blueled, OUTPUT);
  pinMode(greenled, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
if(digitalRead(capteur_D) == LOW) 
  {
    Serial.println("Digital value : wet"); 
    delay(10); 
    digitalWrite(blueled,HIGH);
  }
else
  {
    Serial.println("Digital value : dry");
    delay(10); 
    digitalWrite(blueled,LOW);
  }
val_analogique=analogRead(capteur_A); 
 Serial.print("Analog value : ");
 Serial.println(val_analogique); 
 Serial.println("");
 LDRsensorValue = analogRead(LDRsensorPin);
 if(LDRsensorValue < 600)
 {
   Serial.println("LED light on");
   digitalWrite(greenled,HIGH);Serial.println(LDRsensorValue);
   //delay(1000);
 }
 else {digitalWrite(greenled,LOW);Serial.println(LDRsensorValue);}
  delay(1000);
TEMPERATURE SENSOR & FAN:

We need a temperature sensor DS18B20 with a 4.7kohm resistor for input, as output we have a dc fan.

           If the temperature is high the fan will turn on.

           If the temperature is low the fan is off.

           Digital pin used is pin 5 for the temperature sensor

           Red led is to show if the temp above the limit.

           Redled is on pin 6

Code :

//code for temperature sensor


#include <OneWire.h>


#include <DallasTemperature.h>


#define ONE_WIRE_BUS temppin //pin in 4


OneWire oneWire(ONE_WIRE_BUS);


DallasTemperature sensors(&oneWire);


void setup()


{


  pinMode(redled, OUTPUT);


 


  Serial.begin(9600);


  //code for tempqrature


  sensors.begin();


}


void loop()


{


/********************************************************************/


//temperature sensor


sensors.requestTemperatures(); // Send the command to get temperature readings


Serial.println("Temperature is: ");


 celsius = sensors.getTempCByIndex(0);


Serial.print(celsius);


if(celsius>baselinetemp)digitalWrite(redled,HIGH);


else digitalWrite(redled,LOW);


}

STEPPER MOTOR :
The stepper motor used is a 5 V motor with a Stepper Motor with Driver (28BYJ-48 5V DC).

A stepper motor, much like a DC motor has a rotating permanent magnet propelled by stationary electrical magnets, however the motion is divided into a number of steps around the rotation of the rotating magnet. It does so by having several teeth on the rotating magnet that line up with specific locations around the stationary charged magnets. When voltage is supplied to a specific magnet or specific sequence of magnets the motor will rotate, or step to that position and hold.

Stepper motors can spin like a regular DC motor, however they can also stop on a position like a servo motor.

Code is using the library Stepper.h :

#include <Stepper.h>
// Define number of steps per rotation:
const int stepsPerRevolution = 2048;
// Wiring:
// Pin 8 to IN1 on the ULN2003 driver
// Pin 9 to IN2 on the ULN2003 driver
// Pin 10 to IN3 on the ULN2003 driver
// Pin 11 to IN4 on the ULN2003 driver
// Create stepper object called 'myStepper', note the pin order:
Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);
void setup() {
// Set the speed to 5 rpm:
myStepper.setSpeed(5);
// Begin Serial communication at a baud rate of 9600:
Serial.begin(9600);
}
void loop() {
// Step one revolution in one direction:
Serial.println("clockwise");
myStepper.step(stepsPerRevolution);
delay(500);
// Step one revolution in the other direction:
Serial.println("counterclockwise");
myStepper.step(-stepsPerRevolution);
delay(500);
}

Code Explanation:

The Stepper.h Arduino library is included in the first step of the project. On the website, you may learn more about this library.
// Include the Arduino Stepper.h library:
#include <Stepper.h>
Then we estimated how many steps it takes the motor to complete one rotation. We'll use the motor in full-step mode in this example. This translates to 2048 steps to complete a 360-degree rotation (see motor specifications above).
// Define number of steps per rotation:
const int stepsPerRevolution = 2048;
The next step is to build a new instance of the Stepper class, which represents a specific stepper motor that is attached to the Arduino. The function Stepper(steps, pin1, pin2, pin3, pin4) is used for this, where steps is the number of steps per revolution and pin1 through pin4 are the motor's pins. Set the pins in the following order to acquire the right step sequence: 8, 10,9,11.
// Create stepper object called 'myStepper', note the pin order:
Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);
We labeled the stepper motor 'myStepper' in this example, but you could call it 'z motor' or 'liftmotor' instead. For example ,
Stepper liftmotor = Stepper(stepsPerRevolution, 8, 10, 9, 11);
Multiple stepper motor objects with distinct names and pins can be created. This makes it simple to control two or more stepper motors at once. 

With the function, you may specify the speed in rpm in the setup by having
setSpeed(rpm).
 At 5 V, a 28byj-48 stepper motor's maximum speed is around 10-15 rpm.
void setup() {
// Set the speed to 5 rpm:
myStepper.setSpeed(5);
// Begin Serial communication at a baud rate of 9600:
Serial.begin(9600);
}
We just call the step(steps) function in the loop part of code, which rotates the motor a certain number of steps at a speed defined by the function below
setSpeed(rpm)
Passing a negative value to this function causes the motor to spin in the opposite direction.
void loop() {
// Step one revolution in one direction:
Serial.println("clockwise");
myStepper.step(stepsPerRevolution);
delay(500);
// Step one revolution in the other direction:
Serial.println("counterclockwise");
myStepper.step(-stepsPerRevolution);
delay(500);
}

Source Used : 

28byj-48-stepper-motor-arduino-tutorial




ASSEMBLY:

After having each sensor as input and component as outputs, we put everything together to assemble the project. For the processing code we based our code on the professors code :

https://github.com/aaronsherwood/introduction_interactive_media/blob/master/arduinoExamples/serialExamples/04_sendMultipleToProcessing/04_sendMultipleToProcessing.ino

In order to send multiple values from the Arduino to processing, we kept the handshake and we read the values until having the new line. The processing is to display values on the screen of the temperature, the rain status, and the light status. We created rectangles to present each input. The background color of the rectangles changes in accordance to the value. If the rain is present, the rectangle of rain changes to blue color and displays the sentence “it’s raining”. If the temperature is high or low we can see it as a graph with history of the previous 30 values. The temperature is displayed in Celsius and in Farhranayt. The LDR shows the light value so the rectangle changes color to yellow when it is dark which indicates that the light is turned on. In other words, processing was our way to visualize the data coming from the Arduino.

CONNECTION:

The stepper Motor is connected to the cover that should close when it rains. In order to have the motor control the cover we assumed the cover has a roller controller like the one found in normal curtains. So, we designed the controller that could be fitted into the stepper motor and to the cable of the roller curtain. Once the stepper motor turns clockwise, it will close the cover and if it turns anti clockwise it will open the cover
The reference to have the piece for the roller curtain is on this tutorial found below ...

https://circuitdigest.com/microcontroller-projects/arduino-based-roller-blinds-project-to-automate-and-control-window-curtains-using-nodemcu-and-stepper-motor

IMAGES OF OUR PROCEDURE :

The 3D printer that we used to print the pieces we made 


The journey of making our brainstorming session come into reality by putting the hardware of Arduino to processing connection.

The doll sized house we are in the process of making to allow you a full experience


PROGRESS VIDEO :

USER TESTING VIDEO :

FEEDBACK FROM THE TESTER :

At first without explaining our project to him , he said he was not able to figure it out, like he cant make sense of what's being presented to him. However, after I gave the general instructions of what each shall do, and the whole project's concept, it made sense. He recommends us to create a brochure or a manual as a guidelines. Another thing he suggested is maybe connect our light sensor to an actual light bulb so it creates a more realistic experience or instead remove the other LEDs so only the light one has the impression of a light bulb as the others are technical. Last, but not least, his final comment was that cause our concept is based on an outdoor experience, it will be nice if after finishing our project we test it out in the daylight.

NEXT STEPS OF IMPROVING :

We would definitely try to either remove the other less or connect to a light bulb if it works with us, and other than that add the extra features that shall be there. For instance, we are still designing our doll size house and we still haven't done the temperature connection to the fan. Our main goal is to finish up with the actual features we shall have , and if we were able to finish all that, then we may consider either removing less or adding a light bulb as mentioned above.



PROCESSING FULL CODE:

//import Serial communication library
import processing.serial.*;
//init variables
Serial myPort;
int tempC;
int tempF;
int yDist;
int rainstatus;
int[] tempHistory = new int[100];
int ldrvalue;
void setup()
{
//set the size of the window
 size(800,600);
 printArray(Serial.list());
 String portname=Serial.list()[7];
 println(portname);
 
//init serial communication port
 myPort = new Serial(this, portname, 9600);
 myPort.clear();
 myPort.bufferUntil('\n');
//fill tempHistory with default temps
 for(int index = 0; index<100; index++)
 tempHistory[index] = 0;
}

void draw()
{
 //get the temp from the serial port
 //while (myPort.available() > 0) 
 {

//refresh the background to clear old data
 background(123);
 //draw the temp rectangle
 colorMode(RGB, 160);  //use color mode sized for fading
 stroke (0);
 rect (49,120,22,162);
 //fade red and blue within the rectangle
 for (int colorIndex = 0; colorIndex <= 160; colorIndex++) 
 {
 stroke(160 - colorIndex, 0, colorIndex);
 line(50, colorIndex + 120, 70, colorIndex + 120);
 }
//draw graph
 stroke(0);
 fill(255,255,255);
 //rect(90,180,100,100);
 rect(90,120,220,150);
 for (int index = 0; index<100; index++)
 { 
 if(index == 99)
 tempHistory[index] = tempC;
 else
 tempHistory[index] = tempHistory[index + 1];
 point(90 + index, 280 - tempHistory[index]); 
 }
//write reference values
 fill(0,0,0);
textAlign(RIGHT);
text("Temperature Value",180,80);
 text("210 F", 45, 130); 
 text("32 F", 45, 287);
//draw triangle pointer
 yDist = int(260 - (160 * (tempC * 0.01)));
 stroke(0);
 triangle(75, yDist + 20, 85, yDist + 15, 85, yDist + 25);
//write the temp in C and F
 fill(0,0,0);
textAlign(LEFT);
 text(tempC + " C", 115, 137);
 tempF = ((tempC*9)/5) + 32;
 text(str(int(tempF)) + " F", 115, 165);
 
 text("Light Value",520,80);
 if(ldrvalue<400){
 fill(0,255,0);
 rect(475,120,220,150);
 fill(0,0,0);
 text("Light Value : "+ldrvalue + " .", 480,137);
 text("It's dark , light is turned ON. ", 480, 157);
 }
 else
 {fill(255,255,255);
 rect(475,120,220,150);
 fill(0,0,0);
 text("Light Value : "+ldrvalue + " .", 480, 137);
 text("It's day , light is turned OFF. ", 480, 157);}
 
 
  text("Rain Status",320,340);
 if(rainstatus==1){
   fill(0,0,255);
 rect(275,350,220,150);
 fill(0,0,0);
 text("It's Raining! The roof is closed." , 280,370);
 }
 else {fill(255,255,255);
 rect(275,350,220,150);
 fill(0,0,0);
 text("No rain ", 280,370);}
 
 }
} 

void serialEvent(Serial myPort){

  String s=myPort.readStringUntil('\n');

  s=trim(s);

  if (s!=null){

    int values[]=int(split(s,','));

    if (values.length==3){

     // tempC=(int)map(values[0],0,1023,0, width);
tempC=values[0];
ldrvalue=values[1];
      rainstatus=values[2];

    }
      println(tempC,ldrvalue,rainstatus);

  myPort.write('0');

}

  }

ARDUINO FULL CODE :

const int capteur_D = 4;

const int capteur_A = A0;

int blueled=2;//for rain

int val_analogique;

int LDRsensorPin=A1;

int LDRsensorValue = 0;

int greenled = 3;//green light for ldr

int redled=6;

int temppin=5;

int baselinetemp=25;

int ldrvaluelimit=400;

int celsius=0;

bool closed=false;
int raining=0;
//code for stepper motor

#include <Stepper.h>

const int stepsPerRevolution = 2048;

Stepper myStepper(stepsPerRevolution, 8, 10,9, 11);

 

 

//code for temperature sensor

#include <OneWire.h>

#include <DallasTemperature.h>

#define ONE_WIRE_BUS temppin //pin in 4

OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

 

void setup()

{

  pinMode(capteur_D, INPUT);

  pinMode(capteur_A, INPUT);

  pinMode(blueled, OUTPUT);

  pinMode(greenled, OUTPUT);

  pinMode(redled, OUTPUT);

 

myStepper.setSpeed(10);

 

  Serial.begin(9600);

  //code for tempqrature

  sensors.begin();

//handshake

  Serial.println("0,0");

}

 

void loop()

{

  /********************************************************************/

  //rain sensor

if(digitalRead(capteur_D) == LOW)

  {

   // Serial.println("Digital value : wet");
   raining=1;
    delay(10);

    digitalWrite(blueled,HIGH);

    if(!closed){//Serial.println("close: turn counterclockwise"); 

    myStepper.step(stepsPerRevolution);

    delay(1000);

    closed=true;  }

  }

else

  {raining=0;
    //Serial.println("Digital value : dry");

    delay(10);

    digitalWrite(blueled,LOW);

   if(closed){

    //Serial.println("open: turn clockwise"); 

    myStepper.step(- stepsPerRevolution);

    delay(1000);

    closed=false;}

  }

val_analogique=analogRead(capteur_A);
 //Serial.println("Analog value for rain sensor : ");

//Serial.print(val_analogique);

// Serial.println("");

delay(500);

/********************************************************************/

//ldr sendor


 LDRsensorValue = analogRead(LDRsensorPin);

if(LDRsensorValue < ldrvaluelimit)

{

  /// Serial.println("LED light on");

   digitalWrite(greenled,HIGH);//Serial.print(LDRsensorValue);

   //delay(1000);

}

else {digitalWrite(greenled,LOW);//Serial.println("LED light off,LDR value:");Serial.print(LDRsensorValue);
}

 

/********************************************************************/

//temperature sensor

sensors.requestTemperatures(); // Send the command to get temperature readings

//Serial.println("Temperature is: ");

 celsius = sensors.getTempCByIndex(0);

if(celsius>baselinetemp)digitalWrite(redled,HIGH);

else digitalWrite(redled,LOW);

 

 

  delay(1000);

//processing code

Serial.print(celsius);
Serial.print(',');
Serial.print(LDRsensorValue);
Serial.print(',');
Serial.println(raining);
/*/
if(Serial.available()>0){
char state = Serial.read ( );    // Reading the data received and saving in the state variable

if(state == '1')             // If received data is '1', then turn on LED

{ 

digitalWrite (greenled, HIGH); 

}  

if (state == '0') {     // If received data is '0', then turn off led

digitalWrite (greenled, LOW);

} 

} 

delay(50);

 */   

  }




 REFERENCES:

https://create.arduino.cc/projecthub/MisterBotBreak/how-to-use-a-rain-sensor-bcecd9

https://create.arduino.cc/projecthub/SURYATEJA/automatic-street-light-controller-27159f

https://randomnerdtutorials.com/guide-for-ds18b20-temperature-sensor-with-arduino/

https://www.aranacorp.com/en/control-a-stepper-motor-with-arduino/

https://osoyoo.com/2017/07/10/arduino-lesson-stepper-motor/

https://www.makerguides.com/28byj-48-stepper-motor-arduino-tutorial/

https://github.com/aaronsherwood/introduction_interactive_media/blob/master/arduinoExamples/serialExamples/04_sendMultipleToProcessing/04_sendMultipleToProcessing.ino

https://circuitdigest.com/microcontroller-projects/arduino-based-roller-blinds-project-to-automate-and-control-window-curtains-using-nodemcu-and-stepper-motor

Final Project Proposal : Shamma & Theyab documentation


FINAL PROJECT CONCEPT:

The project is a weather-proof patio. It is a weather station that could be used for an outdoor area, as in a patio, a pet house, or even a plant house. The station will basically monitor the weather and take action when some conditions require attention.

DIFFERENT FEATURES:

  • The system will detect if it’s raining, and if it is then it will close the rollable roof.
  • The system measures the temperature and if the temperature is very high, it will turn on a fan.
  • The system detects if it’s nighttime and turns on the lights when it’s dark.
  • The system allows for monitoring of the sensors data on a screen
  • The system can be controlled manually, so the roof, the fan and even the light can be turned on manually using the screen controls.

SYSTEM I/O:

System will involve:
INPUT:
  • rain sensor
  • temperature sensor
  • Light Sensor
OUTPUT:
  • Servo or DC Motor
  •   Fan DC
  •   LED Strip with relay: A low-current circuit can regulate a high-current circuit, such as a huge LED light bar, using an electrical switch which is a relay.

EACH INPUT/OUTPUT DESCRIPTION ON ARDUINO & WHAT IT WILL SEND/RECEIVE FROM PROCESSING

Input Arduino:
  1. Rain sensor to detect if it’s raining
  2. Temperature sensor to detect the ambient (surrounding) temperature.
  3. Light sensor to detect the light in the area.
Outputs:
  1. Motor (servo or DC) to close and open the roof top
  2. Fan to cool down the temperature
  3. LED strip or bulb to add light during the night.

All the inputs will send the data to the processing to be visualized on the processing screen. That allows monitoring of the temperature, rain existence and light in the area.

All the outputs of the Arduino will receive control from the processing, as the system we are building will be controlled manually using the screen of processing or automatically using the Arduino code.



PROCESSING DESCRIPTION & WHAT IT WILL SEND/RECEIVE TO ARDUINO

Processing will be mainly used for two reasons:

  • Monitor the values given by the temperature sensor and other sensors.
  • Allow for manual control of the outputs. As we will add buttons on the screen to be able to turn on/off the outputs when we need regardless of the value.

The manual control is needed as sometimes even if it is not raining, we might want to close the roof top. Or even turn on / off the fan regardless of if it’s too hot. Also, turn on and off the light regardless of the time of the day.



CONCLUSION:

The system is useful as a weatherproof outdoor system for any area. It could be used for multiple stuff like:

-patio area, pet house, parking spot, garden, etc.

Or any other outdoor area that requires monitoring and controlling depending on the weather conditions.

Additional features would involve adding more sensors such as soil moisture for plants maybe or it could even add a person detector sensor for protection and safety reasons.

 

Serial Communication Exercises – Shamma & Theyab documentation

EXERCISE 1 :

Procedure – The sensor on the Arduino Is the LDR, light depending on resistor. So, once the value from the LDR Arduino is less than 200, the ellipse will move by adding 1 to the Xposition.

Challenges- The difficulty was in working using both processing and Arduino together to be able to read from Arduino and control processing ellipse. By using myport to create an object from serial reading in processing , the problem was solved.

PROCESSING CODE :

import processing.serial.*;
int xPos=0;
int yPos=100;
Serial myPort;  // Create object from Serial class
int val;      // Data received from the serial port

void setup(){
  size(200, 200); 
  String portname=Serial.list()[3];
  myPort = new Serial(this, portname, 9600);
  println(portname);
}
void draw()
{background(255);
  ellipse(xPos,yPos,30,30);
  
  if ( myPort.available() > 0) {  // If data is available,
 
   val = myPort.read();         // read it and store it in val
  }
  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);  xPos++;               // set fill to light gray
  }
  ellipse(xPos,yPos,30,30);
}

ARDUINO CODE :

void setup() {
  Serial.begin(9600);

}

void loop() {
      int sensor = analogRead(A0);
      delay(1);
 
      //Serial.println(sensor);
      //Serial.write(sensor);
        if (sensor <200)
 {  
    Serial.write(1);               // send 1 to Processing
  } else {           
    Serial.write(0);               // send 0 to Processing
  }
    delay(100);
    }

OUTPUT :

EXERCISE 2 :

Procedure – The program is to show two rectangles on processing screen. If the mouse is over the first square on the left, the brightness of the light is increased by 1 and if the mouse is over the second square, the brightness is less by 1. The analogWrite(ledPin,i) is the command used for controlling the brightness of the led.

Challenges- The hardship was to connect the serial to write to the Arduino. By creating 2 different rectangles, we had two options for increasing and decreasing the brightness of the light.

PROCESSING CODE :

import processing.serial.*;

Serial myPort;  // Create object from Serial class
int val;        // Data received from the serial port

void setup() 
{
  size(200, 200);
  String portName = Serial.list()[3];
  myPort = new Serial(this, portName, 9600);
  print(portName);
}

void draw() {
  background(255);
  if (mouseOverRect1() == true) {  // If mouse is over square,
    fill(204);                    // change color and
    myPort.write('H');              // send an H to indicate mouse is over square
  } 
  else {                        // If mouse is not over square,
    fill(0);                      // change color and
    //myPort.write('L');              // send an L otherwise
  
  if (mouseOverRect2() == true) {  // If mouse is over square,
    fill(204);                    // change color and
    myPort.write('L');              // send an H to indicate mouse is over square
  } 
  else {                        // If mouse is not over square,
    fill(0);                      // change color and
    //myPort.write('N');              // send an L otherwise
  }}
  rect(20, 20, 50, 100);         // Draw a square
  rect(90, 20, 50, 100);
}

boolean mouseOverRect1() { // Test if mouse is over square
  return ((mouseX >= 30) && (mouseX <= 70) && (mouseY >= 20) && (mouseY <= 120));
}
boolean mouseOverRect2() { // Test if mouse is over square
  return ((mouseX >= 90) && (mouseX <= 140) && (mouseY >= 20) && (mouseY <= 120));
}

ARDUINO CODE :

char val; // Data received from the serial port

int ledPin = 13; // Set the pin to digital I/O 4

int i = 10;

void setup() {

pinMode(ledPin, OUTPUT); // Set pin as OUTPUT

Serial.begin(9600); // Start serial communication at 9600 bps

}

 void loop() {

while (Serial.available()) { // If data is available to read,

val = Serial.read(); // read it and store it in val

if (val == 'H') { // If H was received
i++;
analogWrite(ledPin,i);

}
else if (val == 'L'){
i--;
analogWrite(ledPin,i); // Otherwise turn it OFF


}

delay(100); // Wait 100 milliseconds for next reading
}
}

OUTPUT :

EXERCISE 3 :

Procedure – The analog sensor used is the potentiometer on A1 analog port 1. If the value is less than 1024/2, the wind is blowing to the right. If the value is higher, then the wind is blowing to the left. Thus, the light turns on when the ball is bouncing.

Challenges- The challenge is to turn on the LED to have it on during the bouncing of the ball on processing screen. The second challenge was to use one analog sensor to make right and left movement, so our solution was to use a potentiometer that reads values from 0 to 1023. The mid value is the threshold, if under 1023/2, it moves to the right side, and if higher, moves to left side

PROCESSING CODE :

import processing.serial.*;

Serial myPort;  // Create object from Serial class
int val;  
PVector velocity;
PVector gravity;
PVector position;
PVector acceleration;
PVector wind;
float drag = 0.99;
float mass = 50;
float hDampening;

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()[3];
  myPort = new Serial(this, portName, 9600);
}

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;
      myPort.write('L');
    } 
    else myPort.write('H');
    
  if ( myPort.available() > 0) {  // If data is available,
    val = myPort.read();         // read it and store it in val
  }
    
     if(val==0){
    wind.x=-1;
  }
 
   else{
    wind.x=1;
  }
}
  
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 CODE :

char val; // Data received from the serial port

int ledPin = 13; // Set the pin to digital I/O 4

int i = 50;
int left = 0;
int right = 0;
int rightbool=0;
void setup() {

pinMode(ledPin, OUTPUT); // Set pin as OUTPUT

Serial.begin(9600); // Start serial communication at 9600 bps

}

 void loop() {

while (Serial.available()) { // If data is available to read,

val = Serial.read(); // read it and store it in val

}

if (val == 'H') { // If H was received

digitalWrite(ledPin,HIGH);

} else {

digitalWrite(ledPin,LOW); // Otherwise turn it OFF

}
int sensor = analogRead(A1);
//Serial.println(sensor);
if(sensor<511){rightbool=1; Serial.write(1);}
else {rightbool=0;Serial.write(0);}

delay(100); // Wait 100 milliseconds for next reading

}

CIRCUIT DIAGRAM:

FINAL VIDEO :

[ Shamma – Toomie’s ] MUSICAL INSTRUMENT GROUP : Shamma’s Documentation !

SCATTERED PIANO: MUSIC IN THE AIR

WELCOME !

INTRODUCTION:

Starting off with this week's project , me and Toomie have teamed up to create an interactive music instrument, which brought us joy, and we hope you would enjoy watching it. As far as planned, our scope for what we were initially planning to do changed due to the difficulties with some of its components.  On account of that,  we had the courage to dump that idea and start all over by yesterday - a day till the deadline . Stressful ? YES. Yet we still managed to incorporate the piano in a distinct way and for that we present to you Scattered Piano - Music in the Air.

INSPIRATION:

The initial idea for our project was to create an Arduino-based piano where the notes are controlled by specific keys on the board. Yet, it didn't work. In particular, trying to get the piano keys sensor to work when we connected them with the conductive tape and wires, some keys would just work while others wouldn't. The piano, though, inspired the notion of creating music in the air using the Ultrasonic, which controls  the frequency of the buzzer according to the distance between the object and the board. The character, which I named Pianair (pian-air: piano in the air), used to denote the sounds is a toy I brought from home to provide the project with some sort of lightheartedness and cheeriness to resemble the project’s purpose.

IDEA OVERVIEW:

The idea was to interface a distance sensor or ultrasonic sensor with Arduino, measure the distance of the sensor from an obstacle and accordingly play different frequencies using the buzzer. We also used a switch to control how to turn the sensor on and off. So, we went ahead and created our musical Instrument where we can move our hand in front of the sensor and according to the distance of our hand in front of the sensor, the buzzer will play different tones. So, we can change the tone based on the distance from the sensor. A switch and led were used to indicate if our musical instrument were active or not. It was an alternate on/off logic where you can press once to turn on and press again to turn off.

PROCEDURE:

As always, our first target was to interface the distance sensor & Arduino and we gathered the following hardware for our project:
Arduino Uno R3 board with USB cable

Push Button (switch)

Breadboard

Buzzer

Jumper wires to complete the connections.

 Ultrasonic or Distance Sensor (analog to be used later)
Firstly, we just attached the ultrasonic sensor to the board. We connect it as following so that we can access all 4 pins of the ultrasonic sensor.

Next, we connected 4 wires to the ultrasonic sensor as seen. One from Vcc to 5V, other from TRIG to PIN 3 in Arduino, then echo to pin 4 in Arduino, and at last ground to ground.

Moving forward, the buzzer has been placed taking into consideration its plus and minus sides.

Then, the buzzer has been connected. We use 2 jumper wires behind the buzzer, one from the buzzer's positive side to pin 11, and the other from buzzer's negative side to ground in Arduino board.

 

The push button was placed in the middle where there is a split as it connects to points on a circuit when pressed. We need the two diagonal ends of the switches which are shorted once the switch is pressed.

2 extra jumper wires were placed diagonally for the push button (switch),  one end of the button to pin 5 , and the other end from button to ground in Arduino.


CHALLENGES AND PROBLEMS:


We discussed and brainstormed how can we build a unique musical instrument using sensors. Initially we thought of making a piano using conductive tape but after hours of trial and error we were unfortunately unable to complete it so we decided to build something else. Instead, we decided to use ultrasonic which is a distance sensor and a switch to make our instrument. It was very engaging to learn on how they could both work together.  

FINAL WORK:

CONCLUSION:

Overall, despite the fact that we began the project with high hopes and a determination to outperform our prior efforts, we were confronted with the harsh reality of our initial concept failing when being implemented. After a long night of trial and error, we were compelled to change our whole project in a matter of hours. But it's fine, as without trial and error, nothing comes to being. Fortunately, we came up with another concept during our brainstorming session which later came handy as we could put into action as our final idea. It was basically that we used a distance sensor to monitor the distance from an obstacle and accordingly play different tones using different frequencies in the tone() function. To show whether our musical instrument was active or not, we used a switch and the led on Arduino. What we both learned is that one shall always take their chances and trust the process with its ups and downs. Have alternatives as you never know what will go wrong. However,  don't forget that ...
AFTER EVERY STORM COMES A RAINBOW  –

FINAL CODE:

//Defined the pins 
int SW=5;// connect switch to 5
int LED=13; // connect led to 13
//Variables that are capturing the values of different parameters 
long duration, cm;
// this is to implement the switch logic 
int count;

//we initialize pins as our input and output 
void setup() 
{
  pinMode(LED, OUTPUT);// configure led as output
  pinMode(3, OUTPUT);// configure pin 3 of ultrasonic sensor as output, this is PING
  pinMode (4, INPUT);//attach pin 4 to Echo and congiure as input 
  pinMode (SW,INPUT_PULLUP);//configure switch as input, pull up resistor on to read  switch properly

  digitalWrite(LED,LOW);// led off by default
  

}

//Infinite loop which will run forever, contains main logic 

void loop()
{
  //read input from switch and store it as variable 
  bool switch_status = digitalRead(SW);

//press switch, becomes low , in other words it says switch has been pressed 

  if(switch_status == LOW)
  {
    //if we press first time, value is 1 
    count++; 
    // if switch is pressed twice , make the value go back to default which is zero  
    if(count == 2)
    {
      
      count = 0;
    }
  }

// true case if count is 1 , it means switch was pressed for first time 
  if(count == 1) // Sensor ON
  {
    digitalWrite(LED,HIGH);

    
  
 
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  // here just sending a pulse to trigger pin in the ultrasonic 
  // the transmittor 
  
  digitalWrite(3, LOW);  delayMicroseconds(2);  
  digitalWrite(3, HIGH);  delayMicroseconds(5);  
  digitalWrite(3, LOW);

  // the recievor 
  // we calculate time taken by pulse to come back
  duration = pulseIn(4, HIGH);


  // convert the time into a distance
  //inches = microsecondsToInches(duration);
  // getting the direct value of the distance which is calculated by microsecond to centimeters  
  cm = microsecondsToCentimeters(duration);
 
 
//initialize a variable Tonetoplay

  int toneToPlay = 0;

//according to different distance, we give different values 

// Standard values , each if statemnet represents a different note on a piano 

  // different distance range from ultrasonic sensor 
  if(cm <= 160 && cm > 140)
  {
    // here it stores the frequency that will be played in hertz 
     toneToPlay = 523; 
  }
  if(cm <= 140 && cm > 120)
  {
     toneToPlay = 493; 
  }
  if(cm <= 120 && cm > 100)
  {
     toneToPlay = 440; 
  }
  if(cm > 100)
  {
    toneToPlay = 0;
  }
  if(cm <= 100 && cm > 80)
  {
     toneToPlay = 392; 
  }
  if(cm <= 80 && cm > 60)
  {
     toneToPlay = 349; 
  }
  if(cm <= 60 && cm > 40)
  {
     toneToPlay = 329; 
  }
  if(cm <= 40 && cm > 20)
  {
     toneToPlay = 294; 
  }
  if(cm <= 20)
  {
     toneToPlay = 261; 
  }
  
  if(toneToPlay == 0)
  {
    //noTone means dont generate any frequency by the sound , basically switch off the buzer 
    noTone(11);
  }
  else
  {
    //Here generate frequency of value equal to Tonetoplay
    //syntax is tone(pin, frequency, duration)
    tone(11, toneToPlay, 200);
  }
  

  }

  else if(count == 0)
  {
    digitalWrite(LED,LOW);
  }
  
  delay(250);
}


long microsecondsToCentimeters(long microseconds)
{
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance travelled.
  // distance is being calcualted from the time taken by pulse to come back 
  return microseconds / 29 / 2;
}

 

Cats Party : Lets go ! – Digital & Analog Sensors , Shamma’s Work

CATS PARTY

INTRODUCTION:

In week 10, I have continued working with Arduino hardware and got an in-depth understanding of both the analog and digital inputs. For my project, I had to use at least one analog and one digital sensor to control at 10 LEDs in some creative manner. So, I decided to use the proximity sensor as my digital sensor and the potentiometer as my analog sensor to control 5 LED’s each in a respective manner that creates light mashups.

INSPIRATION:

The inspiration behind the usage of different LED's is their colorful and attractive appearance which in my case would give a disco themed party. They light up the room in a distinctive manner providing the crowd with a lighthearted experience. Generally speaking, colors often provide a joyful emotion, and an ideal manner to execute this is was by using LED's as an inspiration. In this project, the aim is to mimic those lights on a smaller scale using arduino. The usage of the cat theme came as an inspiration from my sister's love of cats as well as the well-loved campus cats. It provides a fun twist to the project result and appearance, as well as personalizes it in a creative and unique manner.

IdEA OVERVIEW IMPLEMEnTAtION:

Once I grasped the notion of working with both the analog and digital sensor, I decided to make a unique led pattern with it. This implies that I can compare them with a progressive volume or fuel level indicator using the LED’s. To start off, I used 5 LEDs each for analog and digital sensor (total 10 LED’s). With the digital sensor, by default all the LEDs are off and as I place my hand on the proximity sensor, the LEDs switch on one by one till all 5 are lit up. So basically, I can swipe my hand on the sensor and turn on 1 LED, 2 LED or 3 LED as per the number of swipes on the sensor or time duration for which the hands are on the sensor. Later, when all the LEDs are on, any further swipe over the proximity sensor will result in resetting all the LEDs and they will then again start from the all off state. On the other hand, with the analog sensor, again all LEDs are off and as I turn my potentiometer the LEDs start switching on. From all off at one end, the LEDs light up one by one till all are on to the other end. In other words, this can be compared to a volume control knob on older TV’s or music players on vehicles where one end is mute and other end is max volume.

CHALLENGES & PROBLEMS:

In this week, I had decided to use the proximity sensor as a digital sensor. For that, I used one which I have ordered via amazon. Then, although working with the analog sensor was quite straight forward, I had to divide the output of the analog sensor into different ranges as per my concept. This have taken some time for me to comprehend it and the conversion of the ADC value from 0V - 5V to 0 – 1023 has required some effort and additional readings. One thing that aided my process was watching a few YouTube videos for the ADC value conversion concept.

PROCEDURE:

First, I used the Arduino board to power the + and – rails of the breadboard so that the entire circuit can use + and – from these rails whenever required in future connections. In the following image, a jumper wire goes into the +ve rail and the other goes into the -ve rail.

Having already connected the LED in the last assignment, I have quickly completed the following circuit and the anode of LED (longer leg) was connected to Arduino D7 and the resistor was connected to the ground rail as shown below.


I tested the simple LED circuit by uploading the following code and it have worked.
// C++ code

//it runs only once 

void setup()
{
  //pinmode is used to configure pin number 7 as an output 
  pinMode(7, OUTPUT);
}

// runs forever 
void loop()
{
  //writing a logic high which equals 5 volt or 1 in binary 
  //jumper wire connected to anode, LED switch on
  digitalWrite(7, HIGH);
  delay(1000); // Wait for 1000 millisecond(s)
  
  //writing a logic low which equals  0 in binary 
  //jumper wire connected to anode, LED switch off
  digitalWrite(7, LOW);
  delay(1000); // Wait for 1000 millisecond(s)
}
The video shown below was the output !

 

Next, I wanted to test the digital sensor with a single LED, so I have connected the sensor on breadboard and powered it with the onboard power rails. I connected the output of sensor to digital pin 7 which was configured as an input. Moreover , I have utilized the following code and the output was as shown in video below.
// C++ code


void setup()
{
  //pinmode is used to configure pin number 7 as an output 
  pinMode(7, OUTPUT);
  //configuring 6 as input to read data from external switch/ sensor 
  pinMode(6,INPUT);
}

void loop()
{
  //LED switch off
  
  if(digitalRead(6)==LOW)
  {
    // LED switch on
    digitalWrite(7, HIGH);
  }
  else
  {
    // LED switch off
    digitalWrite(7, LOW);
  }

Then, I moved on to the connection of the digital proximity sensor with 5 LED’s. I removed the earlier LED and disconnected the sensor output pin. Now, only the power rails were connected to the respective pins as shown.

Next, I started to connect a single LED. All the other LED’s were kept ready to be placed on the breadboard.

Then, all the 5 LEDs were connected with the resistors. I kept the colours different to get a nice colourful effect.

Moving forward, I connected all the LEDs and the digital sensor with Arduino and wrote a code to test all LEDs with my sensor. This way I was able to test all LEDs individually. The output video is shown. 
// Shamma's code 

// LED connected to 3,4,5,6,7 in arduino board 
int gled = 3, b1led = 4, b2led = 5, yled = 6, rled = 7;

//sensor connected to pin 2 , the proximity sensor 
int sensor = 2;

// initialize count variable to zero
int count = 0;

void setup()
{
  //All leds are being configured as an output and sensor is configured as an input because we read from it
  pinMode(gled, OUTPUT);pinMode(b1led, OUTPUT);
  pinMode(b2led, OUTPUT);pinMode(yled, OUTPUT);
  pinMode(rled, OUTPUT);
  pinMode(sensor,INPUT);
  
  //by default, I am switching all the leds off, 
  //even if I remove those, code will work as my count is zero 
  digitalWrite(gled,LOW);digitalWrite(b1led,LOW);
  digitalWrite(b2led,LOW);digitalWrite(yled,LOW);
  digitalWrite(rled,LOW);
}


void loop()
//reading if proximity sensor is low, then I will increment count variable by one 

{
  //Once I place the hand, the count variable will switch from zero to 1,2,3,4,5,6
  //One is off, while next is on
  if(digitalRead(sensor)==LOW)
  {
    count = count + 1;
    
    //I use 5 LEDS, so I put 6 to restart the count 
    if(count == 6)
    {
      count = 0;
    }
  }

// IF CONDITION for each LED on the mother board 
  if(count == 0)
  {
    digitalWrite(gled,LOW);digitalWrite(b1led,LOW);
    digitalWrite(b2led,LOW);digitalWrite(yled,LOW);
    digitalWrite(rled,LOW);
  }
  else if(count == 1)
  {
    digitalWrite(gled,HIGH);digitalWrite(b1led,LOW);
    digitalWrite(b2led,LOW);digitalWrite(yled,LOW);
    digitalWrite(rled,LOW);
  }
  else if(count == 2)
  {
    digitalWrite(gled,LOW);digitalWrite(b1led,HIGH);
    digitalWrite(b2led,LOW);digitalWrite(yled,LOW);
    digitalWrite(rled,LOW);
  }
  else if(count == 3)
  {
    digitalWrite(gled,LOW);digitalWrite(b1led,LOW);
    digitalWrite(b2led,HIGH);digitalWrite(yled,LOW);
    digitalWrite(rled,LOW);
  }
  else if(count == 4)
  {
    digitalWrite(gled,LOW);digitalWrite(b1led,LOW);
    digitalWrite(b2led,LOW);digitalWrite(yled,HIGH);
    digitalWrite(rled,LOW);
  }
  else if(count == 5)
  {
    digitalWrite(gled,LOW);digitalWrite(b1led,LOW);
    digitalWrite(b2led,LOW);digitalWrite(yled,LOW);
    digitalWrite(rled,HIGH);
  }
  // once I place my hand, this delay will stop down the program 
  delay(500);
}

After successfully completing the digital sensor, I worked on analog sensor and chose potentiometer. So, another 5 LEDs were added which would be controlled via analog sensor.

Just to be double sure that all LEDs were connected properly, I wrote a small test LEDs code. This ensured that the wiring was properly done with no errors. The output was as following:
//
int gled = 3, b1led = 4, b2led = 5, yled = 6, rled = 7;
int sensor = 2;
int count = 0;

void setup()
{
  pinMode(gled, OUTPUT);pinMode(b1led, OUTPUT);
  pinMode(b2led, OUTPUT);pinMode(yled, OUTPUT);
  pinMode(rled, OUTPUT);
  pinMode(sensor,INPUT);

  digitalWrite(gled,LOW);digitalWrite(b1led,LOW);
  digitalWrite(b2led,LOW);digitalWrite(yled,LOW);
  digitalWrite(rled,LOW);
}

void loop()
{
  if(digitalRead(sensor)==LOW)
  {
    count = count + 1;
    if(count == 6)
    {
      count = 0;
    }
  }

// only difference is that when one lights up, the other follows without switching off 
  if(count == 0)
  {
    digitalWrite(gled,LOW);digitalWrite(b1led,LOW);
    digitalWrite(b2led,LOW);digitalWrite(yled,LOW);
    digitalWrite(rled,LOW);
  }
  else if(count == 1)
  {
    digitalWrite(gled,HIGH);digitalWrite(b1led,LOW);
    digitalWrite(b2led,LOW);digitalWrite(yled,LOW);
    digitalWrite(rled,LOW);
  }
  else if(count == 2)
  {
    digitalWrite(gled,HIGH);digitalWrite(b1led,HIGH);
    digitalWrite(b2led,LOW);digitalWrite(yled,LOW);
    digitalWrite(rled,LOW);
  }
  else if(count == 3)
  {
    digitalWrite(gled,HIGH);digitalWrite(b1led,HIGH);
    digitalWrite(b2led,HIGH);digitalWrite(yled,LOW);
    digitalWrite(rled,LOW);
  }
  else if(count == 4)
  {
    digitalWrite(gled,HIGH);digitalWrite(b1led,HIGH);
    digitalWrite(b2led,HIGH);digitalWrite(yled,HIGH);
    digitalWrite(rled,LOW);
  }
  else if(count == 5)
  {
    digitalWrite(gled,HIGH);digitalWrite(b1led,HIGH);
    digitalWrite(b2led,HIGH);digitalWrite(yled,HIGH);
    digitalWrite(rled,HIGH);
  }
  delay(500);
}

Finally, I added my analog sensor, the potentiometer in the circuit. It had 3 terminals out of which the corner ones were power rails and the middle one was the analog output which was connected to the analog input 0.

I wrote another small code to test only the analog sensor which turned the 5 LEDs dedicated for analog sensor one by one like shown.
// C++ code
//
int gled = 3, b1led = 4, b2led = 5, yled = 6, rled = 7;
//added the other 5 leds which will be used for my analog 
int g2led = 8, b3led = 9, b4led = 10, y2led = 11, r2led = 12;
int digital_sensor = 2;
//declared the analog sensor 
int analog_sensor = A0;
int count = 0;

void setup()
// all ten leds are configured as outputs 
{
  pinMode(gled, OUTPUT);pinMode(b1led, OUTPUT);
  pinMode(b2led, OUTPUT);pinMode(yled, OUTPUT);
  pinMode(rled, OUTPUT);
  
  pinMode(digital_sensor,INPUT);

  pinMode(g2led, OUTPUT);pinMode(b3led, OUTPUT);  
  pinMode(b4led, OUTPUT);pinMode(y2led, OUTPUT);
  pinMode(r2led, OUTPUT);
  
 // All 10 leds will be turned off

  digitalWrite(gled,LOW);digitalWrite(b1led,LOW);
  digitalWrite(b2led,LOW);digitalWrite(yled,LOW);
  digitalWrite(rled,LOW);
  
  digitalWrite(g2led,LOW);digitalWrite(b3led,LOW);
  digitalWrite(b4led,LOW);digitalWrite(y2led,LOW);
  digitalWrite(r2led,LOW);
}

void loop()
{
  // Analog Sensor Code
  // Reading the value from the analog sensor and storing it in the variable count 
  int count = analogRead(analog_sensor);

// I divided 1024 by 5 as I have 5 leds and took the range from one switch to another 
  if(count<10)
  {
    digitalWrite(g2led,LOW);digitalWrite(b3led,LOW);    digitalWrite(b4led,LOW);digitalWrite(y2led,LOW);    digitalWrite(r2led,LOW); 
  }
  // 
  else if(count>=10 && count<210)
  {
    digitalWrite(g2led,HIGH);digitalWrite(b3led,LOW);  digitalWrite(b4led,LOW);digitalWrite(y2led,LOW);    digitalWrite(r2led,LOW);
  }
  else if(count>=210 && count<410)
  {
    digitalWrite(g2led,HIGH);digitalWrite(b3led,HIGH);  digitalWrite(b4led,LOW);digitalWrite(y2led,LOW);    digitalWrite(r2led,LOW);
  }
  else if(count>=410 && count<610)
  {
    digitalWrite(g2led,HIGH);digitalWrite(b3led,HIGH);  digitalWrite(b4led,HIGH);digitalWrite(y2led,LOW);    digitalWrite(r2led,LOW);  
  }
  else if(count>=610 && count<810)
  {
    digitalWrite(g2led,HIGH);digitalWrite(b3led,HIGH);  digitalWrite(b4led,HIGH);digitalWrite(y2led,HIGH);    digitalWrite(r2led,LOW);
  }
  else if(count>810)
  {
    digitalWrite(g2led,HIGH);digitalWrite(b3led,HIGH);  digitalWrite(b4led,HIGH);digitalWrite(y2led,HIGH);    digitalWrite(r2led,HIGH);
  }

//  // Digital Sensor Code
//  
//  if(digitalRead(digital_sensor)==LOW)
//  {
//    count = count + 1;
//    if(count == 6)
//    {
//      count = 0;
//    }
//  }
//
//  if(count == 0)
//  {
//    digitalWrite(gled,LOW);digitalWrite(b1led,LOW);
//    digitalWrite(b2led,LOW);digitalWrite(yled,LOW);
//    digitalWrite(rled,LOW);
//  }
//  else if(count == 1)
//  {
//    digitalWrite(gled,HIGH);digitalWrite(b1led,LOW);
//    digitalWrite(b2led,LOW);digitalWrite(yled,LOW);
//    digitalWrite(rled,LOW);
//  }
//  else if(count == 2)
//  {
//    digitalWrite(gled,HIGH);digitalWrite(b1led,HIGH);
//    digitalWrite(b2led,LOW);digitalWrite(yled,LOW);
//    digitalWrite(rled,LOW);
//  }
//  else if(count == 3)
//  {
//    digitalWrite(gled,HIGH);digitalWrite(b1led,HIGH);
//    digitalWrite(b2led,HIGH);digitalWrite(yled,LOW);
//    digitalWrite(rled,LOW);
//  }
//  else if(count == 4)
//  {
//    digitalWrite(gled,HIGH);digitalWrite(b1led,HIGH);
//    digitalWrite(b2led,HIGH);digitalWrite(yled,HIGH);
//    digitalWrite(rled,LOW);
//  }
//  else if(count == 5)
//  {
//    digitalWrite(gled,HIGH);digitalWrite(b1led,HIGH);
//    digitalWrite(b2led,HIGH);digitalWrite(yled,HIGH);
//    digitalWrite(rled,HIGH);
//  }
  delay(500);
}

At last, I integrated the digital sensor and analog sensor code in one final code and I could control all 10 LEDs using different types of sensors.
// C++ code
// This is a combination of code 2 and 3 , both the proximity sensor and the analog which is the potentiometer 
//Digital and analog sensor 

int gled = 3, b1led = 4, b2led = 5, yled = 6, rled = 7;
int g2led = 8, b3led = 9, b4led = 10, y2led = 11, r2led = 12;
int digital_sensor = 2;
int analog_sensor = A0;
int count = 0,count2 = 0;

void setup()
{
  pinMode(gled, OUTPUT);pinMode(b1led, OUTPUT);  pinMode(b2led, OUTPUT);pinMode(yled, OUTPUT);  pinMode(rled, OUTPUT);
  pinMode(digital_sensor,INPUT_PULLUP);
  pinMode(g2led, OUTPUT);pinMode(b3led, OUTPUT);    pinMode(b4led, OUTPUT);pinMode(y2led, OUTPUT);  pinMode(r2led, OUTPUT);
  digitalWrite(gled,LOW);digitalWrite(b1led,LOW);  digitalWrite(b2led,LOW);digitalWrite(yled,LOW);  digitalWrite(rled,LOW);
  digitalWrite(g2led,LOW);digitalWrite(b3led,LOW);  digitalWrite(b4led,LOW);digitalWrite(y2led,LOW);  digitalWrite(r2led,LOW);
}

void loop()
{
  // Analog Sensor Code
  int count = analogRead(analog_sensor);

  if(count<10)
  {
    digitalWrite(g2led,LOW);digitalWrite(b3led,LOW);    digitalWrite(b4led,LOW);digitalWrite(y2led,LOW);    digitalWrite(r2led,LOW); 
  }
  else if(count>=10 && count<210)
  {
    digitalWrite(g2led,HIGH);digitalWrite(b3led,LOW);  digitalWrite(b4led,LOW);digitalWrite(y2led,LOW);    digitalWrite(r2led,LOW);
  }
  else if(count>=210 && count<410)
  {
    digitalWrite(g2led,HIGH);digitalWrite(b3led,HIGH);  digitalWrite(b4led,LOW);digitalWrite(y2led,LOW);    digitalWrite(r2led,LOW);
  }
  else if(count>=410 && count<610)
  {
    digitalWrite(g2led,HIGH);digitalWrite(b3led,HIGH);  digitalWrite(b4led,HIGH);digitalWrite(y2led,LOW);    digitalWrite(r2led,LOW);  
  }
  else if(count>=610 && count<810)
  {
    digitalWrite(g2led,HIGH);digitalWrite(b3led,HIGH);  digitalWrite(b4led,HIGH);digitalWrite(y2led,HIGH);    digitalWrite(r2led,LOW);
  }
  else if(count>810)
  {
    digitalWrite(g2led,HIGH);digitalWrite(b3led,HIGH);  digitalWrite(b4led,HIGH);digitalWrite(y2led,HIGH);    digitalWrite(r2led,HIGH);
  }

  // Digital Sensor Code
  
  if(digitalRead(digital_sensor)==LOW)
  {
    count2 = count2 + 1;
    if(count2 == 6)
    {
      count2 = 0;
    }
  }

  if(count2 == 0)
  {
    digitalWrite(gled,LOW);digitalWrite(b1led,LOW);
    digitalWrite(b2led,LOW);digitalWrite(yled,LOW);
    digitalWrite(rled,LOW);
  }
  else if(count2 == 1)
  {
    digitalWrite(gled,HIGH);digitalWrite(b1led,LOW);
    digitalWrite(b2led,LOW);digitalWrite(yled,LOW);
    digitalWrite(rled,LOW);
  }
  else if(count2 == 2)
  {
    digitalWrite(gled,HIGH);digitalWrite(b1led,HIGH);
    digitalWrite(b2led,LOW);digitalWrite(yled,LOW);
    digitalWrite(rled,LOW);
  }
  else if(count2 == 3)
  {
    digitalWrite(gled,HIGH);digitalWrite(b1led,HIGH);
    digitalWrite(b2led,HIGH);digitalWrite(yled,LOW);
    digitalWrite(rled,LOW);
  }
  else if(count2 == 4)
  {
    digitalWrite(gled,HIGH);digitalWrite(b1led,HIGH);
    digitalWrite(b2led,HIGH);digitalWrite(yled,HIGH);
    digitalWrite(rled,LOW);
  }
  else if(count2 == 5)
  {
    digitalWrite(gled,HIGH);digitalWrite(b1led,HIGH);
    digitalWrite(b2led,HIGH);digitalWrite(yled,HIGH);
    digitalWrite(rled,HIGH);
  }
  delay(500);
}
Just to add a little spice, I decided to cut down a cartoon box I found that is recycled and turn it into a space for cats to party. I did that by printing a couple of images, using a card board to give definition in terms of the party stage by adding a couple of card board together. Then, I used cotton bods as they will act as the cat paws which will trigger the proximity sensor when being moved on top of it. Later, I did not have any markers to draw the entrance of the party, so I used some makeup powders and eyeliner that I had, so excuse me for the mess. I also added a small radio I had on top of the box so I can run inside it a little fun cat song. At last, I placed the Arduino inside the cat space party to make the experience more real.

CONCLUSION:

The experience with this assignment has opened my eyes to the use of different sensors and how to interface them with Arduino. By being able to control LEDs using analog and digital sensors, although it’s a simple thing,  it made me more enthusiastic about the more interesting applications that is to come.

Week 8 : Hands Free Switch

SIT AT YOUR OWN RISK

INTRODUCTION:

In week 8, we were given task which involved using Arduino and hardware. We had to create a unique & creative type of switch which could be operated without the use of our hands. By using this switch, we could turn the led on and off as required. So, I mainly learnt about building a simple led circuit using both the breadboard and resistor. I have built an aluminium foil-based switch platform separated by a non-conductive foam which is operated by force. So, the switch on happens by applying force on the platform.

IDEA:

I decide to make my own switch using conductive foils on cutted foam boards which was then separated by a non-conductive material. One side of the stranded wires were stuck to the foam board with the aluminium,  using a clear tape and the other side of it which was stripped was connected with the jumper wires stripped using an electrical tape.  At last, due to force, the terminals would come in contact with each other and circuit would be complete, thus LED would turn on and as the person stands up, the led would turn off.

INSPIRATION:

COVID-19 has become our new normal. Wearing masks, social distancing, constant use of cleaning wipes and sanitizers until our hands dry out is now integrated into our daily routines. This project was inspired by the COVID-19 regulations, specifically the social distancing requirement. In public seating, there is a required empty seat to be set empty between an individual and the person sitting next to them. What is currently being used are stickers and/or tape indicating on which seats it is permitted to sit. This project aims to improve this application. Every time someone sits on an undesignated seat, the LED lights up to tell the person to change their seat. This project’s purpose is to further develop and add technology to accommodate our new normal.

CHALLENGES & PROBLEMS:

The concept I had finalized for completing this task involved was the use of two aluminium foils which had to be wrapped around a carboard sheet and separated by a non-conductive material. Also, I had to find a way to stick the wires to the aluminium foil as soldering would not make them  hold on the foil. Thus, since I had not worked on wiring and hardware much before, using the hardware was new for me. Another things I had to be very careful about is not to mix the +ve and -ve supplies as it could lead to the system getting damaged. The jumper wires were not fitting the Arduino board completely which made me put some force which bended some of them. So , now I take on the lesson that it only needs to be in-tact, no need to be fully on. To conclude, the entire process of sticking wire to the aluminium foil took a lot of time as the tape was not sticking to the foil. Thus, this was a very important process as without this, the switch won’t work for me, but eventually it all worked out. 

PROCEDURE:

The first target was to blink an LED using Arduino and to do that I have gathered the following hardware:

Arduino board - LED - Resistor of value 330 Ohms -Jumper wires - USB Cable

The circuit diagram which we referred was as following:

So, I used the hardware to power the + and – rails of the breadboard so that the entire circuit can use + and – from these rails if and when required in future connections. In the following image, the white wire goes into the +ve rail and the black wire goes into the -ve rail.

Next, we used a led, identified its Anode and Cathode (cathode has the shorter leg), and connected a resistor with it as shown. Resistor is used to limit the current through the led. We chose a value of 330 ohms as we read that led requires 20 – 25 mA of current for proper operation so resistor value of 100 ohms to 330 ohms work well.

Then I connected the other end of resistor to the ground to give it a -ve or GND signal

In this step, I connected the digital pin 7 from Arduino to Anode of led using a yellow jumper wire as shown.

Afterwards, I wrote a simple program to blink the led connected to digital 7 and uploaded it to our Arduino board by using the following settings on Arduino software. I selected usbmodem 143141 (Arduino Uno)
// C++ code
//
void setup()
{
  pinMode(7, OUTPUT);
}

void loop()
{
  digitalWrite(7, HIGH);
  delay(1000); // Wait for 1000 millisecond(s)
  digitalWrite(7, LOW);
  delay(1000); // Wait for 1000 millisecond(s)
}
Once the code was uploaded, we could see the led blinking on and off with a gap of 1000 ms

Once my LED circuit was complete, I started gathering material for making my own switching platform.

Next, I have cut the carboard in two different parts and these would serve as two different terminals of the switch.

Then I used foil and put it on the foam cardboard using clear tapes as shown. 

Now, I needed multi-strand wires to be connected to the foil. So, I used a single wire and cut it into two parts using a cutter, one for each foil board.

Using a wire stripper, both the ends of the two pieces of wires were stripped like shown

Afterwards, I used electrical tape to stick one end of each wire to the foil in such a way the wire strands were in contact with the conductive surface of the foil.

Later, I used a male-to-male jumper wire and cut it from middle using a wire cutter.

The other end of the wires taped to the foil was taped to male end of jumper wire as shown below.

 

Now, I am ready to test my switch with my led circuit. I connected one foil arrangement to ground and the other was connected to a digital IO of Arduino as per my code.

The, I used the following code in my Arduino circuit and tested the foil switch which I made.
// C++ code

int led = 7;
int sensor = 6;

void setup()
{
  pinMode(led, OUTPUT);
  pinMode(sensor,INPUT_PULLUP);
}

void loop()
{
  if(digitalRead(sensor)==LOW)
  {
    digitalWrite(led, HIGH);
  }
  else
  {
    digitalWrite(led, LOW);
  }
}
So, I observed that the LED switched on once the two foils were made in contact with each other and switched off once the foils were separated which is how a switch works.

At the last step, I used the black non-conductive foam as a separator between the two foil boards and put everything together like a sandwich in which the non-conductive material ensured the foil would turn on only if someone puts force on the two boards. In this case the two foils would come in contact and the LED would turn on. The final arrangement looked like this.

FINAL WORK:

CONCLUSION:

There were a lot of ups and downs in this assignment, but I pulled it off at the end and had a great time exploring with the construction of my mini project. Furthermore, I will hopefully be taking this experience to achieve much more complicated tasks in the future.

HOPE YOU ENJOYED , HERE IS THE FULL CODE with the comments 🙂

// Shamma's Sit at your own risk Program
//C++ coding in Ardiuno 

// Setting Global Variables 
int led=7;
int sensor =6;


// This code runs only once 
void setup() 
{
  // only declaring input and ouput 
  pinMode(led, OUTPUT); //  define the LED connected on pin 7 as an output 

  // I did not use the input because it wont work properyly with what I builded
  // So,  input_pullup was used because it requires no external components and can be turned on & off in software during program execution 
  //Another thing is that is it used to read switches properly and prevent missed readings
  pinMode(sensor,INPUT_PULLUP);// the proximity sensor acts as an input devide which will take an anction , in our case presnece of an obstacle 
}


// This runs forever as long as system is turned on 
void loop() 
{
  if(digitalRead(sensor)==LOW)// reading if an obstacle (someone infront of sensor) is present 
  {
    digitalWrite(led, HIGH);// turning on LED by giving the anode of LED +5 volt signal
    
  }
  else
  {
    digitalWrite(led, LOW);// if no one is present, turn off LED by giving low signal 
  }
}

 

UNI RUSH- Shamma’s Midterm Project

UNI RUSH

INTRODUCTION & GAME RULES:

Uni Rush is an innovative idea for gaming in processing which have sketched the idea of a student escaping the reality of university course grades. The basic logic behind it is that the student character is moving in all four directions and the grade letters are coming from the right side of the screen. When a grade passes behind the character, the score increases. However, if the character moves out of the screen or touches any grade, whether bad or good, then it is game over. For the character movements, conventional gaming keyboard keys were used: w for up, a for left, s for down, and d for right.

INSPIRATION BEHIND UNI RUSH:

The inspiration behind the game I wanted to create comes from how overprotective I tend to be with my GPA. Since I was a kid, I always would work to achieve the highest grades and even the slightest deduction of grades would make me cry. However, after I came to university, that reality changed, and it’s been like a roller-coaster with all its ups and downs. The game resembles a university student who is running all over to escape the sad reality of university grades. Based on that, the more grades the character is able to escape , the higher the score is.  I have always been keen to understand how gpa calculation works, so I searched it up and decided to base my game on that. Yet, this did not work and the fun of it made me come up with a new game logic, closer to reality.

CHALLENGES & PROBLEMS:

The very first and foremost challenge I have faced was rendering the grades continuously on the screen, in addition to its movement within the specified speed. This has put me in chaos, as I felt that my code is all over the place. A second  difficulty was during the movement of the character. Third, the management of frames and the glitches found during frame rendering. Last, but not least, playing the sound based on the movement of the character and rendering the grade letters as a series of image was an obstacle.

OBJECTS USED :

1- Grade letters

The grade letter objects are moving images of all grade letters 

2- Student Character

This is an NYU Mascot cartoon character given a bigger size as compared to the grade letters and is able to move left- right & up-down based on the key pressing

3- Game Background

This object is a university campus image 

4- GPA Score Prompt

This object is a simple score text prompt which gets added as the character escapes the grade letters.

PROCEDURE:

I have started my game by implementing the player character class. This class was responsible for the actions taken by the character. Later, I have implemented attributes and methods in that class that helps with the movement of the character in all four directions. The rendering of the character is also implemented in that class. I performed the default constructor for the  character class which takes x and y positions of the character.

The die function implemented to check if the player character moves out of the screen.
//function to check if the player character is out screen which means the character died
  //stopping the game background sound and playing main menu sound
  void die() 
  {
  
    this.xPos = -500;
    this.yPos = -500;
    this.CharacterDropped = true;
    BackSoundEffect.stop();
    SkipGradeLetterSound.play();
    MainMenuSoundEffect.play();
  
  }
The player character is moving based on the key pressed events which work on the specified keys for the movement of the player character in upward, downward, left, or right direction.
void keyPressed() 
{

  //If the key is 'w' then moving the character upward
  if(key == 'w') Character.move(0, -1);
  //if the key is 'a' then moving the character left
  if(key == 'a') Character.move(-1, 0);
  //if the key is s then moving the character down
  if(key == 's') Character.move(0, 1);
  //if the key is 'd' then moving the character right
  if(key == 'd') Character.move(1, 0);

  //if the key is 'r' then setting the character to its default state and postion
  if(key == 'r' || Character.CharacterDropped)
  {
    //stop playing background sounds
    BackSoundEffect.stop();
    MainMenuSoundEffect.stop();
    BackSoundEffect.loop();
    //restarting game to its default configuration
    restart();
    gameFrame = 0;
  }
}
For rendering the player character on screen I implemented show() method inside the character class which is loading the player character image on the current frame x and y position.
//for rendering the player character in rectangular box structure on screen
  void show() 
  {
    rectMode(CENTER);
    fill(255);
    noStroke();
    //showing player character image on screen
    image(PlayerCharacter[currentFrame], this.xPos + xRail * screenHeight/4, this.yPos + this.yRail * screenHeight/4);
 
  }
Then I did the implementation letter class which I used later to render grade letters on the screen. The letter class contains attributes for the position of letters and the movement speed of letter images on the screen. Afterwards, I implemented a function to update letters on-screen through frames and another function to check if the letter moves out of the screen. In this case, the letter further drops out from the object array.

The default constructor of the letter class takes the position of the letter as a parameter and sets the default speed and movement direction of the letter on screen.
//default constructor for letter class which takes position of letter as parameter
  Letter(PVector pos) 
  {

    //setting radom speed and velocity of the letters for the movement of letter
    acceleration = new PVector(random(-0.05, 0.05), random(-0.05, 0.05));
    velocity = new PVector(random(-2, 2), random(-2, 2));
    //default position of each letter
    position = pos.copy();
    //random boundry for each letter movement
    MovementSpan = random(100.0, 255.0);  
  }
I implemented the function IsLetterDrops() to check if the letter moves out the screen or not. If the letter moves out of the screen then the letter will be removed further from the letters array.
//for checking if the letters moves out of the screen or not
  boolean IsLetterDrops() 
  {
    //if the letter movement boundry value is less than 0 then letter is out of screen thus returning true else false
    if(MovementSpan < 0.0) 
    {
      return true;
    } 
    else 
    {
      return false;
    }

  }
For loading background image and sound effects, I made a separate function and called that function in the draw and setup functions to render the graphical assets on screen. There are different sound effects used to represent different behaviours. When the character moves, then the sound effect is different. Thus, for the main menu screen and game over screen, a different sound effect is allocated.

I implemented the loadGraphics() function which is loading the images saving in the global image arrays for the player character and grade letters. Furthermore, the background image is also loading into the global background image variable.
// for loading graphics on screen
void loadGraphics() 
{


  PlayerCharacter[0] = loadImage("C1.png");
  PlayerCharacter[1] = loadImage("C2.png");
  PlayerCharacter[2] = loadImage("C3.png");
  PlayerCharacter[3] = loadImage("C4.png");
  

  gradeLetters[0] = loadImage("A.png");
  gradeLetters[1] = loadImage("B.png");
  gradeLetters[2] = loadImage("C.png");
  gradeLetters[3] = loadImage("D.png");
  gradeLetters[4] = loadImage("F.png");
  
  gradeLetters[5] = loadImage("B+.png");
  gradeLetters[6] = loadImage("C+.png");
  gradeLetters[7] = loadImage("D+.png");
 
  

  GPAScoreValues[0] = loadImage("0.png");
  GPAScoreValues[1] = loadImage("1.png");
  GPAScoreValues[2] = loadImage("2.png");
  GPAScoreValues[3] = loadImage("3.png");
  GPAScoreValues[4] = loadImage("4.png");
  

  background = loadImage("back.png");
  KeyControlsImage = loadImage("Controls.png");
  MainPromptText = loadImage("textprompt.png");
  GPAScore = loadImage("gpascore.png");


}
In setup() function I am setting the frame rate by using framerate() builtin function, loading the graphical assets, and playing the main menu sound effect in the loop.
//Main setup function for the configuration of game 
void setup() 
{
  //setting the size of screen by width and height
  size(1080, 720);
  //setting framerate which means how many times screen should be repeated
  frameRate(30);
  //loading sound and background images assets on screen
  loadAssets();
  
  //Put the game in default configuration and game renders from starting position
  restart();
  
  //checking true which shows that character is at its default state
  Character.CharacterDropped = true;
  
  //for playing main menu sound
  MainMenuSoundEffect.loop();

}
In draw() function I am rendering the background image by using image() function and also updating the game assets, for example, repositioning the player character based on the key pressed by the user.
//Main draw function which iterates infinite time and render game screen
void draw() 
{
  image(background,0,0);
  //Updating GPA score point and game configuration
  updateGame();
  //showing graphichs and other assets on screen
  show();

}

FINAL WORK:

CONCLUSION:

For my midterm project, I learned how to implement game logic, render multiple graphics all at the same time, move images from one position to another, and use my knowledge of data structures (for example arrays lists in processing). The game making journey has enhanced my knowledge in regards to different object initialization and creation, and in audio file manipulations from the loading of sound effects that has been done.

GOOGLE DRIVE LINK:

https://drive.google.com/drive/folders/11FKKklnNtAAbftPXK7VQ85PIB9F_IHjX?usp=sharing

COMPLETE CODE OF UNI RUSH GAME 🙂

//importing library for sound
import processing.sound.*;

//Object Creation for Background Sound Effect while game playing
SoundFile BackSoundEffect; 

//Object Creation For Main Menu Background Sound Effect 
SoundFile MainMenuSoundEffect;

//Object Creation For Sound Effect When Character Fails to Eat Any Grade Letter
SoundFile SkipGradeLetterSound; 

//Object Creation For Sound Effect during the movement of character
SoundFile CharacterMovementSoundEffect;

//Image object array creation  for lion character
PImage PlayerCharacter[] = {null, null, null, null};


//Object Creation for grade letters
PImage gradeLetters[] = {null, null, null, null, null, null, null, null};


//Object Creation for the background image
PImage background;

//object creation for key controls for game playing
PImage KeyControlsImage;

//Object creation for main screen text prompt
PImage MainPromptText;

//Object creation for GPA Score Prompt
PImage GPAScore;

//Object creation for GPA score Points
PImage GPAScoreValues[] = {null, null, null, null, null, null, null, null, null, null};

//Game screen width and height
int screenWidth = 1080;
int screenHeight = 720;


//for how many times background should be repeated
int backgroundRepeat[] = {((int)screenWidth/128) + 2, ((int)screenHeight/128) + 2};

//the starting point of the background image
int backgroundOffset = 0;



ArrayList<IntersectionWithLetter> fframes; 
float framespeed; 
float margin;
float marginCounter;

int score; 
int gameFrame = 0;

GradeLetters GradeLetters = new GradeLetters();

Character Character;


//Main setup function for the configuration of game 
void setup() 
{

  //setting the size of screen by width and height
  size(1080, 720);
  //setting framerate which means how many times screen should be repeated
  frameRate(30);
  //loading sound and background images assets on screen
  loadAssets();
  
  //Put the game in default configuration and game renders from starting position
  restart();
  
  //checking true which shows that character is at its default state
  Character.CharacterDropped = true;
  
  //for playing main menu sound
  MainMenuSoundEffect.loop();

}


//Main draw function which iterates infinite time and render game screen
void draw() 
{
   image(background,0,0);
  //Updating game background which include background image,character images and grade letters
 // updateBackground();
  //Updating GPA score point and game configuration
  updateGame();
  //showing graphichs and other assets on screen
  show();

}

//Key pressed function event which occurs when any keyboard key is pressed
void keyPressed() 
{

  //If the key is 'w' then moving the character upward
  if(key == 'w') Character.move(0, -1);
  //if the key is 'a' then moving the character left
  if(key == 'a') Character.move(-1, 0);
  //if the key is s then moving the character down
  if(key == 's') Character.move(0, 1);
  //if the key is 'd' then moving the character right
  if(key == 'd') Character.move(1, 0);

  //if the key is 'r' then setting the character to its default state and postion
  if(key == 'r' || Character.CharacterDropped)
  {
    //stop playing background sounds
    BackSoundEffect.stop();
    MainMenuSoundEffect.stop();
    BackSoundEffect.loop();
    //restarting game to its default configuration
    restart();
    gameFrame = 0;
  }
}


//Main class for Grade letters which inherits the letters class object array
class GradeLetters
{

  //grade letters object array
  ArrayList<Letter> letters;

  //default constructor for grade letters
  GradeLetters() 
  {
    //initializing letters object array in defualt constructor
    letters = new ArrayList<Letter>();
  }
  

  //populating grade letters with different screen positions
  void AddLetter(PVector position, int nletters) 
  {

    //for loop which iterates through number of letters and adding letter with its position
    for(int i = 0; i < nletters; i++) 
    {
      //adding letter with its position
      this.AddLetter(position);
    }
  
  }

  //single paramter add letter function which is for initializing new letter with its position
  void AddLetter(PVector position) 
  {
    //calling letters array add function and adding new letter with it position into the array
    letters.add(new Letter(position));
  }

  //function for updating letters on screen
  void UpdateLettersOnScreen() 
  {
    
    //for loop which runs till letters array size in reverse order
    for (int i = letters.size()-1; i >= 0; i--) 
    {
      //getting the letter from the array from ith index
      Letter l = letters.get(i);
      //rendering the letter on screen
      l.UpdateLettersOnScreen();
      
      //checking if the letter goes out of screen then removing the letter from the array
      if (l.IsLetterDrops()) 
      {
        letters.remove(i);
      }

    }

  }

}


//letter class which represents single letter object
class Letter 
{

  //Position of Letter on screen
  PVector position;
  //Velocity of movement of letter on screen
  PVector velocity; 
  //Accelration of movement of letter on screen
  PVector acceleration;

  //size of the letter which is randomly generated from values 1 to 4
  int size = (int)random(1, 4);
  

  //varibale for limiting the area for the movement of each letter on screen. the letter moves in its setting boundry
  float MovementSpan;


  //default constructor for letter class which takes position of letter as parameter
  Letter(PVector pos) 
  {

    //setting radom speed and velocity of the letters for the movement of letter
    acceleration = new PVector(random(-0.05, 0.05), random(-0.05, 0.05));
    velocity = new PVector(random(-2, 2), random(-2, 2));
    //default position of each letter
    position = pos.copy();
    //random boundry for each letter movement
    MovementSpan = random(100.0, 255.0);  
  }

  //to update the rendering of letter on screen
  void UpdateLettersOnScreen() 
  {
    //updating speed and velocity of letter movement and decresing the movement boundry of letter by value 2.
    velocity.add(acceleration);
    position.add(velocity);
    MovementSpan -= 2.0;
    
    //displaying the letter on screen
    display();
    
  }

  //to display letter on screen
  void display() 
  {
    
    //setting transparent color 
    fill(255, MovementSpan);
    //drawing rectangle which represents the boundry of letters
    rect(position.x, position.y, size, size);
  }


  //for checking if the letters moves out of the screen or not
  boolean IsLetterDrops() 
  {
    //if the letter movement boundry value is less than 0 then letter is out of screen thus returning true else false
    if(MovementSpan < 0.0) 
    {
      return true;
    } 
    else 
    {
      return false;
    }

  }

}

//Player Character Class   
class Character 
{
  //The default x and y position value variables for player character.
  int xPos, yPos;
  //The default x and y direction of the player character
  int xRail = 0, yRail = 0;
  
  //variable for default image frame value for player character
  int currentFrame = 0;
  
  //varibale for checking of the player character is inside screen or not
  boolean CharacterDropped = false;
  
  //default constructor for player character which sets the default position of the player character
  Character(int xPos, int yPos)
  {
    this.xPos = xPos;
    this.yPos = yPos;
  }
  
  //function for the movement of player character accoriding to the x and y direction of the character
  void move(int xDirection, int yDirection)
  {
    
    //checking if the movement of the character is in horizontal direction 
    if(this.xRail + xDirection <= 4 && this.xRail + xDirection >= -1)
    {

      //if the y direction value is zero then adding new letter in the followed direction and playing player character movement sound
      if(yDirection == 0)
      {
        
        GradeLetters.AddLetter(new PVector(this.xPos + xRail * screenHeight/4, this.yPos + this.yRail * screenHeight/4 + 30), 20);
        keyViewerActive(key, 10, screenHeight - 10);
        CharacterMovementSoundEffect.play();
      }

      //moving one step forward the direction of player character in x direction
      this.xRail += xDirection;

    }


    //checking if the movement of the character is in verticle direction 
    if(this.yRail + yDirection <= 1 && this.yRail + yDirection >= -1)
    {

      //if the x direction value is zero then adding new letter in the followed direction and playing player character movement sound
      if(xDirection == 0) 
      {
        
        GradeLetters.AddLetter(new PVector(this.xPos + xRail * screenHeight/4 + 20, this.yPos + this.yRail * screenHeight/4 + 30), 10);
        keyViewerActive(key, 10, screenHeight - 10);
        CharacterMovementSoundEffect.play();
      
      }
      
      //moving one step forward the direction of player character in y direction
      this.yRail += yDirection;
    
    }


  }
  
  //function to check if the player character is out screen which means the character died
  //stopping the game background sound and playing main menu sound
  void die() 
  {
  
    this.xPos = -500;
    this.yPos = -500;
    this.CharacterDropped = true;
    BackSoundEffect.stop();
    SkipGradeLetterSound.play();
    MainMenuSoundEffect.play();
  
  }
  
  //for rendering the player character in rectangular box structure on screen
  void show() 
  {


    rectMode(CENTER);
    fill(255);
    noStroke();
    //showing player character image on screen
    image(PlayerCharacter[currentFrame], this.xPos + xRail * screenHeight/4, this.yPos + this.yRail * screenHeight/4);
 
  }
  
  //for updating grade letters on screen
  void UpdateLettersOnScreen() 
  {

    //if the player character is in screen boundry
    if(!CharacterDropped) 
    {

      //shwoing the player character
      this.show();
      //updating the current frame value to render assests on screen
      if(frameCount % 5 == 0) 
      {
        currentFrame++;
        if(currentFrame == 4) currentFrame = 0;
      }

    }

  }

}


// class for checking if the player character eat or absorb any grade or not
class IntersectionWithLetter 
{

  // variable for the x postion
  int xPos;
  // varibales for the screen frames and its speed initialized by random values
  int currentFrame = (int)random(0, 7), frameSpeed = (int)random(4, 6), empty = (int)random(-2, 2);


  float speed, slowSpeed = 0;
  //check if there is need to add gpa point or not
  boolean canAddToScore = true;

  //default constructor which takes x position of intersecting the grade letter and player character + the speed with which intersection occurs
  IntersectionWithLetter(int xPos, float speed)
  {
    this.xPos = xPos;
    this.speed = speed;
  }
  
  //function to check if the player character eat any grade letter or not
  void Eat() 
  {
   

    if(!Character.CharacterDropped && Character.yRail != this.empty && Character.xPos + Character.xRail * screenHeight/4 >= this.xPos -40 && Character.xPos + Character.xRail * screenHeight/4 <= this.xPos + 70)
    {
      Character.die();
    }

  }
  
  //for showing grade letter on the current rendered frame
  void show() 
  {

    rectMode(CENTER);
    noStroke();
    //for loop which iterates one time and if the ith index is not empty then showing image of grade letter on current frame
    for(int i = -1; i <= 1; i++)
    {
      if(i != empty) image(gradeLetters[currentFrame], this.xPos, screenHeight/2 + i * screenHeight/4);
    }


  }
  
  //for updating letters on current rendered frame
  void UpdateLettersOnScreen() 
  {

    //updating the speed of grade letters
    if(this.slowSpeed == 0) this.xPos -= this.speed;
    else this.xPos -= this.slowSpeed;
    this.Eat();
    this.show();

    // if the rendering is done with all frames then resetting the current frame value to zero
    if(frameCount % frameSpeed == 0) 
    {

      currentFrame++;
      if(currentFrame == 8) 
      {
        currentFrame = 0;
      }

    }

  }


}


//for updating frames on screen after intersection
void UpdateFrames() 
{
  
  //looping to update letters on screen frame after intersection
  for(IntersectionWithLetter IntersectionWithLetter : fframes) 
  {
      IntersectionWithLetter.UpdateLettersOnScreen();
  }

  //checking if the top frame is first frame 
  if(fframes.size() > 0 && fframes.get(0).xPos < -128) 
  {
    //removing the first frame from the screen
    removeFirstFrame();
  }
  //checking if there is space on rendering more frame on screen
  if(marginCounter <= 0 && !(gameFrame >= 2400 && gameFrame <= 3030)) 
  {
    //adding new frame on screen
    addFrame();
  }

  SlowFrameSpeed();

}


//for removing the first frame from the screen
void removeFirstFrame() 
{
  fframes.remove(0);
}

//for adding new frame on screen
void addFrame() 
{
  
  fframes.add(new IntersectionWithLetter(screenWidth + 128, framespeed));
  if(margin > screenWidth/4) margin *= 0.95;
  marginCounter = margin;
  if(framespeed < 20) 
  {
    framespeed *= 1.015;
  }


}

//for slowing the frame rendering speed
void SlowFrameSpeed() 
{

  //if there is space to render more frames on screen then setting the frame speed to 1
  if(gameFrame >= 2400 && gameFrame <= 3030) 
  {
    
    for(IntersectionWithLetter IntersectionWithLetter : fframes) 
    {
      IntersectionWithLetter.slowSpeed = 1;
    }

  } 
  //if there is no space to render more frames on screen then setting the frame speed to 0
  else 
  {

    for(IntersectionWithLetter IntersectionWithLetter : fframes) 
    {
      IntersectionWithLetter.slowSpeed = 0;
    }

  }


}


//for updating background of the game
void updateBackground() 
{
  
  // if the frame vlue is even then updating the background offset position
  if(frameCount%2 == 0) 
  {
    backgroundOffset++;  
  }

  //if the background offset value is maximum then resetting the offset value to 0 and showing the background image
  if(backgroundOffset == 128)
  {

  backgroundOffset = 0;
  showBackground();

  } 

}

//for displaying background on screen
void showBackground() 
{

  //nested for loop to render the background image on each pixel on screen in x and y direction  
  for(int x = 0; x < backgroundRepeat[0]; x++)
  {

    for(int y = 0; y < backgroundRepeat[1]; y++)
    {
      
      image(background, x*background.width - backgroundOffset, y*background.height);
    }

  }


}


// for converting number to images
ArrayList<PImage> numberToArrayOfImages(int number) 
{

  ArrayList<PImage> images = new ArrayList<PImage>();
  String numberS = str(number);
  int len = numberS.length(), buffer;
  
  //iterating till the number length
  for(int index = 0; index < len; index++) 
  {
    //switch for checking for the desired gpa point and if the case match then updating buffer
    switch(numberS.charAt(index)) 
    {
    
     case '0':
       buffer = 0;
       break;
     case '1':
       buffer = 1;
       break;
     case '2':
       buffer = 2;
       break;
     case '3':
       buffer = 3;
       break;
     case '4':
       buffer = 4;
       break;
     case '5':
       buffer = 5;
       break;
     case '6':
       buffer = 6;
       break;
     case '7':
       buffer = 7;
       break;  
     case '8':
       buffer = 8;
       break;  
     case '9':
       buffer = 9;
       break;
     default:
       buffer = 0;
       break;
      }
    images.add(GPAScoreValues[buffer]);
  }
  return images;

}


//showing gpa score
void showScore() 
{

  fill(255);
  textSize(16);
  //rendering gpa score image
  image(GPAScore, 0, 0);
  

  ArrayList<PImage> images = numberToArrayOfImages(score);
  int index = 0;
  
  //iterating all gpa score images
  for(PImage image : images) 
  {
    int yOffset = 0;
    //if the gpa score value matches with the image
    if(image == GPAScoreValues[0]) yOffset = 4;
    //then rendering the image on screen
    image(image, 60 + index * 11, 10 - yOffset);
    index++;
  }



}

// for updating gpa score
void updateScore() 
{
  //checking if player is in screen boundry
  if(!Character.CharacterDropped) 
  {

    //checking if the 
    for(IntersectionWithLetter layer : fframes) 
    {

      if(layer.canAddToScore == true && layer.xPos <= Character.xPos + (Character.xRail * screenHeight/4)) 
      {
        score++;
        layer.canAddToScore = false;
      }

    }

  }
}


//for displaying key viewer on screen
void keyViewer() 
{

  image(KeyControlsImage, 10, screenHeight - 10 - KeyControlsImage.height);

}

//for updating the position based on the active key press
void keyViewerActive(char keyName, int xPos, int yPos)
{

  fill(50, 255, 50);

  //if the key is w then drawing square to new required position
  if(keyName == 'w') 
  {
    square(xPos + 3 * 3 + 44 + 25, yPos + 3 * 3 - 44 * 2, 46);
  } 
  //if the key is a then drawing square to new required position
  else if(keyName == 'a') 
  {
    square(xPos + 3 + 22, yPos - 3 - 22, 46);
  } 
  //if the key is s then drawing square to new required position
  else if(keyName == 's') 
  {
    square(xPos + 3 * 3 + 44 + 25, yPos - 3 - 22, 46);
  } 
  //if the key is d then drawing square to new required position
  else if(keyName == 'd') 
  {
    square(xPos + 3 * 5 + 44 * 2 + 28, yPos - 3 - 22, 46);
  }

  keyViewer();

}



// function for main menu screen
void mainScreen() 
{

  // filling up a rectangle with light color
  fill(50, 150);
  rect(screenWidth/2, screenHeight/2, screenWidth, screenHeight);
  
  textSize(36);
  fill(255);
  
  imageMode(CENTER);
  //prompting text on screen
  image(MainPromptText, screenWidth/2, screenHeight/3);
  
  imageMode(CORNER);

}


// for loading images and sound effect assests on screen
void loadAssets() 
{

  loadGraphics();
  loadSound();

}


// for loading graphics on screen
void loadGraphics() 
{


  PlayerCharacter[0] = loadImage("C1.png");
  PlayerCharacter[1] = loadImage("C2.png");
  PlayerCharacter[2] = loadImage("C3.png");
  PlayerCharacter[3] = loadImage("C4.png");
  

  gradeLetters[0] = loadImage("A.png");
  gradeLetters[1] = loadImage("B.png");
  gradeLetters[2] = loadImage("C.png");
  gradeLetters[3] = loadImage("D.png");
  gradeLetters[4] = loadImage("F.png");
  
  gradeLetters[5] = loadImage("B+.png");
  gradeLetters[6] = loadImage("C+.png");
  gradeLetters[7] = loadImage("D+.png");
 
  

  GPAScoreValues[0] = loadImage("0.png");
  GPAScoreValues[1] = loadImage("1.png");
  GPAScoreValues[2] = loadImage("2.png");
  GPAScoreValues[3] = loadImage("3.png");
  GPAScoreValues[4] = loadImage("4.png");
  

  background = loadImage("back.png");
  KeyControlsImage = loadImage("Controls.png");
  MainPromptText = loadImage("textprompt.png");
  GPAScore = loadImage("gpascore.png");


}


//for loading sound effects 
void loadSound() 
{
  //background sound effect
  BackSoundEffect = new SoundFile(this, "backgroundsound.mp3");
  //main menu sound effect
  MainMenuSoundEffect = new SoundFile(this, "mainmenusound.mp3");
  //skipping grade letter sound
  SkipGradeLetterSound = new SoundFile(this, "dropsound.mp3");
  //player character movement sound effect
  CharacterMovementSoundEffect = new SoundFile(this, "cmovesound.mp3");

}


//for updating game
void updateGame() 
{
  //upodating frames count on screen
  gameFrame++;

  //updating grade letters on screen
  Character.UpdateLettersOnScreen();
  //updating frames on screen
  UpdateFrames();
  //updating gpa score
  updateScore();
  //for updating letters on screen
  GradeLetters.UpdateLettersOnScreen();
  //upodating frame speed
  marginCounter -= framespeed;
  
}



//for showing gpa score and key viewer on game screen
void show() 
{

  //showing gpa score
  showScore();

  //if player character is out of screen then returning to main menu screen
  if(Character.CharacterDropped) 
  {
    mainScreen();
  }

  //for rendering key viewer on screen
  keyViewer();

}

// for restarting the game. 
void restart() 
{
  // the gpa score will be zero
  score = 0;
  
  //frame speed reset to 5 which means 5 frames will be rendered in one second
  framespeed = 2;
  //margin between player character and grade letters
  margin = screenWidth/2;
  marginCounter = margin;


  //initializing player character to its default position
  Character = new Character(230, height/2);
  // resetting frames
  fframes = new ArrayList<IntersectionWithLetter>();
  fframes.add(new IntersectionWithLetter(screenWidth + 128, framespeed));  
  

}

MIDTERM PROJECT PROGRESS

UNI RUSH 

INSPIRATION:

The inspiration behind the game I want to create comes from how overprotective I tend to be with my GPA. Since I was a kid, I always would work to achieve the highest grades and an even the slightest deduction of grades would make me cry. However, after I came to university, that reality changed, and it’s been like a roller-coaster with all its ups and downs. The games resemble a university student who is running all over to catch the grades they want. Based on that, the gpa gets either incremented or decremented depending on the letter grade they catches.  I have always been keen to understand how gpa calculation works, so I searched it up and decided to base my game on that. Also, gpa calculator still always saves my life. Finally, uni rush is a game logic in which a student character is moving different grades comes along the path. So, when the student catches the appearing grade, then GPA is getting calculated at the back end based on the overall grades taken.

GAME RULES:


To score a higher GPA score, the character must catch the better grades and skip the bad ones. The winner of the game will get a maximum GPA score of four. For the movement, the user must move the character in the right path either up or down, right, or left.

IMPLEMENTATION STRATEGY:


I will be using object-oriented approach to divide the coding patterns based on the game logic. Then, I will use an array data structure to store the grade letters in form of images. Afterwards, I will implement 3 different sound effects for each game screen. Eventually, I will have a win sound effect if GPA score was 4.0.

OBJECTS TO BE USED IN GAME:


Grade letters

The grade letter objects will be images of each grade letter on its own

Student Character

This can be any cartoon character with a bigger size as compared to grade letters and can move either left-right or up and down based on the key pressing

Game Background

This object will be a university campus image which is set as the background of the game

GPA Score Prompt

This object will be a simple text prompt and the value of the GPA score will be calculated at run time depending on the game logic.

STORY BOARD OF THE GAME


The game starts with a menu screen on which a prompt will display that shows which key to press to start the game and other instructions. On the main menu screen there is a button to move to the game rules screen. The game rule screen shows all keys for the movement of character for example up, down, left, and right. The start game button on the main menu screen will move to the game screen which is the main part of the game. Furthermore, on the top there will be a GPA score prompt. The character on the other hand will be either standing on one side, and the grades are coming towards him from the other side, or the character is moving while grades are appearing suddenly on a random basis. Background sound effects will be played on every screen.

PROGRESS :

 

CODE FOR NOW :

// import library for sound 
import processing.sound.*;
// objects for bakcground, charcter,  alphabets, and gpa calculation
PImage background;
PImage character;
PImage A;
PImage B;
PImage C;
PImage D;
PImage F;
int score; 

// Position of the character in x and y coordinates 
int posx=0;
int posy=300;

//  background sound object 
SoundFile backmusic;

// Set up function 
void setup() 
{
  // setting screen size
  size(1080, 720);
  // every 30 milescond, a new screen is rendering 
  frameRate(30);
  // initialzie background image object and setting background image as parameter
  background = loadImage("back.png");
  // initializing charcter image object 
  character = loadImage("character.png");
  // initializing letter grade objects 
  A= loadImage("A.png");
  B= loadImage("B.png");
  C= loadImage("C.png");
  D= loadImage("D.png");
  F= loadImage("F.png");
  // initiliaze sound object 
  backmusic = new SoundFile(this, "BackSound.mp3");
}

void keyPressed() 
{
  // if key is pressend by w , then move charcter up
  if(key == 'w') 
  {
    image(character,0,posy-1);
  }
  // if press a, charcter move to left side 
  if(key == 'a') 
  {
    image(character,posx-1,0);
  }
  // if charcter press s, charcter move down 
  if(key == 's') 
  {
    image(character,posx,posy);
  }
  // if press d, character, move right 
  if(key == 'd') 
  {
    image(character,posx+1,posy);
  }
  
}


void draw() 
{ 
  // playing the sound
  backmusic.play();
  // dispalying  background image 
  image (background,0,0);
  // displaying chacrter image and give its initial positions (x,y)
  image(character,posx,posy);
  // displaying letter grades,  plus I give each letter grade their position (x,y)
  image(A,width-120,300);
  image(B,width-150,500);
  image(C,width-180,200);
  image(D,width-220,600);
  image(F,width-140,150);
  // displaying gpa score at the top 
  text("GPA Score: ",30,30);

 

Week 4 : Data Visualization

FEMALES PRESENCE ON SOCIAL MEDIA 

INTRODUCTION:

In week 4, we must brainstorm on some creative ideas to visualize and see an insight of data visualization. Data visualization plays a vital role in processing and analyzing data. The new era is of big data and the only way to get knowledge from data is through graphs and charts. So Processing is ideal as it allows us to manipulate and simulate the data and draw various graphs based on our own requirements. 

INSPIRATION BEHIND DATA VISUALIZATION:

The idea comes into visualization by comparing Gulf countries in terms of female users on social media. There are numerous social media platforms, and, on every platform, we have number of active users by gender. Based on the above facts, I decided to visualize active female users on different social media platforms in different gulf countries. This stems from the fact that in previous generations, the society in the Middle East was more conservative in terms of allowing girls to engage and interact on social media. As a Middle Eastern woman, I found it to be interesting to statistically show how this mindset changed throughout recent generations. Google trends was a part of my research as it shows that females are more active on social media platforms rather than males.

CHALLENGES & PROBLEMS:

The generation of data for active female users on different social media platforms was challenging for me due to data ambiguity on the internet. Preprocessing of data was another challenge too. To sort out this issue, I converted csv format dataset into tab separated format to preprocess the values in a convenient way. It was difficult for me to find the maximum and minimum number of female active social media users from the data to draw graph points. The labeling was somehow easy but drawing area for each social media platform was a hurdle.

PROCEDURE:

Based on the previous knowledge of classes and object oriented, I started by implementing classes which supports me further to manage my code while visualizing the data. I implemented the dataset class and its main purpose was to read and preprocess the data before visualizing the data. The class contained some important attributes which further stored different values from the dataset.
class Dataset 
{

  //Atribute for Number Of rows
  int NumberOfRows;
  //Attribute for Number of columns
  int NumberOfColumns;
  //2D array for getting social media users percentage data
  float[][] SocialData;
  //For getting name of rows
  String[] NameOfRows;
  //For getting GCC countries names
  String[] GCCCountries;
The dataset is in tabular format and is tab delimited. The first row contains column names. The first column contains GCC countries names. While the float values represent active social media female user’s percentage. 

The dataset function is taking the file name as a parameter and loading all the lines in a string array. Then we further split it by tab and get the columns which is at first row. I store GCC Countries names in the class attribute named as GCCCountries. Then, did a preprocessing on the data present in the attributes to remove unnecessary spaces and quotations.  By doing so, I got the number of columns and number of rows in this function. 
//Function to read data from the tsv (Tab Seperated File) file
 //Parameter is filename
 Dataset(String filename)
 {
   //storing rows in string array
   String[] rows = loadStrings(filename);
   
   //Getting column names
   String[] columns = split(rows[0], TAB);
   //Getting GCC Countries Names
   GCCCountries = subset(columns, 1);
   //Pre processing on GCC Countries
   Preprocessing(GCCCountries);
   //for Countires Count
   NumberOfColumns = GCCCountries.length;
   
   //For name of each row
   NameOfRows = new String[rows.length-1];
   //For Social Data
   SocialData = new float[rows.length-1][];

   // We are ignoring first column as it containes headers
   for (int i = 1; i < rows.length; i++)
    {
     // Spliting row based on Tab
     String[] pieces = split(rows[i], TAB);
     //Pre processing on row data
     Preprocessing(pieces);
     
     // Getting row name
     NameOfRows[NumberOfRows] = pieces[0];
     // Getting social media users data 
     SocialData[NumberOfRows] = parseFloat(subset(pieces, 1));

     // incrementing rows
     NumberOfRows++;      
   }
   // adding more storage in social data varible
   SocialData = (float[][]) subset(SocialData, 0, NumberOfRows);
 }
In the preprocessing function, I am passing an array containing active social media female user’s percentage values. In other words, I am checking if the values are quoted, and then removing the quotes from the values. 
// for pre processing the dataset. removing unecessary quotations and spacing
  void Preprocessing(String[] array) 
  {
    for (int i = 0; i < array.length; i++) 
    {
      if (array[i].length() > 2) 
      {
        if (array[i].startsWith("\"") && array[i].endsWith("\"")) 
        {
          array[i] = array[i].substring(1, array[i].length() - 1);
        }
      }
      array[i] = array[i].replaceAll("\"\"", "\"");
    }
  }
Then we have small getter functions which returns class attribute values. These functions aid in the code reusability. 
//For getting number of rows
 int getNumberOfRows() 
 {
   return NumberOfRows;
 }
 
 //For getting row names
 String getRowName(int rowIndex) 
 {
   return NameOfRows[rowIndex];
 }
 
 //for getting social media platform names
 String[] getNameOfRows() 
 {
   return NameOfRows;
 }
Moving forward, I implemented the function to get which GCC country has the minimum active female social media users. I am passing the social platform index to check for minimum value. 
//Getting the minimum number female users on social media platform
 float MinimumColumn(int col) 
 {
   float m = Float.MAX_VALUE;
   for (int i = 0; i < NumberOfRows; i++) 
   {
     if (!Float.isNaN(SocialData[i][col])) 
     {
       if (SocialData[i][col] < m) 
       {
         m = SocialData[i][col];
       }
     }
   }
   return m;
 }
Later, I calculated which GCC country has maximum active female social media users and passed the social media index as a parameter. Moreover, inside the for loop, I am checking if the new value is greater than previous one, then updating the temp m variable which contains maximum value. 
//Getting the maximum number female users on social media platform
  float MaximumColumn(int col) 
  {
    float m = -Float.MAX_VALUE;
    for (int i = 0; i < NumberOfRows; i++) 
    {
      if (isValid(i, col)) 
      {
        if (SocialData[i][col] > m) 
        {
          m = SocialData[i][col];
        }
      }
    }
    return m;
  }
Afterwards, I implemented maximum and minimum values based on social media platforms. Each GCC country has multiple social media platforms and, in these functions, calculation of which social media has minimum active female users and which has maximum social media users is done. 
//Getting GCC Country which has lowest female users on social media platforms
  float MinimumRow(int row) 
  {
    float m = Float.MAX_VALUE;
    for (int i = 0; i < NumberOfColumns; i++) 
    {
      if (isValid(row, i)) 
      {
        if (SocialData[row][i] < m) 
        {
          m = SocialData[row][i];
        }
      }
    }
    return m;
  } 


//Getting GCC Country which has highest female users on social media platforms
float MaximumRow(int row) 
{
float m = -Float.MAX_VALUE;
for (int i = 1; i < NumberOfColumns; i++) 
{
if (!Float.isNaN(SocialData[row][i])) 
{
if (SocialData[row][i] > m) 
{
m = SocialData[row][i];
}
}
}
return m;
}
Next, I implemented class for social platform. This class supports in drawing areas and value points. In addition, I initialized attributes to store min and max values, countries count and social platforms count. 

public class SocialPlatform
{
  
  //Initializing object of female users count on social media platforms by GCC countries
  Dataset FemaleUsers;
  
  //Attributes for maximum and minimum count
  float dataMin, dataMax;
  String datesMin, datesMax;

  // for number of rows and number of columns
  int rowCount, columnCount;
  int columnNumber;
  String GCCCountries[];
  
  // Attributes for plotting graphs
  float plotX1, plotY1, plotX2, plotY2;
  
  //For coloring the graph
  color hexcode;
The social platform function is drawing area on the screen for each social media platform with specified color. The color value and social media platform index is passed as parameter. 

//function to draw social platform insight with color
  SocialPlatform(color hexcode, int columnNumber) 
  { 
  //saving the color of social platform
  this.hexcode = hexcode;
  //for column number
  this.columnNumber = columnNumber;
  
  //For female Social Media users 
  FemaleUsers = new Dataset("SocialMediaUsersFemales.tsv");
  //for row and column count
  rowCount = FemaleUsers.getNumberOfRows();
  columnCount = FemaleUsers.getNumberOfColumns();  
  
  //getting GCC country
  GCCCountries = FemaleUsers.getNameOfRows();
  //getting maximum and minimum value of female users on social media with respect to GCC Country
  datesMin = GCCCountries[0];
  datesMax = GCCCountries[GCCCountries.length-1];  
  
  
  dataMin = FemaleUsers.MinimumTable();
  dataMax = FemaleUsers.MaximumTable();
  
  //How much gap from the left of the screen
  plotX1 = 50; 
  //Gap from the top of the screen
  plotY1 = 150; 
  plotX2 = width - plotX1;
  plotY2 = height - 50; 
  
  DrawFemaleUsersPoints(this.columnNumber);
  DrawAreaofFemaleUsersbyMedia(this.columnNumber);
  mouseMoved();
}
Here I am drawing points to show the active females social media users on graph. When the mouse hovers to the point, then the percentage value pops up with the social platform name.

void DrawFemaleUsersPoints(int col) 
{
  
  // for row count
  int rowCount = FemaleUsers.getNumberOfRows();
  
  for(int row = 0; row < rowCount; row++) 
  {
    float value = FemaleUsers.getFloat(row, col);
    String mediaName = FemaleUsers.getColumnName(col);
    float x = map(row, 0, 12, 100, width - 50);
    float y = map(value, dataMin, dataMax, plotY2, plotY1);
    stroke(0);
    strokeWeight(3);
    point(x, y);
    mouseMoved();
    if((mx>100) && (mx<(width-50)))
     {
      stroke(2);
      strokeWeight(2);
      line(mx, plotY2, mx, plotY1);
      println("x: " + x + " y: " + y);
      if((abs(mx-x) < 5) && (abs(my-y) < 5))
      {
        fill(0);
        textSize(15);
        text(mediaName, mx+26, my-40);
        text(value+"%", mx+26, my-20);
      }
    }
    
    }
}
In the main program, initializing objects for each social media platform is created. Then, I called relevant functions to draw areas and points of each social media platform. 
 Dataset FemaleUsers;


  float dataMin, dataMax;
  String datesMin, datesMax;

  int rowCount, columnCount;
  int columnNumber;
  String GCCCountries[];
  
  float plotX1, plotY1, plotX2, plotY2;
  
  String hexcode;
  
  float mx, my;


SocialPlatform facebook;
SocialPlatform twitter;
SocialPlatform pinterest;
SocialPlatform instagram;
SocialPlatform youtube;
SocialPlatform reddit;
In draw function, I initialized each social media platform with a different color. Drawing countries label and female users labels on x and y axis of graph. 

void draw() 
{
  background(244); 
  title();
  DrawGCCCountriesLabels();
  DrawFemaleUsersLabel();
  smooth();
  
  facebook = new SocialPlatform(#4267B2, 0);
  pinterest = new SocialPlatform(#BD081C, 1);
  twitter = new SocialPlatform(#1DA1F2, 2);
  instagram = new SocialPlatform(#FFDC80, 3);
  reddit = new SocialPlatform(#FF4500, 4);
  youtube = new SocialPlatform(#FF0000, 5);
}

COMPLETE CODE ATTACHED BELOW:

class Dataset 
{

  //Atribute for Number Of rows
  int NumberOfRows;
  //Attribute for Number of columns
  int NumberOfColumns;
  //2D array for getting social media users percentage data
  float[][] SocialData;
  //For getting name of rows
  String[] NameOfRows;
  //For getting GCC countries names
  String[] GCCCountries;
  
  
  //Function to read data from the tsv (Tab Seperated File) file
  //Parameter is filename
  Dataset(String filename)
  {
    //storing rows in string array
    String[] rows = loadStrings(filename);
    
    //Getting column names
    String[] columns = split(rows[0], TAB);
    //Getting GCC Countries Names
    GCCCountries = subset(columns, 1);
    //Pre processing on GCC Countries
    Preprocessing(GCCCountries);
    //for Countires Count
    NumberOfColumns = GCCCountries.length;
    
    //For name of each row
    NameOfRows = new String[rows.length-1];
    //For Social Data
    SocialData = new float[rows.length-1][];

    // We are ignoring first column as it containes headers
    for (int i = 1; i < rows.length; i++)
     {
      // Spliting row based on Tab
      String[] pieces = split(rows[i], TAB);
      //Pre processing on row data
      Preprocessing(pieces);
      
      // Getting row name
      NameOfRows[NumberOfRows] = pieces[0];
      // Getting social media users data 
      SocialData[NumberOfRows] = parseFloat(subset(pieces, 1));

      // incrementing rows
      NumberOfRows++;      
    }
    // adding more storage in social data varible
    SocialData = (float[][]) subset(SocialData, 0, NumberOfRows);
  }
  
  // for pre processing the dataset. removing unecessary quotations and spacing
  void Preprocessing(String[] array) 
  {
    for (int i = 0; i < array.length; i++) 
    {
      if (array[i].length() > 2) 
      {
        if (array[i].startsWith("\"") && array[i].endsWith("\"")) 
        {
          array[i] = array[i].substring(1, array[i].length() - 1);
        }
      }
      array[i] = array[i].replaceAll("\"\"", "\"");
    }
  }
  
  //For getting number of rows
  int getNumberOfRows() 
  {
    return NumberOfRows;
  }
  
  //For getting row names
  String getRowName(int rowIndex) 
  {
    return NameOfRows[rowIndex];
  }
  
  //for getting social media platform names
  String[] getNameOfRows() 
  {
    return NameOfRows;
  }

  //for getting row index based on social media platform name
  int getRowIndex(String name) 
  {
    for (int i = 0; i < NumberOfRows; i++) 
    {
      if (NameOfRows[i].equals(name)) 
      {
        return i;
      }
    }
    return -1;
  }
  
  //for getting number of columns
  int getNumberOfColumns() 
  {
    return NumberOfColumns;
  }
  
  //for getting column name
  String getColumnName(int colIndex) 
  {
    return GCCCountries[colIndex];
  }
  
  //for getting GCC countries list
  String[] getGCCCountries() 
  {
    return GCCCountries;
  }


  //getting female social media users value which is in percentage as float value
  float getFloat(int rowIndex, int col) 
  {
    return SocialData[rowIndex][col];
  }
  
  
  //checking of the value is valid
  boolean isValid(int row, int col) 
  {
    if (row < 0)
    { 
    return false;
    }
    if (row >= NumberOfRows)
    {
     return false;
    }
    if (col >= SocialData[row].length)
    {
     return false;
    }
    if (col < 0)
    {
     return false;
     }
    return !Float.isNaN(SocialData[row][col]);
  }
  
  //Getting the minimum number female users on social media platform
  float MinimumColumn(int col) 
  {
    float m = Float.MAX_VALUE;
    for (int i = 0; i < NumberOfRows; i++) 
    {
      if (!Float.isNaN(SocialData[i][col])) 
      {
        if (SocialData[i][col] < m) 
        {
          m = SocialData[i][col];
        }
      }
    }
    return m;
  }

  //Getting the maximum number female users on social media platform
  float MaximumColumn(int col) 
  {
    float m = -Float.MAX_VALUE;
    for (int i = 0; i < NumberOfRows; i++) 
    {
      if (isValid(i, col)) 
      {
        if (SocialData[i][col] > m) 
        {
          m = SocialData[i][col];
        }
      }
    }
    return m;
  }

  //Getting GCC Country which has lowest female users on social media platforms
  float MinimumRow(int row) 
  {
    float m = Float.MAX_VALUE;
    for (int i = 0; i < NumberOfColumns; i++) 
    {
      if (isValid(row, i)) 
      {
        if (SocialData[row][i] < m) 
        {
          m = SocialData[row][i];
        }
      }
    }
    return m;
  } 

  //Getting GCC Country which has highest female users on social media platforms
  float MaximumRow(int row) 
  {
    float m = -Float.MAX_VALUE;
    for (int i = 1; i < NumberOfColumns; i++) 
    {
      if (!Float.isNaN(SocialData[row][i])) 
      {
        if (SocialData[row][i] > m) 
        {
          m = SocialData[row][i];
        }
      }
    }
    return m;
  }
  
  //Getting the minimum female users on social media platform in a table
  float MinimumTable() 
  {
    float m = Float.MAX_VALUE;
    for (int i = 0; i < NumberOfRows; i++) 
    {
      for (int j = 0; j < NumberOfColumns; j++) 
      {
        if (isValid(i, j)) 
        {
          if (SocialData[i][j] < m) 
          {
            m = SocialData[i][j];
          }
        }
      }
    }
    return m;
  }

  //Getting the maximum female users on social media platform in a table
  float MaximumTable() 
  {
    float m = -Float.MAX_VALUE;
    for (int i = 0; i < NumberOfRows; i++) 
    {
      for (int j = 0; j < NumberOfColumns; j++) 
      {
        if (isValid(i, j)) 
        {
          if (SocialData[i][j] > m) 
          {
            m = SocialData[i][j];
          }
        }
      }
    }
    return m;
  }
}

public class SocialPlatform
{
  
  //Initializing object of female users count on social media platforms by GCC countries
  Dataset FemaleUsers;
  
  //Attributes for maximum and minimum count
  float dataMin, dataMax;
  String datesMin, datesMax;

  // for number of rows and number of columns
  int rowCount, columnCount;
  int columnNumber;
  String GCCCountries[];
  
  // Attributes for plotting graphs
  float plotX1, plotY1, plotX2, plotY2;
  
  //For coloring the graph
  color hexcode;
  
  
  float mx, my;

  //function to draw social platform insight with color
  SocialPlatform(color hexcode, int columnNumber) 
  { 
  //saving the color of social platform
  this.hexcode = hexcode;
  //for column number
  this.columnNumber = columnNumber;
  
  //For female Social Media users 
  FemaleUsers = new Dataset("SocialMediaUsersFemales.tsv");
  //for row and column count
  rowCount = FemaleUsers.getNumberOfRows();
  columnCount = FemaleUsers.getNumberOfColumns();  
  
  //getting GCC country
  GCCCountries = FemaleUsers.getNameOfRows();
  //getting maximum and minimum value of female users on social media with respect to GCC Country
  datesMin = GCCCountries[0];
  datesMax = GCCCountries[GCCCountries.length-1];  
  
  
  dataMin = FemaleUsers.MinimumTable();
  dataMax = FemaleUsers.MaximumTable();
  
  //How much gap from the left of the screen
  plotX1 = 50; 
  //Gap from the top of the screen
  plotY1 = 150; 
  plotX2 = width - plotX1;
  plotY2 = height - 50; 
  
  DrawFemaleUsersPoints(this.columnNumber);
  DrawAreaofFemaleUsersbyMedia(this.columnNumber);
  mouseMoved();
}



void DrawFemaleUsersPoints(int col) 
{
  
  // for row count
  int rowCount = FemaleUsers.getNumberOfRows();
  
  for(int row = 0; row < rowCount; row++) 
  {
    float value = FemaleUsers.getFloat(row, col);
    String mediaName = FemaleUsers.getColumnName(col);
    float x = map(row, 0, 12, 100, width - 50);
    float y = map(value, dataMin, dataMax, plotY2, plotY1);
    stroke(0);
    strokeWeight(3);
    point(x, y);
    mouseMoved();
    if((mx>100) && (mx<(width-50)))
     {
      stroke(2);
      strokeWeight(2);
      line(mx, plotY2, mx, plotY1);
      println("x: " + x + " y: " + y);
      if((abs(mx-x) < 5) && (abs(my-y) < 5))
      {
        fill(0);
        textSize(15);
        text(mediaName, mx+26, my-40);
        text(value+"%", mx+26, my-20);
      }
    }
    
    }
}

void DrawAreaofFemaleUsersbyMedia(int col)
{
  fill(this.hexcode);
  noStroke();
  beginShape();
  int rowCount = FemaleUsers.getNumberOfRows();
  for (int row = 0; row < rowCount; row++) 
  {
    float value = FemaleUsers.getFloat(row, col);
    float x = map(row, 0, 12, 100, width - 50);
    float y = map(value, dataMin, dataMax, plotY2, plotY1);
    vertex(x, y);
  }
// Draw the lower-right and lower-left corners.
vertex(plotX2, plotY2);
vertex(100, plotY2);
endShape(CLOSE);
}

void mouseMoved() 
{
  mx = mouseX;
  my = mouseY;
}

}


  Dataset FemaleUsers;


  float dataMin, dataMax;
  String datesMin, datesMax;

  int rowCount, columnCount;
  int columnNumber;
  String GCCCountries[];
  
  float plotX1, plotY1, plotX2, plotY2;
  
  String hexcode;
  
  float mx, my;


SocialPlatform facebook;
SocialPlatform twitter;
SocialPlatform pinterest;
SocialPlatform instagram;
SocialPlatform youtube;
SocialPlatform reddit;



void setup() 
{
  size(1500, 300);
  smooth();
  
  FemaleUsers = new Dataset("SocialMediaUsersFemales.tsv");
  rowCount = FemaleUsers.getNumberOfRows();
  
  //For Social Media 
  FemaleUsers = new Dataset("SocialMediaUsersFemales.tsv");
  rowCount = FemaleUsers.getNumberOfRows();
  columnCount = FemaleUsers.getNumberOfColumns();  
  
  GCCCountries = FemaleUsers.getNameOfRows();
  datesMin = GCCCountries[0];
  datesMax = GCCCountries[GCCCountries.length-1];  
  
  dataMin = FemaleUsers.MinimumTable();
  dataMax = FemaleUsers.MaximumTable();
  
  //How much gap from the left of the screen
  plotX1 = 50; 
  //Gap from the top of the screen
  plotY1 = 150; 
  
  plotX2 = width - plotX1;
  plotY2 = height - 50; 
}

void draw() 
{
  background(244); 
  title();
  DrawGCCCountriesLabels();
  DrawFemaleUsersLabel();
  smooth();
  
  facebook = new SocialPlatform(#4267B2, 0);
  pinterest = new SocialPlatform(#BD081C, 1);
  twitter = new SocialPlatform(#1DA1F2, 2);
  instagram = new SocialPlatform(#FFDC80, 3);
  reddit = new SocialPlatform(#FF4500, 4);
  youtube = new SocialPlatform(#FF0000, 5);
}


void title()
{
  fill(0);
  textAlign(CENTER);
  textSize(20);
  text("Female Social Media Users by Percentage By GCC Countries", width/2, 30);
}


void DrawGCCCountriesLabels() 
{
  fill(0);
  textSize(10);
  textAlign(CENTER, TOP);
  
  stroke(224);
  strokeWeight(1);
  
  int rowCount = FemaleUsers.getNumberOfRows();
  
  for(int row = 0; row < rowCount; row++)
  {
      float x = map(row, 0, 12, 100, width-50);
      text(GCCCountries[row], x, plotY2 + 10);
      line(x, 50, x, plotY2);    
  }
}

void DrawFemaleUsersLabel()
{
fill(50);
textSize(10);
textAlign(RIGHT, CENTER);
for (float p = 0; p < 101; p += 25)
 {
  float y = map(p, 0, 100, plotY2, 50);
  text(int(p), plotX1 + 40, y);
  textSize(10);
  textAlign(CENTER, CENTER);
  text("Percentage\nof female \n social\nmedia users",45, height/2);
  }
}

FINAL WORK:

CONCLUSION:

The assignment made me explore how to manipulate data and visualize it in a knowledgeable way with the use of object-oriented programming. I learned to plot graph areas and the basic of graphs and charts. Not only did I familiarize myself with how to collect data and prepare it for data visualization, but also on how to display and manipulate with text and strings in processing.