duinozone.cz - Arduino a Raspberry fórum

Autor Téma: ovládání motorů senzorem hc-sr04  (Přečteno 6038 krát)

Offline fidomil

  • Bastlíř začátečník
  • *
  • Příspěvků: 10
ovládání motorů senzorem hc-sr04
« kdy: Říjen 23, 2014, 00:32:57 dopoledne »
Zdravím.
s arduinem jsem teprve v začátcích takže bych potřeboval poradit jak mám napsat program pro ovládání robota ultrazvukem hc-sr04.
mám podvozek se dvěma motorama, desku mega 2560, motorshield r3 a senor hc-sr04.
motory (směr a rychlost) už jsem se naučil, ale to ovládaní ultrazvukem mi po někollika špatných pokusech nějak nejde.
po nikom nechci aby mi to celé napsal. stačí mi jen popostrčit.
Tady dávám kód který jsem napsal ale nefunguje.
poradíte?



Kód: [Vybrat]
const int pingPin = 53;
int inPin = 52;
int safeZone = 40;
 
void setup() {
  // initialize serial communication
  Serial.begin(9600);
  //kanál A
  pinMode(12, OUTPUT);
  pinMode(9, OUTPUT);
  //kanál B
  pinMode(13, OUTPUT);
  pinMode(8, OUTPUT);
}
 
void loop()
{
  long duration, cm;
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
 
  pinMode(inPin, INPUT);
  duration = pulseIn(inPin, HIGH);

  cm = microsecondsToCentimeters(duration);
 
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();

  if (cm > safeZone)
  {
// kanál 1 směr vpřed
digitalWrite(12, HIGH);
 digitalWrite(9, LOW);
 analogWrite(3, 155);
 //kanál 2 směr vpřed
  digitalWrite(13, HIGH);
 digitalWrite(8, LOW);
 analogWrite(11, 155);
 delay(3000);

  }
  else
  {
// kanál 1 směr vzad
    digitalWrite(12, LOW);
    digitalWrite(9, LOW);
    analogWrite(3, 155);
// kanál 2 směr vpřed
  digitalWrite(13, HIGH);
 digitalWrite(8, LOW);
 analogWrite(11, 155);


  }
 
  delay(50);
}
 
long microsecondsToCentimeters(long microseconds)
{

  return microseconds / 29 / 2;
}
« Poslední změna: Říjen 23, 2014, 12:57:58 odpoledne od Yenda »

Offline posjirka

  • Zkušený bastlíř
  • ****
  • Příspěvků: 433
Re:ovládání motorů senzorem hc-sr04
« Odpověď #1 kdy: Říjen 24, 2014, 15:38:45 odpoledne »
a co ti nefunguje?

Offline posjirka

  • Zkušený bastlíř
  • ****
  • Příspěvků: 433
Re:ovládání motorů senzorem hc-sr04
« Odpověď #2 kdy: Říjen 24, 2014, 15:45:00 odpoledne »
jen pro začátek zkus změnit typ proměné z LONG na FLOAT.
u LONGu bývá obecně problém při početních opreacích.
Tu změnu proved všude máš tu hodnotu distance roztahanou i mimo hlavní smyčku.
zkus se podívat na
http://arduino8.webnode.cz/news/lekce-9-merime-vzdalenost-s-hc-sr04/
má to celkem dobře oppsáno.

Offline fidomil

  • Bastlíř začátečník
  • *
  • Příspěvků: 10
Re:ovládání motorů senzorem hc-sr04
« Odpověď #3 kdy: Říjen 24, 2014, 19:44:44 odpoledne »
Nedetekuje mi to překážku.  Pořád to do něčeho naráží.
Hned jak budu mit čas tak na to mrknu a dam vědět jestli to funguje
díky za odpověď.

Offline fidomil

  • Bastlíř začátečník
  • *
  • Příspěvků: 10
Re:ovládání motorů senzorem hc-sr04
« Odpověď #4 kdy: Říjen 24, 2014, 19:49:31 odpoledne »
Dival jsem se na ten odkaz a mám malou otázku.
v tom odkazu je měřič vzdálenosti.  Jak do toho mám zakomponovat podmínku aby mi to tu překážku detekovalo a změnilo to směr.

Offline posjirka

  • Zkušený bastlíř
  • ****
  • Příspěvků: 433
Re:ovládání motorů senzorem hc-sr04
« Odpověď #5 kdy: Říjen 24, 2014, 20:36:29 odpoledne »
podmínku máš správně.
if (cm > safeZone)
ano - jeď dopředu
ne - zatoč.

Já bych to udělal tak, že bych připojil arduino k Pc připojil ultrazvuk.čidlo a nechal si na seriový port vypisovat jak měřenou vzdálenost tak zda má jet vpřed, nebo změnit směr.  Navíc těch 50ms na celou smyčku (plus měření) mi přijde strašně málo na to aby odezněly všechny dozvuky. Navíc nemáš ošetřené max. dobu měření.
Já bych to viděl takto:
Kód: [Vybrat]
const int pingPin = 53;
int inPin = 52;
int safeZone = 40;
int cm; // změna
 
