ARDUINO DUE conflitto tra libreria servo.h e adafruit

Salve a tutti, da diversi giorni sto riscontrando un problema CON ARDUINO DUE e le matrici led di Adafruit e un servomotore classico. Non appena collego il servo a qualsiasi pin sia pwm che digitale non mi funziona. se mi invece commento ''matrix.show()'' allora il servo funziona perfettamente. pensavo fosse un problema di conflitto tra librerie. qualcuno mi può aiutare?grazie mille in anticipo
ecco il codice:

#include <Servo.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#ifndef PSTR
#define PSTR // Make Arduino Due happy

#endif


 

#define PIN 6


Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(32, 8, 3, 1, PIN,
                            NEO_TILE_TOP   + NEO_TILE_RIGHT   + NEO_TILE_COLUMNS   + NEO_TILE_PROGRESSIVE +
                            NEO_MATRIX_TOP + NEO_MATRIX_RIGHT + NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE
                            ,
                            NEO_GRB + NEO_KHZ800);

const uint16_t colors[] = {
  matrix.Color(255, 0, 0), matrix.Color(0, 255, 0), matrix.Color(0, 0, 255)
};

uint16_t color = colors[0];


Servo myservo;
 
int pos = 0;
int x    = 0;
int y    = 0;
int pass0,pass1,pass2,pass3,pass4,pass5 = 0;
int j=0;


boolean stringComplete = false;  // whether the string is complete
int inputCommand;

void setup() {
  pinMode( 52,OUTPUT);
  myservo.attach(9);
  matrix.begin();
  matrix.setTextWrap(false);
  matrix.setBrightness(10);
  matrix.setTextColor(colors[0]);

  // initialize serial:
  Serial.begin(9600);
  // reserve 200 bytes for the inputString:
  //inputString.reserve(200);
}



void loop() {
  serialEvent(); //call the function
  
  digitalWrite(52,LOW);
   
  



  
  matrix.fillScreen(0);
  

    matrix.drawLine(pass0, 0, pass0, 7, colors[0]);
    matrix.drawLine(pass1, 0, pass1, 7, colors[0]);
    matrix.drawLine(pass2, 0, pass2, 7, colors[0]);
     matrix.drawLine(pass3, 0, pass3, 7, colors[1]);
     matrix.drawLine(pass4, 0, pass4, 7, colors[1]);
     matrix.drawLine(pass5, 0, pass5, 7, colors[1]);

  matrix.show();
  delay(100);

}




void serialEvent() {
  inputCommand = Serial.read();
  
      switch(inputCommand){
      case 'r':
        color = colors[0];
        break;

      case 'g':
        color = colors[1];
        break;

      case 'b':
        color = colors[2];
        break;
      
      case 't'://turn the servomotor

        
        
        
        
        for(pos = 0; pos < 180; pos += 1)
      {
        myservo.write(pos);
        delay(15);
        }
        for(pos = 180; pos>=1; pos-=1)
        {
        myservo.write(pos);
        delay(15);
        }
        
        break;
        



        
        case 'a':
         digitalWrite( 52,HIGH);
        delay(80);
        pass0=82;
        pass1=83;
        pass2=84;
        pass3=62;
        pass4=63;
        pass5=64;
       
        //digitalWrite(52,LOW);
        
        break;

          case 'c':
        digitalWrite( 52,HIGH);
        delay(80);
        //digitalWrite(52,LOW);
        
        pass0=12;
        pass1=13;
        pass2=14;
        pass3=37;
        pass4=38;
        pass5=39;
        
        break;
          
        }
        
         inputCommand = 0;

}

Nessuno è in grado di risolvere il problem?accendere una matrice led e un servo?

Non ti può aiutare nessuno con quello che hai postato

ma perchè che ho postato?non va bene?

Non essendoti ancora presentato Ti invitiamo a presentarti QUI (dicci quali conoscenze hai di elettronica e di programmazione) e a leggere il regolamento QUI se non lo hai già fatto.

