Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 11 of 11

Thread: freqmeasuremulti library

  1. #1

    freqmeasuremulti library

    Hello,
    Use teensy3.2 with freqmeasuremulti library, but the system is too slow.
    What can I do to improve response speed?
    Greetings Vito

  2. #2
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,416
    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.

  3. #3
    The problem is when I remove the frequency and the pin remains high by numbers for about 5 seconds?

  4. #4
    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 Frank B; 03-25-2019 at 08:12 PM. Reason: added [code] tag

  5. #5
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,416
    Quote Originally Posted by vlelectroniclab View Post
    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().

  6. #6
    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);
    
    }

  7. #7
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,416
    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.

  8. #8
    but I do not blame the library, looking for someone who gives me a straight

  9. #9
    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.

  10. #10
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,416
    Quote Originally Posted by vlelectroniclab View Post
    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.

  11. #11
    Junior Member
    Join Date
    Mar 2019
    Posts
    2
    It's clear to me now.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •