Можно конечно и потенциометр подключить. Но он неудобен тем что для того чтобы установить его в какое либо положение нужно проскакать по предыдущим.
кнопки не решают проблемы практической невозможности мгновенной телепортации значения напряжения от 0 до, допустим 3,5В, минуя промежуточные значения - по любому значение напряжения будет повышаться от 0 до 3,5В, включая все кнопки в этом диапазоне.
Ну тогда можно и про скорость движения электронов поговорить.
О каких промежуточных значениях вы говорите ? Скорость переключения от 0 до нужного напряжения определяется рскоростью распространения электрического поля в проводе.
Если углубляться в такие дебри то да, переключение происходит не мгновенно. Оно длятся несколько пикосекунд.
А теперь посмотрите ( в справочных материалах) сколько времени занимает опрос пина АЦП.
О каких промежуточных значениях вы говорите ? Скорость переключения от 0 до нужного напряжения определяется рскоростью распространения электрического поля в проводе.
ок - проверю практически, теоретически - более чем уверен, что существует ненулевая вероятность срабатывания кнопок находящихся в диапазоне изменяемых напряжений.
Есть резистивные кнопки. Подключены к аналоговому пину. Ардуино в качестве HID клавиатуры.
Сейчас у меня при нажатии на кнопку отправляется только одно значение. Работает отлично, как и надо при одиночном нажатии.
Не могу понять как сделать чтобы при одиночном нажатии отправлялось одно действиие а при удержании другое. Например кнопка "следующий трек". При одиночном нажатии отправляла Remote.next() (следующий трек), а при удержании постоянно отправляла Remote.forward() (перемотка).
Вот какой скетч сейчас.
int buttonPin=6; //пин для резистивных кнопок
int data;
int flag=0;
void setup()
{
Keyboard.begin();
Serial.begin(9600);
}
void loop()
{
data=analogRead(buttonPin); //читаем значение нажатой кнопки
Serial.println(data); //для определения кодов нажатых кнопок на мониторе порта
//кнопка громкости +
if (data>=210 && data<=232 && flag==0) // нажата кнопка
{
Remote.increase();
Remote.clear();
flag=1;
}
//кнопка громкости -
if (data>=460 && data<=488 && flag==0) // нажата кнопка
{
Remote.decrease();
Remote.clear();
flag=1;
}
//кнопка следующий трек
if (data==0 && flag==0) // нажата кнопка
{
Remote.next();
Remote.clear();
flag=1;
}
//кнопка предидущий трек
if (data>=76 && data<=92 && flag==0) // нажата кнопка
{
Remote.previous();
Remote.clear();
flag=1;
}
//кнопка приглушения звука
if (data>=565 && data<=594 && flag==0) // нажата кнопка
{
Remote.mute();
Remote.clear();
flag=1;
}
//не нажата не одна из кнопок
if (data>=950 && data<=960 && flag==1)
{
flag=0;
}
}
Делаете таймер , который при нажатии на кнопку начинает отсчет времени и присваивает это значение переменной. При отпущеной кнопке переменная обнуляется.
А потом отслеживаете значение переменной. Если время нажатия превысило пороговое значение - удержание кнопки. Если нет (обнулилось) - короткое нажатие.
Делаете таймер , который при нажатии на кнопку начинает отсчет времени и присваивает это значение переменной. При отпущеной кнопке переменная обнуляется.
А потом отслеживаете значение переменной. Если время нажатия превысило пороговое значение - удержание кнопки. Если нет (обнулилось) - короткое нажатие.
Спасибо!!! Почти всё получилось. Вот только при нажатии и удержании кнопки "следующий трек", сначало переключается трек а потом начинается перемотка. Т.е. выполняется и условие строки 063 и условие строки 070. С другими кнопками аналогичная ситуация. А как сделать что бы при удержании не выполнялось условие 063?
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 >40)
{
previousMillis = millis();
val++;
}
}
else
{
val=0;
}
//кнопка громкости +
if (data>=210 && data<=232 && flag==0 && val>=1 && val<=3) //одиночное нажатие
{
Remote.increase(); //прибавить громкость на ед.
Remote.clear();
flag=1;
val=0;
}
else if (data>=210 && data<=232 && val>=4) // удержание
{
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;
}
else if (data>=460 && data<=488 && val>=4) //удержание
{
Remote.decrease(); //убавлять громкость до отпускания
Remote.clear();
val=0;
}
//кнопка следующий трек
if (data==0 && flag==0 && val>=1 && val<=5) //одиночное нажатие
{
Remote.next(); //следующий трек
Remote.clear();
flag=1;
val=0;
}
else if (data==0 && val>=6) //удержание
{
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;
}
else 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;
}
//не нажата не одна из кнопок
if (data>=950 && data<=960 && flag==1)
{
flag=0;
}
}
Прошу программистов помочь в очень простой для вас, практической задаче для уменьшения простоя лифта. Сегодня лифты напичканы электроникой, а элмеханик не всегда может локализовать неисправность – то ли электроника глючит (тогда жди пока наладчик приедет – бывает долго. Это я и есть) или в шахте непорядок. У меня есть самодельный стенд для полной проверки, собрал его на жесткой логике. Вот хочу для механиков собрать такую приблуду, чтобы меня меньше дергали – старенький я и сами меньше в шахте ползали.
Для начала информация:
В шахте лифта и на кабине расположены шунты, а на кабине -герконовые датчики. Основных датчиков три: VN, TO и VV. (Дал им имена для скетча). По последовательности появления этих сигналов , главный контроллер лифта определяет направление движения, местоположение кабины и обеспечивает точную остановку в датчике ТО.
VN - TO - VV -вниз VV - TO - VN -вверх
Задача : собрать с помощью Ардуино эмулятор движения кабины лифта для проверки главного контроллера в части работы узла местоположения кабины. Датчики – это три светодиода VN, TO и VV, подключенные к выходам 50,51 и 52 Они должны поочередно засвечиваться в зависимости от заданного направления.
Направление задают две кнопки , подключенные на выходы 30 и 31.
Собрал схемку – 3 светодиода с резисторами и две кнопки кподключил к МЕГА 2560, загрузил свой примитивный скетч – последовательность работает, но неправильно. Просьба помочь по двум вопросам:
1. при снятии сигнала на входе, цикл продолжается , а нужна немедленная остановка. И если он остановился, в момент, когда на выходе пина «1», то выход должен остаться в этом состоянии (запомнить эту «1»).??
2. Другой цикл движения не знаю как вставить. ?
// определяю назначение выходов и входов
int VN = 51; //датчик замедления вниз ( светодиод+резистор)
int TO = 50; // датчик точной остановки
int VV = 52; // датчик замедления вверх
int pinN = 31; // команда на включение привода кабины вниз ( кнопка и резистор дотяжки 15ком)
int pinV = 30; // команда на включение привода кабины вверх
int valN=0 ;
int valV=0;
void setup() {
pinMode(VN , OUTPUT);
pinMode(TO , OUTPUT);
pinMode(VV , OUTPUT);
pinMode(pinN, INPUT);
pinMode(pinV, INPUT);
}
void loop(){
valN = digitalRead(pinN);
valV = digitalRead(pinV);
if (val == 1) // поехали вверх, поочередно включаем светодиоды. имитируем вход -выход шунта из датчика. (потом эти выходы будут подключены ко входам проверяемого контроллера)
{
digitalWrite(VN, 1);
delay (2000);
digitalWrite(VN, 0);
digitalWrite(TO, 1);
delay (2000);
digitalWrite(TO, 0); //понимаю, что это примитивно., но не знаю других способов, без delay
МАКСИМ! Спасибо большое - сразу заработало. мне нужно время изучить, как ВЫ сделали.
У меня просто уже есть мега от внука- подарил ему на день рождения - получилось себе. Своим механикам, если все получится, дам схему на что-нить подешевле.
Это ведь начало задачи. Буду потом искат прогу для подсчета количества остановок по этим трем импульсам и вывода №этажа на семисегментный двустрочный индикатор. Может сразу мне и подскажите где посмотреть пример?
Всё так же как и было. При нажатии и удержании кнопки сначало проходит сигнал как при одиночном нажатии а потом как при удержании. Т.е. при нажатии идалнейшем удержании кнопки следующий трек отсылается сначала и 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;
}
}
если же первый код не закомментирован то включение по часам не срабатывает
весь код целиком :
#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");
}
}
}
Ошибка в логике.
Допустим, сейчас 20 часов. Свет автоматически включается (строка 97). И тут же гасится (строка 109, ledOn в состоянии low). Естественно, реле не успевает отработать за эти микросекунды, поэтому визуально ничего не происходит.
По этой же причине днём не удастся включить свет кнопкой - он тут же будет гаситься, потому что часы говорят: "День. Пин должен быть в Low".
Ошибка в логике. Допустим, сейчас 20 часов. Свет автоматически включается (строка 97). И тут же гасится (строка 109, ledOn в состоянии low). Естественно, реле не успевает отработать за эти микросекунды, поэтому визуально ничего не происходит. По этой же причине днём не удастся включить свет кнопкой - он тут же будет гаситься, потому что часы говорят: "День. Пин должен быть в 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.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");
}
}
}
Очень не советую использовать функцию 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(), только который прерывается состоянием пина и может сказать "когда его прервали".
Добрый день ! Прошу помощи,так как в программировании совсем новичок. Пытаюсь сделать подобие умного дома, необходимо чтобы выключатель мог поочередно включать несколько разных светильников, воспользовался вот этим примером
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 Ищу также, не безвозмездно, специалиста,который на основе моих пожеланий по созданию умного дома, поможет написать программу и параллельно обучит меня минимальным основам программирования на ардуино,для возможности внесения изменений в работу программы при дальнейшей эксплуатации системы.
Подскажите каким образом можно подсчитать количество нажатий кнопки в течении времени, т.е для выполнения действия необходимо трижды нажать на кнопку в течении 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;
}
вариан с переменной flag. удачно проходит компиляцию а на ардуине не работает диод горит в самом начале и при нажатии на кнопку загорается чуть ярче почему ?
Здравствуйте, Дмитрий. Я Вас заочно знаю по многочисленным роликам в You Tube с Вашим опытом не откажите в помощи. Есть скетч в котором четыре светодиода включаются и выключаются от своих кнопок. На каждый светодиод по одной кнопке. Все прекрасно работает, но нужно, чтобы одновременно с включением одного из светодиодов, отключался любой другой светодиод, если он был включен раньше. Проще говоря - взаимоотключение друг друга. Может есть другой вариант скетча, главное чтобы соблюдался алгоритм:
1. Скетч на четыре светодиода и четыре кнопки
2. Включение и отключение каждого светодиода своей одной кнопкой
3. Невозможность одновременного включения двух и более светодиодов (взаимоотключение)
>>а про это где можно подробнее почитать? Если я правильно понимаю, то это 3,4в на первой кнопке? Как вообще этот диапазон вычисляется или есть какие-то табличные значения?<<
Да это 3.4в . Если вы имеете в виду диапазон АЦП, то это от 0 до 1023 . Что соответствует напряжению от 0 до 5в. Например значение 512 это 2.5в.
А вот вам конкретый множитель - 0.0048828125. Если умножить значение пина АЦП на этоу цифру то получите точное напряжение в вольтах.
эта тема обсуждена до мозга костей ИЛИ до костей мозга - 0 = 0 V , 1023 = 5 / 1024 *1023 = 4.995
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;}
}
вариан с переменной flag. удачно проходит компиляцию а на ардуине не работает диод горит в самом начале и при нажатии на кнопку загорается чуть ярче почему ?
подключил кнопку с одного конца на 5v ,а со второго на 8 вход и второй провод от этой же лапки кнопки через резистор на земле
пробовал даже ставить перемычку на 8 вход и GND и светодиод горит в самом начале что не так ?
кнопки можно подсоединять через К555ТР2 ( четыре RS-триггера )... один корпус К555ТР2 , восемь резисторов по 10 kOm , четыре кнопки ( НО - три контакта ).... где есть возможность поставить НЗ-НР-Общ-кнопки - всегда ставлю ТР2.... а в коде про дребезг можно забыть зато :)
Здравствуйте, jane Jack. Сегодня проверил работу программы. Вполне стабильно работает. но есть один нюанс: если удерживать любую кнопку нажатой то светодиод мигает, а если нажать одновременно две и более кнопок светодиоды начинают загораться по очереди. А можно сделать так, чтобы состояние светодиода изменялось один раз только либо при нажатии или при отпускании и не мигали. и не включались все при удержании нескольких кнопок? Если не получится отпишитесь, пож-та. ОК?
Олег, по пробуй убрать матиматику из скетча. замени val++ на val=1. А в сравнении val>=5 замени на val==1. И эксперементируй с таймером
if (millis() -previousMillis >100) //то ждем 100мс для
думаю можно поднять планку примерно до 300 это около 1/3 секунды. Хотя если это весь скеч, то можно не ловить проблему с таким таймером и написать на делей с использованием примера флаг описанные выше по этой теме. А вот при нажатии двух и более кнопок надо добавить проверку и о этой задаче я по думаю не сегодня. Может на неделе но не буду обещать.
Спасибо большое. Буду эксперементировать. Вот , с помощью отзывчивых людей , можно двигаться дальше.
У меня это будет не весь скетч, а фрагмент, который, благодаря тебе, будет вставлен в общую программу. И, я думаю, что таймер заменить на delay не желательно, дабы не затормозить обшее быстродействие скетча. Ведь у меня их там сколько-то встречается. Хотя все равно надо посмотреть, может и с такой задержкой будет вполне нормально рабтать. Благодарю еще раз!!
В дополнение к вышеизложенному, предлагаю очень простую схемку для подключения матричных клавиатур. Вариантов схем много, но такая позволяет использовать всего 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;
}
По сути дела это не номиналы. Это означает всего лишь, что резисторы 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к и так далее.
Столкнулся с такой проблемой: на первой странице приведен пример работы с кнопкой и режимами, так вот если в одном из режимов находится ШИМ (Плавное загорание Светодиода и его плавное отключение) то невозможно перейти на следующий за ним режим.
такое ощущение что кнопка не читается и цикл не видит ее изменение.
"The analog pins also have pullup resistors, which work identically to pullup resistors on the digital pins. They are enabled by issuing a command such as
digitalWrite(A0, HIGH); // set pullup on analog pin 0 while the pin is an input.
Be aware however that turning on a pullup will affect the values reported by analogRead()."
Подтягиваю неподключенный А3 и читаю значение на нем analogRead. Ожидаю близко к 1023, но получаю 0.
В то же время digitalRead читает pullup правильно (HIGH). Что я неправильно делаю?
Оказалось, что если AVCC (pin 20 ATMega328) подтянут к +5В, то происходит такая ошибка. Отключил - работает правильно. Почему - пока не понятно, буду разбираться.
Можно конечно и потенциометр подключить. Но он неудобен тем что для того чтобы установить его в какое либо положение нужно проскакать по предыдущим.
кнопки не решают проблемы практической невозможности мгновенной телепортации значения напряжения от 0 до, допустим 3,5В, минуя промежуточные значения - по любому значение напряжения будет повышаться от 0 до 3,5В, включая все кнопки в этом диапазоне.
Вы это серьезно ?!
Ну тогда можно и про скорость движения электронов поговорить.
О каких промежуточных значениях вы говорите ? Скорость переключения от 0 до нужного напряжения определяется рскоростью распространения электрического поля в проводе.
Если углубляться в такие дебри то да, переключение происходит не мгновенно. Оно длятся несколько пикосекунд.
А теперь посмотрите ( в справочных материалах) сколько времени занимает опрос пина АЦП.
О каких промежуточных значениях вы говорите ? Скорость переключения от 0 до нужного напряжения определяется рскоростью распространения электрического поля в проводе.
ок - проверю практически, теоретически - более чем уверен, что существует ненулевая вероятность срабатывания кнопок находящихся в диапазоне изменяемых напряжений.
Здравствуйте. Подскажите пожалуйста.
Есть резистивные кнопки. Подключены к аналоговому пину. Ардуино в качестве HID клавиатуры.
Сейчас у меня при нажатии на кнопку отправляется только одно значение. Работает отлично, как и надо при одиночном нажатии.
Не могу понять как сделать чтобы при одиночном нажатии отправлялось одно действиие а при удержании другое. Например кнопка "следующий трек". При одиночном нажатии отправляла Remote.next() (следующий трек), а при удержании постоянно отправляла Remote.forward() (перемотка).
Вот какой скетч сейчас.
int buttonPin=6; //пин для резистивных кнопок int data; int flag=0; void setup() { Keyboard.begin(); Serial.begin(9600); } void loop() { data=analogRead(buttonPin); //читаем значение нажатой кнопки Serial.println(data); //для определения кодов нажатых кнопок на мониторе порта //кнопка громкости + if (data>=210 && data<=232 && flag==0) // нажата кнопка { Remote.increase(); Remote.clear(); flag=1; } //кнопка громкости - if (data>=460 && data<=488 && flag==0) // нажата кнопка { Remote.decrease(); Remote.clear(); flag=1; } //кнопка следующий трек if (data==0 && flag==0) // нажата кнопка { Remote.next(); Remote.clear(); flag=1; } //кнопка предидущий трек if (data>=76 && data<=92 && flag==0) // нажата кнопка { Remote.previous(); Remote.clear(); flag=1; } //кнопка приглушения звука if (data>=565 && data<=594 && flag==0) // нажата кнопка { Remote.mute(); Remote.clear(); flag=1; } //не нажата не одна из кнопок if (data>=950 && data<=960 && flag==1) { flag=0; } }Делаете таймер , который при нажатии на кнопку начинает отсчет времени и присваивает это значение переменной. При отпущеной кнопке переменная обнуляется.
А потом отслеживаете значение переменной. Если время нажатия превысило пороговое значение - удержание кнопки. Если нет (обнулилось) - короткое нажатие.
Делаете таймер , который при нажатии на кнопку начинает отсчет времени и присваивает это значение переменной. При отпущеной кнопке переменная обнуляется.
А потом отслеживаете значение переменной. Если время нажатия превысило пороговое значение - удержание кнопки. Если нет (обнулилось) - короткое нажатие.
Спасибо!!! Почти всё получилось. Вот только при нажатии и удержании кнопки "следующий трек", сначало переключается трек а потом начинается перемотка. Т.е. выполняется и условие строки 063 и условие строки 070. С другими кнопками аналогичная ситуация. А как сделать что бы при удержании не выполнялось условие 063?
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 >40) { previousMillis = millis(); val++; } } else { val=0; } //кнопка громкости + if (data>=210 && data<=232 && flag==0 && val>=1 && val<=3) //одиночное нажатие { Remote.increase(); //прибавить громкость на ед. Remote.clear(); flag=1; val=0; } else if (data>=210 && data<=232 && val>=4) // удержание { 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; } else if (data>=460 && data<=488 && val>=4) //удержание { Remote.decrease(); //убавлять громкость до отпускания Remote.clear(); val=0; } //кнопка следующий трек if (data==0 && flag==0 && val>=1 && val<=5) //одиночное нажатие { Remote.next(); //следующий трек Remote.clear(); flag=1; val=0; } else if (data==0 && val>=6) //удержание { 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; } else 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; } //не нажата не одна из кнопок if (data>=950 && data<=960 && flag==1) { flag=0; } }В программу особо не вчитывался , но ...
Переделайте все конструкции if else if на просто if ( лучше вообще откажитесь от оператора else). Возможно у вас конфликт по условиям if else.
Примерно так. //кнопка следующий трек if (data==0 && flag==0 && val>=1 && val<=5) //одиночное нажатие { Remote.next(); //следующий трек Remote.clear(); flag=1; val=0; } if (data==0 && val>=6) //удержание { Remote.forward(); //перемотка вперёд Remote.clear(); val=0; }И еще. Как вариант , перенесите скобку из строки 25 в самый низ.
Ход таймера маловат (40мс). Получается чтобы сработало одиночное нажатие нужно удерживать кнопку не более 120мс (неудобно).
Оптимальное время для одиночного нажатия 500-1000мс.
Я бы сделал отдельный таймер для каждой кнопки.
Прошу программистов помочь в очень простой для вас, практической задаче для уменьшения простоя лифта. Сегодня лифты напичканы электроникой, а элмеханик не всегда может локализовать неисправность – то ли электроника глючит (тогда жди пока наладчик приедет – бывает долго. Это я и есть) или в шахте непорядок. У меня есть самодельный стенд для полной проверки, собрал его на жесткой логике. Вот хочу для механиков собрать такую приблуду, чтобы меня меньше дергали – старенький я и сами меньше в шахте ползали.
Для начала информация:
В шахте лифта и на кабине расположены шунты, а на кабине -герконовые датчики. Основных датчиков три: VN, TO и VV. (Дал им имена для скетча). По последовательности появления этих сигналов , главный контроллер лифта определяет направление движения, местоположение кабины и обеспечивает точную остановку в датчике ТО.
VN - TO - VV -вниз VV - TO - VN -вверх
Задача : собрать с помощью Ардуино эмулятор движения кабины лифта для проверки главного контроллера в части работы узла местоположения кабины. Датчики – это три светодиода VN, TO и VV, подключенные к выходам 50,51 и 52 Они должны поочередно засвечиваться в зависимости от заданного направления.
Направление задают две кнопки , подключенные на выходы 30 и 31.
Собрал схемку – 3 светодиода с резисторами и две кнопки кподключил к МЕГА 2560, загрузил свой примитивный скетч – последовательность работает, но неправильно. Просьба помочь по двум вопросам:
1. при снятии сигнала на входе, цикл продолжается , а нужна немедленная остановка. И если он остановился, в момент, когда на выходе пина «1», то выход должен остаться в этом состоянии (запомнить эту «1»).??
2. Другой цикл движения не знаю как вставить. ?
// определяю назначение выходов и входов
int VN = 51; //датчик замедления вниз ( светодиод+резистор)
int TO = 50; // датчик точной остановки
int VV = 52; // датчик замедления вверх
int pinN = 31; // команда на включение привода кабины вниз ( кнопка и резистор дотяжки 15ком)
int pinV = 30; // команда на включение привода кабины вверх
int valN=0 ;
int valV=0;
void setup() {
pinMode(VN , OUTPUT);
pinMode(TO , OUTPUT);
pinMode(VV , OUTPUT);
pinMode(pinN, INPUT);
pinMode(pinV, INPUT);
}
void loop(){
valN = digitalRead(pinN);
valV = digitalRead(pinV);
if (val == 1) // поехали вверх, поочередно включаем светодиоды. имитируем вход -выход шунта из датчика. (потом эти выходы будут подключены ко входам проверяемого контроллера)
{
digitalWrite(VN, 1);
delay (2000);
digitalWrite(VN, 0);
digitalWrite(TO, 1);
delay (2000);
digitalWrite(TO, 0); //понимаю, что это примитивно., но не знаю других способов, без delay
digitalWrite(VV, 1);
delay (2000);
digitalWrite(VV, 0);
} else {
digitalWrite(VN, 0); // ЭТО ВЕРОЯТНО ЛИШНЕЕ?
digitalWrite(TO, 0);
digitalWrite(VV, 0);
}}
второй цикл хотел, но не знаю куда вставить
******************************************
if (valV == 1) //вниз {
digitalWrite(VV, 1);
delay (2000);
digitalWrite(VV, 0);
digitalWrite(TO, 1);
delay (2000);
digitalWrite(TO, 0);
digitalWrite(VN, 1);
delay (2000);
digitalWrite(VN, 0);
не в эту тему ;)
Мега для таких целей ох как жирновато....
// определяю назначение выходов и входов #define VN 51 //датчик замедления вниз ( светодиод+резистор) #define TO 50 // датчик точной остановки #define VV 52 // датчик замедления вверх #define pinN 31 // команда на включение привода кабины вниз ( кнопка и резистор дотяжки 15ком) #define pinV 30 // команда на включение привода кабины вверх byte state = 1; void setup() { pinMode(VN, OUTPUT); pinMode(TO, OUTPUT); pinMode(VV, OUTPUT); } void loop() { if(digitalRead(pinV)) { state++; if(state == 4) state = 1; State(state); } if(digitalRead(pinN)) { state--; if(state == 0) state = 3; State(state); } } void State(byte state) { if(state == 1) digitalWrite(VV, 1); else digitalWrite(VV, 0); if(state == 2) digitalWrite(TO, 1); else digitalWrite(TO, 0); if(state == 3) digitalWrite(VN, 1); else digitalWrite(VN, 0); delay (2000); }МАКСИМ! Спасибо большое - сразу заработало. мне нужно время изучить, как ВЫ сделали.
У меня просто уже есть мега от внука- подарил ему на день рождения - получилось себе. Своим механикам, если все получится, дам схему на что-нить подешевле.
Это ведь начало задачи. Буду потом искат прогу для подсчета количества остановок по этим трем импульсам и вывода №этажа на семисегментный двустрочный индикатор. Может сразу мне и подскажите где посмотреть пример?
Заранее благодарю.
где посмотреть пример?
В программу особо не вчитывался , но ...
Переделайте все конструкции if else if на просто if ( лучше вообще откажитесь от оператора else). Возможно у вас конфликт по условиям if else. [/
И еще. Как вариант , перенесите скобку из строки 25 в самый низ.
Ход таймера маловат (40мс). Получается чтобы сработало одиночное нажатие нужно удерживать кнопку не более 120мс (неудобно).
Оптимальное время для одиночного нажатия 500-1000мс.
Я бы сделал отдельный таймер для каждой кнопки.
Перенёс скобку, else убрал, всё равно не получается(((
Есть у кого ещё идеи?
Таймер пока настроил оптимально для моих целей, потом возможно перестрою получше.
Как именно не получается ? Что происходит ?
Всё так же как и было. При нажатии и удержании кнопки сначало проходит сигнал как при одиночном нажатии а потом как при удержании. Т.е. при нажатии идалнейшем удержании кнопки следующий трек отсылается сначала и 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; } }Добрый вечер.
Подскажите можно ли в матричной клавиатуре к примеру 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); }в таком варианте получается нужно все время нажимать на кнопку а хочу чтоб при нажатии показания увеличивались
Как это сделать?
Спасибо.
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); } }Всем привет!
помогите разобраться пожалуйста, не работает включение кнопкой светодиода и включение по времени, тоесть либо одно либо другое, если закомментить код
весь код целиком :
#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"); } } }Ошибка в логике.
Допустим, сейчас 20 часов. Свет автоматически включается (строка 97). И тут же гасится (строка 109, ledOn в состоянии low). Естественно, реле не успевает отработать за эти микросекунды, поэтому визуально ничего не происходит.
По этой же причине днём не удастся включить свет кнопкой - он тут же будет гаситься, потому что часы говорят: "День. Пин должен быть в 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.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"); } } }Хм... представил что кто-то делая свои первые шаги и желая разобратся "как же работать с кнопками", наткнется на скетч из #212. Поседеет сразу.
Хм... представил что кто-то делая свои первые шаги и желая разобратся "как же работать с кнопками", наткнется на скетч из #212. Поседеет сразу.
Извиняюсь, не хотел никого напугать :))) просто я сам еще новичек в общении с ардуино, и потребовался совет именно по кнопке
а скетч то проверил? я его в блокноте правил, так как у меня сейчас не платы не среды нет .
Очень не советую использовать функцию 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(), только который прерывается состоянием пина и может сказать "когда его прервали".
Добрый день ! Прошу помощи,так как в программировании совсем новичок. Пытаюсь сделать подобие умного дома, необходимо чтобы выключатель мог поочередно включать несколько разных светильников, воспользовался вот этим примером
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 Ищу также, не безвозмездно, специалиста,который на основе моих пожеланий по созданию умного дома, поможет написать программу и параллельно обучит меня минимальным основам программирования на ардуино,для возможности внесения изменений в работу программы при дальнейшей эксплуатации системы.
Подскажите каким образом можно подсчитать количество нажатий кнопки в течении времени, т.е для выполнения действия необходимо трижды нажать на кнопку в течении 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; }вариан с переменной flag. удачно проходит компиляцию а на ардуине не работает диод горит в самом начале и при нажатии на кнопку загорается чуть ярче почему ?
01intflag=0;0203voidsetup()04{0506pinMode(13, OUTPUT);070809}1011voidloop()1213{1415if(digitalRead(8)==HIGH&&flag==0)//если кнопка нажата16// и перемення flag равна 0 , то ...17{1819digitalWrite(13,!digitalRead(13));20flag=1;21//это нужно для того что бы с каждым нажатием кнопки22//происходило только одно действие23// плюс защита от "дребезга" 100%2425}2627if(digitalRead(8)==LOW&&flag==1)//если кнопка НЕ нажата28//и переменная flag равна - 1 ,то ...29{3031flag=0;//обнуляем переменную flag32}33}подключил кнопку с одного конца на 5v ,а со второго на 8 вход и второй провод от этой же лапки кнопки через резистор на земле
пробовал даже ставить перемычку на 8 вход и GND и светодиод горит в самом начале что не так ?
Здравствуйте, Дмитрий. Я Вас заочно знаю по многочисленным роликам в 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);
}
это 20 kOm, который встроенный.... моя думает - что нано рассчитать ентот резюк ! попал в 20 kOm - подключай встроенный, не попал - вешай dytiyvq !
пардон... ВЕШАЙ ВНЕШНИЙ !
>>а про это где можно подробнее почитать? Если я правильно понимаю, то это 3,4в на первой кнопке? Как вообще этот диапазон вычисляется или есть какие-то табличные значения?<<
Да это 3.4в . Если вы имеете в виду диапазон АЦП, то это от 0 до 1023 . Что соответствует напряжению от 0 до 5в. Например значение 512 это 2.5в.
А вот вам конкретый множитель - 0.0048828125. Если умножить значение пина АЦП на этоу цифру то получите точное напряжение в вольтах.
эта тема обсуждена до мозга костей ИЛИ до костей мозга - 0 = 0 V , 1023 = 5 / 1024 *1023 = 4.995
Олег, а может лучше будет вот этот вариант?
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;} }вариан с переменной flag. удачно проходит компиляцию а на ардуине не работает диод горит в самом начале и при нажатии на кнопку загорается чуть ярче почему ?
подключил кнопку с одного конца на 5v ,а со второго на 8 вход и второй провод от этой же лапки кнопки через резистор на земле
пробовал даже ставить перемычку на 8 вход и GND и светодиод горит в самом начале что не так ?
Gvined проблема в самом коде.
у меня этот код не спасал от дребезга контактов.
Большое спасибо, надо попробовать. Обязательно отпишусь по результатам.
кнопки можно подсоединять через К555ТР2 ( четыре RS-триггера )... один корпус К555ТР2 , восемь резисторов по 10 kOm , четыре кнопки ( НО - три контакта ).... где есть возможность поставить НЗ-НР-Общ-кнопки - всегда ставлю ТР2.... а в коде про дребезг можно забыть зато :)
возможно тоже вариант.надо пробовать, и смотреть как будет работать. Благодарю за дельные советы.
хотя у меня будут кнопки только с НО контактами, видимо, триггеры придется отставить...
??
Здравствуйте, jane Jack. Сегодня проверил работу программы. Вполне стабильно работает. но есть один нюанс: если удерживать любую кнопку нажатой то светодиод мигает, а если нажать одновременно две и более кнопок светодиоды начинают загораться по очереди. А можно сделать так, чтобы состояние светодиода изменялось один раз только либо при нажатии или при отпускании и не мигали. и не включались все при удержании нескольких кнопок? Если не получится отпишитесь, пож-та. ОК?
Олег, по пробуй убрать матиматику из скетча. замени val++ на val=1. А в сравнении val>=5 замени на val==1. И эксперементируй с таймером
думаю можно поднять планку примерно до 300 это около 1/3 секунды. Хотя если это весь скеч, то можно не ловить проблему с таким таймером и написать на делей с использованием примера флаг описанные выше по этой теме. А вот при нажатии двух и более кнопок надо добавить проверку и о этой задаче я по думаю не сегодня. Может на неделе но не буду обещать.
Спасибо большое. Буду эксперементировать. Вот , с помощью отзывчивых людей , можно двигаться дальше.
У меня это будет не весь скетч, а фрагмент, который, благодаря тебе, будет вставлен в общую программу. И, я думаю, что таймер заменить на delay не желательно, дабы не затормозить обшее быстродействие скетча. Ведь у меня их там сколько-то встречается. Хотя все равно надо посмотреть, может и с такой задержкой будет вполне нормально рабтать. Благодарю еще раз!!
#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кОм. Нет таких в стандартных рядах. Есть такие 3.6, 3.9, 4.7, 5.1
По сути дела это не номиналы. Это означает всего лишь, что резисторы 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к и так далее.
Доброго всем времени суток уважаемые коллеги!
Столкнулся с такой проблемой: на первой странице приведен пример работы с кнопкой и режимами, так вот если в одном из режимов находится ШИМ (Плавное загорание Светодиода и его плавное отключение) то невозможно перейти на следующий за ним режим.
такое ощущение что кнопка не читается и цикл не видит ее изменение.
Каким образом можно выйти из положения?
Для примера приведу пример:
#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); } }А какой из режимов ШИМ. state1,2 или 3? Ни в одном не наблюдаю. Если шим в цикле for, то где условие входа в функцию LEDFade?
PULL_UP на аналоговом пине
Подскажите!
void setup(){ Serial.begin(9600); pinMode(A3,INPUT); digitalWrite(A3, HIGH); } void loop(){ Serial.print("analogRead: "); Serial.println (analogRead(A3)); Serial.print("digitalRead: "); Serial.println (digitalRead(A3)); delay(1000); }В описании (http://arduino.cc/n/Tutorial/AnalogInputPins) говорится:
"The analog pins also have pullup resistors, which work identically to pullup resistors on the digital pins. They are enabled by issuing a command such as
digitalWrite(A0, HIGH); // set pullup on analog pin 0 while the pin is an input.
Be aware however that turning on a pullup will affect the values reported by analogRead()."
Подтягиваю неподключенный А3 и читаю значение на нем analogRead. Ожидаю близко к 1023, но получаю 0.
В то же время digitalRead читает pullup правильно (HIGH). Что я неправильно делаю?
Так не бывает
Спасибо.
Оказалось, что если AVCC (pin 20 ATMega328) подтянут к +5В, то происходит такая ошибка. Отключил - работает правильно. Почему - пока не понятно, буду разбираться.