Rotary encorders till B737 panel

Hej

Jag använder det färdiga exemplet från Arduino playground:

Notera att namn är bytta och det handlar om flera encorders. Men om jag vet koden första så vet jag koden för de andra också!

Syftet med mina encorders är att det ska fungera som diverse rotary knappar i en B737 cockpit. T.ex. Brake rotary knappen kan ställas i 6 lägen m.m.

Mina encorders har 24 steg där jag vill att det steget som jag nu har inställt på ska visas på serial monitor t.ex. 12 om jag har vridit fram till den medsols och -12 om jag vridit till den motsols. Går det att få till?

Fråga så lägger jag upp en bild iså fall!

"int val;
int VC24A = 23;
int VC24B = 22;
int VC24ABPos = 0;
int VC24ABPinALast = LOW;
int n = LOW;

void setup() {
pinMode (VC24A,INPUT_PULLUP);
pinMode (VC24B,INPUT_PULLUP);
Serial.begin (9600);
}

void loop() {
n = digitalRead(VC24A);
if ((VC24ABPinALast == LOW) && (n == HIGH)) {
if (digitalRead(VC24B) == LOW) {
VC24ABPos--;
} else {
VC24ABPos++;
}
Serial.print (VC24ABPos);
Serial.print ("/");
}
VC24ABPinALast = n;
}"

Frågor på koden:
1.)
Kort och gott, är dessa rader för att man ska ha något att utgå från, för att kortet ska veta vad som händer om man inte vrider på Encordern och hur lägena för encordern är före

och efter de olika pos?

Svårt att förklara men jag förstår till 25% varför dessa finns!
int val;
int VC24ABPos = 0;
int VC24ABPinALast = LOW;
int n = LOW;

2.)
Dessa förstår jag till 40%!

Det har med att encordern vill vet när jag vrider och dess läge den hamnade på, sedan ska det fungera åt båda håll!

n = digitalRead(VC24A);
if ((VC24ABPinALast == LOW) && (n == HIGH)) {
if (digitalRead(VC24B) == LOW) {
VC24ABPos--;
} else {
VC24ABPos++;


Mvh Fredrik

freddehboy:
Mina encorders har 24 steg där jag vill att det steget som jag nu har inställt på ska visas på serial monitor t.ex. 12 om jag har vridit fram till den medsols och -12 om jag vridit till den motsols. Går det att få till?

En encoder håller inte ordning på något speciellt steg utan genererar pulser när den vrids åt ena eller andra hållet. Den går att vrida hur många varv som helst utan att gå tillbaka till ursprungsläget.
Du kommer garanterat att missa någon puls ibland och vid andra tillfällen kommer du att få studsar som genererar dubbla pulser trots att du bara vridit den ett steg.
Självklart kommer du att kunna stega ett värde från -12 till 12 i takt med att du rattar på decodern men du kommer inte att kunna ha någon indikator på ratten som pekar på fasta värden, till sånt behöver du andra reglage.
Det låter ändå på din beskrivning som att en encoder kommer att göra jobbet.

1.)
Kort och gott, är dessa rader för att man ska ha något att utgå från, för att kortet ska veta vad som händer om man inte vrider på Encordern och hur lägena för encordern är före och efter de olika pos?

Ja, dessa finns för att det ska finnas någon historik att jämföra med för att avgöra åt vilket håll encodern vridits.

2.)
Dessa förstår jag till 40%!

Det har med att encordern vill vet när jag vrider och dess läge den hamnade på, sedan ska det fungera åt båda håll!

Hur var frågan?

Jag hade använt en annan typ av kod än den du hittat. Encoders styrs lämpligast med interrupt.
Förenklad teori som du förstår om du läst hur en rotary enkoder fungerar:

Man kopplar den ena pulspinnen på encodern till en interruptpinne på Arduino.
Den andra pulspinnen kopplar man till en annan pinne på Arduino. Behöver inte vara en interruptpinne.

