Manage datas from jit.matrix to send values to a matrix of LED arranged differently. Worked with 192 datas not with 384. SOLVED

benjamin vyger's icon

Hellooo ;)

I need to transform data from a jit.matrix of layer 8*16*3.
I use this data to control a matrix of 8*16 RGB LEDs.
My LED matrix is arranged in a snake, or zigzag in French. In fact, it is a single strip of 128 LEDs that are bent every 8 LEDs.

The matrix is like that

1 2 3 4 5 6 7 8
16 15 14 13 12 11 10 9
17 18 19 20 21 22 23 24
... 26 25

Thanks to a good engineer on this forum, I manage to change the data transmission mode every 8*3 data.
It works perfectly with 8*8 matrices managing RGB LEDs.

Now it's almost the same problem with 128 LEDs and not just 64.
With 64 datas, the value in zl.group was 192. (64*3 layers).
So I change the value to 384. (128*3).
But as you see after the [zl.group] object, I only have 256 datas not 384 datas
While I changed the maximum size. length of group zl to 512 with inspector.

after zl.group we see only 16*16 datas. Here we see inspector of jit.matrix. It is set at 512 datas too.

So, what is the problem?
When I tap on [coll] I see only 256 datas. The problem should be there.
Big thanks in advance

Max Patch
Copy patch and select New From Clipboard in Max.

TFL's icon

Try to explicitely declare [zl.group 384 @zlmaxsize 512] instead of just changing the attribute in the inspector view (it was still 256 when I pasted your example patch).

benjamin vyger's icon

Thank you very much.
I did what you say.

Max Patch
Copy patch and select New From Clipboard in Max.

But now, when I set the object of the bottom to [zl.group 384 @zlmaxsize 512] I don't receive anymore datas in the ESP32. I tested several maxsize at 290 and my ESP32 can't manage datas. maxsize set at 289 esp32 works.

Maybe you can see something with the esp32 program made with Arduino IDE. I receive OSC datas from IP 192.168.1.142 and local port 8000
With maxsize 290 Arduino ide print error


/*---------------------------------------------------------------------------------------------

  Open Sound Control (OSC) library for the ESP8266/ESP32

  Example for receiving open sound control (OSC) messages on the ESP8266/ESP32
  Send integers '0' or '1' to the address "/led" to turn on/off the built-in LED of the esp8266.

  This example code is in the public domain.

--------------------------------------------------------------------------------------------- */

#include <WiFi.h>
#include <WiFiUdp.h>
#include <OSCMessage.h>
#include <OSCBundle.h>
#include <OSCData.h>

#include <WiFiMulti.h>

WiFiMulti wifiMulti; // select wifi automatically

WiFiUDP Udp;

const unsigned int outPort = 9999;    // remote port (not needed for receive)
const unsigned int localPort = 8000;  // local port to listen for UDP packets (here's where we send the packets)

OSCErrorCode error;
unsigned int ledState = LOW;  // LOW means led is *on*. not use

//------------ END  ESP and OSC setting

#define LED_BUILTIN 16
#define BUILTIN_LED LED_BUILTIN

#include <FastLED.h>
#define NUM_LEDS 128// 64. number of led
//#define PIN_CONTROLLING_STRIP 21 // 21 node 97 // 1 heltcec
#define PIN_CONTROLLING_STRIP 21 // 21 node 97 // 1 heltcec
CRGB leds[NUM_LEDS];

//----------- END FastLed setting

#define numberOfDataPerLed 3 // not sure it is usefull
#define numberOfLed 128 // not sure it is usefull

int size;

