Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple Universes on a ESP32 Dev #156

Closed
simplo opened this issue Jun 9, 2024 · 14 comments
Closed

Multiple Universes on a ESP32 Dev #156

simplo opened this issue Jun 9, 2024 · 14 comments

Comments

@simplo
Copy link

simplo commented Jun 9, 2024

Hi all, I'm trying to handle 2 RS485 on the same ESP32 Dev using port1 and port2 but as soon as the dmx_driver_install(dmxPort2, &config, personalities, personality_count); is executed the system crashes.
Would it be possible to handle different (even more than 2) RS485 just uninstalling the driver and reinstalling it with different pins and same UART port at each loop?

@cgiles
Copy link

cgiles commented Jun 9, 2024

Can you share your setup ?

@simplo
Copy link
Author

simplo commented Jun 9, 2024

Hi, it seems to work in this way but the system freezes randomly. :(

#include <Arduino.h>
#include <esp_dmx.h>

// Definizione dei pin
int transmitPin1 = 22;
int enablePin1 = 21;

int transmitPin2 = 17;
int enablePin2 = 2;

// Porta DMX da utilizzare
dmx_port_t dmxPort = 1;

// Buffer per i dati DMX
byte data[DMX_PACKET_SIZE];

// Intervallo di aggiornamento
unsigned long lastUpdate = millis();

void setup() {
Serial.begin(115200);
configureDMX(transmitPin1, enablePin1); // Configura il driver DMX per la prima volta con il primo set di pin
}

void loop() {
unsigned long now = millis();
if (now - lastUpdate >= 100) {
// Aggiorna ogni byte nel pacchetto DMX
for (int i = 1; i < DMX_PACKET_SIZE; i++) {
data[i]++;
}

    // Invia i dati al primo set di pin
    configureDMX(transmitPin1, enablePin1);
    dmx_write(dmxPort, data, DMX_PACKET_SIZE);
    dmx_send(dmxPort);
    dmx_wait_sent(dmxPort, DMX_TIMEOUT_TICK);

    // Invia i dati al secondo set di pin
    configureDMX(transmitPin2, enablePin2);
    dmx_write(dmxPort, data, DMX_PACKET_SIZE);
    dmx_send(dmxPort);
    dmx_wait_sent(dmxPort, DMX_TIMEOUT_TICK);

    // Log dei cambiamenti al monitor seriale
    Serial.printf("Sending DMX 0x%02X\n", data[1]);
    lastUpdate = now;
}

}

void configureDMX(int transmitPin, int enablePin) {
// Disinstalla il driver attuale prima di cambiarne la configurazione
dmx_driver_delete(dmxPort);
// Configurazione e installazione del driver con i nuovi pin
dmx_config_t config = DMX_CONFIG_DEFAULT;
dmx_personality_t personalities[] = {};
dmx_driver_install(dmxPort, &config, personalities, 0);
dmx_set_pin(dmxPort, transmitPin, -1, enablePin);
}

@simplo
Copy link
Author

simplo commented Jun 9, 2024

I found that after some second I get this error:
E (380647) dmx: dmx_driver_delete(251): driver is not installed
E (380657) dmx: parameter malloc error
E (380657) dmx: parameter malloc error
E (380657) dmx: parameter malloc error
E (380657) timer_group: TIMER driver malloc error
E (380661) timer_group: timer_isr_callback_remove(246): HW TIMER NEVER INIT ERROR
E (380668) timer_group: timer_deinit(312): HW TIMER NEVER INIT ERROR
E (380674) dmx: dmx_driver_install(234): timer init error

@simplo
Copy link
Author

simplo commented Jun 9, 2024

Sorry, this is the last code version I have, the error is the same I posted before.

`#include <Arduino.h>
#include <esp_dmx.h>

// configurazoine conteggio FPS
unsigned long lastTime = 0; // Ultima volta che abbiamo registrato il tempo
unsigned long lastReportTime = 0; // Ultima volta che abbiamo riportato il conteggio
int callCount = 0; // Numero di volte che la funzione è stata chiamata

// Definizione dei pin
int transmitPin1 = 22;
int enablePin1 = 21;

int transmitPin2 = 17;
int enablePin2 = 2;

// Porta DMX da utilizzare
dmx_port_t dmxPort = 1;

// Buffer per i dati DMX
byte data[DMX_PACKET_SIZE];

// Intervallo di aggiornamento
unsigned long lastUpdate = millis();

void setup() {
Serial.begin(115200);
configureDMX(transmitPin1, enablePin1); // Configura il driver DMX per la prima volta con il primo set di pin
}

void loop() {
unsigned long now = millis();
//if (now - lastUpdate >= 100) {
// Aggiorna ogni byte nel pacchetto DMX
for (int i = 1; i < DMX_PACKET_SIZE; i++) {
data[i]++;
}

    // Invia i dati al primo set di pin
    configureDMX(transmitPin1, enablePin1);
    dmx_write(dmxPort, data, DMX_PACKET_SIZE);
    dmx_send(dmxPort);
    //dmx_wait_sent(dmxPort, DMX_TIMEOUT_TICK);

    // Invia i dati al secondo set di pin
    configureDMX(transmitPin2, enablePin2);
    dmx_write(dmxPort, data, DMX_PACKET_SIZE);
    dmx_send(dmxPort);
    //dmx_wait_sent(dmxPort, DMX_TIMEOUT_TICK);

    // Log dei cambiamenti al monitor seriale
    Serial.printf("Sending DMX 0x%02X\n", data[1]);
    lastUpdate = now;
    countCallsPerSecond();
//}

}

void configureDMX(int transmitPin, int enablePin) {
// Disinstalla il driver attuale prima di cambiarne la configurazione
dmx_driver_delete(dmxPort);

  // Configurazione e installazione del driver con i nuovi pin
  dmx_config_t config = DMX_CONFIG_DEFAULT;
  dmx_personality_t personalities[] = {};
  dmx_driver_install(dmxPort, &config, personalities, 0);
  dmx_set_pin(dmxPort, transmitPin, -1, enablePin);

}

void countCallsPerSecond() {
unsigned long currentTime = millis();

// Incrementa il conteggio ogni volta che questa funzione viene chiamata
callCount++;

// Controlla se sono passati 5 secondi dall'ultimo report
if (currentTime - lastReportTime >= 1000) {
// Calcola quante volte al secondo la funzione è stata chiamata
float callsPerSecond = (float)callCount / 1.0;

// Stampa il risultato sulla porta seriale
Serial.print("Chiamate al secondo negli ultimi 5 secondi: ");
Serial.println(callsPerSecond);

// Resetta il conteggio e aggiorna l'ultimo tempo di report
callCount = 0;
lastReportTime = currentTime;

}
}
`

@simplo
Copy link
Author

simplo commented Jun 10, 2024

NEW UPDATE:

I'm using this code now, it works (I mean it doesn't crashes) but it seems to send same data to both the pins gorups:

