Paso 6: El código de Arduino
Aquí está el código que se ejecuta en el Arduino:/*
Controlador de garaje
Escrito por Aram Perez
Licenciado bajo GPLv2, disponible en http://www.gnu.org/licenses/gpl-2.0.txt
*/
#define LOG_SERIAL
#include < SPI.h >
#include < Ethernet.h >
#include < Wire.h >
#define NO_PORTA_PINCHANGES
#define NO_PORTC_PINCHANGES
#include < PinChangeInt.h >
#define IOPORT 23 //Normal telnet puerto
#define NBR_OF_RELAYS 4
Botón y sensores de puerta de garaje
#define GARAGE_CLOSED_SENSOR 2 //Connect a terminal NC, alta activa
#define GARAGE_PARTIALLY_OPEN_SENSOR 3 //Connect a ningún terminal, activo alto
#define RELAY0 4
#define GARAGE_RELAY RELAY0 //Relay para el botón de la puerta de garaje
#define relé 1 5
#define relé 2 6
#define RELAY3 7
#define CR ((char) 13)
#define LF ((char) 10)
Introduzca una dirección de MAC y dirección IP para el controlador a continuación.
La dirección IP dependerá de su red local.
puerta de enlace y subred son opcionales:
mac de estática bytes [] = {}
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
ip dirección IP estática (192 168 1, 170);
entrada de dirección IP estática (192, 168, 1, 1);
subred de dirección IP estática (255, 255, 255, 0);
server(IOPORT) de EthernetServer estáticos;
cliente de EthernetClient estático;
Static char relayState [NBR_OF_RELAYS];
clase GarageDoor
{
bool closedState, partiallyOpenState;
público:
GarageDoor();
void Init();
void SetClosedState(bool st) {}
closedState = st;
}
void SetPartiallyOpenState(bool st) {}
partiallyOpenState = st;
}
char State() const;
void PushButton();
};
garageDoor de GarageDoor estático;
Esto debe ser una función privada en la clase de GarageDoor
es decir, GarageDoor::StateChangedISR(void),
pero el compilador da un error si es :-(
Static void StateChangedISR(void)
{
Si (PCintPort::arduinoPin == GARAGE_CLOSED_SENSOR) {}
garageDoor.SetClosedState(PCintPort::pinState);
}
Else {}
Debe haber sido el GARAGE_PARTIALLY_OPEN_SENSOR:
garageDoor.SetPartiallyOpenState(PCintPort::pinState);
}
}
GarageDoor::GarageDoor()
{
}
void GarageDoor::Init()
{
pinMode (GARAGE_CLOSED_SENSOR, INPUT_PULLUP);
PCintPort::attachInterrupt (GARAGE_CLOSED_SENSOR y StateChangedISR, cambio);
pinMode (GARAGE_PARTIALLY_OPEN_SENSOR, INPUT_PULLUP);
PCintPort::attachInterrupt (GARAGE_PARTIALLY_OPEN_SENSOR y StateChangedISR, cambio);
closedState = digitalRead(GARAGE_CLOSED_SENSOR);
partiallyOpenState = digitalRead(GARAGE_PARTIALLY_OPEN_SENSOR);
}
void GarageDoor::PushButton()
{
digitalWrite (GARAGE_RELAY, bajo);
Delay(400); Demora segundos.4
digitalWrite (GARAGE_RELAY, alto);
}
char GarageDoor::State() const
{
Si (closedState) return 'c';
¿volver partiallyOpenState? 'p' : 'o';
}
void setup() {}
#ifdef LOG_SERIAL
Serial.Begin(56700);
#endif
inicializar el dispositivo ethernet
Ethernet.Begin (mac, ip, puerta de enlace, subred);
empezar a escuchar para clientes
Server.Begin();
garageDoor.Init();
para (int i = 0; i < NBR_OF_RELAYS; i ++) {}
pinMode (RELAY0 +, salida); Zona 1
digitalWrite (RELAY0 +, HIGH); Relés de lógica de uso invertido, alta = Off
relayState [i] = '0'; Usar la lógica normal
}
Si (client.connected()) {}
Client.Flush();
}
#ifdef LOG_SERIAL
Serial.println("\r\nOK");
#endif
}
char ReadNext()
{
char ch = client.read();
#ifdef LOG_SERIAL
Serial.Print(CH);
#endif
volver ch;
}
//
Comandos:
// g? -devolver el estado actual de la puerta del garaje
c - la puerta está cerrada
o - la puerta está completamente abierta
p - puerta está parcialmente abierta
GB - botón "push" de la puerta del garaje
¿RX? -relé de retorno x estado
rXY - relé set x a y (0 ó 1)
//
void loop() {}
Static char lastGarageDoorState = 'c';
char ch, rAsc;
Si (! client.connected()) {}
Si el cliente no está conectado, esperar para un nuevo cliente:
cliente = server.available();
}
Si (client.available() > 0) {}
int rNdx;
bool err = false;
mientras (client.available() > 0) {}
interruptor (ReadNext()) {}
caso 'g':
interruptor (ReadNext()) {}
caso '?':
CH = garageDoor.State();
Client.Print('g');
Client.println(CH);
#ifdef LOG_SERIAL
Serial.Print ("> g");
Serial.println(CH);
#endif
rotura;
caso 'b':
garageDoor.PushButton();
rotura;
por defecto:
ERR = true;
}
rotura;
caso 'r':
CH = ReadNext();
interruptor (ch) {}
caso '1':
caso '2':
Case '3':
rAsc = ch;
rNdx = ch - '1';
CH = ReadNext();
interruptor (ch) {}
caso '?':
CH = relayState [rNdx];
rotura;
caso '0':
digitalWrite (relé 1 + rNdx, HIGH); Lógica invertida
relayState [rNdx] = ch;
rotura;
caso '1':
digitalWrite (relé 1 + rNdx, LOW); Lógica invertida
relayState [rNdx] = ch;
rotura;
por defecto:
ERR = true;
}
Si (! err) {}
Client.Print('r');
Client.Print(rAsc);
Client.println(CH);
#ifdef LOG_SERIAL
Serial.Print('>');
Serial.println(CH);
#endif
}
rotura;
por defecto:
ERR = true;
}
rotura;
caso de CR:
caso LF:
rotura; Ignorar el CR y LF
por defecto:
ERR = true;
}
}
Si (err) {}
Client.println('?');
#ifdef LOG_SERIAL
Serial.println ("> ¿Qué decir?");
#endif
}
}
CH = garageDoor.State();
Si (ch! = lastGarageDoorState) {}
lastGarageDoorState = ch;
Client.Print('g');
Client.println(CH);
#ifdef LOG_SERIAL
Serial.Print ("> g");
Serial.println(CH);
#endif
}
}