Помогите с кодом для дискретного входа
- Войдите на сайт для отправки комментариев
Вс, 02/12/2012 - 17:53
Доброго времени суток.
Помогите с кусочком программы:
Цель: выводить в потр или через Enthernet sheld команду при замыкании дискретного входа
**/
int pirPin = 7; // присваеваем 7 ноге название pirPin
...
...
...
// Настройка портов на вывод
pinMode (pirPin, INPUT); // Настройка порта как вход
digitalWrite(pirPin, LOW); // Установить на 7 ноге низкий уровень
...
...
...
void CheckMotion()
{
motionDetected = 0;
if(digitalRead(pirPin) == HIGH){
Serial.println("yes"); motionDetected = 1;
}else{
Serial.println("no");
motionDetected = 0;}
}
Вот кусок кода ...
В у меня получается что если на входе LOW в порт постоянно передает "no"
Когда на входе HIGH в порт постоянно передает "yes"
А нужно, чтобы команда выходила один раз только когда меняется значение.
Вот в этом не получается разобратся (мало опыту по программированию)
Недавно написал довольно объемную статью о кнопках. Там есть то что вам нужно.
Вот http://forumdvrobot.ru/forum/3-21-1 Шестой пример кода.
Для этого нужно объявить переменную, которая будет хранить последнее состояние кнопки и когда текущее состояние отлично от последнего, то в этот момент и выводить данные в сериал и текущее состояние кнопки сохранить как последнее.
**/ byte pirPin = 7; // присваиваем 7 ноге название pirPin byte motionDetected_prev = 0; ... ... ... void CheckMotion() { if(digitalRead(pirPin) |= motionDetected_prev){ if(digitalRead(pirPin) == HIGH){ Serial.println("yes"); motionDetected = 1; } else{ Serial.println("no"); motionDetected = 0; } motionDetected_prev = motionDetected; } }Эти строки можете удалить, они бессмысленны
если находятся в setup и используются только в начале при настройке.
nestandart: спачибо огромное за ссылку. Очень хорошо описано.
Я немного подкорректировал код под себя:
* функция проверки команд **/ void inputcommands() { if(digitalRead(startPin)==HIGH&&flag==0) { Serial.print("1"); flag=1; delay(10); } if(digitalRead(startPin)==LOW&&flag==1) { Serial.println("0"); flag=0; delay(10); } }подскажите как можно сделать опрос только для нескольких портов разом:
byte startPin=1; byte endPin=5; ... void CheckMotion(){ for (int thisPin = startPin; thisPin <=endPin; thisPin++)Опрос нужных пинов можно сделать, например, записав номера пинов в массив (особенно, если они расположены не друг за другом):
#define MAX_PINS 4 const byte pin_array[MAX_PINS] = { 1, 5, 3, 2 }; ... for( i = 0; i < MAX_PINS; ++i ) { byte l_pin_state = digitalRead( pin_array[ i ] ); ... }Массив также можно использовать для инициализации этих пинов в setup()
UPD: исходник немного поправил, const забыл
а как быть со старым значанием pin с которым сравниваем и выполняем действие если значание изменилось относительно предыдущего именно этого порта???
Добавьте еще один массив, он будет хранить предыдущие значения. Сравниваете текущие значения со значениями из массива и знаете где что изменилось. После сравнения изменившиеся значения пишите в массив для сравнения в следующем цикле.
Массив для моего примера можно описать так: byte val_array[MAX_PINS] ={ 0, 0, 0, 0 };
как-то не получается?
#define MAX_PINS 4 //максимальное количество входоа 4 const byte pin_array[MAX_PINS] = { 1, 3, 4, 5 }; //номера пинов byte val_array[MAX_PINS] ={ 0, 0, 0, 0 }; //предыдущие значения портов void setup() { Serial.begin(9600); } void loop(){ for( int i = 0; i < MAX_PINS; i++) //цикл переберает значения MAX_PIN попорядку { byte l_pin_state = digitalRead(pin_array[i]); //считать данные и записать в l_pin_state if( l_pin_state != val_array[i] ) { // сравнить l_pin_state и val_array[i] Serial.print(pin_array[i]); Serial.print("="); Serial.print(l_pin_state); byte val_array[i] = l_pin_state // записать текущее значение в val_array } } }16 строка, слово byte уберите и в конце точку с запятой не забудьте поставить, т.е.
Вообще конструкция "забавная", такого я еще не видел, чтобы сожрал компилятор, хотя были приколы похлеще. Фактически это объявление локальной переменной, а не запись в существующий массив, потому у Вас "не работает", остальной текст в норме, во всяком случае с первого взгляда.
UPD: Да, еще, помните, что начальные значения в val_array у Вас нули, т.е. LOW. Как вариант, можно туда забить любое значение, не совпадающее с HIGH, LOW, тогда сработают сразу все 4 пина. А если на входах нули, то сработает при первом изменении, а при старте программы - нет.
UPD2: Да, еще в строке 15 замените print на ptintln, будет приятнее выводиться.
мало что понял ещё и запутался в конец
Для начала замените строку 16, на мой вариант, дальше проще
Заменил и в потр сыпится 11=11=11 и т.д.
Исходник приложите, только отформатируйте его нормально (Ctrl-T, если не ошибаюсь). Предполагаю, что Вы там не только это изменили, либо некорректно изменили, всё должно работать.
Насколько я понимаю, Вы пока при отладке меняете состояние только пин 1?
Если 15 строку замените print на println, то будет выводить построчно, а не в одну строку. Надеюсь это несложно найти в строке 15 фрагмент print и заменить его на println?
Большой СПС "kisoft" за помощь
Сел, собрался, и получил:
#include <EEPROM.h> #define MAX_PINS 4 //максимальное количество входоа 4 const byte pin_array[MAX_PINS] = { 3, 4, 5, 6 }; //номера пинов byte val_array[MAX_PINS] ={ 0, 0, 0, 0 }; //предыдущие значения портов void setup() { Serial.begin(9600); } void loop() { for( int i = 0; i < MAX_PINS; i++) //цикл переберает значения MAX_PIN попорядку { val_array[i] = EEPROM.read(i); byte l_pin_state = digitalRead(pin_array[i]); //считать данные и записать в l_pin_state if( l_pin_state != val_array[i] ) // сравнить l_pin_state и val_array[i] { Serial.print("Pin"); Serial.print(pin_array[i]); Serial.print("="); Serial.println(l_pin_state); val_array[i] = l_pin_state; // записать текущее значение в val_array EEPROM.write(i, l_pin_state); delay(20); } } }Ещё сделал сохранение последнего значения порта в EEPROM вдруг напруга пропадёт
А как можно вывести вместо 1 или 0 строку формата "GET /objects/?object=D8&op=m&m=statusChanged&status=%i" для вебсервера на компе.
использую W5100 шилд
К сожалению не подскажу, поскольку даже близко не пользовался библиотеками Ethernet.
А строка у Вас почти готова, вместо %i нужно подставить l_pin_state. Вариантов море, отчасти зависят от возможностей бибилиотеки, которая отправляет строку.
Тупой вариант, что называется, в лоб, это завести буфер, в котором будет отправляться строка, формировать в ней эту строку, потом этот буфер передавать функции, которая отправит её в сеть. Например:
Другой вариант, расположить строку в объекте типа String.
Есть и более сложные варианты.
Вот, еще тупой вариант, возможно и самый простой:
В общем, каждый выбирает себе сам, что ему ближе, а также от ситуации.
Еще, строки большой длины лучше хранить где нибудь в EEPROM или во флешке (PROGMEM), но в этом случае будет несколько сложнее добавить в эту строку состояние пина.