Dimensionamento Array

Ciao a tutti sto costruendo un piccolo plotter con 2 assi X;Y

Sono riuscito a creare il corretto sketch che interpola gli assi comandandoli da pc con istruzioni iso, attualmente invio una stringa l'arduino mega la esegue dopodichè riceve la riga successiva e via così...

Il mio problema è che quando legge dalla seriale l'istruzione separa i dati e fa i relativi calcoli necessari l'esecuzione dei movimenti si interrompe qualche decimo di secondo, vorrei annullare questo tempo.

Ho quindi pensato di caricare inizialmente le mie stringhe e poi eseguirle in continuo.

Per eseguire il mio movimento necessito di memorizzare 2 long un int e un long in relative array che vado a popolare in fase di caricamento ma non so come calcolare quanto possono essere grandi queste array.

Attualmente quando carico lo sketch l'IDE visualizza questo messaggio:

"Le variabili globali usano 816 byte (9%) di memoria dinamica, lasciando altri 7.376 byte liberi per le variabili locali. Il massimo è 8.192 byte."

Ho aggiunto le mie array pubbliche:

float Kx[800];
float Ky[800];
long Pls[800];
int KAcc[800];

Al variare della loro dimensione (400,800,1000,...) il messaggio non cambia, come faccio a calcolare le dimensioni limite delle mie array?

per usare tutti i 7376kb dovresti allocare i vettori da 526 elementi, ma considerando che lo stack necessita di memoria allora diciamo che non è il caso di superare i 300 elementi.
a runtime puoi usare questa funzione:

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

A che velocità di comunicazione lavori?
kx e ky sono le coordinate? perché usi i float? quale valore minimo e massimo possono avere e che precisione dopo la virgola ti serve?

La RAM utilizzata da un Array lo calcoli moltiplicando i byte usato dal tipo di variabile per il numero di elementi.
esempio: float[10] 4 byte e 10 elemnti sono 40 bye occupati.

Secondo me la soluzione non é questa ma migliorare lo sketch.

Ciao Uwe

Attualmente imposto la baude a 115200.

Kx e Ky è la quantità di impulsi che deve fare ogni asse ad ogni ciclo
Pls è la quantità di cicli che deve fare
KAcc è l’accelerazione che integra o decrementa ad ogni ciclo

il ciclo di movimentazione è:

    while (Serial.available() > 0) {  //Se c'è qualcosa in arrivo dalla seriale

        float Kx = Serial.parseFloat();
        float Ky = Serial.parseFloat();
        long Pls = Serial.parseInt();
        int KAcc = Serial.parseInt();

        float appX,appY;//Appoggio assi virtuali
        appX = 0;
        appY = 0; 
  
        while (Pls > 0){        //Ciclo finchè Pulse app > 0
          appX += Kx;                 //Calcolo nuova posizione asse virtuale
          appY += Ky;                 //Calcolo nuova posizione asse virtuale
          P += KAcc;                          //Ricalcolo pausa
          if(appX >= 1){GoX();appX-=1;}            //Se necessario faccio uno step positivo X
          if(appX <= -1){BackX();appX+=1;}         //Se necessario faccio uno step negativo X
          if(appY >= 1){GoY();appY-=1;}            //Se necessario faccio uno step positivo Y
          if(appY <= -1){BackY();appY+=1;}         //Se necessario faccio uno step negativo Y
          if (P > Pmax){P = Pmax;}              //Se Pausa > Pausa max faccio pausa max
          if (P < Pmin){delayMicroseconds(Pmin);}              //Se Pausa < Pausa min faccio pausa min
          if (P >= Pmin && P <= Pmax){delayMicroseconds(P);}   //Se Pmin < Pausa < Pmax faccio pausa
          Pls--;
     }//End while seriale

più semplice di così non saprei proprio come fare.

il fatto è che quando esegue le istruzioni:

        float Kx = Serial.parseFloat();
        float Ky = Serial.parseFloat();
        long Pls = Serial.parseInt();
        int KAcc = Serial.parseInt();

ci mette un po ed è per questo che pensavo di mettere i dati in array

Non hai detto i valori minimi e massimi che possono avere le variabili, manca anche la precisione che deve avere il float.
come invii i dati?

Potresti provare anche ad alzare il baud a 500000, se il tuo pc lo supporta oltre ad andare più veloce arduino lavora meglio.

Pls da 1 a 400000
Kx/Ky da 1 a 0.0000025
KAcc da 1 a 50

trasmetto i dati con un programmino che ho scritto in vb.net

ma li trasmetti in formato stringa o trasmetti direttamente i byte?

stringa con virgole che separano i vari dati

Willy_80:
stringa con virgole che separano i vari dati

Non ha senso passare i valori per stringa, scomponili in array di byte e inviali cosi, magari facendo riferimento ad una struct. L'invio di dati in forma di stringa rallenta notevolmente il processo, in quanto è necessaria un interpretazione dei dati in arrivo che nel tuo caso non sarebbe necessaria. Stai solo attento ai formati dei dati, immagino che la dimensione in byte dei float su PC sia diversa da quella su Arduino.

riesci a farmi un esempio?

Kx/Ky da 1 a 0.0000025
ma sono i numero di passi che deve fare il motore?

Ciao Uwe

ad ogni ciclo integro su un asse virtuale float il relatico valore quando l'asse ha un valore pari a 1 o -1 faccio uno step

Secondo me non ha molto senso giocare su un range del genere, prenditi un int e usa quello, se non basta passa ad un long, ma il float sembrerebbe totalmente inadatto per questo compito; i float non si usano con cicli ed integrazioni!

Per tornare al discorso precedente, devo inviare un intero di due byte che contiene il numero 512410 quivalente a 00010100000001002 e a 140416 lo divido in due byte primo byte 0x14 e il secondo 0x04 a questo punto li invio attraverso la seriale come singoli byte indipendenti, dalla parte di Arduino riceverò i singoli byte e da quelli ricostruirò l’intero di partenza.

Willy_80:
ad ogni ciclo integro su un asse virtuale float il relatico valore quando l'asse ha un valore pari a 1 o -1 faccio uno step

Questa è una cosa da suicidio, per giunta vai a farlo su un ciofechino a 8 bit senza fpu.
Gli step dei motori si gestiscono con int o long int, se parliamo di assi di di movimento ogni count scegli a cosa corrisponde come movimento reale, p.e. 1 count = 0.02 mm.
Non usare assolutamente i float per queste cose, primo su Arduino hanno la ridicola risoluzione di solo 5-6 cifre, per via del limite a 32 bit, inoltre per la loro natura esponenziale non sono precisi sull'ultima cifra.