Pomiar przyspieszenia - część 2 (029; 10.02.2012; arduino)
Rozwijam temat przedstawianego wcześniej pomiaru przyspieszenia z użyciem taniego czujnika i Arduino. 23 stycznia 2011 przetestowałem możliwość odbierania sygnałów pomiarowych z użyciem języka programowania Python. Na początek filmik prezentujący działanie opisanego układu:
Simple vibration measurements from MyInventions on Vimeo.
Akcelerometr
W opisywanym projekcie zastosowałem akcelerometr LIS3L06AL, który szczegółowo opisałem w tym artykule.
Najprostrzy kod do Arduino jaki tu zastosowałem:
void setup() { Serial.begin(115200); } void loop() { //delay(1); // 1kHz delayMicroseconds(500); //2kHz Serial.print(analogRead(1)/4, BYTE); }
Pragnę podkreślić, że pomiary te mają charakter poglądowy i są bardziej zabawą niż rzeczywistymi pomiarami. Osoby zainteresowane pomiarami inżynierskimi zachęcam do nauczenia się programowania mikrokontrolerów w języku C (używanie funkcji delay tak jak tu w przykładzie jest prawdę mówiąc ogromnym błędem, robię tu tak tylko dla uproszczenia, w rzeczywistości powinno się użyć timera sprzętowego, co wymaga od czytelnika dużo większej wiedzy - na temat rejestrów procesora, preskalerów itd). Również budowa układu pomiarowego ma niezwykle istotny wpływ na jakość otrzymanych wyników.
Zapis do pliku
Aby odbierać sygnały z portu szeregowego COM przesłane od Arduino po kablu USB użyłem oprogramowania języka Python wraz z biblioteką do obsługi komunikacji szeregowej. W moim przypadku były to:
- Python w wersji 3.2 (pobierz),
- bibliteka pySerial w wersji 2.5 dla Pythona 3.2 (pobierz).
Poniżej przykładowy prosty kod, który należy zapisać do pliku tekstowego i skrypt ten uruchomić w Pythonie (z konsoli lub skryptem shell/bat). Kod spowoduje przekierowanie danych z portu szeregowego bezpośrednio do pliku tekstowego w ilości tysiąca próbek. Taki sposób zapisu można wykorzystać, aby później dane importować do arkusza kalkulacyjnego.
textFile = open('C:\\data.txt', "w") import serial arduino = serial.Serial() arduino.port = 'COM4' arduino.baudrate = 115200 arduino.timeout = 2 #sec print(arduino) arduino.open() byte = arduino.read(1) if len(byte) != 0: int = ord(byte) #print (int) s = str(int)+'\n' textFile.write(s) arduino.close() textFile.close()
Wizualizacja
Aby narysować najprostszy wykres pobranych sygnałów zaproponowałem tu użycie biblioteki pygame (w wersji 1.9.1 dla pythona 3.2; pobierz). Co prawda jest stworzona do dużo bardziej skomplikowanych rzeczy, ale tu pozwoliła prosto stworzyć okno rysunkowe i szybko nanosić nań wykresy. A oto przykładowy kod:
import pygame import sys pygame.init() width = 1000 height = 180 window = pygame.display.set_mode((width, height)) import serial arduino = serial.Serial() arduino.port = 'COM4' arduino.baudrate = 115200 arduino.timeout = 2 #sec print(arduino) arduino.open() px = 0 py = 0 x = 0 y = 0 while True: byte = arduino.read(1) if len(byte) != 0: y = ord(byte) x += 1 pygame.draw.line(window, (255, 255, 255), (px, py), (x, y)) pygame.display.flip() #odświeżenie obrazu px = x py = y if x >= width: #czyszczenie okna px = 0 x = 0 window.fill((0, 0, 0)) for event in pygame.event.get(): if event.type == pygame.QUIT: # zamknięcie okna sys.exit(0) elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: # ESC sys.exit(0) #else: #print(event)
W razie niejasności powyższego kodu, odsyłam do obszernej dokumentacji i różnych poradników w internecie. Zaproponowana tu prędkość przesyłu i wyświetlania 2tys. próbek na sekundę była prawie maksymalną, przy jakiej uzyskałem działanie układu bez rosnącego opóźnienia między ruchem czujnika a przebiegiem wykresu (w końcu doszło by do przepełnienia bufora i utraty danych). Dla uzyskania wyższych częstotliwości pomiaru można zmniejszyć wielkość obszaru rysunkowego oraz ograniczyć odświeżanie obrazu.