İf döngü kodumu bir switch/case deyimine dönüştür

Işık sensörlerinde sürekli değer okuduğum ve lazer dış cisimler tarafından kesilirse sesli uyarı veren bir proje yaptım.

Bir anahtar durum bazı insanlar tarafından önerildiği gibi kolaylaştıracak. Kısa kodumu aşağıya yazdım, değiştirmeme yardım eder misiniz?

Tüm if döngülerinin bir switch/ case deyimine dönüştürülmesi.

 int sensorPin = A0;
 int sensorPin1 = A1;
 int sensorPin2 = A2;
 int sensorPin3 =  A3;
 int sensorValue0 = 0;
 int sensorValue1 = 0;
 int sensorValue2 = 0;
 int sensorValue3 = 0;
 const int BUZZER = 9;
 const int BUZZER1 = 7;
 const int BUZZER2 = 8;
 const int BUZZER3 = 5;

void setup() {
 Serial.begin(9600);
 pinMode(BUZZER, OUTPUT);
 pinMode(BUZZER1, OUTPUT);
 pinMode(BUZZER2, OUTPUT);
 pinMode(BUZZER3, OUTPUT);
//put your setup code here, to run once:
}

void loop() {
  sensorValue0 = analogRead(sensorPin);
  sensorValue1 = analogRead(sensorPin1);
  sensorValue2 = analogRead(sensorPin2);
  sensorValue3 = analogRead(sensorPin3);
  Serial.println(sensorValue0);
  delay(100);

  if (sensorValue0>920)
   noTone(BUZZER);
  else 
   tone(BUZZER, 500);

  if (sensorValue1>850)
   noTone(BUZZER1);
  else 
   tone(BUZZER1, 300);

  if (sensorValue2>850)
   noTone(BUZZER2);
  else 
   tone(BUZZER2, 700);
}
1
@SDsolar, yardım merkezi , kod incelemelerinin konuyla ilgili olduğunu söylüyor. Bu OP'nin yanlış yaptığı tek şey, proje eleştirisi etiketini içermemekti.
katma yazar Yoni Baciu, kaynak
İf ifadelerindeki> işleci ve farklı değişkenler nedeniyle bu durumda bir anahtar kullanamazsınız (sensorValue0, 1 ve 2). Ayrıca sensorValue3 için bir zil sesi mi eksik?
katma yazar Pat, kaynak

6 cevap

Bir anahtar, yalnızca tek bir değişkenden farklı ayrık değerler seçebilir. Birden fazla değişkeniniz olduğundan ve ayrık değerler aramıyorsanız, geçiş yapmazsanız kullanmanız gerekir.

3
katma

Bir anahtar ifadesi bu durumda uygun olmaz.

İşi sizin için yapan ve ana döngünün daha güzel görünmesini sağlayan bir işlev ekleyerek kodu optimize edebilirsiniz.

void readValue (const int& sensorPin, const int& limit, const int& buzzerPin, const int& frequency)
{
  const int value = sensorValue0 = analogRead(sensorPin);
  if (value > limit)
  {
    noTone(buzzerPin);
  }
  else
  {
    tone(buzzerPin, frequency);
  }
}

Bu şekilde, pinlerin izin verdiği kadar çok zil ve sensör ekleyebilirsiniz.

2
katma
Bu arada, yukarıdakilerin toplamı, sadece size probleminizi düşünmenin farklı bir yolunu sunmaya çalışıyorum. Sensörü ve sesli uyarı pimlerini uzağa soyutlayabilir ve bu sınıfın içine gizleyebilir, sadece bir enum geçirip 2 dizide arayabilirsiniz. Yine overkill, ama eğlenceli, eğer bükülürseniz :)
katma yazar Thomas Myron, kaynak

"Geçiş davası bazılarının önerdiği gibi kolaylaştıracak."

Bu, ücretsiz tavsiyenin neden oldukça pahalı olabileceğinin harika bir örneği :)

Benzersiz bir şey yapmıyorsanız, mevcut yaklaşımınızla daha iyi olursunuz.

