Go Down

Topic: ArtNet to WS2812 Pixel LED driver : Using Wemos D1 (arduino-esp8266) (Read 21220 times) previous topic - next topic

mcnobby

A standard UNO and an Ethernet Shield could probably get you 2 universes (340 pixels), the main limitation is ram as you need to have 3bytes per RGB Pixel, but it can be done

If you are looking at doing more than this then you might need to be looking at an Arduino Mega as it has alot more ram than an UNO
http://www.youtube.com/user/Recovered
http://www.smartshow.lighting

w31x

hello bob,
first of all thanx for the great job. I've been playing with my D1 mini for a while and now I have 4 universes on one pin (680 pixels). Now I want to supply another pin with the next 4 universes ->  some non-round effects such as green flickers arise on some places and the animation is not as smoothly.
So how do I get more than the 680 pixels on one controller?

Can you please give me a hint ...Thank you!

Code: [Select]

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

#define WSout1 D1 
#define WSout2 D1 
#define WSout3 D1
#define WSout4 D1
#define WSout5 D1

#define WSbit1 (1<<WSout1)
#define WSbit2 (1<<WSout2)
#define WSbit3 (1<<WSout3)
#define WSbit4 (1<<WSout4)
#define WSbit5 (1<<WSout5)

// ARTNET CODES
#define ARTNET_DATA 0x50
#define ARTNET_POLL 0x20
#define ARTNET_POLL_REPLY 0x21
#define ARTNET_PORT 6454
#define ARTNET_HEADER 17

WiFiUDP udp;

//universe 0
uint8_t uniData1[510];
uint8_t universe1 = 0;
uint16_t uniSize1;

//universe 1
uint8_t uniData2[510];
uint8_t universe2 = 1;
uint16_t uniSize2;

//universe 3
uint8_t uniData3[510];
uint8_t universe3 = 2;
uint16_t uniSize3;

//universe 4
uint8_t uniData4[510];
uint8_t universe4 = 3;
uint16_t uniSize4;

//universe 5
uint8_t uniData5[510];
uint8_t universe5 = 4;
uint16_t uniSize5;

uint8_t hData[ARTNET_HEADER + 1];
uint8_t net = 0;
uint8_t subnet = 0;

const char* ssid     = "----";
const char* password = "----";

IPAddress local_ip(172, 20, 10, 10);
IPAddress gateway_ip(172, 20, 10, 1);
IPAddress subnet_ip(255, 255, 255, 240);


void setup() {

  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);
  WiFi.config(local_ip, gateway_ip, subnet_ip);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  udp.begin(ARTNET_PORT); // Open ArtNet port

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());


  pinMode(WSout1, OUTPUT);
  pinMode(WSout2, OUTPUT);
  pinMode(WSout3, OUTPUT);
  pinMode(WSout4, OUTPUT);
  pinMode(WSout5, OUTPUT);
}


void sendWS1() {
  uint32_t writeBits;
  uint8_t  bitMask, time;
  os_intr_lock();
  for (uint16_t t = 0; t < uniSize1; t++) { // outer loop counting bytes
    bitMask = 0x80;
    while (bitMask) {
      // time=0ns : start by setting bit on
      time = 4;
      while (time--) {
        WRITE_PERI_REG( 0x60000304, WSbit1 );  // do ON bits // T=0
      }
      if ( uniData1[t] & bitMask ) {
        writeBits = 0;  // if this is a '1' keep the on time on for longer, so dont write an off bit
      }
      else {
        writeBits = WSbit1;  // else it must be a zero, so write the off bit !
      }
      time = 4;
      while (time--) {
        WRITE_PERI_REG( 0x60000308, writeBits );  // do OFF bits // T='0' time 350ns
      }
      time = 6;
      while (time--) {
        WRITE_PERI_REG( 0x60000308, WSbit1 );  // switch all bits off  T='1' time 700ns
      }
      // end of bite write time=1250ns
      bitMask >>= 1;
    }
  }
  os_intr_unlock();
}


void sendWS2() {
  uint32_t writeBits;
  uint8_t  bitMask, time;
  os_intr_lock();
  for (uint16_t t = 0; t < uniSize2; t++) { // outer loop counting bytes
    bitMask = 0x80;
    while (bitMask) {
      // time=0ns : start by setting bit on
      time = 4;
      while (time--) {
        WRITE_PERI_REG( 0x60000304, WSbit2 );  // do ON bits // T=0
      }
      if ( uniData2[t] & bitMask ) {
        writeBits = 0;  // if this is a '1' keep the on time on for longer, so dont write an off bit
      }
      else {
        writeBits = WSbit2;  // else it must be a zero, so write the off bit !
      }
      time = 4;
      while (time--) {
        WRITE_PERI_REG( 0x60000308, writeBits );  // do OFF bits // T='0' time 350ns
      }
      time = 6;
      while (time--) {
        WRITE_PERI_REG( 0x60000308, WSbit2 );  // switch all bits off  T='1' time 700ns
      }
      // end of bite write time=1250ns
      bitMask >>= 1;
    }
  }
  os_intr_unlock();
}


