Send message from Processing to Touch OSC Mk1 to update a led status

Hi everyone, I am actually working on a processing Sketch to link with Touch OSC app on Iphone / Ipad
to create a custom MIDI controller
I am almost done to cover the functionalities that I need to build my interface.

Last thing that I cannot get to work yet is to be able to turn on and off a led on the interface. I receive all events that I need but for the last part, I need to send a osc message to the iphone to turn on the led.
I think the message is received but the led does not turn on.

If any of you have the time to take a look a t it to help me figured out what I an doing wrong, that would be awesome

Here is the Touch OSC file of the interface :
Touch_OSC file

Here is my code below :

import oscP5.*;
import netP5.*;

OscP5 oscP5;
NetAddress myRemoteLocation;
int portOutgoing = 8000;

void setup()
{
  frameRate(25);
    oscP5 = new OscP5(this,8000);
    myRemoteLocation = new NetAddress("192.168.11.3",8000);  // please change with your local IP
    
    oscP5.plug(this, "toggleFunction", "/1/toggle_button");
    oscP5.plug(this, "pushButtonFunction", "/1/push_button");
}


public void pushButtonFunction(float pushButtonValue) {

    print("push button value received : " + pushButtonValue);
  OscMessage myMessage = new OscMessage("/1/ledPink");
  myMessage.add(1.0);
  oscP5.send(myMessage, myRemoteLocation);
 
}

public void toggleFunction(float toggleValue) {
  print("toggle value button received : " + toggleValue);
}

void draw() {
  background(0);  
}

/* incoming osc message are forwarded to the oscEvent method. */
void oscEvent(OscMessage theOscMessage) {
  
  if(theOscMessage.isPlugged()==false) {
  /* print the address pattern and the typetag of the received OscMessage */
    print("### received an osc message.");
    print(" addrpattern: "+theOscMessage.addrPattern());
    println(" typetag: "+theOscMessage.typetag());
  }
}

Hi @dams2007, you are welcome, but sad to see there is no rush of people familiar with this, and it’s not something I’ve done either. Please clarify: the Processing sketch is running on a PC/Mac? Communicating to app on the iPhone? Where’s the MIDI device? and where are the LEDs?

The the two libraries, oscP5, netP5 - (I tried installing, but failed, not sure why) - do they have examples? is there anything there that helps?

Richard.

1 Like

Hi @RichardDL, thank you for paying attention to my post. So for more clarification I am running Processing 3 on MAC, so the interface that I created with the Touch OSC Editor, is running on my iphone, which is basically a virtual MIDI controller whose communicating with my Processing Sketch.

But everything can run on Mac and Windows, same for Android and iOS

To explain you the all setup, please watch that video. Joshua Davis is probably explaining better than me.
Setup Touch OSC + Processing

The library oscP5 is here but can download it directly from the Processing app. netP5 is part of the oscP5 library

PS: About the app, be careful there is actually 2 app on the GooglePlay or the Appstore, Touch OSC and Touch OSC Mk1. The right one is the Touch OSC Mk1

Here is everything you need for the setup

Touch OSC editor

Touch OSC bridge (to transfer the interface from Touch OSC editor to the Touch OSC Mk1 app)

Touch OSC Mk1 iOS App

You have everything you need on that page
https://hexler.net/touchosc-mk1

Please let me know if you need more details.

Hi @dams2007 again, I had a look at the video and the oscP5 examples (on another PC). Lots of code re sending and receiving messages. “…turn on and off a led on the interface.” Does the interface document the address(?) of the led? Can you combine this information with the given examples to send the message and turn on the led?

Hi @RichardDL , so yes the interface have the address of the led, that’s actually there that you can define it.

and this the code where I actually send the message to the led :

OscMessage myMessage = new OscMessage("/1/ledPink");
myMessage.add(1.0);
oscP5.send(myMessage, myRemoteLocation);

and I have the confirmation in the console that the led receive the OSC message

 addrpattern: /1/ledPink typetag: f

Interesting. (So how can it not work?) Is “OSC” greyed out? or is that how it shows selected? What about that OSC: auto tick box? Anything to go on the front of /1/ledPink? (1.0) have you tried (1), (“1”), (“1.0”) ? Try anything: increase the range to 3, send 1,2,3. Are there any other indicators? text? image?, button? Often once one thing is working it provides information to fix the others.

@RichardDL Yes it means selected for the OSC that been greyed out.
The auto tick box gives you a default path, in my case it’s the same path.
I tried to setup all different type of value (String, Int or float) result is the same.

