2015-11-06 45 views
0

我正在制作一个立体声控制器,并有一个带按钮的旋转编码器。当我按下按钮时,它会循环显示选项,旋转编码器可以让我设置强度。当我来回切换时,我希望个人强度保持不变。当我将低音转为50%,然后将音量设置为80%时,我想返回,基本仍然是50%。我遇到的问题是强度正在转移。(Arduino)与案例计数

对于原型,我使用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; 


    }       
    } 
} 

回答

0

我会将亮度值存储在一个数组中,然后使用索引来更改只有一个led。

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

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

  1. 防抖动编码器和按钮销
  2. 完整的编码器的检查,即检查是否A或B发生变化,并且在两个方向上。

这是代码;只是让我知道;)

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]; 
     } 
    } 
}