Saat ini saya sedang mengembangkan sistem LCD grafis untuk menampilkan suhu, aliran, tegangan, daya dan energi dalam sistem pompa panas. Penggunaan LCD grafis berarti bahwa setengah dari SRAM saya dan ~ 75% dari flash saya telah digunakan oleh penyangga layar dan string.
Saat ini saya menampilkan angka min / maks / rata-rata untuk energi Pada tengah malam ketika angka harian diatur ulang, sistem memeriksa apakah konsumsi untuk hari itu di atas atau di bawah minimum atau maksimum sebelumnya, dan menyimpan nilainya. Rata-rata dihitung dengan membagi konsumsi energi kumulatif dengan jumlah hari.
Saya ingin menampilkan rata-rata harian selama minggu dan bulan terakhir (4 minggu untuk kesederhanaan) yaitu rata-rata bergulir. Saat ini melibatkan mempertahankan array nilai untuk 28 hari terakhir dan menghitung rata-rata seluruh array untuk bulanan dan 7 hari terakhir untuk mingguan.
Awalnya saya melakukan ini menggunakan array pelampung (karena energinya dalam bentuk "12.12kWh"), tetapi ini menggunakan 28 * 4 byte = 112 byte (5,4% dari SRAM). Saya tidak keberatan hanya memiliki satu titik desimal resolusi, jadi saya mengubah menggunakan uint16_t dan mengalikan angka dengan 100. Ini berarti bahwa 12.12 direpresentasikan sebagai 1212, dan saya membaginya dengan 100 untuk keperluan tampilan.
Ukuran array sekarang turun menjadi 56 byte (jauh lebih baik!).
Tidak ada cara sepele untuk mengurangi angka menjadi uint8_t yang bisa saya lihat. Saya bisa mentolerir hilangnya tempat desimal ("12.1kWh" bukan "12.12kWh"), tetapi konsumsi sering kali lebih tinggi dari 25.5kWh (255 adalah nilai tertinggi yang diwakili oleh bilangan bulat 8-bit unsigned). Konsumsi tidak pernah di bawah 10.0kWh atau di atas 35.0kWh, jadi saya bisa mengurangi 10 dari angka yang disimpan, tetapi saya tahu bahwa suatu hari kita akan melampaui batas ini.
Saya kemudian menguji kode untuk mengemas nilai 9-bit ke dalam array. Ini memberikan kisaran 0-51.2kWh dan menggunakan total 32 byte. Namun, mengakses array seperti ini sangat lambat, terutama ketika Anda harus mengulang semua nilai untuk menghitung rata-rata.
Jadi pertanyaan saya adalah - apakah ada cara yang lebih efisien untuk menghitung rata-rata bergerak dengan tiga jendela - seumur hidup, 28 hari dan 7 hari? Efisiensi berarti lebih kecil dalam hal penggunaan SRAM, tetapi tanpa penalti kode besar. Bisakah saya menghindari menyimpan semua nilai?
sumber
Jawaban:
Jika data Anda memiliki standar deviasi yang rendah, maka salah satu metode adalah menjumlahkan nilai di atas jendela, dan kemudian terus mengurangi rata-rata dari jumlah tersebut, sambil menambahkan nilai baru.
Ini akan bekerja dengan baik jika tidak ada outlier , sehingga mengarah ke kesalahan agregat yang cenderung nol dari waktu ke waktu.
sumber
Anda dapat menggunakan metode yang berbeda, Anda mempertahankan rata-rata saat ini dan kemudian lakukan
itu bukan rolling average yang sebenarnya dan memiliki semantik yang berbeda, tetapi mungkin sesuai dengan kebutuhan Anda
untuk metode perhitungan yang lebih efisien untuk solusi 9 bit per nilai, Anda dapat menyimpan 8 bit nilai tertinggi dalam array dan memisahkan bit yang paling tidak signifikan:
untuk menetapkan nilai, Anda perlu membaginya
menghasilkan 2 menggeser sebuah AND dan sebuah OR dan sebuah tidak
untuk menghitung rata-rata, Anda dapat menggunakan berbagai trik bit untuk mempercepatnya:
Anda dapat menggunakan bitcount paralel yang efisien untuk
bitcount()
sumber
Bagaimana kalau hanya menyimpan perbedaan dari nilai sebelumnya? Dalam elektronik ada konsep serupa yang disebut konverter Delta Sigma, yang digunakan untuk konverter DA / AD. Itu bergantung pada fakta bahwa pengukuran sebelumnya cukup dekat dengan yang sekarang.
sumber
Mengapa Anda tidak bisa menambahkan nilai-nilai itu bersama begitu Anda mendapatkannya. Jadi yang saya maksud adalah Anda mendapatkan nilai untuk hari 1, Anda membaginya dengan 1 dan menyimpannya dan 1 di suatu tempat. Kemudian Anda kalikan 1 dengan nilai dan tambahkan ke nilai berikutnya dan bagi keduanya dengan 2.
Melakukan metode ini akan membuat rata-rata bergulir dengan dua atau tiga variabel seperti yang dapat saya pikirkan. Saya akan menulis beberapa kode tapi saya baru di stackexchange jadi tolong ikut saya.
sumber
Anda mungkin cukup dekat menyimpan 11 nilai daripada 28 nilai, mungkin sesuatu seperti:
Dengan kata lain, alih-alih menyimpan setiap detail setiap hari selama 27 hari terakhir, (a) menyimpan 7 atau lebih nilai informasi harian terperinci selama 7 hari terakhir, dan juga (b) menyimpan 4 atau lebih "diringkas". nilai total atau rata-rata informasi untuk masing-masing 4 minggu terakhir.
sumber