LusoRobótica - Robótica em Português

Sistemas específicos => Arduino / AVR => Tópico iniciado por: vasco em 23 de Agosto de 2018, 00:43

Título: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 23 de Agosto de 2018, 00:43
Boa noite,

Costumo tentar evitar o cross posting, mas desde esta tarde que não consigo aceder ao forum.arduino.cc onde coloquei uma pergunta sobre este assunto.
Não entrando muito nos detalhes do que estou a fazer (um ohmimetro, sou um tanto ou quanto daltónico e não consigo ler as barras, e o multímetro nunca está à mão e é lixado medir com as pontas de prova), gostava só de pedir que me explicassem qual é a ideia do uso do analogRead para ler uma voltagem.

Estou a usar um Nano, portanto o ADC é de 10 bits.
Pelo que percebo, quando se faz um leitura deve-se receber 0 se o valor for 0V e 1023 se o valor for 5V, sendo que 2.5V dariam 511, etc...
No muito que já li sobre o assunto dei com alguém a dizer que usava a referência interna de 1.1V para obter melhor precisão.

Realmente existe a instrução analogReference(INTERNAL1V1);
Mas, e isto aqui é que gostaria que me explicassem, fico limitado a medir valores abaixo de 1.1V? É que os valores que medi com com esta referência ativa não fazem sentido. Mas no contexto em que dizem isto também não faz sentido nenhum que não se possam ler valores acima de 1.1V...  :o
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 23 de Agosto de 2018, 01:05
Se Vin for a tensão de entrada, no pino, o número lido do ADC, adc, a que chamamos "contagem", é

adc = Vin / Vref * 210

O expoente 10 é o número de bits do ADC. Por omissão, no Arduino Vref = Vcc = 5V, ou melhor, ~5V, porque a precisão (quão perto dos 5V absolutos) e a estabilidade (a estabilidade face a alterações da temperatura e outras) dependem da "qualidade" da fonte de alimentação que gera esses 5V.

Pela expressão já vês que só consegues medir tensões até Vref - Vref / 210, ou seja Vref - "uma contagem" (também conhecido como "1 LSB") . Para valores de tensão acima disso, a contagem é sempre o valor máximo (1023 no caso de um ADC de 10 bits), diz-se que "satura" (nos 1023, neste caso).

A referência interna de tensão de 1.1V é uma fonte de maior estabilidade do que o tipico regulador de 5V (como o 7805), ou seja, o valor dela varia com a temperatura/Vcc/consumo/etc dentro de certos limites mais apertados (indicados na datasheet do AVR), mas a sua precisão é má, pois pode ser um valor qualquer entre 1 e 1.2V (ver datasheet) para cada chip que sai da fábrica, 1.1V é um valor nominal (acho que até o 7805 tem melhor precisão :D). Para a usar para medir valores absolutos de tensão, tens que medi-la 1º e depois usar esse valor nos cálculos (tipicamente guarda-se na EEPROM e o código faz uso disso).

Ao usares uma Vref mais baixa, estás a aumentar a resolução, à custa de perder gama dinâmica (o intervalo possível de leitura). Com Vref = 5V o passo do ADC, ou, dito de outra forma, a menor variação "garantida" que consegues medir, é

Vref / 210 ~ 4.88 mV

já com Vref = 1.1V é ~ 1.07 mV.

Podes sempre ler valores acima de Vref, se reduzires a tensão de entrada para ser < Vref e tiveres isso em conta no código...

Perguntas?
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 24 de Agosto de 2018, 20:41
Ok, então afinal é mesmo como eu pensava, só se pode medir voltagens abaixo da vref.
Faz sentido quando não se pode garantir a vcc a 5V (baterias por exemplo).

Tenho estado a olhar para alternativas ao ohm meter via x resistências de teste, e parece que ninguém se arrisca a fazer outra coisa com o arduino.
Na vossa opinião, pare medir um range entre 1 ohm (ok 10 ohms) e 1 M qual será o conjunto de resistências de teste apropriado ? Dividir o mais possível pela range toda ou há alguma nuance ?

O método dos 4 pontos (kelvin) parece-me viável, tenho algures um sensor de corrente, mas tenho que investigar para ver se mede gramas ou arrobas.

Estou meio tentado a meter uma caixita com material no meio da roupa das férias, mas é capaz de ser um bocado perigoso... ;-) Portanto acho que não vou fazer mais nada até Setembro.

abraços e obrigado
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: jm_araujo em 24 de Agosto de 2018, 23:33
Já deste uma vista de olhos ao "trasistortester": https://github.com/svn2github/transistortester

Só precisa de uma referência externa e um punhado de resistências (o resto é para alimentação e UI), e compra-se tão barato que pode servir de base para outros projetos.

Não tem problemas em ler resistências dos valores que pretendes, e no manual descreve como é feito o cálculo, página 74 do manual aqui: https://raw.githubusercontent.com/svn2github/transistortester/master/Doku/tags/english/ttester_eng112k.pdf

Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 30 de Agosto de 2018, 18:46
Como costume, excelente sugestão, vou investigar.

