Hallo,
ich habe ein kleines Problem bei dem ich Unterstützung bräuchte. Ich würde gerne 64
Ultraschallsensoren (HCSR04) gleichzeitig über ein bzw. mehrere Arduino Boards ansteuern
und auslesen (Messung soll bei allen Sensoren gleichzeitig erfolgen). Die Übertragung der
gemessenen Daten soll über USB an meinen Computer erfolgen.
Daten HCSR04
Der Ultraschallsensor verfügt über insgesamt vier Pins (VCC, GND, TRIGGER, ECHO). Er wird mit einer
Spannung von 5V und einer Stromstärke von 15mA betrieben.
Aufgrund der hohen Anzahl von Sensoren fiel mir zunächst der Arduino Mega2560 ein.
Aus dem Datenblatt geht hervor, dass dieser über insgesamt 54 Digitale I/O Ports und
16 analogen Inputs besteht. Das bedeutet, dass ich theoretisch 35 Ultraschallsensoren gleichzeitig betreiben
könnte, richtig?
Der Arduino Mega 2560 kann an jedem Port maximal eine Stromstärke von 40mA empfangen/generieren. Bei optimaler
Ausnutzung aber insgesamt nicht mehr als 800mA. Das bedeutet ich kann gar nicht alle Ports mit Ultraschallsensoren belegen, richtig?
Ich habe bereits einen herrvoragenden Sketch von David Pilling gefunden
https://www.davidpilling.com/wiki/index.php/HCSR04
welchen ich gerne verwenden und entsprechend an meine Bedürfnisse anpassen würde.
Im Sketch wird mit Interrupts und Timern gearbeitet. Muss ich aufgrund dessen auf weitere Pins verzichten?
Ihr merkt schon, ich habe zwar eine gewissen Grundkenntnis aber hier und da hapert es doch am tieferen Verständnis.
Mir fehlt der rote Faden an dem ich mich entlang hangeln kann. Ich bin also für jeden Tipp/Hinweis (auch in Form von Links) dankbar.
Viele Grüße und besten Dank.
#include <stdarg.h>
void pr(char *fmt, ... ){
char buf[128]; // resulting string limited to 128 chars
va_list args;
va_start (args, fmt );
vsnprintf(buf, 128, fmt, args);
va_end (args);
Serial.println(buf);
}
#define TRIGGER_PIN 4
#define ECHO_PIN 8
volatile unsigned t1captured = 0;
volatile unsigned t1capval = 0;
volatile unsigned t1ovfcnt = 0;
volatile unsigned long t1time;
volatile unsigned long t1last = 0;
volatile unsigned long t1lastp = 0;
#define BUFFER_SIZE 96
volatile unsigned long int buffer[BUFFER_SIZE];
volatile byte head = 0;
volatile byte tail = 0;
void setup()
{
Serial.begin(250000);
while (!Serial) { ; /* wait for serial port to connect. Needed for native USB */}
TCCR1A = 0x0; // put timer1 in normal mode
TCCR1B = 0x2; // change prescaler to divide clock by 8
// clear any pending capture or overflow interrupts
TIFR1 = (1<<ICF1) | (1<<TOV1);
// Enable input capture and overflow interrupts
TIMSK1 |= (1<<ICIE1) | (1<<TOIE1);
pinMode(8, INPUT); // Feed the signal in here
pinMode(TRIGGER_PIN, OUTPUT);
}
void loop()
{
byte newhead;
unsigned long time1;
time1=millis();
digitalWrite(TRIGGER_PIN, 0);
delayMicroseconds(4);
digitalWrite(TRIGGER_PIN, 1);
delayMicroseconds(10);
digitalWrite(TRIGGER_PIN, 0);
TCCR1B |= (1<< ICES1); //switch edge detector to detect the rise
head=tail;
while(1)
{
if(head!=tail)
{
newhead = (head + 1) % BUFFER_SIZE;
head=newhead;
break;
}
if((millis()-time1)>50) break;
}
delayMicroseconds(5);
TCCR1B &= ~(1 << ICES1); //switch edge detector to detect the fall next time
head=tail;
while(1)
{
if(head!= tail)
{
newhead = (head + 1) % BUFFER_SIZE;
pr("%lu",buffer[newhead]);
head=newhead;
break;
}
if((millis()-time1)>50) break;
}
delay(10);
}
ISR(TIMER1_OVF_vect)
{
t1ovfcnt++; // keep track of overflows
}
ISR(TIMER1_CAPT_vect)
{
unsigned long t1temp;
// combine overflow count with capture value to create 32 bit count
// calculate how long it has been since the last capture
// stick the result in the global variable t1time in 1uS precision
t1capval = ICR1;
t1temp = ((unsigned long)t1ovfcnt << 16) | t1capval;
t1time = (t1temp - t1last) >> 1;
t1lastp=t1last;
t1last = t1temp;
tail = (tail + 1) % BUFFER_SIZE;
buffer[tail] = t1time;
}