void setup() {
  // initialize serial communication
  Serial.begin(9600);
  //kanál A
  pinMode(12, OUTPUT);
  pinMode(9, OUTPUT);
  //kanál B
  pinMode(13, OUTPUT);
  pinMode(8, OUTPUT);
}
 
void loop()
{
  float duration; // změna
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
 
  pinMode(inPin, INPUT);
  duration = pulseIn(inPin, HIGH, 10000); //změna

  cm = duration *0.017315; // změna
 
  Serial.print(cm);
  Serial.print("cm");

  if (cm > safeZone)
  {
  Serial.println("vpřed"); // změna
// kanál 1 směr vpřed
digitalWrite(12, HIGH);
 digitalWrite(9, LOW);
 analogWrite(3, 155);
 //kanál 2 směr vpřed
  digitalWrite(13, HIGH);
 digitalWrite(8, LOW);
 analogWrite(11, 155);
 delay(500); // změna
  }
  else
  {
  Serial.println("překážka"); // změna
// kanál 1 směr vzad
    digitalWrite(12, LOW);
    digitalWrite(9, LOW);
    analogWrite(3, 155);
// kanál 2 směr vpřed
  digitalWrite(13, HIGH);
 digitalWrite(8, LOW);
 analogWrite(11, 155);
  }
  delay(500); // změna
}
« Poslední změna: Říjen 24, 2014, 20:42:20 odpoledne od posjirka »

Offline fidomil

  • Bastlíř začátečník
  • *
  • Příspěvků: 10
Re:ovládání motorů senzorem hc-sr04
« Odpověď #6 kdy: Říjen 24, 2014, 22:08:45 odpoledne »
díky ti za radu.
Kód podle tebe funguje jak má. teď mám otevřená okna s tvým i mým kódem a dívám se na tebou provedené změny. můžeš mi prosím ty změny nějak vysvětlit? zvětšil jsi pauzu delay 500 a smazal jsi nějaké řádky. bylo špatné fungování mého kódu zapřičiněno jen tou pauzou?

Offline posjirka

  • Zkušený bastlíř
  • ****
  • Příspěvků: 433
Re:ovládání motorů senzorem hc-sr04
« Odpověď #7 kdy: Říjen 25, 2014, 20:54:01 odpoledne »
tak od začátku :
---------------------
zavedl jsem globální promennou "cm" , kterou teď  můžu používat kde budu chtít.
int cm; // změna
v podstatě jsem chtěl zkrátit kod.
---------------------
Změnil jsem typ proměnné "duration" na float, se kterým se líp provádí početní operace.
---------------------
Omezil jsem max dobu měření na 10ms resp. 10000us abych nečekal odezvu, která nemusí přijít (to je nejspíš základ chybného fungování prvotního programu, prostě čekal na první odezvu a než jí dostal už narazil)
duration = pulseIn(inPin, HIGH, 10000); //změna
---------------------
prvedl jsem přímý přepočet z "us" na "cm" bez volání dalšího podprogramu. Je tam velká pravděpodobnost, že se mineš v typu předávaných proměnných a příjde ti zpět nesmysl
cm = duration *0.017315; // změna
---------------------
přidal jsem odezvu o směru jízdy na serivý port, a´t se to dá snadnějí rozluštit , kde je chyba
Serial.println("vpřed"); // změna
Serial.println("překážka"); // změna
---------------------
nechal jsem mezi měřením stejnou prodlevu pro oba směry jízdy na 500ms
delay(500); // změna
Zaprvé proto aby se to trochu sjednotilo a za druhé aby byl čas na dozvuky ozvěn těch pingů. Mě to občas trvalo i 1s než se to ustalilo a mohl jsem začít v klidu znovu měřit a získat korektní signál.

Ve výsledku měl jsi kostru a myšlenku správnou. jen pár detailů poopravit.
jsem rád že to funguje psal jsem korekci poslepu :)


Offline fidomil

  • Bastlíř začátečník
  • *
  • Příspěvků: 10
Re:ovládání motorů senzorem hc-sr04
« Odpověď #8 kdy: Říjen 26, 2014, 00:59:23 dopoledne »
Díky za vysvětlení.  Zase jsem chytrejsi. Ted k tomu můžu vymýšlet další funkce. Začíná me to bavit čím dál víc :-)

Offline fidomil

  • Bastlíř začátečník
  • *
  • Příspěvků: 10
Re:ovládání motorů senzorem hc-sr04
« Odpověď #9 kdy: Listopad 29, 2014, 18:40:17 odpoledne »
Ahoj všem. podle vašich rad jsem postavil a rozjel funkčního robota. Teď jsem se rozhodl že senzor hc-sr04 přidělám na servo aby se mohl pohybovat jak na tomhle videu

https://www.youtube.com/watch?v=LQKHeeMBwbI

 servo jsem dal na pin 6 a prošel jsem si nějaké tipy na kód ale nic se mi nepodařilo rozjet. můžete mi někdo prosím poradit jak to udělat aby to fungovalo jak na tom videu.? Děkuji za vaše rady a nápady.

 můj stávající kód je:
 const int pingPin = 53;