#include <Arduino.h>
#include <esp_dmx.h>

// configurazoine conteggio FPS
unsigned long lastTime = 0; // Ultima volta che abbiamo registrato il tempo
unsigned long lastReportTime = 0; // Ultima volta che abbiamo riportato il conteggio
int callCount = 0; // Numero di volte che la funzione è stata chiamata

void countCallsPerSecond();
void configureDMX(int transmitPin, int enablePin);

// Definizione dei pin
int transmitPin1 = 22;
int enablePin1 = 21;

int transmitPin2 = 17;
int enablePin2 = 2;

// Porta DMX da utilizzare
dmx_port_t dmxPort = 1;

// Buffer per i dati DMX
byte data[DMX_PACKET_SIZE];

// Intervallo di aggiornamento
unsigned long lastUpdate = millis();

void setup()
{
Serial.begin(115200);
dmx_config_t config = DMX_CONFIG_DEFAULT;
dmx_driver_install(dmxPort, &config, nullptr, 0);
configureDMX(transmitPin1, enablePin1); // Configura il driver DMX per la prima volta con il primo set di pin
}

void loop()
{
static unsigned long lastTime = 0; // Memorizza l'ultimo tempo in cui il loop è stato eseguito
unsigned long now = millis();

for (int i = 1; i < DMX_PACKET_SIZE; i++) 
{
    data[i]++;
}
data[0]=0;
data[1]=250;
data[2]=0;
data[3]=0;
data[4]=0;
data[5]=127;




// Invia i dati al primo set di pin
configureDMX(transmitPin1, enablePin1);
dmx_write(dmxPort, data, DMX_PACKET_SIZE);
dmx_send(dmxPort);
countCallsPerSecond();
dmx_wait_sent(dmxPort, DMX_TIMEOUT_TICK);


// Invia i dati al secondo set di pin
configureDMX(transmitPin2, enablePin2);
//data[0]=20;
data[5]=2;
dmx_write(dmxPort, data, DMX_PACKET_SIZE);
dmx_send(dmxPort);

dmx_wait_sent(dmxPort, DMX_TIMEOUT_TICK);
for (int i = 1; i < 8; i++) 
{
   // data[i]=data[10];
}
//Serial.printf("Sending DMX 0x%02X\n", data[1]);
countCallsPerSecond();

lastTime = now;  // Aggiorna l'ultimo tempo di esecuzione*/

}

