GALLOPING GHOST besturing

Mijn versie is iets minder elegant dan waar Max mee kwam, ik heb wat meer neiging tot 'stapelen' waar het misschien met één, gecombineerd commando zou kunnen.
Maar ik zit nooit te experimenteren, alleen om meer kennis te krijgen.
Het moet altijd een praktisch doel hebben. Dat remt wellicht de eigen ontwikkeling, maar ik heb toch al zat te doen.
Dus dan is zoiets als dit een prachtig excuus om weer eens wat te gaan proberen....:D
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
Ik wil het je met alle plezier een keer stap voor stap uitleggen, maar op dit moment vliegt de tijd me door de vingers.....
Je mag me hier echt aan houden, dus help me herinneren.... :stout: :rofl:
 
Laatst bewerkt:
Ik heb in parallel met Bruno ook een volledige versie gemaakt, met als extra de mogelijkheid om met twee instelpots de minimum en maximum positie van de servo in te stellen. Mijn probleem is dat ik op dit moment geen ATTiny of Digispark beschikbaar heb om e.e.a. te testen, dus dat heb ik aan Bruno gevraagd.

Code:
/*
A switch to propo channel conversion for ATTiny.
************************************************
This converter will take a 3-position switched channel and change it to an increase-stop-decrease channel.
2 potmeters will adjust the end points of the servo output.
The PWM from the receiver is captured with interrupts, based on Phil Green's Digispark V-tail mixer.

      ATTiny TOP VIEW:
           _____
        1-|  U  |-8
        2-|     |-7
        3-|     |-6
        4-|_____|-5

*/

#define Rxch 0     // receiver channel connected to P0 (ATTiny physical pin 5)
#define led 1      // DigiSpark internal LED on P1 (ATTiny physical pin 6)
#define potmin 2   // minimum throttle setting from potmeter on P2 (ATTiny physical pin 7)
#define potmax 3.  // maximum throttle setting from potmeter on P3 (ATTiny physical pin 2)
#define servo 4    // servo output from P4 (ATTiny physical pin 3)

volatile unsigned long timer_ch; // all timer variables are unsigned long
volatile int pulse_time = 1500;
volatile byte chWas = 0, sync = 0;
int RXpulse, Minpulse, Maxpulse, Outpulse = 1500;

void setup()
{
  pinMode(led, OUTPUT);
  pinMode(servo, OUTPUT);
  pinMode (potmin, INPUT);
  pinMode (potmax, INPUT);
  pinMode(Rxch, INPUT);
  timer_ch = 0;
  GIMSK = (1 << PCIE);   // Enable Pin Change Interrupts
  PCMSK = (1 << Rxch); // 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 = pulse_time; // do an atomic copy in the quickest way
  sei();

  if (RXpulse <= 1200) Outpulse = Outpulse - 5;
  if (RXpulse >= 1800) Outpulse = Outpulse + 5;

  Minpulse = 1000 + map(analogRead(potmin), 0, 1023, 0, 500); // Minpulse: 1000 > 1500
  Maxpulse = 2000 - map(analogRead(potmax), 0, 1023, 0, 500); // Maxpulse: 1500 > 2000

  constrain (Outpulse, Minpulse, Maxpulse);

  digitalWrite(servo, 1); delayMicroseconds(Outpulse); digitalWrite(servo, 0); // servo out
}

ISR(PCINT0_vect)
{
  if (PINB & 0b00000001) { // read the Rx pulse on P0
    if (chWas == 0) {
      timer_ch = micros();
      chWas = 1;
    }
  } else {
    if (chWas == 1) {
      pulse_time = (micros() - timer_ch);
      chWas = 0;
      sync = 1;
    }
  }
}

Max.
 
Laatst bewerkt:
Dat gaat helemaal goed komen.
gisteravond Bruno’s sketch laten lopen,
Werkt prima! Nu jouw sketch proberen, en eerst even de potmetertjes eraan solderen.
Dan is er keus! Wer die Wahl hat, hat die Qual:koud:
 
Bruno heeft mijn versie nu ook getest. Vandaar twee aanpassingen: beginnen met Outpulse = 1000, zodat de servo met gas op minimum opstart. En Constrain() lijkt niet te werken op een ATTiny, dus vervangen door twee if's.
De code aangepast:
Code:
/*
A switch to propo channel conversion for ATTiny.
************************************************
This converter will take a 3-position switched channel and change it to an increase-stop-decrease channel.
2 potmeters will adjust the end points of the servo output.
The PWM from the receiver is captured with interrupts, based on Phil Green's Digispark V-tail mixer.

      ATTiny TOP VIEW:
           _____
        1-|  U  |-8
        2-|     |-7
        3-|     |-6
        4-|_____|-5

*/

#define Rxch 0     // receiver channel connected to P0 (ATTiny physical pin 5)
#define led 1      // DigiSpark internal LED on P1 (ATTiny physical pin 6)
#define potmin 2   // minimum throttle setting from potmeter on P2 (ATTiny physical pin 7)
#define potmax 3.  // maximum throttle setting from potmeter on P3 (ATTiny physical pin 2)
#define servo 4    // servo output from P4 (ATTiny physical pin 3)

volatile unsigned long timer_ch; // all timer variables are unsigned long
volatile int pulse_time = 1000;
volatile byte chWas = 0, sync = 0;
int RXpulse, Minpulse, Maxpulse, Outpulse = 1500;

void setup()
{
  pinMode(led, OUTPUT);
  pinMode(servo, OUTPUT);
  pinMode (potmin, INPUT);
  pinMode (potmax, INPUT);
  pinMode(Rxch, INPUT);
  timer_ch = 0;
  GIMSK = (1 << PCIE);   // Enable Pin Change Interrupts
  PCMSK = (1 << Rxch); // 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 = pulse_time; // do an atomic copy in the quickest way
  sei();

  if (RXpulse <= 1200) Outpulse = Outpulse - 5;
  if (RXpulse >= 1800) Outpulse = Outpulse + 5;

  Minpulse = 1000 + map(analogRead(potmin), 0, 1023, 0, 500); // Minpulse: 1000 > 1500
  Maxpulse = 2000 - map(analogRead(potmax), 0, 1023, 0, 500); // Maxpulse: 1500 > 2000
 
  // constrain Outpulse between Minpulse and Maxpulse:
  if (Outpulse  < Minpulse) Outpulse  = Minpulse;
  if (Outpulse  > Maxpulse) Outpulse  = Maxpulse;
 
  digitalWrite(servo, 1); delayMicroseconds(Outpulse); digitalWrite(servo, 0); // servo out
}

ISR(PCINT0_vect)
{
  if (PINB & 0b00000001) { // read the Rx pulse on P0
    if (chWas == 0) {
      timer_ch = micros();
      chWas = 1;
    }
  } else {
    if (chWas == 1) {
      pulse_time = (micros() - timer_ch);
      chWas = 0;
      sync = 1;
    }
  }
}

Max.
 
Laatst bewerkt:
Ik heb nog een kleine aanpassing gedaan, zie de code m.b.t. het beperken van de Output tussen Minpulse en Maxpulse.
De vorige versie doet het prima, daar niet van, maar ik houd niet van teveel accolades in de code...:confused:

De achtergrond: bij een if met maar een enkele actie kun je die direct achter de if-functie zetten, alleen als er meerdere acties onder moeten vallen moet je die tussen accolades zetten.
Dus:
if (<voorwaarde>) <actie1>;
of:
if (<voorwaarde>) {
<actie1> ;
<actie2> ;
}

P.S. ik heb toch maar weer een paar ATTiny's besteld, leuk om een beetje mee te experimenteren.....:)
 
Laatst bewerkt:
M’n knutselwerkje is klaar, om Max’s creatie te gaan testen.
Henk krijgt nog een zware dobber aan de keuze! Hel zal wel marsepein met slagroom worden! Deze loopt op Vin, misschien beter om de potmeters op de uiteindelijke versie op 5V te solderen. Maar voor de test goef genoeg.
Ps. Vanmorgen Bruno’s versie op de modelvliegclub gedemonstreerd. (Met succes)
image.jpg
 
