freqmeasuremulti library

Status
Not open for further replies.

vlelectroniclab

Active member
Hello,
Use teensy3.2 with freqmeasuremulti library, but the system is too slow.
What can I do to improve response speed?
Greetings Vito
 
Too slow? Too slow for what? Please post code which demonstrates the problem.
I think you have read the read me file of the library which states that precise measurement is only possible for frequencies < ~5kHz and that it’s not the frequency which is measured but the period duration before the frequency is calculated from that. The latter makes that a full signal period has to be captured before a result is available. So, if measuring a frequency around 50Hz, updates will (logically) take around 20ms.
 
Code:
#include <Chrono.h>
#include <LightChrono.h>
#include <i2c_t3.h>
#include <ADC.h>
#include <FreqMeasureMulti.h>


/*Pin

  0 Rx Nextion  -- Al display
  1 Tx Nextion  -- Al display
  2 In1         -- E-Stop
  3 In2         -- ScuotitoriON
  4 In3         -- AspiratoriON
  5 Freq1       -- Rpm Scuotitori
  6 Freq2       -- Rpm Aspiratori
  7 In6         -- ConvogliatoriON
  8 In5
  9 Freq3       -- Rpm ConvogliatoreDX
  10 Freq4      -- Rpm ConvogliatoreSX
  11 In4
  12 Out2       -- Buzzer
  13 Out1       -- Led allarme
  14 Adc Batt   -- Tensione batteria
  15 An3
  16 An4
  17 An5
  18 I2C Sda    -- I2C Eprom e inclinometro
  19 I2c Scl    -- I2C Eprom e inclinometro
  20 Freq5
  21 Freq6
  22 Freq7
  23 Freq8
  24 Out3
  25 Out6
  26 An2
  27 An1
  28 Nc
  29 Nc
  30 Out4
  31 Out5
  32 Pwm for L293D Enable
  33 Nc
  A14 Dac Out 0-3v3

*/







//Da usare per calibrare il massimo valore
#define BattCalMax  33577 //in mV per calibrare
#define BattCalMin  0
#define An1Cal   150
#define An2Cal   4096
#define An3Cal   4096
#define An4Cal   4096
#define An5Cal   4096

//Altre funzioni
//#define NextionTX  1
//#define NextionRX  0
//#define I2CSCL    19
//#define I2CSDA    18


//Frequenze IN
#define Freq1In     5
#define Freq2In     6
#define Freq3In     9
#define Freq4In    10
#define Freq5In    20
#define Freq6In    21
#define Freq7In    22
#define Freq8In    23


//Digital IN
#define In1     2
#define In2     3
#define In3     4
#define In4    11
#define In5     8
#define In6     7


//Analogic IN
#define AdcBatt  A0 // ADC0 pin 14
#define An3      A1 // ADC0 pin 15
#define An4      A2 // ADC0 pin 16
#define An5      A3 // ADC0 pin 17
#define An2     A15 // ADC0 pin 26
#define An1     A16 // ADC0 pin 27


//Digital OUT
#define Out2       12
#define Out1       13
#define Out5       25
#define Out6       31
#define Out3       32
#define Out4       30


//Variabili di sistema
int inByte    = 0;         // incoming serial byte
float sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0, sum5 = 0, sum6 = 0, sum7 = 0, sum8 = 0;
int count1 = 0, count2 = 0, count3 = 0, count4 = 0, count5 = 0, count6 = 0, count7 = 0, count8 = 0;
int frequenza1 = 0, frequenza2 = 0, frequenza3 = 0, frequenza4 = 0 , frequenza5 = 0, frequenza6 = 0, frequenza7 = 0, frequenza8 = 0;
elapsedMillis timeout;
int AdcBattvalue = 0, An1value = 0, An2value = 0, An3value = 0, An4value = 0, An5value = 0;
int In1value = 0, In2value = 0, In3value = 0, In4value = 0, In5value = 0, In6value = 0;
int Allarme1, Allarme2, Allarme3, Allarme4, Allarme5, Allarme6, Allarme7, Allarme8, Allarme9, Allarme10;
int IndirizzoEprom, Ore, Minuti;

// Measure 8 frequencies at the same time! :-)
FreqMeasureMulti freq1;
FreqMeasureMulti freq2;
FreqMeasureMulti freq3;
FreqMeasureMulti freq4;
FreqMeasureMulti freq5;
FreqMeasureMulti freq6;
FreqMeasureMulti freq7;
FreqMeasureMulti freq8;

ADC *adc = new ADC();; // adc object
Chrono Contaore;


