Управление реле через arduino, enc28j60 и кнопки

zidi85
Offline
Зарегистрирован: 10.01.2016

Здравствуйте, уважаемые посетители и администраторы форума.

Совсем недавно начал играться с Ардуино и появился вопрос, который не знаю как решить. Опишу всё максимально подробно.

Есть в наличии: 1) Arduino Uno, 2) модуль сети mini enc28j60(в перспективе хочу заменить), 3) плата с двумя реле srd-05vdc-sl-c (использую только одно реле. В перспективе хочу заменить), кнопка тактовая без фиксации.

С горем пополам спустя несколько дней накидал такой скетч:

#include <EtherCard.h>

// разъем CS из модуля сети подключаем к 10-му пину на ардуино
#define CS 10
#define RELAY_PIN 4
#define REQUEST_RATE 5000

// настройки сетевого интерфейса
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
static byte myip[] = { 10,36,1,52 };
static byte gwip[] = { 10,36,1,7 };
static byte dnsip[] = { 10,36,1,7 };
static byte hisport[] = { 80 };

char* on  = "ON";
char* off = "OFF";
boolean relayStatus;
char* relayLabel;
char* linkLabel;

byte Ethernet::buffer[700];


// --- begin для кнопки
// задаём константы
const int buttonPin = 2;     // номер входа, подключенный к кнопке
// переменные
boolean lastButton = LOW;      // Переменная для сохранения предыдущего состояния кнопки
boolean currentButton = LOW;   // Переменная для сохранения текущего состояния кнопки
// --- end конец для кнопки

// --- begin для светодиода
const int ledPin =  6;     // номер выхода светодиода на Arduino
boolean ledOn = false;         // Текущее состояние светодиода (включен/выключен)
// --- end для светодиода


void setup () {
// begin  инициируем подключение к локальной сети
  delay(300); 
  if (ether.begin(sizeof Ethernet::buffer, mymac, CS) == 0)
    Serial.println(F("Failed to access Ethernet controller"));
  ether.staticSetup(myip);
// end  инициируем подключение к сети

// --- begin для реле
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, HIGH); 
  // если надо чтобы при обновлении
  // страницы в браузере реле сразу включалось
  // надо вместо true поставить false
  relayStatus = true;
  relayLabel = off;
  linkLabel = on;
// --- end для реле


// --- begin для кнопки
  // инициализируем пин, подключенный к кнопке, как вход
  pinMode(buttonPin, INPUT);
// --- end для кнопки

// --- begin для светодиода на 6-ом пине
  // инициализируем пин, подключенный к светодиоду, как выход
  pinMode(ledPin, OUTPUT);
// --- end для светодиода

}


// --- begin сглаживание кнопки
/*
 * функция сглаживания дребезга
 * принимает в качестве аргумента предыдущее состояние кнопки
 * и выдаёт фактическое.
 */
boolean debounce(boolean last)
{
  boolean current = digitalRead(buttonPin);    // Считать состояние кнопки
  if (last != current)                         // Если изменилось ...
{
  delay(5);                                    // ждём 5 мс
  current = digitalRead(buttonPin);            // Считываем состояние кнопки
  return current;                              // Возвращаем состояние кнопки
}
}
// --- end сглаживание кнопки


void loop () {
// --- begin управление по локальной сети
word len = ether.packetReceive();
word pos = ether.packetLoop(len);
 
  if(pos) {    
    if(strstr((char *)Ethernet::buffer + pos, "GET /?ON") != 0) {
      relayStatus = false;
      relayLabel = on;
      linkLabel = off;
    } else if(strstr((char *)Ethernet::buffer + pos, "GET /?OFF") != 0) {
      relayStatus = true;
      relayLabel = off;
      linkLabel = on;
    }
    digitalWrite(RELAY_PIN, relayStatus);

    BufferFiller bfill = ether.tcpOffset();
    bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"
      "Content-Type: text/html\r\nPragma: no-cache\r\n\r\n"
      "<html><head></head><body>"
      "<div style='font:bold 14px verdana;text-align:center'>Relay is $S</div>"
      "<a href='http://10.36.1.52/?OFF'>Выключить</a>"
      "<br></br>"
      "<a href='http://10.36.1.52/?ON'>Включить</a>"
      
      "</div></div></body></html>"
      ), relayLabel, linkLabel, linkLabel);
     
      ether.httpServerReply(bfill.position());
    }
// --- end управление по локальной сети

// --- begin реакция на нажатие кнопки для реле
currentButton = debounce(lastButton);
if (lastButton == LOW && currentButton == HIGH)   // Если нажатие
{
relayStatus = !relayStatus;
ledOn = !ledOn;
}
lastButton = currentButton;
digitalWrite(RELAY_PIN, relayStatus);                 // Изменить статус состояния реле
digitalWrite(ledPin, ledOn);                         // Изменить статус состояния светодиода
// --- end реакция на нажатие кнопки для реле


  }
 
Что делает скетч:
С кнопки можно включить реле и выключить (кнопку постоянно держать нажатой для этого не нужно-это важный момент). Релюшку так же можно переключать через веб интерфейс. Если я щёлкаю релюшкой через веб-интерфейс, то отрисовывается состояние реле (OFF или ON). Могу переключить реле физической кнопкой, а выключить через web и наоборот. Всё вобщем так, как и надо было. На светодиод на пину №6 можно внимание не обращать - это "муки творчества" :-)
 
