Работа с кнопками. В помощь новичку.

Chubaka
Offline
Зарегистрирован: 28.01.2014

nestandart пишет:

В программу особо не вчитывался , но ...

Переделайте все конструкции if else if на просто if ( лучше вообще откажитесь от оператора else).  Возможно у вас конфликт по условиям if  else. [/

И еще. Как вариант , перенесите скобку из строки 25 в самый низ.

Ход таймера маловат (40мс). Получается чтобы сработало одиночное нажатие нужно удерживать кнопку не более 120мс (неудобно).

Оптимальное время для одиночного нажатия 500-1000мс.

 

Я бы сделал отдельный таймер для каждой кнопки.

Перенёс скобку, else убрал, всё равно не получается(((

Есть у кого ещё идеи?

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

 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Как именно не получается ? Что происходит ?

Chubaka
Offline
Зарегистрирован: 28.01.2014

Всё так же как и было. При нажатии и удержании кнопки сначало проходит сигнал как при одиночном нажатии а потом как при удержании. Т.е. при нажатии идалнейшем удержании кнопки следующий трек отсылается сначала и remote.next и потом remote.forward (стр. 065, 072)

int buttonPin=6; //пин для резистивных кнопок
int data;
int flag=0;
long previousMillis = 0; 
int val=0; 

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

void loop()
{
 data=analogRead(buttonPin); //читаем значение нажатой кнопки
 Serial.println(data); //для определения кодов нажатых кнопок на мониторе порта
 
  if (data<=900) //если нажата любая из кнопок начинается отсчёт
  { 
    if (millis() -previousMillis >200)    
    { 
      previousMillis = millis();     
      val++; 

//кнопка громкости +
      if (data>=210 && data<=232 && flag==0 && val==1)  //одиночное нажатие
      {
      Remote.increase(); //прибавить громкость на ед.
      Remote.clear();
      flag=1;
      val=0;
      }
      if (data>=210 && data<=232 && val>=2)  // удержание
      {
      Remote.increase(); //прибавлять громкость до отпускания
      Remote.clear();
      val=0;
      }

//кнопка громкости -
      if (data>=460 && data<=488 && flag==0 && val>=1 && val<=3)  //одиночное нажатие
      {
      Remote.decrease(); //убавить громкость на ед.
      Remote.clear();
      flag=1;
      val=0;
      }
      if (data>=460 && data<=488 && val>=4)  //удержание
      {
      Remote.decrease(); //убавлять громкость до отпускания
      Remote.clear();
      val=0;
      }

//кнопка следующий трек
      if (data==0 && flag==0 && val==1)  //одиночное нажатие
      {
      Remote.next(); //следующий трек
      Remote.clear();
      flag=1;
      val=0;
      }
      if (data==0 && val>=2)  //удержание
      {
      Remote.forward(); //перемотка вперёд
      Remote.clear();
      val=0;
      }
  
//кнопка предидущий трек
      if (data>=76 && data<=92 && flag==0 && val>=1 && val<=5)  //одиночное нажатие
      {
      Remote.previous(); //предидущий трек
      Remote.clear();
      flag=1;
      val=0;
      }
      if (data>=76 && data<=92 && val>=6)  //удержание
      {
      Remote.rewind(); //перемотка назад
      Remote.clear();
      val=0;
      }
    
//кнопка приглушения звука
      if (data>=565 && data<=594 && flag==0)  //нажата кнопка
      {
      Remote.mute();
      Remote.clear();
      flag=1;
      val=0;
      }
    }
  } 
//не нажата не одна из кнопок
   if (data>=950 && data<=960 && flag==1)
  {
   flag=0;
  }
}

 

romeo_b
Offline
Зарегистрирован: 08.11.2013

Добрый вечер.

Подскажите  можно ли в матричной клавиатуре  к примеру 3 на 3,

сделать  событие при удержании одной  кнопки

 мне нужно плано увеличивать значение   set++  


#include <Keypad.h>

int set = 0;

const byte ROWS = 3; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'}

};
byte rowPins[ROWS] = {2, 3, 4}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 6, 7}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){
  Serial.begin(9600);
}
  
void loop(){
  char key = keypad.getKey();
  
  if (key){
    Serial.println(key);
  }



// ?????

 if (key  ==  '1' )
 { set++;
    
 }
 
 
  if (key  ==  '2' )
 { set--;
    
 }
 

Serial.println(set);




}

в таком варианте  получается нужно все время нажимать на кнопку   а хочу чтоб при нажатии показания увеличивались 

Как это сделать?
Спасибо.

dimka
dimka аватар
Offline
Зарегистрирован: 21.09.2012

button switch Read boolean

// button switch boolean
const int buttonPin = 2; 
int Val;
boolean q;
void setup() {
  Serial.begin(9600);
  pinMode(buttonPin, INPUT);   
}
void loop(){
  if (digitalRead(buttonPin) == q)
  {
    q=!q;
    Val++;
    delay(100);
    Serial.println(Val);
  }
}

 

iwizard7
iwizard7 аватар
Offline
Зарегистрирован: 30.04.2013

Всем привет! 

помогите разобраться пожалуйста, не работает включение кнопкой светодиода и включение по времени, тоесть либо одно либо другое, если закомментить код

//////////Включаем и выключаем свет кнопкой///////////
  currentButton = debounce(lastButton);
  
 if (lastButton == LOW && currentButton == HIGH)
 {
   ledOn = !ledOn;
   }
 lastButton = currentButton;
digitalWrite(ledPin, ledOn);
 
то срабатывает код 
 if (RTC.hour >= 19 && RTC.hour <= 23) digitalWrite(ledPin, HIGH); //устанавливаем время и зажигаем светодиод
    else digitalWrite(ledPin, LOW); // тушим светодиод
 если же первый код не закомментирован то включение по часам не срабатывает

весь код целиком :

#include <DS1307new.h> // for clock
#include <Wire.h> // for i2c protocol
#include <OneWire.h> // for DS18B20
#include <LiquidCrystal_I2C.h> // for 1602
#include <SPI.h>
#include <Ethernet.h>
boolean lastButton = LOW; // переменная для хранения состояния кнопки
boolean ledOn = false;    //
boolean currentButton = LOW; //
float maxF=0, minF=212; //переменные для макс и мин температуры
OneWire  ds(6);  // on pin 10 (a 4.7K resistor is necessary)  
int ledPin = 8;  // pin for LED
int LedStatus = 0;   // показывает статус светодиода на страничке
int sensorPin = A0;  // датчик света
const int buttonPin = 2;      // номер входа, подключенный к кнопке
int buttonState = 0;          // переменная для хранения состояния кнопки
unsigned int sensorValue = 0; // цифровое значение фоторезистора
LiquidCrystal_I2C lcd(0x20,16,2); // 0x20 is adresss for LCC 16x2
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC адрес
IPAddress ip(192,168,2,120); // IP адрес
EthernetServer server(80);   // Порт WEB сервера
byte grad[8] = { // рисует значек градуса
  B01110,
  B10001,
  B10001,
  B01110,
  B00000,
  B00000,
  B00000,
};

int ics =0; //count number of sensor

void setup(){
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
   
  Serial.begin(9600);  

  lcd.init(); 
  lcd.backlight(); //backlight is now ON
  // set up the LCD's number of columns and rows: 
  lcd.createChar(0, grad);
  lcd.begin(16, 2);
  /* Print a logo message to the LCD.
   lcd.print("AQUACONTROLLER");  
   lcd.setCursor(0, 1);
   lcd.print("by iWizard");
   delay (2500);
   lcd.clear();
   */
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

}

//////////////////////DEBOUNCE//////////////////////
boolean debounce(boolean last)
{
boolean current = digitalRead(buttonPin);
if (last != current)
{
delay(5);
current = digitalRead(buttonPin);
}
return current;
}
////////////////////////////////////////////////////


void loop(){
  sensorValue = analogRead(sensorPin);  // считываем значение с фоторезистора 
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius;

  if ( !ds.search(addr)) {
    // lcd.clear();   
    lcd.setCursor(0, 1);
    //   lcd.print("doar ");
    //   lcd.print(ics);
    //  lcd.print(" senzor(i)");    
    ds.reset_search();
    ics=0;


    if (RTC.hour >= 19 && RTC.hour <= 23) digitalWrite(ledPin, HIGH); //устанавливаем время и зажигаем светодиод
    else digitalWrite(ledPin, LOW); // тушим светодиод

//////////Включаем и выключаем свет кнопкой///////////
   currentButton = debounce(lastButton);
  
 if (lastButton == LOW && currentButton == HIGH)
  {
   ledOn = !ledOn;
   }
 lastButton = currentButton;

digitalWrite(ledPin, ledOn);
///////////////////////////////////////////////////// 
///----------------------------- начало кода часов -----------------------------///

    RTC.getTime();
    if (RTC.hour < 10)                   
    {
      Serial.println();
      Serial.print("0");
      Serial.print(RTC.hour, DEC);
    }
    else
    {
      Serial.print(RTC.hour, DEC);
    }

    Serial.print(":");

    if (RTC.minute < 10) Serial.print("0");
    Serial.print(RTC.minute, DEC);

    Serial.print(":");
    if (RTC.second < 10) Serial.print("0");
    Serial.print(RTC.second, DEC);


    Serial.print(" ");
    if (RTC.day < 10) Serial.print("0");
    Serial.print(RTC.day, DEC);


    Serial.print("-");
    if (RTC.month < 10) Serial.print("0");
    Serial.print(RTC.month, DEC);  
    Serial.print("-");
    Serial.print(RTC.year, DEC);         
    Serial.print(" ");
    Serial.print("-");
    switch (RTC.dow)                     
{
    case 0: Serial.print("SUN "); break;
    case 1: Serial.print("MON "); break;
    case 2: Serial.print("TUE "); break;
    case 3: Serial.print("WED "); break;
    case 4: Serial.print("THU "); break;
    case 5: Serial.print("FRI "); break;
    case 6: Serial.print("SAT "); break;
}

Serial.print("Uptime: ");
Serial.print(millis()/60000);//Display the Uptime since last Start/Reset and System version.
Serial.print(" Min, ");
//int miliseconds = 9999999;
//printf("%d hours, %d minutes and %d seconds\n", (int) miliseconds / (1000 * 60 * 60), (int) miliseconds / (1000 * 60), (int) miliseconds / 1000);


    ics++; 

    ds.reset();
    ds.select(addr);
    ds.write(0x44, 1);        // start conversion, with parasite power on at the end

    delay(750);     // maybe 750ms is enough, maybe not
    // we might do a ds.depower() here, but the reset will take care of it.

    present = ds.reset();
    ds.select(addr);    
    ds.write(0xBE);         // Read Scratchpad

    for ( i = 0; i < 9; i++) {           // we need 9 bytes
      data[i] = ds.read();
    }
    // Convert the data to actual temperature
    // because the result is a 16 bit signed integer, it should
    // be stored to an "int16_t" type, which is always 16 bits
    // even when compiled on a 32 bit processor.
    int16_t raw = (data[1] << 8) | data[0];
    if (type_s) {
      raw = raw << 3; // 9 bit resolution default
      if (data[7] == 0x10) {
        // "count remain" gives full 12 bit resolution
        raw = (raw & 0xFFF0) + 12 - data[6];
      }
    } 
    else {
      byte cfg = (data[4] & 0x60);
      // at lower res, the low bits are undefined, so let's zero them
      if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
      else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
      else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
      //// default is 12 bit resolution, 750 ms conversion time
    }

 //   if (OneWire::crc8(addr, 7) != addr[7]) {
 //     lcd.print("CRC is not valid!");
 //     return;
 //   }

    celsius = (float)raw / 16.0;

    lcd.setCursor(0,0);
    lcd.print("Temp");
    lcd.print(" = ");
    lcd.print(celsius);
    lcd.write(byte(0));
    lcd.print("C");
    Serial.print(celsius);
    Serial.print("C, ");
    //вывод часов на дисплей//  
    lcd.setCursor(0, 1);
    if(RTC.hour<10)lcd.print(0);
    lcd.print(RTC.hour);

    lcd.print(":");
    //lcd.print( (RTC.second %2 )?" ":":"); //мигать двоеточием
    if(RTC.minute<10)lcd.print(0);
    lcd.print(RTC.minute);

    lcd.setCursor(10, 1); 
    switch (RTC.dow)                      // Friendly printout the weekday
    {
    case 0: lcd.print("SUN"); break;
    case 1: lcd.print("MON"); break;
    case 2: lcd.print("TUE"); break;
    case 3: lcd.print("WED"); break;
    case 4: lcd.print("THU"); break;
    case 5: lcd.print("FRI"); break;
    case 6: lcd.print("SAT"); break;
    }
    lcd.print("-"); 
    lcd.print(RTC.day);
  Serial.print("Light Sensor: ");   
  Serial.print(sensorValue, DEC);     // вывод данных с фоторезистора (0-1024)
  Serial.println("");                 // возврат каретки 

    // listen for incoming clients
    EthernetClient client = server.available();
    if (client) {
      Serial.println("new client");
      // an http request ends with a blank line
      boolean currentLineIsBlank = true;
      while (client.connected()) {
        if (client.available()) {
          char c = client.read();
          Serial.write(c);
          // if you've gotten to the end of the line (received a newline
          // character) and the line is blank, the http request has ended,
          // so you can send a reply
          //if (c == '\n' && currentLineIsBlank) {
            // send a standard http response header
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println("<head> ");
            client.println("<meta http-equiv=Content-Type content=text/html; charset=utf-8/>");
            client.println("<title> Arduino :: Акваконтролеер</title>");
            client.println("</head> ");
            client.println("<body bgcolor=\"#9bbad6\">"); // цвет фона
            client.println("Connection: close");  // the connection will be closed after completion of the response
            client.println("Refresh: 10");  // refresh the page automatically every 5 sec
            client.println();
            client.println("<!DOCTYPE HTML>");
            client.println("<html>");
            client.println("<center>");
            // output the value of each analog input pin
            for (int analogChannel = 0; analogChannel < 1; analogChannel++) {
              int sensorReading = analogRead(analogChannel);
             client.println("<H1>");
              client.print(RTC.hour, DEC);
              client.print(":");
              if (RTC.minute < 10) client.print("0");
              client.print(RTC.minute, DEC);

              client.println("<br>");
              client.println("</h1>");
            client.println("<h2>");
              if (RTC.day < 10) client.print("0");
              client.print(RTC.day, DEC);


              client.print(" ");
             // if (RTC.month < 10) client.print("0");
             // client.print(RTC.month, DEC);
              switch (RTC.month)                     
              {
              case 1: client.print("Января"); break;
              case 2: client.print("Февраля"); break;
              case 3: client.print("Марта"); break;
              case 4: client.print("Апреля"); break;
              case 5: client.print("Мая"); break;
              case 6: client.print("Июня"); break;
              case 7: client.print("Июля"); break;
              case 8: client.print("Августа"); break;
              case 9: client.print("Сентября"); break;
              case 10: client.print("Октября"); break;
              case 11: client.print("Ноября"); break;
              case 12: client.print("Декабря"); break;
}            
              client.print(" ");
              client.print(RTC.year, DEC);         
              client.print(" ");
              client.print(",");
              switch (RTC.dow)                     
{
              case 0: client.print("Воскресенье"); break;
              case 1: client.print("Понедельник"); break;
              case 2: client.print("Вторник"); break;
              case 3: client.print("Среда"); break;
              case 4: client.print("Четверг"); break;
              case 5: client.print("Пятница"); break;
              case 6: client.print("Суббота"); break;
}
              client.println("</h2>");
              client.println("<br>");
                    client.println("<h3>");
              client.print("Температура");
              client.print(" = ");
              client.print(celsius);
              client.write(byte(0));
              client.print("°C");
                 client.println("</h3>");
              client.print(", ");
           
              if (celsius>maxF) {maxF=celsius;}  //check for max temp
  	if (celsius<minF) {minF=celsius;}  //check for min temp
  	client.print("Макс=");
  	client.print(maxF);
        client.print("°C ");
  	client.print("Мин=");
  	client.print(minF);
  	client.print("°C ");
        client.print(", Датчик№");
        client.print(ics); //показывает номер датчика
client.println("<br>");
 if ( digitalRead(ledPin) == HIGH ) {

      client.print ("Подсветка Включена");

  }
  if ( digitalRead(ledPin) == LOW ) {

      client.print ("Подсветка Выключена");

}
client.println("<br>");
client.print("Уровень света:");
client.print(sensorValue);
client.println("<br>");
client.print("Uptime: ");
client.print(millis()/60000);//Display the Uptime since last Start/Reset and System version.
client.print(" Min");
 
   //     client.print("Uptime: ");
   // client.println(uptime/60000);
       client.println("<br>");
       client.print("IP адрес: ");
       client.print(Ethernet.localIP());
            client.println("<br>");
             client.print("Ver. v 0.0.6 ");





}
            client.println("</center>");
            client.println("</html>");
            break;

  }
}

      delay(500);
      client.stop();
      Serial.println("client disonnected");
    }
  }
}

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Ошибка в логике.
Допустим, сейчас 20 часов. Свет автоматически включается (строка 97). И тут же гасится (строка 109, ledOn в состоянии low). Естественно, реле не успевает отработать за эти микросекунды, поэтому визуально ничего не происходит.
По этой же причине днём не удастся включить свет кнопкой - он тут же будет гаситься, потому что часы говорят: "День. Пин должен быть в Low".

iwizard7
iwizard7 аватар
Offline
Зарегистрирован: 30.04.2013

Tomasina пишет:
Ошибка в логике. Допустим, сейчас 20 часов. Свет автоматически включается (строка 97). И тут же гасится (строка 109, ledOn в состоянии low). Естественно, реле не успевает отработать за эти микросекунды, поэтому визуально ничего не происходит. По этой же причине днём не удастся включить свет кнопкой - он тут же будет гаситься, потому что часы говорят: "День. Пин должен быть в Low".

ну да, точно, получается так, может быть посоветуете как правильно сделать ?

jane Jack
Offline
Зарегистрирован: 08.10.2013

может как то так ловить?



#include <DS1307new.h> // for clock
#include <Wire.h> // for i2c protocol
#include <OneWire.h> // for DS18B20
#include <LiquidCrystal_I2C.h> // for 1602
#include <SPI.h>
#include <Ethernet.h>
boolean lastButton = LOW; // переменная для хранения состояния кнопки
boolean ledOn = false;    //
boolean currentButton = LOW; //
float maxF=0, minF=212; //переменные для макс и мин температуры
OneWire  ds(6);  // on pin 10 (a 4.7K resistor is necessary)  
int ledPin = 8;  // pin for LED
int LedStatus = 0;   // показывает статус светодиода на страничке
int sensorPin = A0;  // датчик света
const int buttonPin = 2;      // номер входа, подключенный к кнопке
int buttonState = 0;          // переменная для хранения состояния кнопки
unsigned int sensorValue = 0; // цифровое значение фоторезистора
LiquidCrystal_I2C lcd(0x20,16,2); // 0x20 is adresss for LCC 16x2
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC адрес
IPAddress ip(192,168,2,120); // IP адрес
EthernetServer server(80);   // Порт WEB сервера
byte grad[8] = { // рисует значек градуса
  B01110,
  B10001,
  B10001,
  B01110,
  B00000,
  B00000,
  B00000,
};

int ics =0; //count number of sensor

void setup(){
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
   
  Serial.begin(9600);  

  lcd.init(); 
  lcd.backlight(); //backlight is now ON
  // set up the LCD's number of columns and rows: 
  lcd.createChar(0, grad);
  lcd.begin(16, 2);
  /* Print a logo message to the LCD.
   lcd.print("AQUACONTROLLER");  
   lcd.setCursor(0, 1);
   lcd.print("by iWizard");
   delay (2500);
   lcd.clear();
   */
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

}

//////////////////////DEBOUNCE//////////////////////
boolean debounce(boolean last)
{
boolean current = digitalRead(buttonPin);
if (last != current)
{
delay(5);
current = digitalRead(buttonPin);
}
return current;
}
////////////////////////////////////////////////////


void loop(){
  sensorValue = analogRead(sensorPin);  // считываем значение с фоторезистора 
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius;

  if ( !ds.search(addr)) {
    // lcd.clear();   
    lcd.setCursor(0, 1);
    //   lcd.print("doar ");
    //   lcd.print(ics);
    //  lcd.print(" senzor(i)");    
    ds.reset_search();
    ics=0;


    if (RTC.hour == 19 && RTC.minute == 0 && RTC.second == 0) ledOn = true; //устанавливаем время и включаем свет
    if (RTC.hour == 23 && RTC.minute == 0 && RTC.second == 0) ledOn = false; // устанавливаем время и выключаем свет

//////////Включаем и выключаем свет кнопкой///////////
   currentButton = debounce(lastButton);
  
 if (lastButton == LOW && currentButton == HIGH)
  {
   ledOn = !ledOn;
   }
 lastButton = currentButton;

digitalWrite(ledPin, ledOn);
///////////////////////////////////////////////////// 
///----------------------------- начало кода часов -----------------------------///

    RTC.getTime();
    if (RTC.hour < 10)                   
    {
      Serial.println();
      Serial.print("0");
      Serial.print(RTC.hour, DEC);
    }
    else
    {
      Serial.print(RTC.hour, DEC);
    }

    Serial.print(":");

    if (RTC.minute < 10) Serial.print("0");
    Serial.print(RTC.minute, DEC);

    Serial.print(":");
    if (RTC.second < 10) Serial.print("0");
    Serial.print(RTC.second, DEC);


    Serial.print(" ");
    if (RTC.day < 10) Serial.print("0");
    Serial.print(RTC.day, DEC);


    Serial.print("-");
    if (RTC.month < 10) Serial.print("0");
    Serial.print(RTC.month, DEC);  
    Serial.print("-");
    Serial.print(RTC.year, DEC);         
    Serial.print(" ");
    Serial.print("-");
    switch (RTC.dow)                     
{
    case 0: Serial.print("SUN "); break;
    case 1: Serial.print("MON "); break;
    case 2: Serial.print("TUE "); break;
    case 3: Serial.print("WED "); break;
    case 4: Serial.print("THU "); break;
    case 5: Serial.print("FRI "); break;
    case 6: Serial.print("SAT "); break;
}

Serial.print("Uptime: ");
Serial.print(millis()/60000);//Display the Uptime since last Start/Reset and System version.
Serial.print(" Min, ");
//int miliseconds = 9999999;
//printf("%d hours, %d minutes and %d seconds\n", (int) miliseconds / (1000 * 60 * 60), (int) miliseconds / (1000 * 60), (int) miliseconds / 1000);


    ics++; 

    ds.reset();
    ds.select(addr);
    ds.write(0x44, 1);        // start conversion, with parasite power on at the end

    delay(750);     // maybe 750ms is enough, maybe not
    // we might do a ds.depower() here, but the reset will take care of it.

    present = ds.reset();
    ds.select(addr);    
    ds.write(0xBE);         // Read Scratchpad

    for ( i = 0; i < 9; i++) {           // we need 9 bytes
      data[i] = ds.read();
    }
    // Convert the data to actual temperature
    // because the result is a 16 bit signed integer, it should
    // be stored to an "int16_t" type, which is always 16 bits
    // even when compiled on a 32 bit processor.
    int16_t raw = (data[1] << 8) | data[0];
    if (type_s) {
      raw = raw << 3; // 9 bit resolution default
      if (data[7] == 0x10) {
        // "count remain" gives full 12 bit resolution
        raw = (raw & 0xFFF0) + 12 - data[6];
      }
    } 
    else {
      byte cfg = (data[4] & 0x60);
      // at lower res, the low bits are undefined, so let's zero them
      if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
      else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
      else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
      //// default is 12 bit resolution, 750 ms conversion time
    }

 //   if (OneWire::crc8(addr, 7) != addr[7]) {
 //     lcd.print("CRC is not valid!");
 //     return;
 //   }

    celsius = (float)raw / 16.0;

    lcd.setCursor(0,0);
    lcd.print("Temp");
    lcd.print(" = ");
    lcd.print(celsius);
    lcd.write(byte(0));
    lcd.print("C");
    Serial.print(celsius);
    Serial.print("C, ");
    //вывод часов на дисплей//  
    lcd.setCursor(0, 1);
    if(RTC.hour<10)lcd.print(0);
    lcd.print(RTC.hour);

    lcd.print(":");
    //lcd.print( (RTC.second %2 )?" ":":"); //мигать двоеточием
    if(RTC.minute<10)lcd.print(0);
    lcd.print(RTC.minute);

    lcd.setCursor(10, 1); 
    switch (RTC.dow)                      // Friendly printout the weekday
    {
    case 0: lcd.print("SUN"); break;
    case 1: lcd.print("MON"); break;
    case 2: lcd.print("TUE"); break;
    case 3: lcd.print("WED"); break;
    case 4: lcd.print("THU"); break;
    case 5: lcd.print("FRI"); break;
    case 6: lcd.print("SAT"); break;
    }
    lcd.print("-"); 
    lcd.print(RTC.day);
  Serial.print("Light Sensor: ");   
  Serial.print(sensorValue, DEC);     // вывод данных с фоторезистора (0-1024)
  Serial.println("");                 // возврат каретки 

    // listen for incoming clients
    EthernetClient client = server.available();
    if (client) {
      Serial.println("new client");
      // an http request ends with a blank line
      boolean currentLineIsBlank = true;
      while (client.connected()) {
        if (client.available()) {
          char c = client.read();
          Serial.write(c);
          // if you've gotten to the end of the line (received a newline
          // character) and the line is blank, the http request has ended,
          // so you can send a reply
          //if (c == '\n' && currentLineIsBlank) {
            // send a standard http response header
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println("<head> ");
            client.println("<meta http-equiv=Content-Type content=text/html; charset=utf-8/>");
            client.println("<title> Arduino :: Акваконтролеер</title>");
            client.println("</head> ");
            client.println("<body bgcolor=\"#9bbad6\">"); // цвет фона
            client.println("Connection: close");  // the connection will be closed after completion of the response
            client.println("Refresh: 10");  // refresh the page automatically every 5 sec
            client.println();
            client.println("<!DOCTYPE HTML>");
            client.println("<html>");
            client.println("<center>");
            // output the value of each analog input pin
            for (int analogChannel = 0; analogChannel < 1; analogChannel++) {
              int sensorReading = analogRead(analogChannel);
             client.println("<H1>");
              client.print(RTC.hour, DEC);
              client.print(":");
              if (RTC.minute < 10) client.print("0");
              client.print(RTC.minute, DEC);

              client.println("<br>");
              client.println("</h1>");
            client.println("<h2>");
              if (RTC.day < 10) client.print("0");
              client.print(RTC.day, DEC);


              client.print(" ");
             // if (RTC.month < 10) client.print("0");
             // client.print(RTC.month, DEC);
              switch (RTC.month)                     
              {
              case 1: client.print("Января"); break;
              case 2: client.print("Февраля"); break;
              case 3: client.print("Марта"); break;
              case 4: client.print("Апреля"); break;
              case 5: client.print("Мая"); break;
              case 6: client.print("Июня"); break;
              case 7: client.print("Июля"); break;
              case 8: client.print("Августа"); break;
              case 9: client.print("Сентября"); break;
              case 10: client.print("Октября"); break;
              case 11: client.print("Ноября"); break;
              case 12: client.print("Декабря"); break;
}            
              client.print(" ");
              client.print(RTC.year, DEC);         
              client.print(" ");
              client.print(",");
              switch (RTC.dow)                     
{
              case 0: client.print("Воскресенье"); break;
              case 1: client.print("Понедельник"); break;
              case 2: client.print("Вторник"); break;
              case 3: client.print("Среда"); break;
              case 4: client.print("Четверг"); break;
              case 5: client.print("Пятница"); break;
              case 6: client.print("Суббота"); break;
}
              client.println("</h2>");
              client.println("<br>");
                    client.println("<h3>");
              client.print("Температура");
              client.print(" = ");
              client.print(celsius);
              client.write(byte(0));
              client.print("°C");
                 client.println("</h3>");
              client.print(", ");
           
              if (celsius>maxF) {maxF=celsius;}  //check for max temp
  	if (celsius<minF) {minF=celsius;}  //check for min temp
  	client.print("Макс=");
  	client.print(maxF);
        client.print("°C ");
  	client.print("Мин=");
  	client.print(minF);
  	client.print("°C ");
        client.print(", Датчик№");
        client.print(ics); //показывает номер датчика
client.println("<br>");
 if ( digitalRead(ledPin) == HIGH ) {

      client.print ("Подсветка Включена");

  }
  if ( digitalRead(ledPin) == LOW ) {

      client.print ("Подсветка Выключена");

}
client.println("<br>");
client.print("Уровень света:");
client.print(sensorValue);
client.println("<br>");
client.print("Uptime: ");
client.print(millis()/60000);//Display the Uptime since last Start/Reset and System version.
client.print(" Min");
 
   //     client.print("Uptime: ");
   // client.println(uptime/60000);
       client.println("<br>");
       client.print("IP адрес: ");
       client.print(Ethernet.localIP());
            client.println("<br>");
             client.print("Ver. v 0.0.6 ");





}
            client.println("</center>");
            client.println("</html>");
            break;

  }
}

      delay(500);
      client.stop();
      Serial.println("client disonnected");
    }
  }
}
leshak
Offline
Зарегистрирован: 29.09.2011

Хм... представил что кто-то делая свои первые шаги и желая разобратся "как же работать с кнопками", наткнется на скетч из #212. Поседеет сразу.

iwizard7
iwizard7 аватар
Offline
Зарегистрирован: 30.04.2013

leshak пишет:

Хм... представил что кто-то делая свои первые шаги и желая разобратся "как же работать с кнопками", наткнется на скетч из #212. Поседеет сразу.

Извиняюсь, не хотел никого напугать :))) просто я сам еще новичек в общении с ардуино, и потребовался совет именно по кнопке

