Ir ao conteúdo
  • Cadastre-se

Projetos com Avr : Design, Programação em Basic e Assembly


Ir à solução Resolvido por aphawk,

Posts recomendados

Pessoal,

Segue um novo tutorial, orientado para os principiantes, sobre o uso de microcontroladores AVR ( Atmega, Attiny ) em vários tipos de projetos.

 

Conforme os projetos vão evoluindo, mostro também como pode ser muito importante o uso do Assembly dentro do programa em Basic.

 

Isto torna totalmente desnecessário, (melhor dizendo, obsoleto !) o uso de linguagem C para qualquer tipo de programa, mesmo os de temporização muito crítica.

Apresento os programas-fontes, os objetos da compilação, e os arquivos de simulação do ISIS, tudo incluído para facilitar.

 

Muitos dos projetos aqui neste tópico são inéditos, e conforme vou apresentando, vou explicando muitas técnicas bem avançadas para conseguirmos atingir os objetivos utilizando sempre um hardware de baixo custo.

Lembro aqui que quase sempre podem ser utilizadas as plataformas ARDUÍNO, bastando adequar os esquemas para o hardware escolhido !

O foco foi dado no uso do BASCOM, que possui versão gratuita para gerar objetos até 4K, e a Simulação dos projetos, utilizando o ISIS do PROTEUS.

Assim, fica bem mais fácil para todos fazerem os seus projetos, e rodar a simulação no ISIS, antes de partir para a montagem física.

Este novo tutorial é uma evolução natural do antigo tutorial escrito por mim faz algum tempo, e este novo substitui totalmente o antigo.

Importante -> Acabei de colocar uma versão atualizada, com projetos utilizando sensores de Umidade e de Pressão,

bem como utilização de componentes 1-WIRE e I2C com tensões diferentes à do AVR. Esta nova versão tem agora 169 páginas .....
 

Mas mesmo após ler o tutorial, a continuação natural dele está aqui neste tópico, que já possui muita informação extra e avançada.

 

Boa diversão e um excelente aprendizado a todos.

Paulo

 

Tutorial_AVR.zip

Tutorial_AVR.zip

  • Curtir 8
Link para o comentário
Compartilhar em outros sites

Pessoal,

Comprei um sensor baratinho ( R$ 13,00 ) de umidade do ar e temperatura, que é o DHT-11, chegou ontem, e não tive tempo de incluir o projetinho no tutorial.

Só depois que ele chegou é que ví que embora ele seja do tipo 1-Wire, o protocolo é proprietário, isto é, não segue nenhum padrão !!! Tive de baixar o PDF dele e procurar mais dicas na NET para fazer isso funcionar.....

Só agora conseguí terminar o projetinho, ficou simples e funcional; vou postar aqui o projetinho completo com o programa para quem precisar.

O esquema eletrônico é exatamente o mesmo que eu usei no Tutorial para o Controle de Cooler com 1-Wire, a única diferença é a troca do sensor pelo DHT-11.

Eu encontrei esse programa práticamente pronto na Net, reproduzo aqui , modificando para o meu caso, e acrescentei os comentários para explicar o programa. O site que encontrei foi o AVRproject.ru .

Mais informações sobre o funcionamento do DHT-11 no link abaixo :

http://embedded-lab.com/blog/?p=4333


$regfile = "m48pdef.dat"
$crystal = 8000000


Config Lcd = 16 * 2
Config Lcdpin = Pin , Rs = Portc.0 , E = Portc.1 , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5
Cursor Off
Cls


Declare Sub Get_th(t As Byte , H As Byte)

'vamos ligar o sensor no pino B.0
Dht_put Alias Portb.0 ' aqui usamos como saída
Dht_get Alias Pinb.0 ' e aqui usamos como entrada !
Dht_io_set Alias Ddrb.0 ' aqui mudamos entrada < - > saída

Dim T As Byte 'Temperatura
Dim H As Byte 'Umidade
Dim Crc As Byte 'CRC do medidor
Dim Mybyte As Byte
Dim Sensor_data As String * 40 'buffer para os 5 bytes
Dim Tmp_str8 As String * 8 'string temporária para receber 8 bits
Dim Count As Byte 'contador para os bits recebidos

Enable Interrupts

Set Dht_io_set
Set Dht_put

Lcd "AVRproject.ru"
Lowerline
Lcd "DHT11 sensor"

Do
Waitms 1500
Call Get_th(t , H)
Cls
Lcd "TMP: " ; T ; "C"
Lowerline
Lcd "PHP: " ; H ; "%"

Loop

Sub Get_th(t As Byte , H As Byte)

Count = 0
Sensor_data = ""
Set Dht_io_set 'vira saída
Reset Dht_put 'nivel 0 na saída
Waitms 25 'tempo de espera pro dht11 25mseg

Set Dht_put 'volta nivel 1 na saída
Waitus 40 'espera 40 useg
Reset Dht_io_set 'vira entrada
Waitus 40 'espera mais 40 useg
If Dht_get = 1 Then 'se continua 1 tem algo errado
H = 1 'pois deveria estar em 0 !
Exit Sub
End If


Waitus 80 'espera 80 useg
If Dht_get = 0 Then 'agora tem de estar 1 !
H = 2 'se tiver 0 , deu erro
Exit Sub
End If


While Dht_get = 1 : Wend 'espera iniciar transmissão

Do
While Dht_get = 0 : Wend 'começou a transmissão
Waitus 30 'voltou a nivel 1, espera 30 useg
If Dht_get = 1 Then 'se apos 30 useg continua 1, então o bit é 1
Sensor_data = Sensor_data + "1" 'coloca 1 no buffer de dados
While Dht_get = 1 : Wend 'espera esse bit 1 terminar
Else 'se apos 30 useg virou 0, então o bit é 0
Sensor_data = Sensor_data + "0" 'coloca zero no buffer
End If
Incr Count ' incrementa contador de bits
Loop Until Count = 40 ' repete para 40 bits totais

Set Dht_io_set
Set Dht_put



Tmp_str8 = Left(sensor_data , 8) 'os primeiros 8 bits são a umidade
H = Binval(tmp_str8) 'Vamos transformar para valor numérico

Tmp_str8 = Mid(sensor_data , 17 , 8) 'estes 8 são a temperatura
T = Binval(tmp_str8)

Tmp_str8 = Right(sensor_data , 8) 'os ultimos 8 são o CRC
Crc = Binval(tmp_str8) '


Mybyte = T + H ' o CRC é a soma da umidade + temperatura
If Mybyte <> Crc Then ' considerando 8 bits
H = 3 ' se não bateu, erro !
End If

End Sub 'final da subrotina




Paulo

Link para o comentário
Compartilhar em outros sites

Heheheh isso acontece.....

Pode desconsiderar o velho porque tudo o que tinha nele está também no novo, além de ter os programas-fontes e os arquivos de simulação tudo prontinhos prá rodar !!!!

Aquela sua aplicação, que voce disse no outro tópico, fica muito fácil de fazer em Basic mesmo, é só voce acompanhar o tutorial e estudar pelo menos uns 3 projetos do início, aí já dá para fazer o que voce precisa, ok ?

Aí, se voce resolver montar o projeto, pode tanto usar um protoboard maior e montar tudo inclusive a parte do microcontrolador, como comprar uma plataforma ARDUÍNO simples, eu recomendo o famoso Uno R3, barato e super-documentado com zilhões de aplicações na NET; aí voce só tem que mudar no BASCOM o tipo de processador, o clock utilizado, e as portas que voce quiser utilizar, e usa um pequeno protoboard externo só para montar os circuitinhos externos, ok ?

Para programar , voce usa o soquete ICSP de 6 pinos que tem em todos os Arduínos.

