Kehittelen tässä koodia jolla voisi lukea useita yhtäaikaa laukaistuja ultraäänisensoreita. Sensorit toimivat siten, että niille annetaan väh 10us pulssi trigger-pinniin, sensori lähtettää aallot matkaan. Kun ne palaavat, sensori palauttaa echo pinnistä n. 150us- 25ms pulssin joka on suhteessa mitattuun etäisyyteen. Tyypillisesti näitä käytetään siten että sensoreita luetaan vuoronperään.
Ajattelin koettaa lukea näitä kerralla useampia siten, että luetaan port registeristä inputtien tilaa nopeana luuppina ja aina muutoksen tullessa talletaan luuppien määrä ja tieto siitä mikä pinni on ylhäällä. Sitten voisi laskea mittanauhan avulla mitä matkaa yksi kierros laskurissa vastaa matkassa.
En kuitenkaan saanut tätä toimimaan järkevästi. Mikä alla olevassa kahden sensorin koodissa tai logiikassa mättää. Omat aivot jumittaa näköjään. Ohjelma pyörii mutta tuottaa vain vähän vaihtuvia lukemia joissa ei ole oikein järkeä.
esim.
128sensori
523aika
64sensori2
530aika2
Tämä riippumatta mikä on etäisyys ja kumpaan sensoriin on lyhyempi etäisyys. Aika vaihtelee hiukan. Ei kait tuossa luupissa voi niin kauan kestää ettei se ehdi lukemaan sisään tulevia pulsseja?
#define trigPin 12
#define echoPin 7
#define echoPin2 6
byte eka = 0; //näihin tallennetaan tulokset
unsigned long ekaAika = 0;
byte toka = 0;
unsigned long tokaAika = 0;
void setup() {
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(echoPin2, INPUT);
//DDRD = B00000010; // sets Arduino pins 2 to 7 as inputs, pin 0 as input
}
void loop() {
byte portti = B00000000;
byte maski = B11000000;
byte lukema = B00000000;
unsigned long aika = 0;
digitalWrite(trigPin, HIGH); // aktivoidaan sensorit, molempien
delayMicroseconds(20); // triggerit kytketty samaan pinniin
digitalWrite(trigPin, LOW);
while(lukema == portti)// luetaan inputit kunnes joku pinneistä
// saa signaalin
{
lukema = PIND & maski; //luetaan maskin avulla vain halutut pinnit
++aika; // kasvatetaan laskuria
}
eka = lukema; //tallentaan missä pinnissä signaali
ekaAika = aika;
maski = lukema ^ maski; // poistetaan maskista jo luettu pinni
lukema = B00000000;
while(lukema == portti){
lukema = PIND & maski;
++aika;
}
toka = lukema;
tokaAika = aika;
maski = lukema ^ maski;
lukema = B00000000;
Serial.print(eka);
Serial.println(" sensori");
Serial.print(ekaAika);
Serial.println(" aika");
Serial.print(toka);
Serial.println(" sensori2");
Serial.print(tokaAika);
Serial.println(" aika2");
Serial.println(" XXX");
portti = B00000000;
maski = B11000000;
aika = 0;
delay(500);
}
Ainakin tuo toimii nyt väärin kuvaukseesi verrattuna.
ajan ei muuten tartte olla long. Jos Atmel kasvattaa lukua 10^6 kertaa sekunnissa, 32-bittiä riittää vallan mainiosti neljällä miljardilla. 16-bittiä pystyy mittaamaan 65ms kierroksella.
Tuolla pitäisi pystyä sanomaan, josko sensorit antavat jonkin mittaisen pulssin etäisyyden perusteella. Pulssin alkuhetkeä ei tuossa siis tiedetä, mutta sen lisääminen ei ole vaikeaa. Sillä ei tosin taida tehdä mitään.
Ongelma taisikin olla kyseisen sensorin harhaanjohtavassa “datalehdessä” jota jotkut sen myyjistä jakelevat. Nimittäin toisin kuin siinä oppaassa sanotaan: lähtevän pulssin ja echon väliä mittaamalla ei taida voidakkaan mitata äänen kulkemaa matkaa.
Ilmeisesti laukaisun jälkeen on hyvin lyhyt tauko jonka aikana lähetetään ultraäänipulssit. Sitten echo pinni aktivoituu ja menee taas pois päältä kun kaiku palaa. Alkuperäinen koodini mittasi siis tämän lyhyen pulssin lähetysajan, siitä johtuen staattiset lukemat.
Niimpä sitä tuli haaskattua omaa ja lähimmäisten aikaa mokoman läpyskän takia…mrh