OSC meeseage 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 04:28:50 2014 +0000
Commit message:
OSC receiver(Sparkfun CC3000 WiFi Sheild meets mbed!) Supports the following boards with CC3000 Shield.; 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 04:28:50 2014 +0000
@@ -0,0 +1,198 @@
+/*
+<----------------------------------------------------------------------------------
+
+ OSC message Codec(encoder/decoder)
+ 
+ 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){
+  // 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    
+};
+    
+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 04:28:50 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 04:28:50 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 04:28:50 2014 +0000
@@ -0,0 +1,159 @@
+/*
+
+    CC3000 OSC message 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 (KL25Z)
+    (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:
+----------------------------------
+C3000 OSC receiver demo.
+IP address: 192.168.0.2
+
+Wait for packet...
+incomming OSC msg:
+/1 ,
+Received packet from: 192.168.0.23
+-------------------
+
+Wait for packet...
+incomming OSC msg:
+/1/fader3 ,f 0.565401
+Received packet from: 192.168.0.23
+-------------------
+
+Wait for packet...
+incomming OSC msg:
+/1/fader3 ,f 0.565401
+Received packet from: 192.168.0.23
+-------------------
+
+Wait for packet...
+incomming OSC msg:
+/4 ,
+Received packet from: 192.168.0.23
+-------------------
+
+Wait for packet...
+incomming OSC msg:
+/3 ,
+Received packet from: 192.168.0.23
+-------------------
+
+Wait for packet...
+incomming OSC msg:
+/3/xy ,ff 0.604869 0.505618
+Received packet from: 192.168.0.23
+-------------------
+
+Wait for packet...
+----------------------------------  
+*/
+
+#include "mbed.h"
+#include "cc3000.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 "ssid"
+#define PASSWORD "password"
+
+#include "UDPSocket.h"
+
+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"
+
+#define INCOMMING_PORT 8000
+
+#define PACKET_SIZE 512
+#define RECBUF_SIZE 256
+#define PERIOD_BUZZER 10
+
+union OSCarg msg[10];
+char recbuf[RECBUF_SIZE],buff[PACKET_SIZE],packet[PACKET_SIZE];
+
+int main() {
+    pc.baud(115200);
+
+    printf("\n\nCC3000 OSC receiver 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 sock;
+    sock.bind(INCOMMING_PORT);
+    
+    Endpoint receiver;
+
+    while (true) {
+        printf("\nWait for packet...\n");
+        int n = sock.receiveFrom(receiver, 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", receiver.get_address());
+            printf("-------------------\n");
+        };
+    } // while
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Aug 31 04:28:50 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/9327015d4013
\ No newline at end of file