void setup() {

   Serial.begin(115200);
   pinMode(BUILTIN_LED, OUTPUT);
   digitalWrite(BUILTIN_LED, ledState);  // turn *on* led
   delay(10);

    
    wifiMulti.addAP("Bbox-E69F0626", "NKg5Ad1m3mXFgx142p");
    wifiMulti.addAP("SFR-d078", "DEDW3VPARYGZ");
 

    Serial.println("Connecting Wifi...");
    if(wifiMulti.run() == WL_CONNECTED) {
        Serial.println("");
        Serial.println("WiFi connected");
        Serial.println("IP address: ");
        Serial.println(WiFi.localIP());
    }

 IPAddress local_IP(192, 168, 1, 142);// 145
    // Set your Gateway IP address
 IPAddress gateway(192, 168, 1, 1);

 IPAddress subnet(255, 255, 0, 0);

    WiFi.mode(WIFI_STA);
  if (WiFi.config(local_IP, gateway, subnet) == false) {
    Serial.print("echec de config");
  }
 
  while (WiFi.status() != WL_CONNECTED) {
    digitalWrite(BUILTIN_LED, HIGH);  // turn *on* led
    delay(500);
     digitalWrite(BUILTIN_LED, LOW);  // turn *on* led
    Serial.print(".");
  }
  Serial.println("");

  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  Serial.println("Starting UDP");
  Udp.begin(localPort);
  Serial.print("Local port: ");
  
#ifdef ESP32
  Serial.print("LocalportESP32: ");
  Serial.println(localPort);
#else
  Serial.println(Udp.localPort());
#endif

  // control LED with FastLed NOT USED
  
  FastLED.addLeds<NEOPIXEL, PIN_CONTROLLING_STRIP>(leds, NUM_LEDS);
  FastLED.setBrightness(180); // 0 to 255
  for (int i = 0; i <= NUM_LEDS; i++) {
    leds[i] = CRGB ( NUM_LEDS-(i+1),128-(2*i), 255-(2*i));
  //  leds[i] = CRGB(0, 0, 0);  // turn off all
    FastLED.show();
  } 
}

void loop() {

    OSCMessage msg;
    size = Udp.parsePacket();
    
    if (size > 0) {
    while (size--) {
      msg.fill(Udp.read());
    }
    if (!msg.hasError()) {
      msg.dispatch("/matrixdata",assignDataParsed); // read only 1/8 datadata and write it 1/64 ( so it light only pixel 0 0)
    }

    else {
      error = msg.getError();
      Serial.print("error: ");
      Serial.println(error);
    }
  }

}
void assignDataParsed(OSCMessage &msg) {
  
  for (uint8_t i = 0; i < NUM_LEDS; i++) {
  /*
    Serial.print (" led number "); Serial.print (i);  Serial.print ("");
    Serial.print ( " r"); Serial.print (msg.getInt(i*3));
    Serial.print ( " g"); Serial.print (msg.getInt(i*3+1)); 
    Serial.print ( " b"); Serial.print (msg.getInt(i*3+2));
    Serial.print ( " H"); Serial.println (msg.getInt(i*3+3));
  */
    leds[i] = CRGB (msg.getInt(i*3+0), msg.getInt(i*3+1), msg.getInt(i*3+2)); // , msg.getInt(i*3+3)  
    digitalWrite(BUILTIN_LED, msg.getInt(i*3+1));  // 30 = i      
  }

  FastLED.show();
}
TFL's icon

When you ask people to help you about an error message you get, it's good practice to provide that error message, usually it gives a clue on what's going wrong ;)

Apparently udp protocole (by which OSC data is transmitted) has a limit size that depends on a lot of settings. Maybe you've reached that limitation. The messages you send are around 300 bytes, that's quite a lot!
I would suggest to break your message appart. Instead of send one 8x16x3 block at the same time, try to send two 8x8x3?

Also, you are still publicly revealing your internet router name and passwords.

Roman Thilenius's icon

where? where? kl!k kl!il p4tch p4tch.

benjamin vyger's icon

OK TFL,
I will split datas in tows parts.
I 'll see tomorrow. Maybe there is a way to receive more data s in ESP32.
Thank u.

Sorry Roman , I can't understand your joke? is this one ?

Source Audio's icon

