Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[PHP] Sterowanie USB przez stronę WWW

gsmphone 11 Jun 2010 10:25 5784 26
Relpol
  • #1
    gsmphone
    Level 13  
    Witam,

    Mam taki problem. Mam w do usb kartę która ma 2 przekaźniki. Działa dobrze z aplikacjami Windows.. Tzn mam program gdzie ustawiam com a potem 2 przyciski włącz/wyłącz.
    Problem w tym że chciałem napisać aplikacje pod www żeby robiło to samo. Podobno jak się podłączy urządzenie pod USB to windows przypisuje mu ścieżkę:
    /dev/ttyUSB0

    Więc zrobiłem małą aplikacje www żeby to działało ale nie działa. Jakby ktoś mógłby mi w tym pomóc byłbym wdzięczny.

    $zmienna = $_POST['wybor'];
    echo ('Wyjscie '.$_POST['wybor']);
    switch ($zmienna) {
        case "1": 
            echo system('echo -ne "1" > /dev/ttyUSB0'); 
            break;
        case "2": 
            echo system('echo -ne "2" > /dev/ttyUSB0'); 
            break;
        
    }
    echo (' zmienione!');
    
  • Relpol
  • Relpol
  • #3
    gsmphone
    Level 13  
    hmmm a czy ktoś wie jak jest w windowsie??
  • #4
    McMonster
    Level 32  
    W Windowsie nie ma tak lekko, musisz odnaleźć jakąś bibliotekę do PHP, która umożliwia komunikację z portem USB.
  • #5
    gsmphone
    Level 13  
    a np portem com da się sterować przez php?
  • #6
    McMonster
    Level 32  
    Wydaje mi się, że PHP i COM były omawiane już w tym dziale, spróbuj użyć wyszukiwarki.
  • #7
    gsmphone
    Level 13  
    Bo patrzyłem właśnie i nie znalazłem podobnego przypadku.

    Może opisze bardziej mój problem:

    Mam urządzenie które pod windowsem ma program który steruje przekaźnikami (wł/wył). Urządzenie jest podłączone do USB -> windows wykrywa go pod COM5. W programie ustawiam wtedy że mam to urządzenie pod comem 5 i wszystko działa.

    No i dlatego się pytam czy przez coma sie da bo się kapnąłem że to urządzenie USB jest jako com wykrywane.
  • #9
    marcinj12
    Level 40  
    Witam,
    Skoro masz już działającą aplikację to może ją przerobić tak, żeby przyjmowała parametry? Niech za obsługę USB czy COMa odpowiada aplikacja pracująca w Windows, bo rozumiem że to na nim masz serwer postawiony.

    Zrobiłem sobie dla testu prosty program konsolowy który wypisuje przekazane mu parametry i wrzuciłem do katalogu htdocs - jeśli używasz Apache. I działa.

    <?php
    echo '<pre>';
    
    $last_line = system('paramTestApp.exe wlacz wylacz', $retval);
    
    echo '
    </pre>
    <hr />Last line of the output: ' . $last_line . '
    <hr />Return value: ' . $retval;
    ?> 
  • #10
    gsmphone
    Level 13  
    Dzięki za skrypt. Powiedz jeszcze tylko skąd mam pobrać w moim programie te opcje które u ciebie się nazywają "wlacz wylacz"?
  • #11
    marcinj12
    Level 40  
    To akurat zależy od języka, w którym ten program został napisany :)
    Mój był napisany w C#, i tam tak to wyglądało:
    using System;
    using System.Text;
    
    namespace paramTestApp
    {
    	class Program
    	{
    		static void Main(string[] args)
    		{
    			if (args.Length == 0)
    			{
    				Console.WriteLine("Nie podano żadnych parametrów...");
    			}
    			else
    			{
    				for (int i = 0; i < args.Length; i++)
    				{
    					Console.WriteLine("Parametr {0}: {1}", i, args[i]);
    				}
    			}
    		}
    	}
    }


    W trybie konsolowym "domyślnie" do punktu wejścia Main jest przekazywana tablica argumentów, podobnie jest w większości znanych mi języków - jest tablica z parametrami i często też drugi parametr, określający ich ilość.

    Wygooglaj szczegóy dla Twojego języka wpisując: <nazwa_języka> command line arguments

    W Twoim wypadku nie będziesz wyświetlał paramtrów, tylko robił jakąś funkcję ("wlacz wylacz" było dla przykładu, równie dobrze mogło być "ala ma kota"). Po prostu w miejscu gdzie ja wypisuję, Ty zrobisz coś w stylu:
    
    if (args.Length > 0)
    {
       switch (args[0])
       {
          case "wlacz":   
                        //Wywołanie procedury włączania - rozumiem że to już masz pod przyciskami...
                        Console.WriteLine("Włączono urządzenie");
                        break;
    
          case "wylacz":   
                         //wywołanie procedury wyłącznia...
                         Console.WriteLine("Zatrzymano urządzenie");
                         break; 
    
          default:  
                    Console.WriteLine("Zły parametr");
                          break;     
       }
    }
    


    -------

    edit: to jednak nie jest wprost napisane: Ty sam pisałeś ten program do sterowania przekaźnikami, masz jego kod źródłowy, czy może jest to od kogoś gotowy program?
  • #12
    gsmphone
    Level 13  
    hmmm, zbyt trudne dla mnie. Chyba będę próbować dalej z tym portem com.


    Znalazłem takie coś:
    ser_open( "COM4", 2400, 8, "None", "1", "None" );
    ser_write("1");


    co ma niby odpowiadać linuksowego:
    echo system('echo -ne "4" > /dev/ttyUSB6');

    tylko że wyskakuje błąd:

    Fatal error: Call to undefined function ser_open()


    bo całość znalazłem tutaj:
    http://www.thebyteworks.com/phpserial/php_ser_reference.html


    wiem że jestem już blisko tylko coś nie tak.
  • #13
    marcinj12
    Level 40  
    A ściągnąłeś całą bibliotekę i wrzuciłeś ją gdzie trzeba, tak jak opisali?
    To jest chyba trial jakiś, może rzuć okiem np. na tą klasę:
    Link Na dole jest dyskietka do ściągnięcia, plik .php wrzucasz do katalogu ze stroną i dołączasz poleceniem include(...) jak w przykładzie...
  • #14
    gsmphone
    Level 13  
    Tak, Zrobiłem tak. No i właśnie dlatego pisze bo się zdziwiłem że nie działa:/
  • #15
    marcinj12
    Level 40  
    Rozumiem że restartowałaś serwer po zmianach w php.ini?
    A strona testowa którą zamieścili (php_ser_test.php) odpala się?
    Cóż, ciężko coś stwierdzić poza tym, że u mnie - dla php_ser_5.2.0-5.2.13 zadziałało za pierwszym razem po tym jak zrobiłem to co opisali, więc biblioteka jest chyba sprawna... Spróbuj jeszcze raz zainstalować.
  • #16
    gsmphone
    Level 13  
    No jak odpalam tego testowego php to mi wyskakuje

    Module win_serial is not compiled into PHP

    a co do pliku php.ini to takiego w ogóle nie mam. Cóż to jest za plik i skąd mam go pobrać?
  • #17
    marcinj12
    Level 40  
    Jakiego serwera http używasz? Gdzie chcesz umieścić tą stronkę do sterowania tym urządzeniem?
    PS. Skoro nie masz pliku php.ini to znaczy że NIE ZROBIŁEŚ wszystkiego co było opisane w tej instrukcji.
    Quote:

    Installation:
    - download from website
    - unzip php_ser.zip and place php_ser++.dll file in PHP extension folder.
    For PHP5 this is usualy: drive:\PHP_install_folder\ext\
    Example: C:\PHP\ext\
    - find php.ini file (usualy placed in C:\Windows folder) and open it
    - fill extension_dir directive with extension folder, for example:
    extension_dir= ".\ext"
    - fill an extension directive to load php_ser automatically:
    extension=php_ser++.dll
    - save and close php.ini file
    - test with php_ser_test.php file (included in distribution), which lists functions
  • #18
    gsmphone
    Level 13  
    Serwer mam na apache'u postawionego na xampp'a.

    No właśnie tej części tak jakby w ogóle nie zauważyłem.

    Mógłbyś mi przesłać ten plik php.ini i powiedzieć gdzie na serwerze mam go wkleić?

    Dodano po 43 [minuty]:

    marcinj12 wrote:
    A ściągnąłeś całą bibliotekę i wrzuciłeś ją gdzie trzeba, tak jak opisali?
    To jest chyba trial jakiś, może rzuć okiem np. na tą klasę:
    Link Na dole jest dyskietka do ściągnięcia, plik .php wrzucasz do katalogu ze stroną i dołączasz poleceniem include(...) jak w przykładzie...


    Próbowałem z tym przykładem i wyskakuje mi teraz błędy:

    Warning: Specified serial port is not valid in C:\xampp\htdocs\xampp\com test\php_serial.class.php on line 111

    Warning: The device must be set before to be open in C:\xampp\htdocs\xampp\com test\php_serial.class.php on line 137

    Warning: Device must be opened in C:\xampp\htdocs\xampp\com test\php_serial.class.php on line 541

    Warning: Device must be opened to read it in C:\xampp\htdocs\xampp\com test\php_serial.class.php on line 474

    Warning: Unable to set the baud rate : the device is either not set or opened in C:\xampp\htdocs\xampp\com test\php_serial.class.php on line 204



    ale tak dla porównania to mam podobną kartę właśnie którą chce dokładnie tak sterować. Jak by się to udało to byłbym wdzięczny
  • #19
    marcinj12
    Level 40  
    To tłumaczy czemu masz błąd, Apache "nie widzi" tej biblioteki.
    Plik php.ini musisz mieć swój, skonfigurowany pod Twój komputer, są w nim ustawienia interpretera PHP.
    Nie wiem jak działa xampp, bo nigdy go nie używałem, ale jeżeli instalowałes PHP z xampem to musisz gdzieś mieć ten plik. Powinien być w katalogu Windows (może być ukryty), albo C:\xampp\php\php.ini czy gdzie tam instalowałeś... Może xamp udostępnia jakieś narzędzie do konfiguracji, poszukaj... A najlepiej wyszukaj start->wyszukaj->pliki i foldery...
    Jak już go znajdziesz zrób to co jest w instrukcji, odszukaj sekcję extension... i dodaj extension=php_ser++.dll
    Oczywiście wszystko przy zatrzymanym Apache.

    ------

    AD. Drugiej biblioteki: wklej cały kod który masz...
  • #20
    gsmphone
    Level 13  
    Ok, znalazłem tego ini(był ukryty). Tam do linijki dodałem
    extension=php_ser++.dll

    linijka extension_dir już tam istnieje:
    extension_dir = "\xampp\php\ext"


    plik php_ser++.dll wgrywam do folderu ext oraz na wszelki wypadek do tego samego folderu w którym jest php.ini

    zapisałem, zamknąłem i uruchomiłem od nowa xamppa. W momencie uruchomienia wyskakuje okienko:

    Warning
    PPH Startup: win_serial: Unalble to initalize module
    Module compiled with module API=20060613
    PHP compiled with module API=20090626
    These options need to match.

    Naciskam ok i potem tak jak w instrukcji sprawdzam odpalając plik php_ser_test.php.

    Po odpaleniu dalej wyświetla się:
    Module win_serial is not compiled into PHP

    Co jeszcze mogę mieć źle?
  • #21
    marcinj12
    Level 40  
    Jaką masz wersję PHP?
    Odpal kod:\
    <?php
    phpinfo();
    ?>
    i sprawdź.
    Następnie, sprawdź czy pobrałeś ze strony downloadu php_ser++.dll ZGODNY z tą wersją, jak pisał producent:
    Quote:
    Important notice
    The correct extension version must be used to pair with PHP version. For example there is
    one extension version that works with PHP 5.2.0 to 5.2.11 and one extension version that
    works with 5.3.0.
  • #22
    gsmphone
    Level 13  
    O, dzięki... to wszystko przez to że ja z angielskim nie bardzo. Teraz działa.

    Jeszcze jak byś mógł mi napisać co mam wpisać w tym przykładnie żeby dostać taki sam efekt jak tu:

    case "1":
    echo system('echo -ne "1" > /dev/ttyUSB0');
    break;

    Czyli naciskając 1 (czy wybierając 1), moja karta z przekaźnikami która jest podpięta do usb która jest wykrywana przez windowsa jako com5, spowoduje uruchomienie się pierwszego przekaźnika.
  • #23
    marcinj12
    Level 40  
    Oj, bez czytania dokumentacji to Kolega daleko nie zajedzie... ;)
    Użycie funkcji też było tam opisane.
    Spróbuj połączyć swój fragment kodu z 1-go postu z takim fragmentem testowym:

    
    <html>
    <head>
    <title>PHP serial extension test page</title>
    </head>
    <body>
    <h3>PHP serial extension test page</h3>
    <?php
    $module = 'win_serial';
     
    if (extension_loaded($module)) {
      $str = "Module loaded";
    } else {
     $str = "Module $module is not compiled into PHP";
     die("Module $module is not compiled into PHP");
    }
    echo "$str<br>";
     
    echo "START<br />";
    
    ser_open( "COM3", 9600, 8, "None", "1", "None" );
    if (ser_isopen()) { 
       echo "Port otwarty!<br />"; 
    } else {
       die("Błąd: Nie udało się otworzyć portu<br />");
    }
    
    $wyslany = ser_writebyte(1);
     echo "Wysłano bajtów: $wyslany<br />"; 
     
    ser_close();
    if (ser_isopen()) { 
       die ("Błąd: port ciągle otwarty!<br />"); 
    } else {
       echo "Port zotał zamknięty<br />";
    }
    
    echo "KONIEC<br />";
    
    ?>
    


    W zasadzie można by to ograniczyć do:
    
    ser_open( "COM5", 9600, 8, "None", "1", "None" );     //otwarcie portu - trzeba dobrać parametry
    if (ser_isopen()) { 
       ser_writebyte(1);   //wysłanie bajtu "1"
       ser_close();          //zamknięcie portu
    } else {
       die("Błąd: Nie udało się otworzyć portu<br />");
    }
    


    Więcej nie pomogę bo nie mam takiego urządzenia, pokombinuj z ustawieniami i wartościami które trzeba wysłać na port. I pamiętaj że ta biblioteka co używasz to trial, ma 1 sek. opóźnienie.
  • #24
    gsmphone
    Level 13  
    Spoko. Dzięki:-) Działa:-) Właśnie o to mi chodziło.
    Szkoda tylko że jest to opóźnienie.

    Jak byś miał bibliotekę która działa normalnie to podeślij mi kiedyś:)
  • #25
    marcinj12
    Level 40  
    Jak chcesz bez opóźnienia to możesz spróbować np. tą inną biblioteką o której wcześniej pisałem, ze tej strony.
    Masz tam dwa pliki, jeden z przykładem, drugi umieszczasz w tym samym katalogu co strona. Przykład jest prosty, zmień tylko pod koniec linie na na:
    <p><a href="<?php echo $_SERVER['PHP_SELF'] . "?action=on" ?>">Click here to turn the system on.</a></p>
    <p><a href="<?php echo $_SERVER['PHP_SELF'] . "?action=off" ?>">Click here to turn the system off.</a></p>

    Nie wiem dokładnie jak działa wysyłanie wiadomości w tym przypadku, jest tam: $serial->sendMessage("N1\r");, przypuszczam że zadział też $serial->sendMessage("1\r"); albo zwykłe: $serial->sendMessage("1");, potestuj.
  • #26
    gsmphone
    Level 13  
    No ta biblioteka mi się bardziej podoba. Tylko że
    ani
    $serial->sendMessage("1\r");

    ani
    $serial->sendMessage("1");


    nie robi nic:/... Będę jeszcze próbować. Jakbyś miał jeszcze jakiś pomysł to napisz.

    Dzięki
  • #27
    marcinj12
    Level 40  
    Jeżeli masz możliwość podpięcia jakiś diod czy coś pod port COM (ten lub inny) to sprawdź czy w ogóle wysyła "jedynki" na piny z danymi. Powinno zadziałać $serial->sendMessage("1"); , możesz spróbować też $serial->sendMessage("1\n"); albo $serial->sendMessage("1\r\n"); chociaż to akurat nie powinno mieć znaczenia. Ta funkcja wysyła string, spróbuj też: $serial->sendMessage(1);
    Więcej pomysłów nie mam :)