Hallo zusammen,
in meiner letzten Frage (Drucker Optical Encoder auslesen) habe ich versucht mittels Interrupts das Signal von einem Drucker Encoder auszulesen. Das funktioniert auf den Pins 8 und 9 auch wunderbar mit diesem Code und liefert realistische Ergebnisse:
#include <avr/interrupt.h> // AVR interrupt handling
#include <Arduino.h> // Arduino core library
#include <stdint.h> // Standard integer types
#include <stdbool.h> // Standard boolean types
#define ENC_PIN_A 8
#define ENC_PIN_B 9
volatile uint8_t OldState = 0; // Store the previous state of the encoder pins
volatile int32_t Position = 0; // Store the current position value
volatile bool InvalidInc = false; // Flag indicating an invalid increment
const int8_t IncArray[4][4] = {
{0, -1, 1, 2}, // Lookup table for valid increments based on state transitions
{1, 0, 2, -1},
{-1, 2, 0, 1},
{2, 1, -1, 0}
};
void setup() {
Serial.begin(9600); // Initialize serial communication
pinMode(ENC_PIN_A, INPUT); // Configure digital pin 8 as input
pinMode(ENC_PIN_B, INPUT); // Configure digital pin 9 as input
cli(); // Disable interrupts
PCICR |= (1 << PCIE0); // Enable Pin Change Interrupt for PORT B (PCIE0)
PCMSK0 |= (1 << PCINT0) | (1 << PCINT1); // Enable interrupt for PCINT0 (D8) and PCINT1 (D9)
sei(); // Enable interrupts
}
void loop() {
delay(100); // Delay for readability
Serial.println(Position, DEC); // Print the current position in decimal
if (InvalidInc) {
Serial.println("LOST COUNT"); // Print a message indicating a lost count
InvalidInc = false; // Reset the invalid increment flag
}
}
ISR(PCINT0_vect) {
uint8_t State = PINB & 0b00000011; // Read the state of the encoder pins
int8_t Inc = IncArray[OldState][State]; // Get the increment value from the lookup table
OldState = State; // Update the previous state
Position += Inc; // Update the position value
// Set the InvalidInc flag if the increment is 2
InvalidInc |= (Inc == 2);
}
Nun möchte ich allerdings ein CNC Shield zur Ansteuerung eines Stepper Motors verwenden. Dadurch sind die Pins 8 und 9 aber nicht mehr frei. Aus einem Pinout des Shields (siehe: https://courses.ideate.cmu.edu/16-376/s2020/ref/text/hardware/cnc-shield.html#arduino-pin-assignments) habe ich gelesen, dass ich die Pins 12 und 13 nutzen könnte, da ich deren Shield Funktion nicht benötige. Also habe ich den Code folgendermaßen angepasst und vorerst ohne das Shield getestet:
#include <avr/interrupt.h> // AVR interrupt handling
#include <Arduino.h> // Arduino core library
#include <stdint.h> // Standard integer types
#include <stdbool.h> // Standard boolean types
#define ENC_PIN_A 12
#define ENC_PIN_B 13
volatile uint8_t OldState = 0; // Store the previous state of the encoder pins
volatile int32_t Position = 0; // Store the current position value
volatile bool InvalidInc = false; // Flag indicating an invalid increment
const int8_t IncArray[4][4] = {
{0, -1, 1, 2}, // Lookup table for valid increments based on state transitions
{1, 0, 2, -1},
{-1, 2, 0, 1},
{2, 1, -1, 0}
};
void setup() {
Serial.begin(9600); // Initialize serial communication
pinMode(ENC_PIN_A, INPUT); // Configure digital pin 8 as input
pinMode(ENC_PIN_B, INPUT); // Configure digital pin 9 as input
cli(); // Disable interrupts
PCICR |= (1 << PCIE0); // Enable Pin Change Interrupt for PORT B (PCIE0)
PCMSK0 |= (1 << PCINT4) | (1 << PCINT5); // Enable interrupt for PCINT4 (D12) and PCINT5 (D13)
sei(); // Enable interrupts
}
void loop() {
delay(100); // Delay for readability
Serial.println(Position, DEC); // Print the current position in decimal
if (InvalidInc) {
Serial.println("LOST COUNT"); // Print a message indicating a lost count
InvalidInc = false; // Reset the invalid increment flag
}
}
ISR(PCINT0_vect) {
uint8_t State = PINB & 0b00110000; // Read the state of the encoder pins
int8_t Inc = IncArray[OldState][State]; // Get the increment value from the lookup table
OldState = State; // Update the previous state
Position += Inc; // Update the position value
// Set the InvalidInc flag if the increment is 2
InvalidInc |= (Inc == 2);
}
Jetzt lese ich allerdings Werte aus dem Encoder aus, die um ein Vielfaches höher sind, als noch mit Pin 8 und 9. Gleiches passiert übrigens auch mit anderen Pin Konfigurationen. Es kann doch nicht sein, dass nur Pin 8 und 9 für meinen Zweck gültig sind.
Ich hoffe, dass mir jemand weiterhelfen kann.
Viele Grüße
Nico