Obrigado
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 05 de Setembro de 2018, 18:42
Tenho estado a estudar o esquema e vou ver se construo uma versão "abreviada" só com o necessário para medir resistências.
Ainda não consegui compreender qual é o método que usam, apenas têm duas resistências de referência, não estou a ver para já como é que conseguem a exatidão que dizem que conseguem, e já comprovei que pelo menos a versão que eu tenho dá resultados aceitáveis, portanto haverá algum truque. O código também não é exatamente muito simples... tsk... analogRead() é para maricas... :-D
É um pet project giro, vou andar de volta disto mais uns tempos :-)
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: jm_araujo em 07 de Setembro de 2018, 11:40
Estive a ler sobre o método por curiosidade e para ver se dava uma ajuda, e acho que entendi:
Esquema:
(https://lusorobotica.com/index.php?action=dlattach;topic=9414.0;attach=4507)

O que fazem é ativar primeiro a Out 1 (Out 2 em tri-state, a flutuar),é um divisor de tensão, e medem o valor com a ADC, usando como referência do ADC os 5V da alimentação. Se o valor de resistência for muito baixo dá valores muito perto dos 0V, e nesse caso mudam a referência da ADC  para a interna de 1.1V para aumentar a resolução. Se o valor for muito alto, mudam do Out1 para o Out2, fica um divisor com os 470kOhm e já puxa os valores da ADC para baixo. Não fiz as contas, mas pode ser necessário para valores de resistência na zona de transição entre os 680 e os 470k usar também a referência interna de 1.1V.

Depois é só fazer as contas  para converter a tensão do ADC para a resistência, mas não é nada de muito complicado, é sempre um divisor de tensão.


A "confusão" do esquema original é porque permite ler resistências (e outros componentes) entre quaisquer 3 pinos, e é preciso fazer mais medidas, mas para o teu caso é desnecessário complicar.




Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 07 de Setembro de 2018, 15:05
Ok, parece fazer algum sentido.
Julgo que o esquema original usa uma referencia externa de 2.5V e não os 5V do VCC, não tenho aquela referência mas tenho um modulozinho que pode dar 2.5, 5.0, 7.5 e 10V
Vou tentar ensaiar com ela e com  a interna de 1.1V da maneira que sugeriste.

https://www.ebay.com/itm/331725573000 (https://www.ebay.com/itm/331725573000)

tks.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: jm_araujo em 07 de Setembro de 2018, 15:27
No transistortester a referência externa é usada para calibração e não como referência:
Citar
The additional 2.5V precision voltage reference connected at pin PC4 (ADC4) can be used to
check and calibrate the VCC voltage, but is not required

Assim conseguem ter a gama completa dos 5V para converter.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 07 de Setembro de 2018, 21:32
OK, não tinha compreendido isso.
Mas então fico com duas incógnitas, não sei nem a que voltagem o Nano coloca o pino quando o ponho em HIGH nem sei a que voltagem está a referência de 5V quando alimento o Nano via USB.

Bom, vou ligar uns pinos segundo o teu esquema e já vejo que resultados tenho.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: senso em 07 de Setembro de 2018, 21:53
Mete o pino á voltagem que tem no Vcc, se for 5v, mete 5v, se for 3.3v, mete 3.3v no pino.

A referência de 5v, supostamente estará a 5v se for do tipo shunt, ou a 0v se não tiver headroom para funcionar.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 07 de Setembro de 2018, 22:24
É um nano, portanto são 5V.
O problema é que nunca são MESMO 5v, tal como o VCC vindo do USB também nunca são MESMO 5v. E pelo que consegui medir até agora com a minha limitada "aparelhagem", não são mesmo NADA 5V, são mais 4.5v

Mas bom, como a minha resistência de 680 ohm tem na verdade 546 ohm e a de 470k tem 4773 ohms devo estar a preocupar-me com coisas parvas... :-)
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: senso em 07 de Setembro de 2018, 22:53
Se tens 4.5v no USB algo de errado se passa com o teu ou o teu hub..

Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: jm_araujo em 08 de Setembro de 2018, 10:15
É um divisor resistivo e o ADC tem a mesma referência. Se a alimentação variar o resultado da conversão deve manter-se constante.

Eu preocupava-me mais era se tiveres de usar a referência interna, que já não varia em simultâneo. Não estive a ver o diagrama, talvez dê para converter o valor dessa referência e descobrir a sua relação com a alimentação.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 08 de Setembro de 2018, 11:00
Se tens 4.5v no USB algo de errado se passa com o teu ou o teu hub..

Não estou a usar um hub externo, estou a ligar numa porta frontal de um desktop, a voltagem à saída sem nada ligado é 5.01v mas desce para 4.97 quando lhe ligo o Nano, mas nota que esta medida é feita não com o DMM mas com um daqueles testers USB, portanto os valores podem não ser exactos, mas existe uma variação.

Com o Nano ligado, e medindo entre o shield da tomada mini usb (no Nano) tenho

pino 5V e pino AREF: 4.641V (sim, sei que o AREF é para ligar uma referencia externa, fui só ver o que lá estava)
pino VIN: 4.222 (também sei que este pino é usado para alimentar o nano sem passar pelos reguladores, fui só ver o que lá estava)
pino 3.3V: 3.245
pino a que foi feito um pinMode(x, OUTPUT); digitalWrite(x, HIGH);: 4.607V <== deverei usar este valor para Vin, penso eu de que...

Tenho que medir no shield da tomada, não vou tentar medir nos contactos do board á saida da tomada, era curto-circuito certo.

Sempre vi este comportamento nos Nanos (chineses de várias origens) achei que era mesmo assim, daí estar a pensar que uma referencia externa fazia sentido.

Usando uma função maluca que anda por aí para medir o VCC (feita para usar quando a alimentação vem de baterias), quando está ligado via USB meço 4.5V que bate mais ou menos certo com o que meço com o DMM.

Fica aqui para referência a função que mede o VCC, não é minha, julgo que já a vi algures no código do transistor tester, mas não tenho a certeza da origem.

Código: [Seleccione]
long readVcc() {
  // Read 1.1V reference against AVcc
  // set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
  ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
  ADMUX = _BV(MUX3) | _BV(MUX2);
#else
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif

  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA, ADSC)); // measuring

  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
  uint8_t high = ADCH; // unlocks both

  long result = (high << 8) | low;

  result = (1125300L / result); // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
  return result; // Vcc in millivolts
}
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 11 de Setembro de 2018, 18:58
jm_araujo, depois de ruminar repetidamente sobre o assunto, principalmente sobre que raio queriam dizer com medir nos 2 sentidos acabei por ver que a ligação afinal não é entre 2 pinos via resistência a testar para o GND mas sim entre 2 grupos de dois pinos de cada lado da resistência a testar, e há tb duas leituras do ADC, ainda não sei que contas é que se fazem para esta situação mas a luta continua...  ;D

O esquema que indicaste é o que se usa tradicionalmente com um range de n resistências, foi a primeira versão que fiz e não fiquei muito satisfeito, daí ter pensado em explorar tecnicas alternativas.

(https://lusorobotica.com/index.php?action=dlattach;topic=9414.0;attach=4512;image)
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 11 de Setembro de 2018, 21:15
  // Read 1.1V reference against AVcc
  // set the reference to Vcc and the measurement to the internal 1.1V reference
  (...)
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA, ADSC)); // measuring

  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
  uint8_t high = ADCH; // unlocks both

  long result = (high << 8 )  | low;
  result = (1125300L / result); // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
  return result; // Vcc in millivolts


Ficava melhor com o CPU a dormir durante a espera do fim de conversão. Mantinha o loop mas metia um sleep lá dentro, mesmo no modo mais "leve", e ou habilitava a interrupção de fim de conversão ou confiava em algum timer que tivesse a correr.

O resultado final tem que ser corrigido de alguma forma, pois a referência interna não é de 1.1V certos.

A divisão final causa um arredondamento por defeito, o que não é ideal. O melhor é um arredondamento para o valor mais próximo, assim:

  result = (1125300L + result / 2) / result;
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: jm_araujo em 11 de Setembro de 2018, 22:20
Vasco,

A minha versão é a "descomplicação" do que eles fazem . Eles usam esse esquema porque têm 3 pinos e podes meter quase qualquer componente (não só resistências) entre eles, sem nenhuma ordem. Medem de várias formas porque usam os dados para detetar outros componentes. Se medires nos dois sentidos e o valor obtido não for igual (dentro de uma margem de erro), é porque tens um componente que não uma resistência.

Como tu queres só medir resistências, podes aproveitar só "o sumo" do que eles fazem e esquecer o resto.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 12 de Setembro de 2018, 11:31
Tens razão, será então uma questão do software.
Fui distraído pela parte em que dizem que medem nos dois sentidos, que é claro faz sentido quando se quer detetar outros tipos de componente.

