Bueno esto es lo que hice hasta ahora, te aclaro es un enfoque diferente, que no esta terminado.
Solo para que veas si funciona y le ajustes lo necesario como para que indique los mA y haga las comparaciones.
Bueno hay cosas para eliminar como el LCD lo usé para ver si todo podia funcionar en combinación con la interrupción a 1mseg que cree.
Fijo el TIMER1 a 1khz y eso asegura que tomes muestras cada 1 mseg.
Aca el codigo y te explico dos o tres cosas
#include <LiquidCrystal.h>
#define BAUD_RATE 19200
#define INPUT_PIN A0
#define LED_PIN 13
#define UMBRAL 100
// LiquidCrystal (rs, rw, en, d4, d5, d6, d7)
//LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
LiquidCrystal lcd( 8, 7, 12, 11, 10, 9);
// LiquidCrystal(rs, enable, d4, d5, d6, d7)
volatile int j;
volatile int valorMax = 0;
volatile unsigned int contador = 0;
boolean imprimir = false;
boolean imprimoPasoPorCero = false;
uint8_t sample=0, Pos;
char str[20] = "";
void setup()
{
Serial.begin(BAUD_RATE);
pinMode(LED_PIN, OUTPUT);
cli(); // disable interrupts while messing with their settings
TCCR1A = 0x00; // clear default timer settings, this kills the millis() funciton
TCCR1B = 0x00;
TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode
TCCR1B |= (0 << CS12); // Set timer prescaling by setting 3 bits
TCCR1B |= (1 << CS11); // 001=1, 010=8, 011=64, 101=1024
TCCR1B |= (1 << CS10);
TIMSK1 |= (1 << OCIE1A); // Enable CTC interrupt
OCR1A = 50; // Set CTC compare value
sei(); // turn interrupts back on
Serial.begin(19200);
lcd.begin(16,2); // columns, rows. size of display
lcd.clear(); // clear the screen
}
void loop() {
if (imprimir) {
lcd.setCursor(0,0);
sprintf(str, "%3d Max = %3d", Pos, valorMax);
Serial.println(str);
lcd.print(str);
}
if (imprimoPasoPorCero) {
Serial.print("Paso por cero =");
Serial.println(contador);
imprimoPasoPorCero = false;
}
}
ISR(TIMER1_COMPA_vect) // when timer counts down it fires this interrupt
{
sample++;
j = analogRead(INPUT_PIN); // real mode, sample analog pin
if (j > valorMax) {
valorMax = j;
Pos = sample;
imprimir = true;
}
else imprimir = false;
if (j == 512){
contador++;
if (contador > UMBRAL){
valorMax = 0;
contador = 0;
sample = 0;
imprimoPasoPorCero = true;
}
}
}
Yo supongo que la señal esta debidamente desplazada a 2.5V, pero como lo hice con un simulador eso funciona siempre bien. En la vida real eso no va asi que donde dice
If (j == 512) reemplaza por if(j>510 && j<514) lo que te da un margen. Si ves que funciona con menos estará bien. Incluso si el centro de la alterna no fueran exactos 2.5V igual funcionaría comparando con 512.
Que hago.. .pues como dije, tomo muestras cada 1 mseg y entonces busco el mayor valor igual que tu.
Pero ademas, busco el 0.. o el cruce por cero, y cada vez que pase por 0 incremento contador cuando contador supera UMBRAL (que es modificable) Lo puse en 100 cruces por cero o sea a 20mseg x 100 = 2 segundos. Algo menos que tus 5 seg pero es ajustable. Pones 250 en UMBRAL y tendras 5 seg.
entonces cuando supero UMBRAL es porque hubo varios cruces por cero y reseteo valorMax a 0. y vuelvo a buscar un máximo.
Falta que los valores se transformen en tus valores reales, y se expresen en mA.
Saca el LCD si no te sirve.
Todo se imprime en el loop sin que genere problemas a la interrupción.
Bien.. tal vez te ayude.
Lo sigo y adapto cuando vuelva de ver un cliente