Todo o procedimento de gravação com o PROGISP está detalhado no tutorial, assim fica bem fácil começar !

Enfim, boa diversão !!!!

Paulo

Link para o comentário
Compartilhar em outros sites

Meu amigo, realmente é muitooooo fácil entender a programação em basic, se assemelha muito a programar em LEADER ( que faziamos no senai em CLPS).

Eu que não entendia nada de programação esse tutorial ja me deu bons conhecimentos só no 1º projeto, pisca led, questoes de definições, acredito que depois q aprender BASIC fica mais fácil de entender as outras linguagens de programação... vou continuar lendo o resto aqui.. mas até o momento ta de PARABENS pelo material, excelente, digno de muitos regradecimentos....

obrigado ai pela ajuda...

mais um comentario nao sei se poderia postar um link aqui mas beleza..

seguinte fiz um começo do programa em basic e coloquei no meu topico pra você ver...

porque falta resolver a charada de salvar o tempo na eeprom do avr, para q na promxima rotina ele pegue o ultimo tempo, se o tempo for diferente do ultimo tempo la constado,

ou seja, tem q calcular o tempo que ficou entrada em 1 e comparar com o tempo q ja estava gravado na eeprom, se for diferente substituir...

http://forum.clubedohardware.com.br/projeto-pic-avr/1036690

ai vai o link do meu topico q você esta me ajudadno.. obrigado..

Link para o comentário
Compartilhar em outros sites

Pessoal,

Acabei de receber um sensor de pressão barométrica relativamente barato,o BMP085 da BOSCH, paguei R$ 18,00 , vou fazer um programinha para ter um aparelho que mostre Pressão Atmosférica, Temperatura , Umidade Relativa do Ar e Ponto de Orvalho, para me ajudar nas minhas pescarias ...... até domingo postarei o projetinho.

Paulo

ATUALIZAÇÃO - Estou incluindo no Tutorial o uso do DHT-11, e também um projetinho simples de uso do BMP085, mostrando apenas a pressão e a temperatura. Motivo - o programa que fiz e vou postar aqui no tópico ficou grande demais, pois utilizei 3 sensores com interfaces diferentes para ilustrar um uso mais sofisticado do Bascom; e acabou precisando de um ATMEGA88 para caber tudo, mas a versão demo do Bascom não consegue compilar, pois passa de 4 Kb.

Porisso, estou fazendo esse novo projetinho apenas para o Tutorial, que irá permitir utilizar o ATMEGA48 e a versão demo do Bascom. Logo postarei o Tutorial Atualizado.

Link para o comentário
Compartilhar em outros sites

Pessoal, achei um Bug na simulação do Proteus 7. E é daqueles que deixa a gente doido !

Estava testando o novo projetinho do medidor de pressão, e como resolví fazer algo bem ilustrativo, estou usando 3 sensores ao mesmo tempo : o DS18B20 que é 1-Wire, o DHT-11 que é um tipo de 1-Wire proprietário, e o Bosh BMP085, que é I2C a 3.3 Volts.

Como o sensor de tensão é relativamente trabalhoso em termos de cálculos com ponto flutuante, o programa inteiro não coube mais no ATMEGA48 que estava utilizando.

Aí, como eu tinha um ATMEGA168, troquei o processador no programa, e continuei fazendo.

Logo de cara, compilei e carreguei no ISIS, apenas trocando o ATMEGA48 pelo ATMEGA168 . E a partir daí as leituras com o DS18B20 começaram a dar errado.

Bom, isso era sábado, umas 3 horas da tarde. Fiquei procurando um erro no programa até umas 7 horas da noite. E nada ! O pior é que o osciloscópio virtual , ligado na linha de dados do DS18B20, mostrava um sinal doido, que não tinha nada a ver.

Aí, começou o desespero. Mexí no programa, tirei pedaços e pedaços, até ficar quase idêntico ao programa do Tutorial, que utiliza o DS18S20. E continuava a doidera do sinal de dados.

Como não funcionava, já na madrugada, resolví pegar o programa do Tutorial, que utiliza o DS18S20, e troquei apenas o processador, para um ATMEGA168. Compilei, e quando fui simular no ISIS, aconteceu o mesmo erro que eu estava tendo no novo programa !

Resolví tirar a dúvida, troquei no programa pelo ATMEGA168P , e o erro permaneceu.

Mas .... quando troquei para o ATMEGA88, funcionou direitinho novamente.....

Mudei novamente para o ATMEGA328, e também funcionou direitinho.

Resolví testar mais : troquei a porta onde o DS18S20 estava ligado, recompilei, e não adiantou nada. O erro continuava dando APENAS no ATMEGA168 e ATMEGA168P !

Resolví tirar a prova dos nove : Montei o circuito real no protoboard, primeiro com o ATMEGA48P , e funcionou direitinho.

Aí, recompilei o programa para o ATMEGA168 que tenho, gravei, e coloquei no protoboard. Advinhem : também funcionou direitinho !

Ou seja, o problema não é o ATMEGA168, e nem com o compilador BASCOM, pois o hardware real funciona, mesmo com a simulação do ISIS dizendo que não funcionaria...

O problema está no modelo do ATMEGA168 e no ATMEGA168P do PROTEUS.

Como dica, fiz um teste que funcionou direitinho :

No ISIS, padronizei o processador ATMEGA328, pois consigo carregar nele sem nenhum problema os programas compilados para os ATMEGA48, ATMEGA88 e ATMEGA168. Não preciso alterar nada , é só simular e pronto !

CUIDADO COM O MODELO DO ATMEGA168 e ATMEGA168P.

 

Obs : bug foi corrigido na versão 8 do Proteus !

 

Paulo

Link para o comentário
Compartilhar em outros sites

Pessoal,

Segue o programa que fiz para utilizar o BMP085 . É um programa que permite o uso bem sofisticado dos 3 sensores envolvidos, e mostra 4 informações diferentes. Já está compensado para a altura média na cidade de São Paulo, mostrando a pressão relativa ao nível do mar para facilitar a interpretação da variação de pressão.

Segue o esquema do circuito :

teste_CH.png

Segue o programa :


' ----------------------------------------------------------------
' ESTAÇÃO METEOROLÓGICA COMPENSADA
'
' Permite obter a Temperatura Real, a Umidade Real,
' a Temperatura do Ponto de Orvalho Real, e finalmente
' obtém a Pressão Real Relativa ao Nível do Mar.
' Para a medida de pressão, levewi em conta a elevação em minha
' residência, que é de 746 metros acima do nível do mar.
'
' E estou usando para monitorar as minhas pescas !!!
'
' Embora não fosse necessário utilizar o DS18B20, pois o DHT11 faz
' as medidas de Umidade e Temperatura, acabei utilizando para
' demonstrar o poder do Bascom, ao utilizar 3 interfaces diferentes
' ao mesmo tempo. E a segunda razão é que o sensor DHT11 não é preciso
' nas leituras de temperatura, tendo uma variação muito maior do que o
' DS18B20. Mesmo assim, poderia utilizar a temperatura do sensor
' BMP085, que mede tanto a pressão como a temperatura com uma boa
' precisão. Mas ..... pelo bem da didática, usei os 3 sensores !
'
' Este programa é um apanhado dos programas anteriores do Tutorial
' sobre o uso do DS1820 e DHT11 ( este está aqui no tópico mesmo )
' e usei boa parte do código feito por um usuário do Fórum do BASCOM
' para tratar o BMP085, mas o código dele contém um erro, e eu já
' corrigí aqui nesta versão.
' Como uma boa dica , ilustro o uso do I2C sem os resistores de
' PULL-UP internos , assim posso utilizar dois resistores de
' PULL-UP externos, mas ligados à alimentação do sensor BMP085
' que é de aproximadamente 3.3 Volts, assim elimino qualquer
' tipo de circuito conversor de nível de tensão entre 5V e 3.3V .
' Vale lembrar que este truque só funciona para velocidades baixas
' de I2C, abaixo de 200 Khz, que é o padrão do BASCOM.
' Lembrando que o BASCOM pode mudar a velocidade do I2C, indo desde
' os famosos 10Khz para até 500 Khz sem dificuldade.
' ----------------------------------------------------------------