int inPin = 52;
int safeZone = 40;
int cm; // změna
 
void setup() {
  // initialize serial communication
  Serial.begin(9600);
  //kanál A
  pinMode(12, OUTPUT);
  pinMode(9, OUTPUT);
  //kanál B
  pinMode(13, OUTPUT);
  pinMode(8, OUTPUT);
}
 
void loop()
{
  float duration; // změna
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
 
  pinMode(inPin, INPUT);
  duration = pulseIn(inPin, HIGH, 10000); //změna

  cm = duration *0.017315; // změna
 
  Serial.print(cm);
  Serial.print("cm");

  if (cm > safeZone)
  {
  Serial.println("vpřed"); // změna
// kanál 1 směr vpřed
digitalWrite(12, LOW);
 digitalWrite(9, LOW);
 analogWrite(3, 200);
 //kanál 2 směr vpřed
  digitalWrite(13, HIGH);
 digitalWrite(8, LOW);
 analogWrite(11, 200);
 delay(250); // změna
  }
  else
  {
  Serial.println("překážka"); // změna
// kanál 1 směr vzad
    digitalWrite(12, HIGH);
    digitalWrite(9, LOW);
    analogWrite(3, 150);
// kanál 2 směr vpřed
  digitalWrite(13, HIGH);
 digitalWrite(8, LOW);
 analogWrite(11, 150);
  }
  delay(250); // změna
}
« Poslední změna: Listopad 29, 2014, 18:42:08 odpoledne od fidomil »

Offline posjirka

  • Zkušený bastlíř
  • ****
  • Příspěvků: 433
Re:ovládání motorů senzorem hc-sr04
« Odpověď #10 kdy: Listopad 29, 2014, 20:23:39 odpoledne »
ahoj video je zajimave. je v nem videt ze se servo prepina na jedno ze trech modu. od fixni pozice leva stred prava az po kyvadlo nebo jak to nazvat. bohuzel jsem ale nepochopil co to ma za vyznam. navic pochybuji za takto rychly pohyb cidla je ku prospechu vysledku mereni. byt tebou napsal bych si co od programu ocekavas resp napsal si hrubou funkci jednotlivych komponent. treba servo bude otacet cidlem zleva doprava proto aby .... doba prechodu od dorazu k dorazu bde cca ... sekund. cidlo podle pozice serva bude merit vzdalenost a to v techto uhlech nebo bodech. kdyz zjisti prekazku blizko v tomto uhlu odelej toto .... no a mas program na svete. postupne ozivit jednotlive kroky uz se da zvladnou. nejhorsi je vzdy specifikace zameru  a u neprogramatoru je horor vysvetlit ze standardni beh programu je vklidu ty potrebujech identifikovat vyjimky a  nejak na ne zareagovat. s tim se bohuzel potkavam denne a brzy pochopis ze to ceka i tebe :-)
« Poslední změna: Listopad 29, 2014, 21:56:35 odpoledne od posjirka »

Offline posjirka

  • Zkušený bastlíř
  • ****
  • Příspěvků: 433
Re:ovládání motorů senzorem hc-sr04
« Odpověď #11 kdy: Listopad 29, 2014, 21:59:04 odpoledne »
jinak stačí použít strýčka googla a tutorial jak ovladat servo je na světě
http://playground.arduino.cc/ComponentLib/Servo
http://playground.arduino.cc/Learning/SingleServoExample

Offline fidomil

  • Bastlíř začátečník
  • *
  • Příspěvků: 10
Re:ovládání motorů senzorem hc-sr04
« Odpověď #12 kdy: Listopad 29, 2014, 23:07:11 odpoledne »
No prvne jsem myslel ze to bude fungovat tak, že se servo po detekci překážky podiva doleva, doprava a pak se rozhodne kam chce jet. Pohyb serva bych snad zvladl s pomoci těch tutoriálů. Problem mi bude dělat to rozhodování robota jakym směrem se rozjet po detekci překážky.

Offline posjirka

  • Zkušený bastlíř
  • ****
  • Příspěvků: 433
Re:ovládání motorů senzorem hc-sr04
« Odpověď #13 kdy: Listopad 29, 2014, 23:15:39 odpoledne »
vše je otázkou priorit. Viděl bych to asi takto.

jedu dopředu.
vidím překážku.
Je vlevo překážka?
je vpravo překážka?
Pokud je vlevo volno jeď vlevo.
Pokud je vlevo překážka a vpravo volno je´d vpravo.
Pokud je vlevo překážka a vpravo překážka otoč se a je´d zpět
...

Offline fidomil

  • Bastlíř začátečník
  • *
  • Příspěvků: 10
Re:ovládání motorů senzorem hc-sr04
« Odpověď #14 kdy: Listopad 30, 2014, 00:43:50 dopoledne »
Dík za radu.  Zkusim sesmolit kód a Dám ho sem. Ale hned tak to asi nebude