Что должно получиться и не получается сделать:
Надо, чтобы переключая реле, я знал о текущем его состоянии, не зависимо от того переключил я реле с физической кнопки или через веб-интерфейс. Надо чтобы информация о состоянии реле я знал через веб интерфейс модуля enc28j60 на arduino.
 

Может кто знает как решить задачу?

Заранее благодарен.

vde69
Offline
Зарегистрирован: 10.01.2016

создай переменную boolean и присваивай ей значение как при програмноой так и при хард смене режима

zidi85
Offline
Зарегистрирован: 10.01.2016

А носом ткнёте?

artemon25
Offline
Зарегистрирован: 25.12.2015

Добрый всем вечер может ктото подсказать мне по скетчу

#include <RCSwitch.h>
 
RCSwitch mySwitch = RCSwitch();
int relay6 = 6;
int relayPin = 7; //Реле будет тут
int relayChn = 8;
int relayOn = 9;
 
void setup() {
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // приемник на pin 2 (DATA) 
  pinMode(relayPin, OUTPUT);
  pinMode(relayChn, OUTPUT);
  pinMode(relayOn, OUTPUT);
  pinMode(relay6, OUTPUT);
  digitalWrite(relayPin, HIGH);
  digitalWrite(relayChn, HIGH);
  digitalWrite(relayOn, HIGH);
  digitalWrite(relay6, HIGH);
}
 
void loop() {
  if (mySwitch.available()) {
    
    int value = mySwitch.getReceivedValue();
    
    if (value == 0) {
      Serial.print("error code"); // Ошибка приемка кода
    } else {
      Serial.print("code good"); // Принял код
      Serial.print( mySwitch.getReceivedValue() );
 
    }
    if (mySwitch.getReceivedValue() == 5312960) {   // 6133332 - код Включения1
      digitalWrite(relayPin, HIGH);
      digitalWrite(relayChn, HIGH);
      digitalWrite(relayPin, LOW);
      digitalWrite(relayChn, LOW);
    }
 
    if (mySwitch.getReceivedValue() == 5312816) {   // 6133332 - код Включения3
      digitalWrite(relayOn, HIGH);
      digitalWrite(relay6, HIGH);
      digitalWrite(relayOn, LOW);
      digitalWrite(relay6, LOW);
    }  
 
   
      
    if (mySwitch.getReceivedValue() ==   5312780) {   // 6133392 - код выключения1
      digitalWrite(relayPin, LOW);
       digitalWrite(relayChn, LOW);
      digitalWrite(relayPin, HIGH);
       digitalWrite(relayChn, HIGH);
    }   
 
     if (mySwitch.getReceivedValue() == 5312771) {   // 6133392 - код выключения3
      digitalWrite(relayOn, LOW);
      digitalWrite(relay6, LOW);
      digitalWrite(relayOn, HIGH);
      digitalWrite(relay6, HIGH);
     }
  } 
    mySwitch.resetAvailable();
  
}
 
у меня это работает от радиопульта попарно тоесть одну кнопку нажимаю включается два реле другую нажимаю эти два реле выключаются третья кнопка включает вторую пару реле и соответсвенно четвёртая выключает а вопрос нужно чтобы если какие либо два реле включены то другие два не включаются и наоборот . тоесть я так понимаю что в тело void loop() { надо добавить функцию 
     else {
    
    digitalWrite(relay6, HIGH);      пин6
    digitalWrite(relayPin, HIGH);    пин7
    digitalWrite(relayChn, LOW);   пин8
    digitalWrite(relayOn, LOW);     пин9
}
 
но где иммено его добавить а то я его в конце вставляю он работает не так как как я хочу 
если кому не лень пропишите в моём скетче куда и как втавить то что работает как надо
Заранее всем спасибо за внимание и за ответы
Navigator
Navigator аватар
Offline
Зарегистрирован: 26.01.2016

artemon25 в вашем скетче беспорядок

1. Выводы управления реле объявлены как попало

int relay6 = 6;
int relayPin = 7; //Реле будет тут
int relayChn = 8;
int relayOn = 9;
 
а в таком виде будет более понятно
int relay6 = 6; 
int relay7 = 7; 
int relay8 = 8; 
int relay9 = 9; 
 
2. а вот это что такое?
if (mySwitch.getReceivedValue() == 5312960) {   // 6133332 - код Включения1
      digitalWrite(relayPin, HIGH);
      digitalWrite(relayChn, HIGH);
      digitalWrite(relayPin, LOW);
      digitalWrite(relayChn, LOW);
 
получается, что вы включили два реле и в то же мгновение выключили
 
наведите порядок в скетче, а далее уже будет проще

 

Navigator
Navigator аватар
Offline
Зарегистрирован: 26.01.2016

Вижу Artemon25 создал новую тему на форуме ОБЩИЙ http://arduino.ru/forum/obshchii/rabota-rele-po-peremenno-ne-meshaya-drug-drugu. Ему сразу написали весь скетч, не дали человеку времени поработать головой.