• Welcome to LusoRobótica - Robótica em Português.
 

Torna uma ATX numa fonte segura

Started by LuísR.A., 19 de July de 2013, 13:03

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

dropes

"Tiro a média, o valor máximo e minimo."

A média não se faz somando o valor mais alto e o mais baixo dividindo a seguir por 2.
Pelo teu código estás a somar todos os valores dividindo no final pelo nº de somas, está completamente correcto.
Uma coisa que alterava era a multiplicação no loop, isso exige muito ao micro, no final teria em conta esse valor dando um resultado mais certo devido ao nº de casas decimais.

Compreendo o que o Senso está a dizer, por vezes fazem-se códigos sem pensar na performance do micro, usando potências de 2 reduz significativamente o processamento, já divisões ou multiplicações, traduz-se  numa listagem bem grande de código máquina escondida atrás do C, quem programa em assembler sabe contornar estas situações e em vez de precisar de 32k de flash, bastam 2k ou menos para a mesma tarefa.

LuísR.A.

#61
Quote from: dropes on 26 de July de 2013, 00:28

Compreendo o que o Senso está a dizer, por vezes fazem-se códigos sem pensar na performance do micro, usando potências de 2 reduz significativamente o processamento, já divisões ou multiplicações, traduz-se  numa listagem bem grande de código máquina escondida atrás do C, quem programa em assembler sabe contornar estas situações e em vez de precisar de 32k de flash, bastam 2k ou menos para a mesma tarefa.

Razão porque quero aprender C assembly mas é tão chato as vezes  :P

Aquele é o código só para tirar a média. Para saber a amplitude de valores também registo quais foram os valores mínimos e máximos.

Aqui posto o meu código completo. Pode se tornar mais eficiente como corrigir a multiplicação constante que se faz como sugeriste.
Tem uma biblioteca de C que é igual à do arduino:
float voltagem=0;
float corrente=0;


void setup(){
  Serial.begin(9600);
  pinMode(P1_3,INPUT_PULLUP);
  pinMode(P1_0,OUTPUT);
  pinMode(A6,INPUT);
  pinMode(A7,INPUT);
  analogReference(INTERNAL1V5); // INTERNAL1V5, INTERNAL2V5, EXTERNAL
}

void loop(){
  digitalWrite(P1_0,0);              //desliga o LED vermelho
  while((digitalRead(P1_3))==1){//Espera que se clique no botão
  }
  digitalWrite(P1_0,1);             //liga o LED vermelho
  Serial.println("Voltagem");      //Envia uma palavra para saber que o serial está a funcionar
  while(1){
    float volt = 0;                 
    float voltagemmax=0;
    float voltagemmin=20;
    voltagem=0;
    for(int i=0;i<16;i++){
      voltagem=voltagem+((analogRead(A6))*(0.01955)); //20V
      volt=(analogRead(A6))*(0.01955); //20V
     // delay(1);
      if ((volt > voltagemmax) && (volt < 20)){
        voltagemmax=volt;
        count=i;
      }
      else if((volt < voltagemmin) && (volt > 0)){
        voltagemmin=volt;
      }
      delay(1);   
    }
   
    voltagem=voltagem/16;
    Serial.print("media: ");     
    Serial.print(voltagem,3);
    Serial.println("V");
    Serial.print("voltagem max: ");   
    Serial.print(voltagemmax,3);
    Serial.println("V");
    Serial.print("voltagem min: ");   
    Serial.print(voltagemmin,3);
    Serial.println("V");
    Serial.println(" ");   
    delay(500);
  }
}
Tiva MCU é que é.

Tutoriais Tiva+codigos exemplo:
https://sites.google.com/site/luiselectronicprojects/

dropes

Não sei porque tiras a tensão máxima e mínima das medições, a variação não deve passar 2 ou 3 valores.
A variável "count" não é usada em nenhum local.