jane Jack
Offline
Зарегистрирован: 08.10.2013

а скетч то проверил? я его в блокноте правил, так как у меня сейчас не платы не среды нет .

leshak
Offline
Зарегистрирован: 29.09.2011

nestandart пишет:

Очень не советую использовать функцию pulseIn для данных целей (да и вообще не советую).

Потому что эта функция использует все программные таймеры ардуино.
С функцией pulseIn НЕ будут работать
Tone()
Millis()
analogWrite()
Так же не будут работать сервоприводы.

Ох блин, в первый раз заметил  (сорри если уже обсудили, быстренько пробежался по ветке не нашел упоминаний).

Вообщем откуда взялась идея что " эта функция использует все программные таймеры ардуино", со всемы вытекающими из этого ужасами? В документации об этом ни слова. Да и зачем ей могли понадобится "все програмные таймеры?"  (ну хотя-бы исходи из логики что на разных дуинах и разное кол-во, а работает она на всех).

Заглянул в ее исходник (вдруг дока не полна):

unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
	// cache the port and bit of the pin in order to speed up the
	// pulse width measuring loop and achieve finer resolution.  calling
	// digitalRead() instead yields much coarser resolution.
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);
	uint8_t stateMask = (state ? bit : 0);
	unsigned long width = 0; // keep initialization out of time critical area
	
	// convert the timeout from microseconds to a number of times through
	// the initial loop; it takes 16 clock cycles per iteration.
	unsigned long numloops = 0;
	unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
	
	// wait for any previous pulse to end
	while ((*portInputRegister(port) & bit) == stateMask)
		if (numloops++ == maxloops)
			return 0;
	
	// wait for the pulse to start
	while ((*portInputRegister(port) & bit) != stateMask)
		if (numloops++ == maxloops)
			return 0;
	
	// wait for the pulse to stop
	while ((*portInputRegister(port) & bit) == stateMask) {
		if (numloops++ == maxloops)
			return 0;
		width++;
	}

	// convert the reading to microseconds. The loop has been determined
	// to be 20 clock cycles long and have about 16 clocks between the edge
	// and the start of the loop. There will be some error introduced by
	// the interrupt handlers.
	return clockCyclesToMicroseconds(width * 21 + 16); 
}

