Go Down

Topic: Arduino + VB + Comunicação SerialPort + Dúvidas (Read 4781 times) previous topic - next topic

ruiacm10

Bom dia ;) Estou a fazer um projeto em VB para ligar Leds de uma casa. Esta casa tem várias divisões.
No programa quando eu quero ligar o led quero enviar para a placa o valor da intensidade desse led e a divisão.
Supondo que queria ligar o led da divisao A na intensidade maxima enviaria o valor: 255A  
Code: [Select]
SerialPort1.Write("255A")
Supondo que queria desligar o led da divisao B enviaria o valor:
Code: [Select]
SerialPort1.Write("000B")

Tenho este código para a placa Arduino Uno mas não dá e está a dar erro, alguém pode ajudar :

Code: [Select]

int PINOH = 13;
int PINOQ=12;
void setup(){
 pinMode(PINOH,OUTPUT);
 pinMode(PINOQ,OUTPUT);
 Serial.begin(9600);
}
void loop (){
 char pwm[4];
 unsigned char pwm_int = 0;

 for (int i = 0; i < 3; i++){
   pwm[i] = Serial.read();
}
 pwm[3] = '\0';
 pwm_int = atoi(pwm);
 switch(Serial.read()) {
   case 'H': {
         analogWrite(PINOH, pwm);
         break;
}
   case 'Q': {
         analogWrite(PINOQ, pwm);
         break; }
}
}


Erro:
sketch_mar26a.ino: In function 'void loop()':
sketch_mar26a:21: error: invalid conversion from 'char*' to 'uint8_t'
sketch_mar26a:21: error: initializing argument 2 of 'void digitalWrite(uint8_t, uint8_t)'
sketch_mar26a:25: error: invalid conversion from 'char*' to 'uint8_t'
sketch_mar26a:25: error: initializing argument 2 of 'void digitalWrite(uint8_t, uint8_t)'

bubulindo

Existe um motivo pelo qual o atoi é usado...

Code: [Select]
int PINOH = 13;
int PINOQ=12;
void setup(){
  pinMode(PINOH,OUTPUT);
  pinMode(PINOQ,OUTPUT);
  Serial.begin(9600);
}
void loop (){
  char pwm[4];
  unsigned char pwm_int = 0;

  for (int i = 0; i < 3; i++){
    pwm[i] = Serial.read();
}
  pwm[3] = '\0';
  pwm_int = atoi(pwm);
  switch(Serial.read()) {
    case 'H': {
          analogWrite(PINOH, pwm_int);
          break;
}
    case 'Q': {
          analogWrite(PINOQ, pwm_int);
          break; }
}
}
This... is a hobby.

HugoPT

#2
Mar 27, 2013, 10:23 am Last Edit: Mar 27, 2013, 10:26 am by HugoPT Reason: 1
Tens coisas mal :)
Aqui vao elas:
Quote
char pwm[4];
 unsigned char pwm_int = 0;

Porque estas a declarar estas variaveis na loop ?? Deviam estar logo no inicio.
Quote
for (int i = 0; i < 3; i++){
   pwm = Serial.read();

Como sabes que tens dados para ler e mesmo que os tenhas no buffer nao podes usar um ciclo for, a razao é que a comunicaçao serial é leeeennnttttaaa
e esse for e muito mais rapido.O final disso e que o for ira ser corrido e os dados da serial inda nem chegaram ...
Tens de colocar uma funçao antes para detectares que tens algo no buffer à espera de para ser lido.
Algo assim
if(Serial.available() > 3)doSomething();//Por exemplo ler o buffer
Esta forma apesar de funcionar nao é o correcto, deves colocar um caracter que marca o inicio da comunicao e outro que marque o valor PWM
Code: [Select]
 switch(Serial.read()) {
   case 'H': {
         analogWrite(PINOH, pwm_int);
         break;
}
   case 'Q': {
         analogWrite(PINOQ, pwm_int);
         break; }


Forma errada ...
SerialPort1.Write("255A")
Estas a escrever 5 bytes na porta.Lembra-te que estas a passar um string e que tambem tem caracter terminador.
Logo como queres que isso funcione?Como esperas que esse switch avalie o valor?

Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B

bubulindo

#3
Mar 27, 2013, 10:47 am Last Edit: Mar 27, 2013, 10:48 am by bubulindo Reason: 1

Tens coisas mal :)
Aqui vao elas:
Quote
char pwm[4];
 unsigned char pwm_int = 0;

Porque estas a declarar estas variaveis na loop ?? Deviam estar logo no inicio.


Porque motivo é que estas variáveis necessitam de ser globais? (Se houver a detecção de caracteres disponíveis para ler...)
O SerialPort da Microsoft envia um terminador na comunicação série?

Quote

int PINOH = 13;
int PINOQ=12;
void setup(){
 pinMode(PINOH,OUTPUT);
 pinMode(PINOQ,OUTPUT);
 Serial.begin(19200);
 Serial.println("start");
}
void loop (){
 char pwm[4];
 unsigned char pwm_int = 0;

if (Serial.available() >= 4) {
//ler PWM
 for (int i = 0; i < 3; i++){
   pwm = Serial.read();
}
 pwm[3] = '\0';
 pwm_int = atoi(pwm);
 switch(Serial.read()) {
   case 'H': {
         analogWrite(PINOH, pwm_int);
         Serial.println(pwm_int);
         break;
}
   case 'Q': {
         analogWrite(PINOQ, pwm_int);
         Serial.println(pwm_int);
         break; }
}
}
}



Isto funciona para mim... apesar de haver os problemas que o Hugo indicou.

Já agora... o pino 13 e 12 do Uno não são pinos de PWM.

Para experimentares este código, abre o Serial Port... escolhe No Line Ending, escreve 255H ou 005Q e carrega em send. O valor que escreveste é-te reenviado de volta.

This... is a hobby.

ruiacm10

#4
Mar 27, 2013, 10:48 am Last Edit: Mar 27, 2013, 11:27 am by ruiacm10 Reason: 1

Tens coisas mal :)
Aqui vao elas:
...