But to check things differently, I tried to setup a label with a default text and tried to be update it by pressing the button. But no change on the phone.

So I am thinking that i could be the connection but I am able to transfer my interface the the device and I am able to print out message in the console from my interactions with the phone.

OscMessage myMessage = new OscMessage("/1/label_1");
myMessage.add("LetsGo");
oscP5.send(myMessage, myRemoteLocation);

Hi @dams2007 I got your message and did this for you.
Most of my Touch OSC work was done several years in Processing 1.0. But I am in the process of upgrading this to Processing 3. I don’t have any simple programs that show how to write to the iPad, but I have written one to show you how it can be done. It uses the first page of the “simple” layout that comes with Touch OSC. I can’t seem to attach a zip file or .pde so I will have to post it in text here. The buttons at the bottom of the simple layout if you click on them will toggle their state. The sliders are not controlled in this example, but all elements on the iPad or phone are reflected on the processing screen output hope it helps.

/**
 * TouchOSC
 * 
 * Example displaying values received from
 * the "Simple" layout (Page1)
 * and sending back a mouse click on the toggle boxes to Touch OSC
 * by Mike Cook Jan 2022
 *
 * About Tpuch OSC see http://hexler.net/touchosc
 *
 */

import oscP5.*;
import netP5.*;
OscP5 oscP5;
NetAddress myRemoteLocation;
String iPadIP = "192.168.178.20"; // change this to the Local IP address of your iPad / iPhone

float v_fader1 = 0.0f;
float v_fader2 = 0.0f;
float v_fader3 = 0.0f;
float v_fader4 = 0.0f;
float v_fader5 = 0.0f;
float v_toggle[] = {0.0f, 0.0f, 0.0f, 0.0f };
String toggleAddress [] = {"/1/toggle1", "/1/toggle2", "/1/toggle3", "/1/toggle4"};

boolean needsRedraw = true;
boolean mouseHit = false;
int buttonHit = 0;
int buttonRects[][] = { {22,374,50,40},   // array of button rectangles
                         {97,374,50,40},
                         {173,374,50,40},
                         {249,374,50, 40 }
                        };

void setup() {
  size(320,440);
  frameRate(25);
  println("OSC can take 30 seconds or so to connect");
  /* start oscP5, listening for incoming messages at port 8000 */
  oscP5 = new OscP5(this,8000);
    // set the local IP address on the iPod to this
  myRemoteLocation = new NetAddress(iPadIP, 8001); // local IP on the iPad
  // in choosing a static IP address make sure it is in the same domain as the host
}

void oscEvent(OscMessage theOscMessage) {

    String addr = theOscMessage.addrPattern();
    float  val  = theOscMessage.get(0).floatValue();
    
    if(addr.equals("/1/fader1"))        { v_fader1 = val; }
    else if(addr.equals("/1/fader2"))   { v_fader2 = val; }
    else if(addr.equals("/1/fader3"))   { v_fader3 = val; }
    else if(addr.equals("/1/fader4"))   { v_fader4 = val; }
    else if(addr.equals("/1/fader5"))   { v_fader5 = val; }
    else if(addr.equals("/1/toggle1"))  { v_toggle[0] = val; }
    else if(addr.equals("/1/toggle2"))  { v_toggle[1] = val; }
    else if(addr.equals("/1/toggle3"))  { v_toggle[2] = val; }
    else if(addr.equals("/1/toggle4"))  { v_toggle[3] = val; }
    
    needsRedraw = true;
}