$regfile = "m88Pdef.dat"

$crystal = 8000000


$hwstack = 40
$swstack = 16
$framesize = 32

Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 16 * 2
Config 1wire = Portc.0 ' DS18B20 on pin 12
Config Sda = Portc.4 ' BMP 085 Sensor de pressão I2C
Config Scl = Portc.5

Declare Sub Read1820

Declare Sub Temperature
Declare Sub Orvalho
Declare Sub Get_th(t As Byte , H As Byte)


'vamos ligar o sensor DHT-11 no pino PORTC.2

Dht_put Alias Portc.2 ' aqui usamos como saída
Dht_get Alias Pinc.2 ' e aqui usamos como entrada !
Dht_io_set Alias Ddrc.2 ' aqui mudamos entrada < - > saída

Portc.4 = 0 ' Truque para desabilitar o Pull-Up interno
Portc.5 = 0 ' Assim não precisamos converter de 3.3 para 5V

Dim Tdht As Byte 'Temperatura
Dim Hdht As Byte 'Umidade
Dim Crc As Byte 'CRC do medidor
Dim Mybyte As Byte
Dim Sensor_data As String * 40 'buffer para os 5 bytes
Dim Tmp_str8 As String * 8 'string temporária para receber 8 bits
Dim Count As Byte 'contador para os bits recebidos


Dim Bd(9) As Byte
Dim I As Byte , Tmp As Byte
Dim Tempc As Single , T1 As Single

Const Bmp085_read = &HEF 'BMP085 Read Address
Const Bmp085_write = &HEE 'BMP085 Write Address

'---BMP085 Variables------------------------------------------------------------

Dim I2c_send_buf(5) As Byte
Dim I2c_receive_buf(5) As Byte


'Calibration data variables
'Overlay used for easy access

Dim Calibration_data(22) As Byte
Dim Ac1 As Integer At Calibration_data(1) Overlay
Dim Ac2 As Integer At Calibration_data(1) + 2 Overlay
Dim Ac3 As Integer At Calibration_data(1) + 4 Overlay
Dim Ac4 As Word At Calibration_data(1) + 6 Overlay
Dim Ac5 As Word At Calibration_data(1) + 8 Overlay
Dim Ac6 As Word At Calibration_data(1) + 10 Overlay
Dim B1 As Integer At Calibration_data(1) + 12 Overlay
Dim B2 As Integer At Calibration_data(1) + 14 Overlay
Dim Mb As Integer At Calibration_data(1) + 16 Overlay
Dim Mc As Integer At Calibration_data(1) + 18 Overlay
Dim Md As Integer At Calibration_data(1) + 20 Overlay

' --------------------------------------------
' | | | Temp_high | Temp_low | Type: LONG
' --------------------------------------------
Dim U_temperatur As Long
Dim U_temp_low As Byte At U_temperatur Overlay
Dim U_temp_high As Byte At U_temperatur + 1 Overlay

Dim X1 As Long ' variáveis auxiliares para cáculos BMP085
Dim X21 As Long
Dim X22 As Long
Dim X2 As Long
Dim B5 As Long

Dim T As Long
Dim Temperatur As String * 6

' ---------------------------------------------------------------------
' | | U_pressure_high | U_pressure_mid | U_pressure_low | Type: LONG
' ---------------------------------------------------------------------

Dim U_pressure As Long
Dim U_pressure_low As Byte At U_pressure Overlay
Dim U_pressure_mid As Byte At U_pressure + 1 Overlay
Dim U_pressure_high As Byte At U_pressure + 2 Overlay



Dim B6 As Long 'mais variáveis auxiliares BMP085
Dim X3 As Long
Dim B3 As Long

Dim Oss As Word ' will be set in Sub Bmp085_initiate_measurement(byval Measurement_type As Byte)

Dim B4 As Dword ' mais variáveis auxiliares BMP085
Dim B7 As Dword
Dim P As Long
Dim Pcomp As Single
Dim Pvarx As Single
Dim Pressure As String * 6
Dim Ph As Long

'absolute altitude
'Dim Altitude_var1 As Single
'Dim Altitude As Single
'Dim P_single As Single
'Const Pressure_at_see_level = 101325 ' Pa

Dim X As Byte
Dim Idw As Dword

'-----BMP085 SUB's--------------------------------------------------------------
Declare Sub Bmp085_read_calibration_data()
Declare Sub Bmp085_initiate_measurement(byval Measurement_type As Byte)
'Measurement_type = 1 --> Temparature Measurement
'Measurement_type = 2 --> Ultra Low Power Pressure Measurement (OSS = 0)
'Measurement_type = 3 --> Standard Pressure Measurement (OSS = 1)
'Measurement_type = 4 --> High Resolution Pressure Measurement (OSS = 2)
'Measurement_type = 5 --> Ultra High Resolution Pressure Measurement (OSS = 3)

Declare Sub Bmp085_read_u_temp() 'Read uncompensated Temp Value
Declare Sub Bmp085_read_u_press() 'Read uncompensated Pressure Value
Declare Sub Bmp085_calc_temp() 'Calculate Temperature
Declare Sub Bmp085_calc_pressure()
Declare Sub Bmp085_absolute_altitude()


Cursor Off Noblink
Cls

Locate 1 , 1 : Lcd "BAROMETRO PESCAS"

Set Dht_io_set ' prepara interface com o DHT-11
Set Dht_put
I2cinit ' Inicializa bus I2C, mas com PULL-UP Interno !
Portc.4 = 0 ' temos de desativar eles novamente !
Portc.5 = 0 ' assim protegemos nosso sensor que usa 3.3 V !

' Vamos ler os dados de calibração do BMP 085
Call Bmp085_read_calibration_data()

Do
Temperature ' leitura precisa de temperatura do DS18B20
Waitms 2000

Call Get_th(tdht , Hdht) ' leitura precisa de umidade do DHT-11

' Agora, vamos medir a pressão do BMP085. Para isso :
' É bem complicado, temos primeiro de ler a temperatura sem compensação
' e depois calcular a compensação !
Call Bmp085_initiate_measurement(1) '1 = Temperatur Measurement
Call Bmp085_read_u_temp()
Call Bmp085_calc_temp() 'Calculate Compensated Temperature
'Temperatur = Str(t)

' Agora, vamos medir a pressão sem compensação , e depois calcular a
' compensação, com cálculos bem chatinhos !

Call Bmp085_initiate_measurement(5) 'Very High Resolution Pressure Measurement (OSS=3)
' ^ type in Measurement_type !!!! <<<<<----------------------------------------
Call Bmp085_read_u_press()
Call Bmp085_calc_pressure()

' Agora, temos tudo para calcular o Ponto de Orvalho
Call Orvalho
' Pronto, tudo calculado , é só mostrar !
Cls
Locate 1 , 1
Lcd "T= O= " ' Temperatura e Orvalho na primeira linha
Locate 1 , 3
Lcd Fusing(tempc , "##.#")
Locate 1 , 10
Lcd Fusing(pcomp , "##.#")
Locate 1 , 15
Lcd Chr(223) ; "C"
Locate 2 , 1
Lcd "P= U=" ' Pressão Corrigida E Umidade Na Segunda
Locate 2 , 3
Lcd Ph
Lcd "mB"
Locate 2 , 12
Lcd Hdht
Lcd " %"
Loop

