Aiuto software

Salve a tutti, questo è il mio primo post e vogliate scusarmi se sbaglio qualcosa…

Volevo capire come poter sistemare il software che ho scritto perchè non saprei come fare.
Si tratterebbe solamente di far girare un motore passo passo in un senso poi nell’altro senso. Io ho provato in questo modo.

int pin[4] {2, 3, 4, 5};

byte  paccoA[4] {1, 0, 0, 0};
byte  paccoB[4] {0, 1, 0, 0};
byte  paccoC[4] {0, 0, 1, 0};
byte  paccoD[4] {0, 0, 0, 1};

void setup() {

  Serial.begin(9600);
  for (int i = 0; i < 4; i++) {

    pinMode(pin[i], OUTPUT);

  }
}

void loop() {

  for (int i = 0; i < 1000; i++) {

    digitalWrite(pin[4], paccoA[4]); // devo assegnare ai pin 2,3,4,5 i valori del paccoA ( al pin2=1, al pin3=0 ecc..)
    delay(10);
    digitalWrite(pin[4], paccoB[4]);
    delay(10);
    digitalWrite(pin[4], paccoC[4]);
    delay(10);
    digitalWrite(pin[4], paccoD[4]);

  }

  delay(500);

  for (int i = 0; i < 1000; i++) {

    digitalWrite(pin[4], paccoC[4]);
    delay(10);
    digitalWrite(pin[4], paccoD[4]);
    delay(10);
    digitalWrite(pin[4], paccoB[4]);
    delay(10);
    digitalWrite(pin[4], paccoA[4]);

  }

  delay(500);
}

Esempio : devo assegnare ai pin 2,3,4,5 i valori del paccoA ( al pin2=1, al pin3=0 , al pin4=0 ecc.)

ovviamente non funziona con digitalWrite, qualcuno può cosigliaremi come fare?

Grazie mille

A parte il software, spero comunque tu NON abbia collegato direttamente i pin di Arduino al motore passo passo ...

Come piloti il motore? Cosa c'è tra Arduino e detto motore passo-passo e, hai un link a detto motore così possiamo leggerne le caratteristiche ?

Guglielmo

ciao e grazie per la risposta, effettivamente non ho collegato direttamente il motorino che è un StepMotor 288Y-48 funziona a 5 V ma ho utilizzato un driver ULN che è fornito insieme al motore.

Con un altro programma che ho fatto funziona correttamente ma è lungo. Volevo solamente trovare un altro modo per abbreviare il software.

Patotto1: Volevo solamente trovare un altro modo per abbreviare il software.

E usare la libreria stepper?

Prima di usare una libreria, fagli fare qualche prova per imparare! :-)

E se quelllo stepperino + modulino è quella cinesata che ti vendono su ebay/aliexpress e simili, mi pare ha dei problemi con la libreria stepper (almeno quando la provai, 3 o 4 anni fa)

Seza fare grossi cambiamenti al tuo programma, potresti fare così:

void loop()
{
  for(int n=0; n<1000; n++)
    {
    for(int i=0; i<=3; i++)
      {
      l=i+1; if(l>3) l-=4;
      m=i+2; if(m>3) m-=4;
      n=i+3; if(n>3) n-=4;

      digitalWrite(pin[0], paccoA[i]);
      delay(10);
      digitalWrite(pin[1], paccoA[l]);
      delay(10);
      digitalWrite(pin[2], paccoA[m]);
      delay(10);
      digitalWrite(pin[3], paccoA[n]);
      delay(10);
      }
    }
  delay(500);

  for(int n=0; n<1000; n++)
    {
    for(int i=3; i<=0; i++)
      {
      l=i+1; if(l>3) l-=4;
      m=i+2; if(m>3) m-=4;
      n=i+3; if(n>3) n-=4;

      digitalWrite(pin[0], paccoA[i]);
      delay(10);
      digitalWrite(pin[1], paccoA[l]);
      delay(10);
      digitalWrite(pin[2], paccoA[m]);
      delay(10);
      digitalWrite(pin[3], paccoA[n]);
      delay(10);
      }
    }
  delay(500);
}