"if ((volt > voltagemmax) && (volt < 20))" não necessita de "&& (volt < 20)" assim como
"if ((volt < voltagemmin) && (volt > 0))" não necessita de "&& (volt > 0)"

Continuam a existir multiplicações dentro do loop.

No final tens "voltagem=voltagem/16", trata-se de uma divisão que pode ser substituída por "voltagem = voltagem >> 4"

LuísR.A.

#63
Quote from: dropes on 26 de July de 2013, 00:53
Não sei porque tiras a tensão máxima e mínima das medições, a variação não deve passar 2 ou 3 valores.
A variável "count" não é usada em nenhum local.
Era só para ver agora para ver, não irá para o codigo final. Era para ver se os valores eram muito instaveis mas não são. (a count era para outra coisa que esqueci de remover quando passei para aqui).

Quote from: dropes on 26 de July de 2013, 00:53
No final tens "voltagem=voltagem/16", trata-se de uma divisão que pode ser substituída por "voltagem = voltagem >> 4"

Ai está algo que não sei porque. Tenho de ir ver como funciona isso. Mas reparei que 16=2^4.
Obrigado
Tiva MCU é que é.

Tutoriais Tiva+codigos exemplo:
https://sites.google.com/site/luiselectronicprojects/

senso

Não uses shifts(está explicado por exemplo nos meus tutoriais sobre programação de avr's na parte de bitwise math), enquanto não entenderes o que estás a fazer, o compilador normalmente trata de optimizar o código o melhor possivel(consoante as flags que lhe passas), mas como dizia o Knuth:
Premature optimization is the root of all evil.
Não tentes ser mais inteligente que o compilador para mais numa matéria que não dominas.
Avr fanboy

dropes

Que mal têm os shifts, sempre é melhor que realizar divisões?!

LuísR.A.

O que o sensor quer dizer é que não devo usar algo que não domino senão corre mal.
Eu concordo mas vou ver coisas sobre o assunto.

Vamos dizer de outra maneira, eu vou agora para universidade e só tive um curso normal de ciencias e tecnologias. Só aprendi Basic do mais basico (usei pouca coisa) e muito do C foi em casa e aqui com todos vocês. Logo é preciso calma
Tiva MCU é que é.

Tutoriais Tiva+codigos exemplo:
https://sites.google.com/site/luiselectronicprojects/

Njay

Podes usar a referência que quiseres, tudo depende de quão preciso e estável queres as tuas leituras :)
Uma referência baratucha é o TL431 (por exemplo na minha loja são 0,30€), a versão normal tem 2% de tolerância mas é estável. Só que terias que o calibrar bem, pois com esse divisor tão grande de tensão que tens (queres medir o quê, até 50V?), 50mV de erro na referência corresponde a ~1V de erro do valor real. Por outro lado, calibrar por calibrar também podes calibrar a referência interna do micro e usá-la.

Não sei o que se passa com a cena do condensador, eu colocaria no lugar de C2. A resistência de 100K é que é grande, pode ser demasiado alta para fazeres leituras do ADC a essa velocidade. Experimenta fazer 1 leitura de ADC a cada 0.1s.

Quanto às optimizações de código, deixa isso para depois de estar tudo a funcionar como queres ;)

senso

Quote from: dropes on 26 de July de 2013, 01:08
Que mal têm os shifts, sempre é melhor que realizar divisões?!

Não têm mal absolutamente nenhum, mas o compilador garantidamente que te optimiza a divisão de um inteiro por uma potência de 2 para shifts.
Mas o rapaz não domina totalmente a coisa, e imagina que ele se lembra de mudar a variavel para double/float, ups o código deixa de funcionar e passa a dar valores ultra estranhos, com uma divisão funciona sempre, com shifts, nem sempre.
O que disse foi simplesmente que é uma armadilha para os menos experientes, e que por enquanto ele não deve fazer isso.
Avr fanboy

senso