with 128 LEDS you need to reverse / reorder 8xLED group list of twice the size, compared to what you did with 64 LEDs.
check that umenu.
You need to understand what parts of the patch do.

benjamin vyger's icon

Hi,
Happy reading you!
I checked umenu and I don't understand how to use this function.
I would like to test my system with 8*16 led and I will try 16*16 led.
Could you please adapt the patch for me?
Then I will have to split datas in ESP32 in two or four part.

Max Patch
Copy patch and select New From Clipboard in Max.


TFL's icon

If your data are already in the correct order, just split the list in two parts using [zl.slice 192 @zlmaxsize 512].
Maybe send another message on another address to your ESP32 once all the parts are sent (like a "/matridatacontrol done"), that way you could easily know on the ESP32 when the the current frame is fully dumped.

benjamin vyger's icon

Hi TFL,
Trying to understand the half of what you say, I sliced the 384 datas in two parts.
Then I send datas to different Osc names. matrixdata1 and matrixdata2
Then in esp32 I will say to read matrixdata1 at each odd frame and read matrixdata2 at even frame.
But for now i have to reverse datasin the good wayt, but i don't understand umenu.
And I don't know how to split 384 datas in maxmasp

Max Patch
Copy patch and select New From Clipboard in Max.

manner to split 384 datas in two parts. not the good manner I think


TFL's icon

Please, if you don't know how to use an object, read the doc and check the helper files. Select the object, then ctrl+shift+h or cmd+shift+h (or right click on it and "Open zl.slice Help").

This is how zl.slice works.

As for the umenu, if you don't know what it does, why is it here in the first pace? How did it arrived in your patch?

What do you mean, precisely, when you say "reversing data"? Can you provide an explicit example with a shorter list?

I remember having spent quite some time with you already in a previous thread, you're not really helping us helping you.

benjamin vyger's icon

This the patch working with 64 datas.
8 first data are listed normally 8 following datas are "inversed".
so we have 1 2 3 4 5 6 7 8 16 15 14 13 12 11 10 9 17 18 19 20 21 22 23 24 32 31 30 ....


Max Patch
Copy patch and select New From Clipboard in Max.

I would like to adapt this patch in order to reversed 128 datas with the same arrangement (each 8 datas) .
Not only with 64 datas.
I checked example and help for menu but I don't understand as well :/

Source Audio's icon

in this thred, you started few months go,
after loong posting arround, you finally stated what this reversal should do,
and were offered solutions to do so.

https://cycling74.com/forums/get-values-of-jitmatrix

so go there, read it all and then you should be able to rearange that
list yoursef.

your last post here again is wrong about reversing order !
You even don't understand what you are asking for ....

TFL's icon

I don't know if it's just low effort posting or if OP is struggling with langage, which makes their explanation very blurry and unprecise.

Anyway, I ended up re-doing it for them...
I took the previous patch I did in the last thread, changed the input matrix to 8x16 for testing purpose, changed the last [zl.group 192] by [zl.group 384 @zlmaxsize 512], and added the [zl.slice 192 @zlmaxsize 512]. That's all.

@Benjamin, objects with red borders are the ones you need to transform your matrix into the correct lists.
Objects with red border and purple background are the ones I modified/add since the last working patch I sent you in your previous thread, just so you can see the difference.

About umenu, I forgot in the previous thread I went far enough to provide a benchmark to compare the full zl solution versus the coll+umenu solution, and the zl one appears to be 10 times faster (and it makes things much more manageable if you want to get a sense of what is going and adapt the whole to other situations like, for example, increase your matrix size).


Max Patch
Copy patch and select New From Clipboard in Max.

Source Audio's icon

zl. combo might be faster, on the other hand using things like umenu,
coll , table etc for remapping is more flexible, can recall several mappings,
no need to worry about maxlist size etc.

but problem in this thread was actually failure to receive 384 bytes,
which is not packet size limit on ESP32.
it maxes at 1500, including packet headers

benjamin vyger's icon