Deze loopt op Vin, misschien beter om de potmeters op de uiteindelijke versie op 5V te solderen.
Ik zou dat zeker veranderen. In hoeverre een hogere input spanning dan de Vcc fataal voor de chip is weet ik niet, maar in ieder geval gaat de nauwkeurigheid van de pots naar beneden. De A/D converters zijn berekend op maximaal Vcc aan de input (0V - 5V / 0 - 1023) . Maar als je de voeding van een ontvanger krijgt is er niet zoveel aan de hand (aangenomen dat je die met maximaal 5V voed), je mist dan alleen de spanningsval over de spanningsregelaar.

Ik zie dat je sommige aansluitingen met de poorten veranderd hebt. Ik ga er van uit dat je dat ook in de sketch aangepast hebt. Maar kijk uit, als de ontvanger niet op P0 aangesloten is, moet je ook de interrupt trigger aanpassen.

Succes met de test!
 
Laatst bewerkt:
als de ontvanger niet op P0 aangesloten is, moet je ook de interrupt trigger aanpassen.
Ik heb dat nu in de sketch aangepast, gaat nu automatisch mee met de pin assignment. (geen wijziging nodig zolang het ontvangerkanaal naar P0 gaat).

Scherm­afbeelding 2024-10-28 om 15.51.46.png
 
Laatst bewerkt:
Hoi Max,
Compileert de skech?
Bij mij komt een foutmelding
Collect2.exe: ID returned 5 exit status
Waarschijnlijk omdat mijn oude laptop op XP draait en ik Arduino 1.8.2 gebruik
Oh, en P0 is Rx signaal. P4 is servo. Teveel kabeltjes op de foto.:rolleyes:

Op de laptop van mijn vrouw (vensters 11) werkt het! Dus winXP en arduino versie probleempje.

En ik zie nu ook dat ik de tel kwijt benngeraakt aan de IO zijde….
Alles nu op z’n plaats, ook de 5 V voor de trimmers. Gewoon wat veel aan het hoofd….

En alles werkt, en niemand weet waarom! (Houden zo!). Mooi gemaakt Bruno en Max.
 
Laatst bewerkt:
En alles werkt,
Maar werkt het ook zoals je je het voorstelde? Bruno vond de servo bij mijn versie nogal langzaam bewegen.........Maar dat is simpel aan te passen, gewoon de stapgrootte van +/- 5 microseconden wat groter maken (al wordt het herprogrammeren nogal lastig nadat alles er al aangesoldeerd is...)
 
Bij mij stond 'ie uiteindelijk op 12....:D
Toch leuk hoe we er hier zo met elkaar een compleet clubproject van maken. :yes:

Ik heb daarom mijn AtTiny projectjes vrijwel altijd met een (kwaliteits!) IC voetje uitgerust,
 
Bruno’s versie is inderdaad rapper, maat dat is simpel aan te passen. Met de 10K trimmertjes in de middenstand, laat de Digispark zich nog flashen. Leuk avontuur!
 
Wat in mijn hoofd blijft rondspoken is dat we voor al deze oplossingen wel afhankelijk zijn van een 2,4 systeem dat een fail safe moet hebben.
Want zodra de uitgangspulsen van de ontvanger er mee op zouden houden, vallen ook de decoders stil.
In het gunstigste geval vliegt het model dan rechtdoor met de laatste ontvangen motorinstelling.
Ik zal toch eens kijken of daar iets op te verzinnen valt...
 
Bestaat er zoiets als een time out voor de interrupt?
Maar dan zou de hele sketch op z’n kop komen. Nu takt je de uitgang op de ingang.
Dan zou je altijd in een loop uit moeten sturen pulsbreedte 1, 20000- pulsbreedte 0
Blijft leuk!
 
Back
Top