Achas que faz sentido usar mosfets para dar 5V regulados ás resistências em vez de depender do valor do HIGH dos pinos digitais e/ou ler o pino analógico via um opamp em voltage folower para reduzir ao mínimo a corrente "puxada" do circuito ? Como é evidente tal não é absolutamente necessário uma vez que o transistor tester consegue bons resultados sem isso, mas *talvez* ajude com software inferior.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: jm_araujo em 12 de Setembro de 2018, 11:52
Eu não complicava antes de tempo. Primeiro fazia um proof of concept super simples para ver os resultados antes de começar a pensar nessas.

Inicialmente nem fazia processamento Arduino, lia o ADC nas várias configurações possíveis de resistências internas  e referencias, e cuspia o conjunto de leituras para a porta série. Depois acerta-se as formulas no PC, até em excel, e já consegues verificar a precisão e variação que consegues antes de enfiar tudo de volta no arduino.

"Premature optimization is the root of all evil (or at least most of it)" - Donald Knuth
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 12 de Setembro de 2018, 14:12
O pino dum AVR tem cerca de 20 - 25 Ohm de resistência de saída (resistência em série com o "pino ideal").
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 13 de Setembro de 2018, 09:45
Inicialmente nem fazia processamento Arduino, lia o ADC nas várias configurações possíveis de resistências internas  e referencias, e cuspia o conjunto de leituras para a porta série. Depois acerta-se as formulas no PC, até em excel, e já consegues verificar a precisão e variação que consegues antes de enfiar tudo de volta no arduino.

ok

Citar
"Premature optimization is the root of all evil (or at least most of it)" - Donald Knuth

R-E-S-P-E-C-T !!!  8)
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 13 de Setembro de 2018, 09:50
O pino dum AVR tem cerca de 20 - 25 Ohm de resistência de saída (resistência em série com o "pino ideal").

Já tinha lido isso, mas nunca percebi porquê, haverá certamente uma boa razão. Isso só se verifica quando o pino está em modo de OUTPUT ?
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: senso em 13 de Setembro de 2018, 10:11
Porque vivemos no mundo real, e não faz sentido ter transistors/FET's ultra low rdsOn nos pinos de IO.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 14 de Setembro de 2018, 09:24
Inicialmente nem fazia processamento Arduino, lia o ADC nas várias configurações possíveis de resistências internas  e referencias, e cuspia o conjunto de leituras para a porta série. Depois acerta-se as formulas no PC, até em excel, e já consegues verificar a precisão e variação que consegues antes de enfiar tudo de volta no arduino.

Já fiz uma amostragem e com todas as contas na spreadsheet estou a conseguir valores que andam pelo menos próximo dos 5% em comparações com os valores do DMM.
A meio do teste lembrei-me de fazer tb a leitura com o transistor tester que tenho, e ele consegue melhores resultados (não estou surpreendido  ;D).
Um ponto fraco da minha montagem é certamente a ligação à resistência a testar, não se compara nem com as pontas de prova com gancho que tenho no DMM nem o zif socket que tenho no TT.

A ver se logo à noite consigo por aqui os resultados, se bem que acho que o forum não me deixa enviar um .xls, logo se vê.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 14 de Setembro de 2018, 12:24
Se calibrares o sistema como um todo, ajustas de uma vez só a tolerância da tensão de referência, a das resistências fixas e outras incertezas que possam introduzir erro na leitura. Se o sistema for linear (que no teu caso deve ser), colocas 2 resistências de teste, uma para cada extremo do intervalo que o teu aparelho mede, e usas esses 2 pontos para calcular uma função (recta) de mapeamento directo entre a contagem do ADC e o valor final nas unidades que quiseres.
Se vais tentando compensar a tolerância de cada parte do sistema individualmente, os erros de medida e cálculo acumulam-se e nunca consegues resultados tão bons.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 14 de Setembro de 2018, 14:01
Tenho que olhar melhor para os dados recolhidos para ver se é possível melhorar a exatidão apenas com um offset, ontem quando recolhi os dados nem pensei nisso, estava mais de olho na % de diferença.

Este projeto está a ser um curso...  ;D
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 14 de Setembro de 2018, 14:23
https://lusorobotica.com/index.php?topic=6576.msg85191#msg85191
https://lusorobotica.com/index.php?topic=6576.msg85228#msg85228
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 15 de Setembro de 2018, 09:59
Nunca me disseram no liceu que as retas serviam para isso !!!!!!!!!!!!!!!!!
Essa thread tem lá muita info, tks.

Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 15 de Setembro de 2018, 11:30
Aqui fica um boneco da montagem mais os valores que recolhi e calculei no libre office, não tenho o excel, por isso incluo os dois formatos já que se pode sempre perder qq coisa quando se grava em formato xls.

O que achei interessante daqui é que o valor absoluto do Vin não interessa muito, portanto é mais ou menos irrelevante se este é dado por um pino do arduino é se é dado por uma voltagem regulada que seja exactamente 5V. Desde que seja igual para todos.
Ainda vou ver como integro isto à luz da reta no Njay  ;D