Hi Tfl,
Thank u so much for the patch ;)

So for now,
I send first part of datas, from 0 to 191, to "matrixdata".
I send second part of data, from 192 to 384, to "matrixdata1".
As least, it is what I think I am doing !

But I don't have any led lighting in my matrix1 (the one managed by "matrixdata1" and parsed with assignDataParsed1 in the ESP 32). I have only b2=0.
I have these messages errors as if I send too much datas.
I thought sending 192 datas to the first matrix.
Then to the next loop send 192 datas to the second matrix .

11:58:49.373 ->  b2 0
11:58:49.373 ->  b2 0
11:58:49.406 -> errorMatrix: 0
11:58:49.406 -> errorMatrix1: 0
11:58:49.406 -> errorMatrix: 0
11:58:49.406 -> errorMatrix1: 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.439 ->  b 0
11:58:49.470 ->  b 0
11:58:49.470 ->  b 0
11:58:49.470 ->  b 0
11:58:49.470 ->  b 0
11:58:49.470 ->  b 0
11:58:49.470 ->  b 80
11:58:49.470 ->  b 80
11:58:49.470 ->  b 80
11:58:49.470 ->  b 80
11:58:49.470 ->  b 80
11:58:49.470 ->  b 80
11:58:49.470 ->  b 80
11:58:49.470 ->  b 80

So, I did something wrong with the ESP 32 program.

I put only what I changed
void loop()
void assignDataParsed()
void assignDataParsed1()

unsigned long currentTime; 
unsigned long previousTime;
long timeInterval = 100;
boolean switchFrame = true;

void loop() {

    OSCMessage msg;
    size = Udp.parsePacket();
    
    if (size > 0) {
    while (size--) {
      msg.fill(Udp.read());
    }
    
    currentTime = millis(); // or micros*1000()

  if (!msg.hasError() && currentTime - previousTime > timeInterval )
  {
    if (!switchFrame)
    {    
     previousTime = currentTime;
  
     msg.dispatch("/matrixdata",assignDataParsed); // 

     switchFrame=true;
    }
  }
    
  else
  {
      error = msg.getError();
      Serial.print("errorMatrix: ");
      Serial.println(error);
  }
  }

  if (!msg.hasError() && currentTime - previousTime > timeInterval )
  {
    if (switchFrame)
    {
     previousTime = currentTime;
  
     msg.dispatch("/matrixdata1",assignDataParsed1); // 
     switchFrame=false;
    }
  }

  else
  {
    error = msg.getError();
    Serial.print("errorMatrix1: ");
    Serial.println(error);
  }

}

void assignDataParsed(OSCMessage &msg) {
  
  for (uint8_t i = 0; i < NUM_LEDS/2; i++) {
  /*
    Serial.print (" led number "); Serial.print (i);  Serial.print ("");
    Serial.print ( " r"); Serial.print (msg.getInt(i*3));
    Serial.print ( " g"); Serial.print (msg.getInt(i*3+1)); 
    Serial.print ( " b"); Serial.print (msg.getInt(i*3+2));
    Serial.print ( " H"); Serial.println (msg.getInt(i*3+3));
  */
    leds[i] = CRGB (msg.getInt(i*3+0), msg.getInt(i*3+1), msg.getInt(i*3+2)); // , msg.getInt(i*3+3)  
    digitalWrite(BUILTIN_LED, msg.getInt(i*3+1));  // 30 = i     
    Serial.print ( " b "); Serial.println (msg.getInt(i*3+2)); 
  }

  FastLED.show();
}

