Control of mbed using OSC. Based on code from the Make Controller. Right now you can turn the onboard LEDs on/off and toggle 8 digital out pins. More I/O will be done in the future.

Dependencies:   mbed

mbed_osc.cpp

Committer:
pehrhovey
Date:
2010-03-17
Revision:
0:439354122597

File content as of revision 0:439354122597:

/*
 * mbed_osc.cpp
 *
 *  Created on: Mar 8, 2010
 *      Author: pehr
 *       The functions to control the mBed using OSC
 *     This includes setting up the UDP and  OSC subsystem
 *     And registering handlers to control mBed I/O
 */
 /*********************************************************************************

 Copyright 2006-2009 MakingThings

 Licensed under the Apache License,
 Version 2.0 (the "License"); you may not use this file except in compliance
 with the License. You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software distributed
 under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 CONDITIONS OF ANY KIND, either express or implied. See the License for
 the specific language governing permissions and limitations under the License.

*********************************************************************************/
#include "mbed_osc.h"


//Subsystems
#include "mbed_system_osc.h"
#include "mbed_io_osc.h"
//#include "mbed_analogin_osc.h"

#include <stdarg.h>

InterruptIn button(p5);

DigitalOut got_udp(LED1);
Timeout got_udp_TO;
void got_udp_off(){got_udp=0;}

DigitalOut sent_udp(LED4);
Timeout sent_udp_TO;

void sent_udp_off(){sent_udp=0;}


DigitalOut green_led(p14);
Timeout green_led_TO;
void green_led_off(){green_led=0;}
DigitalOut green_led2(p18);

void sent_udp_lights(){
     if(green_led==0){
    green_led = 1;
    green_led_TO.attach(&green_led_off, 0.5);
    }
    if(sent_udp==0){
    sent_udp = 1;
    sent_udp_TO.attach(&sent_udp_off, 1.0);//auto turn-off
    }
}

void got_udp_lights(){
    if(got_udp == 0){
       got_udp = 1; //LED
       got_udp_TO.attach(&got_udp_off, 1.0);//auto turn-off
    }
}

char scratch1[OSC_SCRATCH_SIZE]; //for building OSC messages
NetServer *osc_net;

struct udp_pcb *osc_pcb; //Bound to receiving port, listening for messages

int lights = 0; //flash lights when we send/receive packets?
int echo = 1; //echo received packets?

NetServer * getNetServer(){ //get the netserver to do things like get hostname
    return osc_net;
}
char * getScratch(){
    return scratch1;
}
struct udp_pcb * getUdpPcb(){
    return osc_pcb;
}

/**UDP recv callback  */

void udp_recv_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
{
    LWIP_UNUSED_ARG(arg);
 //  printf("Received UDP Packet on port %d\r\n",port);

   if(lights)
       got_udp_lights();
  /* if packet is valid */
  if (p != NULL) {
      int length = (int)p->len;

  //  printf("UDP Packet Received! Payload:\r\n");
 //   printf("-- %s -- length: %d\r\n",static_cast<char *>(p->payload),length);

    char *message = (char *)p->payload;

    if(echo && *message!= '/'){ //Echo if its not OSC
         err_t code = udp_sendto(upcb, p, IP_ADDR_BROADCAST, UDP_BROADCAST_PORT); //send it back to port 5555
         printf("Echo'd non-OSC packet, result code is %d\r\n",code);
        if(lights)
            sent_udp_lights();
   }

   //Do something based on the packet...

    OscChannel *ch = Osc_GetChannel(OSC_CHANNEL_UDP);

    memcpy(ch->incoming, message,length);
    //Process packet

    Osc_SetReplyAddress( OSC_CHANNEL_UDP, addr );
    //this would send it back on the same port but we may not be listening on that port
 // Osc_SetReplyPort( OSC_CHANNEL_UDP, port );
    Osc_SetReplyPort( OSC_CHANNEL_UDP, UDP_BROADCAST_PORT ); //this never changes
    Osc_ReceivePacket( OSC_CHANNEL_UDP, ch->incoming, length );

    /* must free the pbuf */
    pbuf_free(p);

  }
}

void osc_sendIPBroadcast(){

    //broadcast IP and the port we are listening on

    //Make sure it goes to broadcast

    Osc_SetReplyAddress( OSC_CHANNEL_UDP, IP_ADDR_BROADCAST );
    Osc_SetReplyPort( OSC_CHANNEL_UDP, UDP_BROADCAST_PORT );

    //Ensure that the property numbers have not changed
    SystemOsc_PropertyGet( 3, OSC_CHANNEL_UDP ); // /system/ipinfo
    Osc_SendPacket(OSC_CHANNEL_UDP); //have to manually send since we didnt go thru normal packet receiving
    //printf("Sent /system/ipinfo msg to broadcast IP and port\r\n");

    if(lights)
        sent_udp_lights();
}

/*
 * Initialize Mbed OSC
 * -Set up network interface
 * -Register UDP receive callback
 * -Set up OSC subsystem to handle received messages
 */
 int osc_init(){
     printf("Initializing Network Interface with DHCP\r\n");

     /*Initialize NetServer which gets us our DHCP address and
    gets the network interface ready
    and set up UDP
    */
   osc_net = NetServer::ready();
   //Initialize UDP
   osc_pcb = udp_new();

  if (osc_pcb != NULL) {
    /* we have to be allowed to send broadcast packets! */
    osc_pcb->so_options |= SOF_BROADCAST;
    udp_bind(osc_pcb, IP_ADDR_ANY, UDP_RECV_PORT); //Receive from any IP address, on the specified port
    udp_recv(osc_pcb,udp_recv_callback, NULL);
  }else{
  printf("Could not make UDP pcb\r\n");
  return;
  }

 osc_net->setHostname("chapala");
  printf("Network Interface Initialized\r\n");

  //Now set up OSC system

  //Configure OSC UDP Channel
  Osc_SystemInit(osc_pcb);

  button.rise(&osc_sendIPBroadcast); //Callback to broadcast the IP and Port that it is listening on

  //Register handlers for mBed control stuff

  //SystemOsc subsystem -- get system info like IP address

  int reg1 = Osc_RegisterSubsystem( SystemOsc_GetName(), SystemOsc_ReceiveMessage, NULL );
  printf("Registered OscSystem, result is %d \r\n",reg1);

  //IoOsc subsystem - get/set digital I/O pins
  int reg2 = Osc_RegisterSubsystem( IoOsc_GetName(), IoOsc_ReceiveMessage, NULL );
  printf("Registered IoSystem, result is %d \r\n",reg2);


  //LedOsc subsystem - get/set onboard LED
  int reg3 = Osc_RegisterSubsystem(LedOsc_GetName(), LedOsc_ReceiveMessage, NULL );
  printf("Registered LedSystem, result is %d \r\n",reg3);

  //AnalogInOsc subsystem - read analog inputs
//  int reg4 = Osc_RegisterSubsystem(AnalogInOsc_GetName(),AnalogInOsc_ReceiveMessage, NULL );
//  printf("Registered AnalogInSystem, result is %d \r\n",reg4);

  //Broadcast the IP for anyone that is listening on the right port
  printf("Broadcasting IP on port %d\r\n",UDP_BROADCAST_PORT);
  osc_sendIPBroadcast();
}

/* Poll netserver for received messages
 * Must be called during main while(1) loop, very fast
 */
void osc_poll(){
    osc_net->poll();
}