(Arduino)用案例计数

时间:2015-11-06 05:41:49

标签: arduino case counter encoder

我正在使用立体声控制器,并有一个带按钮的旋转编码器。当我按下按钮时,它循环选项,旋转编码器让我设置强度。当我来回切换时,我希望保持个体强度。当我将低音转为50%然后将音量设置为80%时我想回来并且基座仍然是50%。我遇到的问题是强度正在转移。

对于原型设计,我使用3个LED。我可以设置个人亮度,但是当我更改下一个LED时,它会自动更改为前一个LED的强度。

这背后的原因是,当我设置低音和高音以及音量时,我不希望当我回来改变某些东西时数值跳跃。我想从它停止的地方开始。

我认为我要采用的结构是基于案例的计数器。外壳外的公共变量由旋转编码器递增,如果可能,则存储。

/*
** Rotary Encoder Example
 ** Use the Sparkfun Rotary Encoder to vary brightness of LED
 **
 ** Sample the encoder at 200Hz using the millis() function
 */

int brightness = 0;    // how bright the LED is, start at half brightness
int fadeAmount = 30;    // how many points to fade the LED by
unsigned long currentTime;
unsigned long loopTime;
const int pin_A = 4;  // pin 12
const int pin_B = 5;  // pin 11
 unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev=0;
const int green = 11;
const int blue = 10;
const int red=9;
int last_bright=0;

int mode = 0; // Selector State (Initial state = ALL OFF)
int val = 0; // Pin 13 HIGH/LOW Status
int butState = 0; // Last Button State
int modeState = 0; 
int selected=710;
int greenvol=0;
int redvol=0;
int bluevol=0;
int select_bright=0;

void setup()  {
  // declare pin 9 to be an output:
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(pin_A, INPUT);
  pinMode(pin_B, INPUT);
  currentTime = millis();
  loopTime = currentTime; 
} 

void loop()  {
  // get the current elapsed time
  currentTime = millis();

  brightness=select_bright;
  if(currentTime >= (loopTime + 5)){
    // 5ms since last check of encoder = 200Hz  
    encoder_A = digitalRead(pin_A);    // Read encoder pins
    encoder_B = digitalRead(pin_B);   
    if((!encoder_A) && (encoder_A_prev)){
      // A has gone from high to low 
      if(encoder_B) {
        // B is high so clockwise
        // increase the brightness, dont go over 255
        if(brightness + fadeAmount <= 255) brightness += fadeAmount;               
      }   
      else {
        // B is low so counter-clockwise      
        // decrease the brightness, dont go below 0
        if(brightness - fadeAmount >= 0) brightness -= fadeAmount;               
      }   

    }   
    encoder_A_prev = encoder_A;     // Store value of A for next time    

    // set the brightness of pin 9:
    analogWrite(selected, brightness);
    last_bright=brightness;   

    loopTime = currentTime;  // Updates loopTime
  }



  // end of rotary encoder


  val = digitalRead(8);
  delay(5);

  // If we see a change in button state, increment mode value
  if (val != butState && val == HIGH){
    mode++;
  }

  butState = val; // Keep track of most recent button state

  // No need to keep setting pins *every* loop
    if (modeState != mode)

    // If no keys have been pressed yet don't execute
    // the switch code below
  {

    switch ( mode ) {


    case 2:
      selected=red;
      select_bright=redvol;
      redvol=last_bright;

      break;


    case 3:
      selected=green;
      select_bright=greenvol;
      greenvol = last_bright;
      break;


    default:
      selected=blue;
      select_bright=bluevol;
      bluevol = last_bright;

      mode = 1;
     break;


    }                         
  }
}

1 个答案:

答案 0 :(得分:0)

我将亮度值存储在数组中,然后使用索引仅更改一个LED。

这是一个(我希望)工作的例子。试一试,看看它是否符合您的需求;)

我做了一些其他更改(你可以在评论中看到它们)。无论如何,我建议你至少添加

  1. 在编码器和按钮引脚上进行消除
  2. 完整的编码器检查,即检查A或B是否改变,以及两个方向。
  3. 这是代码;请告诉我;)

    byte fadeAmount = 30;
    
    const byte pin_button = 8;
    const byte pin_A = 4;  // pin 12
    const byte pin_B = 5;  // pin 11
    unsigned long loopTime;
    
    unsigned char encoder_A;
    unsigned char encoder_B;
    unsigned char encoder_A_prev=0;
    
    // Array to store the brightness of the
    // red (0), green (1) and blue (2) leds
    byte brightnesses[3];
    byte lastbrightnesses[3];
    byte currentLed;
    
    // Pins for red (0), green (1) and blue (2) leds
    byte led_pins[] = {9, 10, 11};
    
    void setup()  {
        pinMode(pin_button, INPUT);
        pinMode(pin_A, INPUT);
        pinMode(pin_B, INPUT);
    
        // set the brightnesses to their initial states
        // and the lastbrightnesses to ANOTHER value
        for (currentLed=0; currentLed<3; i++)
        {
            pinMode(led_pins[currentLed], OUTPUT);
            brightnesses[currentLed] = 255;
            lastbrightnesses[currentLed] = 0;
        }
        currentLed = 0;
    
        loopTime = millis() - 5;
    } 
    
    void loop()  {
        // I prefer this instead of yours
        // because this is overflow-safe
        if((millis() - loopTime) >= 5) {
            loopTime += 5;
    
            // Check encoder
            encoder_A = digitalRead(pin_A);
            encoder_B = digitalRead(pin_B);   
            if((!encoder_A) && (encoder_A_prev)){
                // A has gone from high to low 
                if(encoder_B) {
                    // B is high so clockwise
                    // Again, this is overflow-safe
                    // And it compensates for not reaching the end of the values
                    if(brightnesses[currentLed] <= 255 - fadeAmount)
                        brightnesses[currentLed] += fadeAmount;
                    else
                        brightnesses[currentLed] = 255;
                }   
                else {
                    // B is low so counter-clockwise      
                    // decrease the brightness, dont go below 0
                    if(brightnesses[currentLed] >= fadeAmount)
                        brightnesses[currentLed] -= fadeAmount;
                    else
                        brightnesses[currentLed] = 0;
                }
            }   
            encoder_A_prev = encoder_A;     // Store value of A for next time    
    
            // I'd read the button every 5ms too
            val = digitalRead(pin_button);
            if (val != butState && val == HIGH){
                currentLed++;
                if (currentLed >= 3) currentLed = 0;
                butState = val;
            }
        }
    
        // Here you can also check only currentLed instead
        // of every led if you can only change it through
        // the encoder
        byte i;
        for (i=0; i<3; i++)
        {
            if (lastbrightnesses[i] != brightnesses[i])
            {
                analogWrite(led_pins[i], brightnesses[i]);
                lastbrightnesses[i] = brightnesses[i];
            }
        }
    }