collapse

* Posts Recentes

O que é isto ? por SerraCabo
[12 de Abril de 2024, 14:20]


Amplificador - Rockboard HA 1 In-Ear por almamater
[11 de Abril de 2024, 20:46]


Emulador NES em ESP32 por dropes
[10 de Abril de 2024, 15:30]


Meu novo robô por josecarlos
[29 de Março de 2024, 18:30]


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


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]


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

Autor Tópico: leitura de voltagens com o analogRead(A0)  (Lida 27002 vezes)

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

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #60 em: 30 de Outubro de 2018, 11:23 »
Na verdade entendo-me melhor com os bits isolados do que com a insistência em usar o _BV e os nomes.
Portanto acho que eu quero é '65' :-) Estranho, pensei que ía ser 42... enfim... :-)

Não percebo bem como se indica um zero com os labels, simplesmente não se põe ?
Logo à noite tento...

ADMUX=_BV(REFS0) |  _BV(ADC1);

Código: [Seleccione]
Name:  ADMUX
Offset:  0x7C
Reset:  0x00

76543210     MUXn
| X||------> 0000 ADC0
|  ||------> 0001 ADC1
|  ||------> 0010 ADC2
|  ||------> 0011 ADC3
|  ||------> 0100 ADC4
|  ||------> 0101 ADC5
|  ||------> 0110 ADC6
|  ||------> 0111 ADC7
|  ||------> 1000 Temperature sensor
|  ||------> 1001 Reserved
|  ||------> 1010 Reserved
|  ||------> 1011 Reserved
|  ||------> 1100 Reserved
|  ||------> 1101 Reserved
|  |\------> 1110 1.1V (Vbg)
|  |         ADLAR
|  |-------> 0 right ajusted
|  \-------> 1 left ajusted
|            REFs
|----------> 00 AREF, Internal Vref turned off
|----------> 01 AVcc with external capacitor at AREF pin
|----------> 10 Reserved
\----------> 11 Internal 1.1V Voltage Reference with external cap at AREF pin
Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: leitura de voltagens com o analogRead(A0)
« Responder #61 em: 30 de Outubro de 2018, 12:34 »
Ya, não se põe. Só referes os bits que estão a 1.
Este esquema "standard" de montar não é o mais "compacto" mas é fácil de usar porque basta saberes os nomes dos bits, que vêm directo na datasheet, e não precisas de saber quantos tens que shiftar. Há várias formas de fazer isto. Usar 65 (ou mesmo o significado da vida :D) é a pior, porque é só um número, se queres depois saber o que lá está tens que andar a "fazer contas", é a mais indirecta e menos legível das maneiras; aliás, usar números directamente é sempre a mais ilegível das maneiras (lembro-me sempre de um colega que fazia máquinas de estados em que os estados eram números... impossível de ler!). Em geral eu costumo meter sempre um comentário bastante descritivo, muitas vezes até com as alternativas e descrição dos bits do registo. Às vezes tb atalho, crio constantes (enumerados) por exemplo para os valores de MUXxx e faço um OR directo com a entrada que quero.

enum {
    eADC_In0 = 0,          // ADC0 unused
    eADC_Buttons,          // ADC1
    eADC_PressureSensor,   // ADC2
    eADC_In3,              // ADC3 unused
    eADC_LDR,              // ADC4
    eADC_Pot,              // ADC5
    eADC_In6,              // ADC6 unused
    eADC_In7,              // ADC7 unused
    eADC_Temp,
    eADC_Vbg = 0x0E,
    eADC_GND,
};

// Select the buttons input and set "AVCC with external capacitor at AREF pin" as Vref.
ADMUX = _BV(REFS0) | eADC_Buttons;


Na verdade entendo-me melhor com os bits isolados do que com a insistência em usar o _BV e os nomes.
Portanto acho que eu quero é '65' :-) Estranho, pensei que ía ser 42... enfim... :-)

Não percebo bem como se indica um zero com os labels, simplesmente não se põe ?
Logo à noite tento...

