OSC meeseage tranceiver(Sender/Receiver) for Sparkfun CC3000 WiFi Shield. Supports the following boards: FRDM-KL25Z,ST Nucleo F401RE,ST Nucleo F030R8,LPCXpresso1549,Seeduino-Arch-Pro.

Dependencies:   cc3000_hostdriver_mbedsocket mbed

Files at this revision

API Documentation at this revision

Comitter:
xshige
Date:
Sun Aug 31 15:10:45 2014 +0000
Child:
1:e62251d890c1
Commit message:
OSC meeseage tranceiver(Sender/Reciver) for Sparkfun CC3000 WiFi Shield. Supports the following boards: FRDM-KL25Z,ST Nucleo F401RE,ST Nucleo F030R8,LPCXpresso1549,Seeduino-Arch-Pro. ;

Changed in this revision

OSCmsgCodec.cpp Show annotated file Show diff for this revision Revisions of this file
OSCmsgCodec.h Show annotated file Show diff for this revision Revisions of this file
cc3000_hostdriver_mbedsocket.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OSCmsgCodec.cpp	Sun Aug 31 15:10:45 2014 +0000
@@ -0,0 +1,203 @@
+/*
+<----------------------------------------------------------------------------------
+
+ OSC message Codec(encoder/decoder)
+ 
+ version: 1.3 (2014/ 8/31) encoder bufix(enoceder returns byte length)   
+ version: 1.2 (2014/ 8/30) decoder bufix 
+ version: 1.1 (2013/11/20) support BIG_ENDIAN by #define
+ version: 1.0 (2013/11/10)
+
+ Copyright (C) 2011,2013,2014 S.Komatsu
+ released under the MIT License: http://mbed.org/license/mit
+
+ please refer to: http://opensoundcontrol.org/introduction-osc for OSC(Open Sound Control)
+
+  The followings are supported:
+
+    Features: 
+     Packet Parsing (Client)
+     Packet Construction (Server)
+     Bundle NOT Support
+     Timetag NOT Support
+
+    Type Support: 
+     i: int32
+     b: blob
+     s: string
+     f: float32
+     m: MIDI message(port id, status byte, data1, data2) // I don't know the detail
+     
+  Change Log:
+   Bug(string length is not correct in encoding) Fix on 2013/11/10 (v0.9 -> v1.0)
+
+>----------------------------------------------------------------------------------
+*/
+
+#include "OSCmsgCodec.h"
+//#define BIG_ENDIAN
+
+int lenAlign4B(int len) {
+    if ((len % 4) == 0) {return len; }
+    else {return len+4-(len % 4);}
+}
+
+
+int encOSCmsg(char *packet , union OSCarg *msg){
+  // *** important notice ***
+  // output buffer must be cleared before call this
+  char *p, *s, *d, *typeTag; 
+  char c;
+
+  p=packet;
+  d=p;
+  s=msg[0].address; // address
+  for(int i=0; i<strlen(msg[0].address); i++) *d++ = *s++;
+  *d=0; // terminator
+//  p += 4*((strlen(msg[0].address)+1)/4+1);
+  p += lenAlign4B(strlen(msg[0].address)+1);
+  // 
+  s=msg[1].typeTag;
+  d=p;
+  for(int i=0; i<strlen(msg[1].typeTag); i++) *d++ = *s++; 
+  *d=0; // terminator   
+//  p += 4*((strlen(msg[1].s)+1)/4+1);
+  p += lenAlign4B(strlen(msg[1].typeTag)+1);
+  //
+  typeTag=msg[1].s+1; // skip ','
+  for(int n=0; n<strlen(typeTag); n++){
+    c = typeTag[n];
+    if (('s'==c)) {
+      s=msg[n+2].s;
+      d=p;
+      for(int i=0; i<strlen(msg[n+2].s); i++) *d++ = *s++;
+      *d=0; // terminater    
+//     p += 4*((strlen(msg[n+2].s)+1)/4+1);
+      p += lenAlign4B(strlen(msg[n+2].s)+1);
+    } 
+    else if (('i'==c)||('f'==c)) {
+#ifdef BIG_ENDIAN
+      // no change endian (big to big)
+      p[0]=msg[n+2]._b[0];
+      p[1]=msg[n+2]._b[1];
+      p[2]=msg[n+2]._b[2];
+      p[3]=msg[n+2]._b[3];
+#else
+      // change endian (little to big)
+      p[0]=msg[n+2]._b[3];
+      p[1]=msg[n+2]._b[2];
+      p[2]=msg[n+2]._b[1];
+      p[3]=msg[n+2]._b[0];
+#endif
+        p +=4;  
+    } 
+    else if ('b'==c) {
+      // put length of blog
+#ifdef BIG_ENDIAN
+      // no change endian (big to big)
+      p[0]=msg[n+2]._b[0];
+      p[1]=msg[n+2]._b[1];
+      p[2]=msg[n+2]._b[2];
+      
+      p[3]=msg[n+2]._b[3];
+#else
+      // change endian (little to big)
+      p[0]=msg[n+2]._b[3];
+      p[1]=msg[n+2]._b[2];
+      p[2]=msg[n+2]._b[1];
+      p[3]=msg[n+2]._b[0];
+#endif
+      p +=4;  
+      // get ponter of blog (copy to msg[n].blog.p)
+      s=msg[n+2].blob.p;
+      d=p;
+      for(int i=0; i<msg[n+2].blob.len; i++) *d++ = *s++;    
+      p += 4*(msg[n+2].blob.len/4+1);       
+    } 
+    else if ('m'==c) {
+      // get midi data (copy to msg[n].m[])
+      p[0]=msg[n+2].m[0]; 
+      p[1]=msg[n+2].m[1]; 
+      p[2]=msg[n+2].m[2];
+      p[3]=msg[n+2].m[3];
+      p +=4;  
+    } 
+    else {
+      //printf("*** Not Supported TypeTag:%s ****\n",typeTag);
+    }
+  };
+  //return (p-packet); // return packet size
+  // bugfix 2014/8/31
+  return sizeof(char)*(p-packet);  // return byte length   
+};
+    
+void decOSCmsg(char *packet , union OSCarg *msg){
+  // Caution: the returned result points to packet as blobs or strings (not newly allocatd)
+  char *p, *typeTag; 
+  char c; int n;
+
+  msg[0].address = packet; // address
+  msg[1].typeTag = packet+4*((strlen(msg[0].s)+1)/4+1);//typeTag
+  typeTag=msg[1].s+1; // skip ','
+  
+  // bugfix 2014/8/30
+  if (strlen(typeTag)%2 == 0) p= msg[1].s+4*((strlen(msg[1].s)+1)/4); 
+  else  p= msg[1].s+4*((strlen(msg[1].s)+1)/4+1);
+  
+  for(n=0; n<strlen(typeTag); n++){
+    c = typeTag[n];
+    if (('s'==c)) {
+      msg[n+2].s=p;
+      //p += 4*((strlen(msg[n+2].s)+1)/4+1);
+      p += lenAlign4B(strlen(msg[n+2].s)+1);
+    } 
+    else if (('i'==c)||('f'==c)) {
+#ifdef BIG_ENDIAN
+      // no change endian (big to big)
+      msg[n+2]._b[0]=p[0];
+      msg[n+2]._b[1]=p[1];
+      msg[n+2]._b[2]=p[2];
+      msg[n+2]._b[3]=p[3];
+#else
+      // change endian (big to little)
+      msg[n+2]._b[3]=p[0];
+      msg[n+2]._b[2]=p[1];
+      msg[n+2]._b[1]=p[2];
+      msg[n+2]._b[0]=p[3];
+#endif
+      p +=4;  
+    } 
+    else if ('b'==c) {
+      // get lenth of blog (copy to msg[n].blog.len)
+#ifdef BIG_ENDIAN
+      // no change endian (big to big)
+      msg[n+2]._b[0]=p[0];
+      msg[n+2]._b[1]=p[1];
+      msg[n+2]._b[2]=p[2];
+      msg[n+2]._b[3]=p[3];
+#else
+      // change endian (big to little)
+      msg[n+2]._b[3]=p[0];
+      msg[n+2]._b[2]=p[1];
+      msg[n+2]._b[1]=p[2];
+      msg[n+2]._b[0]=p[3];
+#endif
+      p +=4;
+      // get ponter of blog (copy to msg[n].blog.p)
+      msg[n+2].blob.p=p;
+      //p += 4*(msg[n+2].blob.len/4+1);       
+      p += lenAlign4B(msg[n+2].blob.len+1);
+    } 
+    else if ('m'==c) {
+      // get midi data (copy to msg[n].m[])
+      msg[n+2].m[0]=p[0]; 
+      msg[n+2].m[1]=p[1]; 
+      msg[n+2].m[2]=p[2];
+      msg[n+2].m[3]=p[3];
+      p +=4;  
+    } 
+    else {
+      //printf("*** Not Supported TypeTag:%s ****\n",typeTag);
+    }
+ };
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OSCmsgCodec.h	Sun Aug 31 15:10:45 2014 +0000
@@ -0,0 +1,30 @@
+// OSC message Codec Header
+// 2013/10/28
+#ifndef _OSCMSGCODEC_H
+#define _OSCMSGCODEC_H
+
+#include <string.h>
+
+int encOSCmsg(char *packet , union OSCarg *msg);
+// makes packet from OSC message and returns packet size
+
+void decOSCmsg(char *packet , union OSCarg *msg); 
+// makes OSC message from packet
+
+union OSCarg {
+  // char*, int and float are assumed four bytes
+  char *address;
+  char *typeTag;
+  long int i; // int32 for Arduino(16bits)
+  float f;
+  char *s;
+  struct {
+    long int len; // is "int i"
+    char *p;
+  } 
+  blob;
+  char m[4];  // for MIDI
+  char _b[4]; // endian conversion temp variable
+};
+
+#endif // _OSCMSGCODEC_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_hostdriver_mbedsocket.lib	Sun Aug 31 15:10:45 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/Kojto/code/cc3000_hostdriver_mbedsocket/#ca8c234997c0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Aug 31 15:10:45 2014 +0000
@@ -0,0 +1,225 @@
+/*
+    CC3000 OSC message tranceiver(Sender/Receiver)
+
+    Sparkfun CC3000 WiFi Shield meets mbed!
+       
+    This program supports the following mbed boards with Sparkfun CC3000 Sheild.
+    '#define' switches board.(refer to source code)
+    (1)FRDM-KL25Z (K25Z)
+    (2)ST Nucleo F401RE (STM32F401)
+    (3)ST Nucleo F030R8 (STM32F030)
+    (4)LPCXpresso1549 (LPC1549)
+    (5)Seeduino-Arch-Pro (ARCH_PRO)
+
+ Please push RESET button on CC3000 WiFi Shield to start the program.
+
+  reference:  
+    https://www.sparkfun.com/products/12071 for CC300 Shield
+    http://opensoundcontrol.org/introduction-osc for OSC(Open Sound Control)
+
+  date: 2014/8/31
+  written by: xshige
+
+console out sample:
+==========================================
+CC3000 OSC receive&send demo.
+IP address: 192.168.0.3
+This OSC msg sent:
+/1/fader1 ,f 0.000000
+to: 192.168.0.11
+-------------------
+This OSC msg sent:
+/1/fader5 ,f 0.172000
+to: 192.168.0.11
+-------------------
+
+Wait for OSC message...
+
+This OSC msg sent:
+/1/fader5 ,f 0.127000
+to: 192.168.0.11
+-------------------
+
+Wait for OSC message...
+
+incomming OSC msg:
+/1/fader2 ,f 0.761603
+Received packet from: 192.168.0.2
+-------------------
+This OSC msg sent:
+/1/fader5 ,f 0.711000
+to: 192.168.0.2
+-------------------
+
+Wait for OSC message...
+
+incomming OSC msg:
+/1/fader2 ,f 0.767932
+Received packet from: 192.168.0.2
+-------------------
+This OSC msg sent:
+/1/fader5 ,f 0.286000
+to: 192.168.0.2
+-------------------
+
+Wait for OSC message...
+
+==========================================
+*/
+
+#include "mbed.h"
+#include "cc3000.h"
+
+#include "UDPSocket.h"
+
+// define board you like (KL25Z, LPC1549, STM32F401, STM32F030 ...)
+//#define KL25Z
+#define STM32F401
+//#define STM32F030
+//#define LPC1549
+//#define ARCH_PRO
+
+// define SSID, PASSWORD you like
+#define SSID "sssid"
+#define PASSWORD "password"
+
+using namespace mbed_cc3000;
+
+/* cc3000 module declaration specific for user's board. */
+#if defined(KL25Z)
+// for KL25Z
+cc3000 wifi(PTD4, PTC9, PTD0, SPI(PTD2, PTD3, PTD1), SSID, PASSWORD, WPA2, false);
+Serial pc(USBTX, USBRX);
+#endif
+#if defined(STM32F401)
+// for Nucleo STM32F401
+cc3000 wifi(PA_10, PA_8, PB_6, SPI(PA_7, PA_6, PA_5), SSID, PASSWORD, WPA2, false);
+// for Nucleo STM32F401
+Serial pc(SERIAL_TX, SERIAL_RX);
+#endif
+#if defined(STM32F030)
+// for Nucleo STM32F030
+cc3000 wifi(PA_10, PA_8, PB_6, SPI(PA_7, PA_6, PA_5), SSID, PASSWORD, WPA2, false);
+// for Nucleo STM32F030
+Serial pc(SERIAL_TX, SERIAL_RX);
+#endif
+#if defined(LPC1549)
+// for LPC1549
+cc3000 wifi(P0_29, P0_0, P0_27, SPI(P0_28, P0_12, P0_16), SSID, PASSWORD, WPA2, false);
+Serial pc(USBTX, USBRX);
+#endif
+#if defined(ARCH_PRO)
+// for Seeed Studio Arch Pro
+cc3000 wifi(P0_4, P2_5, P0_6, SPI(P0_9, P0_8, P0_7), SSID, PASSWORD, WPA2, false);
+Serial pc(USBTX, USBRX);
+#endif
+
+// OSC related
+#include "OSCmsgCodec.h"
+
+// set yout IP, PORTs
+#define REMOTE_IP "192.168.0.11" // (will be replaced after OSC msg received)
+#define OUTGOING_PORT 9000
+#define INCOMMING_PORT 8000
+    
+#define PACKET_SIZE 512
+#define RECBUF_SIZE 256
+#define PERIOD_BUZZER 10
+
+union OSCarg msg[10], outmsg[10];
+char recbuf[RECBUF_SIZE],buff[PACKET_SIZE],packet[PACKET_SIZE];
+int len, tn;
+
+char sendto_ip[16];
+
+int main() {    
+    // set initial IP to send
+    strcpy(sendto_ip, REMOTE_IP);
+
+    pc.baud(115200);
+
+    printf("\n\nCC3000 OSC receive&send demo. \n");
+    wifi.init();
+    if (wifi.connect() == -1) {
+        printf("Failed to connect. Please verify connection details and try again. \n");
+    } else {
+        printf("IP address: %s \n", wifi.getIPAddress());
+    }
+    
+    UDPSocket udpRec,udpSend;
+    udpSend.init(); udpRec.bind(INCOMMING_PORT);
+
+    Endpoint target, client;
+    target.set_address(REMOTE_IP, OUTGOING_PORT);
+        
+    // send OSC message with random values (to touchOSC)
+    // make OSC message for sending
+    outmsg[0].address="/1/fader1";    
+    outmsg[1].typeTag=",f";
+    outmsg[2].f= 0.0;
+    memset(packet,0,sizeof(packet)); // clear send buff for OSC msg
+    len=encOSCmsg(packet,outmsg);
+    // send it
+    target.set_address(sendto_ip, OUTGOING_PORT);    
+    udpSend.sendTo(target, packet, len);
+    pc.printf("This OSC msg sent:\n%s %s %f\n", outmsg[0].address, outmsg[1].typeTag, outmsg[2].f);
+    pc.printf("to: %s\n", sendto_ip);
+    pc.printf("-------------------\n");
+    wait_ms(10);
+ 
+    while (true) {
+#if 0
+        // xy 
+        // send OSC message with random values  (to touchOSC)
+        // make OSC message for sending
+        outmsg[0].address="/3/xy";    
+        outmsg[1].typeTag=",ff";
+        outmsg[2].f = rand()%1000/1000.0;
+        outmsg[3].f = rand()%1000/1000.0;
+        memset(packet,0,sizeof(packet)); // clear send buff for OSC msg
+        len=encOSCmsg(packet,outmsg);
+        target.set_address(sendto_ip, OUTGOING_PORT);    
+        udpSend.sendTo(target, packet, len);        
+//pc.printf("len:%d\n",len);
+        pc.printf("This OSC msg sent:\n%s %s %f %f\n", outmsg[0].address, outmsg[1].typeTag, outmsg[2].f, outmsg[3].f);
+        pc.printf("to: %s\n", sendto_ip);
+        pc.printf("-------------------\n");
+        wait_ms(10);
+#else
+        // fader
+        // send OSC message with random values (to touchOSC)
+        // make OSC message for sending
+        outmsg[0].address="/1/fader5";    
+        outmsg[1].typeTag=",f";
+        outmsg[2].f= rand()%1000/1000.0;
+        memset(packet,0,sizeof(packet)); // clear send buff for OSC msg
+        len=encOSCmsg(packet,outmsg);
+        // send it
+        target.set_address(sendto_ip, OUTGOING_PORT);    
+        udpSend.sendTo(target, packet, len);
+//pc.printf("len:%d\n",len);
+        pc.printf("This OSC msg sent:\n%s %s %f\n", outmsg[0].address, outmsg[1].typeTag, outmsg[2].f);
+        pc.printf("to: %s\n", sendto_ip);
+        pc.printf("-------------------\n");
+        wait_ms(10);
+#endif
+
+        // receive OSC message        
+        printf("\nWait for OSC message...\n\n");
+        int n = udpRec.receiveFrom(client, recbuf, sizeof(recbuf));
+        if (n >= 0) {
+            decOSCmsg(recbuf, msg);
+            pc.printf("incomming OSC msg:\n%s %s", msg[0].address, msg[1].typeTag);
+            for(int m=0; m < (strlen(msg[1].typeTag)-1); m++) {
+                if (msg[1].typeTag[m+1]=='f') pc.printf(" %f",msg[m+2].f);
+                if (msg[1].typeTag[m+1]=='i') pc.printf(" %d",msg[m+2].i);                
+            }
+            pc.printf("\n");
+            printf("Received packet from: %s \n", client.get_address());
+            printf("-------------------\n");
+            // change IP to send
+            strcpy(sendto_ip, client.get_address());
+            wait_ms(10);
+        };
+    } // while (true)
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Aug 31 15:10:45 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/9327015d4013
\ No newline at end of file