forkineye / E131

E1.31 (sACN) library for Arduino with ESP8266 support
127 stars 44 forks source link

Static IP #2

Closed yeti195 closed 8 years ago

yeti195 commented 9 years ago

What changes would I need to make to have this use a static IP instead of DHCP?

forkineye commented 9 years ago

If you acquire your address via DHCP initially, you can switch to static from the web configuration. I'll do some testing tonight for setting up static on an initial configuration and get back to you.

yeti195 commented 9 years ago

I figured out how to give it a Static IP. :-)

under the line byte mac[] =, I added these lines.

uint8_t ip[] = { 2, 0, 0, 12 }; uint8_t gateway[] = { 192, 168, 1, 1 }; uint8_t subnet[] = { 255, 0, 0, 0 };

I then changed - e131.begin(mac); to e131.begin(mac, ip, gateway, subnet, dns);

So far it's working great this way.

One final question though. Like I said, I'm using this to control a series of projectors. If lats say ch 200 goes above 50 % is sends a serial command out a serial port I created using software serial. That works great. I'm controlling Power on, off, shutter open, and close.

Now, I wanted to add just one more feature. I wanted to add 4 buttons to the arduino as well. One for each serial command. On, off, open, close. I have them all wired in, and can get them to work, but only if the arduino is receiving sACN data. What I'd like to have it do, is if someone shuts down the lighting console and forgets to power off the projectors, then they just press the button on the box to shut them down. If the sACN stops, like the console is off, the buttons do not work.

Here's my modified code to look at. If you see anything that I could be doing better, please let me know. I have learned so much from this project. Thanks again for the hard work on this and the great code.

// Libraries to include

#include <SPI.h>
#include <Ethernet.h>
#include <E131.h>

// SoftwareSerial is used for the TTL to RS232 IC connected to pins 6 & 7

#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 6); // RX, TX

const int buttonPin_1 = 2;
const int buttonPin_2 = 3;
const int buttonPin_3 = 4;
const int buttonPin_4 = 5;

int buttonState_1 = 0; int buttonState_2 = 0; int buttonState_3 = 0; int buttonState_4 = 0;

byte mac[] = { 0x04, 0xE8, 0xA5, 0x00, 0x68, 0xEF }; uint8_t ip[] = { 2, 0, 0, 12 }; uint8_t gateway[] = { 192, 168, 1, 1 }; uint8_t subnet[] = { 255, 0, 0, 0 };

E131 e131;

void setup() {

// initialize the pushbutton pins as an input:
pinMode(buttonPin_1, INPUT);
pinMode(buttonPin_2, INPUT);
pinMode(buttonPin_3, INPUT);
pinMode(buttonPin_4, INPUT);

// Setup USP serial port
Serial.begin(115200);
delay(10);
Serial.println("USB Serial Ready");

// Setup softwareSerial for DB9 port
mySerial.begin(19200);
delay(10);
mySerial.println("DB9 Serial Ready");

/* Configure via STATIC IP and listen Unicast on the default port */
e131.begin(mac, ip, gateway, subnet, dns);  

}

void loop() {

//Read each button state
buttonState_1 = digitalRead(buttonPin_1);
buttonState_2 = digitalRead(buttonPin_2);
buttonState_3 = digitalRead(buttonPin_3);
buttonState_4 = digitalRead(buttonPin_4);

/* Parse a packet of e1.31 sACN DMX data */
uint16_t num_channels = e131.parsePacket();

/* Process channel data if we have it */
if (num_channels) {

    Serial.print(F("Universe "));
    Serial.print(e131.universe);
    Serial.print(F(" / "));
    Serial.println(num_channels);

    // Do logic based on the DMX data received.

    if (e131.data[199] >= 127 || buttonState_1 == HIGH) {
      mySerial.println(F("$02ADZZ;PON$03")); // Power ON
    }

    if (e131.data[200] >= 127 || buttonState_2 == HIGH) {
      mySerial.println(F("$02ADZZ;POF$03")); // Power OFF
    }

    if (e131.data[201] >= 127 || buttonState_3 == HIGH) {
      mySerial.println(F("$02ADZZ;OSH:0$03")); // Shutter Open
    }

    if (e131.data[202] >= 127 || buttonState_4 == HIGH) {
     mySerial.println(F("$02ADZZ;OSH:1$03"));  // Shutter Close
    } 
}

}

forkineye commented 9 years ago

Sorry about the rabbit trail on DHCP and web config, for some reason I thought this was against my ESPixelStick project - http://github.com/forkineye/ESPixelStick, which is a pixel driver using this library.

You could do switch control the manual way as you describe, or you could set a timeout in the main loop if the console constantly streams DMX data. Most DMX devices have a fallback mode they go into if DMX data isn't seen in X amount of time. For your projector, it could be closing the shutter and powering it off. Grab an initial time at the end of setup (using millis() or something), then update it in the if() loop. After the if() loop, check if time - current timer is met. If so, close the shutter and shut it down. You could probably do it with the Ticker library as well, but I haven't played with that yet.

yeti195 commented 9 years ago

Could I ask you how you would put in the if statement in the main loop where if the DMX stream was available, do this, and if the DMX stream was not available, do this. I keep trying to make this work, but not having any luck.

Thank you again for all the help. This code is so helpful.

forkineye commented 9 years ago

Sorry I haven't had a chance to get back to you on this. Spent this weekend working on another project. I'll be working on the E1.31 library this week and will add an example on how to do DMX stream timeouts.

yeti195 commented 9 years ago

Thank you, I'm looking forward to it. I have learned so much from this project. Can't thank you enough.

forkineye commented 8 years ago

My ESPixelStick code may be a better example, as I'm doing something similar in a testing branch now, here - https://github.com/forkineye/ESPixelStick/blob/ws2811_uart/ESPixelStick.ino.

Up top, define your timeout value and create a global variable to track it:

#define E131_TIMEOUT 1000  /* Timeout state after 1 second */

uint32_t lastPacket;  /* Packet timeout tracker */```

Your main loop would have something like this:

loop() {
    if (num_channels) {
        lastPacket = millis();
        /* rest of your channel processing code */
    }

    if ((millis() - lastPacket) > E131_TIMEOUT) {
        lastPacket = millis(); /* reset our timer */
        /* Timeout state reached, turn off projector and stuff */
    }
}

You could put additional logic in there as well to track if you're in a timeout state. The above code would enter the timeout loop every second a packet isn't received. Below is an example with state tracking, untested. This would only enter the timeout state once, until a new packet arrived.

#define E131_TIMEOUT 1000  /* Timeout state after 1 second */

uint32_t lastPacket;  /* Packet timeout tracker */```
boolean stateAlive = true; /* Start-up in an active state */

loop() {
    if (num_channels) {
        stateAlive = true; /* Reset to active state */
        lastPacket = millis();

        /* rest of your channel processing code */
    }

    if (((millis() - lastPacket) > E131_TIMEOUT) && stateAlive) {
        stateAlive = false; /* Non-active state */
        lastPacket = millis(); /* reset our timer */
        /* Timeout state reached, turn off projector and stuff */
    }
}
yeti195 commented 8 years ago

Thank you, I got it working. The first example you gave worked like a champ. I could not the the second example working, but I did not spend a lot of time on it because the first one worked. Thank you again for the code, and all the help.