FPV Uboot - VNH2SP30 über Multiwii/ArduPilot ansteuren

#1
Hallo Community!

ich bastel grad an einem FPV U-boot, weil mich letzten Sommer der Angelvirus auch noch angesteckt hat. ich muss wissen, was da unten abgeht! ;)

Der Rumpf ist gebaut und getestet. Ich bin jetzt dabei mich um die Steuerung zu kümmern und hänge direkt an der Regelung für den Hauptantrieb und die zwei Schlauchpumpen für einen Ballasttank.
Beides sind Brusched 12V motoren und sollen über eine Multiwii AIO oder einen ArduPilot 2.6 gestellt werden. Dazu habe ich entweder 2 billig BDESC-S10R Brushed-Regler zur Verfügung oder jeweils einen VNH2SP30 Motorshield.

Das Problem mit den BDESC von ebay ist, dass sie im Rückwärtsgang nur knapp halbe drehzahl ausgeben. für den Hauptantrieb ist das ok aber nicht für die pumpen. Vorwärts drehen die Pumpen über den Regler mit voller Drehzahl, der Rückwärtsgang ist aber seeehr schwach. Das ist inakzeptabel, da ich im Rückwärtsgang ja später auftauche durch rauspumpen gegen höheren Druck... Andersherum geschaltet würde das Auffüllen des Ballasttanks ewig dauern.

Die Alternative ist der VNH2SP30, der hier noch rumliegt. Mit einem Arduino und passendem Beispielcode konnte ich schnell die Funktion überprüfen. Der Kontroller tut genau was ich will ;)
Allerdings muss dieser, anstatt mit Servosignalen mit Werten zwischen 0 und 255 auf PWM für die Drehzahl gefüttert und zusätzlich zwei Pins A und B für die Drehrichtung ein- oder ausgeschaltet werden.
Dafür müsste ich also den Code zb der Multiwii so verändern, dass er mir eben diese Signale ausgibt. Mit meinen bescheidenen Programmierkünsten ist das allerdings ne harte Nuss.

Falls jemand eine Bessere Idee hat wie ich die Motoren Ansteuern kann immer her damit!
Eine gute Alternative wäre ein Regler der in beide Drehrichtungen die gleiche Spannung stellt. ich habe aber keinen gefunden, bei dem ich mir da sicher sein konnte.

Ich hoffe auf ein paar gute Ratschläge, wie ich das am besten lösen kann ;)
 

Anhänge

FPVenom

Unerfahrener Benutzer ;)
#2
Gibt es nicht von ?Graupner? so einen RTF Copter, der auch kopfüber fliegen kann? ->Also wo die Motoren rückwärts laufen(?) Hab das Ding letztes Jahr auf der Intermodellbau gesehen. Vielleicht gibts die Regler ja als Ersatzteil.

Aber mal was anderes: Wie willst du die Funkverbindung sicherstellen? Grade das 5,8Ghz Signal mag Wasser überhaupt nicht. Bitte halte mich auf dem laufenden!
 

Optimus

Erfahrener Benutzer
#3
Moin, nur sone idee, wenn es sicher die Regler sind die den Rückwärtslauf einschränken dann evtl. nen Relais nehmen das die Polarität vertauscht und somit die Drehrichtung umkehrt. Das könnte man sicher einfacher über einen Kanal ansteuern.
Gruss Stefan
 

Hans-Jürgen Duwe

Master of Desaster
#4
Ich würde ganz einfach je einen Car Regler für die Ballast Tanks verwenden. Es gibt welche die sogar für zwei Motoren ausgelegt sind, das würde Dir einige Kabel ersparen.

Wie löst Du die Funktechnik?
Nach ein paar cm Wasser ist bei 5.8 und 2.4 GHZ ist Schluss.

Schleppboje?
 
#5
Danke für eure Vorschläge!

es gibt regler die 100% vorwärts und rückwärts ausgeben. allerdings habe ich noch keinen günstigen gefunden, bei dem ich mir sicher war, dass er das wirklich tut.
crawler mode nennt sich das glaub ich. bei denen es genau dabei stand, übersteigen das budget :D alle komponenten zusammen, inkl der beiden erwähnten regeler, habe ich bis jetzt ca 100 euro gezahlt. ohne microcontroller. da kann der regler für die pumpen nicht auf einmal 50 oder 80 kosten :D

das mit dem relais ist vllt gar nicht doof. dann würde ich über ein poti an der fernsteuerung die Last einstellen und über nen aux die Richtung.
hast du da ne idee wie genau du das machen würdest?


In dem Bild oben sieht man so ein kleines schwarzes schwänzchen :D das ist ne moosgummigichtung und hat zum testen das kabel ersetzt.
10 meter kabel zu einer fetten boje und dann zum empfänger und videosender an einem 80cm mast.
im moment habe ich ein einfaches 5-adriges 4mm kabel. dadurch gehen S.Bus vom Empfänger, VideoTx, VCC und Masse. das lief bei einem kurzen test auch soweit.

Grüße!
 
