IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Problème programme Tachometer


Sujet :

Arduino

  1. #1
    Membre averti
    Homme Profil pro
    particulier
    Inscrit en
    Novembre 2022
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : particulier
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Novembre 2022
    Messages : 16
    Par défaut Problème programme Tachometer
    voiic un programme il fonctionnait sur pc et sur l'arduino en nomade et ca ne fonctionne plus je ne trouve pas de l 'aide svp

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    /*
    Tachometer using micros
     
    On this sketch we are going to measure the period between pulses using the micros() function to get the RPM
    (Revolutions Per Minute) from a sensor on pin 2.
    This way of measuring RPM makes it accurate, responsive and versatile. No matter how fast or slow the loop is
    running, the reading accuracy is not going to be affected. Although, the faster you run the loop, the more amount
    of readings you are going to be able to display every second.
     
    It's coded in a way that the micros rollover doesn't create glitches every 71 minutes, so it can run forever
    without problems.
     
    We use an interrupt for the input so you have to choose pin 2 or 3 (for Arduino Uno/nano). In this example we
    use pin 2.
     
     
     
     
     
    /////// OLED 0.96" Display:
    We are going to use the OLED 128x64 I2C with SSD1306 driver using the Adafruit library.
     
    Pins for OLED display and arduino uno/nano:
     * GND = GND
     * VCC = 5V
     * SCL = A5
     * SDA = A4
     
    It's a good idea to put a resistor between A4-5V and A5-5V to help stabilize the connection.
    What that does is pull-up the I2C pins to make it more reliable and prevents lock-ups.
     
    Libraries needed for the OLED display:
    <a href="https://github.com/adafruit/Adafruit_SSD1306" target="_blank">https://github.com/adafruit/Adafruit_SSD1306</a>
    <a href="https://github.com/adafruit/Adafruit-GFX-Library" target="_blank">https://github.com/adafruit/Adafruit-GFX-Library</a>
     
    */


    This sketch was made for my video tutorial shown here:


    Made by InterlinkKnight
    Last update: 05/23/2019
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    ///////////////
    // Calibration:
    ///////////////
     
    const byte PulsesPerRevolution = 4;  // Set how many pulses there are on each revolution. Default: 2.
     
     
    // If the period between pulses is too high, or even if the pulses stopped, then we would get stuck showing the
    // last value instead of a 0. Because of this we are going to set a limit for the maximum period allowed.
    // If the period is above this value, the RPM will show as 0.
    // The higher the set value, the longer lag/delay will have to sense that pulses stopped, but it will allow readings
    // at very low RPM.
    // Setting a low value is going to allow the detection of stop situations faster, but it will prevent having low RPM readings.
    // The unit is in microseconds.
    const unsigned long ZeroTimeout = 100000;  // For high response time, a good value would be 100000.
                                               // For reading very low RPM, a good value would be 300000.
     
     
    // Calibration for smoothing RPM:
    const byte numReadings = 2;  // Number of samples for smoothing. The higher, the more smoothing, but it's going to
                                 // react slower to changes. 1 = no smoothing. Default: 2.
     
     
     
     
     
    /////////////
    // Variables:
    /////////////
     
    volatile unsigned long LastTimeWeMeasured;  // Stores the last time we measured a pulse so we can calculate the period.
    volatile unsigned long PeriodBetweenPulses = ZeroTimeout+1000;  // Stores the period between pulses in microseconds.
                           // It has a big number so it doesn't start with 0 which would be interpreted as a high frequency.
    volatile unsigned long PeriodAverage = ZeroTimeout+1000;  // Stores the period between pulses in microseconds in total, if we are taking multiple pulses.
                           // It has a big number so it doesn't start with 0 which would be interpreted as a high frequency.
    unsigned long FrequencyRaw;  // Calculated frequency, based on the period. This has a lot of extra decimals without the decimal point.
    unsigned long FrequencyReal;  // Frequency without decimals.
    unsigned long RPM;  // Raw RPM without any processing.
    unsigned int PulseCounter = 1;  // Counts the amount of pulse readings we took so we can average multiple pulses before calculating the period.
     
    unsigned long PeriodSum; // Stores the summation of all the periods to do the average.
     
    unsigned long LastTimeCycleMeasure = LastTimeWeMeasured;  // Stores the last time we measure a pulse in that cycle.
                                        // We need a variable with a value that is not going to be affected by the interrupt
                                        // because we are going to do math and functions that are going to mess up if the values
                                        // changes in the middle of the cycle.
    unsigned long CurrentMicros = micros();  // Stores the micros in that cycle.
                                             // We need a variable with a value that is not going to be affected by the interrupt
                                             // because we are going to do math and functions that are going to mess up if the values
                                             // changes in the middle of the cycle.
     
    // We get the RPM by measuring the time between 2 or more pulses so the following will set how many pulses to
    // take before calculating the RPM. 1 would be the minimum giving a result every pulse, which would feel very responsive
    // even at very low speeds but also is going to be less accurate at higher speeds.
    // With a value around 10 you will get a very accurate result at high speeds, but readings at lower speeds are going to be
    // farther from eachother making it less "real time" at those speeds.
    // There's a function that will set the value depending on the speed so this is done automatically.
    unsigned int AmountOfReadings = 1;
     
    unsigned int ZeroDebouncingExtra;  // Stores the extra value added to the ZeroTimeout to debounce it.
                                       // The ZeroTimeout needs debouncing so when the value is close to the threshold it
                                       // doesn't jump from 0 to the value. This extra value changes the threshold a little
                                       // when we show a 0.
     
    // Variables for smoothing tachometer:
    unsigned long readings[numReadings];  // The input.
    unsigned long readIndex;  // The index of the current reading.
    unsigned long total;  // The running total.
    unsigned long average;  // The RPM value after applying the smoothing.
     
    #include <TinyGPS++.h>
    #include <SoftwareSerial.h>
    #include <SPI.h>
    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
     
    float current;
    int termPin = 6;  //termistor pin connection
    int termNom = 100000;   //resistancve du termistor
    int refTemp = 25;    // 
    int beta = 3950;
    int resistance = 100000; // valeure resistance serie
     
     
     
     
    // OLED 0.96" Display:
    #include <Adafruit_GFX.h>  // Include core graphics library for the display.
    #include <Adafruit_SSD1306.h>  // Include Adafruit_SSD1306 library to drive the display.
    Adafruit_SSD1306 display(128, 64);  // Create display.
    #include <Fonts/FreeMonoBold18pt7b.h>  // Add a custom font.
     
    const int RXPin = 2, TXPin = 5;
    const uint32_t GPSBaud = 9600; //Default baud of NEO-6M is 9600
     
     
    TinyGPSPlus gps; // the TinyGPS++ object
    SoftwareSerial gpsSerial(RXPin, TXPin); // the serial interface to the GPS device
     //variable
     
     
     
     
    void setup() { // Start of setup:
     
    {{
     
     Serial.begin(9600);  // Begin serial communication.
     {gpsSerial.begin(GPSBaud);
     
     {attachInterrupt(digitalPinToInterrupt(3), Pulse_Event, RISING);     // Enable interruption pin 2 when going from LOW to HIGH.   { Serial.begin(9600);
     }
     
      delay(1000);  // We sometimes take several readings of the period to average. Since we don't have any readings
                    // stored we need a high enough value in micros() so if divided is not going to give negative values.
                    // The delay allows the micros() to be high enough for the first few cycles.
     
         // OLED 0.96" Display:
      display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // Initialize display with the I2C address of 0x3C.
      display.clearDisplay();  // Clear the buffer.
      display.setTextColor(WHITE);  // Set color of the text to white.
      display.setRotation(0);  // Set orientation. Goes from 0, 1, 2 or 3.
      display.setTextWrap(false);  // By default, long lines of text are set to automatically “wrap” back to the leftmost column.
                                   // To override this behavior (so text will run off the right side of the display - useful for
                                   // scrolling marquee effects), use setTextWrap(false). The normal wrapping behavior is restored
                                   // with setTextWrap(true).
      display.dim(0);  // Set brightness (0 is maximum and 1 is a little dim).
     
      // End of setup.
     
     
    void Pulse_Event()  // The interrupt runs this to calculate the period between pulses:
    {
     
      PeriodBetweenPulses = micros() - LastTimeWeMeasured;  // Current "micros" minus the old "micros" when the last pulse happens.
                                                            // This will result with the period (microseconds) between both pulses.
                                                            // The way is made, the overflow of the "micros" is not going to cause any issue.
     
      LastTimeWeMeasured = micros();  // Stores the current micros so the next time we have a pulse we would have something to compare with.
     
     
     
     
     
      if(PulseCounter >= AmountOfReadings)  // If counter for amount of readings reach the set limit:
      {
        PeriodAverage = PeriodSum / AmountOfReadings;  // Calculate the final period dividing the sum of all readings by the
                                                       // amount of readings to get the average.
        PulseCounter = 1;  // Reset the counter to start over. The reset value is 1 because its the minimum setting allowed (1 reading).
        PeriodSum = PeriodBetweenPulses;  // Reset PeriodSum to start a new averaging operation.
     
     
        // Change the amount of readings depending on the period between pulses.
        // To be very responsive, ideally we should read every pulse. The problem is that at higher speeds the period gets
        // too low decreasing the accuracy. To get more accurate readings at higher speeds we should get multiple pulses and
        // average the period, but if we do that at lower speeds then we would have readings too far apart (laggy or sluggish).
        // To have both advantages at different speeds, we will change the amount of readings depending on the period between pulses.
        // Remap period to the amount of readings:
        int RemapedAmountOfReadings = map(PeriodBetweenPulses, 40000, 5000, 1, 10);  // Remap the period range to the reading range.
        // 1st value is what are we going to remap. In this case is the PeriodBetweenPulses.
        // 2nd value is the period value when we are going to have only 1 reading. The higher it is, the lower RPM has to be to reach 1 reading.
        // 3rd value is the period value when we are going to have 10 readings. The higher it is, the lower RPM has to be to reach 10 readings.
        // 4th and 5th values are the amount of readings range.
        RemapedAmountOfReadings = constrain(RemapedAmountOfReadings, 1, 10);  // Constrain the value so it doesn't go below or above the limits.
        AmountOfReadings = RemapedAmountOfReadings;  // Set amount of readings as the remaped value.
      }
      else
      {
        PulseCounter++;  // Increase the counter for amount of readings by 1.
        PeriodSum = PeriodSum + PeriodBetweenPulses;  // Add the periods so later we can average.
     
     // End of Pulse_Event.
     
      }
     
             void loop()  {
     
             if (gpsSerial.available() > 0) {
             if (gps.encode(gpsSerial.read())) {
             //display.clearDisplay () ;
          // display.setCursor (0,0) ;
          // display.print(F("- speed: "));
             if (gps.speed.isValid()) {
               .clearDisplay () ;
                display.setTextSize (4) ;
                display.setCursor (0,5) ;
                display.print(gps.speed.kmph());
     
                display.display () ;
                delay (3000) ;
     
     
     
            //if (gps.date.isValid() && gps.time.isValid()) {
     
          display.clearDisplay () ;
          display.setTextSize (4) ;
            // display.setTextColor (WHITE) ;
          display.setCursor (0,5) ;
            //display.clearDisplay () ;
             display.print(gps.time.hour() +1 +1);
             display.print(F(":"));
             display.print(gps.time.minute());
            // display.print(F(":"));
            // display.println(gps.time.second());
     
                display.display () ;
                delay (1000) ;
     
     
     
          current = analogRead(termPin);
          current = 1023 / current - 1;
          current = resistance / current;
          float temperature;
          temperature = current / termNom;
          temperature = log(temperature);
          temperature /= beta;
          temperature += 1.0 / (refTemp + 273.15);
          temperature = 1.0 / temperature;
          temperature -= 273.15;
     
                   display.clearDisplay () ;
                   display.setTextSize (4) ;
                   display.setCursor ( 0,5) ;
                   display.print(temperature,1);
                   display.display () ;
                   delay (2000);
         }}
     
      // The following is going to store the two values that might change in the middle of the cycle.
      // We are going to do math and functions with those values and they can create glitches if they change in the
      // middle of the cycle.
      LastTimeCycleMeasure = LastTimeWeMeasured;  // Store the LastTimeWeMeasured in a variable.
      CurrentMicros = micros();  // Store the micros() in a variable.
     
     
     
     
     
      // CurrentMicros should always be higher than LastTimeWeMeasured, but in rare occasions that's not true.
      // I'm not sure why this happens, but my solution is to compare both and if CurrentMicros is lower than
      // LastTimeCycleMeasure I set it as the CurrentMicros.
      // The need of fixing this is that we later use this information to see if pulses stopped.
      if(CurrentMicros < LastTimeCycleMeasure)
      {
        LastTimeCycleMeasure = CurrentMicros;
      }
     
     
     
     
     
      // Calculate the frequency:
      FrequencyRaw = 10000000000 / PeriodAverage;  // Calculate the frequency using the period between pulses.
     
     
     
     
     
      // Detect if pulses stopped or frequency is too low, so we can show 0 Frequency:
      if(PeriodBetweenPulses > ZeroTimeout - ZeroDebouncingExtra || CurrentMicros - LastTimeCycleMeasure > ZeroTimeout - ZeroDebouncingExtra)
      {  // If the pulses are too far apart that we reached the timeout for zero:
        FrequencyRaw = 0;  // Set frequency as 0.
        ZeroDebouncingExtra = 2000;  // Change the threshold a little so it doesn't bounce.
      }
      else
      {
        ZeroDebouncingExtra = 0;  // Reset the threshold to the normal value so it doesn't bounce.
      }
     
     
     
     
     
      FrequencyReal = FrequencyRaw / 10000;  // Get frequency without decimals.
                                              // This is not used to calculate RPM but we remove the decimals just in case
                                              // you want to print it.
     
     
     
     
     
      // Calculate the RPM:
      RPM = FrequencyRaw / PulsesPerRevolution * 60;  // Frequency divided by amount of pulses per revolution multiply by
                                                      // 60 seconds to get minutes.
      RPM = RPM / 10000;  // Remove the decimals.
     
     
     
     
     
      // Smoothing RPM:
      total = total - readings[readIndex];  // Advance to the next position in the array.
      readings[readIndex] = RPM;  // Takes the value that we are going to smooth.
      total = total + readings[readIndex];  // Add the reading to the total.
      readIndex = readIndex + 1;  // Advance to the next position in the array.
     
      if (readIndex >= numReadings)  // If we're at the end of the array:
      {
        readIndex = 0;  // Reset array index.
      }
     
      // Calculate the average:
      average = total / numReadings;  // The average value it's the smoothed result.
     
     
     
     
     
    /*
      // Print information on the serial monitor:
      // Comment this section if you have a display and you don't need to monitor the values on the serial monitor.
      // This is because disabling this section would make the loop run faster.
      Serial.print("Period: ");
      Serial.print(PeriodBetweenPulses);
      Serial.print("\tReadings: ");
      Serial.print(AmountOfReadings);
      Serial.print("\tFrequency: ");
      Serial.print(FrequencyReal);
      Serial.print("\tRPM: ");
      Serial.print(RPM);
      Serial.print("\tTachometer: ");
      Serial.println(average);
    */
     
     
     
     
     
      // OLED 0.96" Display:
      // Convert variable into a string, so we can change the text alignment to the right:
      // It can be also used to add or remove decimal numbers.
      char string[10];  // Create a character array of 10 characters
      // Convert float to a string:
      dtostrf(average, 6, 0, string);  // (<variable>,<amount of digits we are going to use>,<amount of decimal digits>,<string name>)
     
      display.clearDisplay();  // Clear the display so we can refresh.
      display.setFont(&FreeMonoBold18pt7b);  // Set a custom font.
      display.setTextSize(0);  // Set text size. We are using a custom font so you should always use the text size of 0.
      display.setCursor(0, 25);  // (x,y).
      display.println("RPM:");  // Text or value to print.
     
      // Print variable with right alignment:
      display.setCursor(0, 60);  // (x,y).
      display.println(string);  // Text or value to print.
     
      // Print a comma for the thousands separator:
      if(average > 999)  // If value is above 999:
      {
        // Draw line (to show a comma):
        display.drawLine(63, 60, 61, 65, WHITE);  // Draw line (x0,y0,x1,y1,color).
      }
     
      display.display();  // Print everything we set previously.
     
            // delay (3000) ;
     
    //}  // End of loop.
     
     
     // End of Pulse_Event.
    }
     
     
     
    void Pulse_Event()  // The interrupt runs this to calculate the period between pulses:
    {
     
      PeriodBetweenPulses = micros() - LastTimeWeMeasured;  // Current "micros" minus the old "micros" when the last pulse happens.
                                                            // This will result with the period (microseconds) between both pulses.
                                                            // The way is made, the overflow of the "micros" is not going to cause any issue.
     
      LastTimeWeMeasured = micros();  // Stores the current micros so the next time we have a pulse we would have something to compare with.
     
     
     
     
     
      if(PulseCounter >= AmountOfReadings)  // If counter for amount of readings reach the set limit:
      {
        PeriodAverage = PeriodSum / AmountOfReadings;  // Calculate the final period dividing the sum of all readings by the
                                                       // amount of readings to get the average.
        PulseCounter = 1;  // Reset the counter to start over. The reset value is 1 because its the minimum setting allowed (1 reading).
        PeriodSum = PeriodBetweenPulses;  // Reset PeriodSum to start a new averaging operation.
     
     
        // Change the amount of readings depending on the period between pulses.
        // To be very responsive, ideally we should read every pulse. The problem is that at higher speeds the period gets
        // too low decreasing the accuracy. To get more accurate readings at higher speeds we should get multiple pulses and
        // average the period, but if we do that at lower speeds then we would have readings too far apart (laggy or sluggish).
        // To have both advantages at different speeds, we will change the amount of readings depending on the period between pulses.
        // Remap period to the amount of readings:
        int RemapedAmountOfReadings = map(PeriodBetweenPulses, 40000, 5000, 1, 10);  // Remap the period range to the reading range.
        // 1st value is what are we going to remap. In this case is the PeriodBetweenPulses.
        // 2nd value is the period value when we are going to have only 1 reading. The higher it is, the lower RPM has to be to reach 1 reading.
        // 3rd value is the period value when we are going to have 10 readings. The higher it is, the lower RPM has to be to reach 10 readings.
        // 4th and 5th values are the amount of readings range.
        RemapedAmountOfReadings = constrain(RemapedAmountOfReadings, 1, 10);  // Constrain the value so it doesn't go below or above the limits.
        AmountOfReadings = RemapedAmountOfReadings;  // Set amount of readings as the remaped value.
      }
      else
      {
        PulseCounter++;  // Increase the counter for amount of readings by 1.
        PeriodSum = PeriodSum + PeriodBetweenPulses;  // Add the periods so later we can average.
     
     // End of Pulse_Event.
     
         }}}

  2. #2
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 625
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 625
    Par défaut
    Bonjour,

    Si c'est le même programme qui fonctionnait avant, il n'est pas en cause si rien n'a changé.

    Donc la question est : qu'est-ce qui a changé ? Cela peut être volontaire, par exemple le replacement du MCU par un - presque - équivalent. Cela peut aussi être involontaire comme le déplacement d'un câblage volant altérant des branchements.

    Résumé : il faut plus d'informations.

    Salutations

Discussions similaires

  1. Programme de boot qui passe la main à Windows
    Par Bob dans le forum Assembleur
    Réponses: 7
    Dernier message: 25/11/2002, 03h08
  2. [Kylix] Probleme d'execution de programmes...
    Par yopziggy dans le forum EDI
    Réponses: 19
    Dernier message: 03/05/2002, 14h50
  3. communication entre programmes
    Par jérôme dans le forum C
    Réponses: 12
    Dernier message: 16/04/2002, 08h05
  4. Comment débuter en programmation ?
    Par Marc Lussac dans le forum Débuter
    Réponses: 0
    Dernier message: 08/04/2002, 11h29
  5. [Kylix] icone associée à un programme
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 22/03/2002, 09h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo