RISOLTO:Servo a Scatti e monitor LCD

Buonasera chiedo una cortesia , in uno sketch come faccio ad aprire 2 interfacce dell'IDE?.Nella funzione void setup è sufficiente inserire 2 volte la seguente istruzione: Serial.begin(9600);
Poichè ho un braccio meccanico a cui è collegato sia un sensore ad ultrasuoni sia un display LCD e voglio utilizzare una interfaccia per la visualizzazione della distanza e una per acquisire un dato digitato dall'utente che indica di quale servo si vuole la visualizzazione dei gradi nel corso del movimento del braccio sul display. Grazie

Ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta è stato spostato nella sezione di lingua Italiana ... la prossima volta potrebbe venire direttamente eliminato ::slight_smile:

Guglielmo

La risposta alla tua domanda è NO, non si può fare.

Se vuoi due terminali seriali devi usare DUE porte seriali (se sei su un Arduino UNO puoi creare la seconda porta seriale utilizzando la SoftwareSerial) e poi apri le due porte e colleghi a due porte USB diverse del PC per avere due terminali seriali separati.

Guglielmo

... però non capisco, perché non ti va bene UN solo terminale seriale?

Sullo schermo visualizzi i dati, e leggi ciò che viene digitato da tastiera (senza fare l'eco sullo schermo) ... ovvero sul terminale visualizzi la distanza e tramite la tastiera leggi i dati digitati dall'utente.

La seriale è una sola, per la prima parte usi delle Serial.write() ,entre per la seconda delle Serial.read() (o simili).

Guglielmo

Buonasera Sig. Guglielmo mi scuso per aver riposto solo ora ma, ho avuto un po' di problemi personali.Grazie per il consiglio . Ho provato ma c'è qualcosa che ho sbagliato perchè non mi legge il dato digitato da tastiera. Mi spiego : ho definito una variabile char servo[1];dopodiche' non esegue la lettura,sto sbagliando qualcosa ma, non capisco dove. Grazie mille:

if (Serial.available()) {      
     servo[1] = Serial.read();
      
     switch(servo[1])
     {
       case 'b':  desc=descservo [0]; s=0; break;
       case 's':  desc=descservo [1]; s=1; break;
       case 'e':  desc=descservo [2]; s=2; break;
       case 'w':  desc=descservo [3]; s=3; break;
       case 'r':  desc=descservo [4]; s=4; break;
       case 'g' : desc=descservo [5]; s=5; break;
     }

[code]

[/code]

Io mi ero capito che si trattava di una interfaccia IDE-pata

Che molto mi servirebbe, per motivi miei

Ma non sono capace di farla

Qualcuno ha idee?

sky70:
Sto sbagliando qualcosa ma, non capisco dove. Grazie mille

... dichiara la variabile semplicemente come "char servo;" invece che come un array di 1 elemento (a che serve?).

Se vuoi continuare ad usare il tuo array di UN elemento ti devi ricordare che ...
... il primo elemento HA INDICE ZERO e non 1 !!!

Un array di N elementi va da 0 a N-1 ... verifica anche gli altri array.

Guglielmo

Buonasera ho provato a correggere ma non legge il carattere/numero da tastiera . Ho provato a cambiare il case ponendo numeri da 0 a 5 e ho dichiarato int la variabile servo ma, non li legge da IDE. Se potete avrei bisogno ancora di un suggerimento . Nel progetto , che muove un braccio meccanico a cui è collegato un monitor LCD , l'acquisizione da IDE di un numero che va da 0 a 5 mi serve per far decidere quale servo monitorare durante il movimento. Poichè non mi funziona da IDE , ho posizionato la variabile servo a 0 per monitorare il servo BASE. In effetti il monitoraggio avviene ma il servo va a scatti:
// Rotazione Servo Base del Braccio.Vorrei un suggerimento per ovviare al fatto che servo va a catti, se possibile. Grazie mille

for (ang=180; ang>90; ang--){

    if ( s==0 ){
    visgradiservo ( ang );
    }

    Octopus.analogWrite(basePin, ang );

     delay(10);     
 }

Prova a mettere tutto il codice leggendo prima QUESTO.

Buonasera ho provato a correggere ma non legge il carattere/numero da tastiera . Ho provato a cambiare il case ponendo numeri da 0 a 5 e ho dichiarato int la variabile servo ma, non li legge da IDE. Se potete avrei bisogno ancora di un suggerimento . Nel progetto , che muove un braccio meccanico a cui è collegato un monitor LCD , l’acquisizione da IDE di un numero che va da 0 a 5 mi serve per far decidere quale servo monitorare durante il movimento. Poichè non mi funziona da IDE , ho posizionato la variabile servo a 0 per monitorare il servo BASE. In effetti il monitoraggio avviene ma il servo va a scatti.Vorrei un suggerimento sia per acquisire un dato da ide sia per il servo base a non farlo andare a scatti. Grazie

#include <Wire.h>
#include <Octopus.h>
#include <EEPROM.h>
#include "HCSR04.h"
#include <LiquidCrystal.h>



#define p7  7       
#define p8  8     
#define p9  9     
#define p10 10 
#define p11 11     
#define p12 12  

// initialize the library with the numbers of the interface pins
 LiquidCrystal lcd(p7, p8, p9, p10, p11, p12);

//octopus output

#define basePin 0        // Definisco il Servo Base alla porta 0 della Shield Octopus
#define shoulderPin 1    // Definisco il Servo Spalla ( Shoulder ) alla porta 1 della Shield Octopus
#define elbowPin 2       // Definisco il Servo Gomito ( Elbow ) alla porta 2 della Shield Octopus
#define wristPin 3       // Definisco il Servo Polso ( Wrist ) alla porta 3 della Shield Octopus
#define rotationPin 4    // Definisco il Servo Rotazione  alla porta 4 della Shield Octopus
#define gripperPin 5     // Definisco il Servo Pinza ( Gripper )  alla porta 5 della Shield Octopus

float cm = 0; // variabile  in cui viene memorizzata la distanza dall'ostacolo, in centimetri.
             
             
int gradi_servo = 180;
int durata =20;
int frequenza =40;
int s=0;            // Variabile per l'indicizzazione del vettore contenete la descrizione dei servo
int ang=0;          // Variabile definita come intero che contiene l'angolo raggiunto dal braccio
char desc; 
char descservo [6][12] = // descrizione dei servomotori _ servomotor description
{
  
{"Base "}, // base
{"Braccio "}, // arm/Shouder( Braccio/Spalla )
{"Gomito "}, // Elbow
{"Polso "}, // wrist
{"Rot.Polso "}, // wrist turn
{"Pinza "}, // Gripper

};

int servo;
boolean ost=false; // Variabile Booleana che indica se c'è un ostacolo o meno 

void caldist () //***** inizio della routine “caldist” : calcola la distanza dell'ostacolo dal sensore*******

{
  Octopus.digitalWrite(5, LOW); //disattiva, sulla porta 12, il lancio del fascio di ultrasuoni 
  delayMicroseconds(2);         // attende 2 microsecondi 
  
  Octopus.digitalWrite(5, HIGH); // attiva, sulla porta 12, il lancio del fascio di ultrasuoni
  delayMicroseconds(10);         // attende 10 microsecondi ,tempo richiesto dal modulo HC-SR04 per
                                 // ricevere ed elaborare il segnale di ritorno
                         
  Octopus.digitalWrite(5, LOW); // disattiva, sulla porta 12, il lancio del fascio di ultrasuoni
  cm = pulseIn(4, HIGH) / 58.0; // rileva, sulla porta 11, il segnale di ritorno e  lo converte in centimetri 
} 

void visdist (void)       //  inizio della routine “visdist” 

{ 
    
  Serial.print(cm);      // visualizza sul monitor seriale il valore contenuto nella variabile cm
  Serial.println(" cm"); // visualizza la dicitura “ cm” e posiziona il cursore sulla riga successiva

}
//
void visgradiservo (int ang )
{
lcd.clear();
lcd.setCursor(0, 0);         // posiziona il cursore all'inizio della prima riga
lcd.print ("Servo :  ");
lcd.print (descservo [s]);
lcd.setCursor (0, 1);       // posiziona il cursore all'inizio della seconda riga
lcd.print ("gradi = ");
lcd.print (ang);
lcd.print (" ");
return( ang );
}
//

//
void setup(void)
{    
  Wire.begin();
  Wire.setClock(100000);
  Octopus.setPWMFreq(frequenza);

  Serial.begin(9600);            // inizializza il monitor seriale
  Octopus.pinMode(5, OUTPUT);  // definisce la porta digitale 5 (collegata al trigger) come porta di output
  Octopus.pinMode(4, INPUT);  //  definisce la porta digitale 4 (collegata all'echo) come porta di input

//Inzio Posizionamento dei Servo Motori

   Octopus.analogWrite(basePin, 180);
   delay(500); 
   
   Octopus.analogWrite(shoulderPin, 180);
   delay(500); 

   Octopus.analogWrite(elbowPin, 90); 
   delay(500);

   Octopus.analogWrite(wristPin, 185); 
   delay(500);

   Octopus.analogWrite(gripperPin, 75);
   delay(500);

// Fine Posizionamento dei Servo Motori   

 // set up monitor lcd
  lcd.begin(16, 2);
  
}

void loop(void)
{

    
 while( ost==true )
 {
    
  
   caldist ();    // Chiama  la routine di calcolo  della distanza
   visdist ();   //  Chiama  la routine di visualizzazione della distanza calcolata sul monitor seriale
   
   if ( cm>11 )
        {
         ost=false;
        
        } 
          
 } 
  
 while( ost==false )
  {

     
  caldist ();    // Chiama  la routine di calcolo  della distanza
  visdist ();   //  Chiama  la routine di visualizzazione della distanza calcolata sul monitor seriale
  delay(durata);

  if (Serial.available()) {      
      servo=Serial.read();
       
      switch(servo)
      {
        case 0:  desc=descservo [0]; s=0; break;
        case 1:  desc=descservo [1]; s=1; break;
        case 2:  desc=descservo [2]; s=2; break;
        case 3:  desc=descservo [3]; s=3; break;
        case 4:  desc=descservo [4]; s=4; break;
        case 5 : desc=descservo [5]; s=5; break;
      }
   }  
.
.
. 
// Rotazione Servo Base del Braccio

 for (ang=180; ang>90; ang--){

     if ( s==0 ){
     visgradiservo ( ang );
     }
      
     Octopus.analogWrite(basePin, ang );

      delay(durata);     
 
       caldist ();    // Chiama  la routine di calcolo  della distanza
       visdist ();    // Chiama  la routine di visualizzazione della distanza calcolata sul monitor seriale 
       
       

//  Se il sensore rileva un ostacolo , si ritorna nella sua posizione iniziale e ricomincia il ciclo 

       if ( cm<11 )
      {
        ost=true;
        break;
      }  

  
 }
 uint16_t to(int gradi)
{
  float ms_min; 
  float ms_max;
  float ms_gradi;
  float valore_PWM;

  ms_min = 120; //Rappresenta il valore PWM pari a 1 ms (posizione 0°)
  ms_max = 470; //Rappresenta il valore PWM pari a 1 ms (posizione 180°)
  ms_gradi = (ms_max - ms_min) / gradi_servo;
  valore_PWM = ms_min + (ms_gradi * gradi);
  return (valore_PWM);
}

Serial.read() ritorna il carattere letto, e il carattere 0 è diverso dal numero 0. Prova a mettere i case tra apici singoli, tipo:

  case '0':

Buonasera ho provato con i singoli apici ma non funziona. Grazie

sky70:
Buonasera ho provato con i singoli apici ma non funziona. Grazie

Allora, intanto qualche cosina:

  1. modifica i tuoi post #4 e #7 per racchiudere il codice tra i tag “code”
  2. cerca di abituarti ad indentare correttamente il codice (se premi Ctrl-T nell’IDE te lo riformatta lui correttamente) perché questo aiuta te a capire meglio il flusso e noi a leggere con più facilità il tuo codice
  3. come ti hanno detto, la Serial.read() restituisce un byte che a sua volta rappresenta anche un carattere. Quindi se come immagino da monitor seriale mandi il carattere ‘0’ e non un byte con valore 0, nello switch() tu devi confrontare con ‘0’ (che ha valore 48) e non con 0, ossia non "case 0: " ma “case ‘0’:”
  4. Il monitor seriale invia i caratteri digitati solo quando premi Invio, quindi sulla seriale avrai non solo il carattere ‘0’ ma anche il fine riga ossia ‘\r’ (CR, Carriage Return, valore 13) e ‘\n’ (LF, Line Feed o New Line, valore 10): questi caratteri per ora non ti danno fastidio, ma ricorda che in caso di modifica a questo protocollino sarebbe opportuno “filtrarli” o considerarli (ad esempio se in futuro se dovessero servirti più di un singolo carattere, o vorrai far passare più dati ad esempio separati da virgola).

Il che significa quindi:

  if (Serial.available()) {      
      servo=Serial.read();      
      switch(servo)
      {
        case '0':  desc=descservo [0]; s=0; break;
        case '1':  desc=descservo [1]; s=1; break;
        case '2':  desc=descservo [2]; s=2; break;
        case '3':  desc=descservo [3]; s=3; break;
        case '4':  desc=descservo [4]; s=4; break;
        case '5' : desc=descservo [5]; s=5; break;
      }
   }

oppure un più elegante:

  if (Serial.available()) {      
      servo=Serial.read();      
      if(servo>='0 && servo <='5')
     {
        s = servo-'0';
        desc=descservo[s];
      }
   }

Buonasera non appena possibile effettuero' le modifiche e i test. Sono alle mie prime esperienze con la programmazione in linguaggio wiring e con un braccio meccanico. Se potete darmi supporto anche sul fatto che nel ciclo che riguarda il movimento del servo base ,chiamo una funzione che mi visualizza i gradi fatti dal servo. Il tutto è esposto nel codice ultimo sopra riportato e che funziona ma , il servo si muove a scatti e vorrei correggere ma non so come fare. Ho provato a sostituire il ciclo for con il while ma senza risultato. Non trovo la soluzione per evitare che il servo si muova a scatti. Se tolgo la chiamata a tale funzione , il servo si muove correttamente. Grazie mille

In sostanza stai dicendo che sei alle prime armi con il linguaggio (cosa significa sostituire "il ciclo for con il while"?) e con i servo, stai usando un codice fatto da altri che non conosci bene, e secondo me forse è anche un copia-incolla di vari pezzi di codice...

Come consigliamo sempre, bisogna intanto cercare di studiare un poco almeno le basi del linguaggio, poi in secondo luogo fare prove "singole" ossia di singoli elementi (un solo servo, un solo sensore...) per cercare di comprendere meglio il meccanismo generale. Solo allora si può iniziare con qualche progetto un po' più impegnativo, altrimenti siamo nella classica "sindrome di Gundam".

Detto questo, nel tuo caso inizia a fare le cose che ti ho indicato nel precedente post, inclusa la riformattazione corretta del codice perché così com'è ora non è di facile comprensione (e neanche completo credo, visti i "puntini" che ci sono in alcune parti: se hai problemi a caricarlo nel testo per via delle dimensioni, caricalo come allegato). Fatto questo, possiamo cercare di aiutarti, forse anche con questo movimento a scatti del servo (che generalmente è causato da un non corretto uso dei delay()).

Buonasera no il codice è stato sviluppato da me. L'unica parte che mi è stata fornita dall'assitenza dove ho comprato il braccio , è legata alla conversione del segnale PWM ( Ultima parte del flusso). La restante parte l'ho sviluppata io dopo aver studiato ed effettuato prove di vario tipo. Per quanto riguarda il ciclo for , l'ho simulato con un ciclo while e il funzionamento non è cambiato . Ora ,riprovo ,a inserire l'intero codice copiato da Interfaccia con il copia per Forum, ma mi dice che supera il numero di caratteri limite. Ecco perchè ci sono deo puntini. In ogni caso , nel prossimo post , cerco di inserire tutto il codice. Saluti

sky70:
La restante parte l'ho sviluppata io dopo aver studiato ed effettuato prove di vario tipo. Per quanto riguarda il ciclo for , l'ho simulato con un ciclo while e il funzionamento non è cambiato

Argh... Ok, non è copiato ma va male lo stesso perché significa che non hai fatto poi molta pratica col linguaggio e con la gestione dei componenti ad iniziare dall'input seriale!

Ripeto, "simulato un ciclo for con un while" non ha grosso senso, perché se anche venisse fatto bene non potrebbe ovviamente neanche cambiare nulla!

Quindi, ripeto:

  1. modifica i tuoi post #4 e #7 per racchiudere il codice tra i tag "code"
  2. cerca di abituarti ad indentare correttamente il codice (se premi Ctrl-T nell'IDE te lo riformatta lui correttamente) perché questo aiuta te a capire meglio il flusso e noi a leggere con più facilità il tuo codice
  3. come ti hanno detto, la Serial.read() restituisce un byte che a sua volta rappresenta anche un carattere. Quindi se come immagino da monitor seriale mandi il carattere '0' e non un byte con valore 0, nello switch() tu devi confrontare con '0' (che ha valore 48) e non con 0, ossia non "case 0: " ma "case '0':"

Ora ,riprovo ,a inserire l'intero codice copiato da Interfaccia con il copia per Forum, ma mi dice che supera il numero di caratteri limite. Ecco perchè ci sono deo puntini.

Scusa, ma tu i messaggi che ti scriviamo li leggi? Te lo avevo scritto, quale parte di "se hai problemi a caricarlo nel testo per via delle dimensioni, caricalo come allegato" non era chiara?

Buonasera ci tengo a precisare che l’unica parte che mi è stata fornita dall’assistenza dove ho acquistato il braccio è l’ultima dove c’è la conversione del segnale PWM. Tutto il resto l’ho fatto io dopo mesi di studio , tempo libero da lavoro e famiglia, pertanto è facile che abbia commesso errori. Inoltre ho provato a togliere righe in eccesso e salvare ed effettuare il CTRL+T da interfaccia e selezionare copia per forum, ma mi dice sempre che supero il limite consentito. Ecco perchè i puntini. In allegato il codice. Grazie mille per l’aiuto e la comprensione. Saluti

Braccio_Sensore_Lcd.txt (10.9 KB)

Ok, ma guarda che ti basta semplicemente allegare il file "*.ino" nella tua cartella dello sketch, non fare "copia per il forum" e incollarlo in un txt (tra l'altro nel file txt se vedi ci sono i tag "code" che non servono lì, mentre ti ripeto anche che devi mettere i tag code anche nei tuoi post precedenti #4 e #7 prima che te lo dica anche un moderatore.

Salve spero di aver modificato correttamente i tag #4 e #7. In allegato il file richiesto

BRACCIO_SENSORE_LCD.ino (10.9 KB)