Никаких таймеров не видно. Обычная блокирующая функция. "Зла" от нее, ровно столько же сколько и от delay(). Поэтому можно согласится что "нежелательно использовать" (когда во время ожидания импульса нужно еще чем-нибудь заниматся), но этим ее "нежелательность" и ограничивается. По большому счету это и есть тот же самый delay(), только который прерывается состоянием пина и может сказать "когда его прервали".

mikov
Offline
Зарегистрирован: 01.05.2013

Добрый день !  Прошу помощи,так как в программировании совсем новичок. Пытаюсь сделать подобие умного дома, необходимо чтобы выключатель мог поочередно включать несколько разных светильников, воспользовался вот этим примером

int regim=1; 
 int flag=0; 

 void setup()   
 { 
 pinMode(4,OUTPUT);    
 pinMode(5,OUTPUT);    
       
 } 

 void loop() 

 { 
       
     if(digitalRead(12)==HIGH&&flag==0)//если кнопка нажата   
     // и перемення flag равна 0 , то ... 
     { 
       regim++;   
       flag=1; 
         
        //это нужно для того что бы с каждым нажатием кнопки 
        //происходило только одно действие 
        // плюс защита от "дребезга"  100% 
          
        if(regim>4)//ограничим количество режимов 
        { 
          regim=1;//так как мы используем только одну кнопку, 
                    // то переключать режимы будем циклично 
        } 
       
     } 
       
      if(digitalRead(12)==LOW&&flag==1)//если кнопка НЕ нажата 
     //и переменная flag равна - 1 ,то ... 
     { 
          
        flag=0;//обнуляем переменную "knopka" 
     } 
      
       
       
    if(regim==1)//первый режим 
    { 
      digitalWrite(4,LOW);//выключаем все светодиоды 
      digitalWrite(5,LOW); 
        
        
      //здесь может быть любое ваше действие 
    } 
    if(regim==2)//второй режим 
    { 
      digitalWrite(4,HIGH);//включае красный светодиод 
      digitalWrite(5,LOW); 
        
      //здесь может быть любое ваше действие 
    } 
      
    if(regim==3)//третий режим 
    { 
        
      digitalWrite(5,HIGH);//включае зеленый светодиод 
      digitalWrite(4,LOW); 
        
        
      //здесь может быть любое ваше действие 
    } 
      
    if(regim==4)//четвертый режим 
    { 
        
      digitalWrite(4,HIGH);//включаем светодиоды одновременно 
      digitalWrite(5,HIGH); 
      //здесь может быть любое ваше действие 
    } 
      
 } 

