Go Down

Topic: Azzerare la funzione millis() (Read 12400 times) previous topic - next topic

marcello.romani

Io direi che è sempre possibile, ma mai auspicabile :)

PaoloP

#31
Dec 04, 2012, 06:07 pm Last Edit: Dec 04, 2012, 06:27 pm by PaoloP Reason: 1
Ma hai collegato il motore direttamente ai pin di Arduino o stai usando un driver?

Qui trovi le librerie del modulo di Adafruit (http://www.robot-italy.com/it/adafruit-motor-stepper-servo-shield-for-arduino-kit-v1-0.html) --> http://www.ladyada.net/make/mshield/download.html
C'è anche una libreria specifica per far accelerare e decelerare lo stepper.

leandro78

Alla fine credo di avere risolto in questa maniera, anche se in realtà non so se il motorino riesce a percepire incrementi frazionari del tempo di ritardo tra un passo e l'altro o li avverte solo quando superano il millisecondo...

Quote

#include <LiquidCrystal.h>

#define SCENDI 2
#define   SALI 3

LiquidCrystal lcd(12, 13, 7, 6, 5, 4);

int motorPin1 = 8;
int motorPin2 = 9;
int motorPin3 = 10;
int motorPin4 = 11;

int speedPinPot = 0;
int decelPinPot = 1;

int i = 0;
int down = 0;
int up = 0;
int stop = 0;
int downDelayTime = 1;   
double upDelayTime;
double ritardo;
long previousMillis = 0;
long interval = 100;

void setup() {       
  
  pinMode(motorPin1, OUTPUT); 
  pinMode(motorPin2, OUTPUT); 
  pinMode(motorPin3, OUTPUT); 
  pinMode(motorPin4, OUTPUT);
  
  pinMode(SCENDI, INPUT); 
  pinMode(SALI, INPUT);
  pinMode(speedPinPot, INPUT);
  pinMode(decelPinPot, INPUT);
  
  lcd.begin(20, 2);
  lcd.print("Vel.iniz.");
  lcd.setCursor(16, 0);
  lcd.print("mm/s");
  lcd.setCursor(0, 1);
  lcd.print("Deceler.");
  lcd.setCursor(15, 1);
  lcd.print("mm/s2");
}  

void loop() {   
  
  int speedReadPin = analogRead(speedPinPot);
  upDelayTime = (map(speedReadPin, 0, 1024, 10000, 100000)/1000.);
  double velocita = (1000/upDelayTime) * 0.226;
  
  int decelReadPin = analogRead(decelPinPot);
  ritardo = (map(decelReadPin, 0, 1024, 0, 1000)/1000.);
  double decelerazione = ( ( (1/upDelayTime) - (1/(upDelayTime + ritardo)) )/0.1 ) * 1000 * 0.226;
  
  lcd.setCursor(10, 0);
  if (velocita < 10)
    lcd.print(" ");
  lcd.print(velocita);
  
  lcd.setCursor(10, 1);
  if (decelerazione < 10)
    lcd.print(" ");
  lcd.print(decelerazione);
  
  down = digitalRead(SCENDI);     
  up = digitalRead(SALI);
    if (down == HIGH)
      scendi();         
    if (up == HIGH
      sali();    
}   

void scendi() {   
  
  if(!stop) {
    
    digitalWrite(motorPin1, LOW); 
    digitalWrite(motorPin2, HIGH);
    digitalWrite(motorPin3, HIGH); 
    digitalWrite(motorPin4, LOW); 
    delay(downDelayTime); 
    i++;
    
    digitalWrite(motorPin1, LOW); 
    digitalWrite(motorPin2, HIGH);
    digitalWrite(motorPin3, LOW); 
    digitalWrite(motorPin4, HIGH); 
    delay(downDelayTime); 
    i++;
    
    digitalWrite(motorPin1, HIGH); 
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin3, LOW); 
    digitalWrite(motorPin4, HIGH); 
    delay(downDelayTime); 
    i++;
    
    digitalWrite(motorPin1, HIGH); 
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin3, HIGH); 
    digitalWrite(motorPin4, LOW); 
    delay(downDelayTime);
    i++;
    
    if (i > 164)
      stop = 1;
    }
}   