End


'//////////////////////////////////////////////////////////////////////////////
Sub Temperature ' actual measuring
1wreset
1wwrite &HCC
1wwrite &H44 ' start measure

Waitms 1000
Read1820 ' read 9 bytes
End Sub

'//////////////////////////////////////////////////////////////////////////////
Sub Read1820 ' reads sensor ans calculate
' T for 0.1 C
1wreset ' reset the bus
1wwrite &HCC ' read internal RAM
1wwrite &HBE ' read 9 data bytest
Bd(1) = 1wread(9)
Waitms 1
1wreset ' reset the bus


Bd(6) = Bd(2) And &B10000000 ' não usamos para nada mesmo ....
Tmp = Bd(1) And &B00001111
T1 = Tmp / 16
Bd(1) = Bd(1) And &B11110000
Bd(1) = Bd(1) / 16
Bd(2) = Bd(2) And &B00000111
Bd(2) = Bd(2) * 16
Tempc = Bd(1) + Bd(2)
Tempc = Tempc + T1

If Bd(6) = 128 Then
Tempc = Tempc - 256
Else
End If

End Sub

'--------------------------------------------------------------------------------------
' SUB-ROTINA PARA LER O DHT-11
Sub Get_th(tdht As Byte , Hdht As Byte)

Count = 0
Sensor_data = ""
Set Dht_io_set 'vira saída
Reset Dht_put 'nivel 0 na saída
Waitms 25 'tempo de espera pro dht11 25mseg

Set Dht_put 'volta nivel 1 na saída
Waitus 40 'espera 40 useg
Reset Dht_io_set 'vira entrada
Waitus 40 'espera mais 40 useg
If Dht_get = 1 Then 'se continua 1 tem algo errado
Hdht = 1 'pois deveria estar em 0 !
Exit Sub
End If

Waitus 80 'espera 80 useg
If Dht_get = 0 Then 'agora tem de estar 1 !
Hdht = 2 'se tiver 0 , deu erro
Exit Sub
End If

While Dht_get = 1 : Wend 'espera iniciar transmissão

Do
While Dht_get = 0 : Wend 'começou a transmissão
Waitus 30 'voltou a nivel 1, espera 30 useg
If Dht_get = 1 Then 'se apos 30 useg continua 1, então o bit é 1
Sensor_data = Sensor_data + "1" 'coloca 1 no buffer de dados
While Dht_get = 1 : Wend 'espera esse bit 1 terminar
Else 'se apos 30 useg virou 0, então o bit é 0
Sensor_data = Sensor_data + "0" 'coloca zero no buffer
End If
Incr Count ' incrementa contador de bits
Loop Until Count = 40 ' repete para 40 bits totais

Set Dht_io_set
Set Dht_put


Tmp_str8 = Left(sensor_data , 8) 'os primeiros 8 bits são a umidade
Hdht = Binval(tmp_str8) 'Vamos transformar para valor numérico

Tmp_str8 = Mid(sensor_data , 17 , 8) 'os próximos 8 são a temperatura
Tdht = Binval(tmp_str8)

Tmp_str8 = Right(sensor_data , 8) 'os ultimos 8 são o CRC
Crc = Binval(tmp_str8) '


Mybyte = Tdht + Hdht ' o CRC é a soma da umidade + temperatura
If Mybyte <> Crc Then ' considerando 8 bits
Hdht = 3 ' se não bateu, erro !
End If

End Sub 'final da subrotina


'--------------------------------------------------------------------------------------
'subrotina para ler o sensor de pressão BMP085

Sub Bmp085_read_calibration_data()

'Read Calibration Data from Sensor (11x 16Bit Values)

'for optional Error checking --> None of the Values are &H0000 or &HFFFF
Calibration_data(1) = &HAA
I2creceive Bmp085_write , Calibration_data(1) , 1 , 22

'We need to swap High Byte with Low Byte of all integers
Swap Ac1
Swap Ac2
Swap Ac3
Swap Ac4
Swap Ac5
Swap Ac6

Swap B1
Swap B2
Swap Mb
Swap Mc
Swap Md

End Sub

'-------------------------------------------------------------------------------------------------------

Sub Bmp085_initiate_measurement(byval Measurement_type As Byte)
Local M_type As Byte , Wait_time As Byte

If Measurement_type < 1 Or Measurement_type > 5 Then
Ac1 = Ac1 ' achei melhor por alguma coisa do que deixar vazio
Else

Select Case Measurement_type
Case 1: '1 = Temparature Measurement
M_type = &H2E
Wait_time = 5 'ms

Case 2:
M_type = &H34 '2 = Ultra Low Power Pressure Measurement (OSS = 0)
Wait_time = 5 'ms
Oss = 0
Case 3:
M_type = &H74 '3 = Standard Pressure Measurement (OSS = 1)
Wait_time = 8 'ms
Oss = 1
Case 4:
M_type = &HB4 '4 = High Resolution Pressure Measurement (OSS = 2)
Wait_time = 14 'ms
Oss = 2
Case 5:
M_type = &HF4 '5 =Ultra High Resolution Pressure Measurement (OSS = 3)
Wait_time = 26 'ms
Oss = 3
End Select


I2cstart
I2cwbyte Bmp085_write
I2cwbyte &HF4
I2cwbyte M_type
I2cstop

'Wait_time = between 5 and 26ms depending on above selected measurement method
Waitms Wait_time

End If 'If Measurement_type < 1 Or Measurement_type > 5 Then


End Sub

'----------------------------------------------------------------------------------------------------
Sub Bmp085_read_u_temp()

I2cstart
I2cwbyte Bmp085_write
I2cwbyte &HF6

I2crepstart
I2cwbyte Bmp085_read
I2crbyte U_temp_high , Ack
I2crbyte U_temp_low , Nack
I2cstop

End Sub

'----------------------------------------------------------------------------------------------------

Sub Bmp085_read_u_press()

I2c_receive_buf(1) = &HF6

I2creceive Bmp085_write , I2c_receive_buf(1) , 1 , 3
U_pressure_high = I2c_receive_buf(1)
U_pressure_mid = I2c_receive_buf(2)
U_pressure_low = I2c_receive_buf(3)

Select Case Oss
Case 0:
Shift U_pressure , Right , 8
Case 1:
Shift U_pressure , Right , 7
Case 2:
Shift U_pressure , Right , 6
Case 3:
Shift U_pressure , Right , 5
End Select

End Sub

'---------------------------------------------------------------------------------------
Sub Bmp085_calc_temp()

' Calculate true Temperature

'X1 =
X1 = U_temperatur - Ac6

X1 = X1 * Ac5
Shift X1 , Right , 15

'X2 =
X21 = X1 + Md
X22 = 2 ^ 11
X22 = X22 * Mc
X2 = X22 \ X21 'Integer division is denoted by the backslash (\).


'B5 =
B5 = X1 + X2


'T =
T = B5 + 8
Shift T , Right , 4 '4

End Sub




'----------------------------------------------------------------------------------------
Sub Bmp085_calc_pressure()
' Calculate true pressure
B6 = B5 - 4000

'X1 =
X21 = 2 ^ 12
X22 = B6 * B6
X1 = X22 \ X21
X1 = X1 * B2
Shift X1 , Right , 11

'X2 =
X21 = 2 ^ 11
X22 = Ac2 * B6
X2 = X22 \ X21

'X3 =
X3 = X1 + X2


'B3 =
X21 = Ac1 * 4
X22 = X21 + X3

Shift X22 , Left , Oss
X22 = X22 + 2

B3 = X22 \ 4

'X1 =
X21 = 2 ^ 13
X22 = Ac3 * B6
X1 = X22 \ X21