(https://lusorobotica.com/index.php?action=dlattach;topic=9414.0;attach=4517;image)

Relativamente ao codigo

Para ler o A0 estou a usar

Código: [Seleccione]
int read_A(int pin)
{
  int f, X;
  float Xtot=0L, Xmed=0L;

  // 100 é um valor completamente arbitrário, provavelmente 20 funcionava igualmente bem
  for(f=0;f<100;f++)
  {
    X=analogRead(pin);
    Xtot+=X;
    delay(1);
  }
  Xmed=Xtot/100;
  return(int(round(Xmed)));
}

Para "ligar" e "desligar" um pino, estou a fazer

Código: [Seleccione]
void on(int pin)
{
  pinMode(pin, OUTPUT);
  digitalWrite(pin, HIGH);
  delay(1);
}

void off(int pin)
{
  pinMode(pin, OUTPUT);
  digitalWrite(pin, LOW);
  pinMode(pin, INPUT);
  delay(1);
}
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 16 de Setembro de 2018, 13:34
O que achei interessante daqui é que o valor absoluto do Vin não interessa muito, portanto é mais ou menos irrelevante se este é dado por um pino do arduino é se é dado por uma voltagem regulada que seja exactamente 5V. Desde que seja igual para todos.

De facto faz sentido, pois estás a medir um rácio de resistências e não uma tensão arbitrária, pelo que a tensão de alimentação é irrelevante. Quando a corrente sobe ou desce na resistência que estás a medir devido a uma tensão de referência diferente, ela também sobe ou desce na outra resistência - acaba por ser uma medida raciométrica, a tensão de saída (lida no ADC) é sempre a mesma proporção (dada pelas 2 resistências) de Vref.

Num caso genérico, quando estás a medir uma tensão arbitrária, essa tensão não está relacionada com Vref, podes alterar Vref à vontade que a tensão a medir não muda; daí que Vref tem influência no valor medido, não é uma medida raciométrica. A interpolação linear só é útil para este caso.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: jm_araujo em 16 de Setembro de 2018, 18:36
Já tinha referido o facto há 2 páginas atrás, mas acho que passou despercebido.

É um divisor resistivo e o ADC tem a mesma referência. Se a alimentação variar o resultado da conversão deve manter-se constante.

Eu preocupava-me mais era se tiveres de usar a referência interna, que já não varia em simultâneo. Não estive a ver o diagrama, talvez dê para converter o valor dessa referência e descobrir a sua relação com a alimentação.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 13 de Outubro de 2018, 12:24
Conclui que estar a desenvolver sobre um protótipo que era bastante diferente do que eu queria fazer no fim não seria a melhor das ideias.
No mínimo, toda a parte da calibração teria que ser refeita. E como queria incluir um display e um ADC I2C não o conseguia fazer sem voltar para uma breadboard, coisa que não queria fazer por causa dos problemas de maus contactos que sempre tive com estes breadboards chinocas (sim, já sei, valem o que se paga por eles... :-)
Portanto montei a coisa e não resisto a mostrar, não tenho muito orgulho na parte de baixo, mas tenho um imenso orgulho de ter conseguido fazer uma montagem que até está a fazer o que eu queria... Acho que é a parte importante do hobismo (acabei de inventar a palavra).

Fotos em: https://photos.app.goo.gl/JtnzarXNyFVSNMBc7

Queria colocar 1 foto aqui como chamariz, mas o forum está a dizer-me que o meu anexo não passou as verificações de segurança... estranho.

A alteração mais significativa terá sido ir para um ADC I2C baseado no ADS1115 em vez de usar o do AVR.
Não tenho grande utilidade para os 15 bits, de resolução, mas estava a passar-me um bocado com as referências, Vins, etc... Parece-me que isto mata o assunto.
Podia ter ido para um modulo com o ADS1015 (12 bits, mas devem ser só 11) mas o modulo até era mais caro que este que estou a usar.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 14 de Outubro de 2018, 03:02
Oh Vasco, desperdiçaste um ADC, mas tá fixe, parabéns pelo projecto acabado :)
A parte de baixo não tá má, normal para uma montagem do género, apenas um bocadinho de solda em excesso.
De resto é continuar a produzir e mostrar :)

Tens que meter as referências no sítio. O que é que tá a fazer confusão?
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 14 de Outubro de 2018, 14:04
Oh Vasco, desperdiçaste um ADC, mas tá fixe, parabéns pelo projecto acabado :)
A parte de baixo não tá má, normal para uma montagem do género, apenas um bocadinho de solda em excesso.
De resto é continuar a produzir e mostrar :)

Tens que meter as referências no sítio. O que é que tá a fazer confusão?

Obrigado pelo cumprimento :-) Odiava ver uma montagem realmente má... :-P
Quando falava em referências era a voltagem de referência do ADC interno no AVR estava a fazer-me imensa confusão, daí o ADC externo, tem referência própria e é problema dele... :-)

Mas ando a pensar numa coisa, posso por uma ligação ao pino A0 no mesmo ponto que vai ligar ao ADC externo e medir pelos 2 lados ?
Podia simplesmente meter um jumper para poder selecionar ou um ou outro, mas fiquei a pensar se perturbaria simplesmente ligar os 2 ao mesmo ponto. Sei muito pouco disto mas desconfio que não deve funcionar, deve depender a impedância do A0 vs o pino do ADC externo. Certo ? Um deles iria sempre medir 0V ?

Possivelmente poderia ser feito via um opamp a servir como buffer já que é suposto as entradas terem um impedância mt. alta não deviram afetar o sinal ???
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 14 de Outubro de 2018, 14:49
Ok, em comparação com este a minha montagem está aceitável....

https://www.eevblog.com/forum/beginners/horrible-solder-job-buyer-wants-money-back-after-butchering-kit-with-his-skill/

Procurem por "bad solder jobs"... Horas de divertimento garantidas.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 14 de Outubro de 2018, 22:30
Quando falava em referências era a voltagem de referência do ADC interno no AVR estava a fazer-me imensa confusão, daí o ADC externo, tem referência própria e é problema dele... :-)

Easy easy :)

Citar
Mas ando a pensar numa coisa, posso por uma ligação ao pino A0 no mesmo ponto que vai ligar ao ADC externo e medir pelos 2 lados ?

Tens um esquema eléctrico do que tens montado? Se não tens, é por onde deverias ter começado :)...
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 15 de Outubro de 2018, 11:52
Tens um esquema eléctrico do que tens montado? Se não tens, é por onde deverias ter começado :)...

Já estava desatualizado... :-)

NOTA:
    Os valoers de C1 e C2 não são esses;
    A resistência a testar é ligada entre os pinos do J2

A duvida é se posso ligar o A0 do Nano ao mesmo ponto onde está o A0 do ADC externo diretamente (linha laranja). Provavelmente não tem qualquer utilidade mas acho que era giro comparar os valores.