ADMUX=_BV(REFS0) |  _BV(ADC1);
« Última modificação: 30 de Outubro de 2018, 12:54 por Njay »

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: leitura de voltagens com o analogRead(A0)
« Responder #62 em: 30 de Outubro de 2018, 12:57 »
Para descrever pinos normalmente faço uma cena parecida:

https://github.com/vnevoa/DiffTrike/blob/b260b21171f63b09b46e0f14c54ae870e4ed1107/Electronics/PowerBridge/sw/main.c#L90

O ideal é precisarmos apenas do código para perceber o que se está a fazer, sem ter que consultar a datasheet ou outros documentos. Isso é que é bem feito, é qualidade, é redução de bugs, é facilitar alterações e extensões futuras.
« Última modificação: 30 de Outubro de 2018, 12:59 por Njay »

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #63 em: 30 de Outubro de 2018, 14:02 »
Dou-te toda a razão, mas a utilização exige disciplina, coisa que eu não tenho muita.
É por isso que gosto tanto de perl, assim não me sinto mal quando não percebo que raio estava a fazer. :-)
Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #64 em: 31 de Outubro de 2018, 07:45 »
Há qq cena estranha com o Arduino IDE e/ou core que estou a usar:

ADMUX=_BV(REFS0) |  _BV(ADC1) produz resulta em 66 e não 65.

Na verdade ADC1 nem sequer compila, tem que se usar ou MUX1 ou ADCD1, ambos definidos nos .h com o valor 1.
Mas este core deve estar a ir buscar os .h a qq outro sitio, porque quando faço o print de MUX1 ou do ADCD1 obtenho 2, tenho que procurar melhor nos .h tem que estar em algum lado.

Enfim, estou a usar ADMUX=B01000001; sempre é mais legível que 65 :-). Curiosamente 42 é uma valor bastante reservado... Até tenho medo de experimentar.

O que é interessante é que estou a obter valores muito próximos, da realidade. Simplesmente somando o offset de 1 a todas as leituras, e usando o Vin calculado a partir da leitura da referência, (mas já tínhamos determinado que o valor do Vin não altera muito as contas da resistência), talvez seja o condensador de 100nF que está a fazer o seu serviço. Se tivesse uma indutância dessas experimentava a sugestão do senso, mas não é coisa que tenha por aqui.

5 ohm    -    5.07 / 5.58
5 K        -    4.80 K
95 K       -    94.32 K
295 K     -    293.55 K
805 K     -     802.00 K

Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: leitura de voltagens com o analogRead(A0)
« Responder #65 em: 31 de Outubro de 2018, 09:29 »
Porque 1<<1 = 2
Só dava 1 se fosse 1<<0

Tens de ir estudar a matemática dos bits.
Avr fanboy

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #66 em: 31 de Outubro de 2018, 10:29 »
Ah! então a culpa é do _BV

Exactamente

drives/c/Program Files (x86)/Arduino/hardware/tools/avr/avr/include/avr $ grep "#define _BV" *
sfr_defs.h:#define _BV(bit) (1 << (bit))
                                                             
Mudei a linha para

  ADMUX=_BV(REFS0) | ADC1D;

E já dá o resultado esperado.

Mas fico sem saber para que serve o _BV
    "Converts a bit number into a byte value."
Que raio querem dizer com isto ? Só usei o _BV porque estava em todos os exemplos que vi, mas não vejo para que serve multiplicar o numero por 2 (shift left).

A minha aritmética dos bits não é das piores, só não sabia o que o _BV fazia.
Mas não estou nada à vontade com os << e >> que aparecem em todo o código que mexe com os registos, para mim as contas com os bits eram mais à base de ANDs, ORs e XORs, mas tou aprendendo.


Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: leitura de voltagens com o analogRead(A0)
« Responder #67 em: 31 de Outubro de 2018, 10:53 »
Se funciona sem o _BV é porque estás a usar o pino errado.

O BV serve para pegar nesses valores e montar um byte com os bits no sitio correcto.

O registo ADMUX nem sequer tem nenhum bit chamado ADC1D (isto no atmega328p, não sei que micro estás a utilizar).

