nano 33IoT HC-SR04 geeft hogere/verkeerde waarden wanneer object dichterbij komt

Probleem samenvatting
Ik heb de arduino nano 33 IoT met de ultra sonic sensor HC-SR04.
Ik wil heel simpel gewoon de afstand meten van de sensor tot een object.
Alleen naarmate ik een object dichterbij doe, hoe groter de weergegeven afstand is...

Mijn code
De code die ik upload:

#define ULTRASONIC_TRIG_PIN 12 // pin trig is D11
#define ULTRASONIC_ECHO_PIN 11 // pin echo is D12

long duration;
float distance;

void setup() {
  pinMode(ULTRASONIC_TRIG_PIN, OUTPUT);
  pinMode(ULTRASONIC_ECHO_PIN, INPUT);
  Serial.begin(9600);
  delay(1500);
}

void loop() {
digitalWrite(ULTRASONIC_TRIG_PIN, LOW);
delayMicroseconds(2);

digitalWrite(ULTRASONIC_TRIG_PIN, HIGH); //Hiermee zenden we een ultrasoon geluid
delayMicroseconds(10); //Het zenden doen we 10 miliseconden

digitalWrite(ULTRASONIC_TRIG_PIN, LOW); //Nu stoppen we het zenden
duration = pulseIn(ULTRASONIC_ECHO_PIN, HIGH); //Hier meten we hoelang het duurt voordat we het ultrasone geluid terug krijgen.
//distance = duration * 0.034 / 2; // Een manier om de afstand te berekenen
distance = (duration/2) / 29.1; //Hiermee zorgen we dat de waardes in cm worden weergegeven
Serial.print("Afstand: ");
Serial.print(distance);
Serial.println(" cm");

delay(100);
}

Aansluiting
Ik heb de arduino nano 33 IoT verbonden met de sensor zoals hier aangegeven, alleen dan zonder breadboard:


Serial monitor/waarden
Uiteindelijk krijg ik dit terug in mijn serial monitor:

Wanneer ik een object ervoor doe springen de waardes omhoog naar 130 cm.

Wat heb ik al geprobeerd?

  • Verschillende pins (combinaties)
  • Verschillende ports
  • Verschillende baud rates
  • Verschillende data types(int, long, float) voor de duration en distance
  • Verschillende locaties, want het zou kunnen liggen aan omliggende objecten, temperatuur, luchtvochtigheid, etc.

Iemand een idee waar het fout gaat?

Tipje:

Verander de betreffende regel in je code als onderstaand, en voeg direct daarna de andere regels toe.

Serial.print(" cm");
Serial.print("        ");
Serial.print("Meetresultaat:");
Serial.print(duration);
Serial.println("micro seconden");

Dit toont dus niet alleen de centimeters, maar daar achter ook het de waarde die de sensor gemeten heeft in micro seconden.
Dat dient dan als debug hulpmiddel zodat je kunt zien of de waardes zich verhouden tot elkaar en de werkelijke afstand.
Beweeg je object daarvoor langs een liniaal die begint bij je sensor.

PulseIn heeft een bepaalde range, en die start bij 10 micro seconden.
Dat betekent dat je ook een bepaalde minimum afstand hebt die gemeten kan worden.
Met jouw formule kun je ongetwijfeld uitrekenen hoe groot de minimale afstand dus is.

Overigens zijn de 2 formules die in die code staan, volgens mij gelijk.

jelmerovereem:
#define ULTRASONIC_TRIG_PIN 12 // pin trig is D11
#define ULTRASONIC_ECHO_PIN 11 // pin echo is D12

Verkeerde pinnummers of fout commentaar?

jelmerovereem:
duration = pulseIn(ULTRASONIC_ECHO_PIN, HIGH);

Wat voor waardes krijg je van pulseIn()? En is een long dan wel het juiste datatype voor duration? En zo ja, moet dat dan geen unsigned long zijn?

jelmerovereem:
delayMicroseconds(10); //Het zenden doen we 10 miliseconden

Is hier de opdracht fout (micros ipv. millis) of het commentaar?

Edit: Geeft pulseIn() eigenlijk wel de looptijd van het geluid? Of de pulsduur (die altijd 10 microseconden is)?

Nog iets: uit voorbeelden begrijp ik dat interrupts de meting kunnen beïnvloeden; om dat te voorkomen kun je die tijdelijk (!) uitschakelen:

  noInterrupts();
  ...  pulseIn(...);
  interrupts();

Scherp, Erik.

