本帖最后由 dvd1478 于 2016-7-5 23:24 编辑
Landzo C1试用体验】自行停车(总结)
https://bbs.elecfans.com/jishu_909558_1_1.html
(出处: 中国电子技术论坛)
说过模块比较少,做的东西比较少。但实际上并不是,决定是思维,思维能多开拓,创造就有多远。
从外文网站看到的, 决定分享到这里。就是用超声波+舵机+processing 做的一个超声波雷达
【Landzo C1试用体验】超声测距离
https://bbs.elecfans.com/jishu_909545_1_1.html
【Landzo C1申请】舵机
https://bbs.elecfans.com/jishu_900803_1_1.html
先上个效果图
Arduino 代码
- #include
- #include
- //#include
- #include
- #include "MotorDC.h"
- //const int ledPinRed = 7;
- const int ledPinGreen = A0;
- Servo myservo; //创建一个舵机控制对象
- // 使用Servo类最多可以控制8个舵机
- int pos = 0; // 该变量用与存储舵机角度位置
- MotorDC motorLeft(3,5);//DC motor Control
- MotorDC motorRight(6,11);
- #define RECV_PIN 9
- IRrecv irrecv(RECV_PIN);//IRremote
- decode_results results;
- unsigned long _ABVAR_1_control = 0UL ;
- #if 0
- #define TRIGGER_PIN 7 // Arduino pin tied to trigger pin on the ultrasonic sensor.
- #define ECHO_PIN 8 // Arduino pin tied to echo pin on the ultrasonic sensor.
- #define MAX_DISTANCE 500 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
- NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
- #endif
- #define TRIG_PIN 7
- #define ECHO_PIN 8
- SR04 sr04 = SR04(ECHO_PIN,TRIG_PIN);
- const int numReadings = 2;
- long readings[numReadings]; // the readings from the analog input
- int readIndex = 0; // the index of the current reading
- long total = 0; // the running total
- long averageDistance = 0; // the average
- void run_led(void)
- {
- //digitalWrite(ledPinRed, LOW);//亮
- digitalWrite(ledPinGreen, HIGH);//暗
- }
- void stop_led(void)
- {
- digitalWrite(ledPinGreen, LOW);//亮
- //digitalWrite(ledPinRed, HIGH);//暗
- }
- long unsigned int return_decode() {
- if (irrecv.decode(&results)) {
- irrecv.resume(); // 接收下一个值
- return results.value;
- } else {
- return 0;
- irrecv.resume(); // 接收下一个值
- }
- }
- long get_distance(void )
- {
- #if 1
- // subtract the last reading:
- total = total - readings[readIndex];
- // read from the sensor:
- readings[readIndex] = sr04.Distance();
- if(readings[readIndex]>900) //for error
- readings[readIndex] = averageDistance;
- // add the reading to the total:
- total = total + readings[readIndex];
- // advance to the next position in the array:
- readIndex = readIndex + 1;
- // if we're at the end of the array...
- if (readIndex >= numReadings)
- // ...wrap around to the beginning:
- readIndex = 0;
- // calculate the averageDistance:
- averageDistance = total / numReadings;
- #endif
- #if 0
- Serial.print("Ping: ");
- Serial.print(averageDistance); // Send ping, get distance in cm and print result (0 = outside set distance range)
- Serial.println("cm");
- #endif
- return averageDistance;
- }
- void get_stop(void)
- {
- long distance = get_distance();
- run_led();
- motorLeft.setSpeed(255);
- motorRight.setSpeed(255);
- while(distance > 20)
- {
- distance = get_distance();
- delay( 80 );//mx
- }
- motorLeft.setSpeed(0);
- motorRight.setSpeed(0);
- stop_led();
- }
- void setup() {
- Serial.begin(9600);
- //pinMode(ledPinRed, OUTPUT);
- pinMode(ledPinGreen, OUTPUT);
- // put your setup code here, to run once:
- myservo.attach(10); // 该舵机由arduino第10脚控制
- #if 0
- for(pos = 90; pos < 180; pos += 1) { // 从0度到180度运动
- // 每次步进一度
- myservo.write(pos); // 指定舵机转向的角度
- delay(15); // 等待15ms让舵机到达指定位置
- }
- for(pos = 180; pos>=1; pos-=1) { //从180度到0度运动
- myservo.write(pos); // 指定舵机转向的角度
- delay(15); // 等待15ms让舵机到达指定位置
- }
- for(pos = 0; pos < 90; pos += 1) { // 从0度到180度运动
- // 每次步进一度
- myservo.write(pos); // 指定舵机转向的角度
- delay(15); // 等待15ms让舵机到达指定位置
- }
- #endif
- //myservo.detach();
- pinMode(RECV_PIN,INPUT);//设置红外接收引脚为输入
- irrecv.enableIRIn(); //允许接收红外遥控
- motorLeft.setSpeed(0);
- motorRight.setSpeed(0);
- // initialize all the readings to 0:
- for (int thisReading = 0; thisReading < numReadings; thisReading++)
- readings[thisReading] = 0;
- }
- void loop() {
- long distance = 0;
- for(pos= 0; pos<180; pos++){
- myservo.write(pos);
- delay(30);
- distance = get_distance();
- distance = get_distance();
- Serial.print("X");
- Serial.print(pos);
- Serial.print("V");
- Serial.println(distance);
- }
- for(pos= 180; pos>0; pos--){
- myservo.write(pos);
- delay(30);
- distance = get_distance();
- distance = get_distance();
- Serial.print("X");
- Serial.print(pos);
- Serial.print("V");
- Serial.println(distance);
- }
- //delay(200); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
- }
复制代码
Processing 代码
- 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
- printArray(Serial.list());// List all the available serial ports
- 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 QQ 1696933323", 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) {
- try{
- String xString = myPort.readStringUntil('n'); // read the serial port until a new line
- if (xString != null) { // if theres data in between the new lines
- //print(xString);
- 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
- }
- }
- }
- catch(RuntimeException e) {
- println("caught error parsing data:");
- e.printStackTrace();
- }
- }
复制代码
Arduino 与 Processing代码
|