Как независимо управлять двумя светильниками с помощью одной кнопки и системы меню?

Я застрял и не знаю, как с этим справиться. Проблема: я хочу использовать кнопку для меню с двумя экранами (фреймами) Кадр1: если я нажму на кнопку, я хочу включить свет в комнате1 если я нажму еще раз, я хочу выключить свет в комнате1

Кадр 2: с помощью той же кнопки: я хочу включить свет в комнате2 нажав еще раз, я хочу выключить свет в комнате2

Теперь... проблема, с которой я столкнулся... если я нахожусь в кадре 1 и нажимаю кнопку, то включится свет из комнаты 1, но также включится свет из комнаты 2. а я этого не хочу. Все, что я хочу, это как-то сказать uC, что в кадре1 он должен включать только свет из комнаты1 Пожалуйста, кто-то умнее меня .. дайте мне идею, как я могу это сделать. я не могу опубликовать код, потому что он содержит более 3000 строк, и вам потребуется много времени, чтобы прочитать его все.

для кнопок я использую счетчик, чтобы увидеть, изменилось ли состояние, и если да, то увеличить и сделать то, что он должен делать. Также я думаю, что проблема здесь, потому что я использую один и тот же счетчик в обеих функциях.


int btn1 = 46,starebtn1, stareVechebtn1 = 0, btn2 = 50, starebtn2, stareVechebtn2 = 0;
int btn3 = 42, starebtn3, stareVechebtn3 = 0,btn4 = 40, starebtn4, stareVechebtn4 = 0,btn5 = 44, starebtn5, stareVechebtn5 = 0;
int cntbtn1 = 0, cntbtn2 = 0,cntbtn2_1 = 0, cntbtn3 = 0, cntbtn4 = 0, cntbtn5 = 0;
int soilMoisture = A0;
int buzzer = 3;
boolean frame1 = false, frame2 = false;
int procentajUmiditate(){
  int mSensorValue = analogRead(soilMoisture);
  mSensorValue = map(mSensorValue,0,1023,180,0);
  return mSensorValue;
}
void setup()
{
  Serial.begin(9600);
  dht.begin();
  rtc.begin();
  pinMode(ledVerde,OUTPUT);
  pinMode(buzzer,OUTPUT);
  pinMode(soilMoisture,INPUT_PULLUP);
  pinMode(btn1,INPUT);
  pinMode(btn2,INPUT);
  pinMode(btn3,INPUT);
  pinMode(btn4,INPUT);
  pinMode(btn5,INPUT);
  imagineSistemDomotic();
  delay(3000);
  imagineCasaWifi();
  delay(4000);
  tone(buzzer,1000);
  delay(500);
  noTone(buzzer);
  delay(500);
  digitalWrite(ledVerde,HIGH);
}


void loop()
{

  starebtn1 = digitalRead(btn1);
  starebtn2 = digitalRead(btn2); 
  starebtn3 = digitalRead(btn3); 
  starebtn4 = digitalRead(btn4); 
  starebtn5 = digitalRead(btn5);
  int h = dht.readHumidity();  
  int t = dht.readTemperature()-2;
  int f = dht.readTemperature(true);
  temp = t;
  hum = h;
  houR = rtc.getTimeStr();
  dateR = rtc.getDateStr();

//процент условий автоматический
if(procentajUmiditate()<20)
{
  //реле на
}
else 
{
  //релеВыкл.
}



//кнопка1
 if(starebtn1 != stareVechebtn1)
  {
    if(starebtn1 == HIGH)
    {
      Serial.println(cntbtn1);
      cntbtn1++;
    }
  stareVechebtn1 = starebtn1;
  }//конец кнопки1


//btn2
 if(starebtn2 != stareVechebtn2)
  {
    if(starebtn2 == HIGH)
    {


      cntbtn2 = cntbtn2+1;   

    }
    stareVechebtn2 = starebtn2;
  }//endbtn2






//btn3
 if(starebtn3 != stareVechebtn3)
  {
    if(starebtn3 == HIGH)
    {
      cntbtn3 = cntbtn3+1;
    }
    stareVechebtn3 = starebtn3;
  }//endbtn3






//btn4
 if(starebtn4 != stareVechebtn4)
  {
    if(starebtn4 == HIGH)
    {
      cntbtn4 = cntbtn4+1;
    }
    stareVechebtn4 = starebtn4;
  }//endbtn4






//кнопка5
 if(starebtn5 != stareVechebtn5)
  {
    if(starebtn5 == HIGH)
    {
      cntbtn5 = cntbtn5+1;
    }
    stareVechebtn5 = starebtn5;
  }//endbtn5


//экран1
     if(cntbtn1 == 1)
    {
     displayInteriorTempHum();
     //u8g.drawStr(23,58,temp.c_str());
    // u8g.drawStr(99,58,hum.c_str());
    }
//экран2
     if(cntbtn1 == 2)
    {         
     displayInteriorLights();    
    }

//экран3
      if(cntbtn1 == 3)
    {      
     displayExteriorValues();
    }  




     if(cntbtn1 == 4) cntbtn1 = 0;
     if(cntbtn2 == 3) cntbtn2 = 1;
     if(cntbtn2_1 == 3) cntbtn2_1 = 1;
     if(cntbtn3 == 3) cntbtn3 = 1;
} // конец цикла






void imagineSistemDomotic()
{
  u8g.firstPage();
  do{
    u8g.drawFrame(0,0,128,64);
    u8g.setFont(u8g_font_courB10);
    u8g.drawStr(0,30,"Sistem Domotic"); 
    }while(u8g.nextPage());
}

void imagineCasaWifi()
{
   u8g.firstPage();
   do{
    u8g.drawFrame(0,0,128,64);
    u8g.drawBitmapP( 0, 1, 16, 64, CasaDomoticaImage2);  
     }while(u8g.nextPage()); 
}

void tempInterior()
{
   u8g.firstPage();
   do{
    u8g.setFont(u8g_font_courB10);
    u8g.drawStr(32,10,"Interior");
    u8g.drawFrame(0,15,128,49);
    u8g.setFont(u8g_font_5x7);
    u8g.drawStr(2,24,dateR.c_str());
    u8g.drawStr(101,24,houR.c_str());
    u8g.setFont(u8g_font_courB10);
    u8g.drawBitmapP( -3, 4, 16, 64, Temp1);
    u8g.drawCircle(40,46,1);
    u8g.drawStr(23,58,"26");
    u8g.setFont(u8g_font_10x20);
    u8g.drawStr(43,58,"C");
    u8g.setFont(u8g_font_courB10);
    u8g.drawBitmapP( 66, 10, 16, 64, UmidLogo);
    u8g.drawStr(99,58,"57");
    u8g.drawStr(117,58,"%");
     }while(u8g.nextPage());
}

void displayExteriorValues()
{
       frame1 = false;
       frame2 = true;
  u8g.firstPage();
      do{
        u8g.setFont(u8g_font_courB10);
        u8g.drawStr(32,10,"Exterior");
        u8g.drawFrame(0,12,128,51);
        u8g.drawLine(64,12,64,62);


       if(cntbtn2 == 1)
       {
        //u8g.drawBitmapP( 15, 30, 16, 64, robinetApaOprita);
        u8g.setFont(u8g_font_5x8);
        u8g.drawStr(78,23,"Irigare");
        u8g.drawStr(78,30,"pornita");
        u8g.drawBitmapP( 72, 8, 16, 64, robinetApaPornita);
        u8g.setPrintPos(15,40);
        u8g.setFont(u8g_font_courB10);
        u8g.print(procentajUmiditate());
        if(procentajUmiditate()<100)
        {
          u8g.setPrintPos(34,40);
          u8g.print("%");
        }
        else
        {
          u8g.setPrintPos(44,40);
          u8g.print("%");           
        }

       }

  else{

      //u8g.drawBitmapP( 15, 30, 16, 64, faucetWaterOff);
      u8g.setFont(u8g_font_5x8);
      u8g.drawStr(78,23,"Irigare");
      u8g.drawStr(78,30,"pornita");
      u8g.drawBitmapP( 72, 8, 16, 64, robinetApaPornita);
     // u8g.drawBitmapP( 20, -20, 16, 64, LightOff);
    // хорошее значение FanOffLOGO u8g.drawStr(10,23,"Вентиляция");
   // хорошее значение FanOffLOGO u8g.drawStr(20,30,"off");
    // u8g.drawBitmapP(-15, 24, 16, 64, fanOffLogo);
       u8g.drawStr(10,23,"Umid. Sol"); 
       u8g.drawBitmapP( 12, -1, 16, 64, UmiditateSol);
       }
       }while(u8g.nextPage());
    cntbtn2 = 0;
}

