Noch mehr Servos

23 Nov

Beim Projekt Mixomat sieht es momentan nach Servo statt Ventil aus, und in der Summe sind zwei Servos natürlich kein Problem für Direkt-Anschluss am ESP8266. Aber wenn ich schon einmal Servos ausgegraben habe, dann bietet sich auch eine Gelegenheit, diese Anschluss-Boards für 16 Servos gleichzeitig auszuprobieren.

Nur sind sie leider nicht steckbar. In der Fabrik (oder Heimarbeit?) sind von den Steckleisten immer einige dabei, die so schief eingelötet wurden, dass kein Stecker darauf passt.

Zeit für den Heißluft-Löter! Und eine halbe Stunde später …

Diese Boards sind um den Chip PCA9685 gebaut, der 16 Kanäle an PWM ansteuern kann – auf Zuruf über eine I2C-Datenverbindung, die nur zwei Drähte benötigt. Der separate Mikrocontroller sendet nur „Grundtakt 50 Hz“ und „Kanal 5, 150 Teile von 4096 einschalten“, und den Rest macht der PCA bis auf Widerruf allein.

Klassische Modellbau-Servos erwarten 50 Mal pro Sekunden einen Impuls von 1 bis 2 Millisekunden Dauer. Je nach Dauer heißt das „Ganz nach Links“ bis „Ganz nach Rechts“. Anteilig beschränkt sich damit die effektive Signalbreite auf 10 % der verfügbaren Genauigkeit – von den 4096 Schritten akzeptiert ein typischer Servo nur ungefähr 410, und jeder Servo hat etwas andere mechanische Grenzen. Also bleibt nur, den kleinsten gemeinsamen Bereich zu verwenden. Aber damit kann man die meisten Dinge trotzdem erledigen. Erst einmal sollen sich nur mehr Servos bewegen als ich je zuvor zusammengeschaltet habe (also „mehr als zwei“ … keine große Kunst).

Das sieht dann so aus:

Gegenüber dem vorherigen Programm ist die Auswertung viel flexibler geworden: Per MQTT wird ein Befehl „Winkelgrad,Kanal“ an den Controller geschickt, und der zieht sich die beiden Zahlen und sendet den Befehl an den PCA. Nebenbei leuchtet die blaue LED für 0,4 Sekunden auf. Das ist auch ein neues Feature: sichtbare Quittierung!

void mqcallback(char* topic, byte* payload, unsigned int length) {
  unsigned int maxlength = sizeof c_payload_buff - 1;
  if ( length < maxlength ) {
    maxlength = length;
  }

setLED();
  int i = 0;
  int rawval = 0;
  int limval = 0;
  int posval = 0;
  int channel = 0;
  const char * part_cstr; // Hilfsspeicher / Pointer für Komma-Suche
  
  for ( i = 0; i < maxlength; i++ ) {
    c_payload_buff[i] = payload[i];
  }
  c_payload_buff[i] = '\0';
// Match Topic "s" - 0-180 Grad
  
  if ( strcmp( topic, c_topic_s ) == 0 ) { // 0 = match !!!
    
    rawval = atoi( c_payload_buff ); // automatisch bis zum Komma
    limval = constrain( rawval, 0, 180 );
    posval = map( limval, 0, 180, SERVOMIN, SERVOMAX );

    part_cstr = strchr( c_payload_buff, ',' );
    if( part_cstr == NULL ) {
      mqclient.publish( c_topic_stat, "Invalid Message, use VAL,CHAN");
      return;
    }

    channel = atoi( part_cstr+1 );
    if( channel < 0 || channel > 15 ) {
      mqclient.publish( c_topic_stat, "Channel out of range, use 0-15" );
      return;
    }
    
    pwm.setPWM( channel, 0, posval );
    sprintf( c_stat_buff, "Channel %d = %d RAW %d", channel, limval, posval );
    mqclient.publish( c_topic_stat, c_stat_buff );
  }
}

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

vierzehn + fünf =