Contatore con arduino mega

Salve a tutti

Ho alcune domande su un contatore con un arduino mega.

Ho un segnale in LVDS in ingresso sul pin 52, un onda quadra di larghezza 7 us.
La situazione "strana" è la seguente. Il codice che allego al fondo non funziona bene se cerco di leggere quando il segnale diventa alto.
Se invece inverto il cavo, cioè il segnale è sempre alto e si abbassa quando ho un evento, funziona bene (perlomeno nelle varie prove che ho fatto).

L'unico problema (a parte il fatto che logicamente non ha molto senso) si presenta quando ho un segnale in ingresso con frequenza molto bassa. In questo caso il codice si pianta nel while, visto che è sempre alto. Ho provato a inserire un break ma non mi ha funzionato.

Il primo dubbio è questo, relativo al break.
Il secondo è di concetto. Non capisco perchè l'arduino non riesce a campionare bene un segnale in ingesso di 7us, pero una caduta di 7 us si. Forse l'ampiezza del segnale non è abbastanza e vado in una zona di logica grigia?
L'ultimo quesito è relativo ai registri. Mi hanno suggerito di modificare i registri dell'arduino per configurare un contatore su un pin. Pero prima di vedere come fare questo vorrei qualche conferma che potrebbe effettivamente risolvere il problema

#include <stdio.h>

int counter_pin=52;

unsigned long counter = 0;
unsigned long StartTime;
char buffer [50];
long double freq=0;      
unsigned long tempo=60000*1; //time in millisecondi
unsigned long tempo2=0; 
unsigned long CurrentTime;

void setup() {                
  // initialize the digital pin as an output.
  Serial.begin(115200);
  unsigned long StartTime = millis();
}

void loop() {

  CurrentTime = StartTime;

  if(counter==0){
    Serial.println("CONTO");
    CurrentTime = StartTime;
    while ( CurrentTime - StartTime < tempo ) {
      if ( digitalRead(counter_pin) == HIGH){ 
        counter=counter+1;
        while ( digitalRead(counter_pin) == HIGH) CurrentTime = millis();
      //{CurrentTime = millis();if(CurrentTime - StartTime < tempo)break;} // BLOCK the function until cycles
      }
      CurrentTime = millis();
    }

    tempo2=CurrentTime - StartTime;
//    double rate=(double)counter*1000/tempo2;
    sprintf (buffer, "FINE - RATE: ");
    Serial.print(buffer);
    Serial.println((double)counter*1000/tempo2);//lu
    sprintf (buffer, "Tempo acquisizione: %lu ms",tempo2);
    Serial.println(buffer);  

    if(counter==0){
      counter=1;
    }
  }

  counter=0;
  StartTime= millis();
}

non è che vai in una zona di logica grigia, sei proprio nella nebbia
un segnale differenziale che va da 1,0erotti a 1,3erotti è decisamente troppo basso per essere sentito da arduino
il fatto che in un senso senta semmai è indice di altri problemi (tipo disturbi, anelli di massa, corti varii)
anche il programma soffre di impostazione "strana"
ad uno sguardo rapido mi sembra di aver capito che tu vuoi contare gli impulsi (rapidi), e poi metti una while bloccante in attesa per un tempo (anche lungotto), in quel tempo "non conta"

C'é molta confusione, almeno a mio modo di vedere:

  1. troppe variabili che tengono tempi, e che ti dimentichi di settare. Usa più millis() e meno currenttime;. Così come é il codice la while di attesa del minuto é bloccate per sempre, perché in quale punto della stessa aggiorni currenttime?

  2. se vuoi fare qualcosa di vepoce con Arduino nulla é più vepoce di usare gli interrupts, e semplificheresti moltonil codice. Poi se vuoi vediamo come, a patto che, se non li conosci, vada a cercarteli sul reference

  3. l'array buffer é eliminabile, in quanyo lo usi solo per scrivere su seriale, cosa che probabilmente anche la sprintf fa, e che la Serial.print() fa certamente, ma é una sottigliezza

  4. hai per caso provato, mediante tester, se i valori di tensione emessi dall'oggetto contato sono sufficienti a far scattare regolarmente il pin tra 1 e 0 (io farei 0<1V, 1>4V, ma ste cose non pe capisco

  5. usi una Mega (>50 pin) per 1 pin? Probabilmente perché sugli altri fai già girare cose, e vuoi velocità così elevate? Personalmente userei un Arduino, il più piccolo possibile, dedicato

void setup() {
// initialize the digital pin as an output.
Serial.begin(115200);
unsigned long StartTime = millis();
}

non ci dovrebbe essere un pinMode(counter_pin, mode);
Con mode settato per la pull-up o comunque come input almeno.

Ciao.

Ci starebbe bene
In realtà penso che input sia il default

In realtà penso che input sia il default

Forse ci pensa il core di arduino, perché di default li pone in TRISTATE, ma almeno ricordo, c'è da vedere il datasheet che dopo l'acquisizione ho notato essere stato rivisto parecchie volte.

Ciao.

Silente:
C'é molta confusione, almeno a mio modo di vedere:

possibilissimo, sono alle prime armi

  1. troppe variabili che tengono tempi, e che ti dimentichi di settare. Usa più millis() e meno currenttime;. Così come é il codice la while di attesa del minuto é bloccate per sempre, perché in quale punto della stessa aggiorni currenttime?

L'avevo messo perche l'idea era di uscire dal while dopo il tempo fissato, per evitare di bloccarmi all'infinito nel loop. pero effettivamente senza break potrei levarlo

  1. se vuoi fare qualcosa di vepoce con Arduino nulla é più vepoce di usare gli interrupts, e semplificheresti moltonil codice. Poi se vuoi vediamo come, a patto che, se non li conosci, vada a cercarteli sul reference

vado a studiare

  1. hai per caso provato, mediante tester, se i valori di tensione emessi dall'oggetto contato sono sufficienti a far scattare regolarmente il pin tra 1 e 0 (io farei 0<1V, 1>4V, ma ste cose non pe capisco

visti all'oscilloscopio, sono 2.5V
Le prove che ho fatto sono le seguenti
connettato il pin di arduino a un generatore di segnali, con voltaggi ~5V, ed il programma mi conta bene fino a ~70kHz (diciamo verifica del codice)
senza il while conta male, puo contare segnali lunghi piu di una volta

Pero la mia applicazione finale è leggere un sensore di luce
ho quindi connesso il generatore a un led, e il sensore all'arduino (il segnale LVDS di cui parlavo)
ora se leggo al contrario il segnale (sempre alto), i conteggi sono esatti (accendo il led a 500Hz e conto 500 sul sensore). Se leggo il segnale bene (sempre basso e si alza quando hai un evento) invece non ottengo valori stabili, e sono dell'ordine dei 50/100 Hz

  1. usi una Mega (>50 pin) per 1 pin? Probabilmente perché sugli altri fai già girare cose, e vuoi velocità così elevate? Personalmente userei un Arduino, il più piccolo possibile, dedicato

per esempio che arduino suggeriresti?

Con mode settato per la pull-up o comunque come input almeno.

grazie lo vado ad aggiungere
Grazie a tutti per l'aiuto