-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Roboter mit J2ME-Handy steuern

  1. #1
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.782
    Blog-Einträge
    8

    Roboter mit J2ME-Handy steuern

    Anzeige

    Hallo

    Ich bin inzwischen stolzer Besitzer eines Samsung GT-S5620 (Monte) und versuche jetzt, das Teil "sinnvoll" zu nutzen. Für einen guten Ansatz halte ich dabei den Versuch von wolfgangI das Display des Handys als Schnittstelle zu verwenden:

    http://www.roboternetz.de/phpBB2/zei...ag.php?t=52064
    (Displaysensor: http://www.roboternetz.de/phpBB2/zei...g.php?p=468332)

    Erstaunlich, was die ScriptKids alles können. Ich kenne Java leider überhaupt nicht. Nach zähem googlen bin ich auf einen anderen handygesteuerten Roboter gestossen:

    http://www.robohobby.com/index_de.jsp

    Alles gut erklärt und dokumentiert, aber ich scheitere schon bei der Installation der Java-Umgebung. Irgendwelche Referenzen stimmen nicht, das kann ja heiter werden

    Das sollte das Monte auch können. Mit zwei Kameras, WiFi und MIDP 2.0 scheint es mir eine taugliche Plattform zu sein. Allerdings ist der Einstieg ziemlich zäh. Ziel ist ein Websever auf dem Handy, der über eine Browseroberfläche gesteuert wird und das Bild streamen soll. Der Weg dahin ist aber sehr weit und steinig...

    Ein erster kleiner Erfolg ist eine Webcamfunktion, die ich hier gefunden habe: http://www.mobile-mir.com/en/MobileWebCam.php

    Das Monte sendet über WiFi in einstellbaren Intervallen einen Schnappschuss. Empfänger ist ein Serverscript auf einem Webserver:



    Vielleicht habt ihr ein paar Tipps oder Anregungen?

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.782
    Blog-Einträge
    8
    Hallo

    Nach gefühlten 100000 Mausklicks hab' ich nun das nötigste zusammen:


    http://www.youtube.com/watch?v=xY1UIcGEu7o

    Neben dem Java SDK(32Bit) benötigte ich nur noch das SDK des Herstellers (, welches netterweise mein Monte direkt unterstützt,) und schon klappt es mit NetBeans :)

    Ich hatte massive Probleme beim Installieren des Java ME 3.0 SDK. Das lies sich erst installieren, nachdem ich die 32Bit-Version des Java SDK installiert hatte. Irgendwie scheint die 64Bit-Variante mit meinem AMD unverträglich. Ach, ist das alles kompliziert.

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  3. #3
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.782
    Blog-Einträge
    8
    Hallo

    Das Display als Schnittstelle habe ich inzwischen verworfen. So einen hübschen 240x400-Touchscreen sollte man sinnvoller nutzen ;) Mein neuer Ansatz: Der Kopfhöhrerausgang steuert ein Servo.

    Weil man in Java scheinbar keine Ports oder Pins mehr kennt, muss ich die Aufgabe irgendwie mit gelenkten Datenströmen lösen. Datenquelle ist eine Wav-Datei. Inhalt dieser Wav-Datei ist ein PWM-Signal mit 50Hz und ca. 1:20 Puls:Pause Verhältniss. Quasi ein Servosignal auf Band.

    Die "Hardware" ist eine kleine Verstärkerschaltung mit einem NPN-Transistor als Verstärker und einem 7404 als Signalformer. Mit dieser "Zu Fuss"-Elektronik kenne ich mich allerdings überhaupt nicht aus. Das Zwischenergebniss sieht nun so aus:


    http://www.youtube.com/watch?v=CaVxa6zH2bI
    http://www.youtube.com/watch?v=3FbgwJg-btw


    Der Verstärker ist eine stablilsierte Emitterschaltung. Der Arbeitspunkt des Transistors knapp über dem Schaltpunkt des 7404 wird mit einem 39K Widerstand in Reihe zu einem 100K-Poti eingestellt. Kollektorwiderstand ist ein 1k, Emitterwiderstand fehlt. Ein 3,3µF-Elko koppelt das Signal ein, der 7404 invertiert es erneut und gibt es direkt weiter zum Servo. Software im Monte ist der eingebaute Wav-Player.

    Es gibt noch viel zu erforschen ;)

    Gruß

    mic

    btw: Das Oszi ist ein Tektronics 222 aus meinem Fundus. Blöderweise habe ich seit zwei Wochen keine echte serielle Schnittstelle mehr.... *grummel*

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  4. #4
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.782
    Blog-Einträge
    8
    Hallo

    Adapter fertig, kleines Fahrwerk zusammengebastelt, es geht voran:


    http://www.youtube.com/watch?v=bm9Udc27jQA

    Softwaremässig siehts leider noch etwas mau aus.

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    30.12.2008
    Beiträge
    1.418
    tolle sache
    wenn ich mir die rechenleistung von einigen handys ansehe ist das echt verschwendung für die meisten anwendungen
    die handys gehören in roboter

  6. #6
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    23
    Beiträge
    449
    Au ja, das Handy meines kleiner Bruders hat einen schnelleren Prozessor als der Laptop an dem ich gerade sitze! (zugegeben, 700 mhz is nich viel^^)

    In dem Video bewegen sich die 2 Servos (sind es überhaupt 2?) immer gleich. Mit Stereo-musik könntest du ja 2 unabhängig voneinander Steuern. Kann man mit Java auch das Mikrofon benutzen? Dann könnte man auch Daten zum Handy schicken...

    MfG
    -schumi-

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    28.07.2010
    Ort
    Aachen
    Beiträge
    64
    geht das auch mit dem n97?

  8. #8
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.782
    Blog-Einträge
    8
    Hallo

    Weil das Projekt grad etwas durchhängt schildere ich mal, was bisher geht. Natürlich war der Grundgedanke das Stereosignal zu nutzen um beide Servo getrennt anzusteuern. Blöderweise habe ich aber kein (kostenloses) Programm gefunden mit dem man die Signalform brauchbar in Stereo generieren kann. Ich habe deshalb die Monosignale mit Audacity bearbeitet und zusammengeschnitten. Für die Funktionen vor, zurück und stop habe ich für beide Servos zusammen jeweils kurze Waves mit den wichtigsten Kombinationen erzeugt (Anhang). Testweise kann ich mit diesen Tondateien das Fahrwerk auch direkt am Kopfhörerausgang meines PCs betreiben

    Als Java-Laie habe ich mir fürs Monte aus verschiedenen Codeschnippseln ein kleines Programm zusammengeklickt. Ausgangsbasis war das kleine PatchyMIDlet. Es zeigt, wie man quick&dirty eine Socketverbindung aufbaut und ankommende Browseranfragen auswertet und beantwortet. Im Orginalzustand "überliest" das PatchyMIDlet aber die Daten die der Browser sendet und antwortet nur mit der Empfangsquittung und einem zufällig ausgewählten String. In der Praxis gibt man die IP des Monte als URL im Browser des PCs ein und sieht dann den Satz oben im Browserfenster. Prima.

    Nun zu meinen Erweiterung des PatchMIDlet. Ein Browser sendet bei einer Anfrage eine Menge Daten zum Server, unter anderem auch die aufgerufene URL. Diese lese ich aus dem Datenstrom und Suche alles, was hinter http://handy-ip/ eingegeben wurde. Diesen "Anhang" an die URL (normalerweise der Pfad zur angeforderten Datei auf einem Webserver) interpretiere ich als Kommando und ordne einen Dateinamen meiner Servo-WAVs zu. Dann sende ich dem Browser eine kleine HTML-Seite mit einer kleinen Link-Tabelle. Die Links sind dabei die Handy-IP mit passendem Anhang, also z.B. handy-ip/1, handy-ip/2... Der Einfachheit halber im Moment nur einziffrige Befehle:

    Code:
    <html><head><title>Robotersteuerung mit J2ME-Handy</title></head><body>Kommando:  
    <table><tr><td>Test2</td><td>Test4</td><td>Test6</td></tr><tr><td>Test8</td><td>Test0</td><td></td></tr></table>
    </body></html>
    Zusätzlich habe ich einen kleinen Audioplayer ergänzt. Die mit dem Kommando ausgewählte Wav-Datei wird dann am Kopfhöhrerausgang ausgegeben und das Fahrwerk bewegt sich dem Mausklick entsprechend. Leider sind die WAVs etwas zu kurz, deshalb, und weil der Adapter noch nicht gut funktioniert, ist das Video langweilig. Ich zeige es nur, weil es eben existiert:


    http://www.youtube.com/watch?v=kkArTA0t6cY

    Die WAVs werden übrigens direkt in das Java-Programm eingebunden. Die Java-Syntax ist der von C sehr ähnlich. Das Programm dazu sieht so aus:

    Code:
    /*
    Wireless Java 2nd edition
    Jonathan Knudsen
    Publisher: Apress
    ISBN: 1590590775
    */
    import java.io.*;
    
    import javax.microedition.io.*;
    //import javax.microedition.midlet.*;
    import javax.microedition.lcdui.*;
    //import javax.microedition.pki.*;
    import javax.microedition.io.SocketConnection;
    import javax.microedition.io.ServerSocketConnection;
    //import javax.microedition.io.UDPDatagramConnection;
    
    //import java.io.InputStream;
    
    //import javax.microedition.lcdui.Alert;
    import javax.microedition.lcdui.Command;
    import javax.microedition.lcdui.CommandListener;
    import javax.microedition.lcdui.Display;
    import javax.microedition.lcdui.Displayable;
    import javax.microedition.lcdui.Form;
    //import javax.microedition.lcdui.List;
    import javax.microedition.media.Manager;
    import javax.microedition.media.Player;
    import javax.microedition.midlet.MIDlet;
    
    public class PatchyMIDlet extends MIDlet implements CommandListener, Runnable {
    
      private Display mDisplay;
      private Form mForm;
    
      private ServerSocketConnection mServerSocketConnection;
      private boolean mTrucking = true;
      private String line;
    
      public void startApp() {
        mDisplay = Display.getDisplay(this);
    
        if (mForm == null) {
          mForm = new Form("PatchyMIDlet");
    
          mForm.addCommand(new Command("Exit", Command.EXIT, 0));
          mForm.setCommandListener(this);
        }
    
        Thread t = new Thread(this);
        t.start();
    
        mDisplay.setCurrent(mForm);
      }
    
      public void pauseApp() {}
    
      public void destroyApp(boolean unconditional) { shutdown(); }
    
      private void log(String text) { log(null, text); }
    
      private void log(String label, String text) {
        StringItem si = new StringItem(label, text);
        //si.setLayout(Item.LAYOUT_NEWLINE_AFTER);
        mForm.append(si);
      }
    
      private void shutdown() {
        mTrucking = false;
        try { mServerSocketConnection.close(); }
        catch (IOException ioe) {}
      }
    
      public void commandAction(Command c, Displayable s) {
        if (c.getCommandType() == Command.EXIT) {
          shutdown();
          notifyDestroyed();
        }
      }
    
    public void run() {
        try {
          mServerSocketConnection = (ServerSocketConnection)
              Connector.open("socket://:80");
          log("Startup complete.");
          SocketConnection sc = null;
          while (mTrucking) {
            sc = (SocketConnection)
              mServerSocketConnection.acceptAndOpen();
            log("client: ", sc.getAddress());
            //log("Test: ", sc.getLocalAddress());
            // Strictly speaking, each client connection
            // should be handled in its own thread. For
            // simplicity, this implementation handles
            // client connections inline.
            Reader in = new InputStreamReader(
                sc.openInputStream());
            String dummy_line;
            String erste_line="";
            String Kommando;
            while ((dummy_line = readLine(in)) != null) if(erste_line.equals("")) erste_line=dummy_line;
            // Ignoring the request, send a response.
            Kommando=erste_line.substring(5,6);
            PrintStream out = new PrintStream(sc.openOutputStream());
            out.print("HTTP/1.1 200 OK\r\n\r\n");
            //out.print(getMessage());
            out.print("<html><head><title>Robotersteuerung mit J2ME-Handy</title>");
            out.print("</head><body>");
            out.print("Kommando: ");
            out.print(Kommando);
            log(Kommando);
            out.print("
    <table><tr><td><a href=1>Test1</a></td>");
            out.print("<td><a href=2>Test2</a></td>");
            out.print("<td><a href=3>Test3</a></td></tr>");
            out.print("<tr><td><a href=4>Test4</a></td>");
            out.print("<td><a href=5>Test5</a></td>");
            out.print("<td><a href=6>Test6</a></td></tr>");
            out.print("<tr><td><a href=7>Test7</a></td>");
            out.print("<td><a href=8>Test8</a></td>");
            out.print("<td><a href=9>Test9</a></td></tr>");
            out.print("<tr><td></td><td><a href=0>Test0</a></td><td></td>");
            out.print("</tr></table>
    ");
            //out.print(erste_line);
            out.print("");
            out.print("");
            out.print("");
            out.print("");
            out.print("</body></html>");
            out.close();
            in.close();
            sc.close();
            //playFromResource("/"+Kommando+".wav");
            if(Kommando.equals("1")) playFromResource("/servo-4ms-r.wav");
            if(Kommando.equals("2")) playFromResource("/servo-4ms.wav");
            if(Kommando.equals("3")) playFromResource("/servo-4ms-l.wav");
            //if(Kommando.equals("4")) playFromResource("/4.wav");
            //if(Kommando.equals("5")) playFromResource("/5.wav");
            //if(Kommando.equals("6")) playFromResource("/6.wav");
            //if(Kommando.equals("7")) playFromResource("/7.wav");
            if(Kommando.equals("8")) playFromResource("/servo-10ms.wav");
            //if(Kommando.equals("9")) playFromResource("/9.wav");
            if(Kommando.equals("0")) playFromResource("/1ms_lang.wav");
          }
        }
        catch (Exception e) {
          log("exception: ", e.toString());
        }
      }
      private String readLine(Reader in) throws IOException {
        // This is not efficient.
        StringBuffer temp_line = new StringBuffer();
        int i;
        while ((i = in.read()) != -1) {
          char c = (char)i;
          if (c == '\n') break;
          if (c == '\r') ;
          else temp_line.append(c);
        }
        if (temp_line.length() == 0) return null;
        //log(line.toString());
        return temp_line.toString();
      }
    
      private java.util.Random mRandom = new java.util.Random();
    
      private String getMessage() {
        int i = Math.abs(mRandom.nextInt()) % 5;
        String s = null;
        switch (i) {
          case 0: s = "Above all the others we'll fly"; break;
          case 1: s = "There is no reason to hide"; break;
          case 2: s = "I dreamed about Ray Charles last night"; break;
          case 3: s = "Someone keeps moving my chair"; break;
          case 4: s = "Joseph's face was black as night"; break;
          default: break;
        }
        return s;
      }
    
      private void playFromResource(String wavedatei) {
        try {
          InputStream in = getClass().getResourceAsStream(wavedatei);
          Player player = Manager.createPlayer(in, "audio/x-wav");
          player.start();
        } catch (Exception e) {
          log("exception: ", e.toString());
          return;
        }
      }
    }
    
    /*
      public void paint(Graphics g) {
      ((Graphics2D)g).setRenderingHint
      (RenderingHints.KEY_ANTIALIASING,
       RenderingHints.VALUE_ANTIALIAS_ON); 
      g.setColor(Color.green);
      g.drawLine(20, 20, 40, 140);
      g.setColor(Color.blue);
      g.fillOval(50, 110, 120, 60);
      g.setColor(Color.red);
      g.setFont(new Font("Serif", Font.ITALIC, 36));
      g.drawString("Cellini", 40, 80);
      }
    */
    Gruß

    mic
    Angehängte Dateien Angehängte Dateien

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  9. #9
    wie hast du die töne in audacity gemacht?

  10. #10
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.782
    Blog-Einträge
    8
    Ab einer gewissen Zoomstufe (erkennbar an den vielen kleinen Punkten in der Darstellung) kann man den Kurvenverlauf direkt mit der Maus zusammenklicken. Zuerst wird eine einzelne 20ms-Periode mit der gewünschten Impulsdauer erstellt und diese dann vervielfältigt.
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken periode.jpg  

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •