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.
Diff: mbed_osc.cpp
- Revision:
- 0:439354122597
diff -r 000000000000 -r 439354122597 mbed_osc.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed_osc.cpp Wed Mar 17 03:17:38 2010 +0000 @@ -0,0 +1,220 @@ +/* + * 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(); +} + + \ No newline at end of file