Hoe kan ik een geschutstoren 290 graden laten draaien

Discussie in 'Model elektronica' gestart door Herby63, 4 sep 2021.

  1. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.510
    Locatie:
    Brugge
    Met dit als resultaat
    Code:
    pulse = 1504
    pulse = 1504
    pulse = 1492
    pulse = 1540
    pulse = 1508
    pulse = 924
    pulse = 1524
    Xpulse[] = 308    Xtarget[] = 282
    pulse = 1500
    Xpulse[] = 307    Xtarget[] = 272
    pulse = 1464
    Xpulse[] = 308    Xtarget[] = 258
    pulse = 1508
    Xpulse[] = 307    Xtarget[] = 276
    pulse = 1536
    Xpulse[] = 308    Xtarget[] = 314
    pulse = 1508
    Xpulse[] = 307    Xtarget[] = 308
    pulse = 1468
    Xpulse[] = 308    Xtarget[] = 299
    pulse = 1504
    Xpulse[] = 307    Xtarget[] = 307
    pulse = 1464
    pulse = 1464
    pulse = 1560
    pulse = 1512
    pulse = 1484
    pulse = 1536
    pulse = 1512
    pulse = 932
    pulse = 1512
    Xpulse[] = 324    Xtarget[] = 277
    pulse = 1488
    Xpulse[] = 323    Xtarget[] = 268
    pulse = 1468
    Xpulse[] = 324    Xtarget[] = 260
    pulse = 1508
    Xpulse[] = 323    Xtarget[] = 276
    pulse = 1544
    Xpulse[] = 314    Xtarget[] = 315
    pulse = 1516
    Xpulse[] = 307    Xtarget[] = 309
    pulse = 1472
    Xpulse[] = 324    Xtarget[] = 300
    pulse = 1500
    Xpulse[] = 307    Xtarget[] = 306
    pulse = 1464
    pulse = 1464
    pulse = 1564
    pulse = 1500
    pulse = 1476
    pulse = 1536
    pulse = 1516
    pulse = 920
    pulse = 1516
    Xpulse[] = 340    Xtarget[] = 279
    pulse = 1496
    Xpulse[] = 339    Xtarget[] = 271
    pulse = 1472
    Xpulse[] = 340    Xtarget[] = 261
    pulse = 1500
    Xpulse[] = 339    Xtarget[] = 272
    pulse = 1544
    Xpulse[] = 314    Xtarget[] = 315
    pulse = 1512
    Xpulse[] = 309    Xtarget[] = 309
    pulse = 1456
    Xpulse[] = 340    Xtarget[] = 296
    pulse = 1504
    Xpulse[] = 323    Xtarget[] = 307
    pulse = 1476
    pulse = 1476
    pulse = 1556
    pulse = 1496
    pulse = 1484
    pulse = 1540
    pulse = 1512
    pulse = 920
    pulse = 1516
    Xpulse[] = 356    Xtarget[] = 279
    pulse = 1512
    Xpulse[] = 355    Xtarget[] = 277
    pulse = 1460
    Xpulse[] = 356    Xtarget[] = 256
    pulse = 1504
    Xpulse[] = 355    Xtarget[] = 274
    pulse = 1544
    Xpulse[] = 314    Xtarget[] = 315
    pulse = 1524
    Xpulse[] = 309    Xtarget[] = 311
    pulse = 1460
    Xpulse[] = 356    Xtarget[] = 297
    pulse = 1504
    Xpulse[] = 339    Xtarget[] = 307
    pulse = 1460
    pulse = 1460
    pulse = 1548
    pulse = 1500
    pulse = 1488
    pulse = 1548
    pulse = 1508
    pulse = 920
    pulse = 1520
    Xpulse[] = 372    Xtarget[] = 281
    pulse = 1500
    Xpulse[] = 371    Xtarget[] = 272
    pulse = 1464
    Xpulse[] = 372    Xtarget[] = 258
    pulse = 1504
    Xpulse[] = 371    Xtarget[] = 274
    pulse = 1540
    Xpulse[] = 314    Xtarget[] = 315
    pulse = 1516
    Xpulse[] = 311    Xtarget[] = 309
    pulse = 1468
    Xpulse[] = 372    Xtarget[] = 299
    pulse = 1512
    Xpulse[] = 355    Xtarget[] = 309
    pulse = 1460
    pulse = 1460
    pulse = 1556
    pulse = 1508
    pulse = 1492
    pulse = 1540
    pulse = 1512
    pulse = 920
    pulse = 1520
    Xpulse[] = 388    Xtarget[] = 281
    pulse = 1496
    Xpulse[] = 387    Xtarget[] = 271
    pulse = 1464
    Xpulse[] = 388    Xtarget[] = 258
    pulse = 1508
    Xpulse[] = 387    Xtarget[] = 276
    pulse = 1540
    Xpulse[] = 314    Xtarget[] = 315
    pulse = 1512
    Xpulse[] = 327    Xtarget[] = 309
    pulse = 1464
    Xpulse[] = 388    Xtarget[] = 298
    pulse = 1504
    Xpulse[] = 371    Xtarget[] = 307
    pulse = 1464
    pulse = 1464
    pulse = 1556
    pulse = 1508
    pulse = 1496
    pulse = 1540
    pulse = 1508
    pulse = 932
    pulse = 1512
    Xpulse[] = 404    Xtarget[] = 277
    pulse = 1496
    Xpulse[] = 403    Xtarget[] = 271
    pulse = 1460
    Xpulse[] = 404    Xtarget[] = 256
    pulse = 1500
    Xpulse[] = 403    Xtarget[] = 272
    pulse = 1536
    Xpulse[] = 314    Xtarget[] = 314
    pulse = 1516
    Xpulse[] = 343    Xtarget[] = 309
    pulse = 1472
    Xpulse[] = 404    Xtarget[] = 300
    pulse = 1488
    Xpulse[] = 387    Xtarget[] = 303
    pulse = 1460
    pulse = 1460
    pulse = 1560
    pulse = 1500
    pulse = 1484
    pulse = 1540
    pulse = 1516
    pulse = 924
    pulse = 1520
    Xpulse[] = 420    Xtarget[] = 281
    pulse = 1496
    Xpulse[] = 419    Xtarget[] = 271
    pulse = 1472
    Xpulse[] = 420    Xtarget[] = 261
    pulse = 1504
    Xpulse[] = 419    Xtarget[] = 274
    pulse = 1548
    Xpulse[] = 314    Xtarget[] = 316
    pulse = 1512
    Xpulse[] = 359    Xtarget[] = 309
    pulse = 1464
    Xpulse[] = 420    Xtarget[] = 298
    pulse = 1504
    Xpulse[] = 403    Xtarget[] = 307
    pulse = 1456
    pulse = 1456
    pulse = 1552
    pulse = 1496
    pulse = 1488
    pulse = 1544
    pulse = 1516
    pulse = 920
    pulse = 1512
    Xpulse[] = 436    Xtarget[] = 277
    pulse = 1500
    Xpulse[] = 435    Xtarget[] = 272
    pulse = 1468
    Xpulse[] = 436    Xtarget[] = 260
    pulse = 1500
    Xpulse[] = 435    Xtarget[] = 272
    pulse = 1540
    Xpulse[] = 316    Xtarget[] = 315
    pulse = 1520
    Xpulse[] = 375    Xtarget[] = 310
    pulse = 1456
    Xpulse[] = 436    Xtarget[] = 296
    pulse = 1504
    Xpulse[] = 419    Xtarget[] = 307
    
    
    Servo's bewegen niet en blijven gewoon op volledige linkse uitslag staan.
    Bij het starten van de code gaan ze zelfs niet eerst naar de neutraalpositie toe.
     
  2. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.474
    Locatie:
    Boskoop
    Mijn fout, ik heb het getest en zie het nu ook gebeuren. Bijzonder, dat is me nog nooit opgevallen......o_O
     
  3. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.474
    Locatie:
    Boskoop
    Ik kom er niet uit.
    2 observeringen:
    - de multiprop stuurt na elke synchronisatiepuls 16 pulsen uit voordat er een nieuwe sync. puls komt, ik dacht dat jouw module maar 8 pots had?? Ik gebruik er maar 8 trouwens, dus het verstoort op zich niets.
    - als je steeds de eerste regel met Xpulse en Xtarget die na de sync. puls komt bekijkt zie je dat de Xtarget waarde weliswaar een beetje schommelt, maar dat de Xpulse waarde daar juist vanaf beweegt i.p.v. ernaartoe.

    Ik heb de code meerdere malen opnieuw bekeken, ik kan de fout niet vinden, het enige wat ik kan doen is een paar plussen en minnen verwisselen, maar de logica ontgaat me.

    Code:
    volatile unsigned long timer; // all timer variables are unsigned long
    volatile int inpulse =  1500;
    volatile byte sync = 0;
    int mpcount, pulse;
    uint16_t Xtarget [8], Xpulse[8];
    const int slowstep = 1;
    const int Xtargetlow [] = {83, 83, 83, 83, 205, 205, 205, 205};
    const int Xtargethigh [] = {467, 467, 467, 467, 410, 410, 410, 410};
    bool start = false, RxchWas = false;
    
    #include <Wire.h>
    #include <Adafruit_PWMServoDriver.h>
    
    // called this way, it uses the default address 0x40
    Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
    
    void setup() {
     
      attachInterrupt(0, read_pwm, CHANGE); // Pin 2 = interrupt 0
      pinMode(2, INPUT);
     
      Serial.begin(9600);
     
      pwm.begin();
    
      pwm.setOscillatorFrequency(27000000);
      pwm.setPWMFreq(50); // 50Hz, frame length 20 millis
    
      for (int i=0; i<8; i++) {
        Xtarget [i] = 308; // equivalent of 1500 micros
        Xpulse [i] = 308;
      }
    
      delay(10);
    }
    
    void loop() {
     
      while (sync == 0); // ISR sets sync to true when reading Rx pulse is complete, loop starts.
      sync = 0; // stops loop after one run.
     
      delay (6); // do an atomic copy, delayed to midframe to reduce jitter
      cli();
      pulse = inpulse;
      sei();
     
      Serial.print ("pulse = "); Serial.println (pulse);
     
      // read next 8 incoming pulses, triggered by a syncpulse, map to extended range and save in array Xtarget []
     
      if (start && pulse >=1000) {
        Xtarget [mpcount] = map (pulse, 1030, 1980, Xtargetlow [mpcount], Xtargethigh [mpcount]); // extending pulse to Xtarget
    
        Serial.print ("Xpulse[] = "); Serial.print (Xpulse[mpcount]); Serial.print ("    Xtarget[] = "), Serial.println (Xtarget[mpcount]);
    
        mpcount += 1;
        if (mpcount >7) {
          start = false; // stop saving subchannels after 8 counts
          delay(500); // only for testing the output by monitor, deactivate for servo operation
        }
      }
     
      if (pulse >= 850 && pulse <950) { // is syncpulse
        start = true;
        mpcount = 0;
      }
    
      // update all servo outputs with or without changed targets, maximum step is slowstep setting
     
      for (uint8_t j=0; j<8; j++) {
        if (Xtarget [j] - Xpulse [j] >= slowstep) Xpulse [j] -= slowstep;
        else if (Xtarget [j] - Xpulse [j] <= -slowstep) Xpulse [j] += slowstep;
        else Xpulse [j] = Xtarget [j];
        pwm.setPWM(j, 0, Xpulse [j]); // LOW>HIGH at 0, HIGH>LOW at pulselen
      }
     
    }
    
    void read_pwm(){
      if (RxchWas == 0) { // if pin 2 was false previously
        timer = micros(); // start timer
        RxchWas = 1;
      }
      else if (RxchWas == 1) { // if pin 2 was already true, read timer
        inpulse = ((volatile int)micros() - timer);
        RxchWas = 0;
        sync = 1; // start loop
     
      }
    }
     
  4. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.474
    Locatie:
    Boskoop
    Herby, ik wil graag weten of het aan het variabele-type van Xtarget en Xpulse ligt, ik heb dus het type weer teruggebracht naar "int", en de plus en min verwisseling ongedaan gemaakt. Kun je deze versie ook testen?

    Code:
    volatile unsigned long timer; // all timer variables are unsigned long
    volatile int inpulse =  1500;
    volatile byte sync = 0;
    int mpcount, pulse;
    int Xtarget [8], Xpulse[8];
    const int slowstep = 1;
    const int Xtargetlow [] = {83, 83, 83, 83, 205, 205, 205, 205};
    const int Xtargethigh [] = {467, 467, 467, 467, 410, 410, 410, 410};
    bool start = false, RxchWas = false;
    
    #include <Wire.h>
    #include <Adafruit_PWMServoDriver.h>
    
    // called this way, it uses the default address 0x40
    Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
    
    void setup() {
     
      attachInterrupt(0, read_pwm, CHANGE); // Pin 2 = interrupt 0
      pinMode(2, INPUT);
     
      Serial.begin(9600);
     
      pwm.begin();
    
      pwm.setOscillatorFrequency(27000000);
      pwm.setPWMFreq(50); // 50Hz, frame length 20 millis
    
      for (int i=0; i<8; i++) {
        Xtarget [i] = 308; // equivalent of 1500 micros
        Xpulse [i] = 308;
      }
    
      delay(10);
    }
    
    void loop() {
     
      while (sync == 0); // ISR sets sync to true when reading Rx pulse is complete, loop starts.
      sync = 0; // stops loop after one run.
     
      delay (6); // do an atomic copy, delayed to midframe to reduce jitter
      cli();
      pulse = inpulse;
      sei();
     
      Serial.print ("pulse = "); Serial.println (pulse);
     
      // read next 8 incoming pulses, triggered by a syncpulse, map to extended range and save in array Xtarget []
     
      if (start && pulse >=1000) {
        Xtarget [mpcount] = map (pulse, 1030, 1980, Xtargetlow [mpcount], Xtargethigh [mpcount]); // extending pulse to Xtarget
    
        Serial.print ("Xpulse[] = "); Serial.print (Xpulse[mpcount]); Serial.print ("    Xtarget[] = "), Serial.println (Xtarget[mpcount]);
    
        mpcount += 1;
        if (mpcount >7) {
          start = false; // stop saving subchannels after 8 counts
          delay(500); // only for testing the output by monitor, deactivate for servo operation
        }
      }
     
      if (pulse >= 850 && pulse <950) { // is syncpulse
        start = true;
        mpcount = 0;
      }
    
      // update all servo outputs with or without changed targets, maximum step is slowstep setting
     
      for (uint8_t j=0; j<8; j++) {
        if (Xtarget [j] - Xpulse [j] >= slowstep) Xpulse [j] += slowstep;
        else if (Xtarget [j] - Xpulse [j] <= -slowstep) Xpulse [j] -= slowstep;
        else Xpulse [j] = Xtarget [j];
        pwm.setPWM(j, 0, Xpulse [j]); // LOW>HIGH at 0, HIGH>LOW at pulselen
      }
     
    }
    
    void read_pwm(){
      if (RxchWas == 0) { // if pin 2 was false previously
        timer = micros(); // start timer
        RxchWas = 1;
      }
      else if (RxchWas == 1) { // if pin 2 was already true, read timer
        inpulse = ((volatile int)micros() - timer);
        RxchWas = 0;
        sync = 1; // start loop
     
      }
    }
     
  5. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.510
    Locatie:
    Brugge
    Ik tel telkens 15 pulsen tussen de syncpuls, uitzonderlijk eens 1 of 2 minder.
    Ik heb inderdaad maar 8 pots op het uitgelezen kanaal.
    Het TX-lampje op de UNO knippert op het ritme van de string van 16 pulsen.
    Aaanvankelijk geen enkele reactie in de servo's.
    Er staat zelfs geen stroop op, volledig aangesloten kon ik de servo's met de hand verdraaien.
    Wel zag ik een vreemd verschijnsel in de xpulse: die begint langzaam te zakken, tot hij aan nul zou kopen, dan verandeen die waarden in een aftellend getal van rond de 65.500.
    Dan maar eens de USB-kabel uit de UNO getrokken en de 9V batterij aangesloten, geen reactie, geen stroom op de servo's.
    Code:
    pulse = 920
    pulse = 1520
    Xpulse[] = 40    Xtarget[] = 281
    pulse = 1520
    Xpulse[] = 41    Xtarget[] = 281
    pulse = 1508
    Xpulse[] = 64    Xtarget[] = 276
    pulse = 1508
    Xpulse[] = 55    Xtarget[] = 276
    pulse = 1512
    Xpulse[] = 26    Xtarget[] = 309
    pulse = 1524
    Xpulse[] = 25    Xtarget[] = 311
    pulse = 1500
    Xpulse[] = 26    Xtarget[] = 306
    pulse = 1520
    Xpulse[] = 71    Xtarget[] = 310
    pulse = 1508
    pulse = 1484
    pulse = 1532
    pulse = 1516
    pulse = 920
    pulse = 1512
    Xpulse[] = 27    Xtarget[] = 277
    pulse = 1508
    Xpulse[] = 28    Xtarget[] = 276
    pulse = 1536
    Xpulse[] = 51    Xtarget[] = 287
    pulse = 1500
    Xpulse[] = 42    Xtarget[] = 272
    pulse = 1548
    Xpulse[] = 13    Xtarget[] = 316
    pulse = 920
    pulse = 1512
    Xpulse[] = 21    Xtarget[] = 277
    pulse = 1528
    Xpulse[] = 22    Xtarget[] = 284
    pulse = 1500
    Xpulse[] = 45    Xtarget[] = 272
    pulse = 1512
    Xpulse[] = 36    Xtarget[] = 277
    pulse = 1508
    Xpulse[] = 7    Xtarget[] = 308
    pulse = 1524
    Xpulse[] = 6    Xtarget[] = 311
    pulse = 1516
    Xpulse[] = 7    Xtarget[] = 309
    pulse = 1536
    Xpulse[] = 52    Xtarget[] = 314
    pulse = 1504
    pulse = 1500
    pulse = 1540
    pulse = 1512
    pulse = 920
    pulse = 1512
    Xpulse[] = 8    Xtarget[] = 277
    pulse = 1508
    Xpulse[] = 9    Xtarget[] = 276
    pulse = 1520
    Xpulse[] = 32    Xtarget[] = 281
    pulse = 1516
    Xpulse[] = 23    Xtarget[] = 279
    pulse = 1540
    Xpulse[] = 65530    Xtarget[] = 315
    pulse = 932
    pulse = 1504
    Xpulse[] = 2    Xtarget[] = 274
    pulse = 1524
    Xpulse[] = 3    Xtarget[] = 282
    pulse = 1508
    Xpulse[] = 26    Xtarget[] = 276
    pulse = 1516
    Xpulse[] = 17    Xtarget[] = 279
    pulse = 1508
    Xpulse[] = 65524    Xtarget[] = 308
    pulse = 1536
    Xpulse[] = 65523    Xtarget[] = 314
    pulse = 1488
    Xpulse[] = 65524    Xtarget[] = 303
    pulse = 1516
    Xpulse[] = 33    Xtarget[] = 309
    pulse = 1504
    pulse = 1488
    pulse = 1536
    pulse = 1516
    pulse = 932
    
    9V verwijderd en USB kabel terug in de UNO geplugd.
    Toen kwam er plots leven in.
    Op het ritme van het uitlezen van de puls bewogen de 8 servo's langzaam naar volledige rechtse uitslag.
    Hieronder een fragment van rond het kantelmoment. Het lijkt erop dat de xpulse niet berekend wordt op basis van de input, maar licht fluctuerend steeds verlaagt, tot de ondergrens bereikt wordt, waarop het aan een mij niet bekende bovengrens verder aftelt.
    Het voordeel van lange beschrijvingen is dat er wat tijd over gaat: nu zijn net alle servos plots in een ruk volledig naar links gedraaid, waarna ze in schokjes teruggedraaid zijn naar rechts, waar ze weer stil staan.
    Op de serial monitor zie ik gen aanwijzing waarvan dit zou kunnen komen, die blijft de xpulse lekker aftellen.

    Ik heb net even aan de pots gedraaid, alle pots naar links= alle pulse = +- 1985
    alle pots naar links = alle pulse +- 1040
    Dus de ontvangen puls wordt correct weggeschreven, alleen bizar dat elke volledige string bestaat uit 15 pulsen en 1 syncpuls.

    En daar gaan ze weer allemaal naar links en rustig schokkend terug naar echts.

    Ik test zometeen de nieuwste code
     
  6. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.510
    Locatie:
    Brugge
    fout bij opladen:

    exit status 1

    'sync' was not declared in this scope

    maar de servo's spurten wel naar links, om vervolgens terug schokkend hun favoriete rustplaats aan de rechterkant op te zoeken. :)
     
  7. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.510
    Locatie:
    Brugge
    @max z Misschien is deze info nog nuttig, na elke 8e lijn met xpulse en xtarget, volgt een kleine delay vooraleer de reeks met pulsewaarden zonder xpulse en xtarget afgedrukt worden, en op dat moment gaat de TX-LED op de UNO even uit.
     
  8. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.510
    Locatie:
    Brugge
    @max z aanvullende test:
    Ik heb de eerste 4 pots naar links gedraaid, die geven nu een lage puls, en de laatste 4 pots naar rechts gedraaid, die geven nu een hoge puls.
    En dit komt uit de serial monitor:
    Code:
    pulse = 920
    pulse = 1040
    Xpulse[] = 65154    Xtarget[] = 87
    pulse = 1044
    Xpulse[] = 65133    Xtarget[] = 88
    pulse = 1048
    Xpulse[] = 65084    Xtarget[] = 90
    pulse = 1988
    Xpulse[] = 65083    Xtarget[] = 470
    pulse = 1984
    Xpulse[] = 65096    Xtarget[] = 410
    pulse = 1040
    Xpulse[] = 65121    Xtarget[] = 207
    pulse = 1040
    Xpulse[] = 65090    Xtarget[] = 207
    pulse = 1992
    Xpulse[] = 65089    Xtarget[] = 412
    pulse = 1048
    pulse = 1044
    pulse = 1984
    pulse = 1988
    pulse = 1992
    pulse = 1984
    pulse = 920
    pulse = 1040
    Xpulse[] = 65139    Xtarget[] = 87
    pulse = 1044
    Xpulse[] = 65118    Xtarget[] = 88
    pulse = 1044
    Xpulse[] = 65069    Xtarget[] = 88
    pulse = 1984
    Xpulse[] = 65068    Xtarget[] = 468
    pulse = 1984
    Xpulse[] = 65081    Xtarget[] = 410
    pulse = 1052
    Xpulse[] = 65106    Xtarget[] = 209
    pulse = 1036
    Xpulse[] = 65075    Xtarget[] = 206
    pulse = 1984
    Xpulse[] = 65074    Xtarget[] = 410
    pulse = 1040
    pulse = 1040
    pulse = 1984
    pulse = 1996
    pulse = 1984
    pulse = 1968
    pulse = 924
    
    Bij het uitlezen worden dus systematisch pulsen overgeslagen.
    Verder lijkt er geen vaste relatie te zijn tussen pulse en Xpulse, maar wel tussen pulse en Xtarget, alleen de servois staan hierbij allen volledig naar rechts gedraaid, prexies alsof Xtarget niet het commando is dat ze uitvoeren.
     
  9. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.510
    Locatie:
    Brugge
    @max z
    En met deze instelling zou je telkens een lage en een hoge puls moeten registreren.
    Probleempje met een niet synchroon lopende timer?
    Code:
    pulse = 928
    pulse = 1044
    Xpulse[] = 58689    Xtarget[] = 88
    pulse = 1988
    Xpulse[] = 58668    Xtarget[] = 470
    pulse = 1984
    Xpulse[] = 58619    Xtarget[] = 468
    pulse = 1984
    Xpulse[] = 58618    Xtarget[] = 468
    pulse = 1988
    Xpulse[] = 58631    Xtarget[] = 411
    pulse = 1052
    Xpulse[] = 58656    Xtarget[] = 209
    pulse = 1992
    Xpulse[] = 58625    Xtarget[] = 412
    pulse = 1040
    Xpulse[] = 58624    Xtarget[] = 207
    pulse = 1988
    pulse = 1048
    pulse = 1984
    pulse = 1044
    pulse = 1044
    pulse = 1996
    pulse = 920
    pulse = 1056
    Xpulse[] = 58674    Xtarget[] = 93
    pulse = 1988
    Xpulse[] = 58653    Xtarget[] = 470
    pulse = 1992
    Xpulse[] = 58604    Xtarget[] = 471
    pulse = 1988
    Xpulse[] = 58603    Xtarget[] = 470
    pulse = 1984
    Xpulse[] = 58616    Xtarget[] = 410
    pulse = 1040
    Xpulse[] = 58641    Xtarget[] = 207
    pulse = 1984
    Xpulse[] = 58610    Xtarget[] = 410
    pulse = 1048
    Xpulse[] = 58609    Xtarget[] = 208
    pulse = 1988
    pulse = 1040
    pulse = 1988
    pulse = 1040
    pulse = 1048
    pulse = 1984
    pulse = 924
    pulse = 1040
    Xpulse[] = 58659    Xtarget[] = 87
    pulse = 1988
    Xpulse[] = 58638    Xtarget[] = 470
    pulse = 1984
    Xpulse[] = 58589    Xtarget[] = 468
    pulse = 1988
    Xpulse[] = 58588    Xtarget[] = 470
    pulse = 1988
    Xpulse[] = 58601    Xtarget[] = 411
    pulse = 1040
    Xpulse[] = 58626    Xtarget[] = 207
    pulse = 1992
    Xpulse[] = 58595    Xtarget[] = 412
    pulse = 1040
    Xpulse[] = 58594    Xtarget[] = 207
    pulse = 1984
    pulse = 1040
    pulse = 1984
    pulse = 1040
    pulse = 1040
    pulse = 1988
    pulse = 920
    
     
  10. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.474
    Locatie:
    Boskoop
    Om te beginnen zat er nog een ongewenste delay() in de code, die de zaak aardig kan verstoren, er stond wel bij deactiveren als je de servo's gaat testen, maar ik had er ook niet meer aan gedacht.

    De systematiek is dat de binnenkomende puls uitgerekt wordt tot Xtarget. Xpulse hoort dan langzaam richting Xtarget te bewegen. Dat gebeurde in omgekeerde richting, waardoor de servo's helemaal naar links of helemaal naar rechts lopen. Ik had gehoopt dat, door het veranderen van het type van Xpulse en Xtarget, de zaak weer in de goede richting zou lopen. In eerste instantie had ik daar het type "unsigned int" voor gebruikt, naar analogie van de test code. Maar door de onverklaarbare manier waarop alles de verkeerde kant uit liep heb ik besloten er maar weer een gewone "int" van te maken.

    Overigens heb je het effect van een "unsigned int" mogen aanschouwen, bij het (aflopend) bereiken van de 0-waarde krijg je een zogenaamde "roll over", de variabele gaat dan ineens van 0 naar de maximale waarde die dat type variabele kan bevatten ("unsigned" betekend geen negative waarden mogelijk).

    Ik ben een beetje de draad kwijtgeraakt, dus stuur ik je nogmaals de laatste code, nu zonder delay(), en wil je opnieuw vragen om die te testen, sorry.

    Code:
    volatile unsigned long timer; // all timer variables are unsigned long
    volatile int inpulse =  1500;
    volatile byte sync = 0;
    int mpcount, pulse;
    int Xtarget [8], Xpulse[8];
    const int slowstep = 1;
    const int Xtargetlow [] = {83, 83, 83, 83, 205, 205, 205, 205};
    const int Xtargethigh [] = {467, 467, 467, 467, 410, 410, 410, 410};
    bool start = false, RxchWas = false;
    
    #include <Wire.h>
    #include <Adafruit_PWMServoDriver.h>
    
    // called this way, it uses the default address 0x40
    Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
    
    void setup() {
     
      attachInterrupt(0, read_pwm, CHANGE); // Pin 2 = interrupt 0
      pinMode(2, INPUT);
     
      Serial.begin(9600);
     
      pwm.begin();
    
      pwm.setOscillatorFrequency(27000000);
      pwm.setPWMFreq(50); // 50Hz, frame length 20 millis
    
      for (int i=0; i<8; i++) {
        Xtarget [i] = 308; // equivalent of 1500 micros
        Xpulse [i] = 308;
      }
    
      delay(10);
    }
    
    void loop() {
     
      while (sync == 0); // ISR sets sync to true when reading Rx pulse is complete, loop starts.
      sync = 0; // stops loop after one run.
     
      delay (6); // do an atomic copy, delayed to midframe to reduce jitter
      cli();
      pulse = inpulse;
      sei();
     
      Serial.print ("pulse = "); Serial.println (pulse);
     
      // read next 8 incoming pulses, triggered by a syncpulse, map to extended range and save in array Xtarget []
     
      if (start && pulse >=1000) {
        Xtarget [mpcount] = map (pulse, 1030, 1980, Xtargetlow [mpcount], Xtargethigh [mpcount]); // extending pulse to Xtarget
    
        Serial.print ("Xpulse[] = "); Serial.print (Xpulse[mpcount]); Serial.print ("    Xtarget[] = "), Serial.println (Xtarget[mpcount]);
    
        mpcount += 1;
        if (mpcount >7) {
          start = false; // stop saving subchannels after 8 counts
        }
      }
     
      if (pulse >= 850 && pulse <950) { // is syncpulse
        start = true;
        mpcount = 0;
      }
    
      // update all servo outputs with or without changed targets, maximum step is slowstep setting
     
      for (uint8_t j=0; j<8; j++) {
        if (Xtarget [j] - Xpulse [j] >= slowstep) Xpulse [j] += slowstep;
        else if (Xtarget [j] - Xpulse [j] <= -slowstep) Xpulse [j] -= slowstep;
        else Xpulse [j] = Xtarget [j];
        pwm.setPWM(j, 0, Xpulse [j]); // LOW>HIGH at 0, HIGH>LOW at pulselen
      }
     
    }
    
    void read_pwm(){
      if (RxchWas == 0) { // if pin 2 was false previously
        timer = micros(); // start timer
        RxchWas = 1;
      }
      else if (RxchWas == 1) { // if pin 2 was already true, read timer
        inpulse = ((volatile int)micros() - timer);
        RxchWas = 0;
        sync = 1; // start loop
     
      }
    }
    De "sync" foutmelding herken ik niet, bij het compileren treedt die bij mij niet op.
     
    Laatst bewerkt: 23 aug 2022
  11. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.474
    Locatie:
    Boskoop
    Dat had ik ook al eerder gevraagd om te controleren, omdat ik dat wel verwacht had. De Adafruit module heeft dus kennelijk niet zelf een startwaarde ingebouwd, dus als dat nodig blijkt moet ik dat aan de setup sectie toevoegen.
     
    Laatst bewerkt: 23 aug 2022
  12. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.510
    Locatie:
    Brugge
    @max z
    bij die laatste code, staat er wel degelijk stroom op de servo's,
    Alles af; behalve de stroom op de terminal van de PCA9865
    servo's handmatig naar links gedraaid.
    Zender aangezet, UNO aan de USB-kabel, servo's huppelen naar rechts, en blijven onder stroom
    nu de USB-kabek uitgetrokken, UNO dus niet meer onder stroom, ook de ontvanger niet, enkel de power nog op de terminal van de PCA9865, kan ik de servo's niet verdraaien met de hand, waarschijnlijk daarnet toen ik dat wel kon een slecht contact, of de condensator op de PCA9865 die de boel onder stroom houdt, en langzaam vrijgeeft, waardoor je nog een tijdje de servo niet kan verdraaien?
    Na 2 minuten kan ik nog steeds de servo's niet handmatig verdraaien, maar van zodra ik de + loskoppel kan dat wel.

    Voorgaande test herhaald:
    Alles af; behalve de stroom op de terminal van de PCA9865
    servo's handmatig naar links gedraaid.
    Zender aangezet, UNO aan de USB-kabel, servo's huppelen naar rechts, en blijven onder stroom
    nu de USB-kabel uitgetrokken, UNO dus niet meer onder stroom, ook de ontvanger niet, enkel de power nog op de terminal van de PCA9865, kan ik de servo's niet verdraaien met de hand,
    Onmiddellijk de - uit de terminal van de PCA9865 verwijderd en kan diredt de servo's verdraaien, dus toch niet de condensator denk ik.
     
    Laatst bewerkt: 23 aug 2022
  13. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.510
    Locatie:
    Brugge
    Nog een laatste test voor vandaag:
    alle pots op de zender op een andere waarde ingesteld, oplopend van pot 1 tot 8, en dit is het resultaat, je kan nu duidelijk er uithalen waar een puls niet gelezen wordt, en zelfs waar éénzelfde puls 2x na elkaar gelezen wordt.
    Code:
    pulse = 920
    pulse = 1048
    Xpulse[] = 308    Xtarget[] = 90
    pulse = 1176
    Xpulse[] = 309    Xtarget[] = 142
    pulse = 1356
    Xpulse[] = 308    Xtarget[] = 214
    pulse = 1588
    Xpulse[] = 309    Xtarget[] = 308
    pulse = 1848
    Xpulse[] = 308    Xtarget[] = 381
    pulse = 1040
    Xpulse[] = 309    Xtarget[] = 207
    pulse = 1356
    Xpulse[] = 308    Xtarget[] = 275
    pulse = 1584
    Xpulse[] = 309    Xtarget[] = 324
    pulse = 1356
    pulse = 1356
    pulse = 1428
    pulse = 1604
    pulse = 1720
    pulse = 1848
    pulse = 1988
    pulse = 936
    pulse = 1040
    Xpulse[] = 292    Xtarget[] = 87
    pulse = 1176
    Xpulse[] = 293    Xtarget[] = 142
    pulse = 1360
    Xpulse[] = 292    Xtarget[] = 216
    pulse = 1588
    Xpulse[] = 309    Xtarget[] = 308
    pulse = 1852
    Xpulse[] = 292    Xtarget[] = 382
    pulse = 1040
    Xpulse[] = 293    Xtarget[] = 207
    pulse = 1372
    Xpulse[] = 292    Xtarget[] = 278
    pulse = 1576
    Xpulse[] = 293    Xtarget[] = 322
    pulse = 1356
    pulse = 1356
    pulse = 1432
    pulse = 1588
    pulse = 1716
    pulse = 1856
    pulse = 1988
    pulse = 920
    pulse = 1040
    Xpulse[] = 276    Xtarget[] = 87
    pulse = 1180
    Xpulse[] = 277    Xtarget[] = 143
    pulse = 1360
    Xpulse[] = 276    Xtarget[] = 216
    pulse = 1592
    Xpulse[] = 309    Xtarget[] = 310
    pulse = 1856
    Xpulse[] = 276    Xtarget[] = 383
    pulse = 1036
    Xpulse[] = 277    Xtarget[] = 206
    pulse = 1356
    Xpulse[] = 278    Xtarget[] = 275
    pulse = 1592
    Xpulse[] = 277    Xtarget[] = 326
    pulse = 1356
    pulse = 1356
    pulse = 1428
    pulse = 1584
    pulse = 1712
    pulse = 1852
    pulse = 1988
    pulse = 920
    pulse = 1036
    Xpulse[] = 260    Xtarget[] = 85
    pulse = 1180
    Xpulse[] = 261    Xtarget[] = 143
    pulse = 1360
    Xpulse[] = 260    Xtarget[] = 216
    pulse = 1576
    Xpulse[] = 293    Xtarget[] = 303
    pulse = 1856
    Xpulse[] = 260    Xtarget[] = 383
    pulse = 1040
    Xpulse[] = 261    Xtarget[] = 207
    pulse = 1356
    Xpulse[] = 276    Xtarget[] = 275
    pulse = 1588
    Xpulse[] = 261    Xtarget[] = 325
    pulse = 1360
    pulse = 1360
    pulse = 1428
    pulse = 1584
    pulse = 1716
    pulse = 1848
    pulse = 1980
    pulse = 920
    pulse = 1040
    Xpulse[] = 244    Xtarget[] = 87
    pulse = 1180
    Xpulse[] = 245    Xtarget[] = 143
    pulse = 1360
    Xpulse[] = 244    Xtarget[] = 216
    pulse = 1588
    Xpulse[] = 277    Xtarget[] = 308
    pulse = 1852
    Xpulse[] = 244    Xtarget[] = 382
    pulse = 1032
    Xpulse[] = 245    Xtarget[] = 205
    pulse = 1352
    Xpulse[] = 276    Xtarget[] = 274
    pulse = 1580
    Xpulse[] = 245    Xtarget[] = 323
    pulse = 1356
    pulse = 1356
    pulse = 1432
    pulse = 1584
    pulse = 1716
    pulse = 1856
    pulse = 1992
    pulse = 924
    pulse = 1040
    Xpulse[] = 228    Xtarget[] = 87
    pulse = 1176
    Xpulse[] = 229    Xtarget[] = 142
    pulse = 1360
    Xpulse[] = 228    Xtarget[] = 216
    pulse = 1588
    Xpulse[] = 261    Xtarget[] = 308
    pulse = 1860
    Xpulse[] = 228    Xtarget[] = 384
    pulse = 1036
    Xpulse[] = 229    Xtarget[] = 206
    pulse = 1356
    Xpulse[] = 274    Xtarget[] = 275
    pulse = 1580
    Xpulse[] = 229    Xtarget[] = 323
    pulse = 1360
    pulse = 1360
    pulse = 1428
    pulse = 1584
    pulse = 1720
    pulse = 1856
    pulse = 1988
    pulse = 920
    pulse = 1044
    Xpulse[] = 212    Xtarget[] = 88
    pulse = 1180
    Xpulse[] = 213    Xtarget[] = 143
    pulse = 1356
    Xpulse[] = 216    Xtarget[] = 214
    pulse = 1588
    Xpulse[] = 245    Xtarget[] = 308
    pulse = 1852
    Xpulse[] = 212    Xtarget[] = 382
    pulse = 1044
    Xpulse[] = 213    Xtarget[] = 208
    pulse = 1352
    Xpulse[] = 258    Xtarget[] = 274
    pulse = 1592
    Xpulse[] = 213    Xtarget[] = 326
    pulse = 1360
    pulse = 1360
    pulse = 1408
    pulse = 1588
    pulse = 1724
    pulse = 1852
    pulse = 1972
    pulse = 928
    pulse = 1044
    Xpulse[] = 196    Xtarget[] = 88
    pulse = 1176
    Xpulse[] = 197    Xtarget[] = 142
    pulse = 1344
    Xpulse[] = 214    Xtarget[] = 209
    pulse = 1592
    Xpulse[] = 229    Xtarget[] = 310
    pulse = 1848
    Xpulse[] = 196    Xtarget[] = 381
    pulse = 1044
    Xpulse[] = 209    Xtarget[] = 208
    pulse = 1360
    Xpulse[] = 242    Xtarget[] = 276
    pulse = 1588
    Xpulse[] = 197    Xtarget[] = 325
    pulse = 1352
    pulse = 1352
    pulse = 1428
    pulse = 1588
    pulse = 1720
    pulse = 1848
    pulse = 1984
    pulse = 924
    pulse = 1040
    Xpulse[] = 180    Xtarget[] = 87
    pulse = 1176
    Xpulse[] = 181    Xtarget[] = 142
    pulse = 1364
    Xpulse[] = 210    Xtarget[] = 218
    pulse = 1588
    Xpulse[] = 213    Xtarget[] = 308
    pulse = 1856
    Xpulse[] = 180    Xtarget[] = 383
    pulse = 1044
    Xpulse[] = 209    Xtarget[] = 208
    pulse = 1360
    Xpulse[] = 226    Xtarget[] = 276
    pulse = 1588
    Xpulse[] = 181    Xtarget[] = 325
    pulse = 1348
    pulse = 1348
    pulse = 1424
    pulse = 1588
    pulse = 1716
    pulse = 1852
    pulse = 1988
    pulse = 924
    pulse = 1040
    Xpulse[] = 164    Xtarget[] = 87
    pulse = 1168
    Xpulse[] = 165    Xtarget[] = 138
    pulse = 1356
    Xpulse[] = 194    Xtarget[] = 214
    pulse = 1584
    Xpulse[] = 197    Xtarget[] = 306
    pulse = 1852
    Xpulse[] = 164    Xtarget[] = 382
    pulse = 1044
    Xpulse[] = 209    Xtarget[] = 208
    pulse = 1364
    Xpulse[] = 210    Xtarget[] = 277
    pulse = 1592
    Xpulse[] = 165    Xtarget[] = 326
    pulse = 1360
    pulse = 1360
    pulse = 1428
    pulse = 1584
    pulse = 1728
    pulse = 1852
    pulse = 1984
    pulse = 920
    
     
  14. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.474
    Locatie:
    Boskoop
    Ik zal een regeltje toevoegen om de servo's eenmalig de neutraalstand in te laten nemen, dus in de setup al een puls laten sturen zodat ze direct "onder stroom" komen te staan zoals jij het noemt, wat in feite de combinatie van spanning/stroom op de servo's èn een geldige puls is.

    Ik zie helaas nog steeds een enkel dalende pulswaarde, ongeacht of de target hoger of lager is, en ik kan blijven staren naar de code, maar snap het nog steeds niet. Om de één of andere reden wordt de eerste if statement,
    Code:
    if (Xtarget [j] - Xpulse [j] >= slowstep) Xpulse [j] += slowstep;
    , genegeerd.
     
  15. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.474
    Locatie:
    Boskoop
    Soms doen een paar extra haakjes wonderen, je moet wat verzinnen. Ik heb er nu dit van gemaakt:
    Code:
    if ((Xtarget [j] - Xpulse [j]) >= slowstep) Xpulse [j] += slowstep;
    En de aangepaste code:

    Code:
    volatile unsigned long timer; // all timer variables are unsigned long
    volatile int inpulse =  1500;
    volatile byte sync = 0;
    int mpcount, pulse;
    int Xtarget [8], Xpulse[8];
    const int slowstep = 1;
    const int Xtargetlow [] = {83, 83, 83, 83, 205, 205, 205, 205};
    const int Xtargethigh [] = {467, 467, 467, 467, 410, 410, 410, 410};
    bool start = false, RxchWas = false;
    
    #include <Wire.h>
    #include <Adafruit_PWMServoDriver.h>
    
    // called this way, it uses the default address 0x40
    Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
    
    void setup() {
     
      attachInterrupt(0, read_pwm, CHANGE); // Pin 2 = interrupt 0
      pinMode(2, INPUT);
     
      Serial.begin(9600);
     
      pwm.begin();
    
      pwm.setOscillatorFrequency(27000000);
      pwm.setPWMFreq(50); // 50Hz, frame length 20 millis
    
      for (uint8_t i=0; i<8; i++) {
        Xtarget [i] = 308; // equivalent of 1500 micros
        Xpulse [i] = 308;
        pwm.setPWM(i, 0, Xpulse [i]);
      }
    
      delay(10);
    }
    
    void loop() {
     
      while (sync == 0); // ISR sets sync to true when reading Rx pulse is complete, loop starts.
      sync = 0; // stops loop after one run.
     
      delay (6); // do an atomic copy, delayed to midframe to reduce jitter
      cli();
      pulse = inpulse;
      sei();
     
      Serial.print ("pulse = "); Serial.println (pulse);
     
      // read next 8 incoming pulses, triggered by a syncpulse, map to extended range and save in array Xtarget []
     
      if (start && pulse >=1000) {
        Xtarget [mpcount] = map (pulse, 1030, 1980, Xtargetlow [mpcount], Xtargethigh [mpcount]); // extending pulse to Xtarget
    
        Serial.print ("Xpulse[] = "); Serial.print (Xpulse[mpcount]); Serial.print ("    Xtarget[] = "), Serial.println (Xtarget[mpcount]);
    
        mpcount += 1;
        if (mpcount >7) {
          start = false; // stop saving subchannels after 8 counts
        }
      }
     
      if (pulse >= 850 && pulse <950) { // is syncpulse
        start = true;
        mpcount = 0;
      }
    
      // update all servo outputs with or without changed targets, maximum step is slowstep setting
     
      for (uint8_t j=0; j<8; j++) {
        if ((Xtarget [j] - Xpulse [j]) >= slowstep) Xpulse [j] += slowstep;
        else if ((Xtarget [j] - Xpulse [j]) <= -slowstep) Xpulse [j] -= slowstep;
        else Xpulse [j] = Xtarget [j];
        pwm.setPWM(j, 0, Xpulse [j]); // LOW>HIGH at 0, HIGH>LOW at pulselen
      }
     
    }
    
    void read_pwm(){
      if (RxchWas == 0) { // if pin 2 was false previously
        timer = micros(); // start timer
        RxchWas = 1;
      }
      else if (RxchWas == 1) { // if pin 2 was already true, read timer
        inpulse = ((volatile int)micros() - timer);
        RxchWas = 0;
        sync = 1; // start loop
     
      }
    }
     
    Laatst bewerkt: 24 aug 2022
  16. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.510
    Locatie:
    Brugge
    @Max,
    Ik ben nu de code van post 175 aan het testen.
    Servo's schieten naar de neutraalstand, en bewegen dan volgens de ontvangen pulswaarde.
    In de serial monitor krijg ik echter gelijkaardige waarden als ik in post 173 al liet zien.
    Ik heb nog even met de pots op de zender gespeeld zodat nu de pulse van pot 1 begint met 11, die van pot 2 begint met 12, enz. tot pot 8 waar de puls begint met 18.
    Er lijkt een afwijkend terugkerend patroon te ontstaan in de uitgelezen waarden.
    Het lijkt dus op een synchronisatieprobleem tussen het verzonden signaal en het gelezen signaal: de gelezen potvolgorde is pulse/1/2/3/5/7/1/3/5/7/9/pulse/1/3/5/7/pulse/1/3/5/9/1/3/6/9/1/2/3/4/5/6/7/9/pulse. De reeksen zijn niet helemaal identiek, maar sterk gelijkaardig. De servo's staan in verschillende posities zachtjes heen en weer te wiegen (enkele graden maar) behalve servo 1 die stilstaat op de volledig rechtse positie (hoge puls)
    Als ik aan pot 1 draai, volledig naar rechts, draait de servo bijna schokloos aan een rustig tempo volledig naar links.
    Als ik pot 2 volledig naar rechts draai, schuift de servo 2 enkele graden naar links, en herneemt dan het wiegen of staat langere tijd stil.
    Als ik pot 3 volledig naar rechts draai, draait servo 2 volledig naar links, en servo 3 draait een 30-tal graden naar links voor het zachtjes heen en weer bewegen te hernemen.
    Als ik ook pot 4 volledig naar rechts draai, verandert er niets in het gedrag van de servo's.
    Als ik pot 5 volledig naar echts draai vermindert het oscilleren van servo 8, en de andere servos veranderen hun gedrag niet.
    En zo kan ik nog een tijdje doorgaan met het beschrijven van allerlei gedragingen bij verschillende potstanden, maar deze wil ik je niet onthouden: alle pots naar links gedraaid, staan alle servo's roerloos stil, de kanalen 1-4 staan volledig naar rechts gedraaid, de servo's 5-8 taan op 45° naar rechts van de neutraalstand, en bij alle pots naar rechts gedraaid (hoge puls) draaien de eerste 4 servo's volledig naar links, en de laatste 4 gaan net iets voor bij de 90° naar links van de neutraalstand.
    Voor deze spiegeling heb ik de waarden in Xtarget low en Xtargethigh eens verwisseld en nu volgen ze de bewegingsrichting van de pots


    Code:
    pulse = 924
    pulse = 1116
    Xpulse[] = 117    Xtarget[] = 117
    pulse = 1224
    Xpulse[] = 211    Xtarget[] = 161
    pulse = 1360
    Xpulse[] = 312    Xtarget[] = 216
    pulse = 1560
    Xpulse[] = 467    Xtarget[] = 297
    pulse = 1776
    Xpulse[] = 224    Xtarget[] = 365
    pulse = 1120
    Xpulse[] = 273    Xtarget[] = 224
    pulse = 1344
    Xpulse[] = 339    Xtarget[] = 272
    pulse = 1564
    Xpulse[] = 411    Xtarget[] = 320
    pulse = 1768
    pulse = 1984
    pulse = 920
    pulse = 1116
    Xpulse[] = 117    Xtarget[] = 117
    pulse = 1348
    Xpulse[] = 200    Xtarget[] = 211
    pulse = 1572
    Xpulse[] = 301    Xtarget[] = 302
    pulse = 1764
    Xpulse[] = 456    Xtarget[] = 379
    pulse = 932
    pulse = 1116
    Xpulse[] = 117    Xtarget[] = 117
    pulse = 1348
    Xpulse[] = 205    Xtarget[] = 211
    pulse = 1564
    Xpulse[] = 302    Xtarget[] = 298
    pulse = 1996
    Xpulse[] = 451    Xtarget[] = 473
    pulse = 1120
    Xpulse[] = 240    Xtarget[] = 224
    pulse = 1364
    Xpulse[] = 257    Xtarget[] = 277
    pulse = 1660
    Xpulse[] = 323    Xtarget[] = 340
    pulse = 1992
    Xpulse[] = 395    Xtarget[] = 412
    pulse = 1116
    pulse = 1240
    pulse = 1348
    pulse = 1440
    pulse = 1564
    pulse = 1672
    pulse = 1768
    pulse = 1984
    pulse = 924
    pulse = 1116
    Xpulse[] = 117    Xtarget[] = 117
    pulse = 1224
    Xpulse[] = 211    Xtarget[] = 161
    pulse = 1352
    Xpulse[] = 298    Xtarget[] = 213
    pulse = 1572
    Xpulse[] = 468    Xtarget[] = 302
    pulse = 1764
    Xpulse[] = 224    Xtarget[] = 363
    pulse = 1120
    Xpulse[] = 274    Xtarget[] = 224
    pulse = 1352
    Xpulse[] = 340    Xtarget[] = 274
    pulse = 1564
    Xpulse[] = 412    Xtarget[] = 320
    pulse = 1768
    pulse = 1992
    pulse = 920
    pulse = 1120
    Xpulse[] = 117    Xtarget[] = 119
    pulse = 1360
    Xpulse[] = 200    Xtarget[] = 216
    pulse = 1564
    Xpulse[] = 287    Xtarget[] = 298
    pulse = 1772
    Xpulse[] = 457    Xtarget[] = 382
    pulse = 924
    pulse = 1116
    Xpulse[] = 119    Xtarget[] = 117
    pulse = 1352
    Xpulse[] = 205    Xtarget[] = 213
    pulse = 1564
    Xpulse[] = 292    Xtarget[] = 298
    pulse = 1984
    Xpulse[] = 452    Xtarget[] = 468
    pulse = 1116
    Xpulse[] = 240    Xtarget[] = 223
    pulse = 1348
    Xpulse[] = 258    Xtarget[] = 273
    pulse = 1656
    Xpulse[] = 324    Xtarget[] = 340
    pulse = 1988
    Xpulse[] = 396    Xtarget[] = 411
    pulse = 1120
    pulse = 1224
    pulse = 1348
    pulse = 1448
    pulse = 1568
    pulse = 1656
    pulse = 1768
    pulse = 1992
    pulse = 924
    
     
  17. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.474
    Locatie:
    Boskoop
    Dit begint steeds onbegrijpelijker te worden. Ik zie wat je bedoelt met een synchronisatieprobleem, met wisselende volgorde van binnenkomende pulsen. Het is logisch dat daar een inconsequent gedrag van de servo's uit voortvloeit, want de verwerking van de pulsen en het opslaan van targets geschiedt steeds in een vaste volgorde na binnenkomst van de puls.

    Het mechanisme van het registreren en "printen" naar de monitor is als volgt: de pulsen die binnenkomen op pin 2 starten de interrupt routine "void read_pwm()" met voorrang op alle andere activiteiten en de nieuwe pulswaarde wordt vastgelegd in variable "inpulse". In die interrupt routine bevind zich ook een variabele "sync", welke op een slimme manier via de "while" aan het begin van de loop deze vrijgeeft om te starten zodra de nieuwe puls in z'n geheel binnen is. Even daarna krijgt "pulse" de laatste nieuwe waarde van "inpulse".

    Terwijl ik dit opschrijf realiseer ik mij dat de loop alleen maar vrijgegeven wordt, maar niet noodzakelijk op dat moment opnieuw start, want dat gebeurt pas als de verwerking van de pulsen en het sturen van de nieuwe input naar de Adafruit helemaal rond is. Het zou dus kunnen dat er in de tijd die dat kost méér dan 1 puls door de interrupt routine ontvangen wordt, en dat de pulsen dus voor gaan lopen op de verwerking ervan.

    Ik moet iets gaan verzinnen zodat de interrupt routine óók bijhoudt welk volgnummer de laatst binnenkomen pulse heeft.......pfoe!

    Overigens een slimme manier hoe je die volgorde vastgesteld hebt....:thumbsup:
     
    Herby63 vindt dit leuk.
  18. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.474
    Locatie:
    Boskoop
    Ok, dit zou 'm moeten zijn. Ik heb de teller nu ingesloten in de interrupt routine, en in de rest van de code laten zien in samenhang met deze teller. Ik heb de vaste volgorde dus nu losgelaten.
    Als het goed is zouden we nu ook kunnen zijn waar er pulsen gemist zijn.

    Code:
    volatile unsigned long timer; // all timer variables are unsigned long
    volatile int inpulse =  1500, seqnr = 20;
    volatile byte sync = 0;
    int mpcount, pulse;
    int Xtarget [8], Xpulse[8];
    const int slowstep = 1;
    const int Xtargetlow [] = {83, 83, 83, 83, 205, 205, 205, 205};
    const int Xtargethigh [] = {467, 467, 467, 467, 410, 410, 410, 410};
    bool start = false, RxchWas = false;
    
    #include <Wire.h>
    #include <Adafruit_PWMServoDriver.h>
    
    // called this way, it uses the default address 0x40
    Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
    
    void setup() {
     
      attachInterrupt(0, read_pwm, CHANGE); // Pin 2 = interrupt 0
      pinMode(2, INPUT);
     
      Serial.begin(9600);
     
      pwm.begin();
    
      pwm.setOscillatorFrequency(27000000);
      pwm.setPWMFreq(50); // 50Hz, frame length 20 millis
    
      for (uint8_t i=0; i<8; i++) {
        Xtarget [i] = 308; // equivalent of 1500 micros
        Xpulse [i] = 308;
        pwm.setPWM(i, 0, Xpulse [i]);
      }
    
      delay(10);
    }
    
    void loop() {
     
      while (sync == 0); // ISR sets sync to true when reading Rx pulse is complete, loop starts.
      sync = 0; // stops loop after one run.
     
      delay (6); // do an atomic copy, delayed to midframe to reduce jitter
      cli();
      pulse = inpulse;
      mpcount = seqnr;
      sei();
     
      Serial.print ("mpcount = "); Serial.print (mpcount); ("     pulse = "); Serial.println (pulse);
     
      // read next 8 incoming pulses, triggered by a syncpulse, map to extended range and save in array Xtarget []
     
      if (start && pulse >=1000) {
        Xtarget [mpcount] = map (pulse, 1030, 1980, Xtargetlow [mpcount], Xtargethigh [mpcount]); // extending pulse to Xtarget
    
        Serial.print ("Xpulse["); Serial.print (mpcount); Serial.print ("] = "); Serial.print (Xpulse[mpcount]);
        Serial.print ("    Xtarget["); Serial.print (mpcount); Serial.print ("] = "); Serial.println (Xtarget[mpcount]);
    
        if (mpcount >7) {
          start = false; // stop saving subchannels after 8 counts
        }
      }
     
      if (pulse >= 850 && pulse <950) { // is syncpulse
        start = true;
      }
    
      // update all servo outputs with or without changed targets, maximum step is slowstep setting
     
      for (uint8_t j=0; j<8; j++) {
        if ((Xtarget [j] - Xpulse [j]) >= slowstep) Xpulse [j] += slowstep;
        else if ((Xtarget [j] - Xpulse [j]) <= -slowstep) Xpulse [j] -= slowstep;
        else Xpulse [j] = Xtarget [j];
        pwm.setPWM(j, 0, Xpulse [j]); // LOW>HIGH at 0, HIGH>LOW at pulselen
      }
     
    }
    
    void read_pwm(){
      if (RxchWas == 0) { // if pin 2 was false previously
        timer = micros(); // start timer
        RxchWas = 1;
      }
      else if (RxchWas == 1) { // if pin 2 was already true, read timer
        inpulse = ((volatile int)micros() - timer);
        RxchWas = 0;
        sync = 1; // release loop stop
        seqnr += 1;
        if (inpulse<950) seqnr = 0; // reset seqnr for next incoming pulses
      }
    
    }
     
    Herby63 vindt dit leuk.
  19. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.510
    Locatie:
    Brugge
    @max z We gaan duidelijk in de goede richting.
    Servo's bewegen proportioneel mee met de pots :banana: , bewegen tegen een matige snelheid (heel licht schokkend) :beer:, halen de gevraagde draaihoek :worship:, maar
    bij draaien pot 1 beweegt servo 2 (=aansluiting 1),
    bij draaien pot 2 beweegt servo 3,
    bij draaien pot 3 beweegt servo 4,
    bij draaien pot 4 beweegt servo 5,
    bij draaien pot 5 beweegt niets, - correctie, als je voldoende geduld hebt schiet servo 6 in actie, en beweegt nu ook proportioneel mee;
    bij draaien pot 6 beweegt servo 7,
    bij draaien pot 7 beweegt servo 8, en
    bij draaien pot 8 gebeurt niets.
    Alle servo's draaien in de tegengestelde richting van de beweging op de pot, maar ik weet hoe dat aan te passen :)
     
    Laatst bewerkt: 24 aug 2022
  20. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.474
    Locatie:
    Boskoop
    Code:
    volatile unsigned long timer; // all timer variables are unsigned long
    volatile int inpulse =  1500, seqnr = 20;
    volatile byte sync = 0;
    int mpcount, pulse;
    int Xtarget [8], Xpulse[8];
    const int slowstep = 1;
    const int Xtargetlow [] = {83, 83, 83, 83, 205, 205, 205, 205};
    const int Xtargethigh [] = {467, 467, 467, 467, 410, 410, 410, 410};
    bool start = false, RxchWas = false;
    
    #include <Wire.h>
    #include <Adafruit_PWMServoDriver.h>
    
    // called this way, it uses the default address 0x40
    Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
    
    void setup() {
     
      attachInterrupt(0, read_pwm, CHANGE); // Pin 2 = interrupt 0
      pinMode(2, INPUT);
     
      Serial.begin(9600);
     
      pwm.begin();
    
      pwm.setOscillatorFrequency(27000000);
      pwm.setPWMFreq(50); // 50Hz, frame length 20 millis
    
      for (uint8_t i=0; i<8; i++) {
        Xtarget [i] = 308; // equivalent of 1500 micros
        Xpulse [i] = 308;
        pwm.setPWM(i, 0, Xpulse [i]);
      }
    
      delay(10);
    }
    
    void loop() {
     
      while (sync == 0); // ISR sets sync to true when reading Rx pulse is complete, loop starts.
      sync = 0; // stops loop after one run.
     
      delay (6); // do an atomic copy, delayed to midframe to reduce jitter
      cli();
      pulse = inpulse;
      mpcount = seqnr;
      sei();
     
      Serial.print ("mpcount = "); Serial.print (mpcount); ("     pulse = "); Serial.println (pulse);
     
      // read next 8 incoming pulses, triggered by a syncpulse, map to extended range and save in array Xtarget []
     
      if (start && pulse >=1000) {
        Xtarget [mpcount] = map (pulse, 1030, 1980, Xtargetlow [mpcount], Xtargethigh [mpcount]); // extending pulse to Xtarget
    
        Serial.print ("Xpulse["); Serial.print (mpcount); Serial.print ("] = "); Serial.print (Xpulse[mpcount]);
        Serial.print ("    Xtarget["); Serial.print (mpcount); Serial.print ("] = "); Serial.println (Xtarget[mpcount]);
    
        if (mpcount >7) {
          start = false; // stop saving subchannels after 8 counts
        }
      }
     
      if (pulse >= 850 && pulse <950) { // is syncpulse
        start = true;
      }
    
      // update all servo outputs with or without changed targets, maximum step is slowstep setting
     
      for (uint8_t j=0; j<8; j++) {
        if ((Xtarget [j] - Xpulse [j]) >= slowstep) Xpulse [j] += slowstep;
        else if ((Xtarget [j] - Xpulse [j]) <= -slowstep) Xpulse [j] -= slowstep;
        else Xpulse [j] = Xtarget [j];
        pwm.setPWM(j, 0, Xpulse [j]); // LOW>HIGH at 0, HIGH>LOW at pulselen
      }
     
    }
    
    void read_pwm(){
      if (RxchWas == 0) { // if pin 2 was false previously
        timer = micros(); // start timer
        RxchWas = 1;
      }
      else if (RxchWas == 1) { // if pin 2 was already true, read timer
        inpulse = ((volatile int)micros() - timer);
        RxchWas = 0;
        sync = 1; // release loop stop
        seqnr += 1;
        if (inpulse<950) seqnr = -1; // reset seqnr for next incoming pulses to start with 0
      }
    
    }
     

Deel Deze Pagina