This allows an LPC1768 to take Art-Net data and send it to WS2812B LED's

Dependencies:   mbed mbed-rtos EthernetInterface

main.cpp

Committer:
tonydbeck
Date:
2018-12-26
Revision:
15:c730bd607d9a
Parent:
11:59dcefdda506

File content as of revision 15:c730bd607d9a:

//Code adapted from ArtNode by Suga Koubou 
//https://os.mbed.com/users/okini3939/code/ArtNode/file/e3d0bc58141e/main.cpp/





#include "mbed.h"
#include "EthernetInterface.h"
#include "ArtNet.h"
#include "NeoStrip.h"
#include "gt.h"

#define STATIC
#define DNS_SERVER_ADDRESS(ipaddr)        (ip4_addr_set_u32(ipaddr, ipaddr_addr("192.168.1.254")))
#define ECHO_SERVER_PORT   0x1936
#define DATA_PIN p18
#define LED_COUNT 300
 
 
const char *ipAddr = "192.168.1.130";
const char *snMask = "255.255.255.0";
const char *gwAddr = "192.168.1.254";
int okToWrite;
//******************************************Art-Net Stuff*******************************
extern "C" void mbed_mac_address(char *s);
struct ArtPacketHeader ArtHead;
struct ArtDMX_Packet ArtDMX;
struct ArtPoll_Packet ArtPoll;
struct ArtAddr localaddr;
struct ArtPollReply_Packet ArtPollReply;
int rxlen = 0;
int LastRecievedUniverse;

NeoStrip strip(DATA_PIN, LED_COUNT);

void InitArtPollReplyDefaults () {
   memcpy(ArtPollReply.ID, ArtHeaderID, 8);
   ArtPollReply.OpCode = OP_PollReply; // reply packet
   ArtPollReply.Version = ArtVersion;

   memcpy(&ArtPollReply.Addr, &localaddr, sizeof(localaddr));
   strncpy(ArtPollReply.ShortName, STR_ShortName, 18);
   strncpy(ArtPollReply.LongName, STR_LongName, 64);
   strncpy(ArtPollReply.NodeReport, "OK", 64);
   ArtPollReply.Style = StyleNode;

   mbed_mac_address((char*)&ArtPollReply.Mac);

   ArtPollReply.NumPortsH = 0;
   ArtPollReply.NumPorts = 2;
   ArtPollReply.Swout[0] = 1;
   ArtPollReply.Swout[1] = 2;
   ArtPollReply.Swout[2] = 0;
   ArtPollReply.Swout[3] = 0;
   ArtPollReply.Swin[0] = 0;
   ArtPollReply.Swin[1] = 0;
   ArtPollReply.Swin[2] = 0;
   ArtPollReply.Swin[3] = 0;

   ArtPollReply.GoodOutput[0] = 0;
   ArtPollReply.GoodOutput[1] = 0;
   ArtPollReply.GoodOutput[2] = 0;
   ArtPollReply.GoodOutput[3] = 0;
   ArtPollReply.PortType[0] = 0x40; // bit7:Can output from Art-Net network, bit0-5: 0 - type = DMX512 
   ArtPollReply.PortType[1] = 0x40;
   ArtPollReply.PortType[2] = 255;
   ArtPollReply.PortType[3] = 255;
  
 } 
  
   
void Init_ArtDMX ()
 {
   // header stuff
   okToWrite = 0;
   memcpy(ArtDMX.ID, ArtHeaderID, 8);
   ArtDMX.OpCode = OP_Output;
   ArtDMX.Version = ArtVersion;
   // dmx stuff
   ArtDMX.Universe = 0; // this is the destination for the dmx
   ArtDMX.Sequence = 0;
   ArtDMX.Length = htons(512);
}
// Converts HSV to RGB with the given hue, assuming
// maximum saturation and value
int hueToRGB(float h)
{
    // lots of floating point magic from the internet and scratching my head
    float r, g, b;
    if (h > 360)
        h -= 360;
    if (h < 0)
        h += 360;
    int i = (int)(h / 60.0);
    float f = (h / 60.0) - i;
    float q = 1 - f;
    
    switch (i % 6)
    {
        case 0: r = 1; g = f; b = 0; break;
        case 1: r = q; g = 1; b = 0; break;
        case 2: r = 0; g = 1; b = f; break;
        case 3: r = 0; g = q; b = 1; break;
        case 4: r = f; g = 0; b = 1; break;
        case 5: r = 1; g = 0; b = q; break;
        default: r = 0; g = 0; b = 0; break;
    }
    
    // scale to integers and return the packed value
    uint8_t R = (uint8_t)(r * 255);
    uint8_t G = (uint8_t)(g * 255);
    uint8_t B = (uint8_t)(b * 255);
 
    return (R << 16) | (G << 8) | B;
}

int makeword16 (int lsb, int msb)
{
    return (msb << 8) + lsb;
}
//*************************************************************************************


 
    


void thread1(void const *args)
{
    
    while(true) 
    {  
   /* static float dh = 360.0 / LED_COUNT;
    static float x = 0;
 
    for (int i = 0; i < LED_COUNT; i++)
        strip.setPixel(i, hueToRGB((dh * i) - x));
    
    x += 1;
    if (x > 360)
        x = 0;*/
   
    
        strip.write();
    
    Thread::wait(10);      
    }
}   


