• Welcome to LusoRobótica - Robótica em Português.
 

Arduino SerialPort

Started by almamater, 04 de August de 2010, 00:28

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

almamater

Hello!

Estou a programar uma pequena aplicação em VB para se conectar ao arduino e obter informação da eeprom, consigo que funcione mas tenho um problema..

Só consigo obter resposta do Arduino (mesmo com a ligação série efectuada / open) se fizer Reset manual nele, isto apenas acontece qdo antes ele foi utilizado tb por um serial monitor como o que vem no software de upload do Arduino...

A minha questão é, pq é que ao ligar o Serial Monitor da aplicação do Arduino ele faz Auto-Reset e através da minha aplicação ele não o faz, se fizesse ia ficar com este problema resolvido..

Estou a usar:

       clsSerial.BaudRate = 9600
        clsSerial.DataBits = 8
        clsSerial.Parity = 0
        clsSerial.StopBits = 1
        clsSerial.GetPorts()
        clsSerial.PortNumber = 6

Há alguma forma de "forçar" o reset ao arduino durante esta ligação?

Se ligar o Arduino e utilizar logo a minha aplicação funciona bem, mas se usar antes a porta série dele a seguir já me acontece o que referi  :-[

Marvin

Bom dia,

VB .net ou VB6?

Penso que esse problema pode ser devido a teres a ligação da porta de serie já aberta, terias de verificar se já existe uma ligação aberta e fecha-la manualmente (não sei se é possivel).

Acho que quando fazes um reset, fechas as ligações com a porta de serie actuais e abres as novas ligações, dai ele funcionar nessa altura.



Dronetech BlogThe Scientist and the Geek

almamater

Quote from: Marvin on 04 de August de 2010, 09:05
Bom dia,

VB .net ou VB6?

Penso que esse problema pode ser devido a teres a ligação da porta de serie já aberta, terias de verificar se já existe uma ligação aberta e fecha-la manualmente (não sei se é possivel).

Acho que quando fazes um reset, fechas as ligações com a porta de serie actuais e abres as novas ligações, dai ele funcionar nessa altura.

Vb .net 2008 e 2010, pois deve ser isso.. já tentei encontrar alguma opção para forçar o fecho das ligações da COM do arduino mas sem resultados.. grr foi um filme para perceber o envio/recepção para o arduino e consegui, agora reparei neste pormenor!



Marvin

Se perceberes de C# posso-te enviar o que uso para a comunicação. Sendo .net podes inclusive colocar como um projecto em paralelo na solução.
Dronetech BlogThe Scientist and the Geek

almamater

Quote from: Marvin on 04 de August de 2010, 11:11
Se perceberes de C# posso-te enviar o que uso para a comunicação. Sendo .net podes inclusive colocar como um projecto em paralelo na solução.

OK, gracias! pode ser que resolva o meu problema! podes enviar para aqui sff

msr

Dá uma vista de olhos aqui também: http://bravomofo.blogspot.com/2010/03/serial-talk.html

Comigo funcionou sem problemas até ao momento.

almamater

humm estranho, estava a testar agora a mesma coisa mas num Computador com Windows XP e funciona tudo bem  :o, estabelecendo ligação com a minha aplicação em VB o Arduino faz reset.. coisa que em Windows 7 não faz.. será dos drivers FTDI?

almamater

Bom.. outra dúvida.. a questão anterior tem de se resolver com um Reset ao Arduino sempre que acontece.

Agora estou com outra situação, como é que posso enviar o valor por exemplo  "155" e o Arduino não ler linha a linha:

1
5
5

mas sim um valor inteiro 155 ?  ::)

A função que estou a usar em VB para o envio é:

Dim WithEvents serialPort As New IO.Ports.SerialPort

  Public Function Send(ByVal txtMsg As String) As Boolean
        Try
            txtMsg += vbCrLf
            serialPort.Write(txtMsg)
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function
-----------------------------------

Private WithEvents clsSerial As New Serial

'ENVIO:

clsSerial.Send("155")




senso

Tens que usar a função atoi, que converte ASCII ou seja strings em inteiros.
Para usares essa função tens de passar a string a usar, não sei como lhe chamas no teu programa, portanto imaginemos que se chama String_recebida, para converteres para um int fazes o seguinte no teu programa:
meu_inteiro =  atoi(String_recebida);
Avr fanboy

almamater

#9
Bom.. tentei de diversas formas implementar isso no programa do arduino mas sem sucesso.. algo me está a escapar  :-\


Peguei no exemplo do site do arduino para tentar perceber:

int incomingByte = 0; // for incoming serial data

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

void loop() {

// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();

// say what you got:
Serial.print("I received: ");
Serial.println(incomingByte, DEC);
               }
             }


Enviado para o Arduino o valor "255" ele recebe isto:

I received: 50
I received: 53
I received: 53


Ok, apresenta segundo a tabela Aschii, colocando a função atoi "int meu_inteiro =  atoi(incomingByte);" tenho um erro:

error: invalid conversion from 'int' to 'const char*

