[go: up one dir, main page]

  • Cancel
    Showing results for 
    Show  only  | Search instead for 
    Did you mean: 

    Accelerometer app crashing during the night

    I have a an app that needs to :
    - read accelerometer data at 50Hz.
    - aggregate 1minute of these readings
    - verify if the sum of the standard deviations of x,y,and z is larger than a threshold. 
        - if yes, write the aggregated data into a file
        - if not, empty the buffer and repeat. 

    The app runs normally during the day when I test it. It runs for hours no issues.

    However, when I use it at night time, I noticed the app would last at most a couple of hours then it crashes. 

    Here are pieces of code I use, in hopes that someone can help me understand the issue. 
    This piece reads the accelerometer, aggregates the sum of standard deviations and the ts,x,y,z values. 

     

     startAccel() {
    
            this.dataBufferView[this.bufferIndex++] = Int16Array.from(Date.now() - this.fitbitData.sessionDate)
    
            //console.log("I am startAccel")
            this.accelerometer.addEventListener("reading", () => {
    
                this.ss = scientific.std(this.accelerometer.readings.x) + scientific.std(this.accelerometer.readings.y) + scientific.std(this.accelerometer.readings.z);
                this.accelCumm.push(this.ss);
                fileTimestamp = prevTimestamp = this.accelerometer.readings.timestamp[0]
                const batchSize = this.accelerometer.readings.timestamp.lengthf
                // let bufferIndex = 0, timestamp
                //console.log(`ss=${this.ss}`)
                //console.log(`timestamp[]=${accel.readings.timestamp}`)
                for (let index = 0; index < batchSize; index++) {
                    //console.log(`${accel.readings.timestamp[index]} ${accel.readings.x[index]}}`)
                    // timestamp = this.accelerometer.readings.timestamp[index]
                    // this.dataBufferView[bufferIndex++] = timestamp - prevTimestamp // store differential timestamps so they fit in Int16
                    // prevTimestamp = timestamp
    
                    this.dataBufferView[this.bufferIndex++] = this.accelerometer.readings.x[index] * ACCEL_SCALAR
                    this.dataBufferView[this.bufferIndex++] = this.accelerometer.readings.y[index] * ACCEL_SCALAR
                    this.dataBufferView[this.bufferIndex++] = this.accelerometer.readings.z[index] * ACCEL_SCALAR
                }
    
            });
            this.accelerometer.start();
    
        }

     

    This here is where I verify the max of the standard deviations and if it is higher than a threshold. 

     

    sendAccelInfo = () => {
            fs.writeSync(this.file, this.dataBufferView);
            // fs.closeSync(this.file);
            let stats = fs.statSync('pippo.bin');
            //vibration.start("ping");
            displayText.text = `Size: ${stats.size} B`;
    
        }
    
        get_accelerometer = () => {
            let maxActivity = 0;
            for (let i = 0; i < this.accelCumm.length; i++) {
                if (this.accelCumm[i] > maxActivity) {
                    maxActivity = this.accelCumm[i]
                }
            }
    
            if (maxActivity >= this.maxIntesityThreshold) {
                console.log(`Max=${maxActivity} is found..break`);
                this.sendAccelInfo()
                this.bufferIndex = 0;
                this.accelCumm = [];
            }
    
            if (this.stopAccel) {
                clearInterval(this.tid2);
                fs.closeSync(this.file);
            }
    
        }

     

    - the get_accelerometer function is called in a setInterval every 60 seconds.  
    - the binary file is open at the beginning of the app and closed when the app is closed in the morning. It is opened as 

     

    this.file = fs.openSync('pippo.bin', "w")

     

    In my first testings, I thought the app would simply run out of memory since it has to keep 18kb of data for every minute but I tried running the app during the day for hours and it did not crash. Also if I understood correctly, there is a 4MB usable memory.

    Unfortunately I am not very proficient with JS and I ran out of ideas on where I am getting it wrong. What also puzzles me is why does the app crashes at night when I go to sleep? Is it because of sleep monitoring running while also my app is running and thus my app, consuming a lot of memory is getting killed to give way to sleep monitoring? 

    my idea is to open and close the app everytime with append instead of opening it once and leaving it there.

     

    Please let me know if you have any suggestions of what I might have been missing. 

    Best Answer
    0 Votes
    9 REPLIES 9

    I doubt it's running out of memory, but it's worth checking. Use this. Don't worry if you see it building up; JS only frees memory when it needs to.

    A memory leak isn't impossible, but if you're reusing data structures and/or scoping things properly, that shouldn't be a problem.

    Will you buffer be emptied if SD remains above threshold?

    Is it possible that indices into any arrays are going out of range?

    Your app has access to 128kB RAM and much more file-system storage.

    Peter McLennan
    Gondwana Software
    Best Answer
    0 Votes

    @Gondwana thanks for your response. 
    I already notice that I missed the emptying of buffer if value is not above the threshold. 

    I'll also keep an eye on the memory as you suggested.  

    I'll keep you posted. 

    Best Answer

    Hi @ac_devel - by crash, if you mean ended, check that no swipe or button press has accidentally ended it in the night just in case that situation is not catered for.

    Author | ch, passion for improvement.

    Best Answer
    0 Votes

    hi @Guy_ my app has already the swipe and button press disabled. 
    It turned out that I was not emptying the buffer correctly as pointend out by @Gondwana .
    Thank you both for always supporting here. 

    the app stayed on all night. However, this morning I noticed while debugging that this piece of code is acting strange: where after 30 seconds of reading, the for loop starts to not iterate anymore and the index variable remains at 0. It does not cause any crash but then I assume, random numbers are written to my buffer and not accelerometer data. 
    App: Unhandled exception: TypeError: Invalid argument type. because my in the for loop, the index value

     this.accelerometer.addEventListener("reading", () => {
    
                this.ss = scientific.std(this.accelerometer.readings.x) + scientific.std(this.accelerometer.readings.y) + scientific.std(this.accelerometer.readings.z);
                this.accelCumm.push(this.ss);
                fileTimestamp = prevTimestamp = this.accelerometer.readings.timestamp[0]
                const batchSize = this.accelerometer.readings.timestamp.length
                if (this.bufferIndex == 0) {
                    console.log("Start of  new reading!! ")
                    var diff = new Int16Array(1)
                    diff[0] = ((Date.now() - this.sessionDate) / 1000) / 60;
                    this.dataBufferView[this.bufferIndex++] = diff[0];
                    // console.log(`${diff[0]}`);
                    console.log(`${this.dataBufferView[0]}`)
                }
                for (let index = 0; index < batchSize; index++) {
                    console.log(`Index: ${index} - Buffer Index = ${this.bufferIndex}`);
                    this.dataBufferView[this.bufferIndex++] = this.accelerometer.readings.x[index]
                    this.dataBufferView[this.bufferIndex++] = this.accelerometer.readings.y[index]
                    this.dataBufferView[this.bufferIndex++] = this.accelerometer.readings.z[index]
                }
                //console.log(`${this.dataBufferView}`)
            });
            this.accelerometer.start();
    

     

    Best Answer

    Is batchSize always what you expect?

    Peter McLennan
    Gondwana Software
    Best Answer

    Yes, it stay at 50 all the time which so I assume there are is accelerometer data but the for loop seems to get stuck. It unstucks at some point but goes back and forth in between states. 
    Code wise, I really haven't changed the code as much. 

    Best Answer
    0 Votes

    Never mind guys! I missed a *2 when defining the dimension of the array, 
    Thank you for your help! 

    Best Answer

    After I got the app stabilized, I was able to gather some data. I used 

    new Accelerometer({ frequency: 20, batch: 20 }) to accumulate data every second. 
    With that said, I wanted your opinion ( @Gondwana  @Guy_ ) if this data looks reasonable to you.  Both are a round a minute of accelerometer data. Plot is smoothed a bit for visualization purposes. 
    Thanks in advance! 

    1701240490503.383.png1701198420195.554.png
    Best Answer

    Yep; that looks great.

    It can be worthwhile to check the interval between timestamps using a spreadsheet; there may be occasional anomalies.

    Note that gravity is included: very relativistic!

    Peter McLennan
    Gondwana Software
    Best Answer
    0 Votes