Considera che il loop gira continuamente e si ripete, quindi avrai una sequenza infinita di 1000 passi in un verso e 1000 passi nell’altro. Se vuoi che avvenga una sola volta, devi mettere tutto nel setup() e lasciare vuoto il loop(): loop(){}

Grazie mille Datman.

 l=i+1; if(l>3) l-=4; // serve per azzerare l giusto ?
 m=i+2; if(m>3) m-=4; 
 n=i+3; if(n>3) n-=4;

Patrick

Altra idea, ma stravolge abbastanza:

//Esiste solo l'array di pin, non gli altri
//Si comincia che tutto è spento
if (devomuovermi())//Funzione fittizia che restituisce in che verso devo muovermi (+1=avanti, -1=indietro)
{
  digitalWrite (pin [0], HIGH);//Comincio ad alzare il primo pin, gli altri sono giù
  for (byte a=0;a<4;a++)//Per 4 volte faccio 1 scatto
    for (char i=0,i<4;i++)//verifico se trovo un pin alto
      if (digitalRead (pin [i])
      {
        delay (eventuale)://Se è necessario un delay tra uno scatto e l'altro, non lo so
        digitalWrite (pin [i], LOW);//Abbasso il piedino alto
        i=(i+devomuovermi());
        if (i<0)
          i=3;
        i=i%4;//Il nuovo valore di i è l'indice del pin giusto
        digitalWrite (pin [i], HIGH);//Alzo il pin giusto
        break;//Esco dal primo for, scatto finito
      }
}

NON so se va bene, mi è venuto in mente in 20 minuti di noia e non lo ho provato

Per semplificare un bel po', ci vuole il PORT

Ti ringrazio Silente, cercherò di capire per bene come funziona il tuo steck. Poi lo provo!

Datman cosa sarebbe il PORT?

Cerca port manipulation: controllo delle porte a basso livello.

Ciao a tutti,
grazie al vostro aiuto sono riuscito a fare un programmino che funziona come volevo !!

lo posto cosi mi direte le vostre considerazioni

byte pin[4] = {2, 3, 4, 5};
byte r, n, abilita[4], abilita1[4];
int matrice[4][4] = {
  {1, 0, 0, 0},
  {0, 1, 0, 0},
  {0, 0, 1, 0},
  {0, 0, 0, 1}
};

int matrice1[4][4] = {
  {0, 0, 0, 1},
  {0, 0, 1, 0},
  {0, 1, 0, 0},
  {1, 0, 0, 0}
};

void setup() {
  Serial.begin(9600);
  for (byte i = 0; i < 4; i++) {
    pinMode(pin [i], OUTPUT);

  }

}

void loop() {
  
  delay(2000);
  
  for (int a = 0; a < 500; a++) {

    for (byte n = 0; n < 4; n++) {

      for ( byte r = 0; r < 4; r++) {

        abilita[4] = matrice[n] [r];
        digitalWrite (pin [r], abilita [4]);
      }
      delay(7);
    }
  }
  
  delay(2000);

  for (int a = 0 ; a < 500 ; a++) {

    for (byte n = 0 ; n < 4 ; n++) {

      for ( byte r = 0 ; r < 4 ; r++) {

        abilita1[4] = matrice1[n] [r];
        digitalWrite (pin [r], abilita1 [4]);
      }
      delay(7);
    }
  }
}

grazie
Patrick

Con PORT, mantenendo i delay(), viene così:

void setup()
{
Serial.begin(9600);
pinMode(2, OUTPUT); // Uscita 1
pinMode(3, OUTPUT); // Uscita 2
pinMode(4, OUTPUT); // Uscita 3
pinMode(5, OUTPUT); // Uscita 4
}

void loop()
{
for (int a=0; a<500; a++)
  {
  for(byte x=2; x<=5; x++)
    {
    PORTD&=(0b11000011+(1<<x));
    PORTD|=1<<x;
    delay(7);
    }
  }

delay(2000);

for (int a=0; a<500; a++)
  {
  for(byte x=5; x>=2; x--)
    {
    PORTD&=(0b11000011+(1<<x));
    PORTD|=1<<x;
    delay(7);
    }
  }

delay(2000);
}

Se vogliamo eliminare i delay() e rendere il loop continuo, come buona norma:

unsigned long t1;

void setup()
{
Serial.begin(9600);
pinMode(2, OUTPUT); // Uscita 1
pinMode(3, OUTPUT); // Uscita 2
pinMode(4, OUTPUT); // Uscita 3
pinMode(5, OUTPUT); // Uscita 4
t1=millis();
}

void loop()
{
if(millis()-t1<=2000) // Per i primi 2 secondi:
  {
  for(int a=0; a<500; a++)
    {
    for(byte x=2; x<=5; x++)
      {
      PORTD&=0b11000011; // "Spegne" le quattro uscite, senza influire sugli altri I/O.
      PORTD|=1<<x; // "Accende" ciclicamente una delle 4 uscite.
      delay(7);
      }
    }
  }

if(millis()-t1>2000 && millis()-t1<=4000) // Per i successivi 2 secondi:
  {
  for (int a=0; a<500; a++)
    {
    for(byte x=5; x>=2; x--)
      {
      PORTD&=0b11000011;
      PORTD|=1<<x;
      delay(7);
      }
    }
  }

if(millis()-t1>4000) t1=millis(); // A 4 secondi, "azzera" il tempo.
}

In realtà, pur avendo eliminato i delay(), rimangono i for(), in particolare quelli da 0 a 499, che sono bloccanti: il passaggio successivo è usare millis(), con una variabile unsigned long t2, per sostituire i for(int a=0; a<500; a++).

Ooops… Mi rendo conto solo ora che i 2 secondi erano di pausa, invece i due millis che ho messo fanno due cicli di due secondi!..

Grazie Datman, ma non riesco a capire il PORT riesci a commentarmi il codice ?

Ho provato a leggere qui https://www.arduino.cc/en/Reference/PortManipulation ma sinceramente non ho capito molto…

Patrick

Bisognerebbe studiare il datasheet del micro presente nelle singole schede. Si tratta di quei rari casi nei quali ci si deve dimenticare le semplificazioni introdotte dall’ecosistema arduino…

>Patotto1: prova invece a leggere QUI ;)

