0 голосов

Всем привет!
Хотел бы попросить вашей помощи в следующем вопросе: подключил к Raspberry Pi4 сонар URM37(датчик) и пытаюсь получить от него данные адоптировав код из листинга (1) на сайте производителя(Wiki по датчику)  с помощью WiringPi.
    Однако получаю все время значения меньше 50, что меньше 1cm. Написав тупой костыль, заранее извиняюсь за его корявость, в виде листинга (2) я получаю нормальное значение расстояния, понятное дело с очень большой задержкой.
    Датчик и код из листинга (1) проверял на ардуинке, все ок. Во время работы Raspberry и датчика подключал осцилограф и смотрел на сигнал, все нормально 50us = 1cm.
 

Можете подсказать, как сделать так, чтобы за один запрос я получал корректное значение расстояния?

Листинг 1.

 # Connection:
// #       Vcc (Arduino)    -> Pin 1 VCC (URM V5.0)
// #       GND (Arduino)    -> Pin 2 GND (URM V5.0)
// #       Pin 3 (Arduino)  -> Pin 4 ECHO (URM V5.0)
// #       Pin 5 (Arduino)  -> Pin 6 COMP/TRIG (URM V5.0)

// # Working Mode: PWM trigger pin  mode.

int URECHO = 3;         // PWM Output 0-25000US,Every 50US represent 1cm
int URTRIG = 5;         // trigger pin

unsigned int DistanceMeasured = 0;

void setup()
{
  //Serial initialization
  Serial.begin(9600);                        // Sets the baud rate to 9600
  pinMode(URTRIG, OUTPUT);                   // A low pull on pin COMP/TRIG
  digitalWrite(URTRIG, HIGH);                // Set to HIGH
  pinMode(URECHO, INPUT);                    // Sending Enable PWM mode command
  delay(500);
  Serial.println("Init the sensor");

}
void loop()
{
  Serial.print("Distance=");
  digitalWrite(URTRIG, LOW);
  digitalWrite(URTRIG, HIGH);              

  unsigned long LowLevelTime = pulseIn(URECHO, LOW) ;
  if (LowLevelTime >= 50000)              // the reading is invalid.
  {
    Serial.println("Invalid");
  }
  else
  {
    DistanceMeasured = LowLevelTime / 50;  // every 50us low level stands for 1cm
    Serial.print(DistanceMeasured);
    Serial.println("cm");
  }

  delay(200);
}

Листинг 2. 

void Setup(){
    trig_.PinMode(OUTPUT);
    trig_.DigitalWrite(HIGH);
    echo_.PinMode(INPUT);
    delay(500);
}

GPIO::ErrorCode Read(){
	trig_.DigitalWrite(LOW);
    trig_.DigitalWrite(HIGH);

    auto time = echo_.pulseInLength(LOW, 45000);
    if(time == 0)
        return GPIO::ErrorCode::ERROR_TIMEOUT;

    distance_ = time / 50;

    return GPIO::ErrorCode::OK;
}
void TryRead{
  while(int(Read()) || distance_ < 1){delayMicroseconds(1);}
}

(10 баллов) 2 6
исправил

1 Ответ

+1 голос
 
Лучший ответ
На малинке (и ей подобных системах) можно даже не пытаться измерять время между двумя импульсами. Ядро линукс, под которым работает малинка, не является операционной системой реального времени (ни мягкой, ни уж тем более жёсткой). Прерывания также полностью программные - когда планировщик операционной системы решит дать приложению обработать прерывание, тогда и даст, а вовсе не сразу). Поэтому это либо RTOS (не знаю, что портировано на одноплатники), либо младшие микроконтроллеры.
(2.7 тыс. баллов) 10 29 55
выбран
Добро пожаловать на Бредборд! Сайт вопросов и ответов на тему Arduino, Raspberry Pi и хоббийной электроники в целом. Цель Бредборда — быть максимально полезным. Поэтому мы строго следим за соблюдением правил, боремся с холиворами и оффтопиком.

    За этот месяц ещё никого.

    ...