Vai al contenuto
PLC Forum


Ricevere variabile da seriale


roberto8303

Messaggi consigliati

Salve, come da titolo devo utilizzare arduino per pilotare un motore passo passo ma devo dare due input ad arduino uno e’ la velocita ed un altro e la posizione. Utilizzo visual basic come interfaccia utente ma non riesco a risolvere un problema. Praticamente mi occorrono queste due variabili che invio tramite connessione seriale ad arduino con la pressione di un bottone invio il comando serialport.writeline = velocita che avevo scritto in una texbox. Fino a qui tutto ok funziona, su arduino leggo questa variabile con velocita = serial.parseInt(). Il problema nasce con la ricezione della seconda variabile posizione, quando la invio non so come leggerla differenziandola dall altra variabile. Cioe arduino legge cio che riceve sulla seriale ma come faccio a dirgli leggi questo dato e associalo a velocita e leggi quest altro dato sulla seriale e associalo a posizione. Grazie 

Link al commento
Condividi su altri siti


Puoi usare 2 metodi uno aleatorio ma semplice e l'altro più complesso ma sicuro.

 

1 Metodo semplice.

Si presuppuno che si invii sempre prima il dato di velocità e poi quello di posizione.

Metti una memaoria su arduino che parte a zero.

Invii il dato di velocità, se la memoria è a zero, lo leggi e lo memorizzi, metti a 1 la memoria.

Invii il dato di posizione, se la memoria è a d 1, arduino interpreta questo secondo dato come posizione ed azzera la memoria.

 

2 metodo sicuro.

 

Devi creare un vero e proprio protocollo.

Il terminale invia prima un codice, per esempio "A" per velocità e "B" per posizione.

Arduino risponde con il codice ricevuto ed un codice di "OK", Trasmetti il dato ed arduino rimanda l'ok e lo memorizza a seconda del codice ricevuto.

Link al commento
Condividi su altri siti

Sicuramente il secondo metodo e il piu efficace ma devo trovare qualche esempio altrimenti ci impiegherei giorni prima di arrivarci😀 

 

Link al commento
Condividi su altri siti

si grazie ma il mio problema è un po diverso, riesco gia ad inviare un numero ad arduino, ma il problema è che ne devo inviare due per due funzioni diverse. 

Se su arduino uso il serial read come faccio a sapere se questo numero ricevuto è per la quota di posizione o è per la velocita con cui devo raggiungere la posizione?

Livio ha capito perfettamente ma creare un protocollo di comunicazione per me è difficile, e poi sono solo due dati che dovrei ricevere.

Ho visto che c è anche la libreria firmata per visual basic ma comanda e legge solo i pin strano che non ci sia il modo di creare e leggere variabili.

Ho pensato di inviare in due modi, allora creo i due caratteri A e B se arduino riceve A allora vuol dire che devo inserire nella velocita il numero ricevuto, se arriva B allora è la posizione il numero ricevuto. Ho provato a farlo ma praticamente il numero inviato si confonde sempre a volte lo legge come posizione e a volte come velocita o viceversa

 

Link al commento
Condividi su altri siti

8 minuti fa, roberto8303 scrisse:

Livio ha capito perfettamente ma creare un protocollo di comunicazione per me è difficile,

 

Ma no.

Puoi semplicemente inviare 4 dati invece di 2.

Il primo dato è sempre il codica che identifica se il seguente sarà la velocità o la posizione.

Link al commento
Condividi su altri siti

ok, sto pensando di usare un altro metodo con tastiera keypad e display i2c, ma ecco un altro problema, la tastiera invia caratteri numerici che equivalgono 1=49 2=59 e cosi via fino a 9

come faccio a, inserire le mie tre cifre per la quota e leggere queste cifre com numero intero in una variabile?

un esempio che ho fatto ma non so come stampare a video il numero intero ad esempio digitato con il keypad 123 come centoventitre sul monitor

 