Se queres meter o primeiro bit do byte a zero simplesmente _BV(MUX0) que faz 1<<0.

O ADC1D é um bit do registo DIDR0 que serve para desligar o buffer digital, ajuda a reduzir o consumo, E corresponde ao bit 1 e não ao zero.

Vai á datasheet e lê o Register Description do ADC, secção 28 , mais explicado é complicado..

Avr fanboy

Offline jm_araujo

  • Mini Robot
  • *
  • Mensagens: 2.948
  • NERD!
Re: leitura de voltagens com o analogRead(A0)
« Responder #68 em: 31 de Outubro de 2018, 12:41 »
_BV:

Se numerares os bits no byte:
bits    :0b00000000 = (0x0 = 0)
numero  :  76543210


O _BV(bit) retorna um byte com o bit numero bit a 1.
Por exemplo _BV(5):
bits    : 0b00100000 = (0x20 = 32)
numero :    76543210

O 1<<bit faz shift à esquerda bit vezes do byte 00000001, que resulta no que disse. Fazendo OR com outros valores garantes que esse bit vai ficar a 1 no resultado.

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #69 em: 31 de Outubro de 2018, 14:36 »
Tens razão, no atmega328p deveria usar os nome MUX0, MUX1, MUX2, MUX3, tinha ido à procura do ADC0, não encontrei e pimba, escolhi um nome parecido.

O problema é que demorei umas horas para perceber que o uso destas constantes não é exatamente como eu estava habituado.
Estava habituado a definir constantes com um valor tal que só tinham a 1 os bits que lhe diziam respeito, era só fazer o OR delas para obter o valor final, tipicamente também há a definição de uma mascara para isolar eventuais grupos de bits... Não interessa, aqui as constantes indicam o numero do bit a fazer o set, deve haver alguma razão para isso já que isso obriga a ter apenas constantes com 1 bit.

Portanto o que tenho que usar é (_BV(REFS0) | _BV(MUX0)), e funciona.

Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #70 em: 05 de Novembro de 2018, 13:42 »
Oh, estão a falar do AREF e não do AVCC.

1uF X7r no AREF, 1uF+100nF+BLM31PG121SN1L ou 81-BLM15BB221SN1D, funciona que nem ginjas quando tinha as atxmega/atmegaRFA/RFR pendurados em reguladores comutados, e melhor ainda com LDO's.

Agora fiquei confuso, é um cap (ao GND) de 100nF no AREF e/ou 1 cap (ao GND) no AVCC + uma indutância de 10uH entre o AVCC e o VCC ?

Relativamente ás indutâncias, qual é o tipo thru-hole que posso usar ? Aquelas que são porreiras para confundir com as resistências ou têm que ser aquelas maiores com núcleo de ferrite ? Não faço a mínima ideia se em termos de função são equivalentes.
Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #71 em: 05 de Novembro de 2018, 15:45 »
Trabalhas em Lx Vasco? Posso emprestar-te por uns tempos uma cena para calibrares os teus aparelhos/chips, é de 1.8V -/+1mV. Contacta-me por MP se interessado.

Agradeço a oferta, mas julgo que nenhum dos DMM Aneg que tenho possuam uma forma de ser calibrados (pelo utilizador).
Eu tenho uma referência baratinha, que dá 2.5V / 5V / 7.5V / 10V, baseada num AD584, dizem na página que é 'High Precision' mas isto numa pagina da ebay vale o que vale.
Tenho na calha para comprar uma cena destas https://www.ebay.com/itm/123110358010 mas só lá para o ano.
Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: leitura de voltagens com o analogRead(A0)
« Responder #72 em: 05 de Novembro de 2018, 20:15 »
Só o tamanho das patas mata em parte a funcionalidade de uma ferrite igual á que dei referências.

Se queres mesmo utilizar, ferrite em série com a tua alimentação para o pino Avcc mais o condensador, no AREF, metes um condensador, ou dois, ou mete-lhe uma referência semi decente de 2€ no AREF, ou por 2€ metes um ADC melhorzinho que o do atmega, ou por 2€, mudas para um micro com um ADC muito melhor :D