void setup() {

  Wire.begin();

  //Input Analogici
  pinMode(AdcBatt, INPUT);
  pinMode(An1, INPUT);
  pinMode(An2, INPUT);
  pinMode(An3, INPUT);
  pinMode(An4, INPUT);
  pinMode(An5, INPUT);


  //Input Digitali
  pinMode(In1, INPUT);
  pinMode(In2, INPUT);
  pinMode(In3, INPUT);
  pinMode(In4, INPUT);
  pinMode(In5, INPUT);
  pinMode(In6, INPUT);

  //Input Frequenze
  pinMode(Freq1In, INPUT);
  pinMode(Freq2In, INPUT);
  pinMode(Freq3In, INPUT);
  pinMode(Freq4In, INPUT);
  pinMode(Freq5In, INPUT);
  pinMode(Freq6In, INPUT);
  pinMode(Freq7In, INPUT);
  pinMode(Freq8In, INPUT);

  //Output
  pinMode(Out1, OUTPUT);
  pinMode(Out2, OUTPUT);
  pinMode(Out3, OUTPUT);
  pinMode(Out4, OUTPUT);
  pinMode(Out5, OUTPUT);
  pinMode(Out6, OUTPUT);





  Serial1.begin(9600);
  delay(2000);
  freq1.begin(Freq1In);
  freq2.begin(Freq2In);
  freq3.begin(Freq3In);
  freq4.begin(Freq4In);
  freq5.begin(Freq5In);
  freq6.begin(Freq6In);
  freq7.begin(Freq7In);
  freq8.begin(Freq8In);

  ///// ADC0 ////
  // reference can be ADC_REFERENCE::REF_3V3, ADC_REFERENCE::REF_1V2 (not for Teensy LC) or ADC_REFERENCE::REF_EXT.
  //adc->setReference(ADC_REFERENCE::REF_1V2, ADC_0); // change all 3.3 to 1.2 if you change the reference to 1V2
  adc->setReference(ADC_REFERENCE::REF_3V3, ADC_0); // change all 3.3 to 1.2 if you change the reference to 1V2

  adc->setAveraging(16); // set number of averages
  adc->setResolution(12); // set bits of resolution

  // it can be any of the ADC_CONVERSION_SPEED enum: VERY_LOW_SPEED, LOW_SPEED, MED_SPEED, HIGH_SPEED_16BITS, HIGH_SPEED or VERY_HIGH_SPEED
  // see the documentation for more information
  // additionally the conversion speed can also be ADACK_2_4, ADACK_4_0, ADACK_5_2 and ADACK_6_2,
  // where the numbers are the frequency of the ADC clock in MHz and are independent on the bus speed.
  adc->setConversionSpeed(ADC_CONVERSION_SPEED::VERY_LOW_SPEED); // change the conversion speed
  // it can be any of the ADC_MED_SPEED enum: VERY_LOW_SPEED, LOW_SPEED, MED_SPEED, HIGH_SPEED or VERY_HIGH_SPEED
  adc->setSamplingSpeed(ADC_SAMPLING_SPEED::MED_SPEED); // change the sampling speed

  // always call the compare functions after changing the resolution!
  //adc->enableCompare(1.0/3.3*adc->getMaxValue(ADC_0), 0, ADC_0); // measurement will be ready if value < 1.0V
  //adc->enableCompareRange(1.0*adc->getMaxValue(ADC_0)/3.3, 2.0*adc->getMaxValue(ADC_0)/3.3, 0, 1, ADC_0); // ready if value lies out of [1.0,2.0] V

  // If you enable interrupts, notice that the isr will read the result, so that isComplete() will return false (most of the time)
  //adc->enableInterrupts(ADC_0);


  ////// ADC1 /////
#if ADC_NUM_ADCS>1
  adc->setAveraging(16, ADC_1); // set number of averages
  adc->setResolution(12, ADC_1); // set bits of resolution
  adc->setConversionSpeed(ADC_CONVERSION_SPEED::VERY_LOW_SPEED, ADC_1); // change the conversion speed
  adc->setSamplingSpeed(ADC_SAMPLING_SPEED::MED_SPEED, ADC_1); // change the sampling speed

  adc->setReference(ADC_REFERENCE::REF_3V3, ADC_1);

  // always call the compare functions after changing the resolution!
  //adc->enableCompare(1.0/3.3*adc->getMaxValue(ADC_1), 0, ADC_1); // measurement will be ready if value < 1.0V
  //adc->enableCompareRange(1.0*adc->getMaxValue(ADC_1)/3.3, 2.0*adc->getMaxValue(ADC_1)/3.3, 0, 1, ADC_1); // ready if value lies out of [1.0,2.0] V


  // If you enable interrupts, note that the isr will read the result, so that isComplete() will return false (most of the time)
  //adc->enableInterrupts(ADC_1);

#endif

  delay(500);
  Wire.requestFrom(0x50, B0);

}



