Programmfehler, find ihn aber nicht

Hallo zusammen,

ich habe einen Arduino Due mit einem Rotary Encoder (siehe: http://www.exp-tech.de/Zubehoer/Sparkfun-Rotary-Encoders---Illuminated.html )
und einem 16fach LED Anzeigefeld (siehe: http://www.exp-tech.de/Shields/Rotary-Encoder-LED-Ring-Breakout-Board---Blue-332.html )

Aber irgendwie will das Sketch nicht richtig laufen. Ich sitz jetzt schon den dritten abend dran. Nehm alle Zeilen auseinander, und finde den fehler nicht.

Kann mir jemand sagen, warum ich noch nicht mal was im seriellen Monitor sehe?
ich bekomm noch nicht mal die Erfolgsmeldung, dass das Setup durchgelaufen ist.

Danke für jede Hilfe. Verbesserungen im Quellcode sind ebenso gerne willkommen.

Gruß

Til

//These are the pins that will talk to the shift register through SPI
#define SDI    20    //Data
#define CLK    21    //Clock
#define LE     22    //Latch

//These are the rotary encoder pins A, B, and switch
#define ENC0_A    2 
#define ENC0_B    3
#define ENC0_SW   30

//These are the pins for the encoder light
#define ENC0_Red   32 
#define ENC0_Green 33

// Global variables
int scaledCounter = 0;  //The LED output is based on a scaled veryson of the rotary encoder counter
int sequenceNumber = 0;   //The output sequence for the LEDs

int lastEncoded = 0; //

int ENC0_Pos = 0;   // 0 to 100
int ENC0_Col = 0;   // 0 = off, 1 = green, 2 red

int lastMSB = 0;
int lastLSB = 0;

/*This is a 2 dimensional array with 3 LED sequences.  The outer array is the sequence; 
 the inner arrays are the values to output at each step of each sequence.  The output values
 are 16 bit hex values (hex math is actually easier here!).  An LED will be on if its 
 corresponding binary bit is a one, for example: 0x7 = 0000000000000111 and the first 3 LEDs 
 will be on.
 
 The data type must be 'unsigned int' if the sequence uses the bottom LED since it's value is 0x8000 (out of range for signed int).
 */
unsigned int sequence[3][16] = {
  {0x0,0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x100,0x200,0x400,0x800,0x1000,0x2000,0x4000},
  {0x0,0x1,0x3,0x7,0xf,0x1f,0x3f,0x7f,0xff,0x1ff,0x3ff,0x7ff,0xfff,0x1fff,0x3fff,0x7fff},
  {0x0,0x7fff,0x3ffe,0x1ffc,0xff8,0x7f0,0x3e0,0x1c0,0x80,0x1c0,0x3e0,0x7f0,0xff8,0x1ffC,0x3ffe,0x7fff}
  };

void setup() {
  //Set SPI pins to output
  pinMode(SDI, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(LE,OUTPUT);
  //Set encoder pins to input, turn internal pull-ups on
  pinMode(ENC0_A, INPUT);
  digitalWrite(ENC0_A, HIGH);
  attachInterrupt(ENC0_A, updateEncoder, CHANGE); 
  pinMode(ENC0_B, INPUT);
  digitalWrite(ENC0_B, HIGH);
  attachInterrupt(ENC0_B, updateEncoder, CHANGE);
  pinMode(ENC0_SW, INPUT);
  digitalWrite(ENC0_SW, HIGH);
  //Set encoder color pins
  pinMode(ENC0_Red, OUTPUT);
  pinMode(ENC0_Green, OUTPUT);  
  //Set serial rate for debug
  Serial.begin(9600);
  Serial.println("Setup finished");
}

void loop() { 
  digitalWrite(ENC0_Red, LOW);
  digitalWrite(ENC0_Green, HIGH);
 
  //if the encoder has moved
  if(ENC0_Pos) {
    //Set the new counter value of the encoder      
    scaledCounter = map(ENC0_Pos,0,100,0,15);
    //Send the LED output to the shift register 
    digitalWrite(LE,LOW);
    shiftOut(SDI,CLK,MSBFIRST,(sequence[sequenceNumber][scaledCounter] >> 8));    //High byte first
    shiftOut(SDI,CLK,MSBFIRST,sequence[sequenceNumber][scaledCounter]);           //Low byte second
    digitalWrite(LE,HIGH);
  }

  //If the encoder switch is pushed, this will turn on the bottom LED.  The bottom LED is turned
  //on by 'OR-ing' the current display with 0x8000 (1000000000000000 in binary)
  if (!digitalRead(ENC0_SW)) {
    if (sequenceNumber == 3) {
      sequenceNumber = 0;
    } else {
      sequenceNumber++;
    }
    digitalWrite(LE,LOW);  
    shiftOut(SDI,CLK,MSBFIRST,((sequence[sequenceNumber][scaledCounter]|0x8000) >> 8));
    shiftOut(SDI,CLK,MSBFIRST,sequence[sequenceNumber][scaledCounter]);              
    digitalWrite(LE,HIGH);   
  }
}

void updateEncoder() {
  int MSB = digitalRead(ENC0_A); //MSB = most significant bit
  int LSB = digitalRead(ENC0_B); //LSB = least significant bit

  int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
  int sum  = (lastEncoded << 2) | encoded; //adding it to the previous encoded value

  if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) ENC0_Pos++;
  if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) ENC0_Pos--;

  if (ENC0_Pos < 0) {
    ENC0_Pos = 0;
    //set green LED on
    digitalWrite(ENC0_Red, LOW);
    digitalWrite(ENC0_Green, HIGH); 
  }
  if (ENC0_Pos > 100) {
    ENC0_Pos = 100;
    //set red LED on
    digitalWrite(ENC0_Red, HIGH);
    digitalWrite(ENC0_Green, LOW);
  }
  lastEncoded = encoded; //store this value for next time
  Serial.print("Counter value: ");
  Serial.println(ENC0_Pos, DEC); 
}

Update: Rechtschreibfehler verbessert. g

Ohne jetzt dein Programm im Detail angeschaut zu haben: Ich gehe bei solchen Fehlern immer so an die Sache ran:

void setup() {
  //Set serial rate for debug
  Serial.begin(9600);
  Serial.println("Setup started");
  //Set SPI pins to output
  pinMode(SDI, OUTPUT);
  Serial.println("1");
  pinMode(CLK, OUTPUT);
  Serial.println("2");
  pinMode(LE,OUTPUT);
  Serial.println("3");
  //Set encoder pins to input, turn internal pull-ups on
  pinMode(ENC0_A, INPUT);
  Serial.println("4");
  digitalWrite(ENC0_A, HIGH);
  Serial.println("5");
  attachInterrupt(ENC0_A, updateEncoder, CHANGE); 
  Serial.println("6");
  pinMode(ENC0_B, INPUT);
  Serial.println("7");
  digitalWrite(ENC0_B, HIGH);
  Serial.println("8");
  attachInterrupt(ENC0_B, updateEncoder, CHANGE);
  Serial.println("9");
  pinMode(ENC0_SW, INPUT);
  Serial.println("10");
  digitalWrite(ENC0_SW, HIGH);
  Serial.println("11");
  //Set encoder color pins
  pinMode(ENC0_Red, OUTPUT);
  Serial.println("12");
  pinMode(ENC0_Green, OUTPUT);  
  Serial.println("Setup finished");
}

Poste mal dein Debug.

Zerstücke Deinen Sketch in kleine Teile und schau ob diese funktionieren. Ich kann Dir keine Hilfe bieten, da ich mich in den Arduino Due noch nicht eingearbeitet habe. Grüße Uwe

Hi,

habe ich gemacht.

Lustigerweise rennt es so.

1
2
3
4
5
Counter value: 25
6
7
8
Counter value: 25
9
10
11
12
13
Setup finished

ich hab es nochmals ohne die "DEBUG" Ausgaben getestet. Funktioniert nicht. Woran kann dass denn liegen? Und nochwas ist mir aufgefallen, wenn ich den Encoder auf bestimmten Stellen stehen lassen. Wird dennoch die Funktion "updateEncoder" durchgeführt, allerdings (logischerweise) ohne den Wert zu verändern. Ist der Encoder mist?

Gruß

Til

Wenn ich die Ausgabe sehe, dann ist es mir klar was den Fehler verursacht. Die Interrupt Routine (ISR) versucht Serial.print bevor der Serial im Setup Initialisiert wurde. Er muss also vor dem Attach Interrupt kommen!!

Was auch noch wichtig ist, dass die ISR nie ein Serial.print des laufenden Programms unterbricht und eigene Ausgaben per Serial.print macht!

In der Interruptroutine darf kein serial.Print stehen, da dies die Interruptroutine sehr verlangsamt. Wir sprechen hier von ca 26mS für die Ausgabe der seriellen Schnittstelle.

Ich verstehe auch nicht die komplizierte Interruptprogrammierung zum Auslesen des Encoders. Mußt Du wirklich auf beide Flanken beider Phasen des Encoders triggern? Genügt nicht die Hälfte der Auflösung und nur auf die ansteidenden Flanken der beiden Phasen zu triggern.

Grüße Uwe