Jump to content

[PHP] Servo Programmierung zur LED Steuerung


Recommended Posts

Hallo,

 

ich bin gerade dabei mit dem Servo-PWM-Signal einen RGB-LED-Strip (keinen digitalen) anzusteuern.

Mit dem BrickV klappt das schon ganz gut. Mit PHP will es nicht.

Hier mein Code:

$this->serv_red = 4;
$this->serv_green = 5;
$this->serv_blue = 6;

$this->tinker_conn = new Tinkerforge\IPConnection();
$this->tinker_serv = new Tinkerforge\BrickServo( tfUID_SERVO, $this->tinker_conn );

$this->tinker_conn->connect( tfHOST, tfPORT );


$this->tinker_serv->setOutputVoltage(9000);

        // blue
        $this->tinker_serv->setDegree($this->serv_blue, 0, 0);
        $this->tinker_serv->setPulseWidth($this->serv_blue, 1000, 2000);
        $this->tinker_serv->setPeriod($this->serv_blue, 1);
        $this->tinker_serv->setAcceleration($this->serv_blue, 0); // Slow acceleration
        $this->tinker_serv->setVelocity($this->serv_blue, 0); // Full speed

        // red
        $this->tinker_serv->setDegree($this->serv_red, 0, 0);
        $this->tinker_serv->setPulseWidth($this->serv_red, 1000, 2000);
        $this->tinker_serv->setPeriod($this->serv_red, 7000);
        $this->tinker_serv->setAcceleration($this->serv_red, 0); // Slow acceleration
        $this->tinker_serv->setVelocity($this->serv_red, 0); // Full speed
        
        // green
        $this->tinker_serv->setDegree($this->serv_green, 0, 0);
        $this->tinker_serv->setPulseWidth($this->serv_green, 1000, 2000);
        $this->tinker_serv->setPeriod($this->serv_green, 1);
        $this->tinker_serv->setAcceleration($this->serv_green, 0); // Slow acceleration
        $this->tinker_serv->setVelocity($this->serv_green, 0); // Full speed

        

        $this->tinker_serv->setPosition($this->serv_blue, 0); // Set to most right position
        $this->tinker_serv->enable($this->serv_blue);
        
        $this->tinker_serv->setPosition($this->serv_red, 0); // Set to most right position
        $this->tinker_serv->enable($this->serv_red);

        $this->tinker_serv->setPosition($this->serv_green, 0);
        $this->tinker_serv->enable($this->serv_green);

$this->tinker_conn->disconnect();

 

Das ganze innerhalb einer Klasse.

 

Was sollte passieren?

Rot sollte leuchten.

 

Was passiert?

Nichts. Bzw keine Änderung. Alle 3 Farben leuchten.

 

Entweder ich habe die API oder den Servo nicht richtig verstanden.

Ich denke, dass ich Geschwindigkeit, Beschleunigung und Winkel nicht brauche, da ich ja keinen Motor habe.

Also stelle ich nur eine Periode ein um die Helligkeit festzulegen. Richtig?

 

Hier nochmal die Stati nach dem Aufruf



Array
(
    [temp] => 436
    [overAllCurr] => 0
    [outV] => 9000
    [stackInV] => 0
    [extV] => 12029
)

RED

Array
(
    [acc] => 0
    [vel] => 0
    [per] => 1
    [puls] => Array
        (
            [min] => 1000
            [max] => 2000
        )

    [degr] => Array
        (
            [min] => 0
            [max] => 0
        )

    [pos] => 0
    [on] => 1
)

BLUE

Array
(
    [acc] => 0
    [vel] => 0
    [per] => 1
    [puls] => Array
        (
            [min] => 1000
            [max] => 2000
        )

    [degr] => Array
        (
            [min] => 0
            [max] => 0
        )

    [pos] => 0
    [on] => 1
)

GREEN

Array
(
    [acc] => 0
    [vel] => 0
    [per] => 1
    [puls] => Array
        (
            [min] => 1000
            [max] => 2000
        )

    [degr] => Array
        (
            [min] => 0
            [max] => 0
        )

    [pos] => 0
    [on] => 1
)

 

 

Vielen Dank schon mal für Eure Hilfe!

MRonline

Link zu diesem Kommentar
Share on other sites

Mit dem BrickV klappt das schon ganz gut. Mit PHP will es nicht.

 

Dass heißt, dein PHP Programm tut nicht exakt das was brickv tut. Du musst also nur herausbekommen was der Unterschied zwischen den beiden ist.

 