void loop() {



  // Use Chrono as a metronome with an interval of 1000 ms :
  if (Contaore.hasPassed(60000) ) { // elapsed(1000) returns 1 if 1000ms have passed.
    Contaore.restart();  // restart the Chrono
    // Do something here...
    //richiedo un byte al 24LC256
    Wire.requestFrom(0x50, B0);
    //attendo la disponibilità di dati sul bus i2c

    while (Wire.available())
    {
      //leggo dal bus il dato relativo alla
    }
    //locazione di memoria precedentemente specificata
    Minuti = Wire.read();
    //invio il dato al serial monitor
    if (Minuti > 60)  {
      Minuti = 0;
      Wire.requestFrom(0x50, 80);
      //attendo la disponibilità di dati sul bus i2c

      while (Wire.available())
      {

        //leggo dal bus il dato relativo alla
        //locazione di memoria precedentemente specificata
        Ore = Wire.read();
      }
    }
  }

  // if we get a valid byte, read analog ins:
  if (Serial1.available() > 0) {
    // get incoming byte:
    inByte = Serial1.read();
    switch (inByte) {
      case 'Allarme1':
        // digitalWrite(2, HIGH);
        break;
      case 'Allarme2':
        // digitalWrite(3, HIGH);
        break;
      case 'Allarme3':
        // digitalWrite(4, HIGH);
        break;
      case 'Allarme4':
        // digitalWrite(5, HIGH);
        break;
      case 'Allarme5':
        // digitalWrite(6, HIGH);
        break;
    }
  }

  if (freq1.available()) {
    sum1 = sum1 + freq1.read();
    count1 = count1 + 1;
  }
  if (freq2.available()) {
    sum2 = sum2 + freq2.read();
    count2 = count2 + 1;
  }
  if (freq3.available()) {
    sum3 = sum3 + freq3.read();
    count3 = count3 + 1;
  }
  if (freq4.available()) {
    sum4 = sum4 + freq4.read();
    count4 = count4 + 1;
  }
  if (freq5.available()) {
    sum5 = sum5 + freq5.read();
    count5 = count5 + 1;
  }
  if (freq6.available()) {
    sum6 = sum6 + freq6.read();
    count6 = count6 + 1;
  }
  if (freq7.available()) {
    sum7 = sum7 + freq7.read();
    count7 = count7 + 1;
  }
  if (freq8.available()) {
    sum8 = sum8 + freq8.read();
    count8 = count8 + 1;
  }


  // print results every half second
  if (timeout > 1000) {
    if (count1 > 0) {
      frequenza1 = (int)freq1.countToFrequency(sum1 / count1);
      Serial1.print("Calibrazione.freq1.val=");
      Serial1.print(frequenza1);
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    } else {
      Serial1.print("Calibrazione.freq1.val=0");
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    }

    if (count2 > 0) {
      frequenza2 = (int)freq2.countToFrequency(sum2 / count2);
      Serial1.print("Calibrazione.freq2.val=");
      Serial1.print(frequenza2);
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    } else {
      Serial1.print("Calibrazione.freq2.val=0");
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    }

    if (count3 > 0) {
      frequenza3 = (int)freq3.countToFrequency(sum3 / count3);
      Serial1.print("Calibrazione.freq3.val=");
      Serial1.print(frequenza3);
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    } else {
      Serial1.print("Calibrazione.freq3.val=0");
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    }

    if (count4 > 0) {
      frequenza4 = (int)freq4.countToFrequency(sum4 / count4);
      Serial1.print("Calibrazione.freq4.val=");
      Serial1.print(frequenza4);
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    } else {
      Serial1.print("Calibrazione.freq4.val=0");
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    }

    if (count5 > 0) {
      frequenza5 = (int)freq5.countToFrequency(sum5 / count5);
      Serial1.print("Calibrazione.freq5.val=");
      Serial1.print(frequenza5);
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    } else {
      Serial1.print("Calibrazione.freq5.val=0");
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    }

    if (count6 > 0) {
      frequenza6 = (int)freq6.countToFrequency(sum6 / count6);
      Serial1.print("Calibrazione.freq6.val=");
      Serial1.print(frequenza6);
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    } else {
      Serial1.print("Calibrazione.freq6.val=0");
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    }

    if (count7 > 0) {
      frequenza7 = (int)freq7.countToFrequency(sum7 / count7);
      Serial1.print("Calibrazione.freq7.val=");
      Serial1.print(frequenza7);
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    } else {
      Serial1.print("Calibrazione.freq7.val=0");
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    }

    if (count8 > 0) {
      frequenza8 = (int)freq8.countToFrequency(sum8 / count8);
      Serial1.print("Calibrazione.freq8.val=");
      Serial1.print(frequenza8);
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    } else {
      Serial1.print("Calibrazione.freq8.val=0");
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    }

    sum1 = 0;
    sum2 = 0;
    sum3 = 0;
    sum4 = 0;
    sum5 = 0;
    sum6 = 0;
    sum7 = 0;
    sum8 = 0;
    count1 = 0;
    count2 = 0;
    count3 = 0;
    count4 = 0;
    count5 = 0;
    count6 = 0;
    count7 = 0;
    count8 = 0;
    timeout = 0;
  }

  delay(100);



  AdcBattvalue = adc->analogRead(AdcBatt);
  AdcBattvalue = map(AdcBattvalue, 0, 4096, BattCalMin, BattCalMax);
  AdcBattvalue = constrain(AdcBattvalue, BattCalMin, BattCalMax);    // limits range of sensor values to between 0 and 100
  Serial1.print("Calibrazione.adcbatt.val=");
  Serial1.print(AdcBattvalue);
  Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
  Serial1.write(0xff);
  Serial1.write(0xff);

  An1value = adc->analogRead(An1);
  An1value = map(An1value, 0, 4096, 0, An1Cal);
  An1value = constrain(An1value, 0, An1Cal);    // limits range of sensor values to between 0 and 100
  Serial1.print("Calibrazione.an1.val=");
  Serial1.print(An1value);
  Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
  Serial1.write(0xff);
  Serial1.write(0xff);


  An2value = adc->analogRead(An2);
  An2value = map(An2value, 0, 4096, 0, An2Cal);
  An2value = constrain(An2value, 0, An2Cal);    // limits range of sensor values to between 0 and 100
  Serial1.print("Calibrazione.an2.val=");
  Serial1.print(An2value);
  Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
  Serial1.write(0xff);
  Serial1.write(0xff);


  An3value = adc->analogRead(An3);
  An3value = map(An3value, 0, 4096, 0, An3Cal);
  An3value = constrain(An3value, 0, An3Cal);    // limits range of sensor values to between 0 and 100
  Serial1.print("Calibrazione.an3.val=");
  Serial1.print(An3value);
  Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
  Serial1.write(0xff);
  Serial1.write(0xff);


  An4value = adc->analogRead(An4);
  An4value = map(An4value, 0, 4096, 0, An4Cal);
  An4value = constrain(An4value, 0, An4Cal);    // limits range of sensor values to between 0 and 100
  Serial1.print("Calibrazione.an4.val=");
  Serial1.print(An4value);
  Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
  Serial1.write(0xff);
  Serial1.write(0xff);


  An5value = adc->analogRead(An5);
  An5value = map(An5value, 0, 4096, 0, An5Cal);
  An5value = constrain(An5value, 0, An5Cal);    // limits range of sensor values to between 0 and 100
  Serial1.print("Calibrazione.an5.val=");
  Serial1.print(An5value);
  Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
  Serial1.write(0xff);
  Serial1.write(0xff);


  delay(100);


  In1value = digitalRead(In1);
  if (In1value) {
    Serial1.print("Calibrazione.in1.val=0");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }
  else {
    Serial1.print("Calibrazione.in1.val=1");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }


  In2value = digitalRead(In2);
  if (In2value) {
    Serial1.print("Calibrazione.in2.val=0");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }
  else {
    Serial1.print("Calibrazione.in2.val=1");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }


  In3value = digitalRead(In3);
  if (In3value) {
    Serial1.print("Calibrazione.in3.val=0");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }
  else {
    Serial1.print("Calibrazione.in3.val=1");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }


  In4value = digitalRead(In4);
  if (In4value) {
    Serial1.print("Calibrazione.in4.val=0");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }
  else {
    Serial1.print("Calibrazione.in4.val=1");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }


  In5value = digitalRead(In5);
  if (In5value) {
    Serial1.print("Calibrazione.in5.val=0");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }
  else {
    Serial1.print("Calibrazione.in5.val=1");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }


  In6value = digitalRead(In6);
  if (In6value) {
    Serial1.print("Calibrazione.in6.val=0");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }
  else {
    Serial1.print("Calibrazione.in6.val=1");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }

  digitalWrite(Out1, HIGH);
  delay(300);
  digitalWrite(Out1, LOW);

}
 
