collapse

* Posts Recentes

Amplificador - Rockboard HA 1 In-Ear por almamater
[Ontem às 19:13]


O que é isto ? por KammutierSpule
[26 de Março de 2024, 19:35]


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


Emulador NES em ESP32 por dropes
[13 de Março de 2024, 21:19]


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]


Meu novo robô por josecarlos
[06 de Janeiro de 2024, 16:46]


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

Autor Tópico: GeoSounduino  (Lida 11693 vezes)

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

Offline Ricardo

  • Mini Robot
  • *
  • Mensagens: 110
GeoSounduino
« em: 06 de Agosto de 2010, 16:07 »
Bom dia.

Este tópico pode ser considerado um “spinoff” do Arduino áudio gps http://lusorobotica.com/index.php?topic=2293.0
Resolvi criar um novo por duas razões:

1º- Finalmente arranjei um nome para baptizar o projecto: GeoSounduino.  8)

2º - O projecto inicial sofreu algumas alterações, não tanto no conceito, mas mais na apresentação/materiais utilizados.

Ainda assim, a ideia mantém-se a mesma: Criar um equipamento autónomo que utilizando a localização GPS, e depois de programado com pontos predefinidos, responde com conteúdos áudio específicos para cada um desses pontos.

Depois de alguns protótipos, e de vários “road-test”, cheguei a um produto semi-finalizado, estando numa fase de criação de uma aplicação VB para criar e gerir os itinerários.

As grandes diferenças para o protótipo original estão na utilização de um módulo gps da libelium (em vez da demoboard original, que embora respondesse bem, é demasiado grande e, parece-me, muito exigente ao nível da corrente). Outra grande diferença é que ao invés de utilizar um atmega328, optei por colocar um arduino nano, mas pretendo voltar ao 328 assim que terminar a optimização do código.
Para isso também irá contribuir (espero) a criação de uma pcb personalizada que irei tentar por em pratica assim que chegarem os produtos da venda colectiva! A seguir, entra em produção em série! ;D

O módulo de som é o mesmo, o LCD é vermelho em vez de azul, e as entradas e saídas têm mais ou menos a mesma filosofia.

Um dos maiores desafios dos últimos dias tem sido a optimização do código de forma a trabalhar com muitos pontos (40) utilizando também a direcção (heading) como variável para escolha do som (ex: se for para norte no ponto A passa o som 1, se for para sul no mesmo ponto, passa o som 2).

Uma das coisas que experimentei, embora ainda não tenha grande certeza da vantagem, foi colocar os pontos na memória flash (progmem) de modo a libertar a ram, pois pareceu-me que a certa altura o comportamento da caixa começava a ficar muito estranho, reiniciando sozinha ou apresentado caracteres esquisitos no lcd…
Calculei que estivesse a exigir muito da memória com tantos dados ao mesmo tempo. Pelo menos agora, e com os 40 pontos, tem funcionado sempre.

Aqui ficam algumas imagens da caixa e do código. O interior fica para mais tarde  ;)








Código: [Seleccione]
/* GeoSounduino v.1.0
Criado por Ricardo Nogueira em 2010
Audioguia georeferenciado
*/

#include <avr/pgmspace.h>
#include <LiquidCrystal.h>
#include "LB_GPS.h"

//pinos e variaveis para SOMO 14d
const int pinClock= 12; //3;
const int pinData =11; //4;
const int pinBusy =10; //6;
const int pinReset=14; //7;
int busy=0;

//pinos e variaveis para lcd
LiquidCrystal lcd(4,5,6,7,8,9);
char symb[4][3] = {"\\",
                    "|",
                    "/",
                    "-"};
int custom_0[] = { 0x0,0x10,0x8,0x4,0x2,0x1,0x0 ,0x0}; // char "\"
int custom_1[] = { 0x0,0x1b,0xe,0x4,0xe,0x1b,0x0 ,0x0}; // char "x"
int custom_2[] = { 0x0,0x1,0x3,0x16,0x1c,0x8,0x0 ,0x0}; // char ok "\_"
int custom_3[] = { 0x1,0x3,0xf,0xf,0xf,0x3,0x1 ,0x0}; // char "som"
int custom_4[] = { 0x0,0xf,0x3,0x5,0x9,0x10,0x0, 0x0}; // char NE "/->"
int custom_5[] = { 0x0,0x10,0x9,0x5,0x3,0xf,0x0 ,0x0}; // char SE "\->"
int custom_6[] = { 0x0,0x1,0x12,0x14,0x18,0x1e,0x0, 0x0}; // char SW"<-/"
int custom_7[] = { 0x0,0x1e,0x18,0x14,0x12,0x1,0x0 ,0x0}; //char NW <-\"

int  s=0;     //estado do detector de actividade     
int np=40;    //total de pontos
int ps=0;     //pontos encontrados

char* raw;    //string recebida pelo gps
double xx;    //latitude
double yy;    //longitude
char* stt=0;  //estado do FIX
char* head;   //heading
double speeed;//velocidade

//estado de cada ponto: true-encontrado; false-por encontrar
boolean stts[40]=
{false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false};

//direcção associada a cada ponto:N;S;E;W;4(NE);5(SE);6(SW);7(NW)
PROGMEM prog_char dirs[40]=
{'N','N','S','5','S','S','5','E','E','S','N','S','E','O','A','B','C','D','N','S',
 'N','S','E','O','A','B','C','D','N','S','N','S','E','O','A','B','C','D','N','S'};

//pontos do itinerário
PROGMEM prog_uint32_t memp[40][2]=
 { 
  {3874348, 930374},{3874012, 930732},{3873645, 930876},{3873470, 930623},{3872969, 930972},
  {3872275, 930974},{3871875, 930593},{3871683, 930219},{3871407, 929718},{3870917, 929618},
  {3874657, 918054},{3874517, 917489},{3874336, 917434},{3874336, 917435},{3874200, 917085},
  {3874254, 917870},{3874402, 918202},{3874517, 918085},{3874585, 918210},{3874822, 918047},
  {3874657, 918054},{3874517, 917489},{3874336, 917434},{3874336, 917435},{3874200, 917085},
  {3874254, 917870},{3874402, 918202},{3874517, 918085},{3874585, 918210},{3874822, 918047},
  {3874822, 918047},{3874822, 918047},{3874822, 918047},{3874822, 918047},{3874822, 918047},
  {3874822, 918047},{3874822, 918047},{3874822, 918047},{3874822, 918047},{3874822, 918047}};


void setup(){
  pinMode(pinData,OUTPUT);     
  pinMode(pinClock,OUTPUT);   
  pinMode(pinReset,OUTPUT);   
  pinMode(pinBusy,INPUT);     
  lcd.begin(16, 2);
  //definir caracteres especiais
  defineCharacter(0, custom_0);
  defineCharacter(1, custom_1);
  defineCharacter(2, custom_2);
  defineCharacter(3, custom_3);
  defineCharacter(4, custom_4);
  defineCharacter(5, custom_5);
  defineCharacter(6, custom_6);
  defineCharacter(7, custom_7);
  lcd.print("GeoSounduino 1.0");
  lcd.setCursor(0,1);
  lcd.print("a Inicializar...");
  //definir tipo de dados gps a analisar (gprmc)
  GPS.setSentences(GPRMC);   
  delay(100); 
  //definir localizaçao inicial, data e hora
  GPS.init();   
  //GPS.setDate("6,08,2010");
  //GPS.setTime("10,00,00");
}

