Enkodér
Re: Enkodér
Nebo si napsat jednoduchý ovladač s použitím interruptu. Ten by měl být tak rychlý, že by mu nevadil ani malý fázový posun průběhů.
Re: Enkodér
onDraN má pravdu. Použít program bez přerušení je nesmysl.
Re: Enkodér
Myslíte to čo má arduino iba na pinoch 2,3?
Re: Enkodér
Přesně tak, pokud je to UNO nebo jiné s CPU ATMEGA 328P
Re: Enkodér
Lepe receno - Arduino to zminuje jen pro ty dva piny, ale atmega386 umi interrupty pro podstatne vic pinu (skoro vsechny), jen se to dela trosku sloziteji, viz napriklad
https://sites.google.com/site/qeewiki/b ... -atmega328
https://sites.google.com/site/qeewiki/b ... -atmega328
Re: Enkodér
Tak som si našiel tento kód
Využíva ten interupt. zistil som že ked enkoderom hýbem pomali tak to funguje. No ked skúsim trocha rýchlejšie už to blbne.Potreboval by som rýchlosť len 100rpm čo nieje tak vela ale blbne to už ovela skôr.
Kód: Vybrat vše
// Used for generating interrupts using CLK signal
const int pinA = 2;
// Used for reading DT signal
const int pinB = 3;
// Keep track of last rotary value
int lastCount = 50;
// Updated by the ISR (Interrupt Service Routine)
volatile int virtualPosition = 50;
// Updated by ISR for each pin
volatile bool pinAStateHigh;
volatile bool pinBStateHigh;
// Old values of pin state so we can compare
bool oldPinAStateHigh;
bool oldPinBStateHigh;
// Delay to counteract switch bounce (milliseconds)
char bounce = 10;
// ------------------------------------------------------------------
// INTERRUPT INTERRUPT INTERRUPT INTERRUPT INTERRUPT
// ------------------------------------------------------------------
void isrA () {
static unsigned long lastInterruptTimeA = 0;
unsigned long interruptTimeA = millis();
// If interrupts come faster than Xms, assume it's a bounce and ignore
if (interruptTimeA - lastInterruptTimeA > bounce) {
// We are here because pinA has CHANGED
pinAStateHigh = !pinAStateHigh;
//pinAStateHigh = digitalRead(pinA) == HIGH;
// Don't do this for real!
//Serial.print("\nPin A state="); Serial.print(pinAStateHigh ? "HIGH" : "LOW");
//Serial.print(" (Pin B state="); Serial.print(pinBStateHigh ? "HIGH)" : "LOW)");
}
// Keep track of when we were here last
lastInterruptTimeA = interruptTimeA;
}
void isrB () {
static unsigned long lastInterruptTimeB = 0;
unsigned long interruptTimeB = millis();
// If interrupts come faster than Xms, assume it's a bounce and ignore
if (interruptTimeB - lastInterruptTimeB > bounce) {
// We are here because pinB has CHANGED
pinBStateHigh = !pinBStateHigh;
//pinBStateHigh = digitalRead(pinB) == HIGH;
// Don't do this for real!
//Serial.print("\nPin B state="); Serial.print(pinBStateHigh ? "HIGH" : "LOW");
//Serial.print(" (Pin A state="); Serial.print(pinAStateHigh ? "HIGH)" : "LOW)");
}
// Keep track of when we were here last
lastInterruptTimeB = interruptTimeB;
}
// ------------------------------------------------------------------
// SETUP SETUP SETUP SETUP SETUP SETUP SETUP
// ------------------------------------------------------------------
void setup() {
// Just whilst we debug, view output on serial monitor
Serial.begin(9600);
// Rotary pulses are INPUTs
pinMode(pinA, INPUT);
pinMode(pinB, INPUT);
// Set initial state of PinA & PinB by reading the pins
pinAStateHigh = digitalRead(pinA) == HIGH;
pinBStateHigh = digitalRead(pinB) == HIGH;
Serial.print("Initial state Pin A = "); Serial.println(pinAStateHigh ? "HIGH" : "LOW");
Serial.print("Initial state Pin B = "); Serial.println(pinBStateHigh ? "HIGH" : "LOW");
// So we remember what the state was (can detect the change)
oldPinAStateHigh = pinAStateHigh;
oldPinBStateHigh = pinBStateHigh;
// Attach the routine to service the interrupts
attachInterrupt(digitalPinToInterrupt(pinA), isrA, CHANGE);
attachInterrupt(digitalPinToInterrupt(pinB), isrB, CHANGE);
// Ready to go!
Serial.println("Start");
}
// ------------------------------------------------------------------
// MAIN LOOP MAIN LOOP MAIN LOOP MAIN LOOP MAIN LOOP
// ------------------------------------------------------------------
void loop() {
// Pin A changed? What direction?
if (pinAStateHigh != oldPinAStateHigh) {
// Pin A is HIGH
if (pinAStateHigh) {
// Pin B is LOW
if (!pinBStateHigh) {
// Clockwise
virtualPosition++;
}
else {
// Anticlockwise
virtualPosition--;
}
} else {
// Pin A just went low and B is HIGH
if (pinBStateHigh) {
// Clockwise
virtualPosition++;
}
else {
// Anticlockwise
virtualPosition--;
}
}
// Keep track of state of Pin A
oldPinAStateHigh = pinAStateHigh;
}
// Pin B changed? What direction?
if (pinBStateHigh != oldPinBStateHigh) {
if (pinBStateHigh) {
if (pinAStateHigh) {
virtualPosition++;
}
else {
virtualPosition--;
}
} else {
// Pin B just went low
if (!pinAStateHigh) {
virtualPosition++;
}
else {
virtualPosition--;
}
}
oldPinBStateHigh = pinBStateHigh;
}
// If the current rotary switch position has changed then update everything
if (virtualPosition != lastCount) {
// Write out to serial monitor the value and direction
Serial.print(virtualPosition > lastCount ? " Up:" : " Down:");
Serial.println(virtualPosition);
// Keep track of this new value
lastCount = virtualPosition ;
}
}
Re: Enkodér
V SETUP máš Serial.begin(9600);
Zkusil bych zvýšit rychlost vypisování na Serial.begin(115200);
Zkusil bych zvýšit rychlost vypisování na Serial.begin(115200);
Re: Enkodér
Skúsim ale nemyslim si že to pomôže. Ono niekedy to zmeni smer niekedy to par krat zasebou posle to iste cislo. Keby nestihala komunikacia asi by vynechavalo riadky. Ale skusim zato nic nedam.
Re: Enkodér
Všimnul jsem si, že máš ty oscilogramy docela "chlupaté". Zkoušel jsi tam zařadit RC filtr?
- pavel1tu
- Příspěvky: 2054
- Registrován: 26 říj 2017, 08:28
- Reputation: 0
- Bydliště: Trutnov
- Kontaktovat uživatele:
Re: Enkodér
Nejde o komunikaci - aby stíhala,
ale dokud to odesílá něco na port, zbytek stojí - jako kdyby jsi použil delay().
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"
Pavel1TU
"Správně napsaný kod lze číst jako knihu"
Kdo je online
Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 2 hosti