collapse

* Posts Recentes

O que é isto ? por SerraCabo
[12 de Abril de 2024, 14:20]


Amplificador - Rockboard HA 1 In-Ear por almamater
[11 de Abril de 2024, 20:46]


Emulador NES em ESP32 por dropes
[10 de Abril de 2024, 15:30]


Meu novo robô por josecarlos
[29 de Março de 2024, 18:30]


Bateria - Portátil por almamater
[25 de Março de 2024, 22:14]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]


Laser Engraver - Alguém tem? por almamater
[16 de Dezembro de 2023, 14:23]

Autor Tópico: Protocolos Serial  (Lida 5969 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline msr

  • Mini Robot
  • *
  • Mensagens: 798
Protocolos Serial
« em: 19 de Dezembro de 2009, 23:59 »
Boas pessoal,

Estou aqui a pensar como hei de fazer um protocolo via porta Serial.
A minha ideia base seria enviar as seguintes intruções:
- ligar e desligar um LED
- posição exacta de um Servo

Estava a pensar num "protocolo" desde género:
"L ON" - led acende
"L OFF" - led apaga
"S 67" - posicao do servo = 67 graus

O problema aparece precisamente no envio da posição do servo. Para sacar aquele inteiro parece-me que são precisas umas quantas maroscas.

Encontrei um post que fala sobre isto e estava a pensar seguir qualquer coisa como a que o "todbot" refere no final do post:
http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/

Mas gostava de vos pergunta se conhecem alguma coisa que facilite aquilo que pretendo fazer?

Offline metRo_

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 3.753
Re: Protocolos Serial
« Responder #1 em: 20 de Dezembro de 2009, 00:22 »
O objectivo é comunicar o que com que? PC com micro? que micro?
Eu digo isto porque por exemplo se fores utilizar um Arduino não me parece nada complicado e eu ainda há  pouco fiz uma coisa parecida. Recebia uma trama do género no Arduino vinda do PC: :p132421& e foi relativamente simples de implementar.

Offline TigPT

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 5.372
    • Tiago Rodrigues
Re: Protocolos Serial
« Responder #2 em: 20 de Dezembro de 2009, 00:37 »
Não percebo... a comunicação vai ser orientada a caracteres é?

é que um send de um caracter tem um byte, 256 combinações.

Um servo se for com o analogWrite vai de 0 a 256, se for com uma servo lib vai de 0 a 180º pelo que qualquer das duas podem ser enviadas com um caracter apenas.

Offline msr

  • Mini Robot
  • *
  • Mensagens: 798
Re: Protocolos Serial
« Responder #3 em: 20 de Dezembro de 2009, 00:44 »
É mesmo  com o Arduino. PC->Arduino. Se pudesses partilhar o código era nice.

A ideia é fazer o "parse" de uma linha de comando.


TigPT, tambem já pensei nisso. Até podia aproveitar os 8bits do byte e fazer o protocolo a partir daí, certo? Mas, para "debug", estou a usar a consola serial do IDE do Arduino que converte tudo o que digitas para caracteres. Daí a comunicação orientada a caracteres.

Edit:
Para fazer uma comunicação orientada ao byte era um bocado manhoso acho. Primeiro preciso saber a que é que se refere a instrução, se ao LED se ao servo. No LED só existe a opção "acende" ou "apaga" no entanto para o Servo queria ter duas opções: move para a esquerda, para a direita ou para uma determinada posição em concreto. Portanto teria mesmo que fazer a comunicação "orientada ao bit" e neste momento, para isso, acho que me faltam alguns skills em C# ou C++ ;D

« Última modificação: 20 de Dezembro de 2009, 00:51 por msr »

Offline TigPT

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 5.372
    • Tiago Rodrigues
Re: Protocolos Serial
« Responder #4 em: 20 de Dezembro de 2009, 00:52 »
N tinhas feito código para isso em C#?

http://lusorobotica.com/index.php/topic,1755.msg16892.html#msg16892

um simples programa em C# fazia logo isso td.

Offline msr

  • Mini Robot
  • *
  • Mensagens: 798
Re: Protocolos Serial
« Responder #5 em: 20 de Dezembro de 2009, 00:57 »
Certo.
Mas o que esse programa faz é enviar uma string. Faz o mesmo que a consola do IDE do Arduino.
« Última modificação: 20 de Dezembro de 2009, 00:59 por msr »

Offline TigPT

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 5.372
    • Tiago Rodrigues
Re: Protocolos Serial
« Responder #6 em: 20 de Dezembro de 2009, 01:05 »
basta metere um campo para enviar posição de servo em k escreves a string, o programa faz Integer.ParseInt da string e se for menos k 256 (para proteger) manda o caracter com esse valor, ou seja send da variável.

Offline metRo_

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 3.753
Re: Protocolos Serial
« Responder #7 em: 20 de Dezembro de 2009, 01:37 »
Código: [Seleccione]
#include <stdlib.h>

#define DATAOUT 11//MOSI
#define DATAIN 12//MISO - nao e' usado
#define SPICLOCK  13//sck
#define SLAVESELECT 10//SS1
#define SLAVESELECT1 9//SS2

byte pot0_0=17,pot0_1=18,pot1_0=17,pot1_1=18;
byte clr;

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

int incomingByte = 0;
uint8_t start=0;
uint8_t pid=0;
uint8_t conta=0;
char message[8] = "";
char valorpid[6];
double p,i,d,t=0;
long Rp,Ri,Rd=0;

void setup(){
  //SPI
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  pinMode(SLAVESELECT1,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH);
  digitalWrite(SLAVESELECT1,HIGH);
  SPCR = (1<<SPE)|(1<<MSTR);
  clr=SPSR;
  clr=SPDR;
  delay(10);
  //Serial
  Serial.begin(115200);
  Serial.print(0x0C, BYTE); 


byte write_pot0(int address, int value){
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(address);
  spi_transfer(value);
  digitalWrite(SLAVESELECT,HIGH);
  delay(10);
}
byte write_pot1(int address, int value){
  digitalWrite(SLAVESELECT1,LOW);
  spi_transfer(address);
  spi_transfer(value);
  digitalWrite(SLAVESELECT1,HIGH);
  delay(10);
}
int res2pot(long res){
  double pot =((res-125)/(330));
  if(pot < 0){pot=0;};
  if(pot > 255){pot=255;}
  return pot;
}

void loop(){
  Serial.print(0x0C, BYTE);
  Serial.print("P:");
  Serial.println(p,DEC);
  Serial.print(" Rp:");
  Serial.println(Rp,DEC);
  Serial.print("I:");
  Serial.println(i,DEC);
  Serial.print(" Ri:");
  Serial.println(Ri,DEC);
  Serial.print("D:");
  Serial.println(d,DEC);
  Serial.print(" Rd:");
  Serial.println(Rd,DEC);
  delay(100);
  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    if(incomingByte == 0x3A & !start & !conta){
      message[conta]=incomingByte;
      conta++; 
      start=1;
    }else if(start & !pid & ((incomingByte == (0x70))|(incomingByte == (0x69))|(incomingByte == (0x64))) & (conta==1)){
      message[conta]=incomingByte;
      conta++;
      pid=1;
    }else if(start & pid){
      if(!(incomingByte == 38) & (incomingByte>=0x30) & (incomingByte<=0x39) & (conta<8)){
        message[conta]=incomingByte;
        conta++; 
      }else if(incomingByte == 0x26 & (conta==8)){
        message[conta]=incomingByte;
        conta++;
        for(int h=2;h<8;h++){
          valorpid[h-2]=message[h];
        }
        switch (message[1]) {
          case 0x70:
            p=(atof(valorpid))/1000;
            Rp=p*10000;
            write_pot0(pot0_0,res2pot(Rp));
          break;
          case 0x69:
            i=(atof(valorpid))/1000;
            t=1/(0.0000022*i);
            Ri=long(t);
            write_pot1(pot1_0,res2pot(Ri));
          break;
          case 0x64:
            d=(atof(valorpid))/1000;
            t=d/0.0000022;
            Rd=long(t);
            write_pot1(pot1_1,res2pot(Rd));
          break;
        }
        start=0;
        pid=0;
        conta=0;
      }else if(1){
        start=0;
        pid=0;
        conta=0;
      }
    }else if(1){
      start=0;
      pid=0;
      conta=0;
    }
  }
}

Aqui tens o código de todo o projecto que consistia em receber a trama e alterar os valores de uns potenciómetros digitais por SPI. Os potenciómetros digitais seriam para acertar as constantes de um controlador PID analógico.
A parte do código que te interessa é onde começa o   if (Serial.available() > 0) {. Eu no meu caso tratei de evitar receber coisas mal por isso faço algumas confirmações ao que recebo.

Offline msr

  • Mini Robot
  • *
  • Mensagens: 798
Re: Protocolos Serial
« Responder #8 em: 20 de Dezembro de 2009, 02:16 »
controlador PID analógico.

Que coisa bonita!

Bem acho que já pus isto a funcionar.
Estou a usar este código:
Código: [Seleccione]
 
  memset(cmdbuf,'\0',sizeof(cmdbuf));
  while(Serial.available()){
   delay(10);
   if(i != CODE_BUF)
     cmdbuf[i++] = Serial.read();
   else
     break;
  }

Mas ainda tenho que ver melhor. Aquele delay é para garantir que já lá chegaram os bytes todos. Coisa que ha pouco nao acontecia e daí estar a obter resultados inesperados.

Quando tiver tudo feito dou notícias.

Offline metRo_

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 3.753
Re: Protocolos Serial
« Responder #9 em: 20 de Dezembro de 2009, 12:33 »
Não percebi muito bem mas deve ser :p