Man sätter upp ett interrupt som ska triggas varje gång interruptpinnen förändras (går från låg till hög eller från hög till låg signal). Signalen på interruptpinnen kommer ju att förändras varje gång du vrider ett steg oavsett riktning.

När interruptet triggats jämför man signalen på interruptpinnen med signalen på den andra pinnen.
Om de är lika har du vridit åt ena hållet, räkna upp eller ner
Om de är olika har du vridit åt andra hållet, räkna åt andra hållet

Exempel:

const int cwPin = 2;
const int ccwPin = 3;

void setup() {
  Serial.begin(9600);
  
  pinMode(cwPin, INPUT);  
  pinMode(ccwPin, INPUT);
  digitalWrite(cwPin, HIGH);
  digitalWrite(ccwPin, HIGH);
  
  attachInterrupt(0, cw, CHANGE);
}


void loop() {
}


void cw(){
  int cwLevel = digitalRead(cwPin);
  int ccwLevel = digitalRead(ccwPin);
  if (cwLevel != ccwLevel){
      Serial.println("clockwise");
      Serial.println("");
  }
  else{
      Serial.println("counterclockwise");
      Serial.println("");
  }
}

i exemplet har jag kopplat ena pinnen till pinne D2 på Arduino som är pinnen för Interrupt 0. Vill du använda ett annat interrupt än 0 får du kolla vilken pinne som går dit.
Istället för att köra Serial.println("counterclockwise") så kan du ju stega en variabel ett steg uppåt eller nedåt och sen printa innehållet i variabeln till Serial.
Som du ser har jag ingen kod i loop() i exemplet så du kan använda all CPU-tid till annat än att polla läget på decodern. T.ex. till att uppdatera dina displayer och att läsa av läget på alla dina vippbrytare.

Hej

Misstänkte att encordern inte gör det för har inget 0 läge :slight_smile:

Det jag vill med mina encordrar är att t.ex. när jag stället den kanske snett åt höger "/" med en markering som pekar snett åt höger. Arduino kortet regar det som 1 (1 för att jag bara vridit lite på varv ett) Datorn ser att det skrivs ut 1 och gämnför det med possitionern för den funktionen som jag ska styra med encordern. Sedan vill jag att den ska få samma värde om jag vrider encordern lite åt höger och sedan tillbaka!

Hänger du med?

Om dessa incramentella rotary encorder är att likställas med rotary potentiometer fast pottarna går inte ett helt varv så är det fel typ av encorders jag har köpt!?

C# applikationer som länkar mina komponenter till flygsimulatorn fungerar som nedan:
1.) App. läser av korten vad kortet skrivet ut t.ex. "hejdu" :slight_smile:
2.) App. matchar sedan "hejdu" med ett offsett nummer för den valda funktionen i flygsimulatorn

Så positionen av encorderns läge och att den läser ut samma sak hela tiden i just det valda läget är avgörande för att det ska fungera!

Mvh Fredrik

freddehboy:
Det jag vill med mina encordrar är att t.ex. när jag stället den kanske snett åt höger "/" med en markering som pekar snett åt höger. Arduino kortet regar det som 1 (1 för att jag bara vridit lite på varv ett) Datorn ser att det skrivs ut 1 och gämnför det med possitionern för den funktionen som jag ska styra med encordern. Sedan vill jag att den ska få samma värde om jag vrider encordern lite åt höger och sedan tillbaka!

Du KAN få den att bete sig så men det kommer inte att fungera särskilt bra i praktiken.
Rotary encoders är kända för att generera mycket kontaktstudsar och OM du får en dubbelpuls när du vrider encodern ett steg så kommer kortet att tycka att du vridit två steg. Då stämmer inte positionen på encoder med vad programmet tycker.

Om dessa incramentella rotary encorder är att likställas med rotary potentiometer fast pottarna går inte ett helt varv så är det fel typ av encorders jag har köpt!?

