AVT570/USB --> współpraca z debian / mysql

Zaczęty przez Tobas, 12 Sierpień 2014, 20:02

Tobas

Mam sobie 8-kanałowy system pomiaru temperatury z USB
Bez problemu działa mi to na Windows, ale marzy mi się logowanie danych na mysql.
Pod Ubuntu widzi to jako:
Bus 001 Device 010: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
Z opisu wynika że do komunikacji USB używa układu FT232R (IC2)

Tutaj jest link do sklepu gdzie nabyłem to ustrojstwo:
http://sklep.avt.pl/8-kanalowy-system-pomiaru-temperatury-z-usb-zestaw-do-samodzielnego-montazu.html

Pytanie - jak to ugryźć pod ubuntu?

biblioteki usb chyba wszystkie mam:

lsmod | grep ft
ftdi_sio               48930  0
usbserial              45014  1 ftdi_sio

cat /dev/ttyUSB0 - pokazuje mi krzaczki, cyklicznie - tylko nie krzaczków oczekuję a wartości temperatur ;)
Ktoś pomoże?

Szopler

Pewnie te krzaczki to wynik tego, że ktoś z AVT był zbyt leniwy żeby zrobić przesyłanie danych w postaci stringa i wysyła bezpośrednio zmienną (bajty).

Tobas

Cytat: Szopler w 12 Sierpień 2014, 20:47
Pewnie te krzaczki to wynik tego, że ktoś z AVT był zbyt leniwy żeby zrobić przesyłanie danych w postaci stringa i wysyła bezpośrednio zmienną (bajty).
Chyba nie, bo terminal pod Windą wg instrukcji pokazuje normalne wartości.

Szopler

Terminal pod linuksa na pewno też jakiś jest. Sprawdź tam dla parametrów połączenia 19200,8,N,1 (19200bps, 8 bitów danych, brak bitu parzystości, 1 bit stopu).

Tobas

Cytat: Szopler w 12 Sierpień 2014, 21:08
Terminal pod linuksa na pewno też jakiś jest. Sprawdź tam dla parametrów połączenia 19200,8,N,1 (19200bps, 8 bitów danych, brak bitu parzystości, 1 bit stopu).

Pod teminalem działa:


cu -l /dev/ttyUSB0 -s 19200
Connected.
T1= 26.6�C T2= 26.5�C T3= 26.5�C T4=        T5=        T6=        T7=        T8=       


Tylko jak to wrzucać do bazy?

Szopler

cron + mysql + ? (cos do wycinania tekstu z tej linijki) ;)

Tobas

Qrcze teraz nagle cat zaczął wyrzucać normalne dane:

sudo cat /dev/ttyUSB0
T1= 26.1�C T2= 26.0�C T3= 26.2�C T4=        T5=        T6=        T7=        T8=       

Może wcześniej po prostu coś źle skonfigurowałem na porcie.
Ale wynika z tego że działa.
Zrobię i wrzucę tu jeszcze skrypt do bazy i zamknę wątek.

mackal

Witajcie kamraci.

Postanowiłem podnieść wyzwanie i powalczyć z powyższym tematem kontynuując wątek.
Na początku spostrzeżenia do powyższych postów.
Polecenie
Cytat
sudo cat /dev/ttyUSB0 19200
Faktycznie zwraca pierwotnie krzaki.

Korzystamy więc z terminala
Cytat
cu -l /dev/ttyUSB0 -s 19200
Po uruchomieniu połączenia przez terminal sprawa się klaruje i dane pobierane są w czytelny sposób
Cytat
T1= 25.0�C T2=    ...   T4=        T7=        T8= 25.5�C

I teraz nie wiedząc jak zatrzymać połączenie zamknąłem terminal i połączyłem się kolejną sesją.
W tej chwili polecenie
Cytat
sudo cat /dev/ttyUSB0 19200
Zaczęło zwracać wyniki identyczne jak przy terminalu.

OK. Mamy rozpracowany temat wyświetlania danych w terminalu.
Chciałbym dalej oskryptować ten temat jednak nie mam pojęcia w jaki sposób pobrać do skryptu (jako tablicę, string, czy cokolwiek na czym przeprowadzimy obróbkę) dane pomiarowe z czujników.
Używając nawet w skrypcie bash'owym cat'a skrypt biegnie do polecenia odczytu (cat lub cu), a następnie realizuje w nieskończoność pobieranie danych z urządzenia.

Na chwilę obecną mam opracowany patent który nie jest optymalny, ale działa.
Mianowicie podczas uruchamiania systemu uruchamia się również prosty skrypt który przekierowuje dane z terminala do pliku
Cytat
cu -l /dev/ttyUSB0 -s 19200 >> /home/cu-test-01.tu
Aby uniknąć wielkich gabarytów po każdym uruchomieniu tworzymy nowy plik o unikalnym ID kasując stary już zbędny. Pełni on dla nas rolę tymczasowego kontenera danych.