void loop(){
 
  //variaveis auxiliares
  char xxs[10];
  int xx_d;
  double xx_m;
  char yys[10];
  int yy_d;
  double yy_m;
  char* vel;   
  char* lat="             ";
  char* lon="             ";
 // stt=" ";
  vel="     ";
  head="    ";
  speeed=0;
  xx=0;
  yy=0;
  //recaber string gps
  raw=GPS.getRaw(100);
  GPS.GPSStringExplode(GPS.inBuffer,',');
  //identificar variaveis utilizadas
  lat=(char*)GPS.arguments[3];
  lon=(char*)GPS.arguments[5];
  stt=(char*)GPS.arguments[2];
  vel=(char*)GPS.arguments[7];
  head=(char*)GPS.arguments[8]; 
  speeed=atof(vel); 
  //conversão de coordenadas gps (polares) para coordenadas cartesianas
  xx=atof(lat);
  xx_d=xx/100;
  xx_m=xx-xx_d*100;
  xx_m=xx_m/60;
  xx=xx_d+xx_m; 
  yy=atof(lon);
  yy_d=yy/100;
  yy_m=yy-yy_d*100;
  yy_m=yy_m/60;
  yy=yy_d+yy_m;
  //comparação do ponto actual com os pontos gravados
  ponto(xx,yy);
  //escrever dados no lcd
  display1();
  //incremento do detector de actividade
  s++;
  if(s>3){
    s=0;
  }
  delay(500);
}

//tocar faixa audio - código retirado de: Doyle Maleche -> maleche1 at comcast dot net
void sendData(int ThisSong){
  int TheSong = ThisSong;
  int ClockCounter=0;
  int ClockCycle=15;//0x0f;
  digitalWrite(pinClock,HIGH);
  delay(300);
  digitalWrite(pinClock,LOW);
  delay(10);
  while(ClockCounter <= ClockCycle){
    digitalWrite(pinClock,LOW);
    if (TheSong & 0x8000){
      digitalWrite(pinData,HIGH);
    }
    else{
      digitalWrite(pinData,LOW);
    }
    TheSong = TheSong << 1;
    delayMicroseconds(200);     
    digitalWrite(pinClock,HIGH);
    ClockCounter++;
    delayMicroseconds(200);
  }
  digitalWrite(pinData,LOW);
  digitalWrite(pinClock,HIGH);
  digitalWrite(pinClock,LOW); 
}

//definir caracters especiais
int defineCharacter(int ascii, int *data) {
    int baseAddress = (ascii * 8) + 64; 
    // baseAddress = 64 | (ascii << 3);
    lcd.command(baseAddress);
    for (int i = 0; i < 8; i++)
        lcd.write(data[i]);
    lcd.command(128);
    return ascii;
}

//verificação de pontos
void ponto(double x, double y)
{
  for(int n=0;n<np;n++){
    //só percorre pontos ainda não encontrados
    if(stts[n]==false){
      //calculo para confirmar ponto dentro de um raio de +- 50m
      if(pow(x-(0.00001*pgm_read_dword_near(memp[0] + n*2)),2) + pow(y-(0.00001*pgm_read_dword_near(memp[0] + (n*2)+1)),2) <= pow(0.00055,2)){
        //confirma a direcção associada ao ponto
        if(direct(head)==(char)pgm_read_word_near(dirs + n)){
          //dá ponto com encontrado
          stts[n]=true;
          //toca som associado ao ponto
          sendData((n+1)*2);   
          //incrementa pontos encontrados
          ps++;
        }
      }
    }       
  }
}

//informação no lcd
void display1()
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(xx,5);
  lcd.setCursor(8, 0);
  lcd.print("/");
  lcd.print(yy,5);
  lcd.setCursor(0, 1);
  if(stt[0]=='A'){
    lcd.write(2);
  }
  else{
    lcd.write(1);
  }
  lcd.setCursor(2,1);
  if(speeed<=1){
    lcd.print("-");
  }
  else{
    char d=direct(head);
    if(d=='N'||d=='S'||d=='E'||d=='O'){
      lcd.print(d);
    }
    else{
      char* letra;
      letra[0]=d;
      letra[1]='/0'; 
      lcd.write(atoi(letra));
    }
  }
  lcd.setCursor(4,1);
  lcd.print(speeed*1.6093,0);
  lcd.setCursor(8, 1);       
  lcd.write(3);
  lcd.print(ps);
  lcd.print("/");
  lcd.print(np);         
  busy =digitalRead(pinBusy);   
  lcd.setCursor(14,1);
  if(busy==1){
    lcd.write(3);
  } 
  else{
    //para futuramente colocar musica(s) "ambiente" 
  }
  lcd.setCursor(15, 1);       
  if(s==0){
    lcd.write(0); 
  }
  else{
    lcd.print(symb[s]); 
  }
}

//conversão do heading para 8 pontos cardeais
char direct(char* head)
{
  double head_f=atof(head);
  if(head_f>=20 && head_f<=110){
    //NE
   return '4';
  }
  else if(head_f>=70 && head_f<=110){
    return 'E';
  }
  else if(head_f>110 && head_f<160){
    //SE
    return '5';
  }
  else if(head_f>=160 && head_f<=200){
    return 'S';
  }
  else if(head_f>200 && head_f<250){
    //SW
    return '6';
  }
  else if(head_f>=250 && head_f<=290){
    return 'W';
  }
  else if(head_f>290 && head_f<340){
    //NW
    return '7';
  }
  else{
    return 'N';
  }
}

Ah, e obrigado a todos pelas ajudas e sugestões no outro tópico!


Offline msr

  • Mini Robot
  • *
  • Mensagens: 798
Re: GeoSounduino
« Responder #1 em: 06 de Agosto de 2010, 16:25 »
Adorei o projecto!
Está muito bom, os meus parabéns.

E já agora que tenha sucesso quando entrar na produção em série ;D

Uma perguntinha: pode-se saber onde arranjaste a caixa? foi fácil encaixar o LCD?

Offline Ricardo

  • Mini Robot
  • *
  • Mensagens: 110
Re: GeoSounduino
« Responder #2 em: 06 de Agosto de 2010, 16:40 »
Adorei o projecto!
Está muito bom, os meus parabéns.

E já agora que tenha sucesso quando entrar na produção em série ;D

Uma perguntinha: pode-se saber onde arranjaste a caixa? foi fácil encaixar o LCD?

Obrigado!

A caixa foi comprada na dimofel em lisboa, e custa cerca de 4€. É de plástico, tem um sistema de encaixe sem parafusos, o que à primeira vista parecia mau, mas depois até se revelou uma vantagem. Como é de plástico, foi só usar a dremel para fazer o buraco para o lcd, e mesmo não ficando perfeito, tenho uma ideia de como disfarçar a “junta”... :)

Offline metRo_

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 3.753
Re: GeoSounduino
« Responder #3 em: 06 de Agosto de 2010, 19:02 »
O projecto ficou com bastante bom aspecto :) coloca uma mensagem no outro tópico a indicar que a continuação é neste. Se calhar o ideal era usares um micro mais potente como por exemplo o arduino mega mas não sei se este existe numa placa mais pequena. O ideal era não usar linguagem arduino como produto final mas programar em C pois é mais eficiente.

Offline Ricardo

  • Mini Robot
  • *
  • Mensagens: 110
Re: GeoSounduino
« Responder #4 em: 06 de Agosto de 2010, 22:23 »
O projecto ficou com bastante bom aspecto :) coloca uma mensagem no outro tópico a indicar que a continuação é neste.

Obrigado! Farei isso.

Se calhar o ideal era usares um micro mais potente como por exemplo o arduino mega mas não sei se este existe numa placa mais pequena. O ideal era não usar linguagem arduino como produto final mas programar em C pois é mais eficiente.

Em c, em vez de arduino?  Agora baralhaste-me...
Não fazia ideia que podia usar o c. Mas como carrego um programa em C?
E qual "versão" de C? Vou ver se percebo o que queres dizer com isso...

