netbeans e comunicação por porta serie

ola. sou novo a usar o arduino e tenho algumas duvidas.

eu estou a montar um carro para conduçao autonuma , e estou a tenho que controlar um servo motor e um motor de traçao por pwm. com o ambiente do arduino eu ja consigo controlar ambos, sozinhos e em simultaneo, mas agora pretendo implementar um novo sistema, e este tem que ser em c++.

o objectivo final e eu conseguir captar uma imagem em tempo real, e estrair dessa imagem caracteristicas, e mediante essas caracteristicas enviar dados ao arduino para controlar o motor e o servo, e a captura de imagem e extraçao de caracteristicas ja as tenho todas implementadas em c++ atraves do netbeans com recurso ao opencv

eu gostaria de saber se e possivel comunicar com o arduino em c++, em linux, no netbeans. A comunicaçao com o arduino tem que ser efectuada por porta serie (rs232), e é tem que ser efectuada em tempo real.

obrigado

Tudo é possível...

O Arduino é programado por porta série, e se estás a usar Linux, usar a porta série é tão simples como abrir um ficheiro. Tens no entanto de configurar a porta. Procura pelo google, existem mil e mu exemplos de como faz^^e-lo em C. Que serve para o que pretendes (configurar a porta) e depois encapsular a leitura da porta série numa classe C++, se não houver nada que faca isso.

O netbeans é um IDE. Você desenvolve nele. Não entendi o que/como vc quer conectar seu arduino no Netbeans via serial!

Agora, se vc pretende desenvolver o software em C++ no seu PC usando Netbeans, e o software em C++ conversar com seu arduino via serial, aí sim, é possível e não é muito difícil de fazer.

Agora, se vc pretende desenvolver o software em C++ no seu PC usando Netbeans, e o software em C++ conversar com seu arduino via serial, aí sim, é possível e não é muito difícil de fazer.

e exatamente isto que quero fazer