#8
Schau mal, das sollte soweit tun:

Eingänge vom Empfänger auf A2 und A3

Code:
#include <PinChangeInt.h>

/*  MonsterMoto Shield Example Sketch
  date: 5/24/11
  code by: Jim Lindblom
  hardware by: Nate Bernstein
  SparkFun Electronics
 
 License: CC-SA 3.0, feel free to use this code however you'd like.
 Please improve upon it! Let me know how you've made it better.
 
 This is really simple example code to get you some basic
 functionality with the MonsterMoto Shield. The MonsterMote uses
 two VNH2SP30 high-current full-bridge motor drivers.
 
 Use the motorGo(uint8_t motor, uint8_t direct, uint8_t pwm) 
 function to get motors going in either CW, CCW, BRAKEVCC, or 
 BRAKEGND. Use motorOff(int motor) to turn a specific motor off.
 
 The motor variable in each function should be either a 0 or a 1.
 pwm in the motorGo function should be a value between 0 and 255.
 */
#define BRAKEVCC 0
#define CW   1
#define CCW  2
#define BRAKEGND 3
#define CS_THRESHOLD 100

#define PIN_IN1 A3 
#define PIN_IN2 A2
#define inOffset 0

// VNH2SP30 pin definitions
int inApin[2] = {7, 4};  // INA: Clockwise input
int inBpin[2] = {8, 9}; // INB: Counter-clockwise input
int pwmpin[2] = {5, 6}; // PWM input

volatile long pin1_start;             // start time
volatile int pin1_pulse    = 1500;   // pulse duration
volatile long pin2_start;             // start time
volatile int pin2_pulse    = 1500;   // pulse duration

int out1, out2, dir1, dir2;

int statpin = 13;

void setup()
{
  Serial.begin(115200);

  pinMode(PIN_IN1, INPUT); 
  digitalWrite(PIN_IN1, HIGH);
  PCintPort::attachInterrupt(PIN_IN1, &pinfunc1, CHANGE);  
  pinMode(PIN_IN2, INPUT); 
  digitalWrite(PIN_IN2, HIGH);
  PCintPort::attachInterrupt(PIN_IN2, &pinfunc2, CHANGE);
  
  pinMode(statpin, OUTPUT);

  // Initialize digital pins as outputs
  for (int i=0; i<2; i++)
  {
    pinMode(inApin[i], OUTPUT);
    pinMode(inBpin[i], OUTPUT);
    pinMode(pwmpin[i], OUTPUT);
  }
  // Initialize braked
  for (int i=0; i<2; i++)
  {
    digitalWrite(inApin[i], LOW);
    digitalWrite(inBpin[i], LOW);
  }
}

void loop()
{
  // map pulses to pwm values
  long pulse1 = map(pin1_pulse, 1000, 2000, -255, 255);
  long pulse2 = map(pin2_pulse, 1000, 2000, -255, 255);
  
  // // x-MIX 1&2
  //out1 = (pulse1+pulse2);
  //out2 = (pulse1-pulse2);
  out1 = pulse1;
  out2 = pulse2;
  out1 = constrain(out1, -255,255);
  out2 = constrain(out2, -255,255);    

//Serial.print(pulse1);Serial.print(" ");Serial.print(pulse2);Serial.print(" ");
//Serial.print(out1);Serial.print(" ");Serial.println(out2);

  // get Direction
  if (out1 >0) dir1 = CW;
  else dir1 = CCW;
  if (out2 >0) dir2 = CW;
  else dir2 = CCW;

  // center deadband
  // run motors
  if (abs(out1) < 4) {
    motorGo(0, 3, 255);
  } else {
    motorGo(0, dir1, abs(out1));
  }
  
  if (abs(out2) < 4) {
    motorGo(1, 3, 255);
  } else {
    motorGo(1, dir2, abs(out2));
  }
  
  delay(20);

  //if ((analogRead(cspin[0]) < CS_THRESHOLD) && (analogRead(cspin[1]) < CS_THRESHOLD))
  //  digitalWrite(statpin, HIGH);
}

void motorOff(int motor)
{
  // Initialize braked
  for (int i=0; i<2; i++)
  {
    digitalWrite(inApin[i], LOW);
    digitalWrite(inBpin[i], LOW);
  }
  analogWrite(pwmpin[motor], 0);
}

/* motorGo() will set a motor going in a specific direction
 the motor will continue going in that direction, at that speed
 until told to do otherwise.
 
 motor: this should be either 0 or 1, will selet which of the two
 motors to be controlled
 
 direct: Should be between 0 and 3, with the following result
 0: Brake to VCC
 1: Clockwise
 2: CounterClockwise
 3: Brake to GND
 
 pwm: should be a value between ? and 1023, higher the number, the faster
 it'll go
 */
