CC3000 UDP Multicast Receive E1.31 DMX over Ethernet

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
shmorgan
 
Posts: 9
Joined: Thu Mar 06, 2014 1:56 pm

CC3000 UDP Multicast Receive E1.31 DMX over Ethernet

Post by shmorgan »

My goal is to combine two adafruit products into one project. I would like to combine the 40 RGB NeoPixel board with the CC3000 board and allow DMX over Ethernet (E 1.31) to be sent to the Wifi module and have the arduino decode the DMX data and display it on the NeoPixel board. This would create a DMX controlled Pixel display. E 1.31 is usually a stream of UDP packets of around 640 bytes. There is a header of around 126 bytes and 512 bytes of data. The code will need to split up the 512 bytes into 3 byte groups to control each LED. This is my first attempt with the CC3000 board.

I kinda hacked up the example code, trying to get this working and would love some suggestions. I know there must be a better way to do this.

Also, I noticed that the Muticast is not working quite right, I think I need to set the mac address to some other value based on the multcast IP address.

If I set the IP address to 239.255.0.1, it should only receive packets to that IP address. right now it will still receive packets to 239.255.0.2.

Some detail:
E 1.31 Universe 1 IP address: 239.255.0.1
E 1.31 is sent over port:5568

I use the program SACNView to generate the test E 1.31 packets. I hope to get this working with LightJam.

Code: Select all

#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/hci.h"
#include "utility/socket.h"
#include "utility/evnt_handler.h"
#include "utility/netapp.h"
#include "utility/debug.h"

// These are the interrupt and control pins
#define ADAFRUIT_CC3000_IRQ   3  // MUST be an interrupt pin!
// These can be any two pins
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10
// Use hardware SPI for the remaining pins
// On an UNO, SCK = 13, MISO = 12, and MOSI = 11
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                         SPI_CLOCK_DIVIDER); // you can change this clock speed

#define WLAN_SSID       "MORGANTOWN-01"           // cannot be longer than 32 characters!
#define WLAN_PASS       "easystreet"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY   WLAN_SEC_WPA2

unsigned long ulMCSocket;

sockaddr tSocketAddr;
sockaddr from;
socklen_t fromlen = 8;

char McastPacketRX[520];
unsigned long recvDataLen;

void setup(void)
{
  Serial.begin(115200);
  Serial.println(F("Hello, CC3000!\n")); 

  displayDriverMode();
  Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);
  
  /* Initialise the module */
  Serial.println(F("\nInitialising the CC3000 ..."));
  if (!cc3000.begin())
  {
    Serial.println(F("Unable to initialise the CC3000! Check your wiring?"));
    while(1);
  }

  /* Optional: Update the Mac Address to a known value */
/*
  uint8_t macAddress[6] = { 0x08, 0x00, 0x28, 0x01, 0x79, 0xB7 };
   if (!cc3000.setMacAddress(macAddress))
   {
     Serial.println(F("Failed trying to update the MAC address"));
     while(1);
   }
*/
  
  uint16_t firmware = checkFirmwareVersion();
  if ((firmware != 0x113) && (firmware != 0x118)) {
    Serial.println(F("Wrong firmware version!"));
    for(;;);
  }
  
  // Per http://e2e.ti.com/support/low_power_rf/f/851/t/292664.aspx
  // aucInactivity needs to be set to 0 (never timeout) or the socket will close after
  // 60 seconds of no activity
  unsigned long aucDHCP       = 14400;
  unsigned long aucARP        = 3600;
  unsigned long aucKeepalive  = 30;
  unsigned long aucInactivity = 0;
  if(aucInactivity == 0)
  {
    Serial.println(F("Setting netapp to not timeout..."));
  }else{
    Serial.print(F("Setting netapp to timeout in "));
    Serial.print(aucInactivity);
    Serial.println(F(" Seconds"));
  }
  long iRet = netapp_timeout_values(&aucDHCP, &aucARP, &aucKeepalive, &aucInactivity);
  if (iRet!=0)
  {
    Serial.print(F("Could not set netapp option, iRet = "));
    Serial.println(iRet);
    Serial.println(F(", aborting..."));
    while(1);
  }else{
    Serial.print(F("set netapp option, iRet = "));
    Serial.println(iRet);
  }
  
  displayMACAddress();
  
  /* Optional: Get the SSID list (not available in 'tiny' mode) */
#ifndef CC3000_TINY_DRIVER
  //listSSIDResults();