'X2 =
X21 = 2 ^ 12
X2 = B6 * B6
X2 = X2 \ X21
X2 = B1 * X2
Shift X2 , Right , 16

'X3 =
X21 = 2 ^ 2
X3 = X1 + X2
X3 = X3 + 2
X3 = X3 \ X21

'B4 =
B4 = X3 + 32768
B4 = Ac4 * B4
Shift B4 , Right , 15



'B7 =
X21 = 50000
Shift X21 , Right , Oss
B7 = U_pressure - B3
B7 = B7 * X21

If B7 < &H80000000 Then
Idw = B7 * 2
Idw = Idw \ B4
P = Idw
Else
Idw = B7 \ B4
Idw = P * 2
P = Idw
End If

'X1 =
X21 = 2 ^ 8
X1 = P \ X21
X1 = X1 * X1

'X1 =
X21 = 2 ^ 16
X1 = X1 * 3038
X1 = X1 \ X21

'X2 =
X21 = 2 ^ 16
X2 = -7357 * P
X2 = X2 \ X21

'p =
X21 = 2 ^ 4
X22 = X1 + X2
X22 = X22 + 3791
X22 = X22 \ X21
P = P + X22

Pcomp = P * 1.0896 'FATOR CORREÇÃO PARA ALTURA=746 MTS
P = Pcomp

Ph = P \ 100

End Sub


'------------------------------------------------------------------------------
Sub Orvalho
' CALCULA O PONTO DE ORVALHO
'Vamos usar a mesma variável real Pcomp para economizar ...

Pcomp = Hdht / 100
Pcomp = Pcomp ^ 0.125
Pvarx = Tempc * 0.9
Pvarx = Pvarx + 112
Pcomp = Pvarx * Pcomp
Pvarx = 0.1 * Tempc
Pcomp = Pcomp + Pvarx
Pcomp = Pcomp - 112


End Sub

Paulo

Link para o comentário
Compartilhar em outros sites

Pessoal,

Acabei de colocar para download uma atualização do tutorial, com mais projetos e dicas de utilização para componentes mais "especiais" , como sensores de pressão, sensores de umidade, etc.

Por favor, baixem a nova versão, que já chegou a 169 páginas ....

É o mesmo link que está no primeiro post do tópico.

Boa diversão !

Paulo

Link para o comentário
Compartilhar em outros sites

  • 2 meses depois...

Parabens. Este é o melhor tutorial para AVR que eu ja encontrei. Fácil de entender com muitos exemplos práticos e úteis.

Deveria escrever um livro sobre o assunto!!

Pessoal,

Segue um novo tutorial, orientado para os principiantes, sobre o uso de microcontroladores AVR em vários tipos de projetos.

Apresento os programas-fontes, os objetos da compilação, e os arquivos de simulação do ISIS, tudo incluído para facilitar.

Lembro aqui que podem ser utilizadas as plataformas ARDUÍNO, bastando adequar os esquemas para o hardware escolhido !

O foco foi dado em dicas de Design, Programação em Basic do BASCOM, e Simulação dos projetos, utilizando o ISIS do PROTEUS.

Assim, fica bem mais fácil para todos fazerem os seus projetos, e rodar a simulação no ISIS, antes de partir para a montagem física.

Este novo tutorial é uma evolução natural do antigo tutorial escrito por mim faz algum temo, e este novo substitui totalmente o antigo.

Importante -> Acabei de colocar uma versão atualizada, com projetos utilizando sensores de Umidade e de Pressão, bem como utilização de componentes 1-WIRE e I2C com tensões diferentes à do AVR. Esta nova versão tem agora 169 páginas .....

Segue o link para o download :

http://www.4shared.com/rar/x8u4oNuF/Tutorial_AVR.html

Boa diversão e um excelente aprendizado a todos.

Paulo

Link para o comentário
Compartilhar em outros sites

Oi Jagoris, obrigado pelo elogio !

Conforme eu vou encontrando problemas, vou solucionando e tento passar essa experiência para quem está iniciando. Ainda acredito que o velho Basic facilita muito o entendimento, e vou continuar postando mais dicas por aqui, ok ?

Quanto a escrever um livro... Só de pensar eu fico cansado hehehehe !

Mais uma vez, obrigado e espero que esses tutoriais lhe sejam muito úteis.

Aproveitando a resposta,

Pessoal, recentemente eu comprei um rotary switch ( também conhecido como Encoder ) , e levei uma baita surra dele ....

O Bascom tem uma função própria para ler esse rotary, que é a função Encoder() .

Mas não consegui fazer funcionar direito. Fui a uma outra loja e comprei um outro encoder, diferente do primeiro. E o resultado continuou o mesmo : nada !

Finalmente, encontrei um encoder igual ao que a Sparkfun vende, e novamente não funcionou. O gozado era que cada um deles tinha um funcionamento diferente dos outros, mesmo sendo todos errados.

Fui pesquisar nos fóruns do Bascom, e ví que muita gente reclamava que também não conseguiam fazer funcionar.

Pesquisando mais, achei um site onde um cara escreveu uma rotina em C que ele afirmava funcionar perfeitamente, mesmo em alta velocidade.

Estudei o funcionamento da rotina dele, e fiz uma rotina no Bascom baseado na rotina do cara, e não é que funcionou com TODOS os meus 3 encoders diferentes ????

A rotina nova será detalhada no próximo post.

 

Paulo

Link para o comentário
Compartilhar em outros sites

Algo que é pouco divulgado é que podemos usar o BASCOM como um IDE de desenvolvimento com a plataforma Arduíno !

Se configurarmos diretinho o tipo de programador do BASCOM, utilizando o AVRDUDE presente na IDE do Arduíno, podemos fazer o programa no BASCOM, compilar e passar para o Arduino e utilizando o terminal serial do Bascom, podemos interagir com o nosso programa !

Para isso, temos de dizer ao BASCOM que deve gerar o nosso programa para rodar através do BOOTLOADER do Arduíno, e isso é um endereço que varia conforme o Arduíno utilizado !

Para o Arduino que eu uso, que é o UNO Rev 3, o endereço de carregamento é o $H200. Basta informar isto ao compilador pela diretiva $loadersize, conforme o programa apresentado aqui abaixo.

Antes da listagem, se voce leu o post acima, vai ver que eu adaptei um programa em C para rodar no Bascom, e desta maneira conseguí fazer com que os três modelos diferentes de Rotary Encoder que comprei funcionassem sem problema.

Para isto, uso três pinos do Arduíno, e programo a interrupção por mudança de nível nesses 3 pinos, e trato a interrupção. Só tem um probleminha ao fazer isto : o que eu preciso é apenas uma interrupção que funcione na DESCIDA do sinal, portanto eu preciso checar para ver se a interrupção gerada foi por uma descida ou por uma subida; se foi subida, eu simplesmente ignoro !

Desta maneira, voce pode utilizar interrupções EM QUASE TODO PINO DE I/O dos ATMEGA, simplesmente habilitando os pinos desejados e as PCINT's correspondentes a esses pinos, e na rotina de tratamento, filtrar de alguma maneira qual é a interrupção que voce quer tratar.

No meu caso, eu simplesmente guardo o estado dos pinos ANTES de uma interrupção, e quando ela ocorre, eu leio novamente o estado dos pinos e comparo com o anterior ! Assim fica simples detectar, certo ?

Segue o programa :


'-------------------------------------------------------------------------------
' usando um ARDUINO UNO R3 para mostrar o funcionamento
' ligamos o rotary aos pinos ANALOG 0,1 e 2 do Arduino, sendo :
' Pino A0= botão do Rotary
' Pinos A1 e A2 = Sinais de direção do Rotary
' e por ultimo, o pino comum do rotary ligar ao terra