(https://lusorobotica.com/index.php?action=dlattach;topic=9414.0;attach=4548;image)
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 15 de Outubro de 2018, 13:14
Julgo que para ligar os dois ADC teria que fazer qq coisa deste estilo.

(https://lusorobotica.com/index.php?action=dlattach;topic=9414.0;attach=4550;image)
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 15 de Outubro de 2018, 15:29
Podes ligar ao mesmo tempo a uma entrada de ADC do Arduino. Evita fazer a conversão em simultâneo nos 2 ADCs. Não precisas de fazer buffering do sinal, a impedância (resistência) de entrada do ADC do Arduino é grande, para sinais "quietos" como tens na tua aplicação.

D2 não parece fazer muito sentido onde está. No contexto que foi falado lá atrás, era preciso teres tensões de alimentação negativas no teu circuito, mas não tens. Deita fora esse díodo. Se queres proteger contra inversão de polaridade, tens que o passar para a entrada de alimentação do circuito, e meter um fusível antes, tal como no exemplo do autorádio que o jm mostrou.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 17 de Outubro de 2018, 11:48
Sim, o D2 ficou "esquecido", tinha feito assim de inicio com base na página sobre o 780x que tinha referido no inicio.

Experimentei ligar e funciona sem problemas, valores consistentes e como esperado um pouco diferentes.
Experimentei também ligar o ADC externo numa configuração diferencial, uma pata antes do Rt (resistencia desconhecida) e outra pata depois do Rt.
Achei que usando a Intensidade calculada com base na leitura do ADC do AVR e o voltage drop medido pelo ADC diferencial deveria ter um valor mais exacto, mas nem por isso, difere ainda mais do valor lido com o DMM que as contas feitas só com a medida do ADC do AVR. :-(
É claro que o DMM não é um Fluke nem nada que se pareça, é um Aneng Q1, mas tenho que usar alguma coisa como referência, só que assim fica difícil saber em que sentido é que tenho que remar. :-(

Quão confiáveis serão resistências (supostamente) de 1% compradas da China ? Podia usar para aferir o DMM, se confiasse nelas. :-(
Tenho uma caixinha destas https://www.ebay.com/itm/322561303898 que supostamente tb é feita com resistências de 1%, será mais confiável que as outras compradas por atacado ???

Pagar 2.30+5.09 USD por 1 (***UMA***) resistência de 0.1% vinda dos USA está completamente fora de questão.  :-P

EDIT: Depois de atualizar o esquema vejo que esta ligação diferencial não faz sentido uma vez que o Rt está ligado ao GND... wtf!!!

EDIT2: Mandei o DMM ás urtigas, e estou simplesmente a medir a caixa de resistências, está a fazer muito mais sentido... :-)
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 28 de Outubro de 2018, 00:01
Sobre a função que lê o valor do Vcc, tenho uma duvida...
Pelo que percebo usa a referência de 1.1V (REFS0) para ler o valor do Vcc, mas será que isso não vai deixar o ADC nessa referência ? Não deveria guardar o valor da referência anterior e voltar a repor na saída ?

A função é esta, e funciona bem num arduino Nano, reporta 4.7V quando alimentado por USB e 5.1V quando alimentado pelo pino Vin.
Pelo que verifico depois, não me parece que o ADC fique na ref de 1.1V, só não consigo perceber porque é que não fica, eu diria que precisaria de um   ADMUX = _BV(REFS1) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); antes do return().
Mas experimentei colocar esse codigo, e nada se alterou, os valores que são lidos depois continuam a retornar os mesmos valores, não faz diferença nem deixa de fazer. mas não percebo porquê.

Código: [Seleccione]
long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1125300L / result; // Back-calculate AVcc in mV
  return(result);
}
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 28 de Outubro de 2018, 00:25
Tens de ler a secção do ADC na datasheet. Essa função usa Vref = AVcc e faz a leitura da entrada 1110b do (multiplexer analógico do) ADC, que corresponde à tensão de referência 1V1.

Se vires o diagrama no inicio da secção, vês que a "bandgap reference" também é uma entrada possível para o ADC. No diagrama pode ser confuso para quem está descontextualizado por causa de não usarem os mesmos nomes, mas no texto certamente está mais claro. A "bandgap reference" e a "INTERNAL 1.1V REFERENCE" são a mesma, isso podia estar melhor no diagrama.

"Bandgap" (https://en.wikipedia.org/wiki/Bandgap_voltage_reference) é o nome da topologia do circuito de geração da tensão de referência (acho que é o que se usa hoje em dia em todos os chips).
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: senso em 28 de Outubro de 2018, 00:42
E se metes mais de 1.1v num pino com o Vref a 1.1v pode dar torresmos..

E a referência de 1.1v tem 20% de margem de erro, é tudo menos uma referência digna desse nome..
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 28 de Outubro de 2018, 00:49
Entretanto alterei o meu post acima pois inicialmente não tinha percebido o que é que a função estava a fazer.

Acho que não há problema meter mais de 1.1V num pino de entrada de ADC se a Vref do ADC estiver a 1.1V, não me lembro de ver nada disso na datasheet. O que acontece é que a contagem é sempre o valor máximo.

Sim, a "precisão inicial" da referência interna do AVR é de 1 a 1.2V, portanto 1.1V +/- 10% (é mais habitual dizer +/-X% do que 2X%). A vantagem é que ela varia pouco (não tão pouco como a de alguns AVR mais antigos... é verdade que a referência interna dos AVR é um bocado uma anedota comparado com a de outros micros que há hoje em dia). O chip referência de tensão mais "top" do mercado, usado em multímetros de 6 dígitos e meio, tem 2% de precisão inicial.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 28 de Outubro de 2018, 16:30
Já li tantas vezes a parte do ADC da datasheet que acho que vou imprimir e mandar encadernar... :-)

Acho que não perceberam o que eu estava a perguntar.

Essa função, que é usada para ler o Vcc do arduino usa a ref.interna de 1.1v.  ->  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);

Logo, como é possível que:

a) Leia corretamente valores acima de 1.1 V, já testei com USB e dá 4.7 V e com 5V diretos ao pino +5V dá 5.1V

b) Como é que, depois de terminar, não deixa o arduino configurado na ref. de 1.1V ?
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: jm_araujo em 28 de Outubro de 2018, 16:40
Pelo que entendi, acho que percebeste mal essa leitura.
O que faz é ler os 1.1V com a referência do Vcc. Faz a operação invertida ao  que dizes. Por isso quando acaba deixa a referência como Vcc e não como 1.1V

Agora estou no telemóvel e é difícil fazer explicações mais longas, mas se não fui claro diz qq coisa que logo tento desenvolver (se não aparecer ninguém primeiro)
 
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 28 de Outubro de 2018, 16:45
Tu é que ainda não percebeste, Vasco :)
A função usa a alimentação do AVR como Vref (REFS[1:0] = 01b = "AVCC with external capacitor at AREF pin", tabela 28-3 da datasheet), e está a medir e Vref interna de 1.1V, pois uma das entradas do MUX (MUX[3:0] = 1110b = "1.1V (VBG)"*, tabela 28-4) está ligada a ela e permite lê-la. Ou seja, o ADC tem uma Vref de 5V (estás a alimentar o AVR a 5V, acho) e está a ler um valor que anda em torno de 1.1V, portanto não há problema nenhum.

Citar
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);

Isto faz REFS[1:0] = 01b e MUX[3:0] = 1110b


*VBG = Vbandgap
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 28 de Outubro de 2018, 19:00
Daaaaa...