#endif
  
  /* Delete any old connection data on the module */
  Serial.println(F("\nDeleting old connection profiles"));
  if (!cc3000.deleteProfiles()) {
    Serial.println(F("Failed!"));
    while(1);
  }

  /* Attempt to connect to an access point */
  char *ssid = WLAN_SSID;             /* Max 32 chars */
  Serial.print(F("\nAttempting to connect to ")); Serial.println(ssid);
  
  /* NOTE: Secure connections are not available in 'Tiny' mode! */
  if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
    Serial.println(F("Failed!"));
    while(1);
  }
   
  Serial.println(F("Connected!"));
  
  /* Wait for DHCP to complete */
  Serial.println(F("Request DHCP"));
  while (!cc3000.checkDHCP())
  {
    delay(100); // ToDo: Insert a DHCP timeout!
  }  

  /* Display the IP address DNS, Gateway, etc. */  
  while (! displayConnectionDetails()) {
    delay(1000);
  }
  
  /* You need to make sure to clean up after yourself or the CC3000 can freak out */
  /* the next time you try to connect ... */
  //Serial.println(F("\n\nClosing the connection"));
  //cc3000.disconnect();
  
  // create MCAST address 224.0.1.187 port 5454
  // create MCAST address 239.255.0.1 port 5568
  tSocketAddr.sa_family = AF_INET;
  
  // the destination port
  tSocketAddr.sa_data[0] = 0x15;
  tSocketAddr.sa_data[1] = 0xc0;
  
  // the destination IP address
  tSocketAddr.sa_data[2] = 0xef;
  tSocketAddr.sa_data[3] = 0xff;
  tSocketAddr.sa_data[4] = 0x00;
  tSocketAddr.sa_data[5] = 0x01;

  // Setup Multicast Receive Mode
  ulMCSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

  Serial.println(F("Opened Socket!"));
  
  bind(ulMCSocket, &tSocketAddr, sizeof(sockaddr));
  
  Serial.println(F("Bind Socket!"));

}

void loop(void)
{
  
  while(1) {
    Serial.println(F("Recv from Socket!"));

    int rcvlen = recvfrom(ulMCSocket, &McastPacketRX[0], 95, 0, &from, &fromlen);

    if(rcvlen>0) {
       Serial.println(F("Data!"));

       cc3000.printHex((byte*)&McastPacketRX[0],rcvlen);
       Serial.println(rcvlen);
       //Serial.println(from);
       Serial.println(fromlen);
    }
  
  }
}

/**************************************************************************/
/*!
    @brief  Displays the driver mode (tiny of normal), and the buffer
            size if tiny mode is not being used

    @note   The buffer size and driver mode are defined in cc3000_common.h
*/
/**************************************************************************/
void displayDriverMode(void)
{
  #ifdef CC3000_TINY_DRIVER
    Serial.println(F("CC3000 is configure in 'Tiny' mode"));
  #else
    Serial.print(F("RX Buffer : "));
    Serial.print(CC3000_RX_BUFFER_SIZE);
    Serial.println(F(" bytes"));
    Serial.print(F("TX Buffer : "));
    Serial.print(CC3000_TX_BUFFER_SIZE);
    Serial.println(F(" bytes"));
  #endif
}

/**************************************************************************/
/*!
    @brief  Tries to read the CC3000's internal firmware patch ID
*/
/**************************************************************************/
uint16_t checkFirmwareVersion(void)
{
  uint8_t major, minor;
  uint16_t version;
  
#ifndef CC3000_TINY_DRIVER  
  if(!cc3000.getFirmwareVersion(&major, &minor))
  {
    Serial.println(F("Unable to retrieve the firmware version!\r\n"));
    version = 0;
  }
  else
  {
    Serial.print(F("Firmware V. : "));
    Serial.print(major); Serial.print(F(".")); Serial.println(minor);
    version = major; version <<= 8; version |= minor;
  }
#endif
  return version;
}

/**************************************************************************/
/*!
    @brief  Tries to read the 6-byte MAC address of the CC3000 module
*/
/**************************************************************************/
void displayMACAddress(void)
{
  uint8_t macAddress[6];
  
  if(!cc3000.getMacAddress(macAddress))
  {
    Serial.println(F("Unable to retrieve MAC Address!\r\n"));
  }
  else
  {
    Serial.print(F("MAC Address : "));
    cc3000.printHex((byte*)&macAddress, 6);
  }
}


/**************************************************************************/
/*!
    @brief  Tries to read the IP address and other connection details
*/
/**************************************************************************/
bool displayConnectionDetails(void)
{
  uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv;
  
  if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv))
  {
    Serial.println(F("Unable to retrieve the IP Address!\r\n"));
    return false;
  }
  else
  {
    Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress);
    Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask);
    Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway);
    Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv);
    Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv);
    Serial.println();
    return true;
  }
}

/**************************************************************************/
/*!
    @brief  Begins an SSID scan and prints out all the visible networks
*/
/**************************************************************************/

void listSSIDResults(void)
{
  uint8_t valid, rssi, sec, index;
  char ssidname[33]; 

  index = cc3000.startSSIDscan();

  Serial.print(F("Networks found: ")); Serial.println(index);
  Serial.println(F("================================================"));

  while (index) {
    index--;

    valid = cc3000.getNextSSID(&rssi, &sec, ssidname);
    
    Serial.print(F("SSID Name    : ")); Serial.print(ssidname);
    Serial.println();
    Serial.print(F("RSSI         : "));
    Serial.println(rssi);
    Serial.print(F("Security Mode: "));
    Serial.println(sec);
    Serial.println();
  }
  Serial.println(F("================================================"));

  cc3000.stopSSIDscan();
}
Last edited by adafruit_support_mike on Thu Mar 27, 2014 1:43 am, edited 1 time in total.
Reason: added CODE tags to preserve the formatting

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: CC3000 UDP Multicast Receive E1.31 DMX over Ethernet

Post by adafruit_support_rick »

Don't change the MAC address.

I would start by adding a check on your bind, to make sure that it worked. It should return 0 for success.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”