Ir ao conteúdo
  • Cadastre-se
densyy

Onda senoidal repicada

Recommended Posts

Olá, pessoal!

 

Estou desenvolvendo um projeto para faculdade e travei na parte final.

Vou tentar ser breve.

 

Objetivo do Trabalho:

Gerar uma Onda Senoidal, somente isso.

 

Estou usando o Arduino para gerar e uma rede R2R como conversor...

O problema é que a onda que deveria ser senoidal sai toda repicada... fica com uma aparência meio senoide-quadrada

 

Gostaria de saber quais são as opções mais viáveis para deixar a onda mais bonitinha ^^

Agradeço desde já!

Código Arduíno:
 

float senoidal[256] = {128, 131.1536, 134.3053, 137.4531, 140.5952, 143.7297, 146.8546, 149.9681, 153.0682, 156.1531, 159.221, 162.2698, 165.2979, 168.3033, 171.2843, 174.2389, 177.1655, 180.0623, 182.9274, 185.7592, 
                      188.556, 191.3159, 194.0375, 196.7189, 199.3586, 201.955, 204.5066, 207.0116, 209.4687, 211.8763, 214.233, 216.5374, 218.788, 220.9835, 223.1225, 225.2038, 227.2261, 229.1881, 231.0888, 232.9268, 
                      234.7011, 236.4106, 238.0544, 239.6313, 241.1404, 242.5809, 243.9518, 245.2523, 246.4816, 247.639, 248.7238, 249.7352, 250.6728, 251.5359, 252.324, 253.0366, 253.6733, 254.2337, 254.7175, 255.1243, 
                      255.454, 255.7063, 255.881, 255.9781, 255.9976, 255.9393, 255.8033, 255.5898, 255.2988, 254.9305, 254.4852, 253.963, 253.3644, 252.6897, 251.9393, 251.1137, 250.2133, 249.2387, 248.1905, 247.0694, 
                      245.8759, 244.6109, 243.2751, 241.8693, 240.3944, 238.8513, 237.2408, 235.564, 233.822, 232.0157, 230.1462, 228.2147, 226.2224, 224.1705, 222.0602, 219.8927, 217.6695, 215.3918, 213.0611, 210.6788, 
                      208.2462, 205.765, 203.2365, 200.6624, 198.0441, 195.3833, 192.6816, 189.9407, 187.1621, 184.3476, 181.4989, 178.6178, 175.7059, 172.765, 169.797, 166.8035, 163.7866, 160.7479, 157.6893, 154.6127, 
                      151.5199, 148.4129, 145.2935, 142.1635, 139.025, 135.8798, 132.7298, 129.5769, 126.4231, 123.2702, 120.1202, 116.975, 113.8365, 110.7065, 107.5871, 104.4801, 101.3873, 98.3107, 95.25212, 92.21342, 
                      89.19646, 86.20305, 83.23501, 80.29414, 77.38225, 74.50108, 71.65239, 68.83791, 66.05934, 63.31837, 60.61668, 57.95589, 55.33764, 52.76349, 50.23502, 47.75375, 45.32121, 42.93886, 40.60815, 38.33049, 
                      36.10728, 33.93984, 31.82952, 29.77758, 27.78526, 25.8538, 23.98434, 22.17802, 20.43596, 18.75919, 17.14875, 15.6056, 14.13068, 12.7249, 11.3891, 10.12409, 8.930649, 7.809486, 6.761299, 5.786713, 
                      4.886314, 4.060669, 3.310257, 2.635551, 2.036949, 1.514816, 1.069481, 0.7011948, 0.410202, 0.1966553, 0.06070709, 0.002426147, 0.02185822, 0.1189804, 0.2937393, 0.5460281, 0.8756943, 1.282532, 1.766304, 
                      2.326714, 2.963417, 3.676025, 4.464119, 5.327202, 6.264763, 7.27623, 8.360992, 9.518379, 10.7477, 12.0482, 13.4191, 14.85956, 16.36871, 17.94562, 19.58935, 21.2989, 23.07322, 24.91124, 26.81185, 28.77389, 
                      30.79617, 32.87746, 35.0165, 37.21199, 39.4626, 41.76696, 44.12366, 46.5313, 48.98839, 51.49345, 54.04495, 56.64135, 59.28107, 61.96252, 64.68405, 67.44402, 70.24076, 73.07256, 75.93771, 78.83447, 
                      81.76106, 84.71574, 87.69669, 90.70212, 93.73018, 96.77905, 99.84686, 102.9318, 106.0319, 109.1454, 112.2703, 115.4048, 118.5469, 121.6947, 124.8464};