void sali() {   
  
  stop = 0;

  while(i>0){
    unsigned long currentMillis = millis();
    
    if (currentMillis - previousMillis > interval) {
      previousMillis = currentMillis;   
      upDelayTime += ritardo;
    }
    digitalWrite(motorPin1, HIGH); 
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin3, HIGH); 
    digitalWrite(motorPin4, LOW); 
    delay(upDelayTime);
    i--;
    
    if (currentMillis - previousMillis > interval) {
      previousMillis = currentMillis;   
      upDelayTime += ritardo;
    }    
    digitalWrite(motorPin1, HIGH); 
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin3, LOW); 
    digitalWrite(motorPin4, HIGH); 
    delay(upDelayTime); 
    i--;

    if (currentMillis - previousMillis > interval) {
      previousMillis = currentMillis;   
      upDelayTime += ritardo;
    }
    digitalWrite(motorPin1, LOW); 
    digitalWrite(motorPin2, HIGH);
    digitalWrite(motorPin3, LOW); 
    digitalWrite(motorPin4, HIGH); 
    delay( upDelayTime ); 
    i--;
    
    if (currentMillis - previousMillis > interval) {
      previousMillis = currentMillis;   
      upDelayTime += ritardo;
    }    
    digitalWrite(motorPin1, LOW); 
    digitalWrite(motorPin2, HIGH);
    digitalWrite(motorPin3, HIGH); 
    digitalWrite(motorPin4, LOW); 
    delay(upDelayTime); 
    i--; 
  }





Sapreste suggerirmi anche un metodo per visualizzare sul display l'apice del quadrato? Mi servirebbe per l'accelerazione da esprimere in mm/s^2.

lestofante

devi vedere nella libreria gli array dei caratteri, in caso te lo crei tu. in pratica hai una matrice (una tabella) di 1 e 0, dove 0 è pixel spento e 1 pixel acceso.
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

leo72


in realtà non so se il motorino riesce a percepire incrementi frazionari del tempo di ritardo tra un passo e l'altro o li avverte solo quando superano il millisecondo...

La seconda che hai detto.
Delay accetta solo interi come parametro:
http://arduino.cc/en/Reference/Delay

Se vuoi ridurre il tempi, usa delayMicroseconds:
http://arduino.cc/en/Reference/DelayMicroseconds

leandro78

Ottimo suggerimento, grazie Leo!!

Quindi in questo caso dovrei trasformare tutti i tempi in microsecondi giusto??

leo72


Quindi in questo caso dovrei trasformare tutti i tempi in microsecondi giusto??

Sapendo che 1 ms è composto da 1000 us, fare il rapporto è banale.

leandro78

Perfetto....l'unico dubbio mi era venuto perchè avevo provato a passare valori non interi alla funzione delay e sembrava accettarli ma probabilmente effettuava un troncamento alla sola parte intera...

leo72


Perfetto....l'unico dubbio mi era venuto perchè avevo provato a passare valori non interi alla funzione delay e sembrava accettarli ma probabilmente effettuava un troncamento alla sola parte intera...

Non "troncamento" ma conversione fra tipi diversi. Nel tuo caso da float a unsigned long.

leandro78

#39
Dec 05, 2012, 01:22 pm Last Edit: Dec 05, 2012, 01:24 pm by leandro78 Reason: 1
Ho provato a modificare il programma con l'impiego della funzione delayMicroseconds in questo modo:

Quote

#include <LiquidCrystal.h>

#define SCENDI 2
#define   SALI 3

LiquidCrystal lcd(12, 13, 7, 6, 5, 4);

byte esponente[8] = {
 0b01110,
 0b00010,
 0b00100,
 0b01110,
 0b00000,
 0b00000,
 0b00000,
 0b00000
};

int motorPin1 = 8;
int motorPin2 = 9;
int motorPin3 = 10;
int motorPin4 = 11;

int speedPinPot = 0;
int decelPinPot = 1;

int i = 0;
int down = 0;
int up = 0;
int stop = 0;
int downDelayTime = 2;  
long double upDelayTime;
double ritardo;
long previousMillis = 0;
long interval = 100;