void configureDMX(int transmitPin, int enablePin)
{

dmx_set_pin(dmxPort, transmitPin, -1, enablePin);
}

void countCallsPerSecond() {
unsigned long currentTime = millis();

// Incrementa il conteggio ogni volta che questa funzione viene chiamata
callCount++;

// Controlla se sono passati 5 secondi dall'ultimo report
if (currentTime - lastReportTime >= 1000) {
// Calcola quante volte al secondo la funzione è stata chiamata
float callsPerSecond = (float)callCount / 1.0;

// Stampa il risultato sulla porta seriale
Serial.print("Chiamate al secondo negli ultimi 5 secondi: ");
Serial.println(callsPerSecond);

// Resetta il conteggio e aggiorna l'ultimo tempo di report
callCount = 0;
lastReportTime = currentTime;

}
}

@cgiles
Copy link

cgiles commented Jun 10, 2024

You have a single dmxPort, you should have one by uarts, init both in your setup, then use dmx_write and use each dmxport as first variable of it.

Check this : #52

@simplo
Copy link
Author

simplo commented Jun 10, 2024

I know, but if I use uarts I can't use the serial for communicating with other systems.
What I'm trying to do is to use a single dmxPort and change pins each time, so I can use N universes.
Do you think it is possible?

@cgiles
Copy link

cgiles commented Jun 10, 2024

I don't know, but you should try to use dmx_driver_delete(dmxPort); then reinit your dmx driver and assign your pins. Maybe it can work.

@simplo
Copy link
Author

simplo commented Jun 11, 2024

Thanks for your reply, I tried but the system crashed often id I use the delete.
Now I'm trying another solution using a multiplxer to switch the transmission on different RS485 via hardware.
I think it could be an interesting solution for many people id it works.
Now the issue is speed.
If send two full data packets in the same loop cycle it slows down to 30/35fps (exactly the half of the FPS sending 1 packet).
Is it an intrinsic limit on the send command or there is some timing to fit DMX needs that we can speed up?
Thank you again for your kindness and patience.

@cgiles
Copy link

cgiles commented Jun 11, 2024

Is it an intrinsic limit on the send command or there is some timing to fit DMX needs that we can speed up?

I think it is a limit. As you need to wait it is fully sent, you will always divide the fps for 1 universe, by the numbers of universe you send.

You could check others libraries, see if they allow what you want to do.

@bensuffolk
Copy link
Contributor

Hi all, I'm trying to handle 2 RS485 on the same ESP32 Dev using port1 and port2 but as soon as the dmx_driver_install(dmxPort2, &config, personalities, personality_count); is executed the system crashes. Would it be possible to handle different (even more than 2) RS485 just uninstalling the driver and reinstalling it with different pins and same UART port at each loop?

See #150 there is a problem with using uart2

@riwalker
Copy link

riwalker commented Jun 11, 2024 via email

@someweisguy
Copy link
Owner

You may try pulling the latest commit on release/v4.1 to see if this issue is resolved! :)

@simplo
Copy link
Author

simplo commented Jun 14, 2024

Wow! It seems to work! thank you!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants