LusoRobótica - Robótica em Português
Sistemas específicos => Arduino / AVR => Tópico iniciado por: dio123 em 14 de Novembro de 2015, 11:52
-
Boa tarde,
Comprei um modulo GSM/GPS SIM808 no eBay e no entanto estou com dificuldades em comunicar.
Peguei no arduino 2009, tirei o atmega liguei tx com rx e rx com tx, partilhei a alimentação e quando vou terminal enviar o comando AT não recebo resposta. Chekei as ligações e estão OK.
Depois mais uma pesquisa meti atmega328p com exemplo virtualwire na porta 10 ee 11, tx com rx e rx com tx e assim consigo comunicar e fazer chamadas.
Não percebi porque que ligado ao arduino sem chip comrsmo bauldrate não consigo comunicar.
Boa noite, mandei vir do eBay um modulo, ainda sem destino.
Ora hoje chegou a casa e fui brincar peguei no arduino
-
No primeiro caso fizeste um loopback (ligar o rx ao tx no arduino) para confirmar que fazia eco e estava a funcionar a comunicação?
-
Sim, liguei tx ao rx no arduino para testar a comunicacao e para confirmar se a porta com estava certa.
-
Ora ja consegui falar com o modulo. ler lista dos contactos imei e afins. Este site ajuda muito com os comandos.
http://m2msupport.net/m2msupport/module-tester/ (http://m2msupport.net/m2msupport/module-tester/)
Ora uma vez que ainda nao vieram as antenas ebay, e ainda vao demorar, exprimentei uma antena wireless de um portatil que tinha aqui perdido com o mesmo contector do modulo, mas mesmo assim o at+cops nao detecta rede nenhuma, será nornal? até ja meti junto com o telemovel mas mesmo assim nao apanha nada.
-
problema descoberto, hoje chegou antena gsm (identico as antenas routers wireless) , mais o adaptador.
Montei e at+cops nao detectava nenhuma rede, achei que a coisa estava muito estranha, entao vi na net que o a ficha soldada na pcb onde liga antena a solda nao chegava para fazer contacto. Peguei no ferro deitei um pingo de solda no 4 lados do adaptador e voila.
Já me aparece a rede tmn e optimum mas o sinal continua muito fraco fui para o quintal e fraco esta.
O que poderá ser agora tenho rede maxima com o telemovel e o modulo nao tem rede nenhuma.
AT+CSQ
+CSQ: 5,0
OK
Signal level is -103 dbm. Signal condition is marginal.The signal strength range is -53 dbm (Excellent) to -109 dbm (Marginal).
-
Real problema esta descoberto, graças a grande qualidade de produção dos chineses não é que os gajos soldaram os conectores ipex ao contrario, o do gsm e gps estão ao contrario, só Bluetooth e que esta certo.
Entanto tentei tirar ipex com jeitinho mas acabei por estragar arranquei ipex e soldei 2 fios directamente para a antena. e agora tenho rede. csq 13.
-
Pelo teu ultimo comentario, vejo que estas a trabalhar com GPS e GSM, são as duas comunicações integradas no mesmo modulo?
-
Sao 3 comunicações gsm, GPS, bluetooth, todos integrados num do IC SIM808.
BT não testei ainda
GSM já testei fazer chamadas funciona bem
GPS não testei, tentei com antena GSM mas não apanhou nada.
-
Alguma razão especial para escolheres esse modulo?
Eu ando a ver estes e por metade do preço (sem bluetooth ja faço a festa, ou então não ahahah)
uBox Neo 6M - 15,00 € - http://www.ebay.com/itm/GPS-U-blox-NEO-6M-Module-Aircraft-Flight-Controller-For-Arduino-MWC-IMU-APM2-/161103685445 (http://www.ebay.com/itm/GPS-U-blox-NEO-6M-Module-Aircraft-Flight-Controller-For-Arduino-MWC-IMU-APM2-/161103685445)
SimCom - SIM800L - 10,00 €http://www.ebay.com/itm/SIM800L-GSM-Module-SIM-Board-Quadband-850-900-1800-1900-Antenna-F-MCU-Arduino-/191695150915
-
Antes de comprar este era para comprar esses que referistes, mas e a primeira vez.
A razão é mesmo por ser 2 em 1, e de ser mais pratico ter só um modulo na breadboard para comunicar em vez de 2. Apesar de não ter ainda projecto para ele.
Agora estou a começar a tentar meter o atmega a falar com o modulo, só que no entanto o uart por software não esta fácil.
Ainda não arranjei exemplos de jeito,que desse para estudar.
-
Emprestaram me um que tem o SIM808 é mais um GPS integrado, vou testar o bicho :)
Já agora, quanto tempo leva o teu módulo a enviar uma sms?
Em termos de rede é fiável?
-
Boa tarde a todos.
Acham que este módulo também serve para comunicação com o arduino?
Cumps.
http://www.aliexpress.com/item/Smallest-SIM800L-GPRS-GSM-Module-MicroSIM-Card-Core-BOard-Quad-band-TTL-Serial-Port/32284560394.html?spm=2114.01020208.3.1.vXsbMo&ws_ab_test=searchweb201556_7_79_78_77_80,searchweb201644_0,searchweb201560_6 (http://www.aliexpress.com/item/Smallest-SIM800L-GPRS-GSM-Module-MicroSIM-Card-Core-BOard-Quad-band-TTL-Serial-Port/32284560394.html?spm=2114.01020208.3.1.vXsbMo&ws_ab_test=searchweb201556_7_79_78_77_80,searchweb201644_0,searchweb201560_6)
-
Em temos de rede acho que sim, pelos menos consigo ligar-me a rede meo sem antena ligada. O GPS +/- 20segundos e tenho coordenadas +/- diferença 5metros da casa.
RALAX: sim consegues usar no arduino sem problemas.
Agora isto aqui está mau,lcd e uart ok, mas agora nao consigo imprimir buffer uart rx para o lcd, se for uma letra consegui agora frase OK nao estou a conseguir, já ando aqui a 1 dia e nao consegui. Alguma dica.
extern void lcd_cmd(char byte, unsigned char rs);
extern void lcd_msg(char *str);
main.c
volatile int i=0;
volatile uint8_t buffer[20];
int main(void)
{
sei();
DDRD = 0b11100000;
USART_init();
lcd_begin();
lcd_msg("test usuart avr ");
while(1)
{
lcd_gotoxy(0,1);
while(buffer)
lcd_cmd(buffer[i++], 1);
lcd_msg("\r\n");
}
}
ISR(USART_RX_vect)
{
buffer=UDR0;
i++;
}
-
*(devias usar a tag "code" para código, se usas "quote" há cenas que desaparecem, como por exemplo o [ i] no while(buffer[ i]) )
extern void lcd_cmd(char byte, unsigned char rs);
extern void lcd_msg(char *str);
Que biblioteca é esta? não vejo a definição das funções nem encontro nos sites de arduino, mas pelo nome uma devia servir para enviar comandos (posição do cursor, etc: http://mil.ufl.edu/3744/docs/lcdmanual/commands.html (http://mil.ufl.edu/3744/docs/lcdmanual/commands.html)) e outra texto. Se for assim o seu uso abaixo está errado.
main.c
volatile int i=0;
volatile uint8_t buffer[20];
int main(void)
{
sei();
DDRD = 0b11100000;
USART_init();
lcd_begin();
lcd_msg("test usuart avr ");
while(1)
{
lcd_gotoxy(0,1);
while(buffer[i])
lcd_cmd(buffer[i++], 1);
lcd_msg("\r\n");
}
}
ISR(USART_RX_vect)
{
buffer[i]=UDR0;
i++;
}
Mas suponhamos que as funções estão certas: Se "simulares" o funcionamento do programa encontras logo vários erros:
inicio: i=0; buffer[0]=0, loop está sempre a colocar o cursor em (0,1) , salta o while(buffer[ i]) (porque é =0) e manda um "\r\n". Ainda não recebeu nada e já está a mandar newlines em catadupa para o LCD, nem deves chegar a ver o "test usuart avr ".
Recebe um caráter: A interrupção coloca-o em buffer[ 0], i passa a 1. Quando voltar ao loop principal continua tudo na mesma, porque buffer[ i] do while já aponta para um novo valor 0
Recebem mais 20 carateres: o i vai ser incrementado para além do limite do buffer, vais ter um "buffer overrun" e maras a execução do programa porque não meteste nenhum limite no incremento do i...
Ou seja, tens isso tudo gatado e tens de rever a lógica do programa
-
Não será mais fácil usares uma backpack i2c para o LCD?
(Se é que estar a usar os LCDs convencionais claro)
-
O facto de tentares escrever no LCD enviando como comandos o que tens no buffer será um dos problemas.
-
Já consegui, apesar de aparecer um caracter estranho no final "OK&"
Kristey - Estou a utilizar lcd com 74hc595.
jm_araujo, senso- Sim as lib lcd não estao no site do arduino e afins, porque foi eu que as refiz tirei de um exemplo pic. Fica aqui o exemplo de como esta agora.
Agora vou tentar ligar a rede e fazer chamada.
//declaração funções
void USART_init(void);
unsigned char USART_receive(void);
void USART_send( unsigned char data);
void USART_putstring(char* StringPtr);
// declaracao variaveis
int posicao=0;
volatile uint8_t buffer[16];
volatile uint8_t estado=0;
int main(void)
{
sei();
DDRD = 0b11100000;
USART_init();
lcd_begin();
lcd_msg("test usuart avr ");
while(1)
{
USART_putstring("AT\r\n");
_delay_ms(3000);
}
}
ISR(USART_RX_vect)
{
buffer[posicao]=UDR0; //le USART
if(buffer[posicao++]=='\n') //verifica o fim de linha
{
while (posicao < 17){
buffer[posicao]=0x20; //preencher resto da string com "espacos"
posicao++;
}
estado = 1; //string completa
posicao=0; // reset posicao string
}
if (estado == 1)
{
lcd_gotoxy(0,1);
while(buffer[posicao]){
lcd_cmd(buffer[posicao++], 1);
}
posicao = 0; // reset posicao string
estado= 0; // apaga string
}
}
-
Escrever para o lcd que é super lento dentro de um interrupção é um erro crasso!
-
O ideal e usar interrupção apenas para escrever no buffer, e a escrita no lcd ficar dentro while certo?
Isto e apenas testes sem projecto a vista.
Como comparo buffer como determinada palavra?
Terei de converter o buffer e depois comparar?
-
Isto nao esta facil, buffer[posicao = URD0 nao dá nada de jeito, porque envio o comando para dar-me imei, ele responde imei + ok. Entao será perciso tratar das coisas, e aqui nao estou a ver bem como.
Agora posso fazer este proceso no ISR(USART_RX_vect)
detectar 0x0D e 0x0A
gravar para o buffer[posicao++] -- aqui recebe o imei
detectar novamente 0x0D e 0x0A -- termina, aqui copiava para um outro buffer2 e apagava o actual
detectar mais uma vez 0x0D e 0x0A --
recebia o ok
detecta 0x0D e 0x0A.
-
Deves ter o mínimo de código no ISR. Só meter o caracter num buffer e atualizar algum apontador para o mesmo ou flags.
A interpretação do conteúdo do buffer devias fazer numa máquina de estados no programa principal.
-
Bom dia,
Ora bem num buffer tenho 2 respostas imei e ok.
cr+cf do inicio anulei movendo o buffer da posicao 2 para 0 ficando buffer a começar logo com o imei.
funcao memmove (receive+0,receive+2,40);.
Até aqui tranquilo, agora nao consigo e dividir a string.
Ou seja detecto 0x0D no final imei, receive[10] agora quero copiar da posicao 10 ate 20 da string receive para uma outra string resposta, onde fica o OK.
Na net encontrei 2 funcoes mas nao consegui fazer funcionar
memcpy( resposta, &receive[posre] + 6, 20 );
strncpy(resposta, &receive[posre] + 6, 20);
-
cr+cf do inicio anulei movendo o buffer da posicao 2 para 0 ficando buffer a começar logo com o imei.
funcao memmove (receive+0,receive+2,40);.
Nem sempre é preciso mover, podemos pegar num ponteiro e apontá-lo para o inicio do que nos interessa.
Mas claro que para isso é preciso perceber ponteiros, que é uma cena extremamente simples mas da qual o pessoal faz um bicho de 500 cabeças, somente porque não entende o que é e como funciona a "memória" (que também é um conceito extremamente simples).
Até aqui tranquilo, agora nao consigo e dividir a string.
Ou seja detecto 0x0D no final imei, receive[10] agora quero copiar da posicao 10 ate 20 da string receive para uma outra string resposta, onde fica o OK.
Na net encontrei 2 funcoes mas nao consegui fazer funcionar
memcpy( resposta, &receive[posre] + 6, 20 );
strncpy(resposta, &receive[posre] + 6, 20);
Qualquer uma delas poderia servir, mas para já é melhor usares o memcpy, ou memmove, vê o manual:
http://man7.org/linux/man-pages/man3/memcpy.3.html (http://man7.org/linux/man-pages/man3/memcpy.3.html)
O que não perceberes do manual, pergunta especificamente. Não te ponhas a experimentar à toa até (parecer) que acertas, não aprendes nada assim. Tens que entender o teu problema, entender as funções, e escrever o código seguindo a lógica.
-
Já consegui andar mais um pouco depois umas semanas de pausa.
Estou a usar esta função varias vezes pelo programa, só que no entanto nas sms nao esta a funcionar.
chega examente isto; +CMTI: "SM",1
a funcao if (strcmp(buffer, "\r\n+CMTI: "SM",1\r\n") == 0) {} da erro devido as "" do SM ainda troquei por 'SM' mas nao deu.
Alguma ideia de como resolver o problema das aspas?
Obrigado
-
https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences
-
é isso jm_araujo, eu bem meti \0x22 mas passava-lhe ao lado. Refiz o codigo, e desta fez penso ja ter atinado +/- com o código.
Agora na alimentação é que esta um problema, ao fazer chamadas ou receber sms de fez em quando desliga-se assim como ao ligar o modulo de vez em quando desliga-se.
tenho fonte alimentação(home made 3A)no lugar da bateria. voltagem 3.7v fui aumentado até 4.18v mas desliga-se sempre.
Acrescentei um condensador 6800uF na entrada da bateria junto com 100nf nao resolveu, e cada vez que recebo chamada ou sms o lcd da fonte alimentação fica maluco.
E neste caso estou a pensar em colocar uma bateria, e queria saber se a pilha ultrafire servirá ou uma bateria de telemovel de 2A seria melhor?
Obrigado
-
Boa tarde
preciso de uma coisa que aparenta ser simples mas não consigo.
Tenho as coordenadas e 123456789 e preciso de adicionar um espaço para ficar 12 3456789.
Estou a tentar colocar dentro clico FOR que copia as coordenadas para latitude mas não dá.
void coordendas_gps(void)
{
memcpy (data2-10 , buffer , 100);
pch = strstr(data2,"N");
for(char i=0;i<11;)
{
Latitude[10-i]= *(pch-i);
i++;
}
Latitude[9]= 0x4e; // igual "N"
Latitude[10]= 0x00; //NULL
}
r
-
Porque é que não usas 'N' em vez de código hex?
-
Esse codigo esta mesmo complicado, nao consigo perceber o que pretende fazer.
Nao queres dar exemplos do input e output que pretendes?
Geralmente se o codigo esta muito complicado e nao se entende ah primeira, e' porque nao esta bem :P
-
calhou, meter em hex.
O basico é localizar a letra N e W, copiar para as variaveis latitute e longitude e meter um espaço.
void coordendas_gps(void)
{
memcpy (data2-10 , buffer , 100); //copia do buffer para data2 e apaga +GPSINF: (No data2 fica altitute latitude longitude velocidade,speed,...)
pch = strstr(data2,"N"); //Localiza a latitude até letra N
for(char i=0;i<11;)
{
Latitude[10-i]= *(pch-i); //Aqui o ciclo for copia do N para trás ficando na variavel latitude assim 3051.8007,N .
i++;
}
Latitude[9] ='N'; // substitui a virgula por N
Latitude[10]= 0x00; //NULL // apaga o N.
}
r
-
offtopic. comprei um modulo gsm ebay percisamente o gt06 que apesar de funcionar aquilo faz barulho iritante, parecido aquele quando se tem os telemoveis perto dass colunas, quando recebe um sms ou chamada.
Até liguei na moto e o barulho é o mesmo. Dá logo nas vistas.
-
calhou, meter em hex.
O basico é localizar a letra N e W, copiar para as variaveis latitute e longitude e meter um espaço.
void coordendas_gps(void)
{
memcpy (data2-10 , buffer , 100); //copia do buffer para data2 e apaga +GPSINF: (No data2 fica altitute latitude longitude velocidade,speed,...)
pch = strstr(data2,"N"); //Localiza a latitude até letra N
for(char i=0;i<11;)
{
Latitude[10-i]= *(pch-i); //Aqui o ciclo for copia do N para trás ficando na variavel latitude assim 3051.8007,N .
i++;
}
Latitude[9] ='N'; // substitui a virgula por N
Latitude[10]= 0x00; //NULL // apaga o N.
}
r
Vê isto:
http://arduiniana.org/libraries/tinygpsplus/ (http://arduiniana.org/libraries/tinygpsplus/)
Funcional, testado, simples.
-
Bom dia,
o problema é que nao estou a usar nada de arduino mas sim o avr studio. Por isso e que tenho tido dificuldades pelo caminho, mas ja há luz ao fundo do tunel.
Consegui e ta a funcionar prefeitamente tanto se fizer uma chamada como enviar uma sms ele retorna um sms com as coordenadas onde está. O código testado durante 2 dias nunca falhou. Agora fui acrescentar os restantes numeros de telefone e o programa deixa de funcionar.
Se tiver USART_putstring envia o sms se colocar o if ja nao envia sms. e queria saber o porque, porque a variavel "telefone" tem o meu numero telefone e so apaga no final do ciclo.
if (ordem == 4) {
USART_putstring("AT+CGPSINF=32\r\n"); // le coordenadas
_delay_ms(200);
coordenadas(); // converte coordenadas lat e long
_delay_ms(200);
if ( strcmp(telefone, "966*****") == 0){
USART_putstring( "AT+CMGS=\"+351966****\"\r"); //Assim nao envia nem chega a entrar dentro do if
lcd_msg("zzzzzzzzzzzzzzzz2");
_delay_ms(3000);
}
_delay_ms(100);
USART_putstring("A minha localizacao http://maps.google.com/?q=");
USART_putstring(Latitude);
_delay_ms(20);
USART_putstring(Longitude);
_delay_ms(20);
USART_send(0x1A);
lcd_clear();
lcd_gotoxy(0, 1);
lcd_msg("envio de mensagem ok");
_delay_ms(3000);
limpa();
lcd_clear();
lcd_msg("aguardar....");
memset(telefone, 0, 100);
ordem = 3;
-
Delays com fartura no meio do código.
Podes ás mesma olhar para a biblioteca e tirar ideias.
Que variavel é esse telefone?
É um array de chars?
-
Sim e telefone e um char arrays.
. Os delays e para dar tempo ao modulo responder, se calhar nem percisa de tantos.
Agoras as coordenadas o que menos preocupa.
-
Onde está a declaração dessa variável? Se não tiver um '\0' no final, duvido que isso funcione
-
Esta declarada no inicio do programa.Nao tem \0 no fim, assim como no if anterior com os 4 numeros e funciona.
Logo posso postar codigo todo.
-
Tem que ter o '\0', senão o strcmp não tem como saber onde termina a string.
Como tinhas dito que não estava a funcionar, pensei nessa possibilidade.
O mais provável é que o '\0' lá esteja, dependendo da forma como declaraste isso
-
Também comprei um modulo com o sim808, mas estou com dificuldades e registar na rede. Só tentei na rede MEO.
Sabem se é necessário algum cartão sim em especial?
Testes que efetuei:
Após ligar o modulo o sinal é 0
AT+csq
+CSQ: 0,0
OK
Consigo apanhar sinal dos 3 operadores.
AT+COPS=?
Call Ready
SMS Ready
+COPS: (1,"TMN","TMN","26806"),(3,"vodafone","voda P","26801"),(3,"OPTIMUS","OPTIM","26803"),,(0-4),(0-2)
Registo manualmente
AT+COPS=2,0,"TMN"
OK
O sinal passa a ser 31
AT+CSQ
+CSQ: 31,0
OK
AT+COPS?
+COPS: 2
se verificar se está registado, responde que não
AT+CREG?
+CREG: 0,0
Se tentar ligar também não dá
ATD+35196xxxxxxx;
NO CARRIER
Em temos de rede acho que sim, pelos menos consigo ligar-me a rede meo sem antena ligada. O GPS +/- 20segundos e tenho coordenadas +/- diferença 5metros da casa.
RALAX: sim consegues usar no arduino sem problemas.
Agora isto aqui está mau,lcd e uart ok, mas agora nao consigo imprimir buffer uart rx para o lcd, se for uma letra consegui agora frase OK nao estou a conseguir, já ando aqui a 1 dia e nao consegui. Alguma dica.
extern void lcd_cmd(char byte, unsigned char rs);
extern void lcd_msg(char *str);
main.c
volatile int i=0;
volatile uint8_t buffer[20];
int main(void)
{
sei();
DDRD = 0b11100000;
USART_init();
lcd_begin();
lcd_msg("test usuart avr ");
while(1)
{
lcd_gotoxy(0,1);
while(buffer)
lcd_cmd(buffer[i++], 1);
lcd_msg("\r\n");
}
}
ISR(USART_RX_vect)
{
buffer=UDR0;
i++;
}
-
No meu caso meti o cartao telemovel desliguei o pin desliguei o 3G ficando apenas o 2G,
Depois meti o cartao no modulo e ficou a funcionar.
Este site ajuda com os commandos :http://m2msupport.net/m2msupport/module-tester/
-
Boa tarde,
Estou aqui a limar umas arestas, e queria apagar todas as mensagens que não pertence a condição do if
if ( (strcmp(telefone, "96****") == 0) && strcmp(mensagem, "\0x0AFind me\0x0D") == 0) {
}
aqui envia a mensagem sem problemas, agora se acrescentar por baixo
else{
}
para apagar todas as restantes mensagens.
O problema é que mesmo que envie sms certo ele vai para o else e nao para o if. Onde estou a falhar?
agradeço
if (ordem == 5) { // if principal
memcpy (mensagem , data2 , 20);
memcpy (telefone - 26 , data1 , 100);
if ( (strcmp(telefone, "9******7") == 0) && strcmp(mensagem, "\0x0AFind me\0x0D") == 0) {
lcd_clear();
USART_putstring("AT+CMGDA=");
USART_putstring("\"DEL ALL\"\r\n"); // apagar todas mensagem
_delay_ms(10);
memset(mensagem, 0, 100); // apaga variavel mensagem.
limpa(); // limpa as restantes variaveis.
_delay_ms(100);
ordem = 4; // encaminha para outro if e envia o sms. Até tudo ok.
}
else {
USART_putstring("AT+CMGDA=");
USART_putstring("\"DEL ALL\"\r\n"); // apagar todas mensagem
limpa();
lcd_clear();
lcd_msg("msg desconhecida");
ordem = 3;
}
}
-
resolvido primeiro comparo a mensagem e segundo vejo se a mensagem é igual com 2 if's.
O código parece estar finalizado, varias chamadas e mensagens e respondeu e o módulo respondeu sempre.
Fonte de alimentação 12v para 3.9v testado e a funcionar.
Um pequeno curto circuito entre vbat e gnd com um condensador e fritei o modulo. Agora fico em stand by $$.
-
Boa noite estou aqui a começar a desenhar a pcb e precisava de uma opinião.
A fonte que vai converter dos 12v do carro para os 3.8v para alimentar o modulo e o atmega é o que está no manual.
A minha questão é se condensadores chegam ou acrescento um condensador maior a saída. Uma vez que o modulo pode precisar 2A segundo o manual.
fonte: http://cl.ly/2B0n1R0J2P0l (http://cl.ly/2B0n1R0J2P0l)
(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fcl.ly%2F2B0n1R0J2P0l&hash=8111b1733efa715a947562163a15e9753e49e5b9)
-
Boa noite estou aqui a começar a desenhar a pcb e precisava de uma opinião.
A fonte que vai converter dos 12v do carro para os 3.8v para alimentar o modulo e o atmega é o que está no manual.
A minha questão é se condensadores chegam ou acrescento um condensador maior a saída. Uma vez que o modulo pode precisar 2A segundo o manual.
fonte: http://cl.ly/2B0n1R0J2P0l (http://cl.ly/2B0n1R0J2P0l)
(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fcl.ly%2F2B0n1R0J2P0l&hash=8111b1733efa715a947562163a15e9753e49e5b9)
Para teres uma boa linha de alimentacao p o modem, aconselho a nao menos de 1000uF. Se tiveres espaco, poe ainda mais um de igual valor.
Alguns modems GSM sao mt esquisitos c a alimentacao e nao gostam de ver micro-sags na tensao. Outros sao mais robustos. Depende do fabricante pois cada um tem a sua implementacao.
Se a BOM estiver apertada, o q eu costumo fazer eh comecar com 470uF e ir subindo ateh a coisa comecar a trabalhar relaxada.
Se tiver BOM solta e espaco na PCB, entao ponho logo 2000uF.
-
Estou aqui a desenhar a pcb mas acho que vou fazer asneira.
É uma placa de 1 so lado, e fiz tudo no lado button e virei o atmega para o lado button, e agora estou com a impressão que quando for para soldar o atmega fica ao contrario de patas para o ar certo?
O atmega fica no lado tem cobre e os restantes componentes no lado de cima.
link foto: http://cl.ly/282F2u0Q1K0f (http://cl.ly/282F2u0Q1K0f)
-
Se os terminais do atmega estão azuis é porque fica do lado bottom, segue o circuito logo não pode ficar inverso.
Em eagle nem é possível colocar um IC ao contrário, as ligações seriam negadas, parece-me bem o que desenhaste, falta o plano de terra e uns condensadores de desacoplamento junto ao micro.
-
Pois os condensadores e que faltava mas já la estão, apesar de não terem ficado muito juntos ao atmega.
Plano terra ja tenho feito.
No entanto é a primeira vez que vou soldar TQFP e estou um pouco na duvida se os pads do atmega não deveriam sair um pouco mais para fora, para dar mais espaço de manobra para soldar.
-
boa tarde,
No avr studio da para ver quanto tempo demora o atmega no ciclo principal while a repetir o ciclo.
A ideia era saber quanto tempo demora o meu codigo a fazer um loop, e a memoria ocupada com as variaveis globias.
Atmega no lado botton fica ao contraio, e tem logica se o eagle diz que é top nao devia contrariar. Consegui corrigir refiz tudo do lado top.
Foi uma dificuldade enorme soldar tqfp, ainda vi bastantes videos no youtube mas mesmo assim vi-me a rasca. nem com malha os curtos desapareciam. Consegui apenas estanhando todos os pads depois com ferro sem solda ficar em 2 patas. Meti fluxo nos pads todos e ferro sem solda encostar.
Acho que pads de origem do eagle sao muito largos e haviam de ser um pouco mais compridos.
Se nao fosse o vinco do folha celefone tinha ficado bom, mas comprei um rolo e tem esse vinco nele todo.
(https://meocloud.pt/link/6ae16d76-3ce1-4701-aad1-6e697da8309b/IMG_20160820_135430.jpg/)
-
Soldar QFP eh tranquilo. Qd fores p QFP 100 pinos entao podes queixar-te, mas tb se soldam bem. Depois vais querer soldar QFN e mais tarde alguns BGA p testes em casa. Todos se soldam bem c o equipamento e ferramentas correctas.
Solda fina, ferro ponta fina, boa tranca dessoldadora (escolher bem pq ha mt porcaria) e mt fluxo (tb escolher bem pq ha mt porcaria)
Ja agora, fizeste as contas ao material q usaste p fazer as PCBs ?
Eh q conseguem-se 5x5cm por $10+portes e de qualidade aceitavel p hobbies.
-
Contas ao material não fiz, mas sei que nao compensa. Mas fica aquele prazer de fazer tudo de raiz, e ver o projecto crescer aos poucos.
Estou a organizar/testar o meu codigo e decidi meter uns quantos sub-programas e tentar deixar o while(1) principal com o menos possivel. ficando apenas 3 if's. Se detectar chamada, mensagem ou activar alarme.
A questao aqui é que as coordenadas deixaram de funcionar quando tirei do programa principal e nao consigo resolver a questão por nao conhecer a linguagem assim tao bem.
coordenadas(); tem de estar no while para funcionar, e eu só criar obter coordenadas quando chamar sub programa. Mas ao colocar em sub programa as latitude longitude ficam em branco
Foi copiado daqui por ser simples http://stackoverflow.com/questions/36967099/parse-gnss-nmea-string (http://stackoverflow.com/questions/36967099/parse-gnss-nmea-string) o codigo que esta no final.
Codigo foi cortado parte para nao ficar muito extenso.
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
#include <stdlib.h>
#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)
void USART_init(void);
static char *strtok_single(char *str, char const *delims);
void coordenadas(void);
unsigned char USART_receive(void);
void USART_send( unsigned char data);
void USART_putstring(char* StringPtr);
void adc_init(void);
uint16_t read_adc(uint8_t channel);
// declaracao variaveis
char buffer[100];
char * s;
char * pch;
int adc_value;
char busgps[100];
char latitude[11];
char logitude[12];
int main(void)
{
sei();
USART_init();
adc_init();
lcd_begin();
lcd_msg("Iniciar GPS 2.3");
while (1){
if ( strcmp(telefone, "966666666") == 0 ){
lcd_msg("user aceite");
endcall(); // termina chamada
coordenadas(); // le coordenadas
sms(); // envia sms
limpa(); // limpa buffers
menup(); // volta menu
}
}
ISR (USART_RX_vect)
{
}
void coordenadas(void)
{
USART_putstring("AT+CGNSINF\r\n"); // le coordenadas
strcpy(busgps, buffer);
// Parses the string
strtok_single(busgps, " ");
strcpy(latitude, strtok_single(NULL, ",")); // Gets latitude
strcpy(logitude, strtok_single(NULL, ",")); // Gets longitude
}
static char *strtok_single(char *str, char const *delims)
{
static char *src = NULL;
char *p, *ret = 0;
if (str != NULL)
src = str;
if (src == NULL || *src == '\0') // Fix 1
return NULL;
ret = src; // Fix 2
if ((p = strpbrk(src, delims)) != NULL)
{
*p = 0;
src = ++p;
}
else
src += strlen(src);
return ret;
}
-
Onde é que estás a encher o buffer?
Quando envias um comando a resposta demora um bocado a vir, não é imediata.
USART_putstring("AT+CGNSINF\r\n"); // le coordenadas
strcpy(busgps, buffer);
Aí no meio deve faltar qualquer coisa....
-
buffer enche no ISR.
Quando faço delay 10s por baixo strcpy(busgps, buffer); e no proteus vou ver buffer tem as coordenadas e busgps não tem nada.
No meio nao falta nada, so se agora como esta sub programa tenha de levar alguma coisa, mas também não estou a ver.
ISR (USART_RX_vect)
{
buffer[posicao] = UDR0;
if (buffer[posicao] == '\n') {
count_cr++;
}
if (count_cr == 1) {
print = 1;
}
if (count_cr == 2) {
print = 2;
}
if (count_cr == 3) {
print = 3;
}
if (print == 1 ) {
data1[pdata1] = buffer[posicao];
pdata1++;
}
if (print == 2 ) {
data2[pdata2] = buffer[posicao];
pdata2++;
}
if (print == 3 ) {
data3[pdata3] = buffer[posicao];
pdata3++;
}
posicao++;
}
-
Tá-me a falhar algo.
No código que meteste não tem nenhum delay.
Tens de ter o delay entre o pustring que envia o comando para o módulo e a cópia do buffer para o busgps com o strcopy, para dar tempo ao módulo para responder.
O código que mostras do ISR também está confuso. A variável posição não está definida no código original, e não vejo no código verificação que a mesma se mantém dentro dos limites do tamanho do buffer.
Tens de rever esse código e perceber o que está a fazer, parece que estás a ultrapassar os limites do cut&paste, mas é difícil de dizer com certeza.
-
Com o delay ja resolveu meti _ms_delay(100) e ja funcionou, pois anteriormente tinha posto 20 nao ficava latitude longitude altitude certa.
Tinha ideia que o delay dava uma pausa geral ao programa que durante esse tempo nao fazia mais nada.
A minha teoria foi: se coloco o delay por baixo do comando ele envia o comando para o modulo, o modulo responde, mas como esta resposta vem dentro do tempo do delay nao vai apanhar.
O meu ISR esta um pouco confuso, mas na verdade e por causa dos sms. Na pratica divide-me buffer em 3 partes depois pego na parte 2 que onde esta o conteudo da mensagem.
Nao deu para colocar codigo todo por esta mesmo muito extenso por isso e que falta pdata e afins
-
Afinal acertei à primeira ;)
No ISR deves meter o mínimo possível. no caso da porta série metes para o buffer e vaza. Processamento extra deves fazer fora.
Quando um ISR está a correr se ocorrerem outros interrupts ficam bloqueados à espera. Ora se tens algo que "exige" atenção imediata do processador e não a consegue, podem surgir todo um mundo perverso de anomalias. Por exemplo os delays dependem de interrupts, se o processador estiver preso a tratar da porta série e dependeres da precisão dos delays, já eras.
-
Real problema esta descoberto, graças a grande qualidade de produção dos chineses não é que os gajos soldaram os conectores ipex ao contrario, o do gsm e gps estão ao contrario, só Bluetooth e que esta certo.
Entanto tentei tirar ipex com jeitinho mas acabei por estragar arranquei ipex e soldei 2 fios directamente para a antena. e agora tenho rede. csq 13.
como é que estavam os dois conectores soldados ao contrário?
é esquisito, porque as boards sao produzidas aos milhares e normalmente testadas, e automaticamente, mas mm que fossem soldadas à mao, os pinos dos conectores teriam de coincidir com os sitios/pads onde vao a soldar (as pads normalmente em comunhao com a disposiçao dos pinos dos componentes, funcionam como sistemas poka-yoke para evitar más montagens..)
Por acaso tens foto da board antes de re-posicionares e ressoldares os conectores só pra ver?
-
O conector ipex tem 3 pinos massa e 1 pino é sinal. o meu pino sinal estava rodado 90º para esquerda se nao me engano e ficando ligado a massa
-
Afinal não funciona, e está me aqui a escapar alguma coisa e continuo a nao perceber o poque.
(codigo total em anexo)
Se o subprograma estiver dentro ciclo while funciona bem se estiver dentro de um if em que so la passa 1 vez ja nao funciona. e no meu caso nao consigo obter as coordenadas , e quando obtem coordenadas nao copia strcpy(logitudeg,logitude); fica a variavel em branco.
Será que strcpy ate alguma regras para funcionar bem.
int as = 0;
while (1){
if (as == 0){
as = 1;
alarmestate = 1;
limpa();
coordenadas();
lcd_msg("ja esta");
}
}
}
-
Não olhei com atenção, mas tens algumas coisas mal ou potencialmente mal:
-> Normalmente só se habilitam as interrupções depois de feita a inicialização do hw.
-> Todas as variáveis globais que são usadas em interrupções e simultaneamente em ciclos dentro da função principal têm que ser declaradas com volatile, caso contrário a variável pode não ser actualizada; mas podes ter ou vir a ter problemas mais graves (esporádicos), porque não tens sincronização nenhuma no acesso a essas variáveis (pode não ser necessário, não analisei).
-> Cuidado com variáveis locais grandes (como arrays) ou muitas, pois podes estar a ter stack overflow sem te aperceberes.
-> Se declarares as funções (excepto a main()) e variáveis globais com static, o código gerado encolhe.
-> Interrupções vazias podes declarar com EMPTY_INTERRUPT que gera menos código e é mais eficiente, por exemplo: EMPTY_INTERRUPT(WDT_vect)
-> A indentação tá um bocado má, por isso não vejo mais. Precisas de trabalhar um pouco nisso, pois é essencial para aumentar a ergonomia da leitura de código.
-
boa noite, ando aqui com uns grandes bugs, penso que tenha a ver com a comunicação entre avr e o modulo.
Depois de umas maratonas no google e varios testes, de modo a refazer a comunicacao no melhor possivel, não percebo porque é que o meu data_in é alterado quando uso strcpy.
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.
no while tem ordem e ao dividir a resposta em 3 char, o meu data_in altera-se e nao consigo perceber porque, nao devia alterar.
imagem do problema lado esquerdo bom direito mau: https://l68w8n.s.cld.pt
codigo completo em anexo
while (1){
if (cmd_ok == TRUE){
copy_cmd();
cmd_ok = FALSE;
}
}
}
void copy_cmd(void){
strtok(data_in,"\n");
strcpy(data1, strtok(NULL, "\n"));
strcpy(data2, strtok(NULL, "\n"));
strcpy(data3, strtok(NULL, "\n"));
}
ISR (USART_RX_vect)
{
data_in[posicao] = UDR0;
if (data_in[posicao] != '\0' ){
posicao++;
}
if (data_in[posicao +1] == '\0'){
cmd_ok= TRUE;
}
}
-
O que dizes aqui:
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:
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)
-
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.
-
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.
-
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.
-
É o bootloader do Arduino que pisca o led..
-
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.
-
É 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 (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;
}
-
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);
}
}
-
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:
memcpy (tlf -23 , data1 ,110);
-
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 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.