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

Módulo gsm

Started by dio123, 14 de November de 2015, 11:52

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

jm_araujo

#60
O que dizes aqui:
Quote from: dio123 on 13 de November de 2016, 22:26
ISR (USART_RX_vect)  diz-me  cmd_ok= TRUE; quer dizer que ja recebi tudo o que tinha a receber e que posso processar os dados.
E o que tens aqui:
Quote

ISR (USART_RX_vect)
{
data_in[posicao] = UDR0;
if (data_in[posicao] != '\0' ){
posicao++;
}
if (data_in[posicao +1] == '\0'){
cmd_ok= TRUE;
}
}


São muito diferentes entre si.

Se o data_in for inicializado a 00s no reset, mal receba um carater liga logo o cmd_ok.
E não tens qualquer controlo de limites do "posição", é um buffer overflow à espera de acontecer.

( e o "led_on" apesar de em essencia não estar errado, é código muito feio. Pelo menos tira o ";" do define e mete-o na utilização, para que no código seja mais legível)

dio123

E como posso saber que o ISR (USART_RX_vect)  terminou a recepção de dados? Porque o módulo nao tem uma terminação fixa, havia de ser o  \r\n , mas este aparece entre 2 a 4 vezes dependendo do comando.

Quanto ao buffer a ideia seria se ISR (USART_RX_vect)  acabou de receber tudo ou buffer size ==110  mandar a posicao = 0, seria algo assim.

beirao

Quote from: dio123 on 17 de November de 2016, 19:15
E como posso saber que o ISR (USART_RX_vect)  terminou a recepção de dados? Porque o módulo nao tem uma terminação fixa, havia de ser o  \r\n , mas este aparece entre 2 a 4 vezes dependendo do comando.

Quanto ao buffer a ideia seria se ISR (USART_RX_vect)  acabou de receber tudo ou buffer size ==110  mandar a posicao = 0, seria algo assim.

Vou responder tendo em conta que só li o tópico na diagonal.
Se a terminação pode variar com esses comandos repetidos: uma possível solução seria quando recebe o \n verifica o tamanho do buffer, se o buffer tiver dados recebidos termina a recepção e processa os dados; se o buffer estiver vazio (ou neste caso só com \r) termina a recepção mas não processa os dados. Assim de repente parece-me a melhor solução.
"O único lugar onde o sucesso vem antes do trabalho, é no dicionário" - Albert Einstein

dio123

Encontrei um PDF, da própria Atmel com um exemplo umas funções "extras" para a comunicação uart entre elas serial.avaible que resolve o meu grande problema que tinha até agora.

Mas a minha dúvida é nos fuses do avr, que coloquei o standard.  lfuse:w:0xFF:m -U hfuse:w:0xDE:m -U efuse:w:0x05  e um atmega328p tqfp.
A minha dúvida é que atmega tem um arranque estranho.
só tenho no código dentro main ligar led 1. e no while blink led2 . Ao ligar atmega o led 1 pisca 3 vezes. E depois comeca o blink led 2. Não devia só ligar e ficar assim, e que parece que só arranca a  3 vez.  E só reparei porque noutro código a mensagem no lcd pisca 3 vezes.

senso

É o bootloader do Arduino que pisca o led..
Avr fanboy

dio123

Mas eu não instalei o bootloader do Arduino, ou que me lembre. Eu Programo pelo bitbang e faço sempre erease burn verificy. E não uso software Arduino.

dio123

É o ftdi que me provoca os 3 resets ao atmega.

Venho aqui deixar o link que me ajudou a resolver o meu problema uart,
http://ebook.pldworld.com/_Semiconductors/Atmel/Databook%20CDROM/Atmel/acrobat/doc1451.pdf

Apenas acrescentei isto

int uart_available(void)
{
return (UART_RX_BUFFER_MASK + posicao - UART_RxTail) % UART_RX_BUFFER_MASK;
}

dio123

Bom dia,
Criei aqui um problema estranho, criei um if (currentMillis - previousMillis >= 8000) {} para que de 8 em 8 segundos o gajo vai me ler as coordenadas e ver se ha novas sms.

O que acontece é que se tiver memcpy (tlf -23 , data1 ,110); o  gajo passa-se e fica em loop no subprograma readsms(); e nao percebo porque pois no outro if que tinha if ((strcmp(data1, "+CMTI: \"SM\",1\r") == 0)) funcionava bem.
Nao sei se terá haver com o millis();

while (1){
currentMillis = millis();
if (estado == ON){
if (currentMillis - previousMillis >= 8000) {
readsms(); // le mensagem
limpa(); //limpa variaveis
blink(); // pisca os 2 leds
previousMillis = currentMillis;
}
}
}
}

//******************************************
//  sub pragramas completares
//*********************************************
void readsms(void){
lcd_msg("lendo sms");
USART_putstring("AT+CMGR=1\r\n");
_delay_ms(100);
memcpy (tlf -23 , data1 ,110);

}
}

jm_araujo

Os problemas que tenho visto que tens é por não conheceres muito bem a linguagem. Tens de aprofundar primeiro os teus conhecimentos de C e de apontadores. Lê o K&R de fio a pavio (é pequeno), e de certeza que muitos dos teus problemas se resolvem sozinhos ;)


Para o teu problema especifico, explica-me por palavras tuas o que achas que esta função faz:
Quote from: dio123 on 24 de December de 2016, 10:48
memcpy (tlf -23 , data1 ,110);

dio123

Ora bem esta funcao memcpy (tlf -23 , data1 ,110);  copia as 110 posicoes  da variavel data1 para tlf anulando  as primeiras 23 posições.
Agora o 110, deveria ser 9 (que e os 9 numeros do tlf), mas a variavel tlf, fica em branco.

jm_araujo

Quote from: dio123 on 24 de December de 2016, 17:08
Ora bem esta funcao memcpy (tlf -23 , data1 ,110);  copia as 110 posicoes  da variavel data1 para tlf anulando  as primeiras 23 posições.
Agora o 110, deveria ser 9 (que e os 9 numeros do tlf), mas a variavel tlf, fica em branco.
Ora aí está.
Isso é o qu e queres, o que faz é copiar 110 bytes do data1 para a posição de memória 23 bytes antes de começar o tlf, que só tem reservados 10. Vais escrever os 23 bytes antes do tlf, e os 77 que estão depois (110=23+10+77). Ao escrever em memória  assim à toa é para encravar qq programa.