void draw() {

if(needsRedraw == true){
      background(0);
    // fader5 + toggle 1-4 outlines
    fill(0);
    stroke(0, 196, 168);  

    rect(17,21,287,55);
    rect(17,369,60,50);
    rect(92,369,60,50);
    rect(168,369,60,50);
    rect(244,369,60,50);

    // toggle 1-4 fills
    fill(0, 196, 168);
    rect(17,21,v_fader5*287,55);
    if(v_toggle[0] == 1.0f) rect(22,374,50,40);
    if(v_toggle[1] == 1.0f) rect(97,374,50,40);
    if(v_toggle[2] == 1.0f) rect(173,374,50,40);
    if(v_toggle[3] == 1.0f) rect(249,374,50,40);
    
    // fader 1-4 outlines
    fill(0);
    stroke(255, 237, 0);
    rect(17,95,60,255);
    rect(92,95,60,255);
    rect(168,95,60,255);
    rect(244,95,60,255);
    
    // fader 1-4 fills
    fill(255, 237, 0);
    rect(17,95 + 255 - v_fader1*255,60,v_fader1*255);
    rect(92,95 + 255 - v_fader2*255,60,v_fader2*255);
    rect(168,95 + 255 - v_fader3*255,60,v_fader3*255);
    rect(244,95 + 255 - v_fader4*255,60,v_fader4*255);
    needsRedraw = false;
  }
}

 void updateiPad(int button){// update the iPad 
      OscMessage myMessage = new OscMessage(toggleAddress[button]);
      myMessage.add(v_toggle[button]);
      //println("message is ", myMessage);
      oscP5.send(myMessage, myRemoteLocation);
      bufDelay(4); // make sure we don't do thing too fast
     } 

 void bufDelay(long pause){
   pause = pause + millis();
   while(pause > millis()) { } // do nothing
 }
 
void mousePressed() {
 int x,y;
  x = mouseX; 
  y = mouseY; 
  //println("Mouse down at"+x+" "+y);  
  buttonHit = findRect(x, y, 4);
    if(buttonHit != -1) {
    mouseHit= true;
    noStroke();
    if(v_toggle[buttonHit] == 1.0f){
      fill(0, 0, 0);
      v_toggle[buttonHit] = 0.0f;
    }
      else {
        fill(0, 196, 168);
        v_toggle[buttonHit] = 1.0f;
      }
    rect(buttonRects[buttonHit][0], buttonRects[buttonHit][1], buttonRects[buttonHit][2], buttonRects[buttonHit][3]);
    //println("hit button ",buttonHit, "value", v_toggle[buttonHit]);
    needsRedraw = true;
  } 
}

int findRect(int x, int y, int numRects){
  int recDetc = -1;
  for(int i = 0; i<numRects; i++){
     if( x > buttonRects[i][0] && x < (buttonRects[i][0] + buttonRects[i][2]) && y > buttonRects[i][1] && y < (buttonRects[i][1] + buttonRects[i][3])) {
      recDetc = i;
     }
  }
  return recDetc;
}


void mouseReleased() {
  if(mouseHit){
    mouseHit = false;
    if(buttonHit != -1)updateiPad(buttonHit);
  }
}

Hi again,
I have been looking at your code. I have got it so the pink LED toggles when you click on the Processing window. Make sure your Touch OSC setup has port incoming set to 8001 and outgoing to 8000.

import oscP5.*;
import netP5.*;

OscP5 oscP5;
NetAddress myRemoteLocation;
int portOutgoing = 8000;
float led = 1.0;

void setup()
{
  frameRate(25);
    oscP5 = new OscP5(this,8000);
    myRemoteLocation = new NetAddress("192.168.178.20",8001);
    
   println("click in the window to toggle the LED");
}


void pushButtonFunction(float ledValue) {
  //print("test");
    print("push button value received : " + ledValue);
    OscMessage myMessage = new OscMessage("/1/ledb8");
    myMessage.add(ledValue);
    oscP5.send(myMessage, myRemoteLocation);
}

public void toggleFunction(float toggleValue) {
  print("toggle value button received : " + toggleValue);
}

void draw() {
  background(0);  
}

void mousePressed() {
  pushButtonFunction(led);
  // toggle LED state for next time
  if(led == 0.0f) led = 1.0f; else led = 0.0f;
  
}

/* incoming osc message are forwarded to the oscEvent method. */
void oscEvent(OscMessage theOscMessage) {
  
  if(theOscMessage.isPlugged()==false) {
  /* print the address pattern and the typetag of the received OscMessage */
    print("### received an osc message.");
    print(" addrpattern: "+theOscMessage.addrPattern());
    println(" typetag: "+theOscMessage.typetag());
  }
}

Note in the Touch OSC template you posted on the drop box this LED was named ledb8. Your later posts indicate you changed the name, This code works with the template you posted on your drop box.

1 Like

Hi @Grumpy_Mike, thanks a lot for replying to my issue.

I tried both code that you sent. So for the first one, from my phone, I can interact with the Processing sketch by clicking the bottom buttons without problems. But if I tried to tap the buttons on the Processing sketch, nothing is happening on the phone.

And for the second one, nothing is happening even in the console. I am starting to think that it could be a security issue with the new iOS 15 update. I did not have the opportunity to try with the older version.

I tried with a different computer and different devices as well to see if that could change anything but I am getting the same result.

