Página 1 de 1

Descarga vetor de dados via serial

MensagemEnviado: 22 Dez 2008 21:25
por dramos
Olá!

Uma vez que a minha experiência prévia era de programação em assembler e já não pogramava em PICs há, pelo menos 3 anos, estou com seguinte dúvida em relação à um algoritmo que estou desenvolvendo em C (usando PCWH).

Estou implementando um protótipo de aquisição de dados para uma máquina de balanceamento dinâmico. Nesta máquina, há uma coroa dentada, na qual faço uma contagem dos pulsos, que representam o ângulo de giro. Estou usando interrupções de CCP1 e CCP2 para isso. O meu objetivo é: para cada pulso, fazer uma leitura de tensão em um sensor indutivo. Assim, tenho a variação da amplitude de tensão do sensor em função da variação do ângulo da coroa (cada pulso equivale a 2 graus).

A idéia da lógica a ser implementada é a seguinte: armazenar a leitura de 360 valores - de tensão e contagem de pulso (um para cada pulso/grau) - em vetores unidimensionais de 360 elementos. Após realizada a aquisição, aperto um botão para fazer a descarga dos dados (360 valores armazenados em uma espécie de buffer fifo de dados) para o computador, via porta serial.

Meu problema com este programa tem sido o seguinte: fiz com que cada pulso fosse representado por um contador, incrementado (de 0 à 360, e resetado em 360) durante a interrupção de CCP1. Durante a execução normal do programa, realizo as leituras do A/D. Assim, uso o contador de pulsos como indexador do meu vetor de leituras do A/D. Infelizmente, porém, não consigo armazenar nestes vetores as leituras corretas do para descarregar para o pc os dados.

Minha dúvida é a seguinte: eu posso usar o contador de pulsos para indexar (ponteiro) um vetor de dados? Esse procedimento está correto? Basicamente, o que estou fazendo em meu programa é o seguinte:

while(true)

{

Se contador_atual != contador_anterior //verifica se o ângulo de giro variou.

{

tensao[contador] = leitura_ad;

angulo[contador] = contador + 2;

}

Se (botão = pressionado)
desabilita_interrupções
{
para (i = 0, i <= 360, i++)
printf(angulo[contador],tensao[contador]) //descarrega todos os valores do vetor na porta serial
delay_ms(50) //tempo para enviar via rs232
}
}

As minhas rotinas de tratamento de interrupções, envio do buffer de dados e demais configurações do microcontrolador estão corretas. Verifiquei cada uma separadamente. A contagem dos pulsos é feita de forma adequada dentro da interrupção. Testei estas rotinas até uma frequencia de, aproximadamente, 8kHz -usando um gerador de funções - e não observei problemas decorrentes de uma má contagem. Isso minimiza a possibilidade de o pic estar se "perdendo". O problema encontra-se no fato de as leituras de ângulo e tensão não serem corretamente armazenadas no "buffer". Assim, os dados não são descarregados como deveriam no computador.

Estou usando um 18f452, xtal 10MHz, PLL4x, ad 10bits, BR 57600 bps e uma estação de desenvolvimento CUSCOPIC.

Agradeço sugestões. Caso necessário, envio o código-fonte.

Obrigado pela atenção de todos.

Re: Descarga vetor de dados via serial

MensagemEnviado: 23 Dez 2008 06:34
por andre_luis
dramos escreveu:...cada pulso equivale a 2 graus...Se contador_atual != contador_anterior...


Alumas observações :

- O fato de voce estar usando o printf somente após realizadas as leituras está correto, uma vez que o printf realiza um loop bloqueando demais tarefas.
- Dá uma olhada na taxa de amostragem para saber se está condizente com a velocidade angular.
- Conferir se o disco tem realmente 360 graus.
- Esse método de contagem incremental, ao invéz de absoluto tem essa desvantagem de voce não saber exatamente em que posição está. As opções seriam usar um encoder absoluto, ou incluir um furo no disco para voce se certificar que realmente passaram-se 360 graus.
- Testar com metade do angulo ( 180o ). Como 360 está acima da magnitude de um char (=256), o meu palpite seria pela ocorrencia de estouro do ponteiro da variável por parte do compilador.

+++

olá

MensagemEnviado: 23 Dez 2008 07:45
por dramos
Em resposta à sua postagem:

1 - Na realidade, o meu disco tem 180 dentes (cada pulso = 2 graus) - 360 dentes poderiam, na verdade, causar problemas na leitura, mesmo usando um clock mais elevado;
2 - Para marcar a correta posição da coroa principal, incluímos um segundo disco, com apenas uma saliência - com a função de "reset mecânico", alinhado com o "pulso zero" da coroa principal - por isso uso CCP1 e CCP2 - a segunda interrupção é usada para "limpar" o contador principal e identificar o posicionamento físico do eixo da nossa máquina;
3 - Os vetores de armazenamento, então, têm 360 pontos que permitem armazenar os resultados para dois giros da coroa principal - preenchidos estes vetores, só preciso descarregar, quando desejado na porta serial;
4 - Não entendi ao certo o que você quis dizer sobre estourar o ponteiro - estou apenas declarando meus vetores como: unsigned int16 angulo[360],amplitude[360]; Posso estar tendo problemas com esta declaração?

Obrigado por sua atenção.

Diego

Re: olá

MensagemEnviado: 24 Dez 2008 06:51
por andre_luis
dramos escreveu:...Não entendi ao certo o que você quis dizer sobre estourar o ponteiro - estou apenas declarando meus vetores como: unsigned int16 angulo[360],amplitude[360]; Posso estar tendo problemas com esta declaração?...Diego


Olha, não tenho certeza disso, mas acho que o PIC, por ser um uC com barramento de dados de 8 bits, talvez tenha restrição quanto a usar um modelo de memoria extendido.

Um palpite : Confere se no header do programa a diretiva #device *=16 está presente.

+++