Last edited by a moderator:
The problem is when I remove the frequency and the pin remains high by numbers for about 5 seconds?
Sorry, can’t understand what you mean by that?!?
Removing a signal from a pin means that the frequency will be zero. Thus, the period time which you get with read() will be theoretically infinite. So, you would have to add cod to check for timeouts to prevent undefined behavior.
What I can see already is out of that your code is highly inefficient. For example the frequency pins are internally routed to the timer capture module by the library. It makes no sense and asks for trouble when you try to reroute these to the GPIO module with pinMode().
 
Now how is it?

Code:
#include <Chrono.h>
#include <LightChrono.h>
#include <i2c_t3.h>
#include <ADC.h>
#include <FreqMeasureMulti.h>


/*Pin

  0 Rx Nextion  -- Al display
  1 Tx Nextion  -- Al display
  2 In1         -- E-Stop
  3 In2         -- ScuotitoriON
  4 In3         -- AspiratoriON
  5 Freq1       -- Rpm Scuotitori
  6 Freq2       -- Rpm Aspiratori
  7 In6         -- ConvogliatoriON
  8 In5
  9 Freq3       -- Rpm ConvogliatoreDX
  10 Freq4      -- Rpm ConvogliatoreSX
  11 In4
  12 Out2       -- Buzzer
  13 Out1       -- Led allarme
  14 Adc Batt   -- Tensione batteria
  15 An3
  16 An4
  17 An5
  18 I2C Sda    -- I2C Eprom e inclinometro
  19 I2c Scl    -- I2C Eprom e inclinometro
  20 Freq5
  21 Freq6
  22 Freq7
  23 Freq8
  24 Out3
  25 Out6
  26 An2
  27 An1
  28 Nc
  29 Nc
  30 Out4
  31 Out5
  32 Pwm for L293D Enable
  33 Nc
  A14 Dac Out 0-3v3

*/