Até ver, o atmega328 tem aguentado com o código, e os pequenos bugs têm sido resolvidos... mas por vezes falha de forma estranha (reinicia, ou bloqueia). Presumo que o problema está nas conversões (atof e atoi) que não devem correr muito bem.

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: GeoSounduino
« Responder #5 em: 06 de Agosto de 2010, 22:30 »
Para usar puro C e acesso directo a tudo no atmega podes ler isto:
http://www.smileymicros.com/index.php?module=pagemaster&PAGE_user_op=view_page&PAGE_id=70&MMN_position=117:117
E aproveita para ler todos os outros tutoriais desse site que são de topo mesmo, depois regista-te no avrfreaks e lê toda a secção de tutoriais que está aqui:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewforum&f=11&sid=758e68a2f0269e762ad222c5942549f5
É que coisas simples como usar a usart(serial) ou o adc é bem mais "complexo" usando acesso directo aos registos e assim que usando o arduino.
Terás tambem de instalar o AvrStudio e o WinAvr, mas isso é explicado nos primeiros tutoriais desse site que já acima aconselhei a ler.
Por exemplo usar acesso directo ás portas em vez de usar os digitalWrite poupa-te cerca de 40 ciclos de relógio de cada vez, o que dá um diferença massiva de performance.
Avr fanboy

Offline metRo_

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 3.753
Re: GeoSounduino
« Responder #6 em: 07 de Agosto de 2010, 08:33 »
Podes continuar a usar o IDE do arduino.

Offline Ricardo

  • Mini Robot
  • *
  • Mensagens: 110
Re: GeoSounduino
« Responder #7 em: 07 de Agosto de 2010, 13:36 »
Já andei a dar uma vista de olhos nos links que o senso forneceu... e para já só posso dizer... ainda bem que entrei de férias!  :P

Já estou a trabalhar há muito tempo em linguagens de alto nivel em máquinas relativamente potentes, e habituei-me a descurar as implicações ao nivel do desempenho. Mas agora, com esta incursão nos pics, percebo que faz toda a diferença optimizar as coisas de forma a "abreviar" algumas acções. Vou estudar o assunto.  ;)




Offline TigPT

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 5.372
    • Tiago Rodrigues
Re: GeoSounduino
« Responder #8 em: 07 de Agosto de 2010, 18:33 »
Muito bom. O futuro dos guias turisticos.

Atenção à direçcão Norte / Sul por GPS, não é nada de fiar em baixas velocidades ou quando se está parado. Complementa com uma bussula digital!

Parabéns, estou a adorar ver. Muito semelhante a uma ideia minha para geo caching.

Offline microbyte

  • Mini Robot
  • *
  • Mensagens: 1.322
    • http://ricardo-dias.com/
Re: GeoSounduino
« Responder #9 em: 18 de Agosto de 2010, 12:06 »
Muito fixe! :) Parabéns...
Gostei bastante de ver as fotos do projecto... E é bom ver o pessoal a meter o código sem problemas.

É bom para todos... Aprendes tu e aprendemos todos os que lemos.

Continua...

Offline GnGz

  • Mini Robot
  • *
  • Mensagens: 665
Re: GeoSounduino
« Responder #10 em: 19 de Agosto de 2010, 17:30 »
:D LINDO !!!

Offline TigPT

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 5.372
    • Tiago Rodrigues
Re: GeoSounduino
« Responder #11 em: 19 de Agosto de 2010, 23:01 »
Isto mete-me mesmo a babar-me. Quero ver mais ideias a sugeri daqui.

Offline metRo_

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 3.753

Offline andre_f_carvalho

  • Mini Robot
  • *
  • Mensagens: 1.469
    • Pro - andrefcarvalho
Re: GeoSounduino
« Responder #13 em: 20 de Agosto de 2010, 15:07 »
Muito bom. O futuro dos guias turisticos.

Atenção à direçcão Norte / Sul por GPS, não é nada de fiar em baixas velocidades ou quando se está parado. Complementa com uma bussula digital!

Parabéns, estou a adorar ver. Muito semelhante a uma ideia minha para geo caching.

olhando a esta ideia da bússola digital, acho que poderias usar um servo  de 360º e colocar o esquema de uma bússola e sempre que o carro anda-se as voltas a bússola faria mover o servo pondo-o sempre a apontar para norte, que achas da ideia?

Offline GnGz

  • Mini Robot
  • *
  • Mensagens: 665
Re: GeoSounduino
« Responder #14 em: 20 de Agosto de 2010, 16:33 »
Neste momento o que faz ao certo?