Dazu könntest du folgendes tun: Den Servo Brick in brickv so einstellen, dass es funktioniert und dann die komplette Konfiguration einmal in PHP auslesen und mit dem vergleichen was dein Programm einstellt. Irgendwo muss da ja ein Unterschied sein.

 

Nachtrag:

Hast du mal kontrolliert, dass du die richtige UID für den Servo Brick verwendest?

Link zu diesem Kommentar
Share on other sites

Ich glaub ich hab mich zu ungenau ausgedrückt.

 

Die Werte sind exakt so, wie im BrickV.

 

Die Verbindung steht auch, denn ich kann alle Daten des Servos auslesen. Diese (alle Rückgaben der Getter der ServoKlasse) habe ich in Arrays geworfen und ausgegeben (siehe Ende des 1. Posts).

 

Es scheint aber, als würde der Servo die Daten nicht übernehmen, da keine Änderung sichtbar ist.

Beim anpassen der Werte im BrickV werden die Werte manchmal auch nicht übernommen, dann muss ich den Servo deaktivieren und wieder aktivieren. Das ist aber relativ selten der Fall.

 

Ich kann auch gern die komplette Klasse posten, aber der betreffende Code ist oben zu sehen.

Link zu diesem Kommentar
Share on other sites

Okay, wenn du also den Servo Brick über brickv einstellst, dann leuchten die LEDs so wie sie sollen. Wenn du aber die gleichen Einstellungen über dein PHP Programm machst dann funktioniert es nicht.

 

Ich gebe dir recht, dein PHP Programm setzt alles so wie es auch in deinem brickv Screenshot eingestellt ist. Das sollte also funktionieren.

 

Du sagst, manchmal werden auch Einstellungen aus brickv nicht übernommen. Wie ist den die Verbindung zwischen deinem Programm und dem Servo Brick. Ist der einfach per USB angeschlossen? Vielleicht gehen da Aufrufe verloren, weil die Verbindung instabil ist.

 

Aktivier mal ResponseExpected für alle Funktionen, dann sendet der Brick für alle Funktionsaufrufe auch eine Antwort und die PHP Bindings können feststellen, ob diese auch beim Brick angekommen sind. Etwa hier:

 

$this->tinker_serv = new Tinkerforge\BrickServo(tfUID_SERVO, $this->tinker_conn);

$this->tinker_serv->setResponseExpectedAll(True);

 

Wenn dann ein Aufruf verloren geht, wird dir das per Exception mitgeteilt.

Link zu diesem Kommentar
Share on other sites

Hallo,

 

ich hab das Gefühl, wir kommen der Lösung näher. Danke schon mal  ;)

 

Ich habe den Code eingefügt, ohne Ergbnis.

Angeschlossen ist der Stapel (Master mit Servo drauf) wiefolgt:

- Per USB am Raspberry Pi

 

Der BrickV läuft auf einem Win7 PC, der im gleichen LAN läuft.

Das PHP Script habe ich sowohl auf jedem Win-PC als auch auf dem Raspberry direkt getestet.

 

Die Firmware der Bricks und Bricklets ist auch die aktuelle.

 

Hier nochmal eine etwas besser formatierte Ausgabe (alles Getter()), nach dem setzen der Werte:

Array
(
    [temperature] => 454
    [overAllCurr] => 0
    [outputV] => 9000
    [stackInV] => 0
    [externInV] => 12073
)


ROT

Array
(
    [Acceleration] => 0
    [Velocity] => 0
    [Period] => 1
    [PulsWidth] => Array
        (
            [min] => 1000
            [max] => 2000
        )

    [Degree] => Array
        (
            [min] => 0
            [max] => 0
        )

    [Position] => 0
    [Enabled] => 1
)

GRÜN

Array
(
    [Acceleration] => 0
    [Velocity] => 0
    [Period] => 1
    [PulsWidth] => Array
        (
            [min] => 1000
            [max] => 2000
        )

    [Degree] => Array
        (
            [min] => 0
            [max] => 0
        )

    [Position] => 0
    [Enabled] => 1
)

BLAU

Array
(
    [Acceleration] => 0
    [Velocity] => 0
    [Period] => 1
    [PulsWidth] => Array
        (
            [min] => 1000
            [max] => 2000
        )

    [Degree] => Array
        (
            [min] => 0
            [max] => 0
        )

    [Position] => 0
    [Enabled] => 1
)

 

d.h. es wird überall die Periode 1 zurück gegeben.

der LED Streifen leuchtet aber weiß, d.h. die Periode müsste min >100 sein, pro Servo. Wenn ich im BrickV 1 einstelle, leuchten die LEDs nicht, was ja auch gut so ist  :D

 