//Da usare per calibrare il massimo valore
#define BattCalMax  33577 //in mV per calibrare
#define BattCalMin  0
#define An1Cal   150
#define An2Cal   100
#define An3Cal   4096
#define An4Cal   4096
#define An5Cal   4096

//Altri pin
// NextionTX  1
// NextionRX  0
// I2CSCL    19
// I2CSDA    18


//Frequenze IN
#define Freq1In     5
#define Freq2In     6
#define Freq3In     9
#define Freq4In    10
#define Freq5In    20
#define Freq6In    21
#define Freq7In    22
#define Freq8In    23


//Digital IN
#define In1     2
#define In2     3
#define In3     4
#define In4    11
#define In5     8
#define In6     7


//Analogic IN
#define AdcBatt  A0 // ADC0 pin 14
#define An3      A1 // ADC0 pin 15
#define An4      A2 // ADC0 pin 16
#define An5      A3 // ADC0 pin 17
#define An2     A15 // ADC0 pin 26
#define An1     A16 // ADC0 pin 27


//Digital OUT
#define Out2       12
#define Out1       13
#define Out5       25
#define Out6       31
#define Out3       32
#define Out4       30


//Variabili di sistema
int inByte    = 0;         // incoming serial byte
float sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0, sum5 = 0, sum6 = 0, sum7 = 0, sum8 = 0;
int count1 = 0, count2 = 0, count3 = 0, count4 = 0, count5 = 0, count6 = 0, count7 = 0, count8 = 0;
int frequenza1 = 0, frequenza2 = 0, frequenza3 = 0, frequenza4 = 0 , frequenza5 = 0, frequenza6 = 0, frequenza7 = 0, frequenza8 = 0;
elapsedMillis timeout;
int AdcBattvalue = 0, An1value = 0, An2value = 0, An3value = 0, An4value = 0, An5value = 0;
int In1value = 0, In2value = 0, In3value = 0, In4value = 0, In5value = 0, In6value = 0;
int Allarme1, Allarme2, Allarme3, Allarme4, Allarme5, Allarme6, Allarme7, Allarme8, Allarme9, Allarme10;
int IndirizzoEprom, Ore, Minuti;

// Measure 8 frequencies at the same time! :-)
FreqMeasureMulti freq1;
FreqMeasureMulti freq2;
FreqMeasureMulti freq3;
FreqMeasureMulti freq4;
FreqMeasureMulti freq5;
FreqMeasureMulti freq6;
FreqMeasureMulti freq7;
FreqMeasureMulti freq8;

ADC *adc = new ADC();; // adc object
Chrono Contaore;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {

  Wire.begin();

  //Input Analogici
  pinMode(AdcBatt, INPUT);
  pinMode(An1, INPUT);
  pinMode(An2, INPUT);
  pinMode(An3, INPUT);
  pinMode(An4, INPUT);
  pinMode(An5, INPUT);


  //Input Digitali
  pinMode(In1, INPUT);
  pinMode(In2, INPUT);
  pinMode(In3, INPUT);
  pinMode(In4, INPUT);
  pinMode(In5, INPUT);
  pinMode(In6, INPUT);
  

  //Output
  pinMode(Out1, OUTPUT);
  pinMode(Out2, OUTPUT);
  pinMode(Out3, OUTPUT);
  pinMode(Out4, OUTPUT);
  pinMode(Out5, OUTPUT);
  pinMode(Out6, OUTPUT);





  Serial1.begin(9600);
  delay(2000);
  freq1.begin(Freq1In);
  freq2.begin(Freq2In);
  freq3.begin(Freq3In);
  freq4.begin(Freq4In);
  freq5.begin(Freq5In);
  freq6.begin(Freq6In);
  freq7.begin(Freq7In);
  freq8.begin(Freq8In);

  ///// ADC0 ////
  // reference can be ADC_REFERENCE::REF_3V3, ADC_REFERENCE::REF_1V2 (not for Teensy LC) or ADC_REFERENCE::REF_EXT.
  //adc->setReference(ADC_REFERENCE::REF_1V2, ADC_0); // change all 3.3 to 1.2 if you change the reference to 1V2
  adc->setReference(ADC_REFERENCE::REF_3V3, ADC_0); // change all 3.3 to 1.2 if you change the reference to 1V2

  adc->setAveraging(16); // set number of averages
  adc->setResolution(12); // set bits of resolution

  // it can be any of the ADC_CONVERSION_SPEED enum: VERY_LOW_SPEED, LOW_SPEED, MED_SPEED, HIGH_SPEED_16BITS, HIGH_SPEED or VERY_HIGH_SPEED
  // see the documentation for more information
  // additionally the conversion speed can also be ADACK_2_4, ADACK_4_0, ADACK_5_2 and ADACK_6_2,
  // where the numbers are the frequency of the ADC clock in MHz and are independent on the bus speed.
  adc->setConversionSpeed(ADC_CONVERSION_SPEED::VERY_LOW_SPEED); // change the conversion speed
  // it can be any of the ADC_MED_SPEED enum: VERY_LOW_SPEED, LOW_SPEED, MED_SPEED, HIGH_SPEED or VERY_HIGH_SPEED
  adc->setSamplingSpeed(ADC_SAMPLING_SPEED::MED_SPEED); // change the sampling speed

  // always call the compare functions after changing the resolution!
  //adc->enableCompare(1.0/3.3*adc->getMaxValue(ADC_0), 0, ADC_0); // measurement will be ready if value < 1.0V
  //adc->enableCompareRange(1.0*adc->getMaxValue(ADC_0)/3.3, 2.0*adc->getMaxValue(ADC_0)/3.3, 0, 1, ADC_0); // ready if value lies out of [1.0,2.0] V

  // If you enable interrupts, notice that the isr will read the result, so that isComplete() will return false (most of the time)
  //adc->enableInterrupts(ADC_0);


  ////// ADC1 /////
#if ADC_NUM_ADCS>1
  adc->setAveraging(16, ADC_1); // set number of averages
  adc->setResolution(12, ADC_1); // set bits of resolution
  adc->setConversionSpeed(ADC_CONVERSION_SPEED::VERY_LOW_SPEED, ADC_1); // change the conversion speed
  adc->setSamplingSpeed(ADC_SAMPLING_SPEED::MED_SPEED, ADC_1); // change the sampling speed

  adc->setReference(ADC_REFERENCE::REF_3V3, ADC_1);

  // always call the compare functions after changing the resolution!
  //adc->enableCompare(1.0/3.3*adc->getMaxValue(ADC_1), 0, ADC_1); // measurement will be ready if value < 1.0V
  //adc->enableCompareRange(1.0*adc->getMaxValue(ADC_1)/3.3, 2.0*adc->getMaxValue(ADC_1)/3.3, 0, 1, ADC_1); // ready if value lies out of [1.0,2.0] V


  // If you enable interrupts, note that the isr will read the result, so that isComplete() will return false (most of the time)
  //adc->enableInterrupts(ADC_1);

#endif

  delay(500);
  Wire.requestFrom(0x50, B0);

}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {



  // Use Chrono as a metronome with an interval of 1000 ms :
  if (Contaore.hasPassed(60000) ) { // elapsed(1000) returns 1 if 1000ms have passed.
    Contaore.restart();  // restart the Chrono
    // Do something here...
    //richiedo un byte al 24LC256
    Wire.requestFrom(0x50, B0);
    //attendo la disponibilità di dati sul bus i2c

    while (Wire.available())
    {
      //leggo dal bus il dato relativo alla
    }
    //locazione di memoria precedentemente specificata
    Minuti = Wire.read();
    //invio il dato al serial monitor
    if (Minuti > 60)  {
      Minuti = 0;
      Wire.requestFrom(0x50, 80);
      //attendo la disponibilità di dati sul bus i2c

      while (Wire.available())
      {

        //leggo dal bus il dato relativo alla
        //locazione di memoria precedentemente specificata
        Ore = Wire.read();
      }
    }
  }

  // if we get a valid byte, read analog ins:
  if (Serial1.available() > 0) {
    // get incoming byte:
    inByte = Serial1.read();
    switch (inByte) {
      case 'Allarme1':
        // digitalWrite(2, HIGH);
        break;
      case 'Allarme2':
        // digitalWrite(3, HIGH);
        break;
      case 'Allarme3':
        // digitalWrite(4, HIGH);
        break;
      case 'Allarme4':
        // digitalWrite(5, HIGH);
        break;
      case 'Allarme5':
        // digitalWrite(6, HIGH);
        break;
    }
  }

  if (freq1.available()) {
    sum1 = sum1 + freq1.read();
    count1 = count1 + 1;
  }
  if (freq2.available()) {
    sum2 = sum2 + freq2.read();
    count2 = count2 + 1;
  }
  if (freq3.available()) {
    sum3 = sum3 + freq3.read();
    count3 = count3 + 1;
  }
  if (freq4.available()) {
    sum4 = sum4 + freq4.read();
    count4 = count4 + 1;
  }
  if (freq5.available()) {
    sum5 = sum5 + freq5.read();
    count5 = count5 + 1;
  }
  if (freq6.available()) {
    sum6 = sum6 + freq6.read();
    count6 = count6 + 1;
  }
  if (freq7.available()) {
    sum7 = sum7 + freq7.read();
    count7 = count7 + 1;
  }
  if (freq8.available()) {
    sum8 = sum8 + freq8.read();
    count8 = count8 + 1;
  }


  // print results every half second
  if (timeout > 1000) {
    if (count1 > 0) {
      frequenza1 = (int)freq1.countToFrequency(sum1 / count1);
      Serial1.print("Calibrazione.freq1.val=");
      Serial1.print(frequenza1);
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    } else {
      Serial1.print("Calibrazione.freq1.val=0");
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    }

    if (count2 > 0) {
      frequenza2 = (int)freq2.countToFrequency(sum2 / count2);
      Serial1.print("Calibrazione.freq2.val=");
      Serial1.print(frequenza2);
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    } else {
      Serial1.print("Calibrazione.freq2.val=0");
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    }

    if (count3 > 0) {
      frequenza3 = (int)freq3.countToFrequency(sum3 / count3);
      Serial1.print("Calibrazione.freq3.val=");
      Serial1.print(frequenza3);
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    } else {
      Serial1.print("Calibrazione.freq3.val=0");
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    }

    if (count4 > 0) {
      frequenza4 = (int)freq4.countToFrequency(sum4 / count4);
      Serial1.print("Calibrazione.freq4.val=");
      Serial1.print(frequenza4);
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    } else {
      Serial1.print("Calibrazione.freq4.val=0");
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    }

    if (count5 > 0) {
      frequenza5 = (int)freq5.countToFrequency(sum5 / count5);
      Serial1.print("Calibrazione.freq5.val=");
      Serial1.print(frequenza5);
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    } else {
      Serial1.print("Calibrazione.freq5.val=0");
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    }

    if (count6 > 0) {
      frequenza6 = (int)freq6.countToFrequency(sum6 / count6);
      Serial1.print("Calibrazione.freq6.val=");
      Serial1.print(frequenza6);
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    } else {
      Serial1.print("Calibrazione.freq6.val=0");
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    }

    if (count7 > 0) {
      frequenza7 = (int)freq7.countToFrequency(sum7 / count7);
      Serial1.print("Calibrazione.freq7.val=");
      Serial1.print(frequenza7);
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    } else {
      Serial1.print("Calibrazione.freq7.val=0");
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    }

    if (count8 > 0) {
      frequenza8 = (int)freq8.countToFrequency(sum8 / count8);
      Serial1.print("Calibrazione.freq8.val=");
      Serial1.print(frequenza8);
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    } else {
      Serial1.print("Calibrazione.freq8.val=0");
      Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
      Serial1.write(0xff);
      Serial1.write(0xff);
    }

    sum1 = 0;
    sum2 = 0;
    sum3 = 0;
    sum4 = 0;
    sum5 = 0;
    sum6 = 0;
    sum7 = 0;
    sum8 = 0;
    count1 = 0;
    count2 = 0;
    count3 = 0;
    count4 = 0;
    count5 = 0;
    count6 = 0;
    count7 = 0;
    count8 = 0;
    timeout = 0;
  }

  delay(100);



  AdcBattvalue = adc->analogRead(AdcBatt);
  AdcBattvalue = map(AdcBattvalue, 0, 4096, BattCalMin, BattCalMax);
  AdcBattvalue = constrain(AdcBattvalue, BattCalMin, BattCalMax);    // limits range of sensor values to between 0 and 100
  Serial1.print("Calibrazione.adcbatt.val=");
  Serial1.print(AdcBattvalue);
  Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
  Serial1.write(0xff);
  Serial1.write(0xff);

  An1value = adc->analogRead(An1);
  An1value = map(An1value, 0, 4096, 0, An1Cal);
  An1value = constrain(An1value, 0, An1Cal);    // limits range of sensor values to between 0 and 100
  Serial1.print("Calibrazione.an1.val=");
  Serial1.print(An1value);
  Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
  Serial1.write(0xff);
  Serial1.write(0xff);


  An2value = adc->analogRead(An2);
  An2value = map(An2value, 0, 4096, 0, An2Cal);
  An2value = constrain(An2value, 0, An2Cal);    // limits range of sensor values to between 0 and 100
  Serial1.print("Calibrazione.an2.val=");
  Serial1.print(An2value);
  Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
  Serial1.write(0xff);
  Serial1.write(0xff);


  An3value = adc->analogRead(An3);
  An3value = map(An3value, 0, 4096, 0, An3Cal);
  An3value = constrain(An3value, 0, An3Cal);    // limits range of sensor values to between 0 and 100
  Serial1.print("Calibrazione.an3.val=");
  Serial1.print(An3value);
  Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
  Serial1.write(0xff);
  Serial1.write(0xff);


  An4value = adc->analogRead(An4);
  An4value = map(An4value, 0, 4096, 0, An4Cal);
  An4value = constrain(An4value, 0, An4Cal);    // limits range of sensor values to between 0 and 100
  Serial1.print("Calibrazione.an4.val=");
  Serial1.print(An4value);
  Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
  Serial1.write(0xff);
  Serial1.write(0xff);


  An5value = adc->analogRead(An5);
  An5value = map(An5value, 0, 4096, 0, An5Cal);
  An5value = constrain(An5value, 0, An5Cal);    // limits range of sensor values to between 0 and 100
  Serial1.print("Calibrazione.an5.val=");
  Serial1.print(An5value);
  Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
  Serial1.write(0xff);
  Serial1.write(0xff);


  delay(100);


  In1value = digitalRead(In1);
  if (In1value) {
    Serial1.print("Calibrazione.in1.val=0");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }
  else {
    Serial1.print("Calibrazione.in1.val=1");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }


  In2value = digitalRead(In2);
  if (In2value) {
    Serial1.print("Calibrazione.in2.val=0");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }
  else {
    Serial1.print("Calibrazione.in2.val=1");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }


  In3value = digitalRead(In3);
  if (In3value) {
    Serial1.print("Calibrazione.in3.val=0");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }
  else {
    Serial1.print("Calibrazione.in3.val=1");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }


  In4value = digitalRead(In4);
  if (In4value) {
    Serial1.print("Calibrazione.in4.val=0");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }
  else {
    Serial1.print("Calibrazione.in4.val=1");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }


  In5value = digitalRead(In5);
  if (In5value) {
    Serial1.print("Calibrazione.in5.val=0");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }
  else {
    Serial1.print("Calibrazione.in5.val=1");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }


  In6value = digitalRead(In6);
  if (In6value) {
    Serial1.print("Calibrazione.in6.val=0");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }
  else {
    Serial1.print("Calibrazione.in6.val=1");
    Serial1.write(0xff);  // We always have to send this three lines after each command sent to the nextion display.
    Serial1.write(0xff);
    Serial1.write(0xff);
  }

  digitalWrite(Out1, HIGH);
  delay(300);
  digitalWrite(Out1, LOW);

}
 