düzenleme: Bununla birlikte, bir anahtar/vaka yapısının yardımcı olabileceği durumları görebiliyorum. Örneğin, birden çok değişkeni tutarlı bir eşik kümesiyle karşılaştırmanız gerekirse, kodu okumayı zorlaştırmadan yapmanın bir yolu şunun gibi olur:

THRESHOLD_TypeDef threshold(uint16_t val) {
  if (val < VAL1) return THRESHOLD1;
  if (val < VAL2) return THRESHOLD2;
  ...
  if (val < VALn) return THRESHOLDn;
}

THRESHOLD_TypeDef numaralandırılmış bir türdür.

ve kodunuzda şöyle bir şey yazabilirsiniz:

   switch (threshold(myval)) {
   case THRESHOLD1: do_something1(); break;
   case THRESHOLD2: do_something2(); break;    
   ...

Avantajı açıkça daha iyi okunabilirlik ve tutarlılıktır: Tutarlı bir "sınıflandırma" seti oluşturmak için aynı işlevi farklı değişkenlere uygulayabilirsiniz.

Dezavantajı da açıktır: Her bir eşik için() sadece bir sınıflandırma setini test edebilirsiniz. Ancak, farklı değişkenlere uygulanacak her zaman birden fazla işlev oluşturabilirsiniz.

1
katma

Sadece eğlence için, burada konuyu ele almanın başka bir yolu: C ++ sınıfı oluşturun. Bu kod orijinal kodunuzdan biraz daha uzun görünebilir, ancak avantaj, daha fazla işlevsellik eklemek istiyorsanız, yalnızca sınıfı değiştirmeniz gerekir.

class Sensor {
public:
    Sensor(uint8_t analog_pin, uint8_t buzzer_pin, uint16_t threshold, uint16_t tone_duration)
        : analog_pin(analog_pin), buzzer_pin(buzzer_pin), threshold(threshold), tone_duration(tone_duration)
    {
    }
    void setup() {
        pinMode(buzzer_pin, OUTPUT);
    }
    void loop() {
        sensor_value= analogRead(analog_pin);
        delay(100);
        if (sensor_value> threshold)
            noTone(buzzer_pin);
       else 
           tone(buzzer_pin, tone_duration);
    }
protected:
    uint8_t analog_pin, buzzer_pin;
    uint16_t threshold, sensor_value, tone_duration;
};

Ardından, yalnızca bir Sensor nesneleri dizisi oluşturun:

Sensor sensors[] = {
    Sensor(A0, BUZZER1, 920, 500),
    Sensor(A1, BUZZER2, 850, 300),
    Sensor(A2, BUZZER3, 850, 700)
};
const uint8_t num_sensors = sizeof(sensors)/sizeof(sensors[0]);

void setup() {
    for (int i = 0; i < num_sensors; i++) {
        sensors[i].setup();
    }
}
void loop() {
    for (int i = 0; i < num_sensors; i++) {
        sensors[i].loop();
    }
}
1
katma

Actually, you cannot really rewrite this, due to the > operator instead of the == operator.

Ayrıca, üç farklı değişkeni kontrol ediyorsunuz ve bir switch deyimini kontrol etmek için yalnızca bir değişken kullanılabilir.

Ancak, yapabilecekleriniz aşağıdaki gibi parametrelerle bir işlev oluşturmaktır:

void set(int sensorValue, int value, int buzzer, int frequency)
{
  if (sensorValue > value)
  {
       noTone(buzzer);
  }
  else
  {
       tone(buzzer, frequency);
  }
}

ve Çağrı yap:

 set(sensorValue0, 920, BUZZER, 500);
 set(sensorValue1, 850, BUZZER1, 300);
 set(sensorValue2, 850, BUZZER2, 700);
 set(sensorValue3, ...);//I think you miss this one
1
katma

Durumların şöyle gözüküyor:

bool condition = variable > someValue;

Değişkeninizin değeri (yani sensorValue ) bu nedenle sürekli olmalıdır.

Bununla birlikte, anahtar deyimi değişkenimizin değeri ayrık olduğunda kullanılır.

Sonuç olarak kodunuzdaki anahtar ifadelerini kullanamazsınız.

1
katma