void sendWS3() {
  uint32_t writeBits;
  uint8_t  bitMask, time;
  os_intr_lock();
  for (uint16_t t = 0; t < uniSize3; t++) { // outer loop counting bytes
    bitMask = 0x80;
    while (bitMask) {
      // time=0ns : start by setting bit on
      time = 4;
      while (time--) {
        WRITE_PERI_REG( 0x60000304, WSbit3 );  // do ON bits // T=0
      }
      if ( uniData3[t] & bitMask ) {
        writeBits = 0;  // if this is a '1' keep the on time on for longer, so dont write an off bit
      }
      else {
        writeBits = WSbit3;  // else it must be a zero, so write the off bit !
      }
      time = 4;
      while (time--) {
        WRITE_PERI_REG( 0x60000308, writeBits );  // do OFF bits // T='0' time 350ns
      }
      time = 6;
      while (time--) {
        WRITE_PERI_REG( 0x60000308, WSbit3 );  // switch all bits off  T='1' time 700ns
      }
      // end of bite write time=1250ns
      bitMask >>= 1;
    }
  }
  os_intr_unlock();
}


void sendWS4() {
  uint32_t writeBits;
  uint8_t  bitMask, time;
  os_intr_lock();
  for (uint16_t t = 0; t < uniSize4; t++) { // outer loop counting bytes
    bitMask = 0x80;
    while (bitMask) {
      // time=0ns : start by setting bit on
      time = 4;
      while (time--) {
        WRITE_PERI_REG( 0x60000304, WSbit4 );  // do ON bits // T=0
      }
      if ( uniData4[t] & bitMask ) {
        writeBits = 0;  // if this is a '1' keep the on time on for longer, so dont write an off bit
      }
      else {
        writeBits = WSbit4;  // else it must be a zero, so write the off bit !
      }
      time = 4;
      while (time--) {
        WRITE_PERI_REG( 0x60000308, writeBits );  // do OFF bits // T='0' time 350ns
      }
      time = 6;
      while (time--) {
        WRITE_PERI_REG( 0x60000308, WSbit4 );  // switch all bits off  T='1' time 700ns
      }
      // end of bite write time=1250ns
      bitMask >>= 1;
    }
  }
  os_intr_unlock();
}

void sendWS5() {
  uint32_t writeBits;
  uint8_t  bitMask, time;
  os_intr_lock();
  for (uint16_t t = 0; t < uniSize5; t++) { // outer loop counting bytes
    bitMask = 0x80;
    while (bitMask) {
      // time=0ns : start by setting bit on
      time = 4;
      while (time--) {
        WRITE_PERI_REG( 0x60000304, WSbit5 );  // do ON bits // T=0
      }
      if ( uniData5[t] & bitMask ) {
        writeBits = 0;  // if this is a '1' keep the on time on for longer, so dont write an off bit
      }
      else {
        writeBits = WSbit5;  // else it must be a zero, so write the off bit !
      }
      time = 4;
      while (time--) {
        WRITE_PERI_REG( 0x60000308, writeBits );  // do OFF bits // T='0' time 350ns
      }
      time = 6;
      while (time--) {
        WRITE_PERI_REG( 0x60000308, WSbit5 );  // switch all bits off  T='1' time 700ns
      }
      // end of bite write time=1250ns
      bitMask >>= 1;
    }
  }
  os_intr_unlock();
}


void loop() {
  if (udp.parsePacket()) {
    udp.read(hData, ARTNET_HEADER + 1);
    if ( hData[0] == 'A' && hData[1] == 'r' && hData[2] == 't' && hData[3] == '-' && hData[4] == 'N' && hData[5] == 'e' && hData[6] == 't') {
      if ( hData[8] == 0x00 && hData[9] == ARTNET_DATA && hData[15] == net ) {

        if ( hData[14] == (subnet << 4) + universe1 ) { // UNIVERSE One
          if (!uniSize1) {
            uniSize1 = (hData[16] << 8) + (hData[17]);
          }
          udp.read(uniData1, uniSize1);
        }

        if ( hData[14] == (subnet << 4) + universe2 ) { // UNIVERSE two
          if (!uniSize2) {
            uniSize2 = (hData[16] << 8) + (hData[17]);
          }
          udp.read(uniData2, uniSize2);
        }

        if ( hData[14] == (subnet << 4) + universe3 ) { // UNIVERSE drei
          if (!uniSize3) {
            uniSize3 = (hData[16] << 8) + (hData[17]);
          }
          udp.read(uniData3, uniSize3);
        }
        if ( hData[14] == (subnet << 4) + universe4 ) { // UNIVERSE vier
          if (!uniSize4) {
            uniSize4 = (hData[16] << 8) + (hData[17]);
          }
          udp.read(uniData4, uniSize4);
     /*   }
          if ( hData[14] == (subnet << 4) + universe5 ) { // UNIVERSE fünf
          if (!uniSize5) {
            uniSize5 = (hData[16] << 8) + (hData[17]);
          }
          udp.read(uniData5, uniSize5); */
         
          sendWS1();
          sendWS2();
          sendWS3();
          sendWS4();
          //sendWS5();
        }

      } // if Artnet Data

}}}

