PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : HC-SR04 an MK2 anbinden mit Atmel Studio und Labview auswertung



Jeans
14.04.2016, 11:58
Hallo liebe Gemeinde,

kurze Info ich besuche zur Zeit die Techniker Schule (Medizintechnik) nun haben wir ein Proejkt bekommen andem wir einen Ultraschall Sensor an ein MK2 anbinden sollen und dieses dann mit Labview auswerten sollen.
Allerdings habe ich von dem MK2 board leider echt nicht die große Ahnung und vom Atmel Studio auch nicht.


Gibt es hier irgendjemand der das schonmal gemacht hat?

Mein Problem ist das ich nicht weiß wie ich den Aus/Eingang so Programmier das ich was mit der ausgegebenen "Frequenz" was anfangen kann.:confused:



Was ich bis jetzt hinbekommen habe ist die Anbindung des MK2 so dass ich den "Integrierten" Lichtsensor bereits mit Labview auslesen kann.

Bin da echt nicht so fit auf dem Gebiet wäre echt nett wenn mir da jemand helfen könnte.

Mit freundlichen Grüßen
Jens

morob
14.04.2016, 15:51
was für ein us sensor verwendet ihr denn?
mk2 ist bei mir ein programmerboard.

Jeans
14.04.2016, 16:55
Danke für die schnelle Antwort

Wie oben beschrieben verwenden wir den den SR-04
http://www.micropik.com/PDF/HCSR04.pdf

Was soll das denn bedeuten das das mk2 ein programmerboard ist ?
http://www.voelkner.de/products/29877/Myavr-Board-Mk2-USB.html?ref=43&products_model=Q07636&gclid=CLr2qsm-jswCFfUV0wodwL8Arw
Dieses board müssen wir verwenden.

BMS
14.04.2016, 19:42
Hallo und willkommen im Forum.

Was ich bis jetzt hinbekommen habe ist die Anbindung des MK2 (http://www.mikrocontroller-elektronik.de/isp-programmer-fuer-arduino-bascom-und-atmel-studio/) so dass ich den "Integrierten" Lichtsensor bereits mit Labview auslesen kann.
Das hört sich erst mal nicht schlecht an und ist eigentlich schon die halbe Miete :D
Behalte schon mal das aktuelle Programm für den Lichtsensor, an einer Kopie kann man dann den Ultraschallsensor einrichten.

Der Ultraschallsensor braucht erst mal Versorgungsspannung von 5V. Auf dem Mk2 müsste es dazu Anschlüsse geben, wo 5V und GND ("Ground","minus","0Volt") rauskommen.
Dann geht es weiter: Der Ultraschallsensor hat zwei Steuersignale, und zwar einen Trigger-Eingang und einen Echo-Ausgang.
Das Prinzip steht schon in deinem verlinkten Datenblatt drin.
Auf Deutsch:
Der Mk2 muss an die Trigger-Leitung einen kurzen Impuls geben.
Das Ultraschallmodul fängt dann mit der Messung an.
Inzwischen muss das Mk2 auf der Echo-Leitung warten bis ein Signal anfängt, und messen wie lange es dauert, bis es wieder aufhört.
Die Dauer des Signals entspricht der Zeit, die der Schall braucht, um gesendet und vom Ultraschallmodul wieder empfangen zu werden.



Hier als Rezept:
- Suche den Anschluss am Mk2 wo 5V und 0V (GND) rauskommen. Damit wird das Ultraschallmodul versorgt.
- Suche zwei freie digitale Anschlüsse des Mk2. Mit digital meine ich, dass man damit z.B. eine LED ansteuern kann.
- Von den zwei digitalen Anschlüssen suchst du die Portbezeichnungen und Nummern raus (z.B. PB3 oder so was)
- In der Software musst du nun einen davon als Ausgang schalten (für den "Trigger") und den anderen als Eingang (für das "Echo") und entsprechend mit dem Ultraschallsensor verbinden. Damit sicher nichts kaputt geht, kann man auch noch Widerstände in diese Leitungen setzen, z.B. 100 Ohm.
- Der Rest ist dann Software. Prinzip:



Triggerpin auf Ausgang schalten und auf low.
Echopin auf Eingang schalten.
Sonstige Vorbereitungen. Was weiß ich.

Das folende in einer Endlosschleife:
Setze den Triggerpin auf high
Warte einen kurzen Moment (mindestens 10µs laut Datenblatt, aber auch nicht zuuuu lange)
Setze den Triggerpin auf low
warte bis der Echopin logisch high wird
solange der Echopin auf high ist, zähle eine Variable hoch
höre auf zu zählen, wenn Echopin low wird
gebe den Zählerstand der Variable so aus, wie du es schon mit dem Lichsensor gemacht hast
Setze die Variable wieder auf 0, sonst gibt es beim nächsten Durchlauf Mist
Warte einen Moment (z.B. 0,05 Sekunden) damit keine Mehrfachechos gemessen werden


Den Zählerstand muss man noch in die entsprechende Entfernung umrechnen.
Die Schallgeschwindigkeit: In einer Sekunde schafft der Schall etwa 340 Meter. In einer Millisekunde schafft er dann 34 cm. usw.

Wie man Pins schaltet, Schleifen macht, Wartezeiten einbaut usw. findest du sicher in der myavr-Dokumentation.

Am Ende noch mal gut umrühren, abschmecken und so kann man's dann servier'n. Guten Appetit ;)

Grüße,
Bernhard

Jeans
15.04.2016, 11:36
Vielen Dank! Ich werde deine Anleitung jetzt mal weiter verfolgen und falls fragen aufkommen mich hier nochmals melden.

Gruß Jens

morob
15.04.2016, 11:46
http://www.voelkner.de/products/29877/Myavr-Board-Mk2-USB.html?ref=43&products_model=Q07636&gclid=CLr2qsm-jswCFfUV0wodwL8Arw[/URL]
Dieses board müssen wir verwenden.

kannte ich noch nicht :)

Jeans
16.04.2016, 07:29
Dann melde ich mich wohl hier nochmal :D

Nachdem ich mich dran versucht habe und zu keinem Vernüftigen Ergebnis kam hier mal mein Code den ich bis jetzt erstellt habe. Mit ein bisschen hilfe muss ich dazu sagen.

Der Anschluss am Board ist mir auch recht schlüssig und sollte ich richtig gemacht haben.

Vielleicht kann ja jemand mal drüber schauen und mir Konkret sagen was ich noch ändern muss oder kurz einfach überarbeiten.

Danke schonmal
Gruß Jens


// ------------------------------------------------------------------------------------
// Einbinden von Bibliotheken; Festlegen von Einstellungen
// ------------------------------------------------------------------------------------

#define F_CPU 3686400 // Festlegen µC-Takt
#include <avr\io.h> // Bibliothek der Namen der Register
#include <util\delay.h> // Bibliothek mit Warteroutinen
#include <avr/interrupt.h> // Bibliothek mit Interrupts
#include <stdint.h> // Bibliothek mit Datentypen

// ------------------------------------------------------------------------------------
// Deklarationen von globalen Variablen
// ------------------------------------------------------------------------------------

volatile uint8_t uart_str_complete = 0; // Deklaration uart_str_complete
volatile char uart_string[30] = ""; // Deklaration uart_string
volatile uint8_t uart_str_count = 0; // Deklaration uart_str_count

uint16_t Analogwert = 0;

// ------------------------------------------------------------------------------------
// Senden an PC über serielle Schnittstelle (USB)
// ------------------------------------------------------------------------------------

void uartPutChar(char data) // 'uartPutChar' zur Datenübertragung
{
while (!(UCSRA & (1<<UDRE))); // Endlosschleife solange UDR nicht leer ist

UDR = data; // 'data' in 'UART I/O Data Register' schreiben
}

void print(const char buffer1[]) // selbsterstellte Strings an PC senden
{
for(int i=0; buffer1[i]!=0; i++) // Schleife durchlaufen bis alle Daten verarbeitet
{
uartPutChar(buffer1[i]); // Aufruf 'uartPutChar'
}
uartPutChar('\n'); // Endzeichen '\n' zur Markierung des Übertragungsendes
}

// ------------------------------------------------------------------------------------
// AD-Wandlung von Kanal X
// ------------------------------------------------------------------------------------

int AD_Wandlung(int x) // Analog-Digital-Wandlung
{
cli(); // globale Interrupts deaktivieren

ADMUX = x; // Kanal einstellen
ADMUX |= (1<<REFS0); // AVCC als Referenzspannung, Wandlungsergebnis linksbündig
// um die 2 niederwertigsten Bits rauszufiltern (wegen Flatterwerten)
ADCSRA = 0b11000101; // Frequenzvorteiler auf 32 setzen
// und ADC0 als Analogeingangsbit aktivieren
while(bit_is_set(ADCSRA,ADSC)); // Warten bis Wandlung abgeschlossen

Analogwert = ADCW; // ADCW-Wert in Analogwert übergeben

sei(); // globale Interrupts aktivieren

return Analogwert; // Analogwert an Hautprogramm zurückgegeben
}