I don’t know about that, but my iPad is running iOS 14.8 on an iPad Air2. With my Mac running macOS 12.1. I am also running Processing 3.5.4

If there is a perceived security issue you normal get a pop up window asking for confirmation. I suppose you are sure the both Mac and mobile device are connected to the same network. Would you like me to post a video of the code I posted working?

Just a thought, have you updated the oscP5 library to the latest version of V0.9.9?
I have also tested your code on Processing 4 beta 4 and it works.

Make sure on your mobile device the Host is set to the IP address of the Mac, sometimes a router can give your Mac a different IP address when it joins your network, so it is worth checking.

I will give iOS 15 a go later and let you know if it is that?

Well its not that, I just updated this morning to 15.3 and it is still working.
So I think we have covered all bases on the versions front. That only leaves the route between phone and mac. Please ensure the phone is connected to the same network as the Mac.

I had a problem some time ago with my laptop and a Raspberry Pi. I used to log into the Pi from the networks page and was able to exchange files with the Pi using a GUI to transfer them just like the Mac. However, occasionally while the laptop and the Pi could both see and use the internet I couldn’t connect between the two. It turned out it was something to do with the router. A power down on the router for 30 seconds would fix it.

To see if you have the same sort of problem try pinging your phone from your Mac.

To do this open up a terminal window and type
ping <your phone’s IP address> -c 5

Of course replacing <your phone’s IP address> with the actual numbers of you iPhone given by the address in the Touch OSC configuration page.
If the two can see each other you will get five pings sent and you will see the time it took to respond, otherwise you will get a packet lost message.

Yes I tried with Processing 4 and I have the same result.
I think I have the correct IP address. You can see it on the captures

And here the ping, I just did in terminal :

damienbigot@Damiens-iMac ~ % ping 192.168.11.6 -c 5
PING 192.168.11.6 (192.168.11.6): 56 data bytes
64 bytes from 192.168.11.6: icmp_seq=0 ttl=64 time=37.002 ms
64 bytes from 192.168.11.6: icmp_seq=1 ttl=64 time=56.042 ms
64 bytes from 192.168.11.6: icmp_seq=2 ttl=64 time=77.001 ms
64 bytes from 192.168.11.6: icmp_seq=3 ttl=64 time=95.933 ms
64 bytes from 192.168.11.6: icmp_seq=4 ttl=64 time=114.866 ms

--- 192.168.11.6 ping statistics ---
5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 37.002/76.169/114.866/27.669 ms
damienbigot@Damiens-iMac ~ % 

In terms of test I think everything looks fine but I noticed something strange.
I was not receiving anything in the terminal since I put different port for incoming and outgoing.
So I tried to put the same port everywhere just to see what will happen.
And I am able to get /1/ledPink from the oscEvent function again

So I setup this sketch to resume the situation.

import oscP5.*;
import netP5.*;

OscP5 oscP5;
NetAddress myRemoteLocation;

float valueLed = 0.0;

void setup()
{
  frameRate(25);
  size(512, 512);
    oscP5 = new OscP5(this, 8000);
    myRemoteLocation = new NetAddress("192.168.11.2", 8000);
    oscP5.plug(this, "toggleFunction", "/1/toggle_button");
}

public void toggleFunction(float toggleValue) {
  OscMessage myMessage = new OscMessage("/1/ledPink");
  myMessage.add(toggleValue);
  oscP5.send(myMessage, myRemoteLocation);
}

