Robotics | Final Project | Drummy Teletubbies | Gao Yang and Jianghao Hu (Sam)

Final Project

Project~: Drummy Teletubbies

Background Story: My partner and I like music very much, so for the final project, we wanted to make something that related to music. Then we think about what kind of music robot we want and finally decided to build a robot that can play beats.

We can play the guitar and piano, and we found that when we play the instrument by ourselves, we have no hands or time or energy to play the beats. In addition, compared to the band with lots of instruments, the performance that only one person playing the instrument will be calmer and flatter. So can we change this situation? We thought an idea that we can play the robot that can play the beats according to the music we play. So that the music perform in the end will have more layers and will help people enjoy more in music.

Emotions to transmit: Now you do not need to worry about do not have any drummers during the performance because the Drummy Teletubbies can help you play the drums. It can also help you with different kinds of beats sounds and enrich the music you play!

Design Process:

1⃣️At the very beginning, we wanted the robot to learn the beats we play——We play some beats and it can follow us and play the same pattern and we made it in the end. However, as music performance is more impromptu, so that the performer may not have a certain pattern of the beats before the performance, so we give up this in the end.

2⃣️Then we think about using a sounds sensor to detect the sound, so the robot can lwan pattern, play according to the music. Then we tried the sound sensor and used the servo motor to be the robots’ arms. And we found some problems. The sound sensor has some conflict with the servo motor sometimes.

3⃣️We changed the servo motor to solenoids, used transistors and took diodes away.

 

IMG_0060

IMG_0059

IMG_0061

IMG_0058

The flow chart👇

flowingchart

The circuit diagram👇

Diagram

Video of how it works👇

Conclusion:

  • It’s hard to make robots perfectly play music as humans.
  • Machines can imitate human actions and certainly perform as tools to help humans.
  • The relationship between technology and art is tight. Technology can help improve Art.
  • Robots can help improve human’s creativity.
  • After the last time of the course, I began to think about what the robot is. A robot not can read, but also can think. According to a reading we did, the robot is not a machine. A machine needs simple input and it can take some action to the input. However. robots are not the same. The things we did on the first step actually indicate that the robot can think, because in that way the robot actually starts to learn something instead of just reacting to the music.

The code of our project👇

 

const int hand1 = 9;
const int hand2 = 10;
const int hand3 = 11;
const int hand4 = 12;
const int hand5 = 13;

const int touchSensor1 = 5;
const int touchSensor2 = 6;
const int touchSensor3 = 7;

const int led1 = 2;
const int led2 = 3;
const int led3 = 4;

boolean drum1IsOn = false;
boolean drum2IsOn = false;
boolean drum3IsOn = false;

boolean ifChange = false;
const int soundSensor = A0;
long currentVal = 0;
int count = 0;