Esse micro não tem PGA?
Seria o ideal, fazer um auto-range passando da amplificação mais baixa(calculando o valor que se está a ler para não se ter overflows no adc) e ir aumentando a amplificação do sinal para que tires o máximo partido da gama dinâmica do ADC do micro.

E usar um op-amp como buffer tambem não era pior ideia(antes da entrada para a ADC), porque realmente 100k acaba por dar uma corrente minuscula para o ADC carregar o condensador de sample and hold.
Avr fanboy

LuísR.A.

Quote from: Njay on 26 de July de 2013, 01:11

Quanto às optimizações de código, deixa isso para depois de estar tudo a funcionar como queres ;)

É o que pretendo mas pode-se ir aprendendo coisas  ;D

A resolução máxima é 20V. Não espero uma precisão astronomica. Só estou a tentar ter a melhor resolução, e precisão, possivel a um bom preço. Importa-me mais ser preciso a 100mV pelo menos
Pois isto do ADC leio sobre muito mais grandezas e características que não conheço como impedância e tal. (não vale a pena meter-me nisso agora já é muita coisa por hoje)
Poderei diminuir a resistencia, apenas usei esta porque permite usar um trimmer de 10k para calibrar. Mas acho que posso diminuir mais o valor.
Vou experimentar diminuir a velocidade.
Tiva MCU é que é.

Tutoriais Tiva+codigos exemplo:
https://sites.google.com/site/luiselectronicprojects/

dropes

Retiro o que disse, shifts em números reais dá barraca, nem tinha reparado nisso  :-[
Tenho de deixar o assembler e actualizar-me  :P

LuísR.A.

#72
Quote from: senso on 26 de July de 2013, 01:17
Esse micro não tem PGA?
Seria o ideal, fazer um auto-range passando da amplificação mais baixa(calculando o valor que se está a ler para não se ter overflows no adc) e ir aumentando a amplificação do sinal para que tires o máximo partido da gama dinâmica do ADC do micro.

E usar um op-amp como buffer tambem não era pior ideia(antes da entrada para a ADC), porque realmente 100k acaba por dar uma corrente minuscula para o ADC carregar o condensador de sample and hold.

O meu micro é para funcionar facilmente com correntes muito baixas mesmo e vi um tutorial que usava uma de 82k em vez a de 100k. Poderei usar de 50k pelas minhas contas.
Do ADC só sei que a capacitancia é 27pF

PGA? tenho de ver primeiro o que é
Tiva MCU é que é.

Tutoriais Tiva+codigos exemplo:
https://sites.google.com/site/luiselectronicprojects/

LuísR.A.

Quote from: senso on 26 de July de 2013, 01:15
Quote from: dropes on 26 de July de 2013, 01:08
Que mal têm os shifts, sempre é melhor que realizar divisões?!

Não têm mal absolutamente nenhum, mas o compilador garantidamente que te optimiza a divisão de um inteiro por uma potência de 2 para shifts.
Mas o rapaz não domina totalmente a coisa, e imagina que ele se lembra de mudar a variavel para double/float, ups o código deixa de funcionar e passa a dar valores ultra estranhos, com uma divisão funciona sempre, com shifts, nem sempre.
O que disse foi simplesmente que é uma armadilha para os menos experientes, e que por enquanto ele não deve fazer isso.

Nem deixa errar. O compilador deu logo erro quando deixei ficar float "mete la int que tá mal!", foi mais ou menos isso que tava la escrito
Tiva MCU é que é.

Tutoriais Tiva+codigos exemplo:
https://sites.google.com/site/luiselectronicprojects/

LuísR.A.

Vi +- o que é um PGA. O meu uControlador não tem integrado um PGA.
Podia usar um externo mas não queria estar a complicar mais.
Poderei fazer o mesmo com 1 divisor de tensão para cada escala. Com um diodo zener no ADC não haverá problemas. Sempre que a escala fica ao máximo passa para a próxima.

Tiva MCU é que é.

Tutoriais Tiva+codigos exemplo:
https://sites.google.com/site/luiselectronicprojects/