void setup() {      
 
 pinMode(motorPin1, OUTPUT);  
 pinMode(motorPin2, OUTPUT);  
 pinMode(motorPin3, OUTPUT);  
 pinMode(motorPin4, OUTPUT);
 
 pinMode(SCENDI, INPUT);  
 pinMode(SALI, INPUT);
 pinMode(speedPinPot, INPUT);
 pinMode(decelPinPot, INPUT);
 
 lcd.createChar(1, esponente);
 lcd.begin(20, 2);
 lcd.print("Vel.iniz.");
 lcd.setCursor(16, 0);
 lcd.print("mm/s");
 lcd.setCursor(0, 1);
 lcd.print("Deceler.");
 lcd.setCursor(15, 1);
 lcd.print("mm/s");
 lcd.write(1);
}  

void loop() {  
 
 int speedReadPin = analogRead(speedPinPot);
 upDelayTime = map(speedReadPin, 0, 1024, 10000, 100000);
 double velocita = (1000000/upDelayTime) * 0.226;
 
 int decelReadPin = analogRead(decelPinPot);
 ritardo = map(decelReadPin, 0, 1024, 0, 1000);
 double decelerazione = ( ( (1/upDelayTime) - (1/(upDelayTime + ritardo)) )/0.1 ) * 1000000 * 0.226;
 
 lcd.setCursor(10, 0);
 if (velocita < 10)
   lcd.print(" ");
 lcd.print(velocita);
 
 lcd.setCursor(10, 1);
 if (decelerazione < 10)
   lcd.print(" ");
 lcd.print(decelerazione);
 
 down = digitalRead(SCENDI);    
 up = digitalRead(SALI);
   if (down == HIGH)
     scendi();        
   if (up == HIGH)  
     sali();    
}  

void scendi() {  
 
 if(!stop) {
   
   digitalWrite(motorPin1, LOW);  
   digitalWrite(motorPin2, HIGH);
   digitalWrite(motorPin3, HIGH);  
   digitalWrite(motorPin4, LOW);  
   delay(downDelayTime);  
   i++;
   
   digitalWrite(motorPin1, LOW);  
   digitalWrite(motorPin2, HIGH);
   digitalWrite(motorPin3, LOW);  
   digitalWrite(motorPin4, HIGH);  
   delay(downDelayTime);  
   i++;
   
   digitalWrite(motorPin1, HIGH);  
   digitalWrite(motorPin2, LOW);
   digitalWrite(motorPin3, LOW);  
   digitalWrite(motorPin4, HIGH);  
   delay(downDelayTime);  
   i++;
   
   digitalWrite(motorPin1, HIGH);  
   digitalWrite(motorPin2, LOW);
   digitalWrite(motorPin3, HIGH);  
   digitalWrite(motorPin4, LOW);  
   delay(downDelayTime);
   i++;
   
   if (i > 159)
     stop = 1;
   }
}  

void sali() {  
 
 stop = 0;

 while(i>0){
   unsigned long currentMillis = millis();
   
   if (currentMillis - previousMillis > interval) {
     previousMillis = currentMillis;  
     upDelayTime += ritardo;
   }
   digitalWrite(motorPin1, HIGH);  
   digitalWrite(motorPin2, LOW);
   digitalWrite(motorPin3, HIGH);  
   digitalWrite(motorPin4, LOW);  
   delayMicroseconds(upDelayTime);
   i--;
   
   if (currentMillis - previousMillis > interval) {
     previousMillis = currentMillis;  
     upDelayTime += ritardo;
   }    
   digitalWrite(motorPin1, HIGH);  
   digitalWrite(motorPin2, LOW);
   digitalWrite(motorPin3, LOW);  
   digitalWrite(motorPin4, HIGH);  
   delayMicroseconds(upDelayTime);  
   i--;

   if (currentMillis - previousMillis > interval) {
     previousMillis = currentMillis;  
     upDelayTime += ritardo;
   }
   digitalWrite(motorPin1, LOW);  
   digitalWrite(motorPin2, HIGH);
   digitalWrite(motorPin3, LOW);  
   digitalWrite(motorPin4, HIGH);  
   delayMicroseconds(upDelayTime);  
   i--;
   
   if (currentMillis - previousMillis > interval) {
     previousMillis = currentMillis;  
     upDelayTime += ritardo;
   }    
   digitalWrite(motorPin1, LOW);  
   digitalWrite(motorPin2, HIGH);
   digitalWrite(motorPin3, HIGH);  
   digitalWrite(motorPin4, LOW);  
   delayMicroseconds(upDelayTime);  
   i--;
 }

}



