#include <18F1320.h>
#device ADC=10
#device HIGH_INTS=TRUE
#include "math.h"
#FUSES NOWDT //No Watch Dog Timer
#use delay(internal=8MHz)
#use rs232(baud=115200,parity=N,bits=8,stream=PORT1, xmit=PIN_B1, rcv=PIN_B4)
#define SALIDA PIN_B3
#define MUESTRASENCICLO 72
#define NUMMUESTRAS MUESTRASENCICLO*10 // Cada onda a 50Hz está dividida en 36 muestras. Cogemos 10 ondas
#define OFFSET 512.0 // Restamos 512 porque la señal tiene un offset de 2.5V
#define AJUSTAADC 5.0/1024.0 // 5V a 10bits de resolución
unsigned int16 muestras[50];
int16 buffer, objetivo;
float onda, consumo;
int16 potencia;
unsigned int8 capturado, calculado;
unsigned int8 contadorPWM, cortePWM;
unsigned int8 IndMuestra=0;
#INT_RDA HIGH
void intser()
{
char c;
if ((c>='0') && (c<='9'))
buffer = buffer*10 + c - '0';
if ((c == '\r')) {
objetivo = buffer;
buffer=0;
}
if (c=='0')
output_low(SALIDA);
if (c=='1')
output_high(SALIDA);
// Como la interrupción RDA habrá interrumpido la lectura de la onda, empezamos de nuevo
IndMuestra=0;
onda = 0;
}
#INT_EXT
void cruce_por_cero() {
output_low(SALIDA);
set_timer2(0);
contadorPWM=0;
if (!capturado) {
capturado=1;
}
if (calculado) {
calculado=0;
capturado=0;
IndMuestra=0;
}
}
#INT_TIMER2
void LeerADC() {
if ((!capturado) && (IndMuestra<50)){
muestras[IndMuestra]=read_adc();
IndMuestra++;
};
if (contadorPWM++ == cortePWM) {
output_high(SALIDA);
}
}
void main()
{
int8 i;
int16 v;
float corriente;
int16 SumaMuestras;
setup_adc_ports(sAN0, VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL | ADC_TAD_MUL_0);
output_low(SALIDA);
setup_timer_2 (T2_DIV_BY_1,198,2); // 187 para 36 ciclos
output_float(PIN_B0);
output_float(PIN_B4);
set_adc_channel(0);
onda = 0;
IndMuestra=0;
contadorPWM=0;
enable_interrupts(INT_TIMER2);
enable_interrupts(INT_RDA);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
delay_ms(50);
objetivo = 0;
cortePWM=25;
while (1) {
if ((capturado) && (!calculado)) {
onda=0;
SumaMuestras=0;
if (IndMuestra==50) {
for (i=0;i<IndMuestra;i++) {
corriente = (muestras[i]-OFFSET)*AJUSTAADC * 4.6;
SumaMuestras+=muestras[i];
muestras[i]=0;
onda = onda + corriente*corriente;
}
if (!SumaMuestras) {// eliminamos el ruido
consumo=0.0;
potencia = 0;
} else {
consumo
= sqrt(2*onda
/IndMuestra
); potencia = (int16)(consumo * 181.0);
}
//printf ("%u -> %6.2fA -> %4luW. Obj %lu - CortePWM %u\n", IndMuestra, consumo, potencia, objetivo, cortePWM);
}
if ((potencia<objetivo) && (cortePWM>0))
cortePWM--;
if ((potencia>objetivo) && (cortePWM<49))
cortePWM++;
calculado=1;
}
}
}