matpi / EmbeddedSystemsUTU

This repository concerns the course KSA4 Embedded Systems (craft, design and technology education) in the University of Turku, Department of Teacher Education, Rauma Unit in the academic year 2014
4 stars 5 forks source link

Demon tehtävässä ongelma: miten laskutoimitukset hoituvat? #40

Open jumap opened 9 years ago

jumap commented 9 years ago

Kokeilimme Hintsalan Jussin kanssa servoautolla ohjelmaa, jossa ultraäänianturin etäisyysarvot vaikuttaisivat laitteen nopeuteen: se hidastaisi estettä lähestyessään ja vastaavasti peruuttaisi tasaisesti kiihtyvällä nopeudella samalla kääntyen. Muokkamamme koodi ei kuitenkaan oikein toiminut - laite pyöritti kyllä servoja, mutta toinen takerteli ja toimi hyvin hitaasti.

Koodi on tässä:

include

Servo ekaServo; // luodaan servo-objekti nimeltä ekaservo Servo tokaServo; // luodaan servo-objekti nimeltä tokaservo

int echoPin = 11; // Määritellään, mihin Arduino pinniin echoPin yhdistetään

int trigPin = 12; // Määritellään, mihin Arduino pinniin trigPin yhdistetään

long kesto = 0; // Määritellään long-tyyppinen muuttuja nimeltä kesto

long matka = 0; // Määritellään long-tyyppinen muuttuja nimeltä matka

int val = 0; //määritellään muuttujan val arvo

long etaisyys = 0;

// long pako = 0; // tätä kai ei tarvi...

void setup()

{

Serial.begin (9600); // Avataan sarjaliikenne tietokoneelle nopeudella 9600 bps

pinMode(trigPin, OUTPUT); // Määritellään trigPin outputiksi

pinMode(echoPin, INPUT); // Määritellään echoPin inputiksi

ekaServo.attach(9); //käynnistää ekaservo nimisen servo-objektin pinnissä 9 tokaServo.attach(8); //käynnistää tokaservo nimisen servo-objektin pinnissä 8

}

void loop()

{

ultra(); // Määritellään ultra -niminen fuktio

Serial.println(matka); // "Serial.println" komento vaihtaa riviä tulostuksen jälkeen

delay(30);

if(matka >= 100) { ekaServo.write(170); tokaServo.write(10);

}

else if(matka < 180 && matka > 40)

{

etaisyys= matka*80; etaisyys=matka/100; ekaServo.write(etaisyys+90); // käskee servon laskea nopeutensa etäisyysarvon mukaan ja kääntyä arvon osoittamalla nopeudella tokaServo.write(-etaisyys-90); // käskee servon laskea nopeutensa etäisyysarvon mukaan ja kääntyä arvon osoittamalla nopeudella

delay(100); }

else {

pako; //kutsutaan pako-niminen funktio

}

ultra(); }

void ultra() // Kutsutaan ultra

{

digitalWrite(trigPin, HIGH);

delayMicroseconds(10);

digitalWrite(trigPin, LOW);

kesto = pulseIn(echoPin, HIGH);

matka = kesto/58.2; // Muuttujan matka arvo muutetaan senttimetreiksi ko. kaavalla

return;

}

void pako() //kutsutaan pako { if (val=0);
ekaServo.write(etaisyys-140); // käskee servon laskea nopeutensa etäisyysarvon mukaan ja kääntyä arvon osoittamalla nopeudella tokaServo.write(-etaisyys+90); // käskee servon laskea nopeutensa etäisyysarvon mukaan ja kääntyä arvon osoittamalla nopeudella val=val+1;

return;

if (val=1); ekaServo.write(-etaisyys-140); // käskee servon laskea nopeutensa etäisyysarvon mukaan ja kääntyä arvon osoittamalla nopeudella tokaServo.write(etaisyys+90); // käskee servon laskea nopeutensa etäisyysarvon mukaan ja kääntyä arvon osoittamalla nopeudella val=val+1; val=0;

return;

delay(100); }

Robojuchen commented 9 years ago

Ihan fiksun oloinen yritys on mutta kompastuu pariin juttuun... huomaamani virheet:

alussa on kaksi if lausetta joissa osin päällekkäiset ehtoalueet, jos matka on yli sata ohjelma ei mene tuohon vauhdinskaalausfunktioon vaikka sen ylärajaksi on määritelty 180. tämä ei kuitenkaan välttämättä ole ongelma mutta outo juttu kuitenkin.

Suurin ongelma taitaa olla tuo etäisyyden mukaan nopeúdenmääritys osio. Toinen servo saa nimittäin negatiivisia arvoja. Oikeasti servoja ohjataan siten että ne poikkeutetaan 90 asteesta jompaan kumpaan suuntaan.

Itse teksin siten että skaalaisin matkan etäisyyteen siten että se on välillä 0-90 tai 0-70 tms. Sen voisi tehdä siten että etäisyys = map(etäisyys, 40,100, 0, 90); Servoille syötettävä lukema saataisiin siten että 90+ etäisyys ja toiselle servolle 90-etäisyys.

Pako funktiossa if lausetta käytetään väärin. Siinä ei pitäsi olla puolipistettä lopussa ja se mikä tapahtuu ehdon toteutuessa pitäsi rajata aaltosulkeilla.

Pako-ohjelmassa on myös samat ongelmat servon saamien arvojen kanssa. Ajatus että kääntyminen toteutetaan kutsumalla toistuvasti pako aliohjelmaa kunnes ehto pääohjemassa muuttuu, on erittäin hyvä. Lisäksi tuo on hyvä että kääntymissuunta vaihtuu, mutta mutta... nythän se vaihtaa suuntaa joka kerta aliohjemaan mennessään mikä ei oikein toimi. (lisäksi if lauseet ovat pielessä) val-laskurin pitäisi vaihtua vasta sitten kun koko kääntyminen on suoritettu kunniakkaasti loppuun ja seuraavalla kerralla pitäisi kääntyä eri suuntaan. Banaanin arvoinen suoritus jos saatte sen homman toimimaan :)

Vielä pilkunviilausta:

Pää loopissa funktioita KUTSUTAAN ja loopin ulkopuolella ne MÄÄRITELLÄÄN toisin kuin kommenteissanne :) Lisäksi ultra() funktiota kutsutaan aika turhaan loopin lopussa. Mutta fiksu peruajatus koodissa ja hienosti käytetty funktioita. Tämä kannattaisi hieroa loppuun sillä olisi varmaan hieno koodi nähdä tominnassa.