Já pesquisei e já testei definir com char* incomingByte [0];

mas nunca dá!


é que eu precisava mesmo de obter o valor certo definido, pq quero guardar na eeprom várias varáveis e cada uma delas vai ter um valor de 0 a 255 recebido pela porta série, como o Arduino recebe linha a linha tenho possivelmente de fazer um ciclo para juntar as leituras todas para me fazer 1 número: 255 em vez de 3 números: 2, 5, 5




Cynary

Não estás a perceber ... o problema não está no arduino :P
Tens de converter de string para inteiro ... ou melhor provavelmente não precisas de fazer isso, se, como argumento da função send, em vez de uma string, aceitares um inteiro, e o enviares.
Assim, quando fazes:
clsSerial.Send(155)
(nota a falta de aspas), envias o INTEIRO (que será o carácter de acordo com a tabela ASCII :P).
Ou então, dentro da função, usas o atoi.
Usando síntaxe de C (não gosto do de VB xD e não estou habituado), a tua função seria uma coisa assim:
Code (c) Select
  int Send(int intMsg) {
  return serialPort.Write((char)intMsg); } // Considerando que retorna falso quando falha e vice-versa.


No entanto, isto tem a desvantagem de aceitar apenas números entre 0 e 255, já que o arduino recebe byte a byte ... a outra opção, é alterar o código do arduino de forma a que ele receba cada dígito do número, e os transforme em inteiros (postei há pouco tempo uma função que faz isso! xD).
Vê este tópico: http://lusorobotica.com/index.php?topic=2633.0
Apenas tens de enviar um carácter para o arduino saber que tem de parar de ler o número :P, usando a função getnumber()

almamater

Obrigado pela explicação.

Neste caso enviado o 255 dá o seguinte:



Está certo assim não está?

TigPT

O metRo_ uma vez andou a pedir-me ajuda num código para exactamente isso.

O cliente que está a receber o serial tem que processar a informação, já que a transmissão serial é sempre byte a byte

Das duas uma. Ou fazes um software para quem está a enviar os dados, que converte o número que colocas na letra ascii com esse valor, e podes mandar valores de 0 a 256 (equivalente a 1 byte de comunicação), ou quem recebe os dados, sabe que vai receber vários números ascii e vai multiplicado por 10 para shiftar de forma decimal até obter um caracter terminador, ou x bytes pré configurados.

almamater

Ok, podem chamar-me burro  :-X

Tenho 3 processos que podem ser executados de acordo com o que é recebido via serial.read, tenho tudo a funcionar menos a parte de receber o valor inteiro e por inteiro

Em VB tenho as seguintes funções:


                                Envia Strings:
  Public Function Send(ByVal txtMsg As String) As Boolean
        Try

          ' // txtMsg += vbCrLf
            serialPort.Write(txtMsg)
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

                             Para enviar o valor Inteiro (já testei as Byte e as Integer):

    Public Function Send2(ByVal txtMsg2 As Byte) As Boolean
        Try
            serialPort.Write(txtMsg2)
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function



No lado do Arduino tenho:

   
byte com;            //lê string recebido
byte Posicao;       //saber a posição na eeprom
byte ValorExtra;   //para gravar valor na eeprom

int ValorEeprom;  //para ler valor de eeprom


void loop()
{

  if (Serial.available() > 0)
  {

com = Serial.read();
  delay(50);   

  if (com== 103){     //se receber a letra "g"
  Posicao= Serial.read();     
  delay(50);   
  ValorExtra= Serial.read();
   delay(50);   
     }


if (com== 103){                       // letra "g"     
   
   if (Posicao== 97){                  // letra "a"
   EEPROM.write(0,ValorExtra);
      Serial.print("VALOR 1 GUARDADO: ");
   Serial.println(EEPROM.read(0));
   delay(100);
 
   }
     if (Posicao== 98) { // letra "b"
   EEPROM.write(1,ValorExtra);
      Serial.print("VALOR 2 GUARDADO: ");
   Serial.println(EEPROM.read(1));
   delay(100);
   }

etc.



Ou seja, o "g" representa a condição para gravar na eeprom e dentro desta tenho vários IFs que identificam a posição pretendida..

No meu programa em VB estou a fazer assim:


clsSerial.Send("ga")                  '//Usa a função SEND para enviar as letras "g" e "a"           [ciclo gravar e na posição/IF  'a']
clsSerial.Send2(145)      '//Usa a função SEND2 para enviar o valor a gravar na eeprom que pode ser de 0-255
   

O arduino de facto detecta o "g", detecta o "a" mas quando vai a gravar na eeprom grava apenas o número correspondente em ascii do 1º digito que recebeu, neste caso do 1 e grava o valor 49 em vez do 145

-----------------

Estive o dia todo a inventar e alterar coisas e juro que já tinha conseguido receber o valor por inteiro de uma só vez.. mas sinceramente já dei tanta volta que me baralhei e tou assim neste momento.


senso

Mas a função atoi faz isso e devia funcionar devidamente..
Lê sobre ela.
Avr fanboy