(https://lusorobotica.com/index.php?action=dlattach;topic=9414.0;attach=4572)

Vou continuar a ler... eventualmente chego lá.... jezzzzzusss...

Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 28 de Outubro de 2018, 20:36
Assim.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 29 de Outubro de 2018, 14:45
Realmente estava a ver a coisa ao contrário, achei que estavam a usar a ref de 1.1V para ler o AVcc. É escarafunchoso fazer a coisa desta maneira. Mas, obviamente é uma solução válida.

Entretanto tentei criar a minha própria referência para poder compensar as diferenças entre diferentes arduinos Nano. Usei uma referência LT-1004-2.5 e duas resistências de 100K em paralelo (porque raio não fazem resistências de 50 K ????) e nas várias situações que testei tenho sempre o mesmo valor.
No entanto, o facto é que não sei como usar esta referência para calibração.
Tentei simplesmente ler o seu valor, que numa situação ideal deveria retornar 512 e usar o valor lido para obter um offset que depois seria adicionado a todas as medições. Mas não vejo quaisquer melhoras relativamente à exatidão dos valores que estou a obter.

E faz sentido colocar um condensador de 10nF entre o AREF e o GND ?
O valor do condensador não vem na datasheet, mas encontrei varias threads sobre isso no AVRfreaks. Mas parece-me evidente que estão a falar de coisas muito mais hardcore do que aquilo que eu estou a fazer.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 29 de Outubro de 2018, 15:31
Não sei se escarafunchoso é a palavra certa, mas não é uma forma nada precisa, por causa da variação da precisão da Vref interna de 1V1, a não ser que se meça essa Vref (chip a chip) e se use o valor "exacto" nas contas.

A melhor estratégia é sempre a de calibrar o sistema como um todo, como indiquei naquele post da interpolação linear. Mas se quiseres mesmo fazer contas com a Vref interna, um DMM tem muito melhor precisão que ela, por isso podes usá-lo para fazer uma "calibração manual". Configuras o ADC para usar a "Vref interna com um cap no pino AREF", e depois medes a tensão no AREF - essa é a tensão da Vref interna. Usas o valor no teu código. Esta calibração é válida para o chip que usaste (qualquer calibração, baseada na Vref interna, o é).

Em alternativa podes automatizar um pouco mais a calibração, usando uma tensão de referência externa de maior precisão, como esse LT1004-2.5 (espero que seja muito barato, pois 20mV de erro não é nada de especial). Aí ligas essa referência a um pino entrada de ADC e fazes a leitura com a Vref interna. Sabendo tu a tensão que estás a medir, resolves a equação em ordem à Vref interna, que então usas nas contas (eu costumo fazer um programa para calibrar, que guarda o valor da Vref na EEPROM, e depois o"programa principal" lê-o de lá).
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 29 de Outubro de 2018, 16:23
Ah, em relação ao condensador no AREF, eu costumo meter 100nF, mas acho que 10nF tb deve servir.

O condensador serve para ajudar a estabilizar ainda mais a Vref, isto é importante para reduzir os erros na conversão. A Vref dos ADC deve ser "rock solid", ou seja, ter um valor o mais estável possível.

Agora, se o deves fazer ou não, depende. Há um detalhe. Quanto maior for a capacitância, maior é o tempo que demora a mudar a Vref do ADC (por exemplo de AVcc para Vref interna ou vice-versa). Se usas sempre a mesma Vref no teu programa isto não é um problema, mas se tens que trocar de Vref então tens que ter isso em conta.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 29 de Outubro de 2018, 18:59
10nF ou 100nF não me faz diferença, embora num estágio mais avançado possa pensar mudar para a refª de 1.1 quando tiver que medir uma voltagem abaixo de 1 V (como faz o Transistor Tester) para esta aplicação não tenho qualquer problema em esperar que a referência estabilize.
Um LT-1004-2.5 custa cerca de 1.5€, provavelmente haveria maneiras mais baratas mas eu já tenho confusão que chegue dentro da cabeça.
Gostaria de conseguir automatizar a calibração o mais possível, para a coisa poder funcionar com qualquer Nano, entre dois que tenho por aqui que são claramente de fornadas diferentes até o valor do Vcc (quando ligados por USB na mesma porta e com o mesmo cabo) muda significativamente.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: senso em 29 de Outubro de 2018, 19:50
Eu utilizava uma ferrite e um condensador de 1uF , está na datasheet algures.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 29 de Outubro de 2018, 22:40
Encontro na figura 28-9 "ADC Power connections" que o pino AVCC teria um condensador de 100nF ao GND e ligação ao VCC via uma bobine de 10uH... Será isto a que te referes ?
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 29 de Outubro de 2018, 22:55
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.

Não me lembro da ferrite nem cap de 1u na datasheet. Isso que o Vasco fala é relacionado com o ADC mas não é do que o senso está a falar.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: senso em 30 de Outubro de 2018, 00:00
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.

Se bem que depois apanhei o hábito de utilizar LM4040 de 2.048 em sistemas 3.3v ou de 4.096v em sistemas 5v, é baratissimo comparado com a limpeza que dá em arredondamentos.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 30 de Outubro de 2018, 00:25
Em alternativa podes automatizar um pouco mais a calibração, usando uma tensão de referência externa de maior precisão, como esse LT1004-2.5 (espero que seja muito barato, pois 20mV de erro não é nada de especial). Aí ligas essa referência a um pino entrada de ADC e fazes a leitura com a Vref interna. Sabendo tu a tensão que estás a medir, resolves a equação em ordem à Vref interna, que então usas nas contas (eu costumo fazer um programa para calibrar, que guarda o valor da Vref na EEPROM, e depois o"programa principal" lê-o de lá).

Era essa a minha ideia e foi assim que liguei o lt1004.

Tentei calcular o Vcc com base na ref de 2.485V no pino A1, mas falhei miseravelmente... :-(
Dá-me 7.657V de Vcc
Julgo que   ADMUX = _BV(REFS0) | (A1 & 7); quer dizer para ler o pino A1 usando Vcc como referência, certo ?

Código: [Seleccione]
long readVcc_25() {
  long result;
  // Read 2.485V reference in pin A1 against AVcc
  ADMUX = _BV(REFS0) | (A1 & 7);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = (2.485*1023*1000) / result; // Back-calculate AVcc in mV    <===== WRONG !!!!!
  return(result);
}

Nota: o 1023 em vez de 1024 vem da função original onde 1125300 = 1.1*1023*1000
Nota2: Grande referência para o ADC - http://www.gammon.com.au/adc
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 30 de Outubro de 2018, 00:55
Tentei calcular o Vcc com base na ref de 2.485V no pino A1, mas falhei miseravelmente... :-(
Dá-me 7.657V de Vcc
Julgo que   ADMUX = _BV(REFS0) | (A1 & 7); quer dizer para ler o pino A1 usando Vcc como referência, certo ?

A1? Onde foste buscar isso? Estás a misturar coisas de Arduino, parece-me... Os nomes dos bits para selecionar a entrada do multiplexer analógico no registo ADMUX são MUX0 a MUX3 (datasheet... e é o que está a ser usado no código original e é o que temos estado a usar), e tens que converter o número do bit (é o que as macros de nomes de bits num registo são) numa bitmask, com a _BV (Bit Value) por exemplo.

Depois tens que ADCcounts = Vpin * 2ADCbits / Vref daí que Vref = Vpin * 2ADCbits / ADCcounts .
Em mV é multiplicar o resultado por 1000, ou melhor, multiplicar antes de dividir pelo ADCcounts e somar ADCcounts/2 também antes de dividir para melhorar a precisão. Como vês, Vpin * 2ADCbits * 1000, na tua aplicação é uma constante.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco 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
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay 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);
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay 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.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco 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. :-)
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco 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

Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: senso 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.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco 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.


Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: senso 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..

Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: jm_araujo 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.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco 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.

Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco 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.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco 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.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: senso 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 :(
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco 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.

Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay 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?
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 07 de Novembro de 2018, 00:25
Medindo a minha referência com os dois Aneng tenho estes valores.
Considerando que o AD584JH não tem grande exatidão (+-30mv @10.V, +-20mV @7.5V, +-15mV @5V e +-7.5 @2.5V), não hesito muito em classificar o resultado como 'good enough'

Código: [Seleccione]
ANENG 8002 2.500 5.000 07.50 10.00
AMENG Q1 2.498 4.998 7.498 09.99

A referência vinha com um papelucho escrito à mão, supostamente as medidas feitas com um multímetro decente, mas infelizmente não sei dele, devia ter tirado logo uma foto. :-(
O detalhe que falta referir é que a referencia estava alimentada por 12V a partir de um buck/boost converter, não tenho nenhuma bateria de 12V.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 07 de Novembro de 2018, 00:43
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?

Sim, faço a média aritmética.
Esperimentei fazer um "bonito", se a voltagem lida for abaixo de 1.0V, volto a fazer a leitura usando a referência interna. Mas devo estar a cometer algum erro, porque retorna sempre um valor substancialmente mais baixo, por exemplo 0.00450 -> 0.00105.
E a minha leitura da referência interna dá-me 1.3242, não é suposto ser entre 1.0 e 1.2 ???
TODO: Acertar os types, está uma confusão de longs e floats... :-(
SAMPLES é um #define, atualmente 128.
Decididamente entendo-me melhor definido um registo com um valor binário do que usando o _BV
O offset soma (atualmente) 1 a todas as leituras do ADC.

Código: [Seleccione]
float read_V(int pin, bool add_offset)
{
  uint16_t X;
  float XV;
  X=read_U(pin, add_offset);
  XV=( (X*Vin)/1024.0 );
  return(XV);
}


float read_V_bg(int pin, bool add_offset)
{
  uint16_t X;
  float XV;
  X=read_U_bg(pin, add_offset);
  XV=( (X*(VREF11_mv/1000.0))/1024.0 );
  return(XV);
}

uint16_t read_U(int pin, bool add_offset)
{
  uint32_t  X;
  float tot=0, med=0;
  int f;

  ADMUX=B01000000; // AVCC with external capacitor at AREF pin
  delay(5);
  X=analogRead(pin); // dummy read
  delay(1);
 
  for(f=0;f<SAMPLES;f++)
  {
    X=analogRead(pin);
    tot+=X;
  }
  med=tot/SAMPLES;
  if(add_offset) med+=offset;
  return((uint16_t)med);
}

uint16_t read_U_bg(int pin, bool add_offset)
{
  uint32_t  X;
  float tot=0, med=0;
  int f;

//  ADMUX=_BV(REFS1)|_BV(REFS0);
  ADMUX=B11000000; //Internal 1.1V voltage reference with external capacitor at AREF pin
  delay(5);
  X=analogRead(pin); // dummy read
  delay(1);
  for(f=0;f<SAMPLES;f++)
  {
    X=analogRead(pin);
    tot+=X;
  }
  med=tot/SAMPLES;
  if(add_offset) med+=offset;
  delay(5);
  return((uint16_t)med);
}

long read11ref() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  return((long)(result*Vin_mv)/1024L);
}
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 07 de Novembro de 2018, 03:37
Esse papelucho era importante... pode até valer mais que o próprio hw.

Não é boa ideia alimentar uma fonte de referência com uma fonte comutada, este tipo de fonte tem muito ruído à saída.

Sim, faço a média aritmética.
Esperimentei fazer um "bonito", se a voltagem lida for abaixo de 1.0V, volto a fazer a leitura usando a referência interna. Mas devo estar a cometer algum erro, porque retorna sempre um valor substancialmente mais baixo, por exemplo 0.00450 -> 0.00105.

Já fiz isso mas ao contrário, resulta em melhor aproveitamento da Vref interna. Isto é um bocado de código dum outro AVR mais pequeno (tem umas chamadas que só manipulam registos) mas o ADC é quase igual (é deste projecto (http://embeddeddreams.com/site/wp-content/uploads/2008/09/ed1001.pdf)):

// Read the scale limits. When checking TOPSCALE try 1st with Vref = 2V7.
// If read is saturated (all 1's) then switch to Vref = Vcc and re-read.
// The selected Vref will be used on the remaining conversions.
adc_CfgInputPin (eADC7, eSingleEnd);
adc_SetVRef (e2V56);
adc_DoSingleConversion10();     // discard 1st conversion after Vref switch
top = readADC();
if (top >= 1023)
{
    adc_SetVRef (eAVcc);
    adc_DoSingleConversion10();     // discard 1st conversion after Vref switch
    top = readADC();
}


Citar
E a minha leitura da referência interna dá-me 1.3242, não é suposto ser entre 1.0 e 1.2 ???

Sim, entre 1 e 1.2V. É melhor ligares à ATMEL a reportar que eles têm um bug no chip :)

1.2V / 5V * 1024 ~ 246
246 * 5.5V / 1024 ~ 1.316V
é uma hipótese, com outras fontes de erro adicionais, quem sabe

De qualquer forma parece-me irrelevante estar a medir a fonte de tensão interna com a de alimentação... ela tem que ser medida com precisão e o Vcc tipicamente pode ser tudo menos preciso (tu próprio já viste o quanto variam as fontes de 5V e, pela spec, podem variar +/-10%).

Citar
TODO: Acertar os types, está uma confusão de longs e floats... :-(

Ya, devia ser tudo (u)int16/32_t.

Citar
SAMPLES é um #define, atualmente 128.
Decididamente entendo-me melhor definido um registo com um valor binário do que usando o _BV
O offset soma (atualmente) 1 a todas as leituras do ADC.

Código: [Seleccione]
float read_V(int pin, bool add_offset)
{
  uint16_t X;
  float XV;
  X=read_U(pin, add_offset);
  XV=( (X*Vin)/1024.0 );

(...)

long read11ref() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  return((long)(result*Vin_mv)/1024L);
}

Não sei como consegues ler o código com tudo tão encavalitado e indentação a 2 espaços. Não tens sentido os olhos cansados ;)?
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 07 de Novembro de 2018, 23:08
Esse papelucho era importante... pode até valer mais que o próprio hw.

Pois, eu sei, não o devo ter deitado fora, resta saber onde terá ido parar, costumo tirar uma foto logo a essas coisas, mas neste caso parece que não :-(

Citar
Não é boa ideia alimentar uma fonte de referência com uma fonte comutada, este tipo de fonte tem muito ruído à saída.

Também sei isso, mas a alimentação desta ref é suposto ser entre 12 e 15V, o melhor que tinha aqui era uma pilha de 9V, de qq modo, os resultados não são maus.

Já fiz isso mas ao contrário, resulta em melhor aproveitamento da Vref interna. Isto é um bocado de código dum outro AVR mais pequeno (tem umas chamadas que só manipulam registos) mas o ADC é quase igual (é deste projecto (http://embeddeddreams.com/site/wp-content/uploads/2008/09/ed1001.pdf)):

No meu caso a maior parte dos valores lidos é sempre acima de 1V, portanto acho que faz mais sentido assim.

Citar
Citar
E a minha leitura da referência interna dá-me 1.3242, não é suposto ser entre 1.0 e 1.2 ???

Sim, entre 1 e 1.2V. É melhor ligares à ATMEL a reportar que eles têm um bug no chip :)

1.2V / 5V * 1024 ~ 246
246 * 5.5V / 1024 ~ 1.316V
é uma hipótese, com outras fontes de erro adicionais, quem sabe

De qualquer forma parece-me irrelevante estar a medir a fonte de tensão interna com a de alimentação... ela tem que ser medida com precisão e o Vcc tipicamente pode ser tudo menos preciso (tu próprio já viste o quanto variam as fontes de 5V e, pela spec, podem variar +/-10%).

A minha ideia é
a) Medir o Vcc usando a "minha" referencia. Vcc é calculado com result = (2485*1023L) / ADC_result;
b) Confirmar o Vcc voltando a medir a referência, aqui está a falhar por muito, neste momento estou a medir 3441 em vez dos 2485.

Ao menos estou a medir valores consistentes (embora errados) entre Nanos diferentes. :-)
Não vou avançar muito enquanto não perceber o que se passa aqui...

Citar
Não sei como consegues ler o código com tudo tão encavalitado e indentação a 2 espaços. Não tens sentido os olhos cansados ;)?

Não consigo, odeio completamente o Arduino IDE, meu querido vi. Entretanto, como falaste no assunto fui meter o nariz no preferences.txt e lá dá para mudar o tamanho dos tabs, e acima de tudo para desligar a feature em que o editor transforma os tabs em espaços. Ficou ligeiramente melhor.

Já meti o avr-gcc a bombar numa VM linux, ligo-me à VM com o putty e sinto-me em casa, consigo compliar coisas e programar o nano, mas é preciso tomates para largar o layer do Arduino, não só de perdem coisas que dão um jeitão como o pinMode() como também há o problema das libs, onde é que eu encontro uma lib para o oled que seja independente do Arduino? Estou a usar uma chamada SSD1306Ascii (sobre I2C), mas não vai ser amanhã que vou conseguir portar aquilo... :-P
Só me apercebi da complexidade real do layer da Arduino quando vi como era complicado fazer uma função como o pinMode() onde passas o nome de um pino e de alguma maneira isso tem que ser transformado num bit dentro de um port.

Também estou a olhar para o LoseAVR, um fork do WinAVR, pode ser que me ajeite melhor.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: senso em 08 de Novembro de 2018, 00:05
Google?

ssd1306 avr library, primeiro hit:

C++(arduines?):
https://github.com/tibounise/SSD1306-AVR

C:

https://github.com/efthymios-ks/AVR-SSD1306-Library

De resto, para IO's anda por ai um post meu com meia duzia de tutoriais, é para o Avr Studio 4 que já morreu, mas é seguivel, digo eu.

E vi, meh, depois de utilizar IDE's dignos desse nome não ter N mordomias nunca mais peguei no vim, dá para o tornar mais utilizavel, mas não é coisa que me fascine actualmente, prefiro abrir um Eclipse/Visual Studio e ter a papinha feita, e o Intelisense é efectivamente fantástico, o gajo aprende e depressa o que raio queres chamar a seguir a escrever meia duzia de letras.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: Njay em 08 de Novembro de 2018, 01:34
Pode-se usar um editor de texto qualquer e continuar a usar o IDE do Arduino apenas para compilar. Está uma opção para isso nas preferências, acho que é "external editor" ou coisa do género.

pinMode() dificil?

Digital 2 (ATmega328 PD2) como entrada:
DDRD &= ~_BV(PD2);
PORTD &= ~_BV(PD2);


Digital 2 (ATmega328 PD2) como saída:
DDRD |= _BV(PD2);

Digital 2 (ATmega328 PD2) como input pull-up:
DDRD &= ~_BV(PD2);
PORTD |= _BV(PD2);


Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: jm_araujo em 08 de Novembro de 2018, 09:14
Eu mudei-me para VSCode com plugin arduino , e git para version control (funciona mesmo sem repositório online). Tem tantas vantagens que me fizeram nunca mais querer tocar no IDE Arduino.

Antes passei pelo Platform.io (na altura com Atom, agora tb já há para VSCode), mas além de ser muito pesado, não gostei do modelo de negócio que arranjaram, tenho intenções de fazer umas cenas em ARM (STM32) e não estou para pagar para ter debugging (que em VSCode nativo não deve haver problema). Mas tenho de admitir que a gestão de bibliotecas era fixe, e para quem não se preocupa com debugging deve ser o IDE com a menor dificuldade de começar a seguir ao do Arduino.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 08 de Novembro de 2018, 13:49
Google?


Tens razão, fiz um search a seguir a fazer o post e apareceram umas coisas, vou testar.

Citar
E vi, meh, depois de utilizar IDE's dignos desse nome não ter N mordomias nunca mais peguei no vim, dá para o tornar mais utilizavel, mas não é coisa que me fascine actualmente, prefiro abrir um Eclipse/Visual Studio e ter a papinha feita, e o Intelisense é efectivamente fantástico, o gajo aprende e depressa o que raio queres chamar a seguir a escrever meia duzia de letras.

Não é uma questão de funcionalidade, é mesmo de habituação, prefiro umas pantufas confortaveis (é mentira, não uso pantufas) a uns ténis de alta competição.
Uso o vi há  uns 25 anos, praticamente todos os dias. Não uso nada de especial do vim, apesar do syntax highlight dar jeito. O que preciso é de não ter que andar ao estalo com o editor para fazer as coisas mais simples.

Em termos de windows nunca encontrei nada que me deixasse satisfeito, o gvim é uma piada, o Notepad++ usa-se, o Ultra-Edit era bom, mas deixei de usar, já não me lembro exactamente porquê.

Na verdade em termos de PC os únicos editores que estava à vontade era os da borland (Turbo pascal principalmente), mas quando passaram para windows fechei a loja de desenvolver para PC.
Também usava o brief no ms-dos, mas hj em dia já não me lembro de nada dos comandos daquilo.

Vou ver esse Intelisense.
Título: Re: leitura de voltagens com o analogRead(A0)
Enviado por: vasco em 08 de Novembro de 2018, 13:59
Pode-se usar um editor de texto qualquer e continuar a usar o IDE do Arduino apenas para compilar. Está uma opção para isso nas preferências, acho que é "external editor" ou coisa do género.

pinMode() dificil?

Não é o que o pinMode faz que é dificil, o dificil é passar-lhe o "nome" de um pino do Arduino e ele conseguir acertar com o PORT e com o bit... Só por isso tiro o chapeu aos Srs. do Arduino. Estive a olhar para vários .h de vários ARVs e não nos facilitam a vida, é tudo uma questão de mudar de perspetiva, eu sei.
Mas, por exemplo, as funções on() e off() que eu uso no meu codigo são genericas, podes simplesmente passar o nome de um pino e funcionam porque usam o pinMode, no meu nivel atual de conhecimento não sei como as fazer sem particularizar o código para cada pino.