Помогите создать мини УЦИ

Тема в разделе "Моторы, сервоприводы, робототехника", создана пользователем dim@n78, 2 дек 2014.

  1. dim@n78

    dim@n78 Нуб

    #include <Encoder.h>
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>

    Encoder knobLeft(2, 3);
    Encoder knobRight(18, 19);

    LiquidCrystal_I2C lcd(0x27,16,2);


    void setup() {
    lcd.init();
    lcd.backlight();
    lcd.setCursor(0,0);
    }
    long positionLeft = -9999999;
    long positionRight = -9999999;

    void loop() {
    long newLeft, newRight;
    newLeft = knobLeft.read();
    newRight = knobRight.read();
    if (newLeft != positionLeft || newRight != positionRight) {

    lcd.setCursor(0, 0);
    lcd.print("Llne X: ");
    lcd.print(newLeft);
    lcd.setCursor(0, 1);
    lcd.print("Llne Z: ");
    lcd.print(newRight);

    positionLeft = newLeft;
    positionRight = newRight;
    }
    }
    Доброго вам время суток! Вот есть задачка :ардуино мега 2650 пин(2,3)энкодер левый и пин(18,19)энкодер правый пин(20,21)i2cLCD 16*2 пин 5 кнопка обнуления лев. знкодера ,пин 6 обнуления правого энкодера
    нужно чтобы при нажатии на кнопку для показаний одного энкодера прошол сброс а на втором остались показания и все это выводилось на лсд и наоборот
    код для двух энкодоров выше сто процентов рабочий!
    https://www.pjrc.com/teensy/arduino_libraries/Encoder.zip ссылка на библиотеку
    Нужна помощь добрые люди!!!!!!!!!!!!!!!!!!!!!
     
  2. Alex19

    Alex19 Гуру

    С данной библиотекой не знаком, но с энкодерами часто работал.
    https://www.pjrc.com/teensy/td_libs_Encoder.html

    В примере указано
    Код (Text):
    // reset both back to zero.
    knobLeft.write(0);
    knobRight.write(0);
    Проблему понять не могу. Осталось только в обработчике кнопки вызвать knobLeft.write(0);

    Если write не работает должным образом.
    Вот код который планировал использовать без библиотек.
    Код (Text):

    #define encoder0PinA 2
    #define encoder0PinB 3

    volatile long encoder0Pos;

    #define encoder1PinA 21
    #define encoder1PinB 20

    volatile long encoder1Pos;

    #define encoder2PinA 19
    #define encoder2PinB 18

    volatile long encoder2Pos;

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

      // then the encoder inputs
      pinMode(encoder0PinA, INPUT);
      pinMode(encoder0PinB, INPUT);

      // encoder pin on interrupt 0 (pin 2)
      attachInterrupt(0, encoder0PinChangeA, CHANGE);
      // encoder pin on interrupt 1 (pin 3)
      attachInterrupt(1, encoder0PinChangeB, CHANGE);
      encoder0Pos = 0; //reseet the encoder position to 0



      // then the encoder inputs
      pinMode(encoder1PinA, INPUT);
      pinMode(encoder1PinB, INPUT);


      // encoder pin on interrupt 0 (pin 2)
      attachInterrupt(2, encoder1PinChangeA, CHANGE);
      // encoder pin on interrupt 1 (pin 3)
      attachInterrupt(3, encoder1PinChangeB, CHANGE);
      encoder1Pos = 0; //reseet the encoder position to 0



      // then the encoder inputs
      pinMode(encoder2PinA, INPUT);
      pinMode(encoder2PinB, INPUT);

      // encoder pin on interrupt 0 (pin 2)
      attachInterrupt(4, encoder2PinChangeA, CHANGE);
      // encoder pin on interrupt 1 (pin 3)
      attachInterrupt(5, encoder2PinChangeB, CHANGE);
      encoder2Pos = 0; //reseet the encoder position to 0
    }

    void loop() {
      //do stuff dependent on encoder position here
      //such as move a stepper motor to match encoder position
      //if you want to make it 1:1 ensure the encoder res matches the motor res by dividing/multiplying
      Serial.print("1 - ");
      Serial.print(encoder0Pos);
      Serial.print(" ");
      Serial.print("2 - ");
      Serial.print(encoder1Pos);
      Serial.print(" ");
      Serial.print("3 - ");
      Serial.print(encoder2Pos);
      Serial.println(" ");
      delay(100);
    }

    void encoder0PinChangeA() {
    // look for a low-to-high on channel A
      if (digitalRead(encoder0PinA) == HIGH) {
        // check channel B to see which way encoder is turning
        if (digitalRead(encoder0PinB) == LOW) {
          encoder0Pos = encoder0Pos + 1;        // CW
        }
        else {
          encoder0Pos = encoder0Pos - 1;        // CCW
        }
      }
      else  // must be a high-to-low edge on channel A                                
      {
        // check channel B to see which way encoder is turning
        if (digitalRead(encoder0PinB) == HIGH) {
          encoder0Pos = encoder0Pos + 1;          // CW
        }
        else {
          encoder0Pos = encoder0Pos - 1;          // CCW
        }
      }
    }

    void encoder0PinChangeB() {
      // look for a low-to-high on channel B
      if (digitalRead(encoder0PinB) == HIGH) {
      // check channel A to see which way encoder is turning
        if (digitalRead(encoder0PinA) == HIGH) {
          encoder0Pos = encoder0Pos + 1;        // CW
        }
        else {
          encoder0Pos = encoder0Pos - 1;        // CCW
        }
      }
      // Look for a high-to-low on channel B
      else {
        // check channel B to see which way encoder is turning
        if (digitalRead(encoder0PinA) == LOW) {
          encoder0Pos = encoder0Pos + 1;          // CW
        }
        else {
          encoder0Pos = encoder0Pos - 1;          // CCW
        }
      }
    }




    void encoder1PinChangeA() {
    // look for a low-to-high on channel A
      if (digitalRead(encoder1PinA) == HIGH) {
        // check channel B to see which way encoder is turning
        if (digitalRead(encoder1PinB) == LOW) {
          encoder1Pos = encoder1Pos + 1;        // CW
        }
        else {
          encoder1Pos = encoder1Pos - 1;        // CCW
        }
      }
      else  // must be a high-to-low edge on channel A                                
      {
        // check channel B to see which way encoder is turning
        if (digitalRead(encoder1PinB) == HIGH) {
          encoder1Pos = encoder1Pos + 1;          // CW
        }
        else {
          encoder1Pos = encoder1Pos - 1;          // CCW
        }
      }
    }

    void encoder1PinChangeB() {
      // look for a low-to-high on channel B
      if (digitalRead(encoder1PinB) == HIGH) {
      // check channel A to see which way encoder is turning
        if (digitalRead(encoder1PinA) == HIGH) {
          encoder1Pos = encoder1Pos + 1;        // CW
        }
        else {
          encoder1Pos = encoder1Pos - 1;        // CCW
        }
      }
      // Look for a high-to-low on channel B
      else {
        // check channel B to see which way encoder is turning
        if (digitalRead(encoder1PinA) == LOW) {
          encoder1Pos = encoder1Pos + 1;          // CW
        }
        else {
          encoder1Pos = encoder1Pos - 1;          // CCW
        }
      }
    }






    void encoder2PinChangeA() {
    // look for a low-to-high on channel A
      if (digitalRead(encoder2PinA) == HIGH) {
        // check channel B to see which way encoder is turning
        if (digitalRead(encoder2PinB) == LOW) {
          encoder2Pos = encoder2Pos + 1;        // CW
        }
        else {
          encoder2Pos = encoder2Pos - 1;        // CCW
        }
      }
      else  // must be a high-to-low edge on channel A                                
      {
        // check channel B to see which way encoder is turning
        if (digitalRead(encoder2PinB) == HIGH) {
          encoder2Pos = encoder2Pos + 1;          // CW
        }
        else {
          encoder2Pos = encoder2Pos - 1;          // CCW
        }
      }
    }

    void encoder2PinChangeB() {
      // look for a low-to-high on channel B
      if (digitalRead(encoder2PinB) == HIGH) {
      // check channel A to see which way encoder is turning
        if (digitalRead(encoder2PinA) == HIGH) {
          encoder2Pos = encoder2Pos + 1;        // CW
        }
        else {
          encoder2Pos = encoder2Pos - 1;        // CCW
        }
      }
      // Look for a high-to-low on channel B
      else {
        // check channel B to see which way encoder is turning
        if (digitalRead(encoder2PinA) == LOW) {
          encoder2Pos = encoder2Pos + 1;          // CW
        }
        else {
          encoder2Pos = encoder2Pos - 1;          // CCW
        }
      }
    }
     
    Данный код тестировался на Mega 2560 использовались прерывания.
    0 (pin 2), 1 (pin 3), 2 (pin 21), 3 (pin 20), 4 (pin 19), 5 (pin 18).

    Вам останется, только добавить обработку кнопки и там обнулять одну из переменных encoder0Pos, encoder1Pos и т.д.

    Кстати тоже для УЦИ, пока делал появились ЧПУ и сам перестал работать на фрезерном. А фрезеровщику он не нужен, и разбирать и устанавливать энкодеры не стали.
     
  3. dim@n78

    dim@n78 Нуб

    Я тоже фрезеровщик, а дома хобби ,занимаюсь художественной ковкой приходится изобретать новые станочки для удобства.
    Спасибо за понимание!
     
  4. Alex19

    Alex19 Гуру

    Сам не фрезеровщик, но чего только не приходится делать на производстве:). Даже делал литиевые формы для ТПА, но в основном на ЧПУ.

    Будут вопросы, спрашивайте.
     
    Последнее редактирование: 3 дек 2014
  5. dim@n78

    dim@n78 Нуб

    спасиб
     
  6. dim@n78

    dim@n78 Нуб

    Код (Text):
    #define encoder0PinA 2
    #define encoder0PinB 3
    volatile long encoder0Pos;

    #define encoder2PinA 19
    #define encoder2PinB 18
    volatile long encoder2Pos;

    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x27, 16, 2);

    const int button1Pin = 5;
    int button1State = 0;

    const int button2Pin = 8;
    int button2State = 0;

    void setup () {
      lcd.init();
      lcd.backlight();
      lcd.home();

      pinMode(encoder0PinA, INPUT);
      pinMode(encoder0PinB, INPUT);

      attachInterrupt(0, encoder0PinChangeA, CHANGE);
      attachInterrupt(1, encoder0PinChangeB, CHANGE);
      encoder0Pos = 0;

      pinMode(encoder2PinA, INPUT);
      pinMode(encoder2PinB, INPUT);

      attachInterrupt(4, encoder2PinChangeA, CHANGE);
      attachInterrupt(5, encoder2PinChangeB, CHANGE);
      encoder2Pos = 0;

      pinMode(button1Pin, INPUT);
      pinMode(button2Pin, INPUT);
    }
    void loop() {
      button1State = digitalRead(button1Pin);
      if (button1State == HIGH) {
        encoder0Pos = 0;
      }
      button2State = digitalRead(button2Pin);
      if (button2State == HIGH) {
        encoder2Pos = 0;
      }

      lcd.setCursor(0, 0);
      lcd.print("Line X ");
      lcd.print(encoder0Pos);
      lcd.print("            ");
      lcd.setCursor(0, 1 );
      lcd.print("Line Z ");
      lcd.print(encoder2Pos);
      lcd.println("          ");

    }
    void encoder0PinChangeA() {
      if (digitalRead(encoder0PinA) == HIGH) {

        if (digitalRead(encoder0PinB) == LOW) {
          encoder0Pos = encoder0Pos + 1;        // CW
        }
        else {
          encoder0Pos = encoder0Pos - 1;        // CCW
        }
      }
      else
      {
        if (digitalRead(encoder0PinB) == HIGH) {
          encoder0Pos = encoder0Pos + 1;          // CW
        }
        else {
          encoder0Pos = encoder0Pos - 1;          // CCW
        }
      }
    }


    void encoder0PinChangeB() {
      if (digitalRead(encoder0PinB) == HIGH) {
        if (digitalRead(encoder0PinA) == HIGH) {
          encoder0Pos = encoder0Pos + 1;        // CW
        }
        else {
          encoder0Pos = encoder0Pos - 1;        // CCW
        }
      }
      else {
        if (digitalRead(encoder0PinA) == LOW) {
          encoder0Pos = encoder0Pos + 1;          // CW
        }
        else {
          encoder0Pos = encoder0Pos - 1;          // CCW
        }
      }
    }

    void encoder2PinChangeA() {
      if (digitalRead(encoder2PinA) == HIGH) {
        if (digitalRead(encoder2PinB) == LOW) {
          encoder2Pos = encoder2Pos + 1;        // CW
        }
        else {
          encoder2Pos = encoder2Pos - 1;        // CCW
        }
      }
      else
      {
        if (digitalRead(encoder2PinB) == HIGH) {
          encoder2Pos = encoder2Pos + 1;          // CW
        }
        else {
          encoder2Pos = encoder2Pos - 1;          // CCW
        }
      }
    }

    void encoder2PinChangeB() {

      if (digitalRead(encoder2PinB) == HIGH) {

        if (digitalRead(encoder2PinA) == HIGH) {
          encoder2Pos = encoder2Pos + 1;        // CW
        }
        else {
          encoder2Pos = encoder2Pos - 1;        // CCW
        }
      }
      else {
        if (digitalRead(encoder2PinA) == LOW) {
          encoder2Pos = encoder2Pos + 1;          // CW
        }
        else {
          encoder2Pos = encoder2Pos - 1;          // CCW
        }
      }
    }
     
     
  7. dim@n78

    dim@n78 Нуб

    Все заработало !
    А покозание счетчика можно уменьшить в 10 раз сделать 1:10
     
  8. dim@n78

    dim@n78 Нуб

    И еще вопросик нужно ли делать подтяжку к земле на энкодерах
     
  9. Alex19

    Alex19 Гуру

    Конечно можно, вот только могут быть потери, к примеру показания 103, делим на 10 будет остаток 3
    Код (Text):

    long encoder0 = encoder0Pos / 10; // Сохраняем в encoder0 значение деленное на 10
    int encoder0Modulo = encoder0Pos % 10; // Сохраняем в encoder0Modulo остаток от деленния на 10
     
    Надо смотреть, к примеру Omron-ах использую только их, еще не встречал где требовалось. Работают без проблем в других проектах.

    А вот на кнопки, желательно, делать подтяжку к земле.

    Посмотрите требования по току для Ваших энкодеров, если ток равен или превышает 40ma (для Arduino Mega 2560) спалите ножку. Тогда нужно питать их отдельным источником питания. Хотя я бы поставил отдельный блок питания даже если равен или превышает 20ma.

    UPD. Лучше иметь запас.:)
     
    Последнее редактирование: 4 дек 2014
  10. dim@n78

    dim@n78 Нуб

    Энкодоры ток потребления 14мА все нормально проверял получается в риальности 13мА
    А кнопки притянуты к земле 10к
     
  11. Alex19

    Alex19 Гуру

    Тогда проблем быть не должно. Все должно получится.