Kolejny skrypt odpalany już cyklicznie co 2s w przypadku gdy nie chcemy opuścić żadnego pomiaru. Pobiera on z utworzonego pliku tymczasowego ostatnie 88 znaków co odpowiada jednemu pełnemu pomiarowi ze wszystkich czujników. Dalej już jest z górki, gdyż mając te dane w stringu możemy w łatwy sposób zapisać wszystko do bazy danych

Nie jestem jednak przekonany co do jakości takiego rozwiązania.
Tutaj pytanie do znawców i prośba o podpowiedź zarazem w sprawie rozwiązania problemu w sposób optymalny.

apohawk

nie mam takiego urządzenia, więc nie wiem, jak się zachowuje, ale mam pomysł:
cu -l /dev/ttyUSB0 -s 19200 | while read ...; do
parsowanie linii i wrzucanie do mysqla z timestampem
done

i chodziło by sobie coś takiego w tle odpalane jako usługa ze skryptu init.d z wykorzystanie start-stop-daemon
warunek konieczny: cu musiałoby wywalać tekst na stdout na bieżąco
No good deed goes unpunished.

mackal

#9
Pomysł ciekawy tylko wygląda na to, że po zastosowaniu "read" terminal może i pluje danymi, ale tak samo jak i do pliku jako jeden ciąg uzupełniany co 2s. Nie testowałem dodawania to init'a lecz z linii komend składowe i małego basha. Po różnych kombinacjach i tak efekt działania jest taki sam jak do tej pory, czyli oczekiwanie znaku zachęty i odczyt w tle.

A uruchamiałem takie coś:

Cytat
#!/bin/bash
cu -l /dev/ttyUSB0 -s 19200 | while read haha; do
echo $haha
echo $haha >> /home/read1.tu
done

A może coś pogmatwałem?

EDIT:

A jednak powyższe tworzy plik read1.tu w którym znajduje się takie coś:

Cytat
�� ^R^R$$UMOH�� T6= T7= T8= 26.2�C ^LT1= 25.4�C T2= T3= T4= T5= T6= T7= T8= 26.1�C ^LT1= 25.4�C T (*itd.......)
^GConnected.

^GDisconnected.


EDIT2:
No i nie do końca wszystko gra, gdyż powraca problem z samego początku. Odczyty narastają w buforze, a zapis i przekazanie do zmiennej następuje po zakończeniu sesji, nie zaś w jej trakcie.

krzyszp

Zaraz... Jeżeli to wyrzuca na konsolę (tty) dane tekstowe, to jaki problem jest z czytaniem bezpośrednio z USB?
Użyj mocy Lucke, chciałem powiedzieć - zajrzyj w źródła np. apki Radioaktywnego, żeby zobaczyć, jak to zrobić w C++...


Należę do drużyny BOINC@Poland
Moja wizytówka

mackal

Chwile mnie zeszło, ale walczę dzielnie. Radioaktywnego zostawiłem jako asa w rękawie, gdyż znalazłem wcześniej bibliotekę pyUSB. Wygląda że coś działa, jednak trzeba jeszcze rozkodować.
Otrzymuje zwrotnie z portu USB takie oto dane

Cytat
# sudo python usb.py
array('B', [1, 96, 12, 84, 49, 61, 32, 50, 53, 46, 51, 176, 67, 32, 84, 50, 61, 32, 32, 32, 32, 32, 32, 32, 32, 84, 51, 61, 32, 32, 32, 32, 32, 32, 32, 32, 84, 52, 61, 32, 32, 32, 32, 32, 32, 32, 32, 84, 53, 61, 32, 32, 32, 32, 32, 32, 32, 32, 84, 54, 61, 32, 32, 32])

array('B', [1, 96, 32, 32, 32, 32, 32, 84, 55, 61, 32, 32, 32, 32, 32, 32, 32, 32, 84, 56, 61, 32, 50, 53, 46, 52, 176, 67, 32])

array('B', [1, 96])

array('B', [1, 96])

array('B', [1, 96])


I wszystko zaczynało wyglądać fajnie jednak zatrzymałem się na tym właśnie kroku.

Powalczę jeszcze trochę z tą biblioteką pyUSB, chyba że ktoś z tym już współpracował i może coś podpowiedzieć to byłbym wdzięczny.

Daje sobie czas do przyszłego tygodnia i zacznę rozpracowywać tego Radioaktywnego.

Szopler

Kody ASCII poszczególnych znaków?

