GALLOPING GHOST besturing

Discussie in 'Besturen' gestart door Bruno van Hoek, 23 jul 2024.

  1. Raymond-v-M

    Raymond-v-M Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    19 okt 2021
    Berichten:
    283
    Locatie:
    Sittard
    De pulswijdte zal 1500 zijn, naar dat kan ik nog even kontroleren.
     
  2. Bruno van Hoek

    Bruno van Hoek Vriend van modelbouwforum.nl PH-SAM Forum veteraan

    Lid geworden:
    23 aug 2002
    Berichten:
    11.222
    Locatie:
    Almere, MVA (ex-Daedalus Amsterdam)/ PH-SAM/F23D
    Dan zal dat venster van 1400-1600 wel OK zijn, lijkt me.
     
    Raymond-v-M vindt dit leuk.
  3. Bruno van Hoek

    Bruno van Hoek Vriend van modelbouwforum.nl PH-SAM Forum veteraan

    Lid geworden:
    23 aug 2002
    Berichten:
    11.222
    Locatie:
    Almere, MVA (ex-Daedalus Amsterdam)/ PH-SAM/F23D
    Opbouw van de sketch:
    Eerst een input convertor pulstijd → numerieke waarde (1000 -2000) & puls of geen puls detectie.
    Num, waarde en pulsaanwezigheid opslaan ter bewerking.
    Dan de bewerking, tenslotte num.waarde terugvertalen naar een output pulstijd.
    De ruwe flowchart lijkt me:
    Start → output 1000 (gas dicht)
    Loop
    geen puls → output 1000 (gas dicht)
    wel puls: num. w. > 1400 & <1600 → geen actie. (volgt eigenlijk al uit de volgende regels)
    num. w. > 1800 → output + 1 (gas langzaam open)
    num. w. < 1200 → output - 1 (gas langzaam dicht)
    output < 1000 → output = 1000
    output > 2000 → output = 2000
    loop.
    Ik heb een sketch van een goede elevon mixer voor een 328 /16M-5V , lijkt me dat daar wel iets uit te bakken valt.
     
  4. Raymond-v-M

    Raymond-v-M Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    19 okt 2021
    Berichten:
    283
    Locatie:
    Sittard
    Spot-on Bruno!
    Ik wil een digispark gebruiken (ATtyni85) op 16 Mhz, omdat ik er hier een berg van heb.
    Met de servo library zou alles relatief simpel moeten kunnen. Ik had ChatGPT al eens voor een framework om te starten gevraagd: Servo draairichting omdraaien


    #include <Servo.h> // Voeg Servo bibliotheek toe

    const int pwmInputPin = 0; // PWM input op pin 0
    const int pwmOutputPin = 1; // Servo output op pin 1

    Servo myServo;

    void setup() {
    pinMode(pwmInputPin, INPUT); // Zet de PWM input pin als ingang
    myServo.attach(pwmOutputPin); // Verbind de servo met de output pin
    }

    void loop() {
    // Lees het PWM-signaal van de input
    int pwmValue = pulseIn(pwmInputPin, HIGH);

    // Converteer PWM naar een waarde tussen 0 en 180 graden
    int servoPosition = map(pwmValue, 1000, 2000, 0, 180);

    // Inverteer de servo positie om de draairichting om te polen
    int invertedPosition = 180 - servoPosition;

    // Beweeg de servo naar de omgekeerde positie
    myServo.write(invertedPosition);

    delay(20); // Korte pauze om de servo stabiel te houden
    }
     
  5. Bruno van Hoek

    Bruno van Hoek Vriend van modelbouwforum.nl PH-SAM Forum veteraan

    Lid geworden:
    23 aug 2002
    Berichten:
    11.222
    Locatie:
    Almere, MVA (ex-Daedalus Amsterdam)/ PH-SAM/F23D
    Lijkt een goed idee, maar deze sketch geeft bij mij een compileerfout bij de AtTiny 85, maar niet bij een Nano/ProMini....:confused:
    Ik zal daar dan wel even mee testen
     
  6. Raymond-v-M

    Raymond-v-M Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    19 okt 2021
    Berichten:
    283
    Locatie:
    Sittard
    Het is maar een begin, en ik denk dat we de conversie naar hoek helemaal niet nodig hebben. Gewoon pulsbreedte berekenen en uitsturen.
     
  7. HBZWEEF

    HBZWEEF PH-SAM

    Lid geworden:
    8 okt 2008
    Berichten:
    557
    Locatie:
    Harderwijk
    Voor alsnog is het maken van een sketch en het goed begrijpen van alle termen voor mij een brug te ver, maar ik probeer toch wat op te steken van jullie exercities, Dus als het kan zo duidelijk mogelijk uitleg geven en vooral: DOORGAAN.:wave
     
    Bruno van Hoek vindt dit leuk.
  8. Raymond-v-M

    Raymond-v-M Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    19 okt 2021
    Berichten:
    283
    Locatie:
    Sittard
    De Actuators zijn binnen, en ze werken fantastisch:
    FF5F0047-F00F-4D21-9AAA-385D71AED7AA.jpeg

    Inmiddels ook de test opstelling gemaakt voor de gasservo simulatie. Een digispark met op P0 het signaal van de ontvanger, en op P1 het signaal naar de servo. Ook nog Arduino IDE geinstalleerd op de laptop en de boarddefinitie ATTiny85 erin geladen.
    Het programmeren/testen kan beginnen. Steel with pride:D.
    IMG_2062.jpeg
     
    Bruno van Hoek vindt dit leuk.
  9. Rick NL

    Rick NL PH-SAM

    Lid geworden:
    18 apr 2008
    Berichten:
    4.215
    Locatie:
    Gouda
    Wat is dat één kanaal actuatortje een beauty!
    De twee kanaal ziet er trouwens ook (vertrouwd) mooi uit.
    Is de motor sturing van het origineel geen optie?
    Rand-Actuator.jpg
     
  10. Raymond-v-M

    Raymond-v-M Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    19 okt 2021
    Berichten:
    283
    Locatie:
    Sittard
    Het origeneel, de R3 heb ik ook nog gedeeltelijk Rick. Maar deze mist de motor.
    Op de R3 gaat het gas op en neer door de motor hele omwentelingen te laten maken, met een slip van het gas stuurhendeltje op de uiteinden. Op de Fleet zender zit een 3 standen schakelaar. Middenstand niets, onderste stand, actuator hendeltje loop langzaam dicht tot slip. Bovenste stand, actuator hendeltje loop langzaam open tot slip.
    Orgineel flappert tijdens het bedienen van het gas de rest heftig omdat de motor hele rotaties maakt.
    De repro actuator kan niet geheel ronddraaien, en de tandwieletjes zijn in de motor geintegeers. Daarom is het niet mogelijk er een R3 van te maken.
    De gasfunctie gaan we nu met een extra servo simuleren.
     
  11. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.428
    Locatie:
    Boskoop
    Volgens mij herkent de ATtiny geen "pulseIn". Ik heb voor de converter naar een soort GG (Webra Picco) in Gerard's Topsy de volgende schets geschreven, gebaseerd op Phil_G's sketch. In dit geval ging het om een magnetische actuator die heen en weer beweegt afhankelijk van de Mark/Space ratio, maar dat zou je moeten aanpassen naar de behoefte van een echte GG.
    Code:
    // Simple recoder for ATTiny85 board and MIC4427 non-inverting MOSFET driver - Max Z
    // Based on sketch digispark_gg_v2 by Phil G, revised for Webra Picco actuator (relay type)
    // Fixed DrvCycle time, not controlled by elevator pulse ( as would be required for full GG)
    // Mark-space between 30%-70% controlled by rudder channel
    
    #define rudder_ch 2 // receiver rudder channel connected to P2 (ATTiny physical pin 7)
    #define speedpot A3
    #define PiccoDriver 1   // output to driver chip
    #define RUDD_DFLT 1500  // neutral rudder on power-up
    
    volatile unsigned long timer_ch1_R; // all timer variables are unsigned long (volatile because ISR variable)
    volatile int pulse_time_R = RUDD_DFLT; // (volatile because ISR variable)
    volatile byte ch1Rwas = 0; // previous hi/lo state (volatile because ISR variable)
    int rudder_time = RUDD_DFLT; // measured channel pulses from rx
    int speedread; // analog read from pot
    unsigned long rudder_marksp = 0, settle_time;
    unsigned long DrvOn = 0, DrvOff = 0, DrvCycle = 140;   // driver on/off/cycle times in ms
    
    void setup() {
      pinMode(rudder_ch, INPUT_PULLUP);  // pullups in case rx isnt connected, avoids picking up hash
      pinMode(PiccoDriver, OUTPUT);   // o/p to PiccoDriver
      pinMode(speedpot, INPUT_PULLUP);
      timer_ch1_R = 0;
      GIMSK = (1 << PCIE);   // Enable Pin Change Interrupts
      PCMSK = (1 << rudder_ch); // Enable interrupts for rx channel input
      sei();
      settle_time = micros() + 500000; // 500 milliseconds to allow rx outputs to settle on power-up
    }
    
    void loop() {
      if (micros() < settle_time) { pulse_time_R = RUDD_DFLT; }
      cli();
      rudder_time = pulse_time_R; // do an atomic copy in the quickest way
      sei();
      speedread = analogRead(speedpot);
      DrvCycle = map (speedread,0,1023,300,80);
      rudder_time = constrain(rudder_time, 1000, 2000);
      rudder_marksp = map(rudder_time, 1050, 1950, 10, 90);    // map to 10% - 90%
      DrvOn = DrvCycle * rudder_marksp / 100;
      DrvOff = DrvCycle - DrvOn;
      if (rudder_time > 1950) {
        digitalWrite(PiccoDriver, HIGH);
      }
      else if (rudder_time < 1050) {
        digitalWrite(PiccoDriver, LOW);
      }
      else {
      // waggle the driver on and off
      digitalWrite(PiccoDriver, HIGH); delay(DrvOn); digitalWrite(PiccoDriver, LOW); delay(DrvOff);
      }
    }
    
    ISR(PCINT0_vect)  // read the receiver channels into timer_ch1_R
    {
      if (PINB & (1 << rudder_ch)) { // Rx ch 1
        if (ch1Rwas == 0) {
          timer_ch1_R = micros();
          ch1Rwas = 1;
        }
      } else {
        if (ch1Rwas == 1) {
          pulse_time_R = ((volatile int)micros() - timer_ch1_R);
          ch1Rwas = 0;
        }
      }
    }
    
    Zoals je ziet wordt de detectie van de Rx pulsen met een ISR interrupt gedaan.

    Max.
     
    Laatst bewerkt: 24 okt 2024
  12. Raymond-v-M

    Raymond-v-M Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    19 okt 2021
    Berichten:
    283
    Locatie:
    Sittard
    Dankje Max!
    Ik las inderdaad gisteren dat de digispark zeer beperkt is met PWM. De servo library schijnt daardoor ook niet bruikbaar. Ik ga toch een gokje wagen. Ik hoop dat het met interrupts niet de uigang gaat verstoren.
    De digispark is mooi klein, en we hebben maar 1 in en 1 out nodig.
    Bruno, als jij een sketch hebt voor een mixer via de Digispark, dan zou daar alles wat we nodig hebben in zitten.
     
  13. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.428
    Locatie:
    Boskoop
    Als ik het allemaal goed begrepen heb ga je het gas met een gewone servo aansturen. In dat geval is de hele Mark/Space geschiedenis niet nodig. Je kunt dan net zo goed van de originele Digispark_gg (of de V-tail mixer) van Phil uitgaan v.w.b. de Rx-puls uitlezen, en die puls aanpassen zoals Bruno al gestart is.
    Onwaarschijnlijk. Interrupts zijn heel snel, en de uiteindelijke servo-puls word met een simpele delay van maximaal 2 millisecondes gegenereerd direct ná de interrupt. En de volgende Rx-puls komt pas na ongeveer 20 millisecondes.
     
    Laatst bewerkt: 24 okt 2024
    Raymond-v-M vindt dit leuk.
  14. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.428
    Locatie:
    Boskoop
    Ik heb het puls in > puls uit gedeelte gedistilleerd uit de Digispark V-tail mixer van Phil:

    Code:
    //PWM input for ATTiny - based on Phil Green's Digispark V-tail mixer.
    
    #define Rxch1 0 // receiver channel connected to P0 (ATTiny physical pin 5) Set PCMSK to match
    #define servo1 4    // servo 1 (ATTiny physical pin 3)
    #define led 1       // DigiSpark internal LED on P1 (ATTiny physical pin 6)
    #define unused2 2   // define unused/open pins as output to avoid spurious input
    #define unused3 3.  // define unused/open pins as output to avoid spurious input
    volatile unsigned long timer_ch1; // all timer variables are unsigned long
    volatile int pulse_time1 = 1500, RXpulse_time1, outpulse_time1 = 1500;
    volatile byte ch1Was = 0, sync = 0;
    
    void setup()
    {
      pinMode(led, OUTPUT);
      pinMode(servo1, OUTPUT);
      pinMode (unused2, OUTPUT);
      pinMode (unused3, OUTPUT);
      pinMode(Rxch1, INPUT);
      timer_ch1 = 0;
      GIMSK = (1 << PCIE);   // Enable Pin Change Interrupts
      PCMSK = (1 << Rxch1); // Enable interrupts for rx channel inputs
      sei();
    }
    
    void loop()
    {
      while (sync == 0);
      sync = 0;
      delay(6);  // do the o/p pulses mid-frame, reduces jitter...
      cli();
      RXpulse_time1 = pulse_time1; // do an atomic copy in the quickest way
      sei();
    
      /* do the math here, output pulse = outpulse_time1
     
      */
    
      digitalWrite(servo1, 1); delayMicroseconds(outpulse_time1); digitalWrite(servo1, 0); // servo out
    }
    
    ISR(PCINT0_vect)
    {
      if (PINB & 0b00000001) { // read the Rx pulse on P0
        if (ch1Was == 0) {
          timer_ch1 = micros();
          ch1Was = 1;
        }
      } else {
        if (ch1Was == 1) {
          pulse_time1 = ((volatile int)micros() - timer_ch1);
          ch1Was = 0;
          sync = 1;
        }
      }
    }
    
    De weg van ontvangerpuls naar servopuls moet nog in het /* */ gedeelte gecodeerd worden.
    Denk erom dat de doorgang van de loop gesynchroniseerd wordt met de interrupt ( 1x per 20 millisecondes), dus houdt daar rekening mee bij het coderen van langzaam openen/sluiten van het gas.
    Max.
     
    Laatst bewerkt: 24 okt 2024
  15. Raymond-v-M

    Raymond-v-M Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    19 okt 2021
    Berichten:
    283
    Locatie:
    Sittard
    Dankje Max!
    Nu komt de oplossing met rasse schreden in zicht!
    Hopelijk vanovond een momentje tijd om door te knutsulen:kwijl::kwijl:
    Ik las ergens dat er een aantal pinnetjes op de digispark met 68 Ohm aan de ATtiny85 hangen. Dus maar het beste deze pin layout nemen en dus even omsolderen.
     
  16. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.428
    Locatie:
    Boskoop
    Raymond, je kunt een digispark eenvoudig "de-fluffen", dus alle ongewenste zaken verwijderen, lees de allereerste post van Phil in DIT topic.
    Maar je kunt ook een kale ATTiny gebruiken, en die op een stukje experimenteerprint solderen. Je mist dan de spanningsregelaar van de digispark, maar die heb je toch niet nodig als je de voeding van de ontvanger aftapt.
     
    Raymond-v-M vindt dit leuk.
  17. Raymond-v-M

    Raymond-v-M Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    19 okt 2021
    Berichten:
    283
    Locatie:
    Sittard
    Ik “defluff” ze standaard Max. Nu heb ik de digidpark toch via de 7805 aangesloten, zodat hij op 5V aftopt. Geen idee wat een hogere spanning bijvoorbeeld voor invloed op de klok kan hebben.
     
  18. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.428
    Locatie:
    Boskoop
    Dat weet ik ook niet, maar de oscillator is sowieso minder nauwkeurig dan de Arduino's met een kristalgestuurde oscillator.
    Je kunt 'm wel kalibreren zoals bijvoorbeeld HIER beschreven wordt. Maar is die nauwkeurigheid wel nodig voor deze toepassing?
     
    Raymond-v-M vindt dit leuk.
  19. Raymond-v-M

    Raymond-v-M Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    19 okt 2021
    Berichten:
    283
    Locatie:
    Sittard
    Hoe het mis kan gaan….
    Gisteravond laat op de laptop van mijn vrouw IDE arduino gestart, de USBasp programmer en de digispark eraan geprikt, en gaan!
    Helaas….. Niets werkte. Voortdurend foutmelding dat de USBasp niet wordt herkend.
    Een paar maanden geleden deedietnog.
    wat was er gebeurd? Microsoft had zich laten invallen dat de laptop een keer stiekum, ‘s nachts wel kon worden geupdate van Windows 10 naar 11. Goed plan, alleen niet voor de USBasp driver, je weet wel, die van fischl.de.
    Deze was maar gedeeltelijk gemigreerd, omdat deze 32 bits was, en 32 bits drivers niet meer worden ondersteund.
    Ennudan? Toch een driver erop geforceerd met Zapig software. Alleen even opletten, de driver werkt nu op één diskrete USB poort, dus de USBasp moet steeds op dezelfde fysieke poort worden aangesloten, anders moet Zapig weer gedraaid worden.
    Efin, alles staat nu gereed om vanavond de sketch van Max (die gelukkig fijn compileert) uit te gaan breiden.
    Wordt vervolgd.
     
  20. Bruno van Hoek

    Bruno van Hoek Vriend van modelbouwforum.nl PH-SAM Forum veteraan

    Lid geworden:
    23 aug 2002
    Berichten:
    11.222
    Locatie:
    Almere, MVA (ex-Daedalus Amsterdam)/ PH-SAM/F23D
    Mijn eigen probeersel (ontwikkeld uit Phils AtTiny mixer)
    Nee, dat is duidelijk. De structuur van de AtTiny is eenvoudiger dan die van de AtMega 328 processor.
    Het is de interrupt die het onmogelijk maakt om het puls uit proces autonoom te laten verlopen.

    Mijn probeersel ( afgeleid van een AtTiny mixer door Phil) had ik donderdagochtend al aan de gang werkt helemaal volgens mijn flowchart, zoals de bedoeling was... :yes:
    Op één puntje na, dan...:(
    Op het moment dat de ingang pulstrein wegvalt, verdwijnt ook de sturing naar de servo. :confused:
    Logisch, want de trigger voor het uitsturen van de puls komt van de 'sync' en zolang er geen interrupt plaatsvindt, dan wordt de pulsvormingssequence ook niet gestart.
    Je zult dus een ontvanger moeten gebruiken met een fail safe instelling en voor het gaskanaal de positie 'dicht' vastleggen.
    De GG 'recoder' werkt volgens hetzelfde principe en houdt er zonder input volgens mij ook gewoon mee op...
    Dus ook voor deze kanalen de failsave goed instellen, dan zou alles ook bij het wegvallen van de verbinding naar de veilige failsave posities moeten gaan.
    Mijn knutselwerkje (waarom het oorspronkelijke constrain commando niet werkte weet ik niet, maar ik heb het met 'vergelijken en terugzetten naar 1000, resp. 2000' opgelost:
    Code:
    // Switch Slow, adapted from Phil's V-tail mixer for ATTiny85, such as the 16mhz DigiSpark board - Phil_G/ Bruno_vH
    #define IN 0     // receiver channel connected to P0 (ATTiny physical pin 5)
    #define FS 0
    #define OUT 4    // servo connected to P4 (ATTiny physical pin 3)
    volatile unsigned long timer, flsv = 1000; // variables are unsigned long
    volatile int pulse_time = 1000, outpulse_time = 1000, temp = 0;
    volatile byte Was = 0, sync = 0, UP = 0, DWN = 1;
    
    void setup()
    {
      pinMode(IN, INPUT);
      pinMode(FS, INPUT);
      pinMode(OUT, OUTPUT);
      timer = 0;
      GIMSK = (1 << PCIE);   // Enable Pin Change Interrupts
      PCMSK = (1 << IN);     // Enable interrupts for input
      sei();
    }
    
    void loop()
    {
      while (sync == 0);
      sync = 0;
      delay(6);                               // do the o/p pulses mid-frame, reduces jitter...
      cli();
      temp = pulse_time;              // do an atomic copy in the quickest way
                       
        if (temp > 1700) {
        outpulse_time = outpulse_time+15;     // slowly increase servoposition
      }
       if (temp < 1300) {
        outpulse_time = outpulse_time-15;     // slowly decrease servoposition
      }
       if (outpulse_time  < 1000) {                  // constrain within 1000...2000
        outpulse_time = 1000;
      }
       if (outpulse_time  > 2000) {                  //                        "
        outpulse_time = 2000;
      }
     
      digitalWrite(OUT, 1); delayMicroseconds(outpulse_time); digitalWrite(OUT, 0); // servo out on P4/ATTiny physical pin 3
    
      sei();
    }
    
    ISR(PCINT0_vect)
    {
      if (PINB & 0b00000001) {
        if (Was == 0) {
          timer = micros();
          flsv = flsv + 600;
          Was = 1;
        }
      } else {
        if (Was == 1) {
          pulse_time = ((volatile int)micros() - timer);
          Was = 0;
          sync = 1;
        }
      }
    }
    
    En het resultaat:
     
    Laatst bewerkt: 25 okt 2024
    Raymond-v-M vindt dit leuk.

Deel Deze Pagina