En rotary encoder och en potentiometer kan inte alls likställas. Den enda likheter är att de har en axel man kan vrida på.
Funktionen är 100% annorlunda.

Så positionen av encorderns läge och att den läser ut samma sak hela tiden i just det valda läget är avgörande för att det ska fungera!

Då är det inte en rotary encoder du ska ha.

En potentiometer kanske skulle kunna göra det du är ute efter men jag vet inte hur bra precisionen skulle bli.
En rotary switch är nog egentligen det du är ute efter men 24 positioner låter i värsta laget men det kanske finns. Jag har inga erfarenheter av sådana.

Hej

Jag ska nog leta efter rotary switch, visste inte att sådana finns men det finns funktioner där en rotary encorder passar t.ex. där man vrider på saker typ en mätare där man vill ta fram siffror, lik en volym ratt!

Har du något bra tips på rotary switch?

Mvh Fredrik

En rotary switch är nog egentligen det du är ute efter men 24 positioner låter i värsta laget men det kanske finns. Jag har inga erfarenheter av sådana.

Svar nej.

Hej

Jag har hittat rotary switch till ett bra pris på Ebay :slight_smile:

Dessa kommer att fungera som jag har tänkt och koden är som vilken switch som helst, istället för att vippa så vrider man på dessa!

Tack för hjälpen med det :slight_smile:

Mvh Fredrik

Hej

Jag behöver två rotary encorder och jag provar decodrarna med din kod inkl interrupt och ändrar lite i koden till mina namn m.m.:

const int MALW51A = 2; // Ext. Interrupts (int.0)
const int MALW51B = 3;

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

pinMode(MALW51A, INPUT_PULLUP);  // Ext. Interrupts (int.0)
attachInterrupt(0, LALT, CHANGE);
pinMode(MALW51B, INPUT_PULLUP);
}


void loop() {
}

void LALT()
{
  int MALW51Ap = digitalRead(MALW51A);
  int MALW51Bm = digitalRead(MALW51B);
    if (MALW51Ap != MALW51Bm)
    {
      Serial.println("clockwise");
    }
    else
    {
      Serial.println("counterclockwise");
    }
 }

1.)
Det skrivs bara ut när jag vrider på den och det är inget problem, bara bra om det inte skrivs ut för mycker :slight_smile:

2.)
Det skrivs alltid ut "counterclockwise" oavsett vilket håll jag vrider?

3.)
Den stoppar att läsa av komponentern efter några sekunders vridning

Din kod kanske inte är komplett men oavsett det så har jag inte lött utan jag har tryckt fast så gott det går sådana:
Female - Male Jumper Cables for Arduino på de små benen, är nog det som är orsaken då det är svårt att få fast dem helt :frowning:

Det här med dubbelstuds med pulserna gör inget då, ecordrarnas funktion ska vara att likan en ratt där jag antingen vrider upp ett värde eller ner det!

Men kanske är det ändå en annan typ av komponent jag behöver?

Jag har ju rotary potentiometer men de kan man bara vrida ca 140 grader och sedan tillbaka. Denna funktion kräver att jag kan vrida den i flera varv utan stopp!

Därför har utgått från encorders!
Mvh Fredrik

Det är en rotary encoder du ska ha till det du beskriver nu (flera varv utan fasta lägen).
Det låter som du saknar kontakt med benet som går till D3 eller så har du kopplat in encodern fel på något vis. Koden borde fungera.
Din encoder har väl tre ben antar jag och två av dem ska du med din kod koppla in till pinne 2 och 3, den tredje pinnen ska till GND (om du använder internal pull-up). Det är viktigt att rätt ben går till GND. Vanligtvis är det det mellersta benet som ska till GND men det kanske finns andra varianter.
Har du ett datablad till din encoder?

Studs vill du inte ha. Det kommer inte troligen inte ens att gå att använda encodern om du inte debounce på den eftersom du kommer att få slumpmässig studs från båda encoderpinnarna så att koden t.ex. registrerar ett klick motsols och två klick medsols varje gång du vrider ett steg. Det kan bli så att när du vrider medsols registreras bara motsols eller tvärtom.
Debounce behöver du ha.
Se här för exempel på debounce circuit som fungerar klockrent för mig:

