Hardware need:
1. Arduino Pro Mini
2. Ultrasonic sensor HC-SR04
3. Servo motor SG90
Step 1. Ultrasonic sensor
This sensor use ultrasonic to measure distance to object. Distance detected range is 2cm to 400cm
At beginning startup, it needs time to warm up (about 1min) in order working well with Arduino
// Sets the trigPin on HIGH state for 10 micro seconds digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // Reads the echoPin, returns the sound wave travel time in microseconds duration = pulseIn(echoPin, HIGH, 23529); //23529us for timeout 4.0m // Calculating the distance distance= duration*0.034/2;
Step 2. Servo motor:
Servo motor SG90 also an easy part, it can rotate to exact angle appointed by code:
servo.write(servoAngle);
Step 3. Hardware installation & circuit
Use MDF 3mm, cut out by laser cut to make base for sensor, then connect to servo motor
Step 4. Arduino code
#include <Servo.h> const int servoPin = 9; const int trigPin = 17; //ultrasonic const int echoPin = 16; //ultrasonic Servo servo; int servoAngle = 0; // servo position in degrees long duration; int distance; void setup() { pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output pinMode(echoPin, INPUT); // Sets the echoPin as an Input Serial.begin(9600); servo.attach(servoPin); } void loop() { // Clears the trigPin, ultrasonic digitalWrite(trigPin, LOW); delayMicroseconds(2); for(servoAngle = 120; servoAngle > 0; servoAngle--) //now move back the micro servo from 120 degrees to 0 degrees { servo.write(servoAngle); delay(20); // Sets the trigPin on HIGH state for 10 micro seconds digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // Reads the echoPin, returns the sound wave travel time in microseconds duration = pulseIn(echoPin, HIGH, 23529); //23529us for timeout 4.0m // Calculating the distance distance= duration*0.034/2; Serial.print("servoAngle (dg): "); if (servoAngle <10) Serial.print("0"); if (servoAngle <100) Serial.print("0"); Serial.print(servoAngle); Serial.print(" "); Serial.print("Distance (cm): "); if (distance <10) Serial.print("0"); if (distance <100) Serial.print("0"); if (distance <1000) Serial.print("0"); Serial.println(distance); } for(servoAngle = 0; servoAngle < 120; servoAngle++) //now move back the micro servo from 0 degrees to 120 degrees { servo.write(servoAngle); delay(20); // Sets the trigPin on HIGH state for 10 micro seconds digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // Reads the echoPin, returns the sound wave travel time in microseconds duration = pulseIn(echoPin, HIGH, 23529); //23529us for timeout 4.0m // Calculating the distance distance= duration*0.034/2; Serial.print("servoAngle (dg): "); if (servoAngle <10) Serial.print("0"); if (servoAngle <100) Serial.print("0"); Serial.print(servoAngle); Serial.print(" "); Serial.print("Distance (cm): "); if (distance <10) Serial.print("0"); if (distance <100) Serial.print("0"); if (distance <1000) Serial.print("0"); Serial.println(distance); } }
Step 5. Visual Studio code
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { serialPort1->Open(); timer1->Start(); mStr = ""; r = 10; distance = gcnew array< Int32 >(360); } private: System::Void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e) { try { mStr=serialPort1->ReadLine(); } catch (IO::IOException^ e){ //do nothing. This try-catch to prvent error //when close program while receiving data from COM-port } if(mStr->Length >= 41) { if(mStr->Substring(0,10) == "servoAngle"){ distance[Convert::ToInt32(mStr->Substring(17,3))+30] = Convert::ToInt32(mStr->Substring(36,4)); current_pos = Convert::ToInt32(mStr->Substring(17,3))+30; } } } private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) { Graphics^ g = pictureBox1->CreateGraphics(); g->Clear(Color::WhiteSmoke); Pen^ redPen = gcnew Pen(Color::Red); redPen->Width = 2; Pen^ bluPen = gcnew Pen(Color::Blue); bluPen->Width = 5; Pen^ grePen = gcnew Pen(Color::Green); grePen->Width = 2; int x = 400; //x-axis of center int y = 50; //y-axis of center g->DrawLine(grePen, x-300, y, x+300, y); g->DrawArc(grePen, x-300, y-300, 600, 600, 0, 180); g->DrawArc(grePen, x-150, y-150, 300, 300, 0, 180); g->DrawArc(grePen, x-75, y-75, 150, 150, 0, 180); g->DrawArc(grePen, x-37, y-37, 75, 75, 0, 180); for (i = 30; i<150; i++) { r = distance[i]; if (r<=0) r=300; if (i!=current_pos){ g->DrawLine(redPen, x, y, x+r*Math::Cos(i*3.1416/180), y+r*Math::Sin(i*3.1416/180)); } else{ g->DrawLine(bluPen, x, y, x+r*Math::Cos(i*3.1416/180), y+r*Math::Sin(i*3.1416/180)); } label5->Text="Angle: "+current_pos+" degree"; if (distance[current_pos]>0){ label6->Text="Distance: "+distance[current_pos]+" cm"; } else{ label6->Text="Distance: 300 cm"; } } }
Entire code can be found here (google share link)
Result video
0 Comments: