Unter Sonographie versteht man die Untersuchung innerer Körperteile mittels Ultraschall. Ein kurzer Ultraschallpuls breitet sich dabei innerhalb des Körpers fort und wird an inneren Strukturen reflektiert und gelangt wieder zum Sender/Empfänger. Je tiefer im Körper diese Reflexion stattfindet, umso später trifft das Echo wieder beim Empfänger ein. Erfasst man also die Reflexionen zeitlich innerhalb einer bestimmten Zeitspanne nach Aussenden des Ultraschallpulses, so liefert dies auch eine Ortsauflösung der inneren Körpersturktur.
Der zum Einsatz kommende Ultraschallkopf wird eigentlich zur Bestimmung von Lackdicken verwendet. Das entsprechende Modell GM100 ist für rund 60 Euro auf ebay erhältlich (engl. GM100 Thickness gauge). Eigentlich benötigt man für dieses Projekt nur den Ultraschall-Sende/Empfängerkopf. Dieser kann für rund 25 Euro auch separat auf ebay erworben werden.
Die empfohlene Arbeitsfrequenz liegt bei 5 MHz. Deshalb steuere ich den US-Sender nur sehr kurz (rund 200 ns) und einmalig an. Dabei besitzt der am Sender anliegende Spannungspuls eine Amplitude von rund 100V. Erst durch eine so hohe Spannung werden die sehr schwachen Echos im menschlichen Körper sichtbar. Verwendet man anstelle des Körpers einen Metallgegenstand, so wären bereits geringere Pulsspannungen ausreichend.
Der Empfänger liefert ein nur sehr schwaches Signal, welches mittels mehrerer Operationsverstärker-Stufen verstärkt wird. Im Anschluss an die Verstärkung folgt eine sog. Peak-Detektor-Schaltung, denn ich benötige vom Echo quasi nur den positiven, einhüllenden Spannungsverlauf. Dieser wird dann an einen analogen Eingang des Arduino Due gelegt. Ich wählte deshalb den Arduino Due, da dieser über eine höhere/schnellere Leserate analoger Signale verfügt. Ein einzelner analoger Lesevorgang dauert dabei rund 0.4 µs. Insgesamt werden pro Scan 300 bzw. 600 Spannungen eingelesen, was eben 120 bzw. 240 µs in Anspruch nimmt. Im Anschluss daran werden die eingelesenen Spannungen in einen Grauwert umgewandelt und dann untereinander in Form von kurzen horizontalen Strichen mit dem jeweiligen Grauwert gezeichnet. Ein starkes Eche entspricht so einer hohen, eingelesenen Spannung und dementsprechend hell wird auch der kurze Strich gezeichnet. Im 240µs-Modus wird nur jeder zweite, eingelesene Spannungswert graphisch dargestellt. Jeder Scan besitzt eine eigene Spalte auf dem Display. Dies bedeutet, dass sich nacheinander Bilder/Scans von links nach rechts auftun. Sind alle Spalten am Bildschirm voll, beginnt die Darstellung wieder mit der ersten Spalte ganz links auf dem Bildschirm.
Obwohl mein Ultraschallgerät mit einem komerziellen Produkt in keinster Weise mithalten kann, bin ich dennoch zufrieden, damit einzelne Körperechos erfassen zu können. Dabei dürfte es sich zum Beispiel um das Echo an Knochen handeln.
Arduino-Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
#define pin_output 5 #define pin_input_magnification 4 #define pin_input_sleep 3 unsigned long start_time; unsigned long stop_time; unsigned int values[600]; // Array mit den eingelesenen Spannungswerten int i, j; int Trigger_time; // Dauer des Triggerpulses int gray_value; #define CENTRE 240 #include <UTFT.h> // Declare which fonts we will be using extern uint8_t SmallFont[]; UTFT myGLCD (ILI9486,38,39,40,41); // ========================= // ========= SETUP ========= // ========================= void setup() { Serial.begin(115200); REG_ADC_MR = 0x10380080; // change from 10380200 to 10380080, 1 is the PREESCALER and 8 means FREERUN ADC -> ADC_CHER = 0x03; // enable ADC on pin A7 pinMode(pin_output, OUTPUT); pinMode(pin_input_magnification, INPUT); // Switch-input for magnification pinMode(pin_input_sleep, INPUT); // Switch-input for sleep-mode digitalWrite(pin_output, LOW); Trigger_time = 1; // Dauer des Triggerpulses // Setup the LCD myGLCD.InitLCD(); myGLCD.setFont(SmallFont); myGLCD.clrScr(); myGLCD.setColor(255, 255, 0); myGLCD.fillRect(0, 0, 432, 13); myGLCD.setColor(0, 0, 0); myGLCD.setBackColor(255, 255, 0); myGLCD.print("Sonographie - stoppi", CENTER, 1); } // ======================== // ========= LOOP ========= // ======================== void loop() { for (j = 0; j < 18; j++) // Darstellung von 18 scans nebeneinander in x-Richtung { // Ausgabe des Triggersignals // ========================== digitalWrite(pin_output,HIGH); //delayMicroseconds(Trigger_time); digitalWrite(pin_output,LOW); // Einlesen der US-Reflexionen // =========================== //start_time = micros(); if (digitalRead(pin_input_magnification) == LOW) // ohne Zeitstreckung Einlesen von 300 Werten; erfasste Zeitspanne = 120 µsec { for(i = 0; i < 300; i++) { while((ADC->ADC_ISR & 0x03)==0); // wait for conversion values[i] = ADC->ADC_CDR[0]; //get values //delayMicroseconds(1); } } else // mit Zeitstreckung Einlesen von 600 Werten; erfasste Zeitspanne = 240 µsec { for(i = 0; i < 600; i++) { while((ADC->ADC_ISR & 0x03)==0); // wait for conversion values[i] = ADC->ADC_CDR[0]; //get values //delayMicroseconds(1); } } //delayMicroseconds(100); //delay(5); /* stop_time = micros(); Serial.print("Total time for 300 values: "); Serial.print(stop_time-start_time); Serial.println(" microseconds"); Serial.print("Average time in microseconds per conversion: "); Serial.println((float)(stop_time-start_time)/300); */ /* Serial.println("Values: "); for(i = 0;i < 600; i++) { Serial.println(values[i]); } */ // Zeichnen des scans // ================== if (digitalRead(pin_input_magnification) == LOW) // ohne Zeitstreckung Darstellung der ersten 300 eingelesenen Werte { myGLCD.setColor(255, 255, 255); myGLCD.setBackColor(0, 0, 0); myGLCD.drawLine(440, 15, 440, 15 + 300); myGLCD.drawLine(440, 15, 445, 15); myGLCD.drawLine(440, 65, 445, 65); myGLCD.drawLine(440, 115, 445, 115); myGLCD.drawLine(440, 165, 445, 165); myGLCD.drawLine(440, 215, 445, 215); myGLCD.drawLine(440, 265, 445, 265); myGLCD.drawLine(440, 315, 445, 315); myGLCD.print("0 us", 450, 10); myGLCD.print("20 ", 450, 60); myGLCD.print("40 ", 450, 110); myGLCD.print("60 ", 450, 160); myGLCD.print("80 ", 450, 210); myGLCD.print("100", 450, 260); myGLCD.print("120", 450, 310); for(i = 0; i < 300; i++) { values[i] = map(values[i], 0, 4095, 0, 255); // Bringe die Helligkeitswerte in den Zahlenbereich [0,255] //values[i] = random(255); myGLCD.setColor(values[i], values[i], values[i]); myGLCD.fillRect(j * 24, 15 + i, j * 24 + 23, 15 + i); } } else // mit Zeitstreckung Darstellung nur jedes zweiten Werts der 600 eingelesenen Werte { myGLCD.setColor(255, 255, 255); myGLCD.setBackColor(0, 0, 0); myGLCD.drawLine(440, 15, 440, 15 + 300); myGLCD.drawLine(440, 15, 445, 15); myGLCD.drawLine(440, 65, 445, 65); myGLCD.drawLine(440, 115, 445, 115); myGLCD.drawLine(440, 165, 445, 165); myGLCD.drawLine(440, 215, 445, 215); myGLCD.drawLine(440, 265, 445, 265); myGLCD.drawLine(440, 315, 445, 315); myGLCD.print("0 us", 450, 10); myGLCD.print("40 ", 450, 60); myGLCD.print("80 ", 450, 110); myGLCD.print("120", 450, 160); myGLCD.print("160", 450, 210); myGLCD.print("200", 450, 260); myGLCD.print("240", 450, 310); for(i = 0; i < 300; i++) { values[2*i] = map(values[2*i], 0, 4095, 0, 255); // Bringe die Helligkeitswerte in den Zahlenbereich [0,255] //values[2*i] = random(255); myGLCD.setColor(values[2*i], values[2*i], values[2*i]); myGLCD.fillRect(j * 24, 15 + i, j * 24 + 23, 15 + i); } } // Pause-Taster abfragen // ===================== if (digitalRead(pin_input_sleep) == HIGH) { while(digitalRead(pin_input_sleep) == HIGH) { // sleeping } } delay(1000); } } |