// ------------------------------------------------------------------------------------
// Interrupt empfangen
// ------------------------------------------------------------------------------------

ISR(USART_RXC_vect) // Interrupt-Sub-Routine USART_RXC_vect
{
unsigned char nextChar; // Deklaration 'nextChar'
nextChar = UDR; // Daten 'UART I/O Data Register' in 'nextChar'

if(uart_str_complete == 0) // Wenn uart_str_complete=0, dann
{
if(nextChar != '#') // Wenn 'nextChar' nicht '#', dann
{
uart_string[uart_str_count] = nextChar; // Daten 'nextChar' in String ablegen
uart_str_count++; // uart_str_count inkrementieren
}
else // sonst
{
uart_string[uart_str_count] = '\0'; // uart_string[] Ende des Strings '\0' zuweisen
uart_str_count = 0; // 0 in uart_str_count Null schreiben
uart_str_complete = 1; // 1 in uart_str_complete schreiben
}
}
}

//-----------------------------------------------------------------------------------
// main
//-----------------------------------------------------------------------------------

int main ()
{
// 6 Eingänge = PIND,2 bis PIND,7
// 6 Ausgänge = PINB,0 bis PINB,5

DDRD |= 0b00000000; // Datenrichtung Port D 0=Eingang 1=Ausgang
DDRB |= 0b11111111; // Datenrichtung Port B 0=Eingang 1=Ausgang
DDRC |= 0b00000000; // Datenrichtung Port C 0=Eingang 1=Ausgang

PORTD |= 0b11111100; // Ausgänge von Port D
PORTB |= 0b00000000; // Ausgänge von Port B
PORTC |= 0b11111111; // Ausgänge von Port C

UBRRL = 23; // 9600 Baud siehe Baudratentabelle
UCSRB = 0b10011000; // Interrupt RX ein, Senden & Empfangen ein
UCSRC = 0b10000110;

sei(); // globale Interrupts aktivieren

// Programmvariablen

uint16_t AD_Wert=0;
char Eingaenge[15];
char AD_WertBuffer[15];

while (1) // Mainloop-Begin
{
_delay_ms(100); // 100 ms warten

// empfangene Ausgangsdaten von PC auswerten und ausgeben

if(uart_str_complete == 1) // Wenn String komplett Empfangen, dann Auswertung:
{
if(uart_string[0] == 'S') // Wenn erste Stelle = 'S', dann
{

if(uart_string[1] == '1') // Wenn zweites Bit = '1', dann
{

PORTB |= (1<<PB0); // Ausgang Port B,0 = 1
}
else // Wenn zweites Bit = '0', dann
{
PORTB &= ~(1<<PB0); // Ausgang Port B,0 = 0
}

if(uart_string[2] == '1') // Wenn drittes Bit = '1', dann
{

PORTB |= (1<<PB1); // Ausgang Port B,1 = 1
}
else // Wenn drittes Bit = '0', dann
{
PORTB &= ~(1<<PB1); // Ausgang Port B,1 = 0
}

if(uart_string[3] == '1') // Wenn viertes Bit = '1', dann
{

PORTB |= (1<<PB2); // Ausgang PortB,2 = 1
}
else // Wenn viertes Bit = '0', dann
{
PORTB &= ~(1<<PB2); // Ausgang PortB,2 = 0
}

if(uart_string[4] == '1') // Wenn fünftes Bit = '1', dann
{

PORTB |= (1<<PB3); // Ausgang PortB,3 = 1
}
else // Wenn fünftes Bit = '0', dann
{
PORTB &= ~(1<<PB3); // Ausgang PortB,3 = 0
}

if(uart_string[5] == '1') // Wenn sechstes Bit = '1', dann
{

PORTB |= (1<<PB4); // Ausgang PortB,4 = 1
}
else // Wenn sechstes Bit = '0', dann
{
PORTB &= ~(1<<PB4); // Ausgang PortB,4 = 0
}

if(uart_string[6] == '1') // Wenn siebtes Bit = '1', dann
{

PORTB |= (1<<PB5); // Ausgang PortB,5 = 1
}
else // Wenn siebtes Bit = '0', dann
{
PORTB &= ~(1<<PB5); // Ausgang PortB,5 = 0
}
}
uart_str_complete = 0; // Freigabe für Empfang weiterer Strings über RS232
}

// Eingänge zusammenstellen
// Eingänge mit '0' initialisieren

Eingaenge[0] = '0';
Eingaenge[1] = '0';
Eingaenge[2] = '0';
Eingaenge[3] = '0';
Eingaenge[4] = '0';
Eingaenge[5] = '0';

// Eingangs-PINs liegen an PULL-UP-Widerstand und werden bei Beschaltung auf Masse gezogen

if(bit_is_clear(PIND,2)) // Wenn Eingang PIND,2 = 0, dann
{
_delay_ms(23); // Entprellzeit

if(bit_is_clear(PIND,2)) // Wenn Eingang PIND,2 nach Entprellung = 0, dann
{
Eingaenge[0]='1'; // binärer Wert an LabVIEW
}
}

if(bit_is_clear(PIND,3)) // Wenn Eingang PIND,3 = 0, dann
{
_delay_ms(23); // Entprellzeit

if(bit_is_clear(PIND,3)) // Wenn Eingang PIND,3 nach Entprellung = 0, dann
{
Eingaenge[1]='1'; // binärer Wert an LabVIEW
}
}

if(bit_is_clear(PIND,4)) // Wenn Eingang PIND,4 = 0, dann
{
_delay_ms(23); // Entprellzeit

if(bit_is_clear(PIND,4)) // Wenn Eingang PIND,4 nach Entprellung = 0, dann
{
Eingaenge[2]='1'; // binärer Wert an LabVIEW
}
}

if(bit_is_clear(PIND,5)) // Wenn Eingang PIND,5 = 0, dann
{
_delay_ms(23); // Entprellzeit

if(bit_is_clear(PIND,5)) // Wenn Eingang PIND,5 nach Entprellung = 0, dann
{
Eingaenge[3]='1'; // binärer Wert an LabVIEW
}
}

if(bit_is_clear(PIND,6)) // Wenn Eingang PIND,6 = 0, dann
{
_delay_ms(23); // Entprellzeit

if(bit_is_clear(PIND,6)) // Wenn Eingang PIND,6 nach Entprellung = 0, dann
{
Eingaenge[4]='1'; // binärer Wert an LabVIEW
}
}

if(bit_is_clear(PIND,7)) // Wenn Eingang PIND,7 = 0, dann
{
_delay_ms(23); // Entprellzeit

if(bit_is_clear(PIND,7)) // Wenn Eingang PIND,7 nach Entprellung = 0, dann
{
Eingaenge[5]='1'; // binärer Wert an LabVIEW
}
}

// AD_Wert ermitteln

AD_Wert = AD_Wandlung(0); // Analog-Digital-Wandlung aufrufen
itoa(AD_Wert, AD_WertBuffer, 10); // Integer to ASCII; 10 = dezimal

// AD_Wert in Eingangs-String einarbeiten

if(AD_Wert <10) // Wenn Eingangswert<10 -> Tausender, Hunderter, Zehner = '0'
{
Eingaenge[6] = '0'; // Tausenderstelle
Eingaenge[7] = '0'; // Hunderterstelle
Eingaenge[8] = '0'; // Zehnerstelle
Eingaenge[9] = AD_WertBuffer[0]; // Einerstelle
}
else if(AD_Wert <100) // Wenn Eingangswert<100 -> Tausender, Hunderter = '0'
{
Eingaenge[6] = '0'; // Tausenderstelle
Eingaenge[7] = '0'; // Hunderterstelle
Eingaenge[8] = AD_WertBuffer[0]; // Zehnerstelle
Eingaenge[9] = AD_WertBuffer[1]; // Einerstelle
}
else if(AD_Wert <1000) // Wenn Eingangswert<1000 -> Tausender = '0'
{
Eingaenge[6] = '0'; // Tausenderstelle
Eingaenge[7] = AD_WertBuffer[0]; // Hunderterstelle
Eingaenge[8] = AD_WertBuffer[1]; // Zehnerstelle
Eingaenge[9] = AD_WertBuffer[2]; // Einerstelle
}
else // sonst Eingangswert vierstellig (>=1000)
{
Eingaenge[6] = AD_WertBuffer[0]; // Tausenderstelle
Eingaenge[7] = AD_WertBuffer[1]; // Hunderterstelle
Eingaenge[8] = AD_WertBuffer[2]; // Zehnerstelle
Eingaenge[9] = AD_WertBuffer[3]; // Einerstelle
}

Eingaenge[10] = '\0'; // Ausgabestring beenden mit \0

// gesamten Eingangs-String an PC senden

print (Eingaenge);
}
}