Nikolov

hey @w31x

is the code you posted the working one with 4 universes on one pin?

which software do you use to controll the pixels?

w31x

@nikolov: Yes its the one for 4 universes

I donnt know a lot how to handle more universes than 4 on one controller and if nobody can help me with that ... now i built 4 controllers with each 4 universes and one accesspoint to drive jinx on 2048 pixels.

The next problem i got is, if i connect to the accespoint, only 2 or 3 controllers connect and the datatransfer works ... sometimes i have to do a reset with all 4 controllers and sometimes they connect all and the show works absolutely perfect.. but sometimes only a few connect.
The AP is very close to the controllers and yes they all have no ceramic antennas but sometimes i got a good connection and all works as it should!!! I also tryed an 8266 accesspoint with worser results...so i think the problem cannt be only the Wifi router..

If nobody can help me to run more universes on one controller, it would be great if at least someone can help me out here.

DavidAutomacao


Hello Edison, how can I get your Artnet code 32 universe thanks

w31x

why does it only work with an special WiFi AP?
i made an Access-point with an ESP07 and ESP12 with b,g,n but the result is that it stucks and jerks and there is no smoothness anymore..

i tried an old WiFi AP with 11Mbit (b) 54Mbit(g) and 150Mbit(n) but it works only on (b) ?!

can someone explain this?

Joshi32

Hello,

as ESP8266 do not like to disable interrupts as this lead to unintention resets or other strange behavior, unstable running, flicker, packedloss, connection loss, flicker etc.

The code in this post uses a bitbang method for sending data to pixels.
The ESP8266 has an I2S interface and DMA engine so it is possible to send out data in hardware without disabling interrupts. The hardware control the data flow to the LEDs and the CPU could receive WLAN packets.

So I was confusing nobody has mentioned it or maybe it is just to confuse someone? Or is it just to advertise ;)?


ColF

ey mcnobby

for a long I tried to rund 2 universes on my esp8266 (NodeMCU 1.0) for my 20*10 matrix but no succes. :(

I tried nearly everthing, but it didn´t work. Might you be so friendly and send an example code for 2 universes?

thx. ;)

psander247

Hey
i tried the Code from the first post on my NodeMCU (ESP8266)
Sadly i have a few problems.

1. The strip is flickering randomly when sending data from jinx
2. The controller doesn´t connect to wifi network if it is not connected to a pc. Tried it with different 5V power supplys


Can anybody help me?

Moohr

To start thank you @mcnobby for the hard work this is amazing really would like to see more of your code or beeing able to try It !

@w31x I tried you code and I can't get the first three univers to be read, only get the 4th one. Tried to disable sendWS2();, sendWS3(); and sendWS4(); but can't even show sendWS1();
I am trying to figure out what is wrong but I'm not a code expert so make take time ^^ if you have any idea of what is going on please let me know ;)

hello bob,
first of all thanx for the great job. I've been playing with my D1 mini for a while and now I have 4 universes on one pin (680 pixels). Now I want to supply another pin with the next 4 universes ->  some non-round effects such as green flickers arise on some places and the animation is not as smoothly.
So how do I get more than the 680 pixels on one controller?

Can you please give me a hint ...Thank you!

@psander247 did you connect the led strip to the GND of the NodeMCU ? Sheck any bad soldering on pins. Got mine working straight away

psander247

Yeah,
now it works.

GND NodeMCU->WS2812 was not connected properly  :smiley-confuse:

Should have checked this before :D

I´m working with the 160mhz. Only the 1 pixel flickering (green) is left now.


greetings

ColF

May anyone send my a working code for atb least 2 universes? I just can not manage changing the code right.The LEDs out of the first universe are white and do not response.

Please :smiley-confuse:

arduiflex

hello w31x, I test your code, but I have the same problem like MOOHR, 

@w31x I tried you code and I can't get the first three univers to be read, only get the 4th one

what is the mistake ?

Go Up