int main() {
    strip.setBrightness(1.0);    // set default brightness
    strip.setPixels(0, LED_COUNT, gt_img);
    strip.write();

    EthernetInterface eth;
#ifdef STATIC
    eth.init(ipAddr,snMask,gwAddr); //Use DHCP
#else
    eth.init();
#endif
    eth.connect();
    printf("\r\nIP Address is %s\r\n", eth.getIPAddress());
    
    
    
    
    
      
    
 
 /*   
    TCPSocketConnection sock;
    sock.connect("mbed.org", 80);
    
    char http_cmd[] = "GET /media/uploads/mbed_official/hello.txt HTTP/1.0\n\n";
    sock.send_all(http_cmd, sizeof(http_cmd)-1);
    
    char buffer[300];
    int ret;
    while (true) {
        ret = sock.receive(buffer, sizeof(buffer)-1);
        if (ret <= 0)
            break;
        buffer[ret] = '\0';
        printf("Received %d chars from server:\n%s\n", ret, buffer);
    }
      
    sock.close();
    
    eth.disconnect();
    */
    
    
   
    InitArtPollReplyDefaults();
    
    ArtPollReply.PortType[0] = 128;
    ArtPollReply.PortType[1] = 128;
    ArtPollReply.PortType[2] = 64;
    ArtPollReply.GoodInput[2] = 4;
    ArtPollReply.PortType[3] = 64;
    ArtPollReply.GoodInput[3] = 4;
    
    UDPSocket server;
    server.bind(ECHO_SERVER_PORT);
    server.set_broadcasting();
    
    Endpoint client;
    
    char *RecvByte;
    char buffer[1500];
   // char outputString[512];
    
    
    int pos;
    int x,y;
    
    Thread t1(thread1); //start thread1
    //t1.set_priority(osPriorityRealtime);
    
    while (true) {
       // printf("\r\nWaiting for UDP packet...\r\n");
        int n = server.receiveFrom(client, buffer, sizeof(buffer));
        buffer[n] = '\0';
        
        
        memcpy(&ArtHead,buffer,sizeof(ArtPacketHeader));
        if(strncmp(ArtHead.ID, ArtHeaderID, 8) == 0 )
        {
            RecvByte = &buffer[10];
           // printf("Valid ArtNet packet\r\n");
        }
        
       // printf("\nID = %s \n",ArtHead.ID);
        
        switch(ArtHead.OpCode)
        {
            case OP_Output:
                //printf("OPCode = Output,%#x Size = %d\r\n",ArtHead.OpCode,n);
                ArtDMX.VersionH = RecvByte[0];
                ArtDMX.Version = RecvByte[1];
                ArtDMX.Sequence = RecvByte[2];
                ArtDMX.Physical = RecvByte[3];
                x = RecvByte[4];
                y = RecvByte[5];
                ArtDMX.Universe = makeword16(x,y);
                LastRecievedUniverse = ArtDMX.Universe;
                x = RecvByte[6];
                y = RecvByte[7];
                ArtDMX.Length = makeword16(y,x);
                //printf("VerH: %d, VerL: %d, Seq: %d, Phys: %d, Univ: %d, Length: %d\r\n",ArtDMX.VersionH,ArtDMX.Version,ArtDMX.Sequence,ArtDMX.Physical,ArtDMX.Universe,ArtDMX.Length); //used for debugging
                int byteLoc = 0;
                if(ArtDMX.Universe == 1)
                {
                     
                     for (pos = 0;pos<170;pos++)
                     {
                        byteLoc = (pos*3);
                        strip.setPixel(pos, RecvByte[8+byteLoc],RecvByte[9+byteLoc],RecvByte[10+byteLoc]);
                        //  printf("%d, ",RecvByte[8+pos])
                     }
                     
                }
                
                if(ArtDMX.Universe == 2)
                {
                   
                    for (pos = 170;pos<300;pos++)
                    {
                        byteLoc = ((pos-170)*3);
                        strip.setPixel(pos, RecvByte[8+byteLoc],RecvByte[9+byteLoc],RecvByte[10+byteLoc]);
                        
                    }
                }
             //   strip.write();
                break;
                
            case OP_Poll:
                printf("OpCode = Poll, %#x, Size: %d\r\n",ArtHead.OpCode,n);
                ArtPoll.VersionH = RecvByte[0];
                ArtPoll.Version = RecvByte[1];
                ArtPoll.TalkToMe = RecvByte[2];
                printf("Sending Reply\r\n");
                server.sendTo(client, (char*)&ArtPollReply, sizeof(ArtPollReply));
                printf("Sent Reply Complete\r\n");
                break;
            
            default:
                printf("No OPcode read, OPCode=%#x, Size: %d\r\n",ArtHead.ID,n);
                break;
        } 
            
        
        
       // printf("Received packet from: %s\r\n", client.get_address());
     //   printf("Packet contents : '%s'\r\n",buffer);
        //printf("Sending Packet back to Client\n");
        //server.sendTo(client, buffer, n);
       
    }


    while(1) {}
}