при работе с кнопкой на макетной плате все работает ок, но при подключении кнопочного выключателя проявляется дребезг и система работает неустойчиво. Подскажите пожалуйста, как повысить надежность срабатывания и ввести в этот скетч кнопку "выключить всё" ? Заранее благодарю !!!

P.S  Ищу также, не безвозмездно, специалиста,который на основе моих пожеланий по созданию умного дома, поможет написать программу и параллельно обучит меня минимальным основам программирования на ардуино,для возможности внесения изменений в работу программы при дальнейшей эксплуатации системы.

vvadim
Offline
Зарегистрирован: 23.05.2012
 
Так у вас в первом режиме светики не горят
wOOlf
Offline
Зарегистрирован: 21.04.2014

Подскажите каким образом можно подсчитать количество нажатий кнопки в течении времени, т.е для выполнения действия необходимо трижды нажать на кнопку в течении 3 секунд. причем таймер запускается первым нажатем этой же кнопки.
если подумать:
 

const int ledPin =  5;      // the number of the LED pin
#define unlock 3               //пин сигнала unlock

int ledState = LOW;             
unsigned long previousMillis = 0;
unsigned long currentMillis;
long interval = 2000;          
int i=0;
void setup() {
    pinMode(ledPin, OUTPUT);      
}