Eu nunca dei C por isso estou um bocado às cegas...
Como é que fica o código se eu quiser enviar aqueles valores ?

ruiacm10


Isto funciona para mim... apesar de haver os problemas que o Hugo indicou.

Já agora... o pino 13 e 12 do Uno não são pinos de PWM.

Para experimentares este código, abre o Serial Port... escolhe No Line Ending, escreve 255H ou 005Q e carrega em send. O valor que escreveste é-te reenviado de volta.


Não faz nada na mesma bubulindo :s

bubulindo

Estranhamente isso funciona no meu...

Recebes de volta o valor que enviaste? Ou estás à espera que o LED acenda?
This... is a hobby.

ruiacm10


Estranhamente isso funciona no meu...

Recebes de volta o valor que enviaste? Ou estás à espera que o LED acenda?

Envio um valor e mostra-me um caracter estranho ns consola do vb

bubulindo


Para experimentares este código, abre o Serial Port... escolhe No Line Ending, escreve 255H ou 005Q e carrega em send. O valor que escreveste é-te reenviado de volta.


Eu escrevi isto... estás a fazer isto? Eu referia-me ao Serial Port do Arduino.

Também escrevi isto:

Já agora... o pino 13 e 12 do Uno não são pinos de PWM.


Que placa estás a usar?

Repara também que eu configurei o código para usar uma baud de 19200... a tua aplicação está configurada para que baud rate?
This... is a hobby.

ruiacm10



Para experimentares este código, abre o Serial Port... escolhe No Line Ending, escreve 255H ou 005Q e carrega em send. O valor que escreveste é-te reenviado de volta.


Eu escrevi isto... estás a fazer isto? Eu referia-me ao Serial Port do Arduino.

Também escrevi isto:

Já agora... o pino 13 e 12 do Uno não são pinos de PWM.


Que placa estás a usar?

Repara também que eu configurei o código para usar uma baud de 19200... a tua aplicação está configurada para que baud rate?


Bem visto, tinha que mudar o baud -.-
Agora ja faz o que eu quero no Serial Port do Arduino, nao consigo é no VB, estou a tentar assim :
Code: [Select]

Dim i As Integer = TrackBar1.Value
        Dim inta As String
        SerialPort1.Open()
        If i < 10 Then
            inta = "00" & i
        ElseIf i < 100 And i >= 10 Then
            inta = "0" & i
        Else
            inta = i
        End If

        SerialPort1.Write(inta + "H")
        System.Threading.Thread.Sleep(5)
        SerialPort1.Close()

bubulindo

Não será mais simples fazer algo assim:

Code: [Select]

Dim i As Integer = TrackBar1.Value
SerialPort1.Write(i.toString("D3") + "H")


Nota que sempre que abres e fechas o Serial Port no Windows, o Arduino faz um reset... logo este comando nunca é "ouvido".

O ideal é abrir o Serial Port no início da aplicação e quando fechares a aplicação, fechares o Serial Port. Claro que mais tarde, terás de desactivar o auto-reset para fazer algo disto.

This... is a hobby.

ruiacm10


Não será mais simples fazer algo assim:

Code: [Select]

Dim i As Integer = TrackBar1.Value
SerialPort1.Write(i.toString("D3") + "H")


Nota que sempre que abres e fechas o Serial Port no Windows, o Arduino faz um reset... logo este comando nunca é "ouvido".

O ideal é abrir o Serial Port no início da aplicação e quando fechares a aplicação, fechares o Serial Port. Claro que mais tarde, terás de desactivar o auto-reset para fazer algo disto.




Deu assim
Code: [Select]


Dim i As String = Format(TrackBar1.Value, "000") + "A"
SerialPort1.Write(i)
System.Threading.Thread.Sleep(5)



O pior agora é que eu queria ter 8 divisões distintas e a placa que tenho só tem 6 pinos PWM -.-

bubulindo

This... is a hobby.

ruiacm10


ups...


Pois, ahah.
E se for utilizar o shield Ethernet ainda fico com menos ou nao?

bubulindo

Depende do shield... Mas é provável...
Qual era o modelo de shield que estavas a pensar usar? Tens a certeza que te queres meter nisso com o que sabes de C?

This... is a hobby.

Go Up