Comunque benvenuto sul forum.

Attilio

pe89:
ma perchè che ho postato?non va bene?

Intanto edita il tuo primo post e racchiudi il codice negli appositi tag, vedi pulsante in alto a sinistra con il simbolo "</>".

Poi quando si chiede un aiuto bisogna dare il massimo delle informazioni possibili, visto che chi legge non è nella tua testa e non ha la sfera di cristallo. :wink:

Infine se postassi anche uno schema dei collegamenti non sarebbe male.

Ciao

Attilio

Ti invitiamo a presentarti (dicci quali conoscenze hai di elettronica e di programmazione) qui: Presentazioni
e a leggere il regolamento se non lo hai già fatto: Regolamento
Qui una serie di link utili, non inerenti al tuo problema:

Il codice devi racchiuderlo nei tag code, vedi sezione 7 del regolamento, spiega bene come fare ( pulsante </> ).
Altrimenti parte del codice può essere visualizzata male o mancare perchè interpretato come attributo del testo stesso.
Nell'IDE usa CTRL+T che indenta meglio il codice e per favore ELIMINA quelle numerose righe vuote, non stai scrivendo un temino dove più è lungo e meglio è !!

Se fossimo su Arduino Uno o Mega direi è un problema di conflitto dei timer, libreria Servo e penso la NeoPixel si appoggiano allo stesso timer.
Potrebbe essere che anche sulla Due si appoggiano sullo stesso timer.
Per la Mega è possibile modificare nella libreria Servo quale timer utilizzare.
Per la Due, nella sottocartella sam, c'e' ServoTimers.h, all'inizio ci sono delle define,
#define _useTimer1
#define _useTimer2
#define _useTimer3
#define _useTimer4
#define _useTimer5
eliminale tutte tranne una e fai delle prove usandone uno alla volta, vediamo se uno di questi non va in conflitto.

Qui del problema di tempistica ne parla proprio Adaftuit sul suo sito:

@ nid69ita

Repetita iuvant :smiley: :smiley: :smiley:

Attilio

La NeoPixel richiede dei timing ben precisi per funzionare (tanto che è in buona parte scritta in assembler) e la prima cosa che fa quando visualizza i dati con il metodo "void Adafruit_NeoPixel::show(void)" è disabilitare gli interrupt ... quindi ... difficile che assieme possa funzionare qualsiasi altra cosa che usa timer ed interrupt !

Guglielmo

nid69ita:
Se fossimo su Arduino Uno o Mega direi è un problema di conflitto dei timer, libreria Servo e penso la NeoPixel si appoggiano allo stesso timer.

No, la libreria neopixel non usa timer, sugli AVR è scritta quasi totalmente in assembly e usa routine calibrate per durare il giusto numero di cicli macchina al fine di ottenere le corrette temporizzazioni, a 800 kHz o 400 kHz, per i neopixel.
Sulla DUE la libreria è in C in questo caso sfrutta dei cicli for calibrati per ottenere i corretti delay per la generazione del segnale di controllo per i neopixel.
Sia sugli AVR che sulla DUE la libreria neopixel è atomica, ovvero l'operazione non può essere interrotta e vengono bloccati tutti gli interrupt, se la scrittura su i neopixel viene fatta spesso, p.e. per gestire giochi di luce su molti led, questo va facilmente ad interferire con la libreria servo perché per via della sospensione degli interrupt non è più in grado di generare i corretti impulsi di controllo per i servo.
Se si devono gestire molti neopixel, con frequenti variazioni del loro stato, è meglio usare un AVR dedicato allo scopo, va bene anche un Attiny, altrimenti diventa quasi difficile, se non impossibile, fare altre cose, vale anche per la DUE e le altre schede Arduino ARM.
Non è un problema di potenza di calcolo, è un problema di mancanza supporto hardware per comunicare con i neopixel, viene fatto tutto a software con routine che sono bloccanti e monopolizzano il tempo cpu.