void loop()
  {
    if(digitalRead(3)==HIGH)//
  { i=i++;
  delay(500);
  currentMillis = millis();
  previousMillis = currentMillis;//запоминаем момент первого нажатия
  while(currentMillis - previousMillis < interval)// считаем 3 секунды 
    {currentMillis = millis();
      if (digitalRead(3)==HIGH)
     {i=i++;
     delay (500);
     }
     }
    if (i==3)
    {digitalWrite(ledPin, HIGH);
    i=0;
    }
    else 
    {digitalWrite(ledPin, LOW);
     i=0;
    }

 

flamantino
Offline
Зарегистрирован: 13.06.2014

Вопрос пО Кнопкам- Возникла Проблема Подключения — Проект С Купюроприемником NV 9 — Кнопка Отказывается реагировать В Железе ))-это видимо связано как то

attachInterrupt ( функция по счету импульсов с купюроприемника ) -программа компилируется но кнопка не работает — Спасибо 

flamantino
Offline
Зарегистрирован: 13.06.2014
const int moneyInt=0;
volatile float moneyValue = 0.00;
int moneyChange = 0;
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); 
int relayPin = 4 ;
int switchPin = 14 ;
unsigned long time;
void setup()
{
{
 pinMode(switchPin,INPUT);
  pinMode(relayPin,OUTPUT);
  digitalWrite(relayPin,HIGH);
}
{
  Serial.begin(9600);  
  attachInterrupt(moneyInt, moneyInserted, RISING);
  delay(3000);
 lcd.init();
  lcd.clear();  
  lcd.backlight();
  lcd.print("A   Q   U   A");
  
  }
  }