void setup() { 
  
  //DECLARAÇAO DE PINOS
  pinMode(0, OUTPUT); 
  pinMode(1, OUTPUT); 
  pinMode(2, OUTPUT); 
  pinMode(3, OUTPUT); 
  pinMode(4, OUTPUT); 
  pinMode(5, OUTPUT); 
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT); 
  
} 

void loop() { 

  float frequencia = 10;
  float periodo = ((1000000/ frequencia)); //Delay em MicroSegundos
  float tempo = (periodo / 256); //256 posições no Array
  
  for (int i = 0; i < 255; i++) { 
    
     PORTD = senoidal[i]; 
     delayMicroseconds(tempo); 
     
   }
   
}

 

Editado por densyy

Compartilhar este post


Link para o post
Compartilhar em outros sites

não sei a capacidade de processamento do seu precioso arduino mas eu (eu) usaria variáveis tipo unsigned char visto que PORTD provavelmente é 8 bits. Usar float em mc de 8 bits é quase um sacrilégio. E pra este teu propósito penso que é extremamente desnecessário chegando a ser danoso (como comprovaste)

 

Bem...Eu (eu) faria no excel uma tabela e nele mesmo geraria o padrão senoidal de 255 bytes. Depois basta um ctrl-c ctrl-v no fonte. De fato já fiz isso há algum tempo mas estou sem o mesmo pra procurar. Mas é muitíssimo fácil. se eu não estivesse com fome até o faria agora pra você.

 

Voar muçá... vamo?

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@densyy ,

 

Se voce está usando uma rede R-2R e usando apenas uma porta de 8 bits, sua senóide terá apenas 256 possíveis níveis, e isso vai tornar ela um pouco reticulada mesmo. Pode até usar uma rede RC para melhorar o sinal se a frequência a ser gerada é fixa.

 

O que voce pode fazer também é gerar a mesma por PWM, que pode ter 16 bits de resolução e vai gerar uma senóide bem mais bonitinha ( porém vai precisar filtrar por um circuito RC e é bem mais limitado quanto à freqüência gerada ), ou então apelar para uma segunda rede R-2R, usando mais alguns pinos de uma outra porta. Pela minha experiência, se você usar mais 4 bits já vai conseguir um sinal bem mais bonito. Para isso, o ideal é que o clock seja bem rápido, para que o delay entre acionar as duas saídas não distorça a forma de onda. A vantagem é que nem vai precisar do circuito RC de filtro, e pode variar bastante a frequência a ser gerada.

 

Se quiser, veja no meu tópico destacado do BASCOM, tem lá alguns exemplos de se gerar senóides, inclusive por DDS.

 

Paulo

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

fi-lo. Dar-te-ei apenas a fórmula...

coluna A de 0 a 360

coluna B =RADIANOS(A)

coluna C =SEN(B)

coluna D =127+INT(C*127)

A coluna D são os dados em bytes que devem ser transferidos para o fonte

Obs: você cria apenas uma linha de fórmula. As demais, selecione a linha, clique e arraste o +zinho

o início

(clrt-c ctrl-v)

127

129

131

133

135

138

140

142

144

146

149

151

153

155

157

159

162

164

Usando o editar-substituir do word você consegue colocar tudo em ordem.

 

unsigned char const tabelaseno[] = {
127,129,131,133,135,138,140,142,144,146,149,151,153,155,157,159,162,164
//...
}

Depois disso é só alimentar seu port ou o canal pwm do paulão com o dado. Lembrando que a freq do pwm deve ser pelo menos 10x maior do que aquela que queres gerar

 

Ah sim, do jeito que você fez - alimentar um port com variável float - é bem sinistro. Port geralmente é em hexa char, int. Se float, a parte fracionária é ignorada e seu compilador devia de dar um warning pelo menos. (desconheço o compilador do arduíno ok?)

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa! Primeiramente muito obrigado pelas respostas!

 

@Isadora Ferraz , mudei de Float para unsigned char e realmente parece muito mais coerente agora ^_^

No Proteus a onda ficou muito boa, mas só vou poder testar de verdade na segunda com o osciloscópio.

 

@aphawk , Então Paulo, eu pensei em usar um filtro passa baixa, mas meu objetivo é poder variar

de 1 a 20Hz e n uma frequência fixa sabe. Será que com um filtro RC consigo variar ? 

A variação é muito pequena... 20Hz apenas

 

----------------

Tabela Onda Senoidal para quem quiser ;) 