Ich versteh es nicht

 

hier nochmal die komplette Klasse, falls es hilft:

<?php
require_once PATH_INC."main.inc.php";

/**
* @author MR
*/
class Led_Inc extends Main_Inc {

    private $common;
    
    /**
     * @var IPConnection 
     */
    private $tinker_conn;
    /**
     * @var BrickServo 
     */
    private $tinker_serv;
    
    private $color_new;
    
    static private $s_red = array(
        'id'       => 4,
        'min_p'    => 1,
        'max_p'    => 500
    );
    static private $s_green = array(
        'id'       => 5,
        'min_p'    => 1,
        'max_p'    => 8400
    );
    static private $s_blue = array(
        'id'       => 6,
        'min_p'    => 1,
        'max_p'    => 5000
    );
    

    public function __construct(){
        parent::__construct();

        Main_Class::include_db('common','common.db');
        $this->common = new Common_DB();

        $this->DATA =& parent::$DATA['led'];
        $this->DATA['error'] = '';
        $this->DATA['state'] = 0;

        Main_Class::include_utils('Tinkerforge/IPConnection');
        Main_Class::include_utils('Tinkerforge/BrickServo');

        try {
            $this->tinker_conn = new Tinkerforge\IPConnection();
            
            $this->tinker_serv = new Tinkerforge\BrickServo( tfUID_SERVO, $this->tinker_conn );
            $this->tinker_serv->setResponseExpectedAll(True);

            $this->tinker_conn->connect( tfHOST, tfPORT );

            $this->set_color();
            $this->set_data();
            $this->get_data();
            
            $this->tinker_conn->disconnect();
            
            Main_Class::include_design('led','led.design');
        } catch (Exception $exc) {
            echo $exc->getTraceAsString();
        }
    }
    
    public function __destruct() {
        if( $this->tinker_conn->getConnectionState() )
            $this->tinker_conn->disconnect();
    }

    protected function set_color(){
        if( $_REQUEST['rgb'] && substr($_REQUEST['rgb'], 0, 3)=='rgb' ){
            $rgb_str = substr($_REQUEST['rgb'], 4);
            $rgb_str = substr($rgb_str, 0, strlen($rgb_str)-1);
            $arrRGB = explode(',', $rgb_str);
            if( isset($arrRGB[0]) && isset($arrRGB[1]) && isset($arrRGB[2])){
                $this->color_new['red'] = $arrRGB[0];
                $this->color_new['green'] = $arrRGB[1];
                $this->color_new['blue'] = $arrRGB[2];
                
                $this->DATA['newRGB'] = $this->color_new;
            }
        }
    }

    protected function set_data(){
        // Configure two servos with voltage 5.5V
        // Servo 1: Connected to port 0, period of 19.5ms, pulse width of 1 to 2ms
        //          and operating angle -100 to 100°
        //
        // Servo 2: Connected to port 5, period of 20ms, pulse width of 0.95 
        //          to 1.95ms and operating angle -90 to 90°
        $this->tinker_serv->setOutputVoltage(9000);

        // blue
        $this->tinker_serv->setDegree($this->s_blue['id'], 0, 0);
        $this->tinker_serv->setVelocity($this->s_blue['id'], 0); // Full speed
        $this->tinker_serv->setAcceleration($this->s_blue['id'], 0); // Slow acceleration
        $this->tinker_serv->setPulseWidth($this->s_blue['id'], 1000, 2000);
        $this->tinker_serv->setPeriod($this->s_blue['id'], 1);

        // red
        $this->tinker_serv->setDegree($this->s_red['id'], 0, 0);
        $this->tinker_serv->setVelocity($this->s_red['id'], 0); // Full speed
        $this->tinker_serv->setAcceleration($this->s_red['id'], 0); // Slow acceleration
        $this->tinker_serv->setPulseWidth($this->s_red['id'], 1000, 2000);
        $this->tinker_serv->setPeriod($this->s_red['id'], 7000);
        
        // green
        $this->tinker_serv->setDegree($this->s_green['id'], 0, 0);
        $this->tinker_serv->setVelocity($this->s_green['id'], 0); // Full speed
        $this->tinker_serv->setAcceleration($this->s_green['id'], 0); // Slow acceleration
        $this->tinker_serv->setPulseWidth($this->s_green['id'], 1000, 2000);
        $this->tinker_serv->setPeriod($this->s_green['id'], 1);

        
        // setPostion and enable
        $this->tinker_serv->setPosition($this->s_blue['id'], 0); // Set to most right position
        $this->tinker_serv->enable($this->s_blue['id']);
        
        $this->tinker_serv->setPosition($this->s_red['id'], 0); // Set to most right position
        $this->tinker_serv->enable($this->s_red['id']);

        $this->tinker_serv->setPosition($this->s_green['id'], 0);
        $this->tinker_serv->enable($this->s_green['id']);
    } 
    