void assignDataParsed1(OSCMessage &msg) {
  
  for (uint8_t i = NUM_LEDS/2; i < NUM_LEDS; i++) {
  /*
    Serial.print (" led number "); Serial.print (i);  Serial.print ("");
    Serial.print ( " r"); Serial.print (msg.getInt(i*3));
    Serial.print ( " g"); Serial.print (msg.getInt(i*3+1)); 
    Serial.print ( " b"); Serial.print (msg.getInt(i*3+2));
    Serial.print ( " H"); Serial.println (msg.getInt(i*3+3));
  */
    leds[i] = CRGB (msg.getInt(i*3+0), msg.getInt(i*3+1), msg.getInt(i*3+2)); // , msg.getInt(i*3+3)  
    digitalWrite(BUILTIN_LED, msg.getInt(i*3+1));  // 30 = i     
    Serial.print ( " b2 "); Serial.println (msg.getInt(i*3+2)); 
  }

  FastLED.show();
}

TFL's icon

Not even reading at your code. I try to be as explicit as possible with the red borders and all the comments, and you don't even seem to care.

benjamin vyger's icon

Yes, I really appreciate your teaching. It is very clear and explicit.
Thanks again by the way.

I just plugged in the matrix I use "for real" rather than [jit.gen]
I didn't think it was important for further data processing.
Sorry for my communication, I will be care of what I change in patch next time.

So I just put back the patch that you put in at the beginning.
The only changes I made are to add blue objects
[prepend/matrixdata] [prepend/matrixdata1]. These datas go to [udpsend]

objects added in blue

Max Patch
Copy patch and select New From Clipboard in Max.

Now I have a problem by receiving data to esp32.
The program is at the previous thread.

benjamin vyger's icon

I try to receive datas like this in ESP32 by receiving datas with only one void assignDataParsed(OSCMessage &msg)
But no datas from matrixData1 come in ESP32 :/

void loop() {

    OSCMessage msg;
    size = Udp.parsePacket();
    
    if (size > 0) {
    while (size--) {
      msg.fill(Udp.read());
    }

    currentTime = millis(); // or millis()

  if (!msg.hasError() && currentTime - previousTime > timeInterval )
  {
    if (!switchFrame)
    {    
     previousTime = currentTime;
     msg.dispatch("/matrixdata",assignDataParsed); 
    }
  }
    
  else
  {
      error = msg.getError();
      Serial.print("errorMatrix: ");
      Serial.println(error);
  }
  }
  

  if (!msg.hasError() && currentTime - previousTime > timeInterval )
  {
    if (switchFrame)
    {
     previousTime = currentTime;
     msg.dispatch("/matrixdata1",assignDataParsed); 
     switchFrame=false;
    }
  }

  else
  {
    error = msg.getError();
    Serial.print("errorMatrix1: ");
    Serial.println(error);
  }

  Serial.print ( " switchFrame "); Serial.println (switchFrame); 
}

void assignDataParsed(OSCMessage &msg) {
  
   if (switchFrame==true)
   {
      for (uint8_t i = 0; i < NUM_LEDS/2; i++)
      {
       /*
       Serial.print (" led number "); Serial.print (i);  Serial.print ("");
       Serial.print ( " r"); Serial.print (msg.getInt(i*3));
       Serial.print ( " g"); Serial.print (msg.getInt(i*3+1)); 
       Serial.print ( " b"); Serial.print (msg.getInt(i*3+2));
       Serial.print ( " H"); Serial.println (msg.getInt(i*3+3));
       */
       leds[i] = CRGB (msg.getInt(i*3+0), msg.getInt(i*3+1), msg.getInt(i*3+2)); // , msg.getInt(i*3+3)  
       digitalWrite(BUILTIN_LED, msg.getInt(i*3+1));  // 30 = i     
       Serial.print ( " r "); Serial.println (msg.getInt(i*3)); 
      }
    }

   if (switchFrame==false)
   {
    for (uint8_t i = NUM_LEDS/2; i < NUM_LEDS; i++)
     {
     /*
     Serial.print (" led number "); Serial.print (i);  Serial.print ("");
     Serial.print ( " r"); Serial.print (msg.getInt(i*3));
     Serial.print ( " g"); Serial.print (msg.getInt(i*3+1)); 
     Serial.print ( " b"); Serial.print (msg.getInt(i*3+2));
     Serial.print ( " H"); Serial.println (msg.getInt(i*3+3));
     */
     leds[i] = CRGB (msg.getInt(i*3+0), msg.getInt(i*3+1), msg.getInt(i*3+2)); // , msg.getInt(i*3+3)  
     digitalWrite(BUILTIN_LED, msg.getInt(i*3+1));  // 30 = i     
     Serial.print ( " r1 "); Serial.println (msg.getInt(i*3)); 
    }
   }
  FastLED.show();
}

