Jump to content

NLCbanner2024.jpg.2478be509670e60c2d6efd04834b8b47.jpg

Gina

Beyond the Event Horizon
  • Posts

    45,326
  • Joined

  • Last visited

  • Days Won

    120

Posts posted by Gina

  1. I'm running the timer interrupt at 3s.  Only the number of hardware interrupts within that period is important.  The 1m speed integration can be done on counts of the timer ISR.  As long as there are 20 sets of counts summed in the 1m routine it doesn't really matter if the odd set of counts gets lost.

  2. I have yet to work out what I need to do to this to suit my system.

    void loop() {
      if (interrupts > 0) {
        portENTER_CRITICAL(&timerMux);
        interrupts--;
        portEXIT_CRITICAL(&timerMux);
        totalInterrupts++;
        Serial.print("totalInterrupts");
        Serial.println(totalInterrupts);
      }
    }

     

  3. Only the wind speed timings and calculations are time critical, the direction isn't and could be handled with periods in the main loop as before.  Same with all the MQTT messages with a flag to show when speed messages were ready to send.

  4. Tried increasing number of timer ticks to 3,000,000 for 3s and that worked as expected.

    301170664_Screenshotfrom2020-09-0413-36-45.png.5db5f35d8dc83c17c38e54b7a9e08919.png

    Now I presume I just need to insert the do3sJobs(); in the interrupt handler instead of interrupts++;

    void IRAM_ATTR onTime() {
      portENTER_CRITICAL_ISR(&timerMux);
      interrupts++;
      portEXIT_CRITICAL_ISR(&timerMux);
    }

    Like this

    void IRAM_ATTR onTime() {
      portENTER_CRITICAL_ISR(&timerMux);
      do3sJobs();
      portEXIT_CRITICAL_ISR(&timerMux);
    }

    Then inside the do3sJobs(); count 20 times and do the do1mJobs(); after which it will return to what it was doing in the main loop including reconnecting.

    Ah...  had a thought - the sending messages to MQTT would be in the time critical code.  Only the time critical calculations need doing within the interrupt coding.  I could set a flag and do the sending messages in the main loop.

  5. Tried moving the interrupt handler above the setup and it worked!!!

    volatile int interrupts;
    int totalInterrupts;
    
    hw_timer_t * timer = NULL;
    portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
    
    void IRAM_ATTR onTime() {
      portENTER_CRITICAL_ISR(&timerMux);
      interrupts++;
      portEXIT_CRITICAL_ISR(&timerMux);
    }
     
    void setup() {
    
      Serial.begin(115200);
    
      // Configure Prescaler to 80, as our timer runs @ 80Mhz
      // Giving an output of 80,000,000 / 80 = 1,000,000 ticks / second
      timer = timerBegin(0, 80, true);                
      timerAttachInterrupt(timer, &onTime, true);    
      // Fire Interrupt every 1m ticks, so 1s
      timerAlarmWrite(timer, 1000000, true);      
      timerAlarmEnable(timer);
    }
    
    void loop() {
      if (interrupts > 0) {
        portENTER_CRITICAL(&timerMux);
        interrupts--;
        portEXIT_CRITICAL(&timerMux);
        totalInterrupts++;
        Serial.print("totalInterrupts");
        Serial.println(totalInterrupts);
      }
    }

     

  6. Found this and tried it :- Timer Interrupts Explained with Examples

    volatile int interrupts;
    int totalInterrupts;
    
    hw_timer_t * timer = NULL;
    portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
    
    void setup() {
    
      Serial.begin(115200);
    
      // Configure Prescaler to 80, as our timer runs @ 80Mhz
      // Giving an output of 80,000,000 / 80 = 1,000,000 ticks / second
      timer = timerBegin(0, 80, true);                
      timerAttachInterrupt(timer, &onTime, true);    
      // Fire Interrupt every 1m ticks, so 1s
      timerAlarmWrite(timer, 1000000, true);      
      timerAlarmEnable(timer);
    }
    
    void IRAM_ATTR onTime() {
      portENTER_CRITICAL_ISR(&timerMux);
      interrupts++;
      portEXIT_CRITICAL_ISR(&timerMux);
    }
    
    void loop() {
      if (interrupts > 0) {
        portENTER_CRITICAL(&timerMux);
        interrupts--;
        portEXIT_CRITICAL(&timerMux);
        totalInterrupts++;
        Serial.print("totalInterrupts");
        Serial.println(totalInterrupts);
      }
    }

    But it won't compile - with this error :-

    1274312226_Screenshotfrom2020-09-0413-16-33.thumb.png.9b474f736fbfe1f3f6bfa71808266348.png

    I thought "This looks simple enough."  Thought I'd found something I could build on, after all it shouldn't be that difficult.  Just need the info.  Guess my search continues...  Unless anyone can help or explain this.

  7. 2 hours ago, skybadger said:

    you can also drop this line as no longer required 

    
    if (!client.connected()) {reconnect();}

    since the Wifi object will auto reconnect if it detects a broken connection.

    That reconnect is what is causing all the trouble it seems - leave the system frozen for at least 5s while it tries to reconnect.

    I can easily remove that line but what about the following line - is that alright still.

    void loop() {
      if (!client.connected()) {reconnect();}
      client.loop();

     

  8. I shall have to try to arrange that a lost connection doesn't interfere with the calculations. 

    I can see why the disconnections cause an increase in Gust speed and a reduction in Mean speed.  The Gust speed is obtained from the number of anemometer pulses and therefore the number of counts from the interrupt handler.  The interrupt handler is not interrupted by disconnection but the resulting count continues to rise if the 3s period is interrupted by disconnection.  OTOH the Mean is dependent on the summing process and if that is interrupted, data is lost resulting in a lower sum.

  9. I can use the test setup to cause connection failures by interrupting the WiFi signal.

    Or so I thought but I can't stop the connection.  I've completely shielded the WiFi with metal but it still connects.  Maybe it's because it's connected to my Mint box by USB.

  10. 16 minutes ago, skybadger said:

    Can you get a ring buffer dump every time you have gone round the ring index. 

    I certainly could.

    Quote

    Is your buffer being written from somewhere else too ?

    Pretty certain it isn't.

    Quote

    If you are happy that the individual values are in range, does the sum overflow ?

    No, it doesn't.

    Quote

    Are you getting a rash of spurious edges that cause it to occasionally overflow ? a la button damping ?

    No, I don't think so, the Hall device has considerable hysteresis and produces clean, square pulses.

  11. Things seem to work fine when there are no disconnects - I think this is the problem.  I need to take account of the ESP32 getting locked up by connection problems.  And I though using timing periods was a clever approach!!!  Guess I'm not as clever as I like to think!! 🤣

    1446021449_Screenshotfrom2020-09-0318-03-52.thumb.png.3477389ffbea5df0fcbc7dc58fbd2586.png

  12. 12 minutes ago, globular said:

    Hi Gina,

    The maths within do1mjobs relies on do3sjobs being called 20 times between runs; you have a /133 (and the 133 = 10 * 20/1.5).  With connection issues causing 5 second waits between retries there may not always be 20 calls to do3sjobs and so your mean calculation will be too low (i.e dividing the sum of less than 20 speeds by 20 will lower the average speed).

    You could solve this by incrementing a counter in do3sjobs which is then used in do1mjobs instead of the fixed 133 (i.e. use /(10*counter/1.5); and then reset it to zero after it's been used in do1mjobs.

    I'm not sure why everything resets to zero though - it seems unlikely connection delays could last long enough to cause that. 

    Ah yes, lost connection delays could cause a problem and yes, using counting rather than timing would be better.  The actual timing of messages is not important but getting them right is.

  13. Well, the test sketch is not showing the problem I'm getting with the real thing!!  That seems to prove the problem is not with the calculations but there is a problem none the less!!  The direction calculations are still running and everything is the same as the real thing except I'm simulating the anemometer pulses.  The only thing I can think of trying is to set up all the dials and graphs as the real thing in a Test tab on the Dashboard.

    One other thing occurs to me - everything was fine with the display for a couple of days so I'm wondering if there is something time related.  I guess I could reset the real wind client by powering down and back up again.

    Here's the current Wind display before I shut it down.

    1964271613_Screenshotfrom2020-09-0316-38-47.png.7288c834522c586aaa488465728a6b52.png

  14. Well, I guess it isn't too bad but it isn't right so it fails the test.  Timing variations might explain the Gust speed varying between 12 and 13.  The Mean Speed is supposed to be displayed in tenths but I may have used int as speed to the nearest mph is good enough.  Think I'll try a large increase in wind speed and see if serious errors arise.  I'll go to 200ms next - 5pps = 5x4.5mph = 22.5mph.  I would expect the speed to show as 22 or 23.

    84990726_Screenshotfrom2020-09-0315-51-12.thumb.png.0b123577cc26999a1be1a24595d00d5b.png

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. By using this site, you agree to our Terms of Use.