void motorGo(uint8_t motor, uint8_t direct, uint8_t pwm)
{
  if (motor <= 1)
  {
    if (direct <=4)
    {
      // Set inA[motor]
      if (direct <=1)
        digitalWrite(inApin[motor], HIGH);
      else
        digitalWrite(inApin[motor], LOW);

      // Set inB[motor]
      if ((direct==0)||(direct==2))
        digitalWrite(inBpin[motor], HIGH);
      else
        digitalWrite(inBpin[motor], LOW);

      analogWrite(pwmpin[motor], pwm);
    }
  }
}

void pinfunc1() {
  if (digitalRead(PIN_IN1))
    pin1_start = micros();        // positive edge: start
  else
    pin1_pulse = micros() - pin1_start + inOffset;    // negative edge: calculate pulsewidth
}

void pinfunc2() {
  if (digitalRead(PIN_IN2))
    pin2_start = micros();        // positive edge: start
  else
    pin2_pulse = micros() - pin2_start + inOffset;    // negative edge: calculate pulsewidth
}
PinchangeInt müsste diese lib sein:
https://github.com/GreyGnome/PinChangeInt
 

Butcher

Bill the Butcher
#9
@threadstarter:

Find ich ne coole idee, ich wuerde auch eher zum Arduino-shield als regler greifen,
Aber was ich mich frage du redest von ner Multiwii oder ardupilot, wilsst du die 1zu1 mit rein nehmen und nichts am code ändern?
vielleicht hab ich das auch nur falsch verstanden, aber ich denke du wirst um etwas programmieren nicht rum kommen, sicher "fliegst" du ja irgendwie unter wasser aber ob das so auf anhieb funktioniert wag ich zu bezweifeln :) iuch bleib auf jeden fall dran, gefällt mir :)
 
#10
Vielen Dank Herr Frickler ;)
das hilft mir sehr weiter! Flightcontrol gibt mir nur die werte, arduino nano ist bestellt. damit steht das schonmal fest.
in deinen code kommen noch ein paar funktionen wie tauchtiefenmessung per absolutdrucksensor und feuchtigkeitssensor für wassereinbruch.
hast du nen tipp für mich wie ich von meinem dann zusätzlichen arduino eigene messwerte wie strom und tauchtiefe auf ein Minimosd übertragen kann?

Das minimosd wird auf jeden fall eingebaut für den künstlichen horizont! trübes wasser und so... kann ich nun zusätzlich andere messwerte einholen, zb eben die tauchtiefe? alles andere wäre nur bonus, tauchtiefe aber nicht ganz uninteressant.

@butcher
ja ohne änderung! warum auch? ich hab seite, höhe, motor. aux1 pumpen zum satischen tauchen und trimmen, aux2 licht, aux3 über poti zur verstellung der voreren ruder.
dafür kann ich plane, rover, und viele andere fertige settings nehmen. das bekomm ich schon irgendwie hingefummelt :D

die vorderen ruder sollen gar nicht aktiv von der FC geregelt sein, sodern nur die gradeausfahrt stabilisieren und dafür um ein paar grad verstellbar sein. es hängen 10m kabel am uboot, die dann bei vorwärtsfahrt am uboot ziehen. hoffe, dass das ausreicht ;)
 
Zuletzt bearbeitet:
#11
Mmmmh einspielen von Werten ins OSD wird so ne Sache, das hängt ja schon an der FC.
Also entweder in die FC einspielen und die gibts ans OSD, oder du mißbrauchst die weiteren Analogen Eingänge am OSD die sonst Spannung, Strom, RSSI anzeigen.
Also, Stromsensor direkt ans OSD, kann das ja schon, Tiefensensor was analoges rausgeben lassen (notfalls analog-write am Arduino) und am OSD über den Videospannung oder RSSI wert einlesen und anzeigen - das könnte klappen.
 
#12
ja so ähnlich irgendwie hatte ich mir das auch gedacht :D mal sehen ob sich das umsetzen lässt.

ich bin gestern dazu gekommen deinen code zu testen. läuft top mit servotester und einem motor ;)
der finale test mit allen motoren erfolgt dann im verbauten zustand.

ich hab den code noch um einen füllstandsalarm per led und füllstandsensor ergänzt,sowie led's die mir vorn an der camera anzeigen ob der motor vorwärts oder rückwärts dreht. ich will später möglichst viel feedback über die funktionen haben.

jetzt heißt es noch ein bisschen weiter basteln und dann ab ende märz im kanal testen ;)

vielen dank für eure hilfe!
 
#13
Wie gehts dem Projekt?

es gibt regler die 100% vorwärts und rückwärts ausgeben. allerdings habe ich noch keinen günstigen gefunden, bei dem ich mir sicher war, dass er das wirklich tut. crawler mode nennt sich das glaub ich. bei denen es genau dabei stand, übersteigen das budget :D
Habe die Tage noch 2 von diesen Reglern bestellt, 10€ im EU Warehouse und sollen Crawler mode können, werde berichten:
https://hobbyking.com/en_us/hobbyking-x-car-45a-brushed-car-esc.html
http://openpanzer.org/wiki/doku.php?id=wiki:tcb:tcbinstall:motors:rcesc
Können halt nur 2S wie die meisten kleinen Car ESCs.
 
FPV1

Banggood

Oben Unten