Pages: [1]   Go Down
Author Topic: Muovere servomotore tramite tastiere del pc  (Read 961 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Salve a tutti, io ho il seguente problema, ho montato un servo motore e un potenziometro, e tutto funziona bene, ora voglio smontare il potenziometro e far girare il servo tramite la tastiere del pc, il proggetto consiste in questo:
utilizzando i pulsanti da 1 a 8 voglio che il mio servo si muova di tot gradi (sempre gli stetti per i corrispettivi tasti ossia premendo il tasto 1 va in posizione 1, premendo il tasto 3 va in posizione 3, e se premo il tasto 1 va in posizione 1 e non incrementa la posizione 3), come posso realizzare ciò, quale funzioni devo usare? il mio servo si muove di 180 gradi.....
Help Me!!!! Aiuto!!!
P.S. non voglio e non devo usare la libreria srervo.h,  smiley-grin
Logged

BZ (I)
Offline Offline
Brattain Member
*****
Karma: 251
Posts: 21266
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao projectarms

apri un terminale del IDE sul PC o ti scrivi un programma che legge i tasti premuti sulla tastiera invia sulla seriale.
Sul arduino leggi i valori che arrivano dalla seriale e a seconda del numero piloti il servo alla posizione corrispondente.

Ciao Uwe
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wuau, una risposta molto dettagliata, quello ke mi hai descritto lo sapevo già, il problema è il codice, ovvero quali comandi devo utilizzare e come?
come faccio a dirgli all'arduino ke mi deve muovere il servo di tot gradi, ad esempio digido 180° in 8 parti corrispondenti a 8 pulsanti (da 1 a smiley-cool
Come faccio a dare i gradi ai corrispettivi pulsanti?
Grazie.
Logged

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10448
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

il servo legge un segnale PPM.
Il segnale in genere dura 20millis, con il segnale HIGH che va da 800 a 2000 microsec, e il segnale LOW per il resto del tempo.
un segnale 800microsec significherà 0°, e 2000microsec significherà 180°.
Sta a te provare i valori, sono andato a memoria. E occhio a non confondere millisec con microsec.
credo che non ti serva altro per il progetto smiley
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9168
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Il segnale standard per il controllo dei servi è 1ms per una rotazione di -45° e 2ms per una rotazione di +45°, corsa complessiva 90°.
Per ruotare il servo di +/-90° (180°), compatibilmente con i suoi limiti meccanici, serve un segnale compreso tra 500us e 2500us.
Questi valori possono differire leggermente, si parla di decine di us, a seconda della marca e del modello del servo.
Ipotizzando di voler ruotare il servo 90° diviso in 8 parti occorre generare otto diversi impulsi di comando:

1000us 0°
1142us 12.85°
1285us 25.7°
1428us 38.5°
1571us 51.4°
1714us 64.25°
1857us 77.1
2000us  90°

Ovviamente la precisione finale del posizionamento dipende in massima parte dalla qualità del servo, diciamo che con un servo economico è meglio non aspettarsi precisioni superiori al singolo grado.

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ragazzi grazie di tutto ma sono ancora bloccato, non riesco a creare un algoritmo per il mio problema, non so nemmeno come faccio a fare tornare indietro il mio servo, qualcuno mi può aiutare a sviluppare il codice e ad impostare la logica da utilizzare? grazie ancora...
Logged

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9168
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

C'è una cosa che non mi quadra nel tuo discorso, sei partito dicendo che hai mosso un servo tramite un potenziometro il che mi porta ad immaginare che hai caricato su Arduino uno sketch che legge la posizione del potenziometro tramite l'ADC e di conseguenza genera il PPM (treno d'impulsi) per posizionare il servo.
Alla fine dici che non puoi e non vuoi usare servo.h, che non è una libreria come dici tu ma semplicemente un file include per la vera libreria, però se non la usi, e mi dovresti spiegare il motivo, le cose ti diventano molto complicate.
Se hai già il programma che legge il potenziometro e ti posiziona il servo non devi fare altro che eliminare la lettura dell'ADC e al suo posto inserire la lettura della porta seriale, in funzione del valore che ricevi posizioni il servo.
Esempio pratico, sul pc devi avere un programmino semplice semplice che monitorizza la tastiera, se premi i tasti da 1 a a 8 invia sulla seriale il relativo valore sotto forma di numero, ma volendo anche come carattere ASCII, quindi i numeri da 1 a 8, su Arduino tieni sotto controllo la seriale e quando arriva un valore verifichi se è un numero compreso tra 1 e 8 per poi passare a generare il giusto PPM in funzione di questo valore.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sto sviluppando una traccia per un esame dove mi viene richiesto di non usare la servo.h
Il codice che ho sviluppato per il servo con il potenziometro è il seguente:
Code:
int servoPin = 2;      // Pin di controllo per il servo motore
 int minPulse = 500;    // Posizione minima del servo
 int maxPulse = 2500;  // Posizione massima del servo
 int pulse = 0;        // Quantità di impulso per il servo

 long lastPulse = 0;    // Tempo in millisecondi dell'ultimo impulso
 int refreshTime = 20; // Tempo richiesto tra gli impulsi

 int analogValue = 0;  // Valore restituito dal sensore analogico
 int analogPin = 0;    // Pin analogico del potenziometro

 void setup() {
  pinMode(servoPin, OUTPUT);  // Setta il pin del servo in modalità output
  pulse = minPulse;            // Setta la posizione del motore sul valore minimo
  Serial.begin(9600);          // apre la porta seriale,imposta  la velocità di trasmissione in bit al secondo (baud) per la                 
                                        // trasmissione seriale dei dati.
 }

 void loop() {
  analogValue = analogRead(analogPin);      // Legge l'ingresso analogico
  pulse = map(analogValue,0,1023,minPulse,maxPulse);    // Converte il valore analogico in un intervallo tra minPulse e maxPulse.

  // Invia un nuovo impulso al servo se il tempo di refresh (20 ms) è trascorso

if (millis() - lastPulse >= refreshTime) { // millis() Restituisce il numero di millisecondi da quando la scheda Arduino ha iniziato l'esecuzione del programma corrente.
                                                // Questo numero di overflow (tornare a zero), dopo circa 50 giorni.
    digitalWrite(servoPin, HIGH);    // Accende il motore
    delayMicroseconds(pulse);        // La lunghezza dell'impulso setta la posizione del motore.Mette in pausa il programma per la quantità di tempo specificato come parametro.
    digitalWrite(servoPin, LOW);    // Spegne il motore
    lastPulse = millis();            // Salva il tempo dell'ultimo impulso
  }
 }

ora devo modificarlo per assegnare a 8 pulsanti una posizione prestabilita e non ci riseco....
se qualcuno sa come modificare questo programma mi può dare una mano gentilmente.....
Molto importante è che se mi trovo in posizione 5 ad esempio con 157° e devo ritornare alla posizione 2 che è a 22° devo poterlo fare quindi il mio motore deve girare sia a destra che a sinistra....
Per maggiori delucidazioni sono a vostra completa disposizione...
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 189
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

io ci capisco davvero molto ma molto poco...pero dicono che sbagliando si impara, quindi dò la mia idea...anche se ti direi a parole ma il codice non so ancora scriverlo... dovresti utilizzare il comando "if"  ...ovvero, devi programmare l'arduino in questo modo :
ogni tot di tempo legge il segnale sulla seriale, e lo chiamiamo valore servo..
if (valore servo) è 1; sposta il servo a (primo valore che ti serve)
if (valore servo) è 2; sposta il servo a (secondo valore che ti serve)
if (valore servo) è 3; sposta il servo a  (terzi valore che ti serve)
e cosi via anche per i restanti tasti...
 magari ho detto una stupidaggine..
Logged

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10448
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

o anzichè mille if puoi usare uno switch smiley
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9168
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Questo è il tuo sketch modificato per leggere tramite la seriale i tasti premuti sul pc e posizionare il servo in otto diversi punti abbinati ai tasti da 1 a 8.
Ho commentato la parte dove leggi il potenziometro e al suo posto ho inserito la lettura della seriale più lo switch per interpretare il valore.
La riga " pulse = 1500;" preinizializza la posizione del servo al centro, se vuoi che il punto iniziale sia diverso devi solo inserire al posto di 1500 il valore in microsecondi corrispondente alla posizione.
Ho aggiunto nel ciclo generazione impulsi il lampeggio del led ad una frequenza pari ad 1/2 del frame rate, cioè 25 Hz, in questo modo hai un controllo visivo che il programma gira regolarmente e non si è bloccato da qualche parte.
E' buona norma prevedere sempre un led lampeggiante come prima verifica che il tutto non sia bloccato da qualche parte.
Per provare il tutto non devi fare altro che aprire il terminale seriale dell'IDE, 9600 bps, e premere i tasti da 1 a 8 premendo il pulsante "send", oppure usi Hyperterminal e ti basta premere i tasti 1-8, setta ON l'eco per vedere cosa hai premuto.

Code:
int servoPin = 2;      // Pin di controllo per il servo motore
 int minPulse = 500;    // Posizione minima del servo
 int maxPulse = 2500;  // Posizione massima del servo
 int pulse = 0;        // Quantit� di impulso per il servo

 long lastPulse = 0;    // Tempo in millisecondi dell'ultimo impulso
 int refreshTime = 20; // Tempo richiesto tra gli impulsi

 int analogValue = 0;  // Valore restituito dal sensore analogico
 int analogPin = 0;    // Pin analogico del potenziometro
 int Servo_Pos = 0;                 // posizione servo da pc

 void setup() {
  pinMode(servoPin, OUTPUT);  // Setta il pin del servo in modalità output
  pinMode(13, OUTPUT);                  // abilita il led
  pulse = minPulse;            // Setta la posizione del motore sul valore minimo
  Serial.begin(9600);          // apre la porta seriale,imposta  la velocità di trasmissione in bit al secondo (baud) per la                 
                                        // trasmissione seriale dei dati.
 }

 void loop() {
    //analogValue = analogRead(analogPin);     
    //pulse = map(analogValue,0,1023,minPulse,maxPulse);   
   
    pulse = 1500;                        // preinit posizione servo al centro;
   
    if (Serial.available() > 0)          // verifico presenza dati su seriale
     {   
      Servo_Pos = Serial.read();         // leggo la seriale
     }
     
    switch(Servo_Pos)
     {
      case '1': 
       pulse = 1000;
      break;
     
      case '2': 
       pulse = 1142;
      break;
     
      case '3': 
       pulse = 1285;
      break;
     
      case '4': 
       pulse = 1428;
      break;
     
      case '5': 
       pulse = 1571;
      break;
     
     
      case '6': 
       pulse = 1714;
      break;
     
      case '7': 
       pulse = 1875;
      break;
     
      case '8': 
       pulse = 2000;
      break;
     }
   
    // Invia un nuovo impulso al servo se il tempo di refresh (20 ms) � trascorso
    if (millis() - lastPulse >= refreshTime) { // millis() Restituisce il numero di millisecondi da quando la scheda Arduino ha iniziato l'esecuzione del programma corrente.
                                                // Questo numero di overflow (tornare a zero), dopo circa 50 giorni.
    digitalWrite(servoPin, HIGH);    // Accende il motore
    delayMicroseconds(pulse);        // La lunghezza dell'impulso setta la posizione del motore.Mette in pausa il programma per la quantit� di tempo specificato come parametro.
    digitalWrite(servoPin, LOW);    // Spegne il motore
    lastPulse = millis();            // Salva il tempo dell'ultimo impulso
   
    if (digitalRead(13) == HIGH) digitalWrite(13,LOW); // fa lampeggiare il led a 25 Hz
    else digitalWrite(13,HIGH);
     
  }
 }

Logged

Pages: [1]   Go Up
Jump to: