Прием значений с у/з датчика расстояния (PulseIn vs attachInterrupt)

sashabusse
Offline
Зарегистрирован: 17.10.2019
 
 
 
Moderator : пожалуйста, вставьте код правильно (новым сообщением в тему), как описано в http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii
 
 
 
Конфигурация: 
Arduino Uno 
 
Вывод:
started succesfully
18.73 cm - asyncronous
18.25 cm - syncronous
26.28 cm - asyncronous
18.64 cm - syncronous
26.28 cm - asyncronous
18.25 cm - syncronous
26.22 cm - asyncronous
18.25 cm - syncronous
26.28 cm - asyncronous
18.65 cm - syncronous
...
 
Как видно после вызова синхронной версии асинхронная выдает неверный результат.
(При вызове 2ух асинхронных версий после синхронной получим, что первый работает некорректно, а второй дает правильный результат.)
 
В чем проблема?
Заранее спасибо.

 

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

Не можешь в параллельные процессы? Сделай двухъядерную ардуину. Одна мерит тем способом который там работает (синхронный?), далее делай восьмибитный ЦАП на резисторах. Подать во вторую под соусом АЦП, усреднить конденсатором по вкусу. Профит.

И да, не надо мне рассказывать что "цап только 0-255 может а датчик до 400 см же", надеяться на "точность" вертя в руках HCSR04 - самообман.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Да, почему самообман? Ультразвук, он и в Африке ... Если аккуратно всё сделать, да ещё добавить температурную компенсацию - очень неплохо получается.

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

Да это я так. Мутирую в детсимёна.

sashabusse
Offline
Зарегистрирован: 17.10.2019

Да вобщем-то на точность не претендую, да и не про параллельные процессы. Просто интересно, почему такой странный результат получается, что после использования pulseIn на приеме замеры через прерывания становятся неправильными (притом именно неправильными а не неточными т.к. совершенно другой результат: почти в 1,5-2 раза больше.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

sashabusse пишет:

Да вобщем-то на точность не претендую, да и не про параллельные процессы. Просто интересно, почему такой странный результат получается, что после использования pulseIn на приеме замеры через прерывания становятся неправильными (притом именно неправильными а не неточными т.к. совершенно другой результат: почти в 1,5-2 раза больше.

Когда pulseIn считает длину импульса прерывания запрещены. Вставте код правильно, тогда можно будет посмотреть что у вас там не так.

sashabusse
Offline
Зарегистрирован: 17.10.2019

Извиняюсь

Вот код:



static int trig_pin = 4;
static int echo_pin = 2;

typedef void(*callback)(unsigned long);

struct SensorData
{
  bool free = true;
  unsigned long start_time_micro = 0;
  callback fun = 0;
};

volatile SensorData sensor_data;


//------------------------------------async version-------------------------------------------
//catch end of interrupt get duration of pulse and call callback
void sensor_callback(void)
{
  unsigned long end_time_micro = micros();
  
  sensor_data.fun(end_time_micro-sensor_data.start_time_micro);
  
  detachInterrupt(digitalPinToInterrupt(echo_pin));
  
  sensor_data.free = true;
}

//catch rising interrupt get pulse start time
//and set interrupt for end of pulse
void setup_callback(void)
{
  sensor_data.start_time_micro = micros();
  attachInterrupt(digitalPinToInterrupt(echo_pin),sensor_callback,FALLING);
}

//returns true if sensor is free, false otherwise
//just activate measurement by 10 mcs pulse
//and set interrupt
bool asyncronous_measure(callback fun)
{
  if(!sensor_data.free)
    return false;

  sensor_data.free = false;
  sensor_data.fun = fun;
  attachInterrupt(digitalPinToInterrupt(echo_pin),setup_callback,RISING);
  
  digitalWrite(trig_pin,HIGH);
  delayMicroseconds(10);
  digitalWrite(trig_pin,LOW);
  
  return true;
}

void my_callback(unsigned long micros_elapsed)
{ 
  Serial.print(micros_elapsed/60.423);
  Serial.println(" cm - asyncronous");
}





//------------------------------------sync version-------------------------------------------
float syncronous_measure(void)
{
  digitalWrite(trig_pin,HIGH);
  delayMicroseconds(10);
  digitalWrite(trig_pin,LOW);
  unsigned long result = pulseIn(echo_pin,HIGH);
  return result/60.423;
}




void setup() {
  pinMode(trig_pin, OUTPUT);
  pinMode(echo_pin, INPUT);
  Serial.begin(57600);
  Serial.println("started succesfully");
}

void loop() {
  asyncronous_measure(my_callback);
  delay(3000);
  Serial.print(syncronous_measure());
  Serial.println(" cm - syncronous");
  delay(3000);
}