collapse

* Posts Recentes

Power spike on power off por vasco
[Ontem às 23:49]


LusoRobótica - Website - Estado actual por vasco
[Ontem às 14:10]


Circuito para distinguir fase do neutro por TigPT
[Ontem às 14:04]


Vídeo sobre o projecto e a montagem de um conversor 12VDC - 230VAC por senso
[19 de Novembro de 2018, 15:39]


Compra Colectiva Mouser N3-2018 (limite 25 Nov) por Hugu
[19 de Novembro de 2018, 01:01]


Vídeo - selecção da uma fonte de alimentação em substituição de um transformador por vasco
[18 de Novembro de 2018, 16:21]


Placa BMS Desliga por jm_araujo
[17 de Novembro de 2018, 22:36]


Vende-se MUITO e BOM material por m90mine
[13 de Novembro de 2018, 23:32]


leitura de voltagens com o analogRead(A0) por vasco
[08 de Novembro de 2018, 13:59]


Controlar Velocidade Motor AC por senso
[06 de Novembro de 2018, 23:05]

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

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

Online vasco

  • Mini Robot
  • *
  • Mensagens: 319
Re: leitura de voltagens com o analogRead(A0)
« Responder #75 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.
Stupid men are often capable of things the clever wouldn't dare to contemplate.

Online vasco

  • Mini Robot
  • *
  • Mensagens: 319
Re: leitura de voltagens com o analogRead(A0)
« Responder #76 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);
}
Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.385
    • Tróniquices
Re: leitura de voltagens com o analogRead(A0)
« Responder #77 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):

// 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 ;)?

Online vasco

  • Mini Robot
  • *
  • Mensagens: 319
Re: leitura de voltagens com o analogRead(A0)
« Responder #78 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):

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.
Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.578
  • Helpdesk do sitio
Re: leitura de voltagens com o analogRead(A0)
« Responder #79 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.
Avr fanboy

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.385
    • Tróniquices
Re: leitura de voltagens com o analogRead(A0)
« Responder #80 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);



Offline jm_araujo

  • Mini Robot
  • *
  • Mensagens: 2.418
  • NERD!
Re: leitura de voltagens com o analogRead(A0)
« Responder #81 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.

Online vasco

  • Mini Robot
  • *
  • Mensagens: 319
Re: leitura de voltagens com o analogRead(A0)
« Responder #82 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.
Stupid men are often capable of things the clever wouldn't dare to contemplate.

Online vasco

  • Mini Robot
  • *
  • Mensagens: 319
Re: leitura de voltagens com o analogRead(A0)
« Responder #83 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.
Stupid men are often capable of things the clever wouldn't dare to contemplate.