void moneyInserted()    
{
  moneyValue = moneyValue + 1;
  moneyChange = 1;  
  }
  void(*resetFunc) (void) = 0;
  void loop()
  {
  
    time = millis();
 delay (5000); 

  if ( byte (moneyValue) >3 && (digitalRead(switchPin)==HIGH) )
   {
     digitalWrite(relayPin, LOW);
    time = millis();
   lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Privet");
    delay (5000); 
    {
  resetFunc();} 
  delay(5000);
   
     digitalWrite(relayPin, HIGH);   
 }
    
{
  if(moneyChange == 1)  
  {
    moneyChange = 0;  
    
     Serial.print("Credit: grivna");
    Serial.println(moneyValue); 
    lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Grivna");
      lcd.setCursor(2,1);
      lcd.print(moneyValue);

      }
}
}

 

flamantino
Offline
Зарегистрирован: 13.06.2014

написал и сообразил как сделать - Полезная вещь иногда посмотреть со стороні )))Вот віложил может кому пригодится - Всем спасибо

leshak
Offline
Зарегистрирован: 29.09.2011

Не понятно, как баги конкретного проекта относятся к теме "работа с кнопками, помощь новичку". 

Или теперь любой проект, который не работает должен и имеет в своем составе кнопку должен попадать сюда? Как потом новичку, который хочет разобратся с принйципами работы с кнопками потом учится на базе этого? Со всеми этим lcd и 

Почему не отдельной темой? Про купюроемник. Где как-то подробно рассказать про логику, что куда подключено, что ожидается, что происходит и т.д. и т.п.

flamantino
Offline
Зарегистрирован: 13.06.2014

вы Правы - Создам новую тему

aleksej_neh
Offline
Зарегистрирован: 26.06.2014

начал писать скеч и совсем запутался!

скажи те как кнопками - и + изменить значение переменной и вывести значение на 1602

vvadim
Offline
Зарегистрирован: 23.05.2012

aleksej_neh пишет:

начал писать скеч и совсем запутался!

скажи те как кнопками - и + изменить значение переменной и вывести значение на 1602

Создайте тему в разделе Программирование, а перед этим полазьте по форуму , этот вопрос уже не раз обсуждался.

Здесь тема о кнопках!

Gvined
Offline
Зарегистрирован: 25.07.2014

вариан с переменной flag. удачно проходит компиляцию а на ардуине не работает диод горит в самом начале и при нажатии на кнопку загорается чуть ярче почему ?

01 int flag=0;
02  
03 void setup()   
04 {
05        
06     pinMode(13, OUTPUT);        
07       
08         
09 }
10  
11 void loop()
12  
13 {
14         
15      if(digitalRead(8)==HIGH&&flag==0)//если кнопка нажата   
16      // и перемення flag равна 0 , то ...
17      {
18            
19        digitalWrite(13,!digitalRead(13));
20        flag=1;
21         //это нужно для того что бы с каждым нажатием кнопки
22         //происходило только одно действие
23         // плюс защита от "дребезга"  100%
24         
25      }
26         
27       if(digitalRead(8)==LOW&&flag==1)//если кнопка НЕ нажата
28      //и переменная flag равна - 1 ,то ...
29      {
30            
31         flag=0;//обнуляем переменную flag
32      }
33 }

 

подключил кнопку с одного конца на 5v ,а со второго на 8 вход и второй провод от этой же лапки кнопки через резистор на земле

пробовал даже ставить перемычку на 8 вход и GND и светодиод горит в самом начале что не так ?

Oleg.L.
Offline
Зарегистрирован: 19.08.2014

Здравствуйте, Дмитрий. Я Вас заочно знаю по многочисленным роликам в You Tube с Вашим опытом не откажите в помощи. Есть скетч в котором четыре светодиода включаются и выключаются от своих кнопок. На каждый  светодиод по одной кнопке. Все прекрасно работает, но нужно, чтобы одновременно с включением одного из светодиодов, отключался любой другой светодиод, если он был включен раньше. Проще говоря - взаимоотключение друг друга. Может есть другой вариант скетча, главное чтобы соблюдался алгоритм:

1. Скетч на четыре светодиода и четыре кнопки

2. Включение и отключение каждого светодиода  своей  одной кнопкой

3. Невозможность одновременного включения двух и более светодиодов (взаимоотключение)

Заранее поблагодарю. Пожалуйста подсобите.

Вот скетч.

#define knopka1 1
#define lampa1 2

#define knopka2 3
#define lampa2 4

#define knopka3 5
#define lampa3 6

#define knopka4 7
#define lampa4 8
 
bool statuslamp1 = 1;
bool statusknop1 = 0;

bool statuslamp2 = 1;
bool statusknop2 = 0;

bool statuslamp3 = 1;
bool statusknop3 = 0;

bool statuslamp4 = 1;
bool statusknop4 = 0;

 
void setup()

{
 pinMode(knopka1, INPUT);
 pinMode(lampa1, OUTPUT);
 
 pinMode(knopka2, INPUT);
 pinMode(lampa2, OUTPUT);
 
 pinMode(knopka3, INPUT);
 pinMode(lampa3, OUTPUT);
 
 pinMode(knopka4, INPUT);
 pinMode(lampa4, OUTPUT);
 
 
}

void loop()

//========включить-отключить нагрузку  кнопкой 1
{
 
 bool AAAAA1 = digitalRead(knopka1);
 if (AAAAA1 && !statusknop1)
 {
 statuslamp1 = !statuslamp1;
 delay(10);
 }
 statusknop1 = AAAAA1;
 digitalWrite(lampa1, statuslamp1);

//========включить-отключить нагрузку  кнопкой 2
 
 bool AAAAA2 = digitalRead(knopka2);
 if (AAAAA2 && !statusknop2)
 {
 statuslamp2 = !statuslamp2;
 delay(10);
 }
 
 statusknop2 = AAAAA2;
 digitalWrite(lampa2, statuslamp2);

//=========включить-отключить нагрузку  кнопкой 3

 bool AAAAA3 = digitalRead(knopka3);
 if (AAAAA3 && !statusknop3)
 {
 statuslamp3 = !statuslamp3;
 delay(10);
 }
 statusknop3 = AAAAA3;
 digitalWrite(lampa3, statuslamp3);

 //======включить-отключить нагрузку  кнопкой 4

 bool AAAAA4 = digitalRead(knopka4);

 if (AAAAA4 && !statusknop4)
 {
 statuslamp4 = !statuslamp4;
 delay(10);
 }
 statusknop4 = AAAAA4;
 digitalWrite(lampa4, statuslamp4);
 
 
 
}
 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

maksim пишет:

nestandart пишет:
В ардуино есть встроенные подтягивающие резисторы (pull-up) которые можно включить программно, но я не советую их использовать.
А я наоборот советую и рекомендую их использовать, потому как они именно для этого и предназначены.

это 20 kOm, который встроенный.... моя думает - что нано рассчитать ентот резюк ! попал в 20 kOm - подключай встроенный, не попал - вешай dytiyvq !

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

пардон... ВЕШАЙ ВНЕШНИЙ !

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

БЛИИИИИИИИИИИИИИИН ! поенахали..... блин.... к нам в Белокаменную... ( в Северную Столицу ) ( в Киев )

миня ровняли ( не долго ) по вставке кода в тему... изучите уж 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

nestandart пишет:

>>а про это где можно подробнее почитать? Если я правильно понимаю, то это 3,4в на первой кнопке? Как вообще этот диапазон вычисляется или есть какие-то табличные значения?<<

