Varley Gianini
Varley Gianini
Good morning everyone! Well I have a code here to control relays through artnet E1.31 using the Arduino Ethernet shield, but for us to change the IP address we must change the line and compile the code on the Arduino, I would like to know how can I do to put a button that makes this IP change and shows it on an LCD. Can anyone help me with this?
Follow the code below
Follow the code below
C++:
#include <SPI.h> //Biblioteca Padrão
#include <Ethernet.h> //Biblioteca Padrão
#include <EthernetUdp.h> //Biblioteca Padrão
/* defina a sub-rede e o universo desejados (o primeiro universo é 0)
sACN começa com o universo 1, então subtraia 1 do universo sACN
para obter DMX_UNIVERSE. */
#define ARTNET_SUBNET 0 //a sub-rede padrão é 0. Não deve ser necessário alterar.
#define ARTNET_UNIVERSE 41 //primeiro universo sendo usado
#define E131_SUBNET 0 //a sub-rede padrão é 0. Não deve ser necessário alterar.
#define ETHERNET_BUFFER_MAX 640
#define ARTNET_ARTDMX 0x5000
#define ARTNET_ARTPOLL 0x2000
#define ARTNET_PORT 0x1936 //porta padrão
#define ARTNET_START_ADDRESS 18 //O byte 18 no pacote contém os valores do canal 1.
#define E131_PORT 5568 //porta padrão
#define E131_START_ADDRESS 126 //O byte 126 no pacote contém os valores do canal 1. O deslocamento é definido como um anterior.
#define STATUS_LED 13 //nos mostra quando estamos recebendo dados
#define SDCARD_CONTROL 4 //defina o pino 4 para alto para desativar a interface do cartão SD no escudo WiFi
#define NUM_RELAYS 16 //número total de relés usados
int channel; //incremento de canal
//Pinos Reles
int Relay[] = {22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37};
//Configuração do cronômetro
volatile byte currentcounter = 0; //contador para recepção de dados
byte previouscounter = 0; //contador para recepção de dados
unsigned long currentDelay = 0; //valor de tempo atual para ArtNet e recepção E1.31
//Configuração Ethernet
byte mac[] = {0x00, 0xDD, 0xEE, 0x01, 0x10, 0x90};
IPAddress ip(192, 168, 0, 100); //Endereço IP do escudo Ethernet
// buffer to hold E1.31 and Artnet data
unsigned char packetBuffer[ETHERNET_BUFFER_MAX];
// Uma instância EthernetUDP para nos permitir enviar e receber pacotes sobre UDP
// aUDP cria um soquete para uma porta Art-Net
// suUDP cria um soquete para sCAN que é unicast para o endereço IP
EthernetUDP aUDP;
EthernetUDP suUDP;
void setup()
{
pinMode(STATUS_LED, OUTPUT); //LED de status de inicialização
pinMode(SDCARD_CONTROL, OUTPUT); //Inicialize o pino 4
digitalWrite(SDCARD_CONTROL, HIGH); //Defina o pino 4 para alto, pois não estamos usando a interface do cartão SD
for(int a = 0; a < NUM_RELAYS; a++) //loop para inicializar pinos de controle de relé
{
pinMode(Relay[a], OUTPUT); //inicializar pinos de saída de relé
digitalWrite(Relay[a], LOW); //defina os pinos para alto para desligar
}
Ethernet.begin(mac,ip); //Inicializar escudo Ethernet
aUDP.begin(ARTNET_PORT); //Abra a porta Artnet
suUDP.begin(E131_PORT); //Abra a porta E1.31
Serial.begin(9600); //Serial para depuração
POST(); //Execute a função de autoteste ao ligar
Serial.println("Setup Complete"); //impressão completa
}
/* artDMXReceived verifica o universo e a sub-rede, em seguida
envia os dados para os relés */
void artDMXReceived(unsigned char* pbuff)
{
if ( (pbuff[14] & 0xF) == ARTNET_UNIVERSE )
{
if ( (pbuff[14] >> 8) == ARTNET_SUBNET )
{
channel = 0; //redefinir o deslocamento do canal para 0 a cada vez através do loop
//loop liga / desliga o relé com base no valor do canal, começando no endereço inicial Artnet
for(int b = 0; b < NUM_RELAYS; b++)
{
if(pbuff[ARTNET_START_ADDRESS + channel] > 127) //se o valor do canal for maior que 127
{
digitalWrite(Relay[b], HIGH); //ligar relé
}
else
{
digitalWrite(Relay[b], LOW); //senão desligue
}
channel++; //aumentar o deslocamento do canal em 1 a cada vez por meio do loop
}
}
}
} //fim artDM recebido
/* artNetOpCode verifica se o pacote é realmente Art-Net
e retorna o opcode informando que tipo de mensagem Art-Net é. */
int artNetOpCode(unsigned char* pbuff)
{
String test = String((char*)pbuff);
if ( test.equals("Art-Net") )
{
if ( pbuff[11] >= 14 )
{ //versão do protocolo [10] hi byte [11] lo byte
return pbuff[9] *256 + pbuff[8]; //opcode lo byte first
}
}
return 0;
}
/* sacnDMXReceived verifica o universo e a sub-rede, em seguida
envia os dados para relés */
void sacnDMXReceived(unsigned char* pbuff, int count)
{
if ( pbuff[113] == E131_SUBNET )
{
int addressOffset = 125; //primeiros 125 bytes do pacote são informações de cabeçalho
if ( pbuff[addressOffset] == 0 ) //o código inicial deve ser 0
{
channel = 0; //redefinir o deslocamento do canal para 0 a cada vez através do loop
//loop liga / desliga o relé com base no valor do canal, começando no endereço inicial E1.31
for(int c = 0; c < NUM_RELAYS; c++)
{
if(pbuff[E131_START_ADDRESS + channel] > 127) //se o valor do canal for maior que 127
{
digitalWrite(Relay[c], HIGH); //ligar relé
}
else
{
digitalWrite(Relay[c], LOW); //desligue o relé
}
channel++; //incrementar o deslocamento do canal em 1
}
}
}
} //fim sacnDMXReceived
//verifica se o pacote é de dados E1.31
int checkACNHeaders(unsigned char* messagein, int messagelength)
{
if ( messagein[1] == 0x10 && messagein[4] == 0x41 && messagein[12] == 0x37)
{
int addresscount = messagein[123] * 256 + messagein[124]; // número de valores mais o código inicial
return addresscount -1; //Retorne quantos valores estão no pacote.
}
return 0;
}
/************************************************************************
O loop principal verifica e lê os pacotes das duas ethernet UDP
conexões de soquete. Quando um pacote é recebido, ele é verificado para ver se
é válido e então uma das funções DMXReceived é chamada, enviando
os valores DMX para a saída. Também há um temporizador para executar um modo de espera
programa se nenhum dado for recebido por 30 segundos.
*************************************************************************/
void loop()
{
if(currentcounter != previouscounter) //o valor mudou?
{
currentDelay = millis(); //armazene o tempo desde que o valor aumentou
previouscounter = currentcounter; //defina o valor anterior igual ao valor atual
}
if(millis() - currentDelay > 30000) //o tempo desde a alteração do valor é superior a 30 segundos?
{
digitalWrite(STATUS_LED, HIGH); //desligue o LED. Não recebendo E1.31 ou ArtNet.
}
// primeiro verifique se um pacote está disponível na porta Art-Net
int packetSize = aUDP.parsePacket();
if( packetSize )
{
aUDP.read(packetBuffer, ETHERNET_BUFFER_MAX);
/* after reading the packet into the buffer, check to make sure
que é um pacote Art-Net e recupera o opcode que
diz que tipo de mensagem é */
int opcode = artNetOpCode(packetBuffer);
if ( opcode == ARTNET_ARTDMX )
{
Serial.println("ArtNet Packet Received");
artDMXReceived(packetBuffer);
currentcounter++; //aumentar o contador em 1 cada vez através
digitalWrite(STATUS_LED, HIGH); //ligue o LED de status
}
}
else
{
/* então, se ainda não houver pacote, verifique se um pacote
está disponível na porta unicastcast sACN */
packetSize = suUDP.parsePacket();
if( packetSize )
{
suUDP.read(packetBuffer, ETHERNET_BUFFER_MAX);
/* depois de ler o pacote no buffer, verifique se
que é um pacote sACN válido.*/
int count = checkACNHeaders(packetBuffer, packetSize);
if ( count )
{
Serial.println("E131 Packet Received");
sacnDMXReceived(packetBuffer, count);
currentcounter++; //aumentar o contador em 1 cada vez através
digitalWrite(STATUS_LED, LOW); //ligue o LED de status
}
}
}
} //Loop final
//Ligue a função de autoteste para verificar se tudo está conectado corretamente.
void POST()
{
digitalWrite(Relay[0], HIGH);
delay(1000);
digitalWrite(Relay[0], LOW);
digitalWrite(Relay[1], HIGH);
delay(1000);
digitalWrite(Relay[1], LOW);
digitalWrite(Relay[2], HIGH);
delay(1000);
digitalWrite(Relay[2], LOW);
digitalWrite(Relay[3], HIGH);
delay(1000);
digitalWrite(Relay[3], LOW);
digitalWrite(Relay[5], HIGH);
delay(1000);
digitalWrite(Relay[5], LOW);
digitalWrite(Relay[6], HIGH);
delay(1000);
digitalWrite(Relay[6], LOW);
digitalWrite(Relay[7], HIGH);
delay(1000);
digitalWrite(Relay[7], LOW);
digitalWrite(Relay[8], HIGH);
delay(1000);
digitalWrite(Relay[8], LOW);
Serial.println("POST Completo");
}