$regfile = "m328pdef.dat" ' MICRO uno
$crystal = 16000000 ' xtal uno
$baud = 9600 ' baud rate
'-------------------------------------------------------------------------------

$loadersize = &H200

Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Serialin = Buffered , Size = 250
Config Serialout = Buffered , Size = 50

Dim X_enc As Byte
Dim Dado As Byte
Dim Old_val As Byte
Dim Flag_enc_novo As Bit
Dim Flag_enc_apert As Bit
Dim Half_left As Bit
Dim Half_right As Bit
Dim Flag_dir_h As Bit


Config Pinc.0 = Input
Config Pinc.1 = Input
Config Pinc.2 = Input
Rotaryp0 Alias Pinc.2 ' um pino do rotary switch
Rotaryp1 Alias Pinc.1 ' outro pino do rotary switch
Rotarypb Alias Pinc.0 'pino do botão do rotary switch
' o pino comum do rotary switch é ligado ao terra !


Set Rotaryp0 'liga resistor pull-up
Set Rotaryp1
Set Rotarypb


X_enc = 0
Dado = Pinc
Old_val = Dado
Pcmsk1 = &B00000111 ' enable pin change interrupt em pinC.0 - pinC.2
Pcicr.1 = 1 ' enable PCINT1 vector
On Pcint1 Isr_pcint1_encoder ' define a ISR para tratar
Enable Pcint1
Enable Interrupts 'pronto, ints estão ligadas

'agora é só esperar pelos flags setados pela interrupção
Do
If Flag_enc_novo = 1 Then ' temos rotação ?
If Flag_dir_h = 1 Then
Print X_enc ; " direita"
Else
Print X_enc ; " esquerda"
End If
Flag_enc_novo = 0 'já mostramos, resetar
End If
If Flag_enc_apert = 1 Then 'temos botão apertado ?
Print "Encoder Apertado"
Flag_enc_apert = 0 'já mostramos, resetar
End If
Loop




' ISR on PCINT1 for encoder status changes
Isr_pcint1_encoder:

Dado = Pinc 'novo valor nas entradas c
' VAMOS TESTAR SE FOI POR DESCIDA DE NÍVEL
If Old_val.2 = 1 And Dado.2 = 0 Then
Goto A_pin2
End If
If Old_val.1 = 1 And Dado.1 = 0 Then
Goto A_pin1
End If
If Old_val.0 = 1 And Dado.0 = 0 Then
Goto A_pinb
End If
' SE FOI POR SUBIDA ATUALIZAR VALOR E TERMINAR
If Old_val.2 = 0 And Dado.2 = 1 Then
Old_val.2 = 1
Goto Isr1_fim
End If
If Old_val.1 = 0 And Dado.1 = 1 Then
Old_val.1 = 1
Goto Isr1_fim
End If
If Old_val.0 = 0 And Dado.0 = 1 Then
Old_val.0 = 1
Waitms 5
End If
Isr1_fim:
Return

'TRATAMENTO DOS PINOS MUDADOS PELO ENCODER
A_pin1:
Waitms 1
If Rotaryp1 = 0 Then
If Rotaryp0 = 1 And Half_right = 0 Then
Set Half_right
End If
If Rotaryp0 = 0 And Half_left = 1 Then
Reset Half_left
Decr X_enc
Reset Flag_dir_h
Set Flag_enc_novo
End If
Old_val.1 = 0
End If
Goto Isr1_fim

A_pin2:
Waitms 1
If Rotaryp0 = 0 Then
If Rotaryp1 = 1 And Half_left = 0 Then
Set Half_left
End If
If Rotaryp1 = 0 And Half_right = 1 Then
Reset Half_right
Incr X_enc
Set Flag_dir_h
Set Flag_enc_novo
End If
Old_val.2 = 0
End If
Goto Isr1_fim

A_pinb:
Set Flag_enc_apert ' encoder apertado
Waitms 5
Old_val.0 = 0
Goto Isr1_fim

End

Boa diversão !

Paulo

Link para o comentário
Compartilhar em outros sites

Pessoal, recentemente peguei um sensor de ultrasom desses disponíveis no Mercado Livre ou no EBAY, o HC-SR04 .

Falam tão bem deles que comprei duas peças, e chegaram ontem.

Hoje, usei o IDE do Arduíno, montei exatamente seguindo os posts de quem já tinha usado, e me decepcionei com o resultado.

As medidas de distância eram bem fora da realidade, com erros acima de 15% !

Troquei o sensor pelo outro, e as medidas continuaram malucas.

Como não entendo patavina nenhuma de C, não adiantava nada insistir ...

Aí, resolví ir para o campo que domino, que é o Basic do Bascom, e ver se conseguia um resultado melhor do que usando a IDE do Arduíno.

Esses sensores de ultrasom funcionam asim : damos um pulso de início no pino de Trigger, e na saída ECHO teremos um pulso positivo, cuja duração em microsegundos é exatamente o tempo que demorou para o som voltar refletido pelo objeto. Simples demais para dar errado !

Aí, olhando o Datasheet, ele tem a seguinte fórmula : dividindo o tempo desse pulso em microsegundos por 58 já dá o resultado em centímetros !

Tentei usar essa fórmula primeiro, e nada, continuava errado.

 

Começei a pensar no funcionamento do programa :

Clock do Arduíno Uno = 16 Mhz.

 

Tempo a ser gerado pela rotina de Timer, para servir como base de tempo : 1 microsegundo ....

Pera aí ..... isso quer dizer UMA interrupção de Timer a cada 16 ciclos de clock ..... só o tempo necessário para atender a interrupção e salvar o contexto já é maior do que 20 ciclos de clock, essa base de tempo ia ficar totalmente errada !

 

Então pensei que seria melhor usar uma base de tempo de 10 microsegundos, teria 160 ciclos de clock entre duas interrupçoes do Timer.

Isso daria tempo para fazer tudo. ( depois percebí que não ..... )

 

Então, fiz o programa, usando o TIMER1 para gerar a base de tempo de 10 microsegundos.

E o resultado das medidas continuou totalmente errado, mais de 40% de erro agora ....

 

Me lembrei que a velocidade do som é 340 m/seg AO NIVEL DO MAR ! Como estou a 750 metros de altitude, deve ser outro valor. Pesquisando na Internet, achei uma fórmula, e o resultado é de 338 metros por segundo...

A diferença é muito pequena, mas mesmo assim mudei o programa para esse valor.

 

O erro continuava enorme ....

 

Aí bateu um pouco luz .... troquei a base de tempo para 100 microsegundos, e não é que o erro diminuiu prá menos de 10% !!!

 

Imaginei que os erros de tempo entre atender a interrupção, incrementar a variável de tempo, repor o valor do timer1 e sair da interrupção estavam fazendo com que o tempo fosse maior do que os 10 microsegundos que eu tinha planejado.

 

Então, usei o osciloscópio digital para medir o tempo Exato do TIMER1, e adivinhe só : em vez de 10 microsegundos, media sempre algo entre 15 e 16 microsegundos ! Isto se deve ao Bascom salvar vários registradores na entrada e na saída da interrupção, e isso consome tempo !

Existe uma opção NOSAVE na declaração da interrupção, mas ela não pode ser utilizada quando a interrupção faz algumas coisas complexas. Até poderia ter utilizado, mas preferi a maneira da gambiarra !

 

Então, resolvi fazer a velha "abordagem empírica" : fui mudando o valor de TIMER1 , até que o tempo chegasse em 10 microsegundos !

 

Acabei usando um valor 8 unidades maior do que o calculado, e gerava um tempo um pouquinho só maior do que os 10 microsegundos.

 

Na verdade, medindo na tela do osciloscópio, tinha 8,15 divisões quando deveria ter 8 divisões exatas, então introduzi no cálculo de tempo uma correção usando esses valores.

 

Após tudo isso feito, conseguí a precisão que queria !

 

Uma distância exata de 114 centímetros, e a medida resultante foi de 113,8 !

Aí, fui para o outro extremo : Uma distância exata de 15 centímetros resultou na medida de 15,1 !

Como o sensor tem precisão de 0,3 centímetros, para mim está ótimo !

 

Segue o programa feito , para que vocês possam montar esse sensorzinho, que realmente funciona muito bem !

 

 
'-------------------------------------------------------------------------------
' usando um ARDUINO UNO R3 para mostrar o funcionamento do HC-SR04
' SENSOR ULTRA-SONICO HC-SR04
' Trigger - ligado no pino DIGITAL 2
' Echo - ligado no pino DIGITAL 3


$regfile = "m328pdef.dat"               ' MICRO uno
$crystal = 16000000                     ' xtal uno
$baud = 9600                            ' baud rate
'-------------------------------------------------------------------------------

$loadersize = &H200

$hwstack = 32
$swstack = 32
$framesize = 32

Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Dim X As Byte
Dim Tempo As Word
Dim T_mat(4) As Word
Dim Dist As Single
Dim Dist1 As Single

Config Portd.2 = Output
Config Pind.3 = Input

Set Pind.3                              ' LIGA PULL-UP
' VAMOS ESPERAR O SENSOR ESTABILIZAR, E DEPOIS MANDAR O PULSO DE TRIGGER
Portd.2 = 0
Waitms 100
Tempo = 0

' E VAMOS PREPARAR UM TIMER PARA TERMOS CONTAGEM A CADA 10 MICROSEGUNDOS (UAU)
Config Timer1 = Timer , Prescale = 8

' VALOR DE TIMER1 OBTIDO EXPERIMENTALMENTE COM OSCILOSCÓPIO DIGITAL !
' POIS O CALCULADO ERA   65516 PARA 10 MICROSEGUNDOS , MAS VAMOS USAR 65524 !
' A LATENCIA DA INTERRUPÇÃO DO TIMER1 , BEM COMO SALVAR OS
' REGISTRADORES, GASTA A DIFERENÇA DE +- 8 * 8 = 64 CICLOS DE CLOCK !
' AINDA FICA UM PEQUENO ERRO, POIS TENTEI 65525 E FICOU PIOR QUE 65524
' VOU ACERTAR ESSE TEMPO EXATO ABAIXO !
' REPAREM O FATOR 815 E 800 .....

Timer1 = 65524

On Timer1 Sample_isr Nosave             'DIMINUIR A LATENCIA ...
Enable Timer1
Enable Interrupts
Stop Timer1


Do
'VAMOS MEDIR 4 VEZES E FAZER A MÉDIA
For X = 1 To 4
   Portd.2 = 1
' AQUI GERAMOS O TRIGGER DE 10 MICROSEGUNDOS APROXIMADO
   Waitus 10
   Portd.2 = 0
   Tempo = 0
   Espera:
   If Pind.3 = 0 Then Goto Espera
   Start Timer1
   Espera1:
   If Pind.3 = 1 Then Goto Espera1
   Stop Timer1
'  SE NÃO VEIO ECO DENTRO DO ESPERADO, DEFINIR LIMITE DE +- 4 METROS
   If Tempo > 2400 Then Tempo = 2400
' FATOR DE CORREÇAO OBTIDO EXPERIMENTALMENTE MEDINDO O TEMPO
' EXATO DO TIMER1 COM UM OSCILOSCÓPIO DIGITAL
' TINHA 8,15 DIVISÕES QUANDO DEVERIA TER 8 EXATAS !!!
   Dist = Tempo * 815
   Dist = Dist / 800
   Tempo = Dist
   T_mat(x) = Tempo
   Waitms 50
Next X
Tempo = T_mat(1) + T_mat(2)
Tempo = Tempo + T_mat(3)
Tempo = Tempo + T_mat(4)
Tempo = Tempo / 4
' AGORA, OUTRO TRUQUE INTERESSANTE :
' USEI UMA EQUAÇÃO PARA CALCULAR A VELOCIDADE DO SOM PARA A ALTITUDE
' EM QUE ME ENCONTRO ( 750 METROS ) , E RESULTOU V=338 M/SEG OU 33800 CM/SEG
Dist = 33800 * Tempo
' LEMBRAMOS QUE O TEMPO MEDIDO É PARA O DOBRO DA DISTÂNCIA ( IDA E VOLTA ) !
' PORISSO QUE TEMOS DE DIVIDIR POR 200000 EM VEZ DE 100000
' E PORQUE 200000 EM VEZ DE 2000000 ?
' LEMBRE QUE A NOSSA BASE DE TEMPO É UMA CONTAGEM PARA CADA 10 MICROSEGUNDOS !
' E NÃO 1 MICROSEGUNDO ....
Dist = Dist / 200000
Print "Distancia = " ; Dist
Print "Tempo = " ; Tempo
Waitms 800
Loop


Sample_isr:
Pushall
Timer1 = 65524
Incr Tempo
Popall
Return

End

Boa diversão !

 

Paulo

Link para o comentário
Compartilhar em outros sites

Olha só....

Hoje me lembrei que o BASCOM possui uma função própria para medir a largura de um pulso aplicado em um pino de I/O, e que fornece uma contagem que incrementa uma unidade a cada exatos 10 microsegundos !!!! O nome dessa função é PULSEIN . :aplausos:

Ou seja, isso resolve todo o problema que tive de resolver "na bancada" com o programa anterior. Resolví postar ele aqui, pois este programa funcionou de cara sem precisar nenhum ajuste "prático".
 

'-------------------------------------------------------------------------------
' usando um ARDUINO UNO R3 para mostrar o funcionamento do HC-SR04
' SENSOR ULTRA-SONICO HC-SR04 - versão 2 do programa !
' Trigger - ligado no pino DIGITAL 2
' Echo - ligado no pino DIGITAL 3
' Usando a função PULSEIN do BASCOM, que mede a largura de um pulso
' Com resolução de 10 microsegundos, que já é suficiente !
$regfile = "m328pdef.dat" ' MICRO uno
$crystal = 16000000 ' xtal uno
$baud = 9600 ' baud rate
'-------------------------------------------------------------------------------
$loadersize = &H200
$hwstack = 32
$swstack = 32
$framesize = 32

Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Dim X As Byte
Dim Tempo As Word
Dim Tempo1 As Word
Dim Dist As Single
Config Portd.2 = Output
Config Pind.3 = Input

Set Pind.3 ' LIGA PULL-UP
' VAMOS ESPERAR O SENSOR ESTABILIZAR, E DEPOIS MANDAR O PULSO DE TRIGGER
Portd.2 = 0
Waitms 100
Tempo = 0
Do
'VAMOS MEDIR 4 VEZES E FAZER A MÉDIA
Dist = 0
For X = 1 To 4
  Portd.2 = 1
' AQUI GERAMOS O TRIGGER DE 10 MICROSEGUNDOS APROXIMADO
  Waitus 10
  Portd.2 = 0
  Tempo = 0
  Tempo1 = 0
'AGORA, USAR A FUNÇÃO PULSEIN , QUE TEM RESOLUÇÃO DE 10 MICROSEGUNDOS
' E ELA VAI COMEÇAR A CONTAR O TEMPO
' E TERMINAR A CONTAGEM QUANDO RECEBER A BORDA DE DESCIDA
  Pulsein Tempo1 , Pind , 3 , 1
'VAMOS ESPERAR UM POUCO PARA DAR TEMPO DE O ECO CHEGAR
  Waitms 50
' SE O ECO DEMOROU MUITO, DEFINIR LIMITE DE +- 4 METROS
  Tempo = Tempo1
  If Tempo > 2400 Then Tempo = 2400
  Dist = Dist + Tempo
  Waitms 50
Next X
Tempo = Dist / 4
' AGORA, OUTRO TRUQUE INTERESSANTE :
' USEI UMA EQUAÇÃO PARA CALCULAR A VELOCIDADE DO SOM PARA A ALTITUDE
' EM QUE ME ENCONTRO ( 750 METROS ) , E RESULTOU V=338 M/SEG OU 33800 CM/SEG
Dist = 33800 * Tempo
' LEMBRAMOS QUE O TEMPO MEDIDO É PARA O DOBRO DA DISTÂNCIA ( IDA E VOLTA ) !
' PORISSO QUE TEMOS DE DIVIDIR POR 200000 EM VEZ DE 100000
' E PORQUE 200000 EM VEZ DE 2000000 ?
' LEMBRE QUE A NOSSA BASE DE TEMPO É UMA CONTAGAM PARA CADA 10 MICROSEGUNDOS !
' E NÃO 1 MICROSEGUNDO ....
Dist = Dist / 200000
Print "Distancia = " ; Dist
Print
Waitms 700
Loop

End

Boa diversão !

Paulo

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Também já brinquei com esse sensor ultrassom, sem prescaler e usando 8.000.000 interno, multiplico o valor lido * 0,17 tendo o resultado em cm.

Pesquisei sobre balancing bot, quero fazer um robô/veículo com duas rodas paralelas se equilibrar verticalmente usando o atmega e um acelerômetro. Depois, acelerar e equilbrar ao mesmo tempo, que requer cálculos mais complexos. O acelerômetro dá um valor que representa a inclinação do eixo impresso no sensor em relação ao eixo da gravidade. Tenho os componentes, mas me falta tempo.

Tem muita coisa pronta sobre atmega/arduino e sensores na net, gravei o duemilanove num atmega168, peguei um exemplo com o módulo transceiver NRF24L01 wireless 2,4ghz, que enviava bytes e o receptor confirmava, adaptei para o comando de um servo no RX por um potenciômetro no TX, ficou bacana.

Link para o comentário
Compartilhar em outros sites

Jpsek,

Tenho dois projetos que ainda quero fazer, um deles é o balancing bot , e o outro é um pêndulo perpétuo que ví na revista Elektor, ambos são muito interessantes na ciência aplicada ao funcionamento. Mas só de pensar já dá dor de cabeça ....

Se voce puder postar esse seu ultimo projeto com o transceiver, pode ajudar outras pessoas, certo ?

Um abraço, Jpsek !

Paulo

Link para o comentário
Compartilhar em outros sites

Jpsek,

Tenho dois projetos que ainda quero fazer, um deles é o balancing bot , e o outro é um pêndulo perpétuo que ví na revista Elektor, ambos são muito interessantes na ciência aplicada ao funcionamento. Mas só de pensar já dá dor de cabeça ....

Se voce puder postar esse seu ultimo projeto com o transceiver, pode ajudar outras pessoas, certo ?

Um abraço, Jpsek !

Paulo

IDE Arduino 1.0.1, atmega168 com bootloader duemilanove, mas deve funcionar em qualquer Arduino

A ligação do NRF24L01 é a mesma para RX e TX

CE = pino 14 do atmega

CSN = 15

SCK = 16

MOSI = 17

MISO = 18

IRQ = 19

potenciômetro = 23 do atmega TX ou qualquer outro ADC disponível

servo = 11 do atmega RX ou qualquer outro PWM/OSC

Fontes, gravar RX em um atmega e TX em outro:

http://www.4shared.com/archive/i4MBOYrr/nRF24L01_Servo.html

Quem quiser tem a etiqueta de ref dos pinos Arduino para colar em cima do atmega, pra não ficar perdido nos tutoriais de Arduino tendo um atmega com bootloader (acima enumerei os pinos do atmega mesmo):

http://engenheirando.com/downloads/Atmega328%20labels.pdf

O NRF24L01 é 3,3V, mas eu uso com dois 1N4148 em série nos 5V mesmo

Link para o comentário
Compartilhar em outros sites

  • 4 meses depois...

Caro Paulo e demais participantes do forum, boa noite!

Meu nome é Nailson e meu hobby é desenvolver projetos usando os µC atmel, utilizo o compilador BASCOM. Já fiz alguns projetos que considero interessantes, atualmente estou me dedicando a um de automação residencial utilizando rede RS485.

Aproveitando a oportunidade, gostaria de saber se alguém já utilizou esses dois componentes que estou tendo algumas dificuldades:

- O DS1302 da dallas, ele não é I2C e usa uma interface de 3 fios - CLK, DAT e RST;

- ACS758 - esse gera uma tensão em sua saída proporcional à corrente drenada em seu "shunt", essa tensáo é da ordem de milivolts e CA, estou pensando em usar um OPAMP para isso, alguém tem alguma luz? Bascicamente meu problema é conseguir ler essa tenao CA no AD do µC. Talvez alguém já tenha passado por isso e possa ajudar...

Abração e depois vou postar os links de alguns projetos.

Nailson

Link para o comentário
Compartilhar em outros sites

Olá Nailson, bem-vindo ao Fórum !

Eu já usei os dois. O DS1302 eu fiz uma rotininha de escrita e uma de leitura, fazendo a sinalização "na marra", isto é, colocando os pinos nos níveis alto e baixo pelos tempos determinados no protocolo.

Mas alguma boa alma fez algo melhor, criou até uma library para uso no Bascom !!!

Segue o link do post para voce se divertir :

http://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&t=8905&highlight=ds1302

O ACS758 eu usei também, mas eu comprei ele da Sparkfun, que já vem com um amp-op e um trim-pot de ganho que nunca funcionou direito e tive de alterar toda a plaquinha que acabou ficando um monstro de gambiarra.... o melhor mesmo é montar o seu ACS758 com um bom amp-op rail to rail moderno, com ajustes independentes de ganho e de off-set que fica uma beleza !

Pode postar os seus projetos , a turma agradeçe , e qualquer dúvida, pode perguntar aqui, eu também faço tudo com o Bascom, mas estou utilizando como plataforma de desenvolvimento os hardwares padrão Arduíno. É uma baita mão na roda !

Um abraço !

Paulo

Link para o comentário
Compartilhar em outros sites

aphawk

Primeiramente parabéns pelo trabalho, achei muito bacana encontrar uma documentação aqui no fórum, vai ajudar bastante gente como ta me ajudando.

Gostaria de saber onde encontro esses componentes pro proteus, tem como me ajudar?

São os sensores:

* BMP085

* DHT-11

* TMP102 (sensor de temperatura)

* TEMT6000 (sensor de luz ambiente)

* HIH-4030 (sensor de umidade)

* SEN-08942 (sensor de velocidade do vento)

O hardware dos sensores são encontrados no site da SparkFun, mas como ando com pouco dimdim, queria testar primeiro a simulação no proteus para depois investir na compra das peças. Se souber onde tem pelo menos alguns deles já vai me ajudar muito!

Agradeço desde já!

Link para o comentário
Compartilhar em outros sites

Oi ASP40, bem-vindo ao Fórum !

Olha, temos de esperar que o fabricante do Proteus inclua os componentes em uma próxima atualização.......

E olha que já esperei um monte deles e nenhum foi incluido até agora.

Infelizmente o negócio é comprar os danados e mandar bala por conta própria.

Mas sugiro voce pesquisar no EBAY, hoje em dia eu compro tudo pelo Ebay mesmo e acaba ficando bem, mais barato do que na Sparkfun. Claro que a placa é sempre diferente, mas é só questão de adaptar os pinos de ligações.

Boas pesquisas na Internet !

Paulo

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...
Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades 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

×
×
  • Criar novo...