Да это 3.4в . Если вы имеете в виду диапазон АЦП, то это от 0 до 1023 . Что соответствует напряжению от 0 до 5в. Например значение 512 это 2.5в.

А вот вам конкретый множитель - 0.0048828125. Если умножить значение пина АЦП на этоу цифру то получите точное напряжение в вольтах.

 

эта тема обсуждена до мозга костей  ИЛИ до костей мозга - 0 = 0 V , 1023 = 5 / 1024 *1023 = 4.995

jane Jack
Offline
Зарегистрирован: 08.10.2013

Олег, а может лучше будет вот этот вариант?

const int pin1 = 1;     //кнопка1
const int led1 =  11;   //светодиод1
const int pin2 = 2;     //кнопка2
const int led2 =  12;   //светодиод2
const int pin3 = 3;     //кнопка3
const int led3 =  13;   //светодиод3
const int pin4 = 4;     //кнопка4
const int led4 =  14;   //светодиод4
long previousMillis = 0;
int val1=0; 
int val2=0; 
int val3=0; 
int val4=0;
void setup()
{  pinMode(led1, OUTPUT);  // определяет pin на которой подключен led1 как выход
   pinMode(led2, OUTPUT);  // определяет pin на которой подключен led2 как выход
   pinMode(led3, OUTPUT);  // определяет pin на которой подключен led3 как выход
   pinMode(led4, OUTPUT);  // определяет pin на которой подключен led4 как выход
   pinMode(pin1, INPUT_PULLUP);  // определяет pin1 как вход с внутренней подтяжкой
   pinMode(pin2, INPUT_PULLUP);  // определяет pin2 как вход с внутренней подтяжкой
   pinMode(pin3, INPUT_PULLUP);  // определяет pin1 как вход с внутренней подтяжкой
   pinMode(pin4, INPUT_PULLUP);  // определяет pin2 как вход с внутренней подтяжкой
  }
  void loop() {
    if  (digitalRead(pin1) == LOW ){    //если pin1 включили,
     if (millis() -previousMillis >100) //то ждем 100мс для     
     {previousMillis = millis();        //отсечки дребезга контактов
        val1++;}}                       // и в переменную val1 прибавим один
     else 
     {val1=0;}
     if(val1>=5){ 
       if (digitalRead(led2) == HIGH)  //проверяем led2  
         {digitalWrite(led2,LOW);}     // и если включен выключаем
       if (digitalRead(led3) == HIGH)  //проверяем led3  
         {digitalWrite(led3,LOW);}     // и если включен выключаем
       if (digitalRead(led4) == HIGH)  //проверяем led4  
         {digitalWrite(led4,LOW);}     // и если включен выключаем
       digitalWrite(led1,!digitalRead(led1));//инвертируем состояние пина 
        val1=0;}

    if  (digitalRead(pin2) == LOW ){    //если pin2 включили,
     if (millis() -previousMillis >100) //то ждем 100мс для     
     {previousMillis = millis();        //отсечки дребезга контактов
        val2++;}}                       // и в переменную val2 прибавим один
     else 
     {val2=0;}
     if(val2>=5){ 
       if (digitalRead(led1) == HIGH)  //проверяем led1  
         {digitalWrite(led1,LOW);}     // и если включен выключаем
       if (digitalRead(led3) == HIGH)  //проверяем led3  
         {digitalWrite(led3,LOW);}     // и если включен выключаем
       if (digitalRead(led4) == HIGH)  //проверяем led4  
         {digitalWrite(led4,LOW);}     // и если включен выключаем
      digitalWrite(led2,!digitalRead(led2));//инвертируем состояние пина 
        val2=0;}
        
    if  (digitalRead(pin3) == LOW ){    //если pin3 включили,
     if (millis() -previousMillis >100) //то ждем 100мс для     
     {previousMillis = millis();        //отсечки дребезга контактов
        val3++;}}                       // и в переменную val3 прибавим один
     else 
     {val3=0;}
     if(val3>=5){ 
       if (digitalRead(led2) == HIGH)  //проверяем led2  
         {digitalWrite(led2,LOW);}     // и если включен выключаем
       if (digitalRead(led1) == HIGH)  //проверяем led1  
         {digitalWrite(led1,LOW);}     // и если включен выключаем
       if (digitalRead(led4) == HIGH)  //проверяем led4  
         {digitalWrite(led4,LOW);}     // и если включен выключаем
       digitalWrite(led3,!digitalRead(led3));//инвертируем состояние пина 
        val3=0;}
        
    if  (digitalRead(pin4) == LOW ){    //если pin4 включили,
     if (millis() -previousMillis >100) //то ждем 100мс для     
     {previousMillis = millis();        //отсечки дребезга контактов
        val4++;}}                       // и в переменную val4 прибавим один
     else 
     {val4=0;}
     if(val4>=5){ 
       if (digitalRead(led2) == HIGH)  //проверяем led2  
         {digitalWrite(led2,LOW);}     // и если включен выключаем
       if (digitalRead(led3) == HIGH)  //проверяем led3  
         {digitalWrite(led3,LOW);}     // и если включен выключаем
       if (digitalRead(led1) == HIGH)  //проверяем led1  
         {digitalWrite(led1,LOW);}     // и если включен выключаем
       digitalWrite(led4,!digitalRead(led4));//инвертируем состояние пина 
        val4=0;}

  }
    
  

 

jane Jack
Offline
Зарегистрирован: 08.10.2013

Gvined пишет:

вариан с переменной flag. удачно проходит компиляцию а на ардуине не работает диод горит в самом начале и при нажатии на кнопку загорается чуть ярче почему ?

 

подключил кнопку с одного конца на 5v ,а со второго на 8 вход и второй провод от этой же лапки кнопки через резистор на земле

пробовал даже ставить перемычку на 8 вход и GND и светодиод горит в самом начале что не так ?

 

 

Gvined проблема в самом коде.

у меня этот код не спасал от дребезга контактов.

Oleg.L.
Offline
Зарегистрирован: 19.08.2014

 Большое спасибо, надо попробовать.  Обязательно отпишусь по результатам.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

кнопки можно подсоединять через К555ТР2 ( четыре RS-триггера )... один корпус К555ТР2 , восемь резисторов по 10 kOm , четыре кнопки ( НО - три контакта ).... где есть возможность поставить НЗ-НР-Общ-кнопки - всегда ставлю ТР2.... а в коде про дребезг можно забыть зато :) 

Oleg.L.
Offline
Зарегистрирован: 19.08.2014

возможно тоже вариант.надо пробовать, и смотреть как будет работать. Благодарю за дельные советы.

хотя у меня будут кнопки только с НО контактами, видимо, триггеры придется отставить...

Oleg.L.
Offline
Зарегистрирован: 19.08.2014

??

Oleg.L.
Offline
Зарегистрирован: 19.08.2014

Здравствуйте, jane Jack. Сегодня проверил работу программы. Вполне стабильно работает. но есть один нюанс: если удерживать любую кнопку нажатой то светодиод мигает, а если нажать одновременно две и более кнопок светодиоды начинают загораться по очереди. А можно сделать так, чтобы состояние светодиода изменялось один раз   только либо при нажатии или при отпускании и не мигали. и не включались все при удержании нескольких кнопок?  Если не получится отпишитесь, пож-та. ОК?

jane Jack
Offline
Зарегистрирован: 08.10.2013

Олег, по пробуй убрать матиматику из скетча. замени val++ на val=1. А в сравнении val>=5 замени на val==1. И эксперементируй с таймером 

