DCC-EX / CommandStation-EX

EX-CommandStation firmware from DCC-EX. Includes support for WiFi and a standalone WiThrottle server. A complete re-write of the original DCC++.
https://dcc-ex.github.io/
GNU General Public License v3.0
154 stars 104 forks source link

Current measurement #260

Open tanner87661 opened 1 year ago

tanner87661 commented 1 year ago

Change overview

  1. Changes to the command reference

  2. Measurement methodology a) Internal After each current measurement, the getCurrentmA() value is squared and added to a rolling average. When getCurrentRMS() is called, the rolling average is divided by buffer size and rounded sqrt is reported. This is the current in mA. Advantage is the calculation is done in DCC EX. Disadvantage is that due to the average calculation reaction of going down to zero is slow b) broadcast After each current measurement, the getCurrentmA() result is sent to the serial interface. Processing of RMS calculation is done on the host computer where more memory is available to do a ring buffer for each track for the square values, leading to faster phase out if zero current. This is my preferred solution for the RedHat, would also work for JMRI

tanner87661 commented 1 year ago

Please help me to understand. What is async about those calls? They are made from the loop function, similar like responses in DCCExParser. outStream is just a pointer to the stream that is also used in DCCExParser within the same loop system. That way I can send feedback right when analogRead is done. Alternatively I could set a flag and do a separate reporting function and call it from SerialManager.loop2 with serial as parameter. Also this, in my understanding, would be in sync with everything else. What am I missing?

Asbelos commented 1 year ago

What you are missing is that the stream passed to parse is only valid for the duration of the parse call... sometimes its a serial (in which case your code would work) and sometimes its a ring buffer ready prepared to return output to the wifi/ethernet caller. Most commands reply immediately without caring but things that want to reply later (eg a cv read) need to re-prepare the buffer to the correct client before writing.

The prog track commands have to follow due process to ensure that the reply goes to the original caller AND that only one caller can be asking!

The alternative is to create a broadcast function like those in CommandDistributor and send the current to all non-withrottle clients.

tanner87661 commented 1 year ago

Ok, I added broadcastCurrent. After reviewing the other broadcast functions, this seemed to me like the most logical approach. I also changed the A command to only accept 0 and 1 to configure the return messages. I just commented out the code for internal calculation, so we can get back to it later and do an integer version.