void displayInteriorLights()
{

   u8g.firstPage();
      do{
      u8g.setFont(u8g_font_courB10);
      u8g.drawStr(32,10,"Interior");
      u8g.drawFrame(0,12,128,51);
      u8g.drawLine(64,12,64,62);
      u8g.setFont(u8g_font_5x8);


      if(cntbtn2 == 1)
      {
      u8g.drawStr(73,23,"Dormitor");
      u8g.drawStr(75,60,"L.aprinsa");
      u8g.drawBitmapP( 78, 7, 16, 64, LightOn);
      } 
      else if(cntbtn2 == 2)
      {   
      u8g.drawStr(73,23,"Dormitor");
      u8g.drawStr(75,60,"L.stinsa");
      u8g.drawBitmapP( 78, 7, 16, 64, LightOff);
      }
      else{
      u8g.drawStr(73,23,"Dormitor");
      u8g.drawStr(75,60,"L.stinsa");
      u8g.drawBitmapP( 78, 7, 16, 64, LightOff);  
      }

      if(cntbtn3 == 1)
      {
      u8g.drawStr(10,23,"Sufragerie");
      u8g.drawStr(15,60,"L.aprinsa");
      u8g.drawBitmapP( 20, 8, 16, 64, LightOn);    
      }
      else if(cntbtn3 == 2)
      {
      u8g.drawStr(10,23,"Sufragerie");
      u8g.drawStr(15,60,"L.stinsa");
      u8g.drawBitmapP( 20, 8, 16, 64, LightOff);     
      }
    //иначе если(цифровоеЧтение(реле)

    else{
      u8g.drawStr(10,23,"Sufragerie");
      u8g.drawStr(15,60,"L.stinsa");
      u8g.drawBitmapP( 20, 8, 16, 64, LightOff);  
    }
      }while(u8g.nextPage()); 

}

void displayInteriorTempHum()
{
      u8g.firstPage();
      do{
      u8g.setFont(u8g_font_courB10);
      u8g.drawStr(32,10,"Interior");
      u8g.drawFrame(0,15,128,49);
      u8g.setFont(u8g_font_5x7);
      u8g.drawStr(2,24,dateR.c_str());
      u8g.drawStr(101,24,houR.c_str());
      u8g.setFont(u8g_font_courB10);
      u8g.drawBitmapP( -3, 4, 16, 64, Temp1);
      u8g.drawCircle(40,46,1);
      u8g.drawStr(23,58,temp.c_str());
      u8g.setFont(u8g_font_10x20);
      u8g.drawStr(43,58,"C");
      u8g.setFont(u8g_font_courB10);
      u8g.drawBitmapP( 66, 10, 16, 64, UmidLogo);
      u8g.drawStr(99,58,hum.c_str());
      u8g.drawStr(117,58,"%");
      digitalWrite(ledVerde,LOW);
        }while(u8g.nextPage());
}

, 👍1

Обсуждение

Извините, но ваш вопрос очень неясен. Можете ли вы отредактировать свой пост, используя правильные предлоги? Типа: «НА кухне», «В спальне». Также «ВКЛЮЧИТЕ лампочку». Помните, что фраза «включить свет ИЗ комнаты x» означает: «Включить свет нажатием кнопки, расположенной В комнате x»., @smajli

всякий раз, когда кнопка нажата, проверьте номер комнаты, в которой она работает, а затем действуйте соответствующим образом., @jsotola


3 ответа


1

Трудно советовать без более четкой информации, но вот несколько идей, с которыми можно поиграть (сейчас печатаю на телефоне, позже отредактирую).

Если вы используете физическое меню и кнопки, вам нужно каким-то образом отслеживать местоположение. Вы можете попробовать добавить датчики приближения, чтобы проверить физическое местоположение / близость к источнику света, и пусть это будет решающей переменной, для которой активируется лампочка. Вы можете использовать подход «универсальный пульт», используя отдельные Arduino (для каждого источника света) с ИК-приемниками.