Guglielmo

P.S.: Ovvio che come è fatta la MCU, quali sono le sue porte e a quali pin sono colegate ... bisogna saperlo, altrimenti si lascia stare e si usano le classiche funzioni di Arduino.

PORTD pilota contemporaneamente gli 8 bit che compongono la porta D (è l'unica completamente disponibile sull'ATMEGA328P di Arduino Uno). Scrivendo in codice binario il valore che si assegna, è evidente quali uscite vanno a livello alto: sono quelle con valore 1. Facendo così, però, tutti i bit vengono forzati al valore 0 o 1 che assegniamo.

Poichè noi usiamo solo 4 degli 8 bit, per non modificare lo stato degli altri 4, che possiamo usare indipendentemente per leggere lo stato di un pulsante o per pilotare dei led o altro, dobbiamo mascherare il codice. Ciò si fa con gli operatori logici AND (&) e OR (|). Con &, che opera una moltiplicazione, forziamo a 0 i bit che vogliamo spegnere lasciando inalterati gli altri, che vengono moltiplicati per 1; con |, invece, forziamo a 1 (sommandolo) i bit che vogliamo accendere, lasciando inalterati gli altri, a cui viene sommato 0.

A&=B è una scrittura semplificata che significa A=A&B; A|=B significa A=A|B. Tale forma è utilizzabile anche per molte altre operazioni.

N.B. Nel mio ultimo programma ho sostituito i while con degli if, perché anche while è bloccante.

Interessante, grazie gpb01!

adesso mi è più chiaro il funzionamento del PORT.

Appena avrò tempo proverò a far accendere dei led e leggere il loro stato.

Grazie a tutti.