DMX interface (DMX in/out, Art-Net in/out, DMX patch) http://mbed.org/users/okini3939/notebook/dmx-platform/

Dependencies:   ChaNFSSD EthernetNetIf mbed ConfigFile ChaNFS DmxArtNet

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

Go to the documentation of this file.
00001 /*
00002  * DMX Station - mbed DMX Platform
00003  * Copyright (c) 2012 Hiroshi Suga
00004  * Released under the MIT License: http://mbed.org/license/mit
00005  */
00006 
00007 /** @file
00008  * @brief DMX Station
00009  */
00010 
00011 /*
00012  * "Node" Device
00013  * "Universe" 512 DMX datas
00014  * "Sub-Net" 16 Universe
00015  * "Server" Controller
00016  *
00017  * can use over 40 Sub-Net on network.
00018  */
00019 
00020 #include "dbg.h"
00021 #include "mbed.h"
00022 #include "EthernetNetIf.h"
00023 #include "DmxArtNet.h"
00024 #include "DMX.h"
00025 #include "NEC950MHz.h"
00026 #include "dmx_patch.h"
00027 
00028 #define LED_NET_ACT_ON led_yk = 0
00029 #define LED_NET_ACT_OFF led_yk = 1
00030 #define LED_NET_G_ON led_gayk = 1; led_gkya = 0
00031 #define LED_NET_Y_ON led_gayk = 0; led_gkya = 1
00032 #define LED_NET_GY_OFF led_gayk = 0; led_gkya = 0
00033 
00034 // for Touchable Fountains (Juco)
00035 #define UDP_PORT 10465
00036 #define RF_CH 31
00037 
00038 DigitalOut led_red(p22), led_yellow(p23);
00039 DigitalOut led_gayk(p24),led_gkya(p25), led_yk(p26);
00040 DigitalIn eth_link(P1_25), eth_speed(P1_26);
00041 DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
00042 EthernetNetIf *eth;
00043 Serial pc(USBTX, USBRX);
00044 
00045 DmxArtNet art;
00046 DMX dmx1(p13, p14);
00047 DMX dmx2(p28, p27);
00048 
00049 UDPSocket udp;
00050 
00051 volatile int patch_update = 0;
00052 volatile int art_update[2] = {0, 0};
00053 volatile int rf_update = 0, rf_flg = 0;
00054 char dmx_art[2][512] __attribute__((section("AHBSRAM0")));
00055 char dmx_udp[512] __attribute__((section("AHBSRAM0")));
00056 char dmx_rf[512] __attribute__((section("AHBSRAM0")));
00057 
00058 
00059 extern "C" void mbed_mac_address(char *s);
00060 
00061 void no_memory () {
00062     led_red = 1;
00063     printf("panic: can't allocate to memory!\r\n");
00064     exit(-1);
00065 }
00066 
00067 void shutdown () {
00068     art.ArtPollReply.NumPorts = 0;
00069     strcpy(art.ArtPollReply.NodeReport, "Shutdown");
00070     art.SendArtPollReply();
00071     art.Done();
00072 }
00073 
00074 void isr_udp (UDPSocketEvent e) {
00075     int len;
00076     Host remote;
00077 
00078     if (e == UDPSOCKET_READABLE) {
00079         // UDP2DMX
00080         LED_NET_ACT_ON;
00081         led_yellow = 1;
00082         led3 = 1;
00083         len = udp.recvfrom((char*)dmx_udp, sizeof(dmx_udp), &remote);
00084         DBG("recv udp %d\r\n", len);
00085         patch_update = 5;
00086     }
00087 }
00088 
00089 void isr_timer () {
00090     led_yellow = 0;
00091     LED_NET_ACT_OFF;
00092     led1 = 0; led2 = 0; led3 = 0; led4 = 0;
00093 }
00094 
00095 int init_artnet (IpAddr *ip) {
00096     char mac[6];
00097     EthernetErr ethErr;
00098 
00099     eth_link.mode(PullUp);
00100     eth_speed.mode(PullUp);
00101 
00102     if (! eth_link) {
00103         LED_NET_G_ON;
00104     }
00105     LED_NET_ACT_ON;
00106 
00107     // create ip address from mac address
00108     mbed_mac_address(mac);
00109     *ip = IpAddr(2, mac[3], mac[4], mac[5]);
00110     eth = new EthernetNetIf(*ip, IpAddr(255,0,0,0), IpAddr(0,0,0,0), IpAddr(0,0,0,0));
00111     ethErr = eth->setup();
00112     if (ethErr) {
00113         LED_NET_Y_ON;
00114         led_red = 1;
00115         return -1;
00116     }
00117 
00118     wait(2);
00119 
00120     // init ArtNet
00121     art.BindIpAddress = *ip;
00122     art.BCastAddress = IpAddr(2,255,255,255);
00123 
00124     art.InitArtPollReplyDefaults();
00125     // Device
00126     art.ArtPollReply.PortType[0] = 128; // output
00127     art.ArtPollReply.PortType[1] = 128; // output
00128     art.ArtPollReply.PortType[2] = 64; // input
00129     art.ArtPollReply.GoodInput[2] = 4;
00130     art.ArtPollReply.PortType[3] = 64; // input
00131     art.ArtPollReply.GoodInput[3] = 4;
00132 
00133     art.Init();
00134     art.SendArtPollReply(); // announce to art-net nodes
00135 
00136     pc.printf("init ArtNet\r\n");
00137     return 0;
00138 }
00139 
00140 int main () {
00141     int i;
00142     Ticker timer;
00143     ifMessage ifmsg;
00144     IpAddr ip;
00145     UDPSocketErr udpErr;
00146 
00147     set_new_handler(no_memory); // new handler function
00148 
00149     pc.baud(112500);
00150     
00151     memset(dmx_art, 0, sizeof(dmx_art));
00152     memset(dmx_udp, 0, sizeof(dmx_udp));
00153     memset(dmx_rf, 0, sizeof(dmx_rf));
00154 
00155     load_patch();
00156     timer.attach(&isr_timer, 0.1);
00157 
00158     // init ArtNet
00159     if (init_artnet(&ip)) return -1;
00160     pc.printf("Bind to interface: %d.%d.%d.%d\r\n", (unsigned char)ip[0], (unsigned char)ip[1], (unsigned char)ip[2], (unsigned char)ip[3]);
00161 
00162     // init UDP2DMX
00163     udpErr = udp.bind(Host(ip, UDP_PORT, NULL));
00164     if (udpErr) {
00165         pc.printf("Bind error (udp2dmx)\r\n");
00166         return -1;
00167     }
00168     udp.setOnEvent(&isr_udp);
00169     pc.printf("init UDP2DMX\r\n");
00170 
00171     // init NEC950MHz
00172     if (! init_rf(RF_CH)) {
00173         pc.printf("init RF\r\n");
00174     }
00175 
00176     pc.printf("ArtNode begin\r\n");
00177 
00178     for (;;) {
00179         Net::poll();
00180 
00181         if (! eth_link) {
00182             LED_NET_G_ON;
00183         } else {
00184             LED_NET_GY_OFF;
00185         }
00186 
00187         if (dmx1.is_recived) {
00188             // dmx in 1
00189             LED_NET_ACT_ON;
00190             led_yellow = 1;
00191             led1 = 1;
00192             patch_update = 1;
00193             dmx1.is_recived = 1;
00194             DBG("recv, dmx 1\r\n");
00195         }
00196 
00197         if (dmx2.is_recived) {
00198             // dmx in 2
00199             LED_NET_ACT_ON;
00200             led_yellow = 1;
00201             led1 = 1;
00202             patch_update = 2;
00203             dmx2.is_recived = 2;
00204             DBG("recv, dmx 2\r\n");
00205         }
00206 
00207         if (art.Work()) {
00208             // ArtNet
00209             LED_NET_ACT_ON;
00210             led_yellow = 1;
00211             led2 = 1;
00212             patch_update = art.LastRecievedUniverse + 3;
00213             DBG("recv, node %d\r\n", art.LastRecievedUniverse + 1);
00214         }
00215 
00216         if (patch_update) {
00217             // update DMX patch
00218             led4 = 1;
00219             patch();
00220             DBG("update");
00221         
00222             for (i = 0; i < 2; i ++) {
00223                 // ArtNet good status
00224                 if (art_update[i]) {
00225                     DBG("art good");
00226                     Net::poll();
00227                     art.ArtPollReply.GoodInput[i] = 128;
00228                     art.Send_ArtDmx(i, 0, dmx_art[i], 512);
00229                     art_update[i] = 0;
00230                 }
00231             }
00232 
00233             if (! rf_flg && rf_update) {
00234                 // RF send
00235                 send_rf(MSGID_SEND_NOACK, 0xffffffff, dmx_rf, 200);
00236                 rf_flg = 1;
00237                 rf_update = 0;
00238             }
00239 
00240             patch_update = 0;
00241         }
00242 
00243         if (rf_flg && read_rf(&ifmsg) > 0) {
00244             // RF responce
00245             DBG("recv %d\r\n", ifmsg.msgid);
00246             if (ifmsg.msgid != MSGID_ACK) {
00247                 DBG("no ack\r\n");
00248             }
00249             rf_flg = 0;
00250         }
00251     }
00252 }
00253