بــــسم الله الرحمن الرحيــــم
لتكون على استعداد دائماً لحماية نفسك من طائرات الاعداء , أو غـزو الكائنات الفضائية :) سنقوم في هذه التجربة بعمل رادار خاص بك و بعدة اشكال !.
ماذا نحتاج ؟
• اردوينو ( اي نوع ) .
• اردوينو ( اي نوع ) .
• محرك سيرفو .
• حساس ألتراسونيك .
• لوحة تجارب مثقبة .
• برمجية processing .
( البرمجية متوفرة بشكل مجاني من هــنــا )
نقوم بتثبيت الحساس على المحرك , و نوصل الاسلاك حسب الصورة .
echoPin موصول مع المدخل 7 في الاردوينو. trigPin موصول مع المدخل 8 في الاردوينو.
servo موصول مع المدخل 9 في الاردوينو .
شكل الدارة النهائي :
سيقوم الاردوينو بتحريك محرك السيرفو بدرجات معينة ( و بالتالي يتحرك الحساس ) وقياس المسافة عند تلك الزاوية , ثم ارسال هذه البيانات لبرنامج processing ( عبر السيريال ) ليعرضعها باشكال مختلفة .
برمجية processing تمكنك من برمجة الرسوم و الصور المتحركة و هي تشبه برمجية الاردوينو ( واجهة برنامج الاردوينو صممت بالاعتماد على هذا البرنامج ) و لغة البرمجة (C/C++) . يمكنك التعرف عليها اكثر من خلال الموقع الرسمي .
برمجية processing تمكنك من برمجة الرسوم و الصور المتحركة و هي تشبه برمجية الاردوينو ( واجهة برنامج الاردوينو صممت بالاعتماد على هذا البرنامج ) و لغة البرمجة (C/C++) . يمكنك التعرف عليها اكثر من خلال الموقع الرسمي .
البرمجة :
يمكن برمجة عدة اشكال للرادار , هذة بعض الاشكال :
• الشكل الاول :
شـــاهد :
- طول و لون الخط يمثل بعد الاجسام .
- يمكن زيادة سرعة دوران المحرك بالضغط على الشاشة .
__________ كود الاردوينو __________
#include <Servo.h>
Servo servo1;
static const int minAngle = 0;
static const int maxAngle = 180;
int servoAngle;
int servoPos;
int servoPin = 9;
#define echoPin 7
#define trigPin 8
#define LEDPin 13
long duration;
long HR_dist=0;
int HR_angle=0;
int HR_dir=1;
int minimumRange=2;
int maximumRange=500;
/*--------------------SETUP()------------------------*/
void setup() {
Serial.begin (9600);
servo1.attach(servoPin);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(LEDPin, OUTPUT);
}
/*----------------------LOOP()--------------------------*/
void loop() {
if (Serial.available()) {
HR_angle = Serial.parseInt();
if(HR_angle>-1){
servoPos = constrain(map(HR_angle, 0,180,minAngle,maxAngle),minAngle,maxAngle);
servo1.write(servoPos);
getDistance();
}
}
}
/*--------------------getDistance() FUNCTION ---------------*/
void getDistance(){
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
HR_dist = duration/58.2;
if (HR_dist >= maximumRange || HR_dist <= minimumRange){
Serial.println("0");
digitalWrite(LEDPin, HIGH);
} else {
Serial.println(HR_dist);
digitalWrite(LEDPin, LOW);
}
}
______________________________
_______ processing code ________
import processing.serial.*; int distance; int angle=0; int direction=1; int[] alphaVal = new int[100]; int[] distance2 = new int[100]; int lineSize = 4; String comPortString; Serial comPort; /*---------------------SETUP---------------------------*/ void setup( ) { size(displayWidth,displayHeight); smooth(); background(0); comPort = new Serial(this, "COM9", 9600); // ضع رقم المنفذ الموصول مع الاردوينو •••• comPort.bufferUntil('\n'); for(int i=0; i<91; i++){ alphaVal[i] = 0; } } /*---------------------DRAW-----------------*/ void draw( ) { background(0); for(int i=0; i<91; i++){ alphaVal[i]=alphaVal[i]-4; if(alphaVal[i]<0){ alphaVal[i]=0; } stroke(255,distance2[i],0,alphaVal[i]); strokeWeight(2); line(width/2, height, (width/2)-cos(radians(i*2))*(distance2[i]*lineSize), height-sin(radians(i*2))*(distance2[i]*lineSize)); stroke(255); strokeWeight(1); ellipse((width/2)-cos(radians(i*2))*(distance2[i]*lineSize), height-sin(radians(i*2))*(distance2[i]*lineSize),5,5); } } void mousePressed(){ sendAngle(); } void serialEvent(Serial cPort){ comPortString = cPort.readStringUntil('\n'); if(comPortString != null) { comPortString=trim(comPortString); distance = int(map(Integer.parseInt(comPortString),1,200,1,height)); drawSonar(angle,distance); sendAngle(); } } /*---------------------------sendAngle() FUNCTION----------------*/ void sendAngle(){ comPort.write(angle+"."); angle=angle+(2*direction); if(angle>178||angle<1){ direction=direction*-1; } } /*-----------------sketchFullScreen(): Allows for FullScreen view------*/ boolean sketchFullScreen() { return true; } /*----------------- drawSonar(): update the line/dot positions---------*/ void drawSonar(int sonAngle, int newDist){ alphaVal[sonAngle/2] = 180; distance2[sonAngle/2] = newDist; }
_____________________________
• الشكل الثاني :
شــاهد :
__________ كود الاردوينو __________
#include <Servo.h> // include the standard servo library Servo leftRightServo; // set a variable to map the servo int leftRightPos = 0; // set a variable to store the servo position const int numReadings = 10; // set a variable for the number of readings to take int index = 0; // the index of the current reading int total = 0; // the total of all readings int average = 0; // the average int echoPin = 7; // the SRF05's echo pin int initPin = 8; // the SRF05's init pin unsigned long pulseTime = 0; // variable for reading the pulse unsigned long distance = 0; // variable for storing distance /* setup the pins, servo and serial port */ void setup() { leftRightServo.attach(9); // make the init pin an output: pinMode(initPin, OUTPUT); // make the echo pin an input: pinMode(echoPin, INPUT); // initialize the serial port: Serial.begin(9600); } /* begin rotating the servo and getting sensor values */ void loop() { for(leftRightPos = 0; leftRightPos < 180; leftRightPos++) { // going left to right. leftRightServo.write(leftRightPos); for (index = 0; index<=numReadings;index++) { // take x number of readings from the sensor and average them digitalWrite(initPin, LOW); delayMicroseconds(50); digitalWrite(initPin, HIGH); // send signal delayMicroseconds(50); // wait 50 microseconds for it to return digitalWrite(initPin, LOW); // close signal pulseTime = pulseIn(echoPin, HIGH); // calculate time for signal to return distance = pulseTime/58; // convert to centimetres total = total + distance; // update total delay(10); } average = total/numReadings; // create average reading if (index >= numReadings) { // reset the counts when at the last item of the array index = 0; total = 0; } Serial.print("X"); // print leading X to mark the following value as degrees Serial.print(leftRightPos); // current servo position Serial.print("V"); // preceeding character to separate values Serial.println(average); // average of sensor readings } /* start going right to left after we got to 180 degrees same code as above */ for(leftRightPos = 180; leftRightPos > 0; leftRightPos--) { // going right to left leftRightServo.write(leftRightPos); for (index = 0; index<=numReadings;index++) { digitalWrite(initPin, LOW); delayMicroseconds(50); digitalWrite(initPin, HIGH); delayMicroseconds(50); digitalWrite(initPin, LOW); pulseTime = pulseIn(echoPin, HIGH); distance = pulseTime/58; total = total + distance; delay(10); } average = total/numReadings; if (index >= numReadings) { index = 0; total = 0; } Serial.print("X"); Serial.print(leftRightPos); Serial.print("V"); Serial.println(average); } }
_____________________________
_______ processing code ________
import processing.serial.*; // import serial library
Serial myPort; // declare a serial port
float x, y; // variable to store x and y co-ordinates for vertices
int radius = 350; // set the radius of objects
int w = 300; // set an arbitary width value
int degree = 0; // servo position in degrees
int value = 0; // value from sensor
int motion = 0; // value to store which way the servo is panning
int[] newValue = new int[181]; // create an array to store each new sensor value for each servo position
int[] oldValue = new int[181]; // create an array to store the previous values.
PFont myFont; // setup fonts in Processing
int radarDist = 0; // set value to configure Radar distance labels
int firstRun = 0; // value to ignore triggering motion on the first 2 servo sweeps
/* create background and serial buffer */
void setup(){
// setup the background size, colour and font.
size(750, 450);
background (0); // 0 = black
myFont = createFont("verdana", 12);
textFont(myFont);
// setup the serial port and buffer
myPort = new Serial(this, Serial.list()[1], 9600);
myPort.bufferUntil('n');
}
/* draw the screen */
void draw(){
fill(0); // set the following shapes to be black
noStroke(); // set the following shapes to have no outline
ellipse(radius, radius, 750, 750); // draw a circle with a width/ height = 750 with its center position (x and y) set by the radius
rectMode(CENTER); // set the following rectangle to be drawn around its center
rect(350,402,800,100); // draw rectangle (x, y, width, height)
if (degree >= 179) { // if at the far right then set motion = 1/ true we're about to go right to left
motion = 1; // this changes the animation to run right to left
}
if (degree <= 1) { // if servo at 0 degrees then we're about to go left to right
motion = 0; // this sets the animation to run left to right
}
/* setup the radar sweep */
/*
We use trigonmetry to create points around a circle.
So the radius plus the cosine of the servo position converted to radians
Since radians 0 start at 90 degrees we add 180 to make it start from the left
Adding +1 (i) each time through the loops to move 1 degree matching the one degree of servo movement
cos is for the x left to right value and sin calculates the y value
since its a circle we plot our lines and vertices around the start point for everything will always be the center.
*/
strokeWeight(7); // set the thickness of the lines
if (motion == 0) { // if going left to right
for (int i = 0; i <= 20; i++) { // draw 20 lines with fading colour each 1 degree further round than the last
stroke(0, (10*i), 0); // set the stroke colour (Red, Green, Blue) base it on the the value of i
line(radius, radius, radius + cos(radians(degree+(180+i)))*w, radius + sin(radians(degree+(180+i)))*w); // line(start x, start y, end x, end y)
}
} else { // if going right to left
for (int i = 20; i >= 0; i--) { // draw 20 lines with fading colour
stroke(0,200-(10*i), 0); // using standard RGB values, each between 0 and 255
line(radius, radius, radius + cos(radians(degree+(180+i)))*w, radius + sin(radians(degree+(180+i)))*w);
}
}
/* Setup the shapes made from the sensor values */
noStroke(); // no outline
/* first sweep */
fill(0,50,0); // set the fill colour of the shape (Red, Green, Blue)
beginShape(); // start drawing shape
for (int i = 0; i < 180; i++) { // for each degree in the array
x = radius + cos(radians((180+i)))*((oldValue[i])); // create x coordinate
y = radius + sin(radians((180+i)))*((oldValue[i])); // create y coordinate
vertex(x, y); // plot vertices
}
endShape(); // end shape
/* second sweep */
fill(0,110,0);
beginShape();
for (int i = 0; i < 180; i++) {
x = radius + cos(radians((180+i)))*(newValue[i]);
y = radius + sin(radians((180+i)))*(newValue[i]);
vertex(x, y);
}
endShape();
/* average */
fill(0,170,0);
beginShape();
for (int i = 0; i < 180; i++) {
x = radius + cos(radians((180+i)))*((newValue[i]+oldValue[i])/2); // create average
y = radius + sin(radians((180+i)))*((newValue[i]+oldValue[i])/2);
vertex(x, y);
}
endShape();
/* if after first 2 sweeps, highlight motion with red circle*/
if (firstRun >= 360) {
stroke(150,0,0);
strokeWeight(1);
noFill();
for (int i = 0; i < 180; i++) {
if (oldValue[i] - newValue[i] > 35 || newValue[i] - oldValue[i] > 35) {
x = radius + cos(radians((180+i)))*(newValue[i]);
y = radius + sin(radians((180+i)))*(newValue[i]);
ellipse(x, y, 10, 10);
}
}
}
/* set the radar distance rings and out put their values, 50, 100, 150 etc.. */
for (int i = 0; i <=6; i++){
noFill();
strokeWeight(1);
stroke(0, 255-(30*i), 0);
ellipse(radius, radius, (100*i), (100*i));
fill(0, 100, 0);
noStroke();
text(Integer.toString(radarDist+50), 380, (305-radarDist), 50, 50);
radarDist+=50;
}
radarDist = 0;
/* draw the grid lines on the radar every 30 degrees and write their values 180, 210, 240 etc.. */
for (int i = 0; i <= 6; i++) {
strokeWeight(1);
stroke(0, 55, 0);
line(radius, radius, radius + cos(radians(180+(30*i)))*w, radius + sin(radians(180+(30*i)))*w);
fill(0, 55, 0);
noStroke();
if (180+(30*i) >= 300) {
text(Integer.toString(180+(30*i)), (radius+10) + cos(radians(180+(30*i)))*(w+10), (radius+10) + sin(radians(180+(30*i)))*(w+10), 25,50);
} else {
text(Integer.toString(180+(30*i)), radius + cos(radians(180+(30*i)))*w, radius + sin(radians(180+(30*i)))*w, 60,40);
}
}
/* Write information text and values. */
noStroke();
fill(0);
rect(350,402,800,100);
fill(0, 100, 0);
text("Degrees: "+Integer.toString(degree), 100, 380, 100, 50); // use Integet.toString to convert numeric to string as text() only outputs strings
text("Distance: "+Integer.toString(value), 100, 400, 100, 50); // text(string, x, y, width, height)
text("Radar screen code at ali-madness.blogspot.com", 540, 380, 250, 50);
fill(0);
rect(70,60,150,100);
fill(0, 100, 0);
text("Screen Key:", 100, 50, 150, 50);
fill(0,50,0);
rect(30,53,10,10);
text("First sweep", 115, 70, 150, 50);
fill(0,110,0);
rect(30,73,10,10);
text("Second sweep", 115, 90, 150, 50);
fill(0,170,0);
rect(30,93,10,10);
text("Average", 115, 110, 150, 50);
noFill();
stroke(150,0,0);
strokeWeight(1);
ellipse(29, 113, 10, 10);
fill(150,0,0);
text("Motion", 115, 130, 150, 50);
}
/* get values from serial port */
void serialEvent (Serial myPort) {
String xString = myPort.readStringUntil('n'); // read the serial port until a new line
if (xString != null) { // if theres data in between the new lines
xString = trim(xString); // get rid of any whitespace just in case
String getX = xString.substring(1, xString.indexOf("V")); // get the value of the servo position
String getV = xString.substring(xString.indexOf("V")+1, xString.length()); // get the value of the sensor reading
degree = Integer.parseInt(getX); // set the values to variables
value = Integer.parseInt(getV);
oldValue[degree] = newValue[degree]; // store the values in the arrays.
newValue[degree] = value;
/* sets a counter to allow for the first 2 sweeps of the servo */
firstRun++;
if (firstRun > 360) {
firstRun = 360; // keep the value at 360
}
}
}
_____________________________
• الشكل الثالث :
__________ كود الاردوينو __________
#define ECHOPIN 7 // Pin to receive echo pulse #define TRIGPIN 8 #include <Servo.h> Servo myservo; // create servo object to control a servo int pos = 0; // variable to store the servo position void setup() { Serial.begin(9600); myservo.attach(9); // attaches the servo on pin 9 to the servo object pinMode(3,OUTPUT); pinMode(12,OUTPUT); pinMode(13,INPUT); pinMode(ECHOPIN, INPUT); pinMode(TRIGPIN, OUTPUT); } void Print (int R , int T) { Serial.print(R);Serial.print(", "); Serial.print(T);Serial.println("."); delay(100); } float Distance () { digitalWrite(TRIGPIN, LOW); delayMicroseconds(2); digitalWrite(TRIGPIN, HIGH); delayMicroseconds(10); digitalWrite(TRIGPIN, LOW); // Distance Calculation float distance = pulseIn(ECHOPIN, HIGH); distance= distance/58; return(distance); } void loop() { myservo.write(45); // tell servo to go to position in variable 'pos' delay(2000); for(pos = 45; pos <= 135; pos += 3) // goes from 45 degrees to 135 degrees { // in steps of 1 degree myservo.write(pos); // tell servo to go to position in variable 'pos' Print(Distance() , pos); delay(10); // waits 15ms for the servo to reach the position } delay(1000); for(pos = 135; pos>=45; pos-=3) // goes from 135 degrees to 45 degrees { myservo.write(pos); // tell servo to go to position in variable 'pos' Print(Distance() , pos); delay(10); // waits 15ms for the servo to reach the position } }
_____________________________
_______ processing code ________
import processing.serial.*; Serial port; Serial port2; String data = ""; String Radius = ""; String Theta = ""; int index = 0; float distance = 0; float angle = 0; float pi = 22.0/7; void setup() { size(1000,1000); background(255,255,255); ellipse(500,500,1000,1000); line(500,0,500,1000); line(0,500,1000,500); line(500,500,1000,0); line(500,500,0,0); port = new Serial(this, "COM10", 9600); // ضع رقم المنفذ الموصول مع الاردوينو •••• port.bufferUntil('.'); } void draw() { } void serialEvent(Serial port) { data = port.readStringUntil('.'); data = data.substring(0, data.length() - 1); index = data.indexOf(","); Radius = data.substring(0, index); Theta = data.substring (index+1 , data.length()); translate(500,500); point (0,0); distance = float(Radius); angle = float(Theta) /180 * pi; fill(30,200,30); ellipse(distance * cos(angle) , -1 * distance * sin(angle) , 5,5); }
_____________________________
______________
المصادر :
• grook
روعة واكثر من روعة
ردحذف