Ho visto sul sito Adafruit (al link che ho messo prima) che loro suggeriscono l'uso di un'altra libreria per i servo, la TiCoServo, solo che non mi pare sia per la Due.

pe89:
ma perchè che ho postato?non va bene?

A me sembra che dire "matrici led di Adafruit" non significhi nulla, se vado a cercare le matrici su adafruit ne escono 1000 modelli, non è possibile rispondere
Per quanto ne sappiamo noi potresti aver collegato le matrici direttamente ai pin senza driver, o il servo sulla DUE perciò senza schemi non è possibile rispondere
Poi dopo aver consultato l'hardware si va a vedere il software, maggior ragione hai una scheda che usano in pochi

Non è necessario leggere il regolamento per sapere che le domande devono contenere più dettagli possibili, ci vuole solo un po' di logica, capirlo da soli, mettersi nei panni di chi legge, non siamo a casa tua non possiamo sapere cosa hai fatto e quello che hai se non lo dici tu ... è elementare sono le basi della comunicazione verso gli altri umani, non ti si sta chiedendo la luna.

pablos:
A me sembra che dire "matrici led di Adafruit" non significhi nulla, se vado a cercare le matrici su adafruit ne escono 1000 modelli, non è possibile rispondere

pablos ... se guardi sta usando le librerie per i NeoPixel quindi sono questi gli array di LED coinvolti ed il problema, come spiegato, è nelle tempistiche di detti LED e nel fatto che la libreria Adafruit per i NeoPixel disabilita gli interrupt ! :wink:

Guglielmo

Io ancora non vedo un link degli array di led che usa o meglio specificato "matrici led di Adafruit", nemmeno uno schema di collegamento verso la DUE.
Però se lo avete capito voi va bene così, a me non servono altre spiegazioni, era sott'inteso che più spiegazioni si danno meglio è, qualunque sia il problema.

Del resto io non conosco tutte le centrali, ogni settimana ne esce una nuova, basta che mi dai gli schemi te le collego e programmo tutte .... insomma il concetto era questo.

ciao

Scusate per la mancanza di dettagli. Provo a spiegarmi meglio. Sto utilizzando tre matrici led RGB Adafruit 8x32 che dispongono di tre cavi:5v, massa e segnale. Ho collegato il segnale al pin 6 del mio Arduino Due. Fin qui tutto bene. Il problema nasce non appena collego un semplice servomotore ''HitecHS-225MG Metal Gear Mighty Mini Servo'' ad uno dei pin PWM tra 2 e 13 escluso il 6 ovviamente. Infatti i led continuano a funzionare correttamente mentre il servo non si muove. Per comunicare con Arduino ho implementato un codice in Visual Studio in C++ con interfaccia grafica per inviare i comandi tramite comunicazione seriale. In pratica se mando un carattere 't' il servo dovrebbe ruotare di 180°; se per esempio mando un carattere 'b' i led si illuminano di colore blu e cosi via per altri comandi.
Il mio problema nasce quindi quando nello sketch Arduino implemento la funzione ''matrix.show''. commentando solo questa riga riesco perfettamente a muovere il servo però ovviamente i led sono spenti. Allego un'immagine con lo schema non so se sia corretto farlo così. Nell'immagine chiamo pin X per indicare un qualsiasi pin PWM. Ringrazio tutti per la risposta, per i consigli e di chiedermi se qualcosa non fosse.

Mi sembra che ti sia stato ampiamente spiegato che quando funzionano i NeoPixel NON puoi far andare altro sia perché richiedono tempistiche ben precise e quindi null'altro può disturbarli, sia perché, per evitare qualsiasi disturbo, vengono anche disabilitati gli interrupt quindi ... quando visualizzi qualche cosa NON puoi far andare i servo.

Guglielmo

P.S.: Per alcune board basate su MCU AVR (quindi NON Arduino DUE), Adafruit a scritto una libreria apposta che collabora con la libreria per la gestione dei NeoPixel e che permette, con determinate limitazioni, anche l'uso dei servo. In QUESTA pagina i dettagli.