Also ich zerlege mein Gewusel mal:
Diese Routine wird einwandfrei kompiliert, ob sie funktioniert weiß ich mangels Testumgebung noch nicht.
Code:// by rafbuff on: http://playground.arduino.cc/Main/RotaryEncoders#Debounce //including debouncer: 100nF from A&B to gnd and 10k each to signal pin // usually the rotary encoders three pins have the ground pin in the middle enum PinAssignments { encoderPinA = 2, // rigth encoderPinB = 3, // left clearButton = 8 // another two pins }; volatile unsigned int encoderPos = 0; // a counter for the dial unsigned int lastReportedPos = 1; // change management static boolean rotating=false; // debounce management // interrupt service routine vars boolean A_set = false; boolean B_set = false; void setup() { pinMode(encoderPinA, INPUT); pinMode(encoderPinB, INPUT); pinMode(clearButton, INPUT); // turn on pullup resistors digitalWrite(encoderPinA, HIGH); digitalWrite(encoderPinB, HIGH); digitalWrite(clearButton, HIGH); // encoder pin on interrupt 0 (pin 2) attachInterrupt(0, doEncoderA, CHANGE); // encoder pin on interrupt 1 (pin 3) attachInterrupt(1, doEncoderB, CHANGE); Serial.begin(9600); // output } // main loop, work is done by interrupt service routines, this one only prints stuff void loop() { rotating = true; // reset the debouncer if (lastReportedPos != encoderPos) { Serial.print("Index:"); Serial.println(encoderPos, DEC); lastReportedPos = encoderPos; } if (digitalRead(clearButton) == LOW ) { encoderPos = 0; } } // Interrupt on A changing state void doEncoderA(){ // debounce if ( rotating ) delay (1); // wait a little until the bouncing is done // Test transition, did things really change? if( digitalRead(encoderPinA) != A_set ) { // debounce once more A_set = !A_set; // adjust counter + if A leads B if ( A_set && !B_set ) encoderPos += 1; rotating = false; // no more debouncing until loop() hits again } } // Interrupt on B changing state, same as A above void doEncoderB(){ if ( rotating ) delay (1); if( digitalRead(encoderPinB) != B_set ) { B_set = !B_set; // adjust counter - 1 if B leads A if( B_set && !A_set ) encoderPos -= 1; rotating = false; } }
Dann noch die LCD-Routine: Hab noch was eleganteres als oben gefunden, eine Library von Phaiax (@ github.com/Phaiax/sainsmartkeypad) die den Sketch kürzer macht:
Wird ebenfalls ohne Fehlermeldung kompiliert.
So jetzt fehlt noch die Motor-Steuerung, die hab ich aus einem Tutorial, das ich grade nicht wiederfinde.Code:#include <LiquidCrystal.h> #include "Arduino.h" // github.com/Phaiax/sainsmartkeypad #include "sainsmartkeypad.h" LiquidCrystal lcd(8, 9, 4, 5, 6, 7); SainsmartKeypad keypad(0); int value = 0; uint8_t key; void setup() { lcd.begin(16, 2); lcd.setCursor(0,0); lcd.print("Keypad Example"); } void loop() { key = keypad.getKey_fastscroll(); // Try the other possibilities: // (Only one at a time. // fastscroll, waitrelease and periodic // won't work next to each other.) //key = keypad.getKey_waitrelease(); // without fastscroll but usable //key = keypad.getKey_periodic(); // not quite usable //key = keypad.getKey_instant(); // not quite usable if(key != SAMPLE_WAIT) // Do not refresh screen every loop { switch(key) { case UP_KEY: value++; break; case DOWN_KEY: value--; break; } lcd.setCursor(5,1); lcd.print(value); lcd.print(" "); } }
Auch dieser Schnipsel wird fehlerfrei kompiliert.
Code:// Motorsteuerung mit L293 bzw. anderen Endstufen mittels Speed und Dir // Geschwindigkeit per PWM int halt = 2; // Taster "halt" int links = 3; // Taster "links" int rechts = 4; // Taster "rechts" int PWMPin = 9; // PWM Signal Motor int MotorPlus = 6; // Links/Rechts Motor int MotorMinus = 7; // Links/Rechts Motor int SpeedPin = 0; // Eingang Poti int Speed = 0; // Geschwindigkeit char richtung = 'H'; void setup() { pinMode(MotorPlus, OUTPUT); // Motorsteuerung pinMode(MotorMinus, OUTPUT); // Motorsteuerung pinMode(halt,INPUT); // Taster "halt" digitalWrite(halt,HIGH); // PullUp an pinMode(links,INPUT); // Taster "links" digitalWrite(links,HIGH); // PullUp an pinMode(rechts,INPUT); // Taster "rechts" digitalWrite(rechts,HIGH); // PullUp an } void loop() { // Sollwert einlesen Speed = analogRead(SpeedPin) / 4; // 1024:4=256 // Ausgabe PWM analogWrite(PWMPin, Speed); // Taster abfragen if(digitalRead(links)==0){ richtung='L';} if(digitalRead(rechts)==0){ richtung='R';} if(digitalRead(halt)==0){ richtung='H';} // Motor Links if (richtung=='L'){ digitalWrite(MotorPlus, HIGH); digitalWrite(MotorMinus, LOW);} // Motor Rechts if (richtung=='R'){ digitalWrite(MotorPlus, LOW); digitalWrite(MotorMinus, HIGH);} // Motor Halt if (richtung=='H'){ digitalWrite(MotorPlus, LOW); digitalWrite(MotorMinus, LOW);} delay(100); }
Das Problem ist nun mal wieder, diese drei Schnipsel zu einem funktionierenden Code zu verheiraten. Im ersten Beitrag habe ich es mal versucht, das Ding spuckt aber jede Menge Fehlermeldungen aus.
In der "Motorsteuerung" muss ich die Taster umfiedeln auf die Definitionen vom Keypad auf dem LCD-Shield, und die Übergabe aus dem Drehencoder in die Speed-Variable ist auch noch so ein Problem. Ich versuch es einfach mal:
Wenn ich jetzt hingehe und die drei Teile erneut zusammenfüge, dabei möglichst die Deklarationen nach oben packe und die Funktionen hintereinander stelle kommt schon mal dieses heraus:
Und hier also meine ersten Fragen:Code://2. Versuch einer Zusammenfassung der drei Programmteile #include <LiquidCrystal.h> // select the pins used on the LCD panel LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // define some values used by the panel and buttons int backLight = 10; // LCD Panel Backlight LED connected to digital pin 10 int lightLevel = 255; // Initialise light full on int lcd_key = 0; int adc_key_in = 0; #define btnRIGHT 0 #define btnUP 1 #define btnDOWN 2 #define btnLEFT 3 #define btnSELECT 4 #define btnNONE 5 //Hier versteh ich die Zuordnung nicht: was macht #define btnRIGHT 0 ??? //So, und hier muss natürlich die Pin-Zuordnung geändert werden wg. dem LCD und den anderen Tastern. int halt = ; // Taster "halt" das soll eigentlich der SS:Button sein! int links = ; // Taster "links" das müsste btnLEFT sein int rechts = ; // Taster "rechts" das sollte btnRIGHT sein int PWMPin = ; // PWM Signal Motor int MotorPlus = ; // Links/Rechts Motor int MotorMinus = ; // Links/Rechts Motor int SpeedPin = 0; // Eingang Poti int Speed = 0; // Geschwindigkeit char richtung = 'H'; // read the buttons int read_LCD_buttons() { adc_key_in = analogRead(0); // read the value from the sensor // my [Mark Bramwell's] buttons when read are centered at these valies: 0, 144, 329, 504, 741 // we add approx 50 to those values and check to see if we are close if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result if (adc_key_in < 50) return btnRIGHT; if (adc_key_in < 195) return btnUP; if (adc_key_in < 380) return btnDOWN; if (adc_key_in < 555) return btnLEFT; if (adc_key_in < 790) return btnSELECT; return btnNONE; // when all others fail, return this... } // usually the rotary encoders three pins have the ground pin in the middle enum PinAssignments { encoderPinA = 2, // rigth encoderPinB = 3, // left SS_Button = 8, // another two pins Start Stop Button }; volatile unsigned int encoderPos = 0; // a counter for the dial unsigned int lastReportedPos = 1; // change management static boolean rotating=false; // debounce management // interrupt service routine vars boolean A_set = false; boolean B_set = false; void setup() { lcd.begin(16, 2); // start the LCD library lcd.setCursor(0,0); // move cursor to beginning of line "0" lcd.print("Backlight adjust"); // print a simple message } //Setup-Teil für Drehencoder { pinMode(encoderPinA, INPUT); pinMode(encoderPinB, INPUT); pinMode(SS_Button, INPUT); // turn on pullup resistors digitalWrite(encoderPinA, HIGH); digitalWrite(encoderPinB, HIGH); digitalWrite(SS_Button, HIGH); // encoder pin on interrupt 0 (pin 2) attachInterrupt(0, doEncoderA, CHANGE); // encoder pin on interrupt 1 (pin 3) attachInterrupt(1, doEncoderB, CHANGE); } //Setup-Teil Motorsteuerung: { pinMode(MotorPlus, OUTPUT); // Motorsteuerung pinMode(MotorMinus, OUTPUT); // Motorsteuerung pinMode(halt,INPUT); // Taster "halt" digitalWrite(halt,HIGH); // PullUp an pinMode(links,INPUT); // Taster "links" digitalWrite(links,HIGH); // PullUp an pinMode(rechts,INPUT); // Taster "rechts" digitalWrite(rechts,HIGH); // PullUp an } void loop() { analogWrite(backLight, lightLevel); lcd.setCursor(13,1); // move to position 13 on the second line lcd.print(lightLevel); lcd.setCursor(0,1); // move to the begining of the second line lcd_key = read_LCD_buttons(); // read the buttons switch (lcd_key) // depending on which button was pushed, we perform an action { case btnRIGHT: { lcd.print("LED On "); lightLevel = 255; break; } case btnLEFT: { lcd.print("LED Off "); lightLevel = 1; break; } case btnUP: { lcd.print("LED Fade Up "); if (lightLevel < 255) lightLevel += 1; break; } case btnDOWN: { lcd.print("LED Fade Down "); if (lightLevel > 1) lightLevel -= 1; break; } case btnSELECT: { lcd.print("Select "); break; } case btnNONE: { lcd.print(" "); break; } } } // main loop Debouncer & Encoder, work is done by interrupt service routines, this one only prints stuff rotating = true; // reset the debouncer if (lastReportedPos != encoderPos) { lcd.print("Index:"); lcd.print(encoderPos, DEC); lastReportedPos = encoderPos; } if (digitalRead(SS_Button) == LOW ) { encoderPos = 0; } } // Interrupt on A changing state void doEncoderA(){ // debounce if ( rotating ) delay (1); // wait a little until the bouncing is done // Test transition, did things really change? if( digitalRead(encoderPinA) != A_set ) { // debounce once more A_set = !A_set; // adjust counter + if A leads B if ( A_set && !B_set ) encoderPos += 1; rotating = false; // no more debouncing until loop() hits again } } // Interrupt on B changing state, same as A above void doEncoderB(){ if ( rotating ) delay (1); if( digitalRead(encoderPinB) != B_set ) { B_set = !B_set; // adjust counter - 1 if B leads A if( B_set && !A_set ) encoderPos -= 1; rotating = false; } } { // Sollwert einlesen Speed = analogRead(SpeedPin) / 4; // 1024:4=256 analogWrite(PWMPin, Speed); // Ausgabe PWM if(digitalRead(links)==0){ // Taster abfragen richtung='L';} if(digitalRead(rechts)==0){ richtung='R';} if(digitalRead(halt)==0){ richtung='H';} // Motor Links if (richtung=='L'){ digitalWrite(MotorPlus, HIGH); digitalWrite(MotorMinus, LOW);} // Motor Rechts if (richtung=='R'){ digitalWrite(MotorPlus, LOW); digitalWrite(MotorMinus, HIGH);} // Motor Halt if (richtung=='H'){ digitalWrite(MotorPlus, LOW); digitalWrite(MotorMinus, LOW);} delay(100); }
Wie kriege ich das hier hin:
So viel für heute erst mal....Code:#define btnNONE 5 //Hier versteh ich die Zuordnung nicht: was macht #define btnRIGHT 0 ??? //So, und hier muss natürlich die Pin-Zuordnung geändert werden wg. dem LCD und den anderen Tastern. int halt = ; // Taster "halt" das soll eigentlich der SS:Button sein! int links = ; // Taster "links" das müsste btnLEFT sein int rechts = ; // Taster "rechts" das sollte btnRIGHT sein
Schönen Dank für Eure HIlfe!
Grüße, MM






Zitieren

Lesezeichen