#include <Keypad.h>
#include <Wire.h> 
// http://www.dfrobot.com/wiki/index.php/I2C/TWI_LCD1602_Module_(SKU:_DFR0063)
#include <PCF8574_HD44780_I2C.h>
PCF8574_HD44780_I2C lcd(0x27,16,2);
// keypad type definition
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] =
 {{'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}};
 

 byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3};

int count=0;
int numero;

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
 
void setup()
{
  Serial.begin(9600);
  lcd.init();          // initialize the lcd
  lcd.backlight(); // turn on LCD backlight
}
 
void loop()
{ 

  Serial.println(numero);                                                                          // come visualizzo il numero intero? che in key è la somma dei caratteri premuti 1-2-3
  char key= keypad.getKey();
  
  if (key != NO_KEY)
  {
    lcd.print(key);
    count++;
    if (count==4)
    {
      lcd.clear();
      count=0;
    }
  }}

 

Link al commento
Condividi su altri siti

Comincio a non seguirti piùtanto bene.

 

Vediamo se ho capito.

Invece di usare un terminale che colloquia in seriale con arduino, ha cambiato con una periferica che interfaccia arduino trabite il bus I2C.

Ti arrivano 2 numeri che identificano riga e colonna del tasto; da questo a ricavare il numero è un'operazione molto semplice. Ottenuto il numero lo metti in un array o vettore, ed andrai ad incrementare il puntatore ad ogni numero ricevuto sino a quando riceverai il codice di fine riga. Ammettiamo che usi "#".

 A questo punto avrai un vettore di "n" elementi dove "n" è il valore del puntatore.

A questo punto avrai una cifra in formato BCD, se vuoi avere una cifra decimale devi farne la conversione moltiplicando ogni singolo numero contenuto negli elementi dell vettore per la realtiva potenza del 10. L'ultimo numero memorizzato varrà 100 il penultimo 101 il terzultimo 102 e così via.

Una volta moltiplicati i singoli numeri ne fai la somma ed hai il numero espresso in intero decimale.

 

Se fai una ricerca è probabile che trovi una funzione di libreria che implementa la conversione BCD ==> decimale.

 

Link al commento
Condividi su altri siti

allora ci sono riuscito

 ho fatto un esempio con il led 13 se il numero cioe la variabile intera è 200 si accende, solo per verificare che la conversione da char a stringa e poi intero funzionasse. ho usato la funzione toInt di arduino. Ma sono molto lontano devo costruirmi una macchina che mi sposta un collettore a lame di rame da smicare, inserisco il numero di lame, eseguo il calcolo per sapere quanti spostamenti deve fare il motore passo passo per posizionarsi al centro della lamella da pulire, parte una smicatrice che pulisce poi un altro passo e cosi via a pulirlo per il giro completo.

void loop()

  if(numerointero==200){
    digitalWrite(13,1);}
    else{
      digitalWrite(13,0);
    }
    
  numerointero=numero.toInt();
Serial.println(numerointero); 
  char key= keypad.getKey();
   if(isDigit(key)){
   numero+=(char)key;}
  if (key != NO_KEY)
  {
    lcd.print(key);  
    count++;
    if (count==4) {
      lcd.clear();
      numero="";
      count=0;
    }
  }}

 

Link al commento
Condividi su altri siti

Interessante!

In pratica un piccolo controllo numerico dedicato.

 

Ricordati tutti i discorsi sulla immunità ai disturbi praticamente inesistente di arduino, quindi filtri, schermature e separazione galvanica.

Link al commento
Condividi su altri siti

l avevo già fatta con motore brushless praticamente è come un tornio si mette tra mandrino e contropunta un rotore con il collettore da smicare, una smicatrice ad aria compressa è montata sua una slitta con cuscinetti su guida lineare e tramite un inverter e vite con chiocciola va avanti e dietro per pulire la mica. Ad ogni ritorno c è il un micro che comanda lo spostamento del mandrino per posizionarsi al centro di un altra lama da pulire, e cosi via per il numero di lame. Il motore che sposta il mandrino ovviamente è applicato ad un riduttore a gioco ridotto rapporto 1:100. 

Ho tolto il brushless perchè mi è servito per un altra applicazione e adesso invece di comprarne un altro vorrei realizzarla con il motore passo. 

Mi piacerebbe usare visual basic per l interfaccia grafica ma un po sono in difficolta sulla programmazione un po dovrei prevedere un pc o un tablet dove far girare l applicazione, e quindi ho pensato ad un tastierino numerico e display, tra l altro devo solo inserire il numero di lame, poi nel programma ad esempio, ho 150 lame da pulire 

quindi 360/150= 2.4 gradi *100 che sarebbe il rapporto del riduttore quindi dovrò spostare di 240° ogni movimento. il problema sarà se usciranno decimali...vediamo cosa succederà:unsure:

Link al commento
Condividi su altri siti

  • 1 month later...

ti conviene gestire un protocollo tuo di 10-20 o 30 bytes

Usare le funzioni di write e definire la lunghezza dei dati da trasferire e ricevere, in forma binaria non ASCII

In questo modo potrai gestire più cose contemporaneamente in modo serio

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...