    protected function get_data(){
        $arrSred['temperature'] = $this->tinker_serv->getChipTemperature();
        $arrSred['overAllCurr'] = $this->tinker_serv->getOverallCurrent();
        $arrSred['outputV'] = $this->tinker_serv->getOutputVoltage();
        $arrSred['stackInV'] = $this->tinker_serv->getStackInputVoltage();
        $arrSred['externInV'] = $this->tinker_serv->getExternalInputVoltage();
        
        $this->DATA['general'] = $arrSred;
        unset($arrSred);
        
        #echo 'RED';
        $arrSred['Acceleration'] = $this->tinker_serv->getAcceleration($this->s_red['id']);
        $arrSred['Velocity'] = $this->tinker_serv->getVelocity($this->s_red['id']);
        $arrSred['Period'] = $this->tinker_serv->getPeriod($this->s_red['id']);
        $arrSred['PulsWidth'] = $this->tinker_serv->getPulseWidth($this->s_red['id']);
        $arrSred['Degree'] = $this->tinker_serv->getDegree($this->s_red['id']);
        $arrSred['Position'] = $this->tinker_serv->getPosition($this->s_red['id']);
        $arrSred['Enabled'] = $this->tinker_serv->isEnabled($this->s_red['id']);
        
        $this->DATA['red'] = $arrSred;
        unset($arrSred);
        
        
        #echo 'BLUE';
        $arrSred['Acceleration'] = $this->tinker_serv->getAcceleration($this->s_blue['id']);
        $arrSred['Velocity'] = $this->tinker_serv->getVelocity($this->s_blue['id']);
        $arrSred['Period'] = $this->tinker_serv->getPeriod($this->s_blue['id']);
        $arrSred['PulsWidth'] = $this->tinker_serv->getPulseWidth($this->s_blue['id']);
        $arrSred['Degree'] = $this->tinker_serv->getDegree($this->s_blue['id']);
        $arrSred['Position'] = $this->tinker_serv->getPosition($this->s_blue['id']);
        $arrSred['Enabled'] = $this->tinker_serv->isEnabled($this->s_blue['id']);
        
        $this->DATA['blue'] = $arrSred;
        unset($arrSred);

        #echo 'GREEN';
        $arrSred['Acceleration'] = $this->tinker_serv->getAcceleration($this->s_green['id']);
        $arrSred['Velocity'] = $this->tinker_serv->getVelocity($this->s_green['id']);
        $arrSred['Period'] = $this->tinker_serv->getPeriod($this->s_green['id']);
        $arrSred['PulsWidth'] = $this->tinker_serv->getPulseWidth($this->s_green['id']);
        $arrSred['Degree'] = $this->tinker_serv->getDegree($this->s_green['id']);
        $arrSred['Position'] = $this->tinker_serv->getPosition($this->s_green['id']);
        $arrSred['Enabled'] = $this->tinker_serv->isEnabled($this->s_green['id']);
        
        $this->DATA['green'] = $arrSred;
    }
}
new Led_Inc();
?>

die set_color() hat zZ keine Auswirkung!

Link zu diesem Kommentar
Share on other sites

Okay, wir haben das hier mal nachgebaut und können dein Problem so nicht nachstellen. Was aber auffällt ist, dass du eine ungewöhnliche Weise verwendest um das PWM Signal einzustellen. Da scheint noch ein Problem im Servo Brick zu sein, dass im normalen Betrieb mit Servos aber nicht auftritt. Bei Änderung der Period werden nicht alle abhängigen Werte richtig neu berechnet. Das macht im Betrieb mit Servos wie gesagt kein Problem, da die Period hier fest ist. Du verwendest sie aber als den aktiven Stellwert.

 

Ich schlage daher folgende alternative Vorgehensweise vor, die mehr der normalen Arbeitsweise des Servo Bricks entspricht:

 

Pulse Width: 0 bis 20000

Degree: 0 bis 100

Velocitiy und Acceleration: 65535

Period: 20000

 

Jetzt kannst du über die Position zwischen 0 und 100 den High-Anteil des PWM Signals einstellen.

Link zu diesem Kommentar
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Reply to this topic...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...