pelo que li tenho que ligar o arduino por porta serie (atravex dos pin's Rx e Tx e ja fiz isso), mas agora nao estou a ver como faço para conversar com ele.

eu preciso de enviar 2 dados (velocidade do motor e direçao do servo, ja consegui "controlar" ambos atrves do de programas exemplo que vem com o software do arduino), e ao mesmo tempo ler esses valores, dai ligar o Rx e o Tx.

eu gostaria de saber e como e que consigo criar e manter a "conversa" com o arduino, isto no netbens, pois é o ide em que ja desenvolvi parte do codigo que preciso. so falta a conversa com o arduino e ajustar os dados a enviar.

obrigado pela atençao

Opa...

Então, tem vários tutoriais/guias de como ler e escrever na porta serial utilizando C++. Infelizmente C++ não é minha liguagem preferida então não vou poder te ajudar. Só com uma rápida busca no google, eu achei vários links interessantes:
http://www.arduino.cc/playground/Interfacing/CPPWindows
http://todbot.com/blog/2006/12/06/arduino-serial-c-code-to-talk-to-arduino/

Embora alguns destes guias foquem em Visual C++, o código em C é portável entre IDE's, até mesmo sem utilizar IDE's(gcc no linux por exemplo).

[]s

Wagner Sartori Junior

boas.. antes de mais obrigado pela ajuda que tem dado. ja consegui fazer tudo no netbeans, envio de dados por porta serie ou usb, esta implementado das duas maneiras.

agora que envio a informacao necessito de saber como o arduino vai interpertar a informacao.

eu estou a enviar dois dados.

1º a velocidade
2º a direcao

basicamente o que envio e o seguinte [vel dir vel dir vel .......]
os dados estao separados sempre por um espaço, e sao valores numericos entre 0 e 255.

no arduino tenho que defenir o pin de entrada

int rxPin = 0;

depois no setup iniciar a comunicacao via serial
void setup(){
Serial.begin(9600);
pinMode(rxPin, INPUT);
}

agora tenho que lhe dizer que a velocidade vai para o pin 9
e a direcao para o pin 51.

como posso fazer isso?

cumpz angel3love

(se alguem precisar do codigo para fazer comunicaçao porta serie em c no netbeans e so pedir)

angel3love,

vc não precisa definir nada de pino RX. O "Serial" faz isso para você automaticamente. Você vai utilizar o Serial.read() para ler dados que vem pela porta serial.

Tem um exemplo em: Serial.read() - Arduino Reference

Tudo isto é muito simples e está amplamente disponível no playground e na documentação em geral no site do arduino.cc.

[]s

Wagner Sartori Junior

boas mais uma vez obrigado ja consegui ler os dados do programa em c++ e envia-los por porta serie para o pc

o codigo utilizado e este:

int dadosDeEntrada = 0;	
// dados de entrada
void setup() {
Serial.begin(19200);	

// abrir a porta serie       

pinMode(13, OUTPUT);      


}

void loop() {


       if (Serial.available() > 0)
 {          
	// le os dados de entrada:		
	dadosDeEntrada = Serial.read();                
	digitalWrite(13, 5); //liga o pin 13 luz verde		
	
	Serial.print("Dados recebidos: ");		
	Serial.println(char(dadosDeEntrada));	

 }
}

obtenho os seguintes dados:

como podem ver os dados estao sempre separados por um espaço, para poder na separacao ver o que pertence a velocidade e a direcao.( a imagem foi alterado por mim para mais facilmente verem como os dados sao enviados para o arduino. adicionei a imagem o txto velocidade = x e direcao = x)

o que eu pretendo saber e como separo esses dados.

o codigo devera ser algo deste genero

int dadosDeEntrada = 0;	// dados de entrada




void setup() {
Serial.begin(9600);	// abrir a porta serie
pinMode(13, OUTPUT);

pinMode(9,OUTPUT);// controlo do motor dado velocidade (0 - 255)
pinMode(51,OUTPUT);// controlo do servo
}

void loop() {

	
        if (Serial.available() > 0) {
	// le os dados de entrada:
	dadosDeEntrada = Serial.read();
        digitalWrite(13, 5);
		

	//tratamento de dados

	defenir os dados que sao para a velocidade e para o servo

	

	//envio dos dados pro motor

	analogWrite(9,variavel velocidade);
	digitalWrite(51,variavel servo);		

	
	// envia os dados de entrada para o pc	por opçao	
	Serial.print("Dados recebidos: ");
	Serial.println(char(dadosDeEntrada));	
	}
}

so nao sei e como defenir que uns dados sao da velocidade e outros sao do servo.

os dados sao sempre tranmitidos em sequencia, velocidade espaco direcao espaco velocidade espaco direcao ... etc.

eu gostaria de saber se existe alguma maneira de os separar.

os dados da direcao ira ser sempre so um numero, mas a velocidade podera ser entre 0 e 255.

obrigado mais uma vez pela ajuda

cumpz paulo lopes

Ao enviares dados para o computador, colocas uma letra no início para definir qual é qual... exemplo:

Serial.print("S"); //dados do servo
Serial.println(VariavelServo);

Serial.print("V");
Serial.println(VariavelVelocidade);

Porque é que separas em chars o valor da velocidade?

No sentido inverso fazes parecido. Ou seja:

Velocidade xxxV onde xxx é um valor numérico
Servo xxxS

#include <ctype.h>

char dados[4], tipo;
int i =0; 
int velocidade, servo; 

loop()  {

if (Serial.available() > 3)   {//queres ter a certeza que tens dados suficientes para executar um comando... 
    while(isdigit((dados[i++] = Serial.read()))); //enquanto for um digito, copiar para o array
    tipo = dados[--i]; 
    dados[i] = '\0';
    if (tipo == 'V')  {velocidade = atoi(dados);}
    if (tipo == 'S')  {servo = atoi(dados);} 
    }    
     

}

Não compilei nem testei o código, tenho a certeza que há-de haver bugs e não é completamente correcto, mas dá uma ideia de como implementar o que pretendes, certo?

ja consegui ler os dados, mas tem um problema.

o primeiro dado que o arduino recebe e o dado que esta sempre a ser processado e enviado. ele esta a guardar em memoria e sempre que envio um dado ele imprime sempre o mesmo.

o codigo que utilizei foi o seguinte:

#include <ctype.h>

int recebido;
char dados[4];
int i=0;

void setup() {
	Serial.begin(9600);	// opens serial port, sets data rate to 9600 bps
        pinMode(9, OUTPUT);     
}

void loop() {
 
      
      // send data only when you receive data:
      if (Serial.available()>4) {

      while(isdigit((dados[i++] = Serial.read())));
      
      recebido = atoi(dados);
     
      analogWrite(9,recebido);
      Serial.print("dir: ");
      Serial.println(recebido);
      delay(500);
     
    }
    
    else 
   {
     analogWrite (9, 0);
   }
   
}

na imagem a baixo podem ver o k digo.

na consola sempre que primo uma tecla, ele envia um dado, dado que esta por baixo da tecla em que carrego. mas como a 1ª tecla que carreguei foi o 4 e essa tecla corresponde a uma pwm de 100 ele envia sempre 100.

como e que faço para ele ir lendo os valores automaticamente? eu acho que o codigo esta correcto.

ele devia de ir sempre actualizando a string dados quando termina a iteraçao, mas ele esta a ficar sempre com o 1º valor enviado guardado, e depois ja nao le mais nenhum.

ja exprimentei trocar a funcao while por uma funcao for, ja tentei colocar um goto . label mas sempre assim.

em baixo esta tambem o codigo em c++ que estou a utilizar para comunicar.

se me puderem ajudar agradeço.

#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */

int vel;
int dir;
char envio[2] = { ' ' } ;
char* status = 0;
int count = 0;
int flags = 0;
int fd, j;
int enviodados; 

// abrir porta serie
int abrir_porta_serie(char *port) {
  struct termios options;
  fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd == -1) {
    printf("impossivel a comunicaçao \nligar a porta serial \n", port);
    }
    else {
    tcgetattr(fd, &options); // Get the current options for the port...
    cfsetispeed(&options, B9600 ); // Set the baud rates
    cfsetospeed(&options, B9600);
    options.c_cflag |= (CLOCAL | CREAD); // Enable the receiver and set local mode...
    tcsetattr(fd, TCSANOW, &options); // Set the new options for the port...
    }
  return(fd);
}


// envio de dados
int envio_de_dados(int fd) {
  int count;
 count = write(fd, envio , strlen(envio));
 return(count);
}

int main() {


    /* Abrir a porta de dados*/
    char port[50] = "/dev/ttyUSB0";
    fd = abrir_porta_serie(port);
    float opcao;
        int weight;
    for(;;){
    printf("intruduza uma tecla: " );
    scanf("%f", &opcao);

    if(opcao== 1){
        enviodados = 0;
    }
    else if (opcao == 2){
        enviodados = 25;
    }
    else if (opcao == 3){
        enviodados = 50;
    }
    else if (opcao == 4){
        enviodados = 100;
    }
    else if (opcao == 5){
        enviodados = 175;
    }
    else if (opcao == 6){
        enviodados = 225;
    }

    sprintf( envio, "%d ",  enviodados );
    printf("dados enviados %s \n ", envio);
       //sprintf( direcao, "%dS ", dir );


/*_________________________________________________________________________________________*/
   /*inicio dos dados a serem transmitidos*/
 
  envio_de_dados(fd);
  weight = envio_de_dados(fd);
      }
  close(fd);
  return 0;
}

obrigado

cumprimentos paulo lopes