void setup() {
  Serial.begin(115200);
  pinMode(touchSensor1, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(hand1, OUTPUT);
  pinMode(hand2, OUTPUT);
  pinMode(hand3, OUTPUT);
  pinMode(hand4, OUTPUT);
  pinMode(hand5, OUTPUT);
}

void loop() {
  int drum1 = digitalRead(touchSensor1);
  int drum2 = digitalRead(touchSensor2);
  int drum3 = digitalRead(touchSensor3);

  if (drum1 == HIGH) {
    if (drum1IsOn == false) {
      drum1IsOn = true;
      //Serial.println(1);
    } else {
      drum1IsOn = false;
    }
  }
  if (drum2 == HIGH) {
    if (drum2IsOn == false) {
      drum2IsOn = true;
    } else {
      drum2IsOn = false;
    }
  }
  if (drum3 == HIGH) {
    if (drum3IsOn == false) {
      drum3IsOn = true;
    } else {
      drum3IsOn = false;
    }
  }

  long soundSum = 0;
  for (int i = 0; i < 32; i++) {
    soundSum += analogRead(soundSensor);
  }
  delay(150);
  Serial.println(soundSum);

  if (currentVal < 10000 && soundSum > 10000) {
    ifChange = true;
    count += 1;
    currentVal = soundSum;
  } else {
    ifChange = false;
    currentVal = soundSum;
  }

  //Serial.println(count);
  
  if (drum1IsOn == true) {
    digitalWrite(led1, HIGH);

    if (count > 0 && count % 4 == 0 && ifChange == true) {
      //Serial.println(1);
      digitalWrite(hand1, HIGH);
      digitalWrite(hand2, LOW);
    } else {
      //Serial.println(0);
      digitalWrite(hand1, LOW);
      digitalWrite(hand2, HIGH);
    }

  } else {
    digitalWrite(led1, LOW);
    digitalWrite(hand1, LOW);
    digitalWrite(hand2, LOW);
  }

  if (drum2IsOn == true) {
    digitalWrite(led2, HIGH);

    if (count > 0 && count % 4 != 0 && count % 2 == 0 && ifChange == true) {
      //Serial.println(2);
      digitalWrite(hand3, HIGH);
      digitalWrite(hand4, HIGH);
    } else {
      digitalWrite(hand3, LOW);
      digitalWrite(hand4, LOW);
    }

  } else {
    digitalWrite(led2, LOW);
    digitalWrite(hand3, LOW);
    digitalWrite(hand4, LOW);
  }

  if (drum3IsOn == true) {
    digitalWrite(led3, HIGH);

    if (ifChange == true) {
      //Serial.println(3);
      digitalWrite(hand5, HIGH);
    } else {
      digitalWrite(hand5, LOW);
    }

  } else {
    digitalWrite(led3, LOW);
    digitalWrite(hand5, LOW);
  }
}

Final Deliverable and Assignment: Robot Drummy Teletubbies

Student Name: Jianghao HU (Sam). Partner: Yang Gao.

Background Story:

When you play the piano or guitar and singing, do you ever think about making the performance has more layers? Take the band as an example, there are several people in a band, so they can play music with both beats and melodies. However, when we play the instruments like guitar, piano, violin by ourselves, we do not have extra time or energy to play the drum. So compare to the band, the traditional performances of one person playing instrument are usually calmer and flatter.

Can we change this situation?

Emotions to Transmit:

Now you do not need to worry for the drummers any more, the robot can help you play a band by yourself! You can enjoy the music by yourself.

The robot will play different kinds of beats according to the music you play. It has three different timbre of beats. Playing in different patterns, Drummy Teletubbies will help enrich the music you play!

Design Process:

The sketch below shows our early idea of how the robot will look like.

2

As we move on developing , we changed servo motors, which we planned to make hands with, into solenoids, so that the motion of beating will become easier to achieve.

IMG_7383

Below is when we were assembling the robot according to the diagram and the flowing chart (which I will demonstrate later).

IMG_7392

And this is how it eventually looks like.

IMG_7399IMG_7400

We were inspired by marching bands in which there are people playing different kinds of drums. In terms of hardwares, we used boxes and balls as bodies, drums, the table, and heads. We also used solenoids, touch sensors, LEDs, transistors, etc. As for the software and the basic mechanism, I’ll going to demonstrate with diagrams and flowing chart.

Diagram

flowingchart

 

Conclusion:

  • It’s hard to make robots perfectly play music as humans do.
  • Machines can imitate human actions and certainly perform as tools to help humans.
  • The relationship between technology and art is tight.
  • Robots can help improve human’s creativity.
  • When designing our automatic, we originally to make it not only able to play drums according to beats but also able to change how strong they play according to the amplitude. But then we realized this was hard to achieve. It reminds me of Robots and Choreography in which the author mentions the challenge to make robots dance smoothly. It seems that the limit of mechanical motions is obvious.
  • One regret we had is that we got rid of the machine learning feature we had at the beginning. It was a mechanism that allows our robot to learn and remember the beat so that he can constantly play along with the music. Because we didn’t implement this mechanism, our robot more or less lost the power of thinking. This is also a future improvement we could make.

At last, here’s the demo video of our Drummy Teletubbies.

const int hand1 = 9;
const int hand2 = 10;
const int hand3 = 11;
const int hand4 = 12;
const int hand5 = 13;

const int touchSensor1 = 5;
const int touchSensor2 = 6;
const int touchSensor3 = 7;

const int led1 = 2;
const int led2 = 3;
const int led3 = 4;

boolean drum1IsOn = false;
boolean drum2IsOn = false;
boolean drum3IsOn = false;

boolean ifChange = false;
const int soundSensor = A0;
long currentVal = 0;
int count = 0;

void setup() {
  Serial.begin(115200);
  pinMode(touchSensor1, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(hand1, OUTPUT);
  pinMode(hand2, OUTPUT);
  pinMode(hand3, OUTPUT);
  pinMode(hand4, OUTPUT);
  pinMode(hand5, OUTPUT);
}

void loop() {
  int drum1 = digitalRead(touchSensor1);
  int drum2 = digitalRead(touchSensor2);
  int drum3 = digitalRead(touchSensor3);

  if (drum1 == HIGH) {
    if (drum1IsOn == false) {
      drum1IsOn = true;
      //Serial.println(1);
    } else {
      drum1IsOn = false;
    }
  }
  if (drum2 == HIGH) {
    if (drum2IsOn == false) {
      drum2IsOn = true;
    } else {
      drum2IsOn = false;
    }
  }
  if (drum3 == HIGH) {
    if (drum3IsOn == false) {
      drum3IsOn = true;
    } else {
      drum3IsOn = false;
    }
  }

  long soundSum = 0;
  for (int i = 0; i < 32; i++) {
    soundSum += analogRead(soundSensor);
  }
  delay(150);
  Serial.println(soundSum);

  if (currentVal < 9000 && soundSum > 9000) {
    ifChange = true;
    count += 1;
    currentVal = soundSum;
  } else {
    ifChange = false;
    currentVal = soundSum;
  }

  //Serial.println(count);
  
  if (drum1IsOn == true) {
    digitalWrite(led1, HIGH);

    if (count > 0 && count % 4 == 0 && ifChange == true) {
      //Serial.println(1);
      digitalWrite(hand1, HIGH);
      digitalWrite(hand2, LOW);
    } else {
      //Serial.println(0);
      digitalWrite(hand1, LOW);
      digitalWrite(hand2, HIGH);
    }

  } else {
    digitalWrite(led1, LOW);
    digitalWrite(hand1, LOW);
    digitalWrite(hand2, LOW);
  }

  if (drum2IsOn == true) {
    digitalWrite(led2, HIGH);

    if (count > 0 && count % 4 != 0 && count % 2 == 0 && ifChange == true) {
      //Serial.println(2);
      digitalWrite(hand3, HIGH);
      digitalWrite(hand4, HIGH);
    } else {
      digitalWrite(hand3, LOW);
      digitalWrite(hand4, LOW);
    }

  } else {
    digitalWrite(led2, LOW);
    digitalWrite(hand3, LOW);
    digitalWrite(hand4, LOW);
  }

  if (drum3IsOn == true) {
    digitalWrite(led3, HIGH);

    if (ifChange == true) {
      //Serial.println(3);
      digitalWrite(hand5, HIGH);
    } else {
      digitalWrite(hand5, LOW);
    }

  } else {
    digitalWrite(led3, LOW);
    digitalWrite(hand5, LOW);
  }
}

Final Documentation: Poison Protector

Intro

Poison Protector™ detects dangerous gasses in your home and notifies the occupants of your house when such a threat detected. Imagine you are sleeping far away from the kitchen and a CO leak is detected. Perhaps you are a heavy sleeper and the alarm from within the kitchen does not wake you. Poison Protector™ will, upon detection of a dangerous gas, traverse a predetermined path with an alarm. This path will pass all the rooms of the occupants and wake them up accordingly.

 

Block Diagram

As seen in the block diagram below, Poison Protector has 3 infrared sensors, 1 speaker, 1 CO detector, 1 methane detector, 1 Lithium batter, and 2 motors.

block diagram

 

Initial Sketches

Photo Mar 19, 5 54 24 PM

Photo Mar 19, 5 54 17 PM

Iteration 1 (Basic Structure)

Photo Mar 07, 4 19 45 PM

Iteration 2 (all parts working)

Photo Mar 18, 6 13 45 PM

Photo Mar 18, 6 13 29 PM

Iteration 3 (final prototype)

Photo Mar 18, 7 34 57 PM

Photo Mar 18, 7 34 54 PM

Finite State Machine

This finite state machine outlines the code that Poison Protector runs.  It has 3 basic states: default state, alert state, and end state.

fsm

Video of Final Prototype in Action

Video Mar 18, 7 35 49 PM

//motor pins
const int speedPin_M1 = 5;     //M1 Speed Control
const int speedPin_M2 = 6;     //M2 Speed Control
const int directionPin_M1 = 4;     //M1 Direction Control
const int directionPin_M2 = 7;     //M1 Direction Control

//gas pins
const int MQ4_AOUT = 0;
const int MQ7_AOUT = 1;

//infrared pins
const int INF1_AOUT = 2;
const int INF2_AOUT = 3;
const int INF3_AOUT = 4;

//speaker pin
const int SPEAKER_DIN = 3;

//limit ints
const int METHANE_LIMIT = 500;
const int CO_LIMIT = 500;
const int INF_LIMIT = 500;

//speed ints
const int lowSpeed = 60;
const int highSpeed = 100;

//vars for playing sound
int BassTab[]={1911,1702,1516,1431,1275,1136,1012};
int bassLen = 8;
int noteIndex = 0;
unsigned long lastPeriodStart = 0;
const int onDuration=1000;
const int periodDuration=1000;

//for driving
bool lastSeen; //true = right, false = left
bool startDrive = false;

//for stopping
int carStopCount = 0;
int numStops = 25;

//state maintinence
int STATE = 0;//0 = waiting, 1 = alert, 2 = wait for intervention

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

  //for speaker
  pinMode(SPEAKER_DIN,OUTPUT);
  digitalWrite(SPEAKER_DIN,LOW);
}

void loop(){
  int methaneVal = analogRead(MQ4_AOUT);
  int coVal = analogRead(MQ7_AOUT);

  //waiting state
  if (STATE == 0) {
    if (methaneVal > METHANE_LIMIT || coVal > CO_LIMIT) {
      STATE = 1; //if gas hits a certain level, change state
    }  
  }

  //alert state
  else if (STATE == 1) {
    //read values
    int inf1Val = analogRead(INF1_AOUT);
    int inf2Val = analogRead(INF2_AOUT);
    int inf3Val = analogRead(INF3_AOUT);

    //check if at least one infrared sensor read the line
    bool didSense = setDirection(inf1Val, inf2Val, inf3Val);
    if (!didSense) {
      carStopCount++;
      if (carStopCount > numStops) {
        STATE = 2; //after a certain number of times of no reads, change state
      }
    }
    //if value read, reset stop count
    else {
      carStopCount = 0;
    }
    sound(); //play sound
  }

  //waiting alarm state
  else if (STATE == 2) {
    carStop(); //stop car
    sound(); // continue sound
  }
  
  delay(50);  
}

//return false if nothing sensed, true otherwise
bool setDirection(int right, int middle, int left) {
  //set bools for each sensor
  bool r,m,l;
  r = m = l = false;
  if (right > INF_LIMIT) r = true;
  if (left > INF_LIMIT) l = true;
  if (middle > INF_LIMIT) m = true;

  if (r && !l) {
    guideLeft();
  }
  else if (l && !r) {
    guideRight();
  }
  else if (!l && !r && !m) {
    return false;
  }
  else {
    guideStraight();
  }
  return true;
}

void guideRight() {
  carAdvance(highSpeed, lowSpeed);
}

void guideLeft() {
  carAdvance(lowSpeed, highSpeed);
}

void guideStraight() {
  carAdvance(highSpeed, highSpeed);
}

void sound(){
  if (millis() - lastPeriodStart >= periodDuration) {
    lastPeriodStart += periodDuration;
    tone(SPEAKER_DIN, BassTab[noteIndex], onDuration);
    noteIndex ++;
    if (noteIndex == bassLen) noteIndex = 0;
  }
}

void carStop(){                 //  Motor Stop
  digitalWrite(speedPin_M2,0); 
  digitalWrite(directionPin_M1,LOW);    
  digitalWrite(speedPin_M1,0);   
  digitalWrite(directionPin_M2,LOW);    
}   

void carBack(int leftSpeed,int rightSpeed){         //Move backward
  analogWrite (speedPin_M2,leftSpeed);              //PWM Speed Control
  digitalWrite(directionPin_M1,HIGH);    
  analogWrite (speedPin_M1,rightSpeed);    
  digitalWrite(directionPin_M2,HIGH);
} 

void carAdvance(int leftSpeed,int rightSpeed){       //Move forward
  analogWrite (speedPin_M2,leftSpeed);
  digitalWrite(directionPin_M1,LOW);   
  analogWrite (speedPin_M1,rightSpeed);    
  digitalWrite(directionPin_M2,LOW);
}

void carTurnLeft(int leftSpeed,int rightSpeed){      //Turn Left
  analogWrite (speedPin_M2,leftSpeed);
  digitalWrite(directionPin_M1,LOW);    
  analogWrite (speedPin_M1,rightSpeed);    
  digitalWrite(directionPin_M2,HIGH);
}
void carTurnRight(int leftSpeed,int rightSpeed){      //Turn Right
  analogWrite (speedPin_M2,leftSpeed);
  digitalWrite(directionPin_M1,HIGH);    
  analogWrite (speedPin_M1,rightSpeed);    
  digitalWrite(directionPin_M2,LOW);
}

Assignment 4a

timg-3I got inspiration for my drawing robot from a form of Chinese art called “Dishu” (地书). Artists use Chinese calligraphy brush pens and water, instead of ink, to write on the ground. I was really impressed when I saw a professor performed “Dishu” on the 8th floor last semester. Hence it became my initial incentive to build a robot that can draw. Based on my previous deliverables, I decided to use light sensors to control the direction of the robot and the ultrasonic sensor to prevent it from the obstacles. It will act accordingly to whatever information it get from those sensors.

TA&NL Final Documentation — Triangulord

Here is our final presentation of the robot, Triangulord.

TA&NL Robotics Final Presentation

Process Videos

Final Deliverable: “Drawbot”

Material list:

    • Arduino Uno *1
    • Plastic structure *4
    • Caster wheel *1
    • Rubber wheel *2
    • Motor *2
    • Cell box *1
    • Battery *5
    • Servo Motor *1
    • Switch button *1
    • Bread board *1
    • Light sensor *2
    • Ultrasonic sensor *1
    • Marker *1
    • White Board *1

Intro and Background Story:

I got inspiration for my drawing robot from a form of Chinese art called “Dishu” (地书). Artists use Chinese calligraphy brush pens and water, instead of ink, to write on the ground. I was really impressed when I saw a professor performed “Dishu” on the 8th floor last semester. Hence it became my initial incentive to build this robot that can draw. Based on my previous deliverables, I decided to use light sensors to control the direction of the robot and the ultrasonic sensor to prevent it from the obstacles. It is worth mentioning that my idea has been evolving since the beginning. For example, I have changed the main structure, the drawing tool, and even the pattern of drawing for several times. Finally, I ended up making a robot that was inconsistent with initial assumption. Yet I do not think this is necessarily a bad thing. In fact, under the help pf professor Rodolfo and other IMA fellows, I really enjoyed this process of constantly revising and polishing my robot. I am glad to see some self-improvement that came together with making the robot and I believe all the effort and time that I spent on this project is worth it.

Diagram:

In the process of revising the diagram, I was able to get a much deeper understanding of my robot as well as the logic hidden in it. It took me quite a lot of time testing and debugging, especially for the if conditions. Yet every time I found the mistake, I got a clearer image of how my robot would be working perfectly.WechatIMG5

Sketch:

Front view sketch 1 (below)

FullSizeRender 2

Front view sketch 2 (below)

WechatIMG7

Top view sketch 1 (below)

FullSizeRender

Top view sketch 2 (below)

WechatIMG6

Professor Rodolfo suggested that I should came up with a detailed, multi-dimensioned sketch before I started to make the robot. Hence, these sketches actually predated the initial form of the robot. And it works very well! Those sketches really helped me to make a blueprint for my project. My idea kept evolving since the beginning. Thus it was much easier for me to revise the sketch than making actual changes to the robot’s physical structure, as is shown in the uploaded pictures. My final design was a quadrate-shaped robot, with an extended rubber wheel on each side, and a caster ball in the front. Two big motors are attached to the rubber wheels so that the robot is strong enough to impel the marker to draw. The triangular-structure of three wheels also enables the robot to move freely. Above the caster ball is the breadboard, with a light sensor on each side. On the back side , I put the cell box and batteries there. The Arduino uno is on the upper layer of the batteries, attached with a servo motor. On the front side of the Arduino uno is the ultrasonic sensor.

 

Code1:

//This is the code that enables “Drawbot” to draw straight lines and circles according to order it receives.

#include <Ultrasonic.h>

int distance;

Ultrasonic ultrasonic(3);
const int speedPin_M1 = 5; //M1 Speed Control
const int speedPin_M2 = 6; //M2 Speed Control

const int directionPin_M1 = 4; //M1 Direction Control
const int directionPin_M2 = 7; //M2 Direction Control

const int LDR1 = A1; // Analog input pin that the potentiometer is attached to
const int LDR2 = A0; // Analog input pin that the potentiometer is attached to
int light1;
int light2;

#include <Servo.h>
Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards
int pos = 0; // variable to store the servo position

void setup()
{
Serial.begin(9600);
Serial.println(“start “);
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}

/* the main loop is a test of the smooth function. It generates a simulated square wave and then
switches in four different smoothing values. Watch the numbers scroll by as the filter value
slows down the response. */

void loop() {
light1 = analogRead(LDR1); //left
Serial.print(“left:”);
Serial.println(light1);
light2 = analogRead(LDR2); //right
Serial.print(“right:”);
Serial.println(light2);
ultrasonic.MeasureInCentimeters();
distance = ultrasonic.RangeInCentimeters;
Serial.print(“distance:”);
Serial.println(distance);

if (distance < 15) {
carStop();
Serial.println(“Stopping…”);
}

else {
if (light1 > 900 || light2 > 900) {
if (light1 > light2) {
carTurnLeft( 70, 70);
Serial.println(“Turning left…”);}
else if (light1 < light2) {
carTurnRight( 70, 70);
Serial.println(“Turning right…”);}

} else {carAdvance( 100, 100);
Serial.println(“Going FWD…”);}
}

delay(500);

}

void carStop() { // Motor Stop
digitalWrite(speedPin_M2, 0);
digitalWrite(directionPin_M1, LOW);
digitalWrite(speedPin_M1, 0);
digitalWrite(directionPin_M2, LOW);
}

void carBack(int leftSpeed, int rightSpeed) { //Move backward
analogWrite (speedPin_M2, leftSpeed); //PWM Speed Control
digitalWrite(directionPin_M1, HIGH);
analogWrite (speedPin_M1, rightSpeed);
digitalWrite(directionPin_M2, HIGH);
}

void carAdvance(int leftSpeed, int rightSpeed) { //Move forward
analogWrite (speedPin_M2, leftSpeed);
digitalWrite(directionPin_M1, LOW);
analogWrite (speedPin_M1, rightSpeed);
digitalWrite(directionPin_M2, LOW);
}

void carTurnLeft(int leftSpeed, int rightSpeed) { //Turn Left
analogWrite (speedPin_M2, leftSpeed);
digitalWrite(directionPin_M1, LOW);
analogWrite (speedPin_M1, rightSpeed);
digitalWrite(directionPin_M2, HIGH);
}

void carTurnRight(int leftSpeed, int rightSpeed) { //Turn Right
analogWrite (speedPin_M2, leftSpeed);
digitalWrite(directionPin_M1, HIGH);
analogWrite (speedPin_M1, rightSpeed);
digitalWrite(directionPin_M2, LOW);
}

The Final Revision:

After showing the above-mentioned robot to Professor Rodolfo, he asked me to further think about the meaning of the project, for example, in what scenarios would people use it? What is the point of having a drawing robot instead of drawing ourselves? Those questions never came to me before so I started to think about them.  Then I thought of spirographe, a toy that I love to play when I was a kid. I began to think that, what if my “Drawbot” can draw more complicated patterns instead of lines and circles? Under the help of Jack Du, I started to revise my code. Below is the final code that I have for this project.

Final Code:

//This is the code that enables “Drawbot” to draw certain patterns. I can also change the pattern it draw by playing with the code.

#include <Ultrasonic.h>

int distance;

Ultrasonic ultrasonic(3);
const int speedPin_M1 = 5; //M1 Speed Control
const int speedPin_M2 = 6; //M2 Speed Control

const int directionPin_M1 = 4; //M1 Direction Control
const int directionPin_M2 = 7; //M2 Direction Control

const int LDR1 = A1; // Analog input pin that the potentiometer is attached to
const int LDR2 = A0; // Analog input pin that the potentiometer is attached to
int light1;
int light2;
int t;

#include <Servo.h>
Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards
int pos = 0; // variable to store the servo position

void setup()
{
Serial.begin(9600);
Serial.println(“start “);
myservo.attach(9); // attaches the servo on pin 9 to the servo object
t = 0;
}

void loop() {
light1 = analogRead(LDR1); //left
Serial.print(“left:”);
Serial.println(light1);
light2 = analogRead(LDR2); //right
Serial.print(“right:”);
Serial.println(light2);
ultrasonic.MeasureInCentimeters();
distance = ultrasonic.RangeInCentimeters;
Serial.print(“distance:”);
Serial.println(distance);
if (distance < 20) {
carStop();
Serial.println(“Stopping…”);
}
else {
if (light1 > 900 || light2 > 900) {
if (light1 > light2) {
carTurnRight( 200, 200);
Serial.println(“Turning right…”);}
else if (light1 < light2) {
carTurnLeft( 200, 200);
Serial.println(“Turning left…”);}

} else {
t=t+50;
carAdvance(100, 100);
delay(t);
carTurnLeft(100, 100);
delay(500);
Serial.println(“Going in pattern ↖(^ω^)↗ “);
}
}
}
void carStop() { // Motor Stop
digitalWrite(speedPin_M2, 0);
digitalWrite(directionPin_M1, LOW);
digitalWrite(speedPin_M1, 0);
digitalWrite(directionPin_M2, LOW);
}

void carBack(int leftSpeed, int rightSpeed) { //Move backward
analogWrite (speedPin_M2, leftSpeed); //PWM Speed Control
digitalWrite(directionPin_M1, HIGH);
analogWrite (speedPin_M1, rightSpeed);
digitalWrite(directionPin_M2, HIGH);
}

void carAdvance(int leftSpeed, int rightSpeed) { //Move forward
analogWrite (speedPin_M2, leftSpeed);
digitalWrite(directionPin_M1, LOW);
analogWrite (speedPin_M1, rightSpeed);
digitalWrite(directionPin_M2, LOW);
}

void carTurnLeft(int leftSpeed, int rightSpeed) { //Turn Left
analogWrite (speedPin_M2, leftSpeed);
digitalWrite(directionPin_M1, HIGH);
analogWrite (speedPin_M1, rightSpeed);
digitalWrite(directionPin_M2, LOW);
}

void carTurnRight(int leftSpeed, int rightSpeed) { //Turn Right
analogWrite (speedPin_M2, leftSpeed);
digitalWrite(directionPin_M1, LOW);
analogWrite (speedPin_M1, rightSpeed);
digitalWrite(directionPin_M2, HIGH);
}

void carGoPattern(int leftSpeed, int rightSpeed) { //Go in Pattern
analogWrite (speedPin_M2, leftSpeed);
digitalWrite(directionPin_M1, HIGH);
analogWrite (speedPin_M1, rightSpeed);
digitalWrite(directionPin_M2, LOW);
}

Sarabi: Robotics Deliverable 6 || Working Prototype and Refined Presentation

Introduction

My robot, whose name is Aggressive, is fundamentally an antisocial creature. I have so little space to call my own that I tend to be rather territorial of it, so my robot will “protect” it’s space. If left undisturbed, Aggressive “wanders” within the bounds of it’s area (demarcated by dark tape), but once it registers someone within that space, Aggressive will chase the intruder away. In a way, the robot is something like a guard dog. It protects its home. If given someone to take care of (i.e. Shanelle’s Passive), then Aggressive will take care of its space while also looking out for the well being of Passive. IR reflective sensors help Aggressive sense when it has reached the boundaries of its home, while ultrasonic range sensors detect when an intruder arrives. Communication between Passive and Aggressive will be wireless. Arms, made with servo motors, help “scare” the intruder away.

Parts

4 Ultrasonic range finders,1 IR reflective sensor, 2 servo motors, 4 wheels, metal chassis, MDF body, cardboard arms,  tons of wires, 5 AA Batteries, breadboard, glue, drill, screws

Circuit Diagram

IMG_20170319_232705_HDR

Finite State MachineIMG_20170319_232644_HDR

#include <Ultrasonic.h>

Ultrasonic Front(3); //UR sig pin (echo/nc is on 4)
int FDistance = analogRead(4);

const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
const int analogOutPin = 12; // Analog output pin that the LED is attached to
int sensorValue = 0;        // value read from the pot
int outputValue = 0;        // value output to the PWM (analog out)


int speedPin_M1 = 5;     //M1 Speed Control
int speedPin_M2 = 6;     //M2 Speed Control
int directionPin_M1 = 4;     //M1 Direction Control
int directionPin_M2 = 7;     //M1 Direction Control

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

void loop() {
  long FDistance;
  FDistance = Front.MeasureInCentimeters();

  switch (FDistance) {
    case 1: //intruder
      if (FDistance < 200) { //Fdistance = distance from front sensor
        carAdvance(100, 100);
      }
      break;
    case empty:
      if (FDistance > 200) {
        carWander();
      }
      break;
    case boundary: {
        sensorValue = analogRead(analogInPin);
        analogWrite(analogOutPin, outputValue);

        if (analogRead(A0) < 200) {
          Serial.println("clear");
          carAdvance(250, 250);
        } else if (analogRead(A0) > 200) {
          Serial.println("OUT OF BOUNDS");
          carStop();
          delay(10);
          carBack(100, 100);
          delay(1000);
          carTurnLeft(100, 100);
          delay(1000);
          carAdvance(250, 250);
        }
      }
      break;
    default: carWander();
  }

  void carSee() {
    // two measurements should keep an interval
    long RangeInCentimeters;
    RangeInCentimeters = Front.MeasureInCentimeters(); // two measurements should keep an interval
    Serial.print(RangeInCentimeters);//0~400cm
    Serial.println(" cm");
    delay(250);

    analogWrite(analogOutPin, outputValue);

    if (analogRead(IRAnalog) < 200) {
      Serial.println("clear");
    }


  }

  void carStop() {                //  Motor Stop
    digitalWrite(speedPin_M2, 0);
    digitalWrite(directionPin_M1, LOW);
    digitalWrite(speedPin_M1, 0);
    digitalWrite(directionPin_M2, LOW);
  }
  void carBack(int leftSpeed, int rightSpeed) {       //Move backward
    analogWrite (speedPin_M2, leftSpeed);             //PWM Speed Control
    digitalWrite(directionPin_M1, HIGH);
    analogWrite (speedPin_M1, rightSpeed);
    digitalWrite(directionPin_M2, HIGH);
  }
  void carAdvance(int leftSpeed, int rightSpeed) {     //Move forward
    analogWrite (speedPin_M2, leftSpeed);
    digitalWrite(directionPin_M1, LOW);
    analogWrite (speedPin_M1, rightSpeed);
    digitalWrite(directionPin_M2, LOW);
  }
  void carTurnLeft(int leftSpeed, int rightSpeed) {    //Turn Left
    analogWrite (speedPin_M2, leftSpeed);
    digitalWrite(directionPin_M1, LOW);
    analogWrite (speedPin_M1, rightSpeed);
    digitalWrite(directionPin_M2, HIGH);
  }
  void carTurnRight(int leftSpeed, int rightSpeed) {    //Turn Right
    analogWrite (speedPin_M2, leftSpeed);
    digitalWrite(directionPin_M1, HIGH);
    analogWrite (speedPin_M1, rightSpeed);
    digitalWrite(directionPin_M2, LOW);
  }

  void carWander() {

    carAdvance(250, 250);
    delay(2000);
    carTurnLeft(250, 250);
    delay(1000);
    carAdvance(250, 250);
    delay(2000);
    carTurnRight(250, 250);
    delay(1000);

  }

  void carChase() {
    carAdvance(100, 100);
    delay(50);
    unsigned int uS = sonar.ping_cm();
  }


IR: Deliverable 5 – TA & NL

Materials:

  • 3   –  Ultrasonic Rangefinder
  • 6   –  Light-Dependant Resistor
  • 12 – LEDs
  • 3   – Encoder Motors
  • 3   – Omniwheels
  • 1   – 7.9V Lithium Ion Battery
  • 3   – 3V Coin Batteries
  • 3   – NPN Transistors
  • 1   – DFRduino Romeo
  • 1   – Motordriver board
  • X   – Structural materials (laser-cut frame, screws and nuts, 3D-printed braces, etc.)

Story of Triangulord the Partybot:

Triangulord, so named for his triangular shape, loves to dance.  However, he only likes to dance in the dark, so he will seek out dark places before dancing.  When he finds a suitably dark location, he lights up and starts dancing.  Of course, Triangulord doesn’t want to bump into anything while he’s dancing or looking for a dark place, so he’ll avoid any object that gets too close.

Control System:

IMG_3628

Signal Processing:

/*
  HC-SR04 Ping distance sensor:
  VCC to arduino 5v
  GND to arduino GND
  Echo to Arduino pin 9
  Trig to Arduino pin 8*/
#define echopin1 9 // echo pin
#define trigpin1 8 // Trigger pin
#define echopin2 6 // echo pin
#define trigpin2 7 // Trigger pin


long duration1, distance1, duration2, distance2;

void setup() {
  Serial.begin (9600);
  pinMode (trigpin1, OUTPUT);
  pinMode (echopin1, INPUT );
  
  pinMode (trigpin2, OUTPUT);
  pinMode (echopin2, INPUT );
  pinMode (4, OUTPUT);
  pinMode (13, OUTPUT);
}
void loop ()
{

  digitalWrite(trigpin1, LOW);
  digitalWrite(trigpin2, LOW);
  delayMicroseconds(2);
  digitalWrite(trigpin1, HIGH);
  digitalWrite(trigpin2, HIGH);
  delayMicroseconds(10);
  duration1 = pulseIn (echopin1, HIGH);
  duration2 = pulseIn (echopin2, HIGH);
  distance1 = duration1 / 28.2;
  distance2 = duration2 / 28.2;
  delay (50);
  Serial.println(distance1);
  Serial.println(distance2);
  Serial.println(analogRead(A0));
  Serial.println(analogRead(A1));
  Serial.println();


    Serial.println(distance);
    if (distance >= 25 ) {
      digitalWrite (4, HIGH);
      digitalWrite (13, HIGH);
    }
    else if (distance <= 10) {
      digitalWrite (4, LOW);
      digitalWrite (13, LOW);
    }
}