Ir ao conteúdo

Posts recomendados

  • Membro VIP
Postado

Este Vídeo

https://i.imgur.com/fzhdqSn.mp4

foi feito a partir deste fonte:

#include <ioavr.h>

#define B8__(x) ((x&0x0000000fLU)?1:0) \
+((x&0x000000f0LU)?2:0) \
+((x&0x00000f00LU)?4:0) \
+((x&0x0000f000LU)?8:0) \
+((x&0x000f0000LU)?16:0) \
+((x&0x00f00000LU)?32:0) \
+((x&0x0f000000LU)?64:0) \
+((x&0xf0000000LU)?128:0)
#define HEX__(n) 0x##n##LU
#define b8(d) ((unsigned char)B8__(HEX__(d)))
/* for upto 16-bit binary constants, MSB first */
#define b16(dmsb,dlsb) (((unsigned short)b8(dmsb)<< \
+ b8(dlsb))
/* for upto 32-bit binary constants, MSB first */
#define b32(dmsb,db2,db3,dlsb) (((unsigned long)b8(dmsb)<<24) \
+ ((unsigned long)b8(db2)<<16) \
+ ((unsigned long)b8(db3)<< \
+ b8(dlsb))
/* Sample usage:
b8(01010101) = 85
b16(10101010,01010101) = 43605
b32(10000000,11111111,10101010,01010101) = 2164238933
*/

#define SinDivisions 32 //200
#define microMHz 16
#define freq 60   
#define period microMHz*1e6/freq/SinDivisions

unsigned int const tab_sen[]=
{
0,349,694,1031,1356,1667,1960,2231,2478,
2697,2887,3046,3171,3261,3316,3334
};

unsigned char tmp;
unsigned char num;
unsigned char trig;
unsigned char led;
unsigned int a0;
static unsigned char dtrig;
float Vac;

void setup()
{
  TCCR1A = b8(10110010);
  TCCR1B = b8(00011001);
  TIMSK1 = b8(00000001);
  ICR1   = period;   
  DDRB = b8(11111111);//tudo saída
  DDRC = b8(11111110);//PORTC0=entrada analógica
  DDRD = b8(11111111);//tudo saída
  ADCSRA=b8(10000111); //hab. adc, prescaler 128
  ADMUX=b8(01000000); //ref=vcc
  asm("sei"); //hab. interrupção            
}

#pragma vector = TIMER1_OVF_vect
__interrupt void basic_timer(void) 
{
tmp=num; //1º quadrante de 0 a 90º
if (num>=16) tmp=16-num;//2º
if (num>=32) tmp=num-32;//3º
if (num>=48) tmp=48-num;//4º

OCR1A=OCR1B=tab_sen[tmp]; //alimenta hw com seno
if (num==31)//sincronia com o loop
  {
  if (trig++>15) {trig=0;PORTB_Bit5^=1;}//led tô vivo em PB5
  }
if (num==16) dtrig=0xff;
if (num++>63) num=0;//fim da tabela
} 

unsigned int analogRead(unsigned char ch)
{
unsigned int result;
ADMUX=b8(01000000)|ch;
// delay_ms needed for the stabilization of the ADC input voltage
ch=20; //aproveita variável pra dar um atraso
while(ch--);// asm("NOP");
// Start the AD conversion
//ADCSRA|=b8(01000000); ou ADCSRA_Bit6=1; ou...
ADCSRA_ADSC=1;
// Wait for the AD conversion to complete
//while (ADCSRA&b8(01000000)) ou while(ADCSRA_Bit6); ou..
while(ADCSRA_ADSC);// asm("NOP");
result=ADCL; //o hw do mc exige que se capture ADCL primeiro
result+=(unsigned int)ADCH*256;
return result;//ADCL+ADCH*256;
}

void main(void)
{
setup();
for(;;)
{
while(dtrig==0);// asm("NOP");// sinc. com interrupt   
a0=analogRead(0); //captura logo após atingir Vp
PORTD_Bit7=1; //só pra mostrar o momento da captura
PORTD_Bit7=0;//no osciloscópio
dtrig=0; //aguardar momento Vp
//Serial.print("Ad=");
//Serial.print(a0);
//Vac=((float)a0*0.03447);
//Serial.print(" Vac=");
//Serial.println(Vac);
}

}

Extremamente minimalista: não precisei fazer 'adaptação técnica' - funcionou como manda o figurino da linguagem - , ocupou 560 bytes em contraste aos 4K do arduino. Perceba que apenas 16 senos em cada quadrante já compõem a onda senoidal pura. Como se repetem, o pulo do gato [original] foi indexá-los de acordo com sua posição. Vide comentários no fonte. Também este compilador não possui notação binária 0b1010101.. Não contava com a astúcia  de algum "sem noção" mas com muita noção e tempo que criou aquelas intricadas e inexplicáveis macros b8(1010101) pra nós.

Perceba a variação da senoide em função da carga bem como os valores ADCH e ADCL lidos na janela watch. Próximo desafio é usá-los pra fazer a correção da Vac. De novo, a ideia é que a correção pela realimentação seja tão mais raṕida possível que se aproxime do ...

Em 14/03/2024 às 14:56, albert_emule disse:

módulo chinês chamado EGS002.

do França. A propósito, bem bacana este módulo. Não preciso mas senti muita vontade comprar um

  • Membro VIP
Postado

Só pra registro... Desconsidere o fonte acima... Descobri que a senoide está sendo formada pelo hw e não necessariamente pelo sw. Além de possuir um erro na indexação. Não vou apagar/editar só pra efeito de histórico ok? Num futuro [ainda incerto]  dou mais uma revisada... se achar que devo.

  • Curtir 1
  • Haha 1
  • 2 semanas depois...
  • Membro VIP
Postado
1 hora atrás, albert_emule disse:

O mundo analógico é mais fácil de fazer funcionar.

Há controvérsias ... com mc + um simples filtro rc sai a senoide tão bunitinha quanto a sua. Ainda há a vantagem de se ter o sinal em pwm e claro ficar +menor  +versátil +estável e quiçá +barato. No caso do seu analógico ainda vai ter que fazer um modulador pwm pra esta senoide daí.

  • mês depois...
Postado

Arruíno se demostrou algo complexo demais para essa função. O intuito era ser simples. 

Por isso miudei para eletrônica analógica: 

 

Na simulação esse sistema auto-oscilante se demostrou eficiente em tudo.

Além de rejeitar qualquer distorção de forma de onda, ainda estabiliza em tempo real, sem delay.  

 

O oscilador eu já tenho funcionando, todo analógico com 3 transistores.

Uma curiosidade é que essa técnica é muito usada em amplificador classe D auto-oscilante. Eu só modifiquei o capacitor alí no comparador para oscilar em 25Khz. Gera o PWM perfeito que o ardiíno deveria gerar.

 

image.thumb.png.88de4b69c313df92729917109e2d7213.png

 

 

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...