Jelmer heeft een heel slecht voorbeeld vol fouten gekozen en de code 1 op 1 overgenomen behalve een aantal namen van variabelen.
Daarom dat ik ook de resultaten wilde weten van deze meting, daar zou ik het eerst naar kijken.
Maar wanneer de commentaren bij de regels gewoon fout zijn, en je daar je schakeling op bouwt ga je natuurlijk al meteen de mist in.
Helaas vind je dat soort orakels veel vaker dan voorbeelden die wel kloppen (breek me de bek niet open over instructables, nog zo'n pareltje).

Ten eerste super bedankt voor jullie reacties!
Ik snap inderdaad dat de code niet zo netjes was qua comments.

Ik ben echt nog een beginner, waardoor de verschillende pin numbers voor mij een beetje onduidelijk zijn en ik lastig kan onderscheiden welke voorbeelden wel in orde zijn en welke niet.

MAS3:
Tipje:

Verander de betreffende regel in je code als onderstaand, en voeg direct daarna de andere regels toe.

Serial.print(" cm");

Serial.print(" ");
Serial.print("Meetresultaat:");
Serial.print(duration);
Serial.println("micro seconden");




Dit toont dus niet alleen de centimeters, maar daar achter ook het de waarde die de sensor gemeten heeft in micro seconden.
Dat dient dan als debug hulpmiddel zodat je kunt zien of de waardes zich verhouden tot elkaar en de werkelijke afstand.
Beweeg je object daarvoor langs een liniaal die begint bij je sensor.

PulseIn heeft een bepaalde range, en die start bij 10 micro seconden.
Dat betekent dat je ook een bepaalde minimum afstand hebt die gemeten kan worden.
Met jouw formule kun je ongetwijfeld uitrekenen hoe groot de minimale afstand dus is.

Overigens zijn de 2 formules die in die code staan, volgens mij gelijk.

Ik heb dit gevolgd en het aantal microseconden wordt hoger naarmate een object dichterbij komt. En wordt lager naarmate het object weer naar achteren gaat.
Dit is ookal vreemd, want hoe dichterbij een object, hoe minder microseconden er tussen een pulse zouden moeten zijn.

In dit voorbeeld staat namelijk dat 11=D11 en 12=D12, maar hier staat weer dat 14=D11 en 15=D12.
Als ik uit ga van:

#define ULTRASONIC_TRIG_PIN 11 // pin trig zit in D11
#define ULTRASONIC_ECHO_PIN 12 // pin echo zit in D12

Krijg ik dit als resultaat:

Dus dat lijkt me al helemaal niet te kloppen.

Als ik uit ga van:

#define ULTRASONIC_TRIG_PIN 14 // pin trig zit in D11
#define ULTRASONIC_ECHO_PIN 15 // pin echo zit in D12

Krijg ik dit als resultaat:

Maar als ik als code dit doe:

#define ULTRASONIC_TRIG_PIN 12 // pin trig zit in D11
#define ULTRASONIC_ECHO_PIN 11 // pin echo zit in D12

Krijg ik als resultaat:

Maar dit lijkt me dus heel gek, want waarom doen de 2 laatste voorbeelden het allebei terwijl het andere nummers zijn?

Erik_Baas:
Wat voor waardes krijg je van pulseIn()? En is een long dan wel het juiste datatype voor duration? En zo ja, moet dat dan geen unsigned long zijn?

Ik zie in eigenlijk alle voorbeelden dat ze long gebruiken, maar als ik bijvoorbeeld int gebruik zie ik geen verschil. Unsigned geeft ook geen ander resultaat.

Erik_Baas:
Nog iets: uit voorbeelden begrijp ik dat interrupts de meting kunnen beïnvloeden; om dat te voorkomen kun je die tijdelijk (!) uitschakelen:

  noInterrupts();

... pulseIn(...);
interrupts();

Dit geeft ook geen ander resultaat.
Dit is op dit moment mijn code:

#define ULTRASONIC_TRIG_PIN 14 // pin trig is D11
#define ULTRASONIC_ECHO_PIN 15 // pin echo is D12

long duration;
float distance;

void setup() {
  pinMode(ULTRASONIC_TRIG_PIN, OUTPUT);
  pinMode(ULTRASONIC_ECHO_PIN, INPUT);
  Serial.begin(9600);
  delay(1500);
}

void loop() {
digitalWrite(ULTRASONIC_TRIG_PIN, LOW); // geen puls geven
delayMicroseconds(2); // tijd tussen pulsen

digitalWrite(ULTRASONIC_TRIG_PIN, HIGH); // wel een puls
delayMicroseconds(10); // tijd tussen pulsen

digitalWrite(ULTRASONIC_TRIG_PIN, LOW); // geen puls geven

duration = pulseIn(ULTRASONIC_ECHO_PIN, HIGH);
//distance = duration * 0.034 / 2; // Manier 1 om de afstand te berekenen
distance = (duration/2) / 29.1; // Manier 2 om de afstand te berekenen

Serial.print("Afstand: ");
Serial.print(distance);
Serial.println(" cm");
Serial.print("Meetresultaat: ");
Serial.print(duration);
Serial.println(" micro seconden");
delay(100);
}

je moet geluk hebben: jouw nano werkt op 3.3 Volt echter de HC heeft eigenlijk 5 volt nodig, dus of het goed werkt is geluk hebben. Bouw het eens op maar dan op de UNO manier en denk na over welke pinnen je gebruikt, kan namelijk alle pinnen zijn. Je geeft een echopuls en dan is de pulsein gewoon aan het afwachten tot die een puls ziet. Omdat de processor tijd nodig heeft is er dus een minimum afstand. De maxtijd is standaard 1000 microsec en dus daar hangt ook een maximum afstand aan vast. Ik schrijf dit expres een beetje kryptisch op zodat je zelf gaat nadenken hoe het kan.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.