perhof:
Det är en rotary encoder du ska ha till det du beskriver nu (flera varv utan fasta lägen).
Det låter som du saknar kontakt med benet som går till D3 eller så har du kopplat in encodern fel på något vis. Koden borde fungera.
Din encoder har väl tre ben antar jag och två av dem ska du med din kod koppla in till pinne 2 och 3, den tredje pinnen ska till GND (om du använder internal pull-up). Det är viktigt att rätt ben går till GND. Vanligtvis är det det mellersta benet som ska till GND men det kanske finns andra varianter.
Har du ett datablad till din encoder?

Hej

Det är kopplat rätt men den stannar, slutar läsa av efter ca halva varvet. Misstänker klapp i min koppling :frowning:
Databladet: Error

Har du lött din?

perhof:
Studs vill du inte ha. Det kommer inte troligen inte ens att gå att använda encodern om du inte debounce på den eftersom du kommer att få slumpmässig studs från båda encoderpinnarna så att koden t.ex. registrerar ett klick motsols och två klick medsols varje gång du vrider ett steg. Det kan bli så att när du vrider medsols registreras bara motsols eller tvärtom.
Debounce behöver du ha.
Se här för exempel på debounce circuit som fungerar klockrent för mig:
Using Rotary Encoders with Arduino – perhof

Ska prova din sketch men det är märkligt att den stanna, om det inte är glappet vilket jag tror!

Den studsar också vilket din beskrivning förklarar vilket inte kan förekomma men ett fel i taget:)

Jag kommer köra med en mom/off/mom switch om den måste lödas för att fungera korrekt!

Mvh Fredrik

freddehboy:
Det är kopplat rätt men den stannar, slutar läsa av efter ca halva varvet. Misstänker klapp i min koppling :frowning:
Databladet: Error

Det verkar vara ganska typisk benkonfiguration på din encoder. Koppla A till D2, B till annan pinne (behöver inte vara interrupt på den), C i mitten ska till GND.

Jag tror problemet du ser när den hänger sig beror på att du kör serial print inifrån interruptrutinen. Man ska egentligen inte göra så som jag gör i exemplet.
Det fungerar nog bara om Serial.print är klar när nästa interrupt inträffar. Dvs om man vrider sakta på encodern. Har du studsar från encodern kommer den garanterat inte vara klar när studsen kommer och då blir det nog problem.
Ett bättre sätt att göra det är att bara öka eller minska en variabel från LALT() och sedan utvärdera variabeln i lugn och ro från loop()

Exempel (ej testat):

const int MALW51A = 2; // Ext. Interrupts (int.0)
const int MALW51B = 3;
int myInterrupts = 0;

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

pinMode(MALW51A, INPUT_PULLUP);  // Ext. Interrupts (int.0)
attachInterrupt(0, LALT, CHANGE);
pinMode(MALW51B, INPUT_PULLUP);
}


void loop() {
  Serial.println(myInterrupts);
  delay(200);
}

void LALT()
{
  int MALW51Ap = digitalRead(MALW51A);
  int MALW51Bm = digitalRead(MALW51B);
    if (MALW51Ap != MALW51Bm)
    {
      myInterrupts++;
    }
    else
    {
      myInterrupts--;
    }
}

Har du lött din?

Ja och nej, jag har en encoder som jag använder till protoyper på breadboard.
Där har jag lött på anslutningstrådar på benen men i andra änden är de ju bara nedstoppade i en breadboard eller i kontakterna på en Arduino.

Nu fungerar det :slight_smile:

Det var något sådant jag också hade försökt med :slight_smile: Nu är det bara att värdena skall representeras av namn så mina vridningar kan fungera med min applikation och flygsimulatorn!

Mvh Fredrik