При использовании меню приложения, например на телефоне, попробуйте объявить переменную "room" и заставить кнопку передавать имя фрейма или идентификационный номер в зависимости от фрейма ("спальня" или "кухня", "1" или " 2" и т. д.) в качестве этой переменной через линию связи с Arduino. На стороне arduino объявите ту же переменную и обработайте полученные данные из приложения, т.е. String room = your-room-ID. Убедитесь, что у вас есть отдельные объявления распиновки для каждой лампочки, которой вы хотите управлять, т.е. ВЫСОКИЙ);

,

Читая ваш ответ, я понимаю в основном, что я не был так ясен в своем посте. И я согласен с вами в этом. Теперь .. представьте, что у меня есть glcd, который разделен на 2. Слева находится свет комнаты 1, а справа - вентиляция комнаты 1. Это в кадре 1. В кадре 2 (кстати, я прокручиваю кадры с помощью другой кнопки), поэтому в кадре 2 изображение также делится на 2. Слева свет для комнаты 2 и справа температура для комнаты 2. Теперь, помимо кнопки, которую я использую для переключения кадров, у меня есть еще 2, которые я хочу использовать для «текущего» кадра, в котором я нахожусь., @Iulian Chirvasa

Итак... если я нажму кнопку, расположенную под левой стороной экрана. Я мог включить или выключить свет в комнате 1. Но проблема в том, что свет будет включен даже в комнате 2, @Iulian Chirvasa

Примечания к коду моего приложения все еще актуальны, вы управляете glcd с помощью того же Arduino? Если это так, просто добавьте дополнительную строку кода, чтобы установить переменную вашей комнаты при изменении рамки, и используйте остальную часть пин-кода, как я описал. Это все при условии, что в вашем текущем коде нет ошибок, которые приводят к такому результату, без вашего эскиза мы никогда не сможем сказать., @Dan Bailey

вот часть этого, @Iulian Chirvasa


0

Код, который вы показываете, действительно слишком длинный. Однако при беглом взгляде кажется укажите, что вы не используете какую-либо библиотеку устранения дребезга. Это тогда первое, что вы должны сделать. Вариантов, наверное, много. Я буду предложить Bounce2, который, помимо устранения дребезга, обрабатывает край обнаружение. Затем у вас есть метод fell(), который сообщает вам, входной сигнал просто упал с тех пор, как он последний раз тестировался, что является способом для обнаружения нажатия кнопки.

Затем в loop() вы должны добавить что-то вроде этого:

if (mainButton.update() && mainButton.fell()) {

    // Найдите контакт, который управляет соответствующим светом.
    uint8_t lightPin;
    if (currentFrame == FRAME1) {
        lightPin = PIN_LIGHT_ROOM_1;
    } else {  // КАДР2
        lightPin = PIN_LIGHT_ROOM_2;
    }

    // Переключить свет.
    if (digitalRead(lightPin) == HIGH) {
        digitalWrite(lightPin, LOW);
    } else {
        digitalWrite(lightPin, HIGH);
    }
}

Предположения, которые я делаю, должны быть довольно очевидными:

  • currentFrame — это переменная, обновляемая вашей системой меню. Его значение может быть только одной из констант FRAME_1 или FRAME_2
  • PIN_LIGHT_ROOM_1 и PIN_LIGHT_ROOM_2 — это константы, содержащие номера контактов, которые управляют соответствующими индикаторами.
,

1

Думаю, это действительно очень просто... Если я правильно понял...

global frame, lightRoom1, lightRoom2

function changeFrame ( ) {

// если кадр == 1, меняем его на 2

    if ( frame == 1 ) {
        <commands to refresh display>;
        frame = 2;
    } else {
        <commands to refresh display>
        frame = 1;
    }

}

function switchLight ( ) {

// номер комнаты = номер кадра.
// если свет горит, выключаем; если выключен, включите.

    if ( frame == 1 ) {

        if ( lightRoom1 == false ) {
            <code to switch light on >;
            lightRoom1 == true;
        } else {
            <code to switch light off >;
            lightRoom1 == false;
        }

    }

    if ( frame == 2 ) {

        // то же, что и выше, но для комнаты 2.

    }

}


if ( digitalRead ( framePin ) == LOW ) {
    changeFrame ( );
}

if ( digitalRead ( lightPin ) == LOW ) {
    switchLight ( );
}
,