void updateBackground() {
  if (valueLed == 1.0) {
    background(#FF3300);
  }else {
    background(#000000);
  }
}

void draw() {
  updateBackground();
}

/* incoming osc message are forwarded to the oscEvent method. */

void oscEvent(OscMessage theOscMessage) {
  print(theOscMessage + "    ");
  print(" addrpattern: " + theOscMessage.addrPattern() + "    ");
  println(" typetag: "+ theOscMessage.typetag() + "    ");
  if(theOscMessage.isPlugged()==false) {
    valueLed = theOscMessage.get(0).floatValue();
    if(theOscMessage.checkAddrPattern("/1/ledPink")==true) {
      print("value led ", theOscMessage.get(0).floatValue());
    }
   }
}

With this I am able to send and receive value from my phone because with the
print(theOscMessage); I can see the IP of it.

For the port issue looks like it’s switching automatically to a different port

/192.168.11.6:8000 | /1/toggle_button f     addrpattern: /1/toggle_button     typetag: f    
/192.168.11.2:63614 | /1/ledPink f     addrpattern: /1/ledPink     typetag: f    
value led  1.0

So I think in this situation, we can be sure that the event is send but never received.
But if I put different port for incoming and outgoing the OSC message is not even send.

This is because you are using the same port for incoming and outgoing. The OSC manual says

Which I, and common sense says you should use a different values of port for in and out.
You should never get any message from the LED because you can not control it from your phone, the LED can only be controlled from your computer. That is what you setup on your OSC template.

The other problem with what you posted here is that you never send any message from processing to the LED. Only one message is attempted to be sent in the setup function and that is you attempt to send a message to the toggle_button. I thought you wanted to send a message to the LED?

Your oscEvent function only shows messages from the phone, it does not show messages that you send, so lack of activity in the console just shows the lack of the phone sending anything. I have got that last code you posted to work and have the window reflect the state of the LED. I have added a print statement to show you are sending a message so you will see activity in the console when you click on the processing window to toggle the LED. If you can’t get this to work then try with the template that you originally posted on your drop box, as far as I can see then this is the only difference between our two setups.

import oscP5.*;
import netP5.*;

OscP5 oscP5;
NetAddress myRemoteLocation;

float valueLed = 0.0; // click in window to toggle the led

void setup()
{
  frameRate(25);
  size(512, 512);
    oscP5 = new OscP5(this, 8000);
    //myRemoteLocation = new NetAddress("192.168.11.2", 8001); // dams
    myRemoteLocation = new NetAddress("192.168.178.20", 8001); // Mike Cook
    //oscP5.plug(this, "toggleFunction", "/1/toggle_button");
    toggleFunction(valueLed); // set Led to the state  defined above
}

void toggleFunction(float toggleValue) {
  OscMessage myMessage = new OscMessage("/1/ledb8"); // Mike Cook
  //OscMessage myMessage = new OscMessage("/1/ledPink"); // dams
  myMessage.add(toggleValue);
  oscP5.send(myMessage, myRemoteLocation);
      // toggle LED state for next time
  if(valueLed == 0.0f) valueLed = 1.0f; else valueLed = 0.0f;
}

void updateBackground() {  // this toggles the background depending on the valueLed 
  if (valueLed == 1.0) {
    background(#000000);
  }else {
    background(#FF3300);
  }
}

void mousePressed() {
  toggleFunction(valueLed);
  println("A mouse click so set the LED value to", valueLed);
}

void draw() {
  updateBackground();
}

/* incoming osc message are forwarded to the oscEvent method. */
// The problem with this function is that you don't do anything with the recieved message

void oscEvent(OscMessage theOscMessage) {
  print(theOscMessage + "    ");
  print(" addrpattern: " + theOscMessage.addrPattern() + "    ");
  println(" typetag: "+ theOscMessage.typetag() + "    ");
  // As the LED can not send a message then this should never happen
  /*
  if(theOscMessage.isPlugged()==false) {
    valueLed = theOscMessage.get(0).floatValue();
    if(theOscMessage.checkAddrPattern("/1/ledb8")==true) {
      print("value led ", theOscMessage.get(0).floatValue());
    }
   }
   */
}

@Grumpy_Mike Thanks a lot for your help. I tried everything but still getting to same result for now, but I am able at least to interact with my Processing from my phone or IPad. So it’s not a blocking issue to pursue my project. I should just not use the led component. I can use some toggle buttons as a work around to show the status of my actions.

If finally I am figuring out what was wrong for my setup I will put a update here.

OK sorry I couldn’t sort you out, as a final thought I wondered if it could be something to to with the settings.
On my iPad settings under Touch OSC I have enabled the “allow to join other networks”.
On my Mac I have this as the sharing preferences

And under Wi-Fi proxies I have nothing requiring a password

Best of luck with your future projects.
Cheers
Mike

If you are already using the TouchOSC bridge to get MIDI out, you can just send MIDI CC messages back to the iPad instead.

I’m not 100% sure you are doing this because none of the MIDI was enabled in your layout file, but if you don’t need OSC specifically this is an easier way to go.

Thanks, but what we were trying to do is to get a message from processing over to Touch OSC, in order to change things on the OSC screen. Things like an LED that is defined on a template to light up or turn off. We are not trying to do (at this stage) anything to do with MIDI.

Here is something very silly I did with Touch OSC about 5 years ago. No MIDI involved at all.

https://vimeo.com/manage/videos/214817718