unsigned char const senoidal[361] = {127, 129, 131, 133, 135, 138, 140, 142, 144, 146, 149, 151, 153, 155, 157, 159, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 199, 
201, 203, 205, 206, 208, 210, 211, 213, 215, 216, 218, 219, 221, 222, 224, 225, 227, 228, 229, 231, 232, 233, 234, 235, 236, 238, 239, 240, 241, 242, 243, 243, 244, 245, 246, 247, 247, 248, 249, 249, 250, 250, 251, 251, 
252, 252, 252, 253, 253, 253, 253, 253, 253, 253, 254, 253, 253, 253, 253, 253, 253, 253, 252, 252, 252, 251, 251, 250, 250, 249, 249, 248, 247, 247, 246, 245, 244, 243, 243, 242, 241, 240, 239, 238, 236, 235, 234, 233, 
232, 231, 229, 228, 227, 225, 224, 222, 221, 219, 218, 216, 215, 213, 211, 210, 208, 206, 205, 203, 201, 199, 198, 196, 194, 192, 190, 188, 186, 184, 182, 180, 178, 176, 174, 172, 170, 168, 166, 164, 162, 159, 157, 155, 
153, 151, 149, 146, 144, 142, 140, 138, 135, 133, 131, 129, 127, 124, 122, 120, 118, 115, 113, 111, 109, 107, 104, 102, 100, 98, 96, 94, 91, 89, 87, 85, 83, 81, 79, 77, 75, 73, 71, 69, 67, 65, 63, 61, 59, 57, 55, 54, 52, 
50, 48, 47, 45, 43, 42, 40, 38, 37, 35, 34, 32, 31, 29, 28, 26, 25, 24, 22, 21, 20, 19, 18, 17, 15, 14, 13, 12, 11, 10, 10, 9, 8, 7, 6, 6, 5, 4, 4, 3, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 
1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 29, 31, 32, 34, 35, 37, 38, 40, 42, 43, 45, 47, 48, 50, 52, 54, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 
79, 81, 83, 85, 87, 89, 91, 94, 96, 98, 100, 102, 104, 107, 109, 111, 113, 115, 118, 120, 122, 124, 126};

Compartilhar este post


Link para o post
Compartilhar em outros sites

@densyy ,

 

Opa a frequência é baixa, mas a variação é muito alta para um filtro RC, pois se você calcular para 20 Hz, vai sair um certo valor de tensão na saída, e quando você abaixa a frequência, essa tensão começa a subir, sendo que em 1 Hz será mais de 5 vezes maior.... se isso for problema, ferrou.....

 

Bom, tenta fazer com os 8 bits, e se não ficar bem, passa pra 12 , usando 4 pinos de outra porta, e modifique a sua tabela, aliás eu usaria 2 tabelas, uma para cada porta... enfim, veja como fica hehehe.

 

Paulo

 

OPS ... EM TEMPO ... sua tabela tem de ter 256 elementos, meu amigo, senão fica muito descontínua, que é que você relatou ....  você criou com 128 apenas ... cadê o resto ?????

Editado por aphawk

Compartilhar este post


Link para o post
Compartilhar em outros sites

de fato penso que precisa apenas de 90 (63) que são os dados do 1º quadrante. Com um algoritimozinho meia boca pode-se replicar até os 360º (255). Pra freq baixa do amigo penso que uma paradinha tipo switch case pra analisar nem vai fazer cosquinha na onda. Bom... acho que to surfando demais...

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Isadora Ferraz ,

 

Sim, também pode ser feito com 63 elementos e replicando isso 4 vezes com truquezinhos matemáticos, mas aí teria apenas 252 elementos. Já sei .... você ia falar que a diferença na forma de onda é mínima... tem razão kkkk !

 

Paulo

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

é isso aí. Bom... falha minha. Ao mencionar 63 de fato pensei em de 0 a 63 (64 elementos) e de 0 a 255 (256). Perceba o foco nos 8 bits

 

Focando em usar apenas 64 elementos como desafio do intelecto, quiçá mais tarde eu pense algum algoritimo que deforme a onda o mínimo possível... ou não

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não entendi porq temos que usar apenas 256 elementos

Tinha pensando em fazer assim:

Usando a tabela de 361 posições calculada no Excel

//CALCULA FREQUENCIA DE ONDA A PARTIR DO PERIODO
  float periodo = ((1000000/ frequencia)); //Delay em microSegundos
  float tempo = (periodo / 361); //Array com 361 posições
  
  for (int i = 0; i < 361; i++) { 
    
     PORTD = senoidal[i]; //Envia tensão para o PORTD
     delayMicroseconds(tempo);
   }

A variável $tempo vai dividir o período da onda em 361 partes

E então todos os níveis de tensão da onda senoidal serão enviados em 1 único período, completando assim a frequência desejada

Compartilhar este post


Link para o post
Compartilhar em outros sites

@densyy ,

 

Também pode fazer assim como voce quer.

Como a frequência é baixa, até pode manter esse delayMicroseconds() em vez de usar uma interrupção do Timer.

 

Paulo

 

 

Editado por aphawk
  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×