I still don’t see a precise timeout handling for your period/frequency measurements.

And you have enormous delay() times in the loop. Imagine one of the frequencies being around 100Hz. During a 300ms delay, it would become available() 30 times, but your actual code will drop 29 readings and take only the 30th into account for your averaging. That is highly amateurish and far from being efficient and precise. So, please don’t blame the library for being slow, better learn efficient coding, which begins always by designing and optimizing a strategy (algorithm) with pencil and paper. Only when you have considered all possible variants which can happen (best case, worst case, highest frequency, lowest frequency, timeout, overflow) and have a strategy for each of these, you may start writing the code. To ease debugging, you should do that in modules, which means that you test and debug the frequency capturing alone, the analog readings alone, the I2C communication alone, and so on. Only if all modules work perfectly, you should bring everything together.
 
however removing all delays I have the problem that when the frequency is 0 I have to wait 5 seconds before the teensy gives 0.
There must be some error on my code.
I'm not a programmer and I still have a lot to learn.
 
however removing all delays I have the problem that when the frequency is 0 I have to wait 5 seconds before the teensy gives 0.
There must be some error on my code.
I'm not a programmer and I still have a lot to learn.
What you consider being an error is the laws of physics (7th grade stuff). As I explained already, the freqmeasuremulti library measures not frequencies but period durations. The period time is defined as t = 1/f. If f is zero, t becomes infinite and you can already be happy that you have only to wait 5 seconds until you get a zero reading, due to either overflow or limited resolution. As I told you, you have to add an efficient handling for this special case, defining the lowest frequency which you consider already as non zero, convert it into a virtual reading r = F_BUS / f_limit and compare the values obtained with read() against this number. If these are greater or equal as r, you can already consider your frequency to be 0.
You might also consider not doing this averaging since your loop structure will dismiss most of the readings. Averaging means low pass filtering means delayed results. Not meaningful here. You should increase your loop speed to capture and process a maximum of readings, and only occasionally, using elapsedMillis() for example, send the processed value to the display since it makes no sense to update the display 100000 times a second.
 
Status
Not open for further replies.
Back
Top