but nothing has changed

14:54:41.491 ->  r1 0
14:54:41.491 ->  r1 0
14:54:41.524 -> errorMatrix1: 4
14:54:41.524 ->  switchFrame 1
14:54:41.524 -> errorMatrix: 0
14:54:41.524 -> errorMatrix1: 0
14:54:41.524 ->  switchFrame 1
14:54:41.557 -> errorMatrix: 0
14:54:41.557 -> errorMatrix1: 0
14:54:41.557 ->  switchFrame 1
14:54:41.588 ->  r 0
14:54:41.588 ->  r 32
14:54:41.588 ->  r 64
14:54:41.588 ->  r 96
14:54:41.588 ->  r 128
14:54:41.588 ->  r 159
14:54:41.588 ->  r 191
Source Audio's icon

If you don't remove that print rubish from arduino code,
no one will ever want to look at it.
how on earth can one help you ?
you even don't understand basics of simple zl.slice object and order of output.

you send right list 192 - 384 to matrix1 first,
0 -191 to matrix later.
In Arduino you fiddle with unfunctional millis... frames ... ?????
that expects matrix 0 - 192 to get in first.

here is one option with fixed number of leds - 128

prepend /mtx1 and /mtx2
maybe a little delay between sending of 2 lists ?
------------
OSC sends int32 (4 bytes per int), that is why limit of 1500 bytes
gets exceeded with your message.
If you would use raw UDP - there would be no such limit and
need to split the list.

Source Audio's icon

This would be raw UDP, send a list with 384 values (and nothing else)
using sadam.udpSender
bold items - replace with your data:

#include <WiFi.h>
#include <WiFiUdp.h>
#include "esp_wifi.h"
WiFiUDP Udp;
IPAddress local_IP(10, 10, 10, 10); IPAddress gateway(10, 10, 10, 1); IPAddress subnet(255, 255, 0, 0); // Router
const unsigned int localPort = 8888; // UDP Port
uint8_t buffer[384];
#include <FastLED.h>
#define NUM_LEDS 128
#define PIN_CONTROLLING_STRIP 21
CRGB leds[NUM_LEDS];

void setup() {
WiFi.mode(WIFI_STA); esp_wifi_set_ps(WIFI_PS_NONE); WiFi.config(local_IP, gateway, subnet);
WiFi.begin("SSID", "12345678"); Udp.begin(localPort); // SSID & password
FastLED.addLeds<NEOPIXEL, PIN_CONTROLLING_STRIP>(leds, NUM_LEDS); FastLED.setBrightness(180);
for (int i = 0; i <= NUM_LEDS; i++) {leds[i] = CRGB(0, 0, 0); // turn off all
FastLED.show();}
}

void loop() {Udp.parsePacket(); if(Udp.read(buffer, 384) > 0) {doit();}
}

void doit(){for (uint8_t i = 0; i < NUM_LEDS; i++)
{leds[i] = CRGB (buffer[i*3+0], buffer[i*3+1], buffer[i*3+2]);}
FastLED.show();
}

benjamin vyger's icon

Good morning,
I tried the second method, it works perfectly.
I will continue to develop the management of several matrices at a distance in order to have an animation that circulates from one matrix to another ;)
Thank you very much again for your help.
I really pay attention to your explanations, your suggestions and your working methods.
The next time, I will go step by step and I hope to be as simple and clear as possible.
I promise you.
Thank you TFL, thank you "SOURCE AUDIO".