if (millis() -previousMillis >100) //то ждем 100мс для 

думаю можно поднять планку примерно до 300 это около 1/3 секунды. Хотя если это весь скеч, то можно не ловить проблему с таким таймером и написать на делей с использованием примера флаг описанные выше по этой теме. А вот при нажатии двух и более кнопок надо добавить проверку и о этой задаче я по думаю не сегодня. Может на неделе но не буду обещать.

Oleg.L.
Offline
Зарегистрирован: 19.08.2014

Спасибо большое. Буду эксперементировать. Вот ,  с помощью отзывчивых людей , можно двигаться дальше.

У меня это будет не весь скетч, а  фрагмент, который, благодаря тебе,  будет вставлен в общую программу. И, я думаю, что таймер заменить на  delay не желательно, дабы не затормозить обшее быстродействие скетча. Ведь у меня их там сколько-то встречается.  Хотя все равно надо посмотреть, может и с такой задержкой будет вполне нормально рабтать. Благодарю еще раз!!

salan
Offline
Зарегистрирован: 01.10.2014

Не подскажите код: Нужно придумать 2 световых эфекта и переключние между ними двумя кнопками. Буду бгодарен! 

vvadim
Offline
Зарегистрирован: 23.05.2012

Ну ты уж постарайся хотя бы эффекты придумать  и  хоть какой нибудь код состряпать чтоб кто то помог в дальнейшем...

salan
Offline
Зарегистрирован: 01.10.2014

void setup(){
  attachInterrupt (0, button1, RISING);
  attachInterrupt (1, button2, RISING);
  pinMode (13, OUTPUT);

}
void loop(){}
 void button1 () {  
  digitalWrite(13,HIGH); delay (500);
 digitalWrite(13,LOW); delay (500); }
 void button2 () {
  digitalWrite(13,HIGH); delay (1000);
  digitalWrite(13,LOW); delay (1000);
 }
 

salan
Offline
Зарегистрирован: 01.10.2014

кто сделает денег заплочу

1)Нипишите, счётчик с памятью при нажатии на кнопку число будет увеличиваться на на 1цу. За еденицы будет отвечать семисигментный индикатор, а за 10ки аналоговые выводы А0-А6. При перезагрузке контроллера значение должно оставаться в памяти и при нажатии на кнопку число продолжать увеличиваться.

3) Придумайте 2 светодиодных эффекта и настройку переключения между ними при помощи 2-х кнопок. Для работы можно использовать светодиоды с 4го по 13й.

2) Подключите семисегментный индикатор и напишите программу которая при нажатии на одну кнопку будет увеличивать состояние счётчика на 1, а при нажатии на вторую сбрасывать его в ноль

vvadim
Offline
Зарегистрирован: 23.05.2012
SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

карта 4276 0001 0001 5050 - переводи 500р.

1 - написал

3 - придумал

2 - подключил

ВСЁ - КАК ЗАКАЗАЛ ! Только для Вас ! 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

после оплаты КОД можно забрать здесЯ

http://www.arduino.ru/forum/programmirovanie/rabota-s-knopkami-v-pomoshc...

salan
Offline
Зарегистрирован: 01.10.2014

гарантии?

 

varistor
varistor аватар
Offline
Зарегистрирован: 03.02.2013
В дополнение к вышеизложенному, предлагаю очень простую схемку для подключения матричных клавиатур. Вариантов схем много, но такая позволяет использовать всего 1 аналоговый вход и 6 (либо 7) резисторов для 16 клавиш 4х4. Резисторы понадобятся всего двух номиналов, отличающихся в 4 раза. Резистор R7 можно использовать из подтяжки pullUp. При последовательном нажатии клавиш (1, 2, 3, А, 4, 5, 6, В ...) сопротивление между А1 и GND будет увеличиваться ровно на значение резисторов R1-R3 (на 1к в варианте на схеме). С резистором R7 они составляют делитель напряжения 5в.
 
Скетч, любезно предоставленный maksim, можно применить и для опроса матричной клавиатуры. В коде нужно только изменить в строке 01: NUM_KEYS на 16   и в строке 02:  {30, 150, 360, 535, 760}; прописать 16 значений порогов.  Значения порогов легко получить временно добавив в стороке  17:
 
  Serial.println(input, DEC);   
 
Запустив монитор COM-порта и понажимав все клавиши по очереди (1, 2, 3, А, 4, 5, 6, В ...) , получим ряд значений. Для надежности работы и устранения ошибок от дрейфа параметров, пороги следует выбирать в середине между значениями данной клавиши и следующей (средне арифметическое). Например, если для кнопки "1" получили 4, а для "2" - 216, то порог "1" будет 110.
 
Удачи!
 
#define NUM_KEYS 16
int  adc_key_val[NUM_KEYS] = {110, 284, 402, 482, 542, 595, 637, 670, 696, 720, 743, 761, 775, 790, 804, 916};
 
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  int key = get_key(A1);
  if(key) Serial.println(key, DEC);
  delay(500);
}

int get_key(int key_pin)
{
  int input = analogRead(key_pin); //Serial.println(input, DEC); 
  for(int k = 0; k < NUM_KEYS; k++) if(input < adc_key_val[k])  return k + 1;    
  return 0;
}

 

схема матричной клавиатуры

матричная клавиатура 4х4

 

 

Coolerr
Offline
Зарегистрирован: 30.06.2014

Блин, откуда такие номиналы 4кОм. Нет таких в стандартных рядах. Есть такие 3.6, 3.9, 4.7, 5.1

varistor
varistor аватар
Offline
Зарегистрирован: 03.02.2013

По сути дела это не номиналы. Это означает всего лишь, что резисторы R1-R3 и  R4-R6 должны отличаться друг от друга примерно в 4 раза. Мне не хотелось писать 1xR, 4xR. Разброс номиналов сопротивлений может достигать 20%. Причем совсем не обязательно д.б. 1к0 и 3к9. Допустимы сопротивления от 100 ом до 1 Мом. Крайности нежелательны. Возможные варианты: 1к6\6к8, 2к0\8к2, 5к6\22к и так далее.

Space-06
Offline
Зарегистрирован: 22.11.2014

Доброго всем времени суток уважаемые коллеги!

Столкнулся с такой проблемой: на первой странице приведен пример работы с кнопкой и режимами, так вот если в одном из режимов находится ШИМ (Плавное загорание Светодиода и его плавное отключение) то невозможно перейти на следующий за ним режим.

такое ощущение что кнопка не читается и цикл не видит ее изменение.

Каким образом можно выйти из положения?

Для примера приведу пример:

#define led 1
#define BUTTON 3
int val=0;
int old_val=0;
int state=0; 

void setup()
{
  pinMode(led,OUTPUT);
  pinMode(BUTTON,INPUT);
}

void LEDFade(){
    for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
    analogWrite(led, fadeValue);          
    delay(30);}
    delay(500); 
      for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
      analogWrite(led, fadeValue);          
      delay(30);}
      delay(500); 
}

void loop()
{
  val=digitalRead(BUTTON); //check status of pushbutton
  if((val==HIGH)&&(old_val==LOW)) //button pressed
  {
    state++; //increment state
    delay(10); //debounce consideration
    if(state>3) //want only 4 brightness options
    {
      state=1;
      delay(10);
    }
  }
  old_val=val;
  if(state==1)
  {
    analogWrite(led,0); //0 brightness
  }
  else if(state==2)
  {
    analogWrite(led,125);
    delay(1500);
    analogWrite(led,150);
    delay(1500);
    analogWrite(led,20);
    return;
  }
  else if(state==3)
  {
    analogWrite(led,255);
  }
}