ma il motore non risponde più bene ai valori che gli impongo coi potenziometri, addirittura va più veloce quando setto una velocità minore e viceversa!!

Dove potrebbe essere il problema? Perchè adesso effettivamente noto che la regolazione delle decelerazione è molto meno granulosa, non si avvertono più cambiamenti di velocità "a scatti" come succedeva prima solo che succedono cose strane...addirittura se si impongono valori di decelerazione alti, il motore prima rallenta e poi si ferma del tutto ad un certo punto emettendo un fischio pur essendo il range dei valori imposti identico al precedente...

leandro78

In realtà il primo modo a cui avevo pensato per implementare la decelerazione era molto più semplice, con u semplice contatore contavo i passi a ritroso e ad ogni passo incrementavo il valore del ritardo di una certa quantità settabile tramite il potenziometro....però in quel modo non sapevo come fare a calcolare il valore della decelerazione visto che la durata di ciascun passo va variando e quindi la decelerazione non era costante in quel caso...

qsecofr

non ho capito dove detrai (anzi aumenti) il downdelaytime... da un'analisi spannometrica lo lasci a 2....ma sicuramente sono io distratto.

un'altra cosa... e spero qua di non sputtanarmi ma mi pare che è così... vedo che fai operazioni abbastanza complesse tra double e long o int... (tra cui un 1/updelaytime)... mi risulta che lui fin che non serve convertire non converte quindi se hai

double = (1/intero)
...il risultato sarebbe una gran delusione per te...
meglio che fai cose del tipo d= (double) 1 /intero;

a me andava il motore in fischio quando perdeva il passo (picco di accellerazione o decellerazione) e si ritrovava quindi spaesato a fare cose che non può più fare... bloccato. Quando succede prova a dargli dei colpetti e vedi se riparte: di solito riparte e se no bisogna scendere a 0 di velocità e ripartire.

leandro78

#42
Dec 05, 2012, 02:34 pm Last Edit: Dec 05, 2012, 02:36 pm by leandro78 Reason: 1
il downdelaytime è fisso perchè non mi serve variare la velocità di discesa della slitta, quello che varia è l'updelaytime: tramite l'istruzione

#upDelayTime = map(speedReadPin, 0, 1024, 10000, 100000);#

setto un suo valore iniziale che poi posso fare variare nel tempo tramite un altro potenziometro che gestisce la decelerazione: ogni 100 ms il suo valore viene incrementato di una quantità pari a ritardo che può andare da 0 a 1 ms:

# if (currentMillis - previousMillis > interval) {
     previousMillis = currentMillis;  
     upDelayTime += ritardo;
   }#

updelaytime l'ho definito come double, per cui 1/updelaytime dovrebbe essere un double no?

Ma perchè non mi evidenzia mai il codice, cosa sbaglio?!?



PaoloP

Non devi inserire il carattere # da tastiera, ma premere il pulsante # che si trova sopra la faccina ammiccante.  ;)
Alla pressione del pulsante escono i tag (code). Il codice lo devi scrivere tra i due tag.

Volendo puoi anche modificare tutti i tuoi interventi precedenti premendo modify, selezionando il codice e premendi il pulsante #, sopra le faccine.
Poi salvi le modifiche.

qsecofr

quello che intendo dire è che se tu dividi due interi ottieni un intero... che poi tu voglia mettere questo risultato in un double sono affari tuoi ma lui mette dentro interi... prova... metti qualche serial.print e poi mi sai dire perchè io ho penso il peggior simulatore del pianeta ed il leonardo non ce l'ho mai sotto mano.

quindi

se i = 2 e fai d = 1/d non hai d = 0.5 ma... 0... perchè lui prima fa una divisione tra interi con risultato appunto 0 e poi il risultato lo sposta su d... ecco ora l'ho spiegato meglio: spero di non aver detto una cazzata ma mi pare di no.

Go Up