ciao ragazzi,
sto sviluppando un programma per gestire una striscia indirizzabile rgb con la libreria NeoPixel;
ho iniziato con una striscia da 60 led ed ora che strutturato il programma in base alle mie esigenze, devo passare da 60 led a 300 led ma sto riscontrando dei problemi, ovvero, quando faccio la compilazione tutto è ok ma poi quando il programma dovrebbe iniziare a fare il ciclo da l'impressino di bloccarsi.
funzione del programma:
arduino riceve un'indirizzo in MODBUS da un pannello touchscreen;
in base a quale indirizzo riceve deve accendere il led corrispondente (es. indirizzo MODBUS=1 quindi accendi il led 1; indirizzo MODBUS=55 quindi accendi il led 55;
semplicissimo, il problema lo riscontro quando modifico la funzione:
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
e la modifico da 60 a 300:
Adafruit_NeoPixel strip = Adafruit_NeoPixel(300, PIN, NEO_GRB + NEO_KHZ800);
È possibile che ci sia un massimo di led che si possono comandare?
Leggi bene sulle specifiche della libreria e sul sito di Adafruit come cresce l'occupazione di memoria al crescere del numero di LED definiti ...
... ho idea che sei andato oltre il limite della RAM.
Guglielmo
3 cose:
- Quali LED in striscia hai?
- È facile che hai occupato piú RAm di quella che hai fisicamente
- È anche facile che I LED consumano troppa corrente. La USB non regge 60 LED accesi
Ciao Uwe
Per l'assorbimento non ho problemi perché accendo solo 3 led.
Credo proprio che il problema riguardi La RAM.
Sono tornato sul sito e sé non ho capito male, ogni led ha bisogno di 3 bytes.
Erik86:
Per l'assorbimento non ho problemi perché accendo solo 3 led.
Credo proprio che il problema riguardi La RAM.
Normalmente ogni LED necessita per memorizzare lo stato di colore 3 bytes (R,G,B) ... se moltiplichi 3 x 300 sei già a 900 bytes solo per quello ... non so poi se la libreria usa anche qualche altro byte per le sue informazioni ...
In ogni caso alimenta la strip con un alimentatore separato da ... 5V 20A almeno visto che ... tale è l'assorbimento se accendi tutti e 300 i LED (60 mA x 300)
Guglielmo
Quello sicuramente... ho letto che è possibile snellire lo sketch..
Erik86:
Quello sicuramente... ho letto che è possibile snellire lo sketch..
Pubblicalo qui (... mi raccomando racchiuso nei tag CODE) e probabilmente ... qualcuno ci darà un occhiata e magari ti suggerirà delle ottimizzazioni
Guglielmo
#include <SimpleModbusSlave.h>
#include <Adafruit_NeoPixel.h>
#define LED 11
#define LED_1 12
enum
{
ASSE_Xmin,
ASSE_Ymin,
HOLDING_REGS_SIZE
};
unsigned int holdingRegs[HOLDING_REGS_SIZE];
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, LED, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip_1 = Adafruit_NeoPixel(60, LED_1, NEO_GRB + NEO_KHZ800);
void setup()
{
modbus_configure(&Serial, 9600, SERIAL_8N2, 1, 2, HOLDING_REGS_SIZE, holdingRegs);
strip.begin();
strip_1.begin();
Serial.begin(9600);
}
void loop()
{
modbus_update();
strip.clear();
strip_1.clear();
if((holdingRegs[ASSE_Xmin]!=0)&&(holdingRegs[ASSE_Xmin]<59)){
int ix=(holdingRegs[ASSE_Xmin]);
strip.setPixelColor(ix,150,0,0);
}
if((holdingRegs[ASSE_Ymin]!=0)&&(holdingRegs[ASSE_Ymin]<59)){
int ix=(holdingRegs[ASSE_Ymin]);
strip_1.setPixelColor(ix,150,0,0);
}
strip.show();
strip_1.show();
}
Dopo svariate ore ho constatato che il problema non deriva dalla RAM ma il fatto è che le funzioni delle 2 librerie si sovrastano a vicenda.
Come posso fare per far sì che prima funzioni una cosa poi un'altra?
Quindi ricevere l'indirizzo in modbus e poi far accendere il led corrispondente?fermare il tutto e poi ripartire una volta ricevuto un'altro indirizzo?
Interrupt potrebbe essere la soluzione?
Non conosco in nessun modo le due librerie utilizzate. Però tu dici che si sovrappongono quindi immagino tu le conosca.
Cos'è che condividono? Per capire se è un problema risolvibile oppure no.
in sostanza la parte riguardante la striscia continua ad ogni loop ad aggiornare lo stato dei led sovrastando la provocando dei ritardi sulla connessione e modbus
Erik86:
in sostanza la parte riguardante la striscia continua ad ogni loop ad aggiornare lo stato dei led sovrastando la provocando dei ritardi sulla connessione e modbus
Se ad ogni ciclo loop aggiorni lo stato dei led allora si che la libreria si prende tutto il tempo cpu, quella libreria è scritta quasi interamente in assembly perché deve generare un clock, molto preciso, di 800 kHz e gestire l'abbinata linea dati, tutto questo per un totale di 900 byte, servono tre byte per ogni led e vengono sempre trasmessi tutti anche se aggiorni un solo led.
Devi usare la show(), che è la funzione che invia fisicamente i dati, solo quando devi aggiornare lo stato dei led e non ad ogni ciclo.
Un limite dei neopixel è proprio il pesante utilizzo della cpu se usi molti led e li devi aggiornare spesso, p.e. per fare dei giochi di luci.
infatti non capisco perche mi da questo problema visto che la show() è dentro l'if.
aggiungendo un delay(50); non mi salta più la connessione.. ;D
in questo modo impongo delle pause alla srticia così che la connessione modbus continui a inviare e ricevere dati giusto?
Erik86:
in questo modo impongo delle pause alla srticia così che la connessione modbus continui a inviare e ricevere dati giusto?
Non mi sono messo a guardare il tuo codice, però la libreria non fa nulla fino a che non usi la show() per inviare il flusso dati, pertanto basta che la invochi solo nel momento in cui devi realmente cambiare lo stato dei led, se viene invocata continuamente, o troppo spesso, vai sicuramente incontro a delle latenze che possono creare non pochi problemi alle altre parti del programma.