Tens opções.

A nivel de referências tenha 4 LM399 há anos a apanhar pó em casa, tenho de montar uma pcb para os meter a funcionar, mas não tenho maneira de depois os calibrar para 10.0000v :(
Avr fanboy

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #73 em: 05 de Novembro de 2018, 22:49 »
Só o tamanho das patas mata em parte a funcionalidade de uma ferrite igual á que dei referências.

Acredito, mas na montagem que estou a fazer teria que ser mesmo thru-hole.

Citar
Se queres mesmo utilizar, ferrite em série com a tua alimentação para o pino Avcc mais o condensador, no AREF, metes um condensador, ou dois, ou mete-lhe uma referência semi decente de 2€ no AREF, ou por 2€ metes um ADC melhorzinho que o do atmega, ou por 2€, mudas para um micro com um ADC muito melhor :D

Nos desenhos iniciais tentei usar uma referência externa de 5V no AREF, mas não consegui ler valores decentes nessa situação, sem divida culpa minha, acho que agora já faria melhor. Tenho uma referência (LT1004) de 2.5V mas só a uso para determinar o Vcc, imagino que para o efeito que falas teria que ter uma referência de 5V. Já que os valores que estou a medir podem chegar ao Vcc (estou a usar um Arduino Nano).
Também tenho um ADC I2C, um ADS1115, mas desde que meti a referência para calibrar o Vcc e o condensador no AREF passei a ter valores tão decentes que nos últimos tempos tenho só andado a brincar com o ADC do AVR.
No esquema da minha montagem tenho dois jumpers para ligar/desligar o ADC externo.
Este fds estive a olhar para a datasheet dos STM32, mas confesso que me assustei, pareceu-me bem mais complicado de trabalhar do que o do AVR, é possível que com as libs do Arduino não fizesse muita diferença em termos de código, mas achei que era areia demais para a minha camionete.

Deixo aqui o esquema atualizado, a ideia de por a ferrite era só mesmo se melhorasse a exatidão do ADC.

Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: leitura de voltagens com o analogRead(A0)
« Responder #74 em: 06 de Novembro de 2018, 02:59 »
Trabalhas em Lx Vasco? Posso emprestar-te por uns tempos uma cena para calibrares os teus aparelhos/chips, é de 1.8V -/+1mV. Contacta-me por MP se interessado.

Agradeço a oferta, mas julgo que nenhum dos DMM Aneg que tenho possuam uma forma de ser calibrados (pelo utilizador).

Já lhe viste as entranhas?
Mas mesmo que não tenha, ficas a saber o erro do teu DMM, e se precisares calibras a leitura mentalmente.

Citar
Eu tenho uma referência baratinha, que dá 2.5V / 5V / 7.5V / 10V, baseada num AD584, dizem na página que é 'High Precision' mas isto numa pagina da ebay vale o que vale.

Segundo a datasheet, a melhor referência de 2.5V (há várias versões do chip) tem um erro máximo de +/-2.5mV. A que te posso emprestar (é de 1V8) tem um erro máximo um nadinha inferior a +/-1mV.
Update: O chip é o LM4132AMF1.8V, tenho umas fotos do protótipo aqui no fórum: https://lusorobotica.com/index.php?topic=8747.msg98212#msg98212

Citar
Tenho na calha para comprar uma cena destas https://www.ebay.com/itm/123110358010 mas só lá para o ano.

É tão boa tão boa, que a coisa mais importante não diz... qual é a precisão. Nem os valores dos componentes. Falta de specs é logo motivo para classificar como lixo, não gastes o teu dinheiro nisso.

A não ser que esteja com  muita pressa para ir a algum lado, normalmente faço a média de várias leituras de ADC (e arredondo para o valor mais próximo e não por defeito, já tenho falado por aqui sobre isso). Já estás a fazer isso?
« Última modificação: 06 de Novembro de 2018, 03:15 por Njay »