marine77 发表于 2017-10-10 14:13:03

求助,3个超声波的避障小车,只有中间的超声波起作用

目前车子情况:能正常跑,但是只有中间的超声波有效果,2侧的都无效,也可以理解为IO 接口只有8和9有效。
我把3个超声波的VCC都接到了一起,接入板子的5V;把超声波GND也接到了一起,接入板子的GND; TRIGPIN 和ECHOPIN 都是按照程序上的接口接的,不会有错。

超声波接线:
#define TRIGPIN_LEFT 10
#define ECHOPIN_LEFT 11                  //左侧超声波
#define TRIGPIN_MID 8
#define ECHOPIN_MID 9                        //中间超声波
#define TRIGPIN_RIGHT 12
#define ECHOPIN_RIGHT 13                  //右侧超声


主控:Arduino UNO R3
电机控制板:L298N
小车配置:两个直流电机控制左右各一个电机,后面带一个万向轮
供电:
4节5号电池 给L298N
一个9V电池给 UNO R3
传感器:左、中、右共3个HC SR04超声波传感器,分别检测来自左前方、前方、右前方的障碍

一下是复制来的程序:

#include "Arduino.h"

class Detector {                              //HC SR04超声波传感器封装
private:
    uint8_t _trigPin, _echoPin;
public:
    float _dangerDistance;
    bool _state = false;                //危险状态标记(单次)
    bool _stateAve = false;            //危险状态标记(多次)
    //构造函数,初始化超声波测距传感器,缺省危险距离为30cm
    Detector(uint8_t trigPin, uint8_t echoPin, float dangerDistance = 30.0)      {
      _trigPin = trigPin;
      _echoPin = echoPin;
      _dangerDistance = dangerDistance;
      pinMode(_trigPin, OUTPUT);
      pinMode(_echoPin, INPUT);
    }
    void setDangerDistance(float dangerDistance) {
      _dangerDistance = dangerDistance;
    }
    float distance() { //一次取样获取距离参数
      digitalWrite(_trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(_trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(_trigPin, LOW);
      float dist = pulseIn(_echoPin, HIGH) / 58.0;
      if (dist < _dangerDistance)
      _state = true;
      else
      _state = false;
      return dist;
    }
    float distanceAve(uint8_t n = 5) { //n次取样后取平均值,缺省5次
      float distTemp;
      float sum = 0;
      for (int i = 0; i < n; i++) {
      distTemp = distance();
      sum += distTemp;
      delay(5); //间隔5ms取样一次,共n次
      }
      float dist = sum / n;
      if (dist < _dangerDistance)
      _stateAve = true;
      else
      _stateAve = false;
      return sum / n;
    }

};

#define TRIGPIN_LEFT 10
#define ECHOPIN_LEFT 11                  //左侧超声波
#define DANGERDISTANCE_LEFT 24.0    //设定左侧危险距离
#define TRIGPIN_MID 8
#define ECHOPIN_MID 9                        //中间超声波
#define DANGERDISTANCE_MID 28.0   //设定中间危险距离
#define TRIGPIN_RIGHT 12
#define ECHOPIN_RIGHT 13                  //右侧超声波
#define DANGERDISTANCE_RIGHT 24.0   //设定右侧危险距离
Detector sensorMid(TRIGPIN_MID, ECHOPIN_MID, DANGERDISTANCE_MID);
Detector sensorLeft(TRIGPIN_LEFT, ECHOPIN_LEFT, DANGERDISTANCE_LEFT);
Detector sensorRight(TRIGPIN_RIGHT, ECHOPIN_RIGHT, DANGERDISTANCE_RIGHT);

//------------------------------------------------------------------------------------------------------------
class Car {
private:
    uint8_t _ENL, _L1, _L2, _Lspeed;
    //ENL/L1/L2分別為左輪PWM使能和2個正負方向調節參數,_Lspeed为左轮速度
    uint8_t _ENR, _R1, _R2, _Rspeed;
    //ENR/R1/R2分別為右輪PWM使能和2個正負方向調節參數,_Rspeed为右轮速度

public:
    //构造函数,小车初始化,并且停止不动
    Car(uint8_t ENL, uint8_t L1, uint8_t L2, uint8_t Lspeed,
      uint8_t ENR, uint8_t R1, uint8_t R2, uint8_t Rspeed) {
      //定义各针脚
      _ENL = ENL;      _L1 = L1; _L2 = L2;      _Lspeed = Lspeed;
      _ENR = ENR;      _R1 = R1; _R2 = R2;      _Rspeed = Rspeed;

      onForward = 0;

      pinMode(_ENL, OUTPUT); pinMode(_L1, OUTPUT); pinMode(_L2, OUTPUT);
      pinMode(_ENR, OUTPUT); pinMode(_R1, OUTPUT); pinMode(_R2, OUTPUT);

      analogWrite(_ENL, 0);
      analogWrite(_ENR, 0);
    }

    void forward(int interval = 0) {
      analogWrite(_ENL, _Lspeed);
      digitalWrite(_L1, HIGH);
      digitalWrite(_L2, LOW);
      analogWrite(_ENR, _Rspeed);
      digitalWrite(_R1, HIGH);
      digitalWrite(_R2, LOW);
      delay(interval);
      onForward();
    }
    void backward(int interval = 500) {
      analogWrite(_ENL, 255);
      digitalWrite(_L1, LOW);
      digitalWrite(_L2, HIGH);
      analogWrite(_ENR, 255);
      digitalWrite(_R1, LOW);
      digitalWrite(_R2, HIGH);
      delay(interval);
    }
    void leftForward(int interval = 250) {
      analogWrite(_ENL, 0);
      analogWrite(_ENR, 255);
      digitalWrite(_R1, HIGH);
      digitalWrite(_R2, LOW);
      delay(interval);
    }
    void rightForward(int interval = 250) {
      analogWrite(_ENL, 255);
      digitalWrite(_L1, HIGH);
      digitalWrite(_L2, LOW);
      analogWrite(_ENR, 0);
      delay(interval);
    }
    void leftRotate(int interval = 500) {
      analogWrite(_ENL, 255);
      digitalWrite(_L1, LOW);
      digitalWrite(_L2, HIGH);
      analogWrite(_ENR, 255);
      digitalWrite(_R1, HIGH);
      digitalWrite(_R2, LOW);
      delay(interval);
    }
    void rightRotate(int interval = 500) {
      analogWrite(_ENL, 255);
      digitalWrite(_L1, HIGH);
      digitalWrite(_L2, LOW);
      analogWrite(_ENR, 255);
      digitalWrite(_R1, LOW);
      digitalWrite(_R2, HIGH);
      delay(interval);
    }
    void stop(int interval = 10) {
      analogWrite(_ENL, 0);
      analogWrite(_ENR, 0);
    }

    //event
    void (*onForward)();
};

#define ENL 3
#define L1 2
#define L2 4
#define LSPEED 188                        //左侧电机
#define ENR 5
#define R1 6
#define R2 7
#define RSPEED 215                        //右侧电机

Car thisCar(ENL, L1, L2, LSPEED, ENR, R1, R2, RSPEED);

void onForward_do() {
float distLeft = sensorLeft.distanceAve(3);
bool stateLeft = sensorLeft._stateAve;
float distMid = sensorMid.distanceAve(3);
bool stateMid = sensorMid._stateAve;
float distRight = sensorRight.distanceAve(3);
bool stateRight = sensorRight._stateAve;
uint8_t state = (4 * stateLeft) + (2 * stateMid) + stateRight;
switch (state)
{
    case 0x00 :                                        //000左中右无障碍,直行
      break;
    case 0x01 :                                        //001右侧障碍,左前方行驶
      thisCar.leftForward();
      break;
    case 0x02 :                                        //010中间障碍,退后若干,挑左右两边较空旷方向行驶
      thisCar.backward();
      if (distLeft >= distRight)
      thisCar.leftForward();
      else
      thisCar.rightForward();
      break;
    case 0x03 :                                        //011中右有障碍,后退若干,再左前方行驶
      thisCar.backward();
      thisCar.leftForward();
      break;
    case 0x04 :                                        //100左前方障碍,往右前方行驶
      thisCar.rightForward();
      break;
    case 0x05 :                                        //101左右两侧有障碍,中间无障碍,不要进窄缝,转个圈圈往回走
      thisCar.leftRotate();
      break;
    case 0x06 :                                        //110左中有障碍,后退若干,再右前方行驶
      thisCar.backward();
      thisCar.rightForward();
      break;
    case 0x07 :                                        //111左中右都是障碍,转个圈圈往回走
      thisCar.rightRotate();
      break;
    default :
      break;
}
}
//-------------------------------------------------------------------------------------------------------------
void setup() {
Serial.begin(9600);
thisCar.onForward = onForward_do;
}

void loop() {
thisCar.forward();
}

董董soul 发表于 2017-10-10 17:20:44

最好上一下实物图以及程序,以上看不出任何问题出在哪里

marine77 发表于 2017-10-11 11:11:55

董董soul 发表于 2017-10-10 17:20
最好上一下实物图以及程序,以上看不出任何问题出在哪里

麻烦你再帮我看看,我资料重新整理了下。
谢谢

arduinofancier 发表于 2017-10-15 18:02:50

换个端口试试

摄迷迷 发表于 2017-10-17 15:09:31

上半年我作了一个用三个超声波探测距离的避障小车参赛,不过程序是用米思奇写的,这种句子还真看不懂
如你需要可加我QQ:37151169,我把他编泽成语句

通幽境 发表于 2017-10-18 01:44:26

感觉描述的不是很清楚,是超声波传感器没有输出,还是小车不闪避左右的障碍物?
建议先单独测试3个超声波传感器,排除下硬件问题。

marine77 发表于 2017-10-18 09:53:38

通幽境 发表于 2017-10-18 01:44
感觉描述的不是很清楚,是超声波传感器没有输出,还是小车不闪避左右的障碍物?
建议先单独测试3个超声波 ...

不是硬件问题,我现在3个超声波,直接接板子的5V,5V,3.3V,和板子的3个GND,居然2个5V的超声波可以运作。只剩余3.3V的不能运作。
所以超声波不能直接并联,并联后,只有一个有效。
但是不会解决这个问题。

通幽境 发表于 2017-10-18 13:53:55

marine77 发表于 2017-10-18 09:53
不是硬件问题,我现在3个超声波,直接接板子的5V,5V,3.3V,和板子的3个GND,居然2个5V的超声波可以运作。 ...

那就是说可以确定是软件问题,大致看了下代码,loop里是不是写错了? 改成thisCar.onForward();
页: [1]
查看完整版本: 求助,3个超声波的避障小车,只有中间的超声波起作用