32 to spacja

mackal

Cytat: Szopler w 07 Lipiec 2016, 13:27
Kody ASCII poszczególnych znaków?

32 to spacja

BINGO ;)

Do rozkodowania w Pythonie służy funkcja chr() jednak mam teraz problem taki, że wewnątrz pętli to polecenie jak i chyba każde inne od 'print' wywala mi błąd "IndentationError: unexpected indent"

Gdyby ktoś ambitny chciał pociągnąć temat to proszę pisać.

Osobiście wczoraj odpuściłem Pythona i rozwiązałem problem następująco:

1) Skrypt w Pythonie z użyciem biblioteki 'pyUSB' odczytuje z czujników dane w postaci ASCII->DEC
2) Następnie dane wyjściowe w postaci widocznej w cytacie z poprzedniego maila z dodaną aktualną datą i godziną umieszczam w pliku przy pomocy shell'a "python usb.py >> plikwyjsciowy.txt"
3) Mając takie dane możemy użyć już albo bezpośrednio PHP albo BASH'a do którego wczytamy plik, a następnie przetworzymy i wyślemy do bazy danych
4) Warstwa ekspozycji to już kwestia PHP

Kret_polny

Gdybyś wkleił kod pythona łatwiej byłoby coś powiedzieć.
Python jest "wrażliwy" na wcięcia. Jedna źle postawione spacja może doprowadzić do takiego błędu.

Jakiej wersji Pythona używasz?

btw. Korzystasz z jakiegoś IDE do Pythona? Np. plugin do Eclipsa o nazwie Dynamic Languages Toolkit albo PyCharm? Ułatwiają kodowanie. :)

TJM

Lukanie w źródła standardowej aplikacji Rad@H niewiele raczej tu pomoże, bo sensory nie gadają z kompem przez serial (na USB czy natywny wszystko jedno), tylko faktycznie przez USB i komunikacja tam wygląda zupełnie inaczej.

Po serialu (wirtualnym na USB - lub sprzętowym) rozmawia z sensorem aplikacja dla sensora GMC, na linuksie wykorzystuje do tego mix c/c++ i bibliotekę termios ("termios.h"), która teoretycznie chyba służy do całkowicie innych rzeczy ale działa i bezproblemowo się tym gada do COMa (niezależnie czy to /dev/ttyUSB czy jakiś "starego typu" sprzętowy). Mogę źródła gdzieś wrzucić do wglądu.



W razie jakiejś pilniejszej sprawy - jestem często dostępny na kanale IRC B@P, na forum czasami zapominam zajrzeć lub nie mam czasu.

mackal

Zamieszczam razem ze wszystkimi moimi komentami powstałymi po różnych próbach i kombinacjach.
Poniższa wersja zwraca tablice jak w postach powyższej w formacie ASCII DEC

Problem rozwiązałem tak jak opisałem sprawę wyżej. Rozkodowuje całość w PHP ;)

W tym momencie można byłoby dla potomnych doprowadzić temat do postaci takiej, iż skrypt odczytuje, rozkodowuje i w postaci przyjemnej dla użytkownika przekazuje dalej GET'em albo w ogóle zapisuje bezpośrednio do bazy.
Oczywiście jako sztuka dla sztuki.



#!/usr/bin/python

import sys
import usb.core
import usb.util
import time

czas = time.time()
print czas
print ",152880"


dev = usb.core.find(idVendor=0x0403, idProduct=0x6001)

print dev

interface = 0
endpoint = dev[0][(0,0)][0]

if dev.is_kernel_driver_active(interface) is True:
  dev.detach_kernel_driver(interface)
  usb.util.claim_interface(dev, interface)
reads = 0

while reads < 3:
    try:

        data = dev.read(endpoint.bEndpointAddress,endpoint.wMaxPacketSize)

        reads += 1


#rxdata = ''.join([chr(x) for x in data])
#rxdata = ''.join(data)
#print rxdata
#print ---------

#       zmienna = ''
#       sekwencja = ("a", "b", "c")
        #print zmienna.join(sekwencja)
        #print zmienna
        #print sekwencja
        print data
#       print '------------------'

#               print time.localtime()

        #       print czas[3], ':', czas[4]

#       test = data[5]
#       print test

#               try:
#               for x in data:
#               print x, len(x)

#               except:
#                       print 'err'
#                       continue

#       print '------------------'
        #       plik64 = open("plik", "w")
        #       plik64.writelines(test)
        #       plik64.close()

    except usb.core.USBError as e:

        data = None
        if e.args == ('Timeout',):
            continue

usb.util.release_interface(dev, interface)
dev.attach_kernel_driver(interface)

#print '????????????????????????????????'
#print czas