EnviroDIY / Arduino-SDI-12

An Arduino library for SDI-12 communication with a wide variety of environmental sensors. This library provides a general software solution, without requiring any additional hardware.
https://github.com/EnviroDIY/Arduino-SDI-12/wiki
BSD 3-Clause "New" or "Revised" License
158 stars 100 forks source link

AVR 1284P @4Mhz which #define RX_WINDOW_FUDGE to be set in .h? #49

Open xsensefw opened 5 years ago

xsensefw commented 5 years ago

Hi, I'm testing the library running on a AVR 1284P @ 4 Mhz. I would use the following setting but I don' understand the parameter RX_WINDOW_FUDGE in the .h file Is a value of 20 for my case fine?

Many thanks for the support, Kind Regards,

Martino

#if F_CPU == 16000000L
    #define PRESCALE_IN_USE_STR "1024"
    #define TICKS_PER_BIT 13
        // 16MHz / 1024 prescaler = 15624 'ticks'/sec = 64 µs / 'tick'
        // (1 sec/1200 bits) * (1 tick/64 µs) = 13.0208 ticks/bit
    #define BITS_PER_TICK_Q10 79
        // 1/(13.0208 ticks/bit) * 2^10 = 78.6432
    #define RX_WINDOW_FUDGE 2

    static uint8_t preSDI12_TCCR2A;
    static uint8_t preSDI12_TCCR2B;
    void configSDI12TimerPrescale(void)
    {
        preSDI12_TCCR2A = TCCR2A;
        preSDI12_TCCR2B = TCCR2B;
        TCCR2A = 0x00;  // TCCR2A = 0x00 = "normal" operation - Normal port operation, OC2A & OC2B disconnected
        TCCR2B = 0x07;  // TCCR2B = 0x07 = 0b00000111 - Clock Select bits 22, 21, & 20 on - prescaler set to CK/1024
    }
    void resetSDI12TimerPrescale(void)
    {
        TCCR2A = preSDI12_TCCR2A;
        TCCR2B = preSDI12_TCCR2B;
    }

#elif F_CPU == 8000000L
    #define PRESCALE_IN_USE_STR "256"
    #define TICKS_PER_BIT 26
        // 8MHz / 256 prescaler = 31250 'ticks'/sec = 32 µs / 'tick'
        // (1 sec/1200 bits) * (1 tick/32 µs) = 26.04166667 ticks/bit
    #define BITS_PER_TICK_Q10 39
        // 1/(26.04166667 ticks/bit) * 2^10 = 39.3216
    #define RX_WINDOW_FUDGE 10

    static uint8_t preSDI12_TCCR2A;
    static uint8_t preSDI12_TCCR2B;
    void configSDI12TimerPrescale(void)
    {
        preSDI12_TCCR2A = TCCR2A;
        preSDI12_TCCR2B = TCCR2B;
        TCCR2A = 0x00;  // TCCR2A = 0x00 = "normal" operation - Normal port operation, OC2A & OC2B disconnected
        TCCR2B = 0x06;  // TCCR2B = 0x06 = 0b00000110 - Clock Select bits 22 & 20 on - prescaler set to CK/256
    }
    void resetSDI12TimerPrescale(void)
    {
        TCCR2A = preSDI12_TCCR2A;
        TCCR2B = preSDI12_TCCR2B;
    }

    // #define PRESCALE_IN_USE_STR "1024"
    // #define TICKS_PER_BIT 6
    //     // 8MHz / 1024 prescaler = 31250 'ticks'/sec = 128 µs / 'tick'
    //     // (1 sec/1200 bits) * (1 tick/128 µs) = 6.5104166667 ticks/bit
    // #define BITS_PER_TICK_Q10 157
    //     // 1/(6.5104166667 ticks/bit) * 2^10 = 157.2864
    // #define RX_WINDOW_FUDGE 5

    // uint8_t preSDI12_TCCR2A;
    // uint8_t preSDI12_TCCR2B;
    // void configSDI12TimerPrescale(void)
    // {
    //     preSDI12_TCCR2A = TCCR2A;
    //     preSDI12_TCCR2B = TCCR2B;
    //     TCCR2A = 0x00;  // TCCR2A = 0x00 = "normal" operation - Normal port operation, OC2A & OC2B disconnected
    //     TCCR2B = 0x07;  // TCCR2B = 0x07 = 0b00000111 - Clock Select bits 22, 21, & 20 on - prescaler set to CK/1024
    // }
    // void resetSDI12TimerPrescale(void)
    // {
    //     TCCR2A = preSDI12_TCCR2A;
    //     TCCR2B = preSDI12_TCCR2B;
    // }

// xSense AVR 1284P
#elif F_CPU == 4000000L
    #define PRESCALE_IN_USE_STR "256"
    #define TICKS_PER_BIT 13
        // 4MHz / 256 prescaler = 15625 'ticks'/sec = 64 µs / 'tick'
        // (1 sec/1200 bits) * (1 tick/64 µs) = 13.02083333 ticks/bit
    #define BITS_PER_TICK_Q10 79
        // 1/(26.04166667 ticks/bit) * 2^10 = 78.6432
    #define RX_WINDOW_FUDGE 20

    static uint8_t preSDI12_TCCR2A;
    static uint8_t preSDI12_TCCR2B;
    void configSDI12TimerPrescale(void)
    {
        preSDI12_TCCR2A = TCCR2A;
        preSDI12_TCCR2B = TCCR2B;
        TCCR2A = 0x00;  // TCCR2A = 0x00 = "normal" operation - Normal port operation, OC2A & OC2B disconnected
        TCCR2B = 0x06;  // TCCR2B = 0x06 = 0b00000110 - Clock Select bits 22 & 20 on - prescaler set to CK/256
    }
    void resetSDI12TimerPrescale(void)
    {
        TCCR2A = preSDI12_TCCR2A;
        TCCR2B = preSDI12_TCCR2B;
    }

 #endif
SRGDamia1 commented 5 years ago

The RX_WINDOW_FUDGE really is just a fudge factor to make it work. It mostly works to ensure that uneven tick increments get rounded up. I've come up with the existing values just by playing with a board and seeing what values work well.

The whole concept of using the timers comes from NeoSWSerial. He has some explanation of the RxWindowWidth (that comes from the RX_WINDOW_FUDGE) here: https://github.com/SlashDevin/NeoSWSerial/pull/13.

So, if 20 seems to be working nicely for you, then it's probably a good value to put in there.