Close
0%
0%

interpolation low ram method to double resolution

this is a crude but functional method of resolution doubling, when reading of data is slow from sensor, and ram is not really available.

Public Chat
Similar projects worth following
i have several methods i have programmed for resolution doubling. most of them require a large frame buffer, but this method (that works and is currently part of one of my other projects) uses a lot less memory. the buffer just needs to be the size of two lines of data. in my case 32floats per line that use 4 bytes each and some overhead for float calculations. the method of res doubling can even be used on the nano processor, or any 328, or 168. this is just to prove a point that it frees up ram. ram is still a precious resource, and the less of it that is used, the less chance for data error, more efficient a processor runs in speed and energy usage, and so on.the image i have set for the main page of this project is a nano running a mlx90640 sensor calibrated and doubling resolution output. it does it using 1k of ram total. go here https://hackaday.io/project/161

this is not my best method of doubling resolution, however it is one i implemented on the mlx90640 project, mainly to make the code of the project more interesting than the normal code. 

Anyway the data from that project is kept stored on the sensor ram, and the i2c data bus is a lot slower, requires a lot of overhead, and the math is complex. for purposes of better performance i wanted to cache the slow access memory without storing it all in the processor

I wanted a method that ensured data would only be read once from the slow ram, and have the end result only processed once to calibration values from math.

the code below caches data in such a way that it reduces requests from slow memory, and slow math calculations to 1 time. it does it by caching two lines of data, a pre line and a current line, it interpolates the current data with the previous line data, it also predicts when to load the cache again for the next line, so you could start x,y at any value and as long as reads are at least sequential for 10 or more reads there is an improvement of performance

here is the routine below. I have shared it in the hopes that other people find it useful.

you will need to modify the mem reads to either a function call like mine, or a array reference to ram.

here is an update that improves performance as of 9/8/19

//ZZZ_ heading just keeps this showing towards the right of tabs
#define nonfloatReturnNumbers true//if this is false it is more accurate. reduces buffer and speeds up output to serial display
#define center_data_filter true //this is like a gain adjust. if less than half of data in range it adds more, if more than half it lowers
//this is a small process that does not use much memory and increases resolution of data in
// however it requires fast ram reads of data in order to not store its own table
//it also requires modification of main structure so it can read data
//it just interpolates in between data by averaging creating a new pixel
//this is not my zoom method. this is just a quick method. some data resolution
// is lost on the edges. it is effectively a resdouble-1
// do not remove commends from this line and above. written james villeneuve
#include "MLX90640_API.h" //we need this so we can access the memory
#define XresolutionOriginal 32 //this is original resolution
#define YresolutionOriginal 24 //this is original resolution
//we use below as cache. we only update information 1/4 of time
//we need a line cache of 32 values to improve performance
//float DataCache[XresolutionOriginal];//this uses a small amount of cache
#if center_data_filter == true
uint16_t add_this_much;
#endif
uint8_t bufferlineNumber =0;//this is a reference to y lines. x line is cached. and previous x line cached. 

#if nonfloatReturnNumbers != true
  float ReturnCache=0;//this is to make returns more readable. compiler hopefully will remove as a redundancy
  float prebufferCache[32];//we use this to reduce mem reads to 1 time.
  float CurrentbufferCache[32];//we use this to reduce mem reads to 1 time.
float DoubleResolutionValue(uint8_t XatNewresolution, uint8_t YatNewresolution) {
#endif

#if nonfloatReturnNumbers == true
  uint8_t ReturnCache=0;//this is to make returns more readable. compiler hopefully will remove as a redundancy
  uint8_t prebufferCache[32];//we use this to reduce mem reads to 1 time.
  uint8_t CurrentbufferCache[32];//we use this to reduce mem reads to 1 time.
uint8_t DoubleResolutionValue(uint8_t XatNewresolution, uint8_t YatNewresolution) {
#endif

  //this routine uses data from values it can get from sensor reads to double resolution of data without using much memory
  //we just need to know the ram we are reading, the x and y resolution, and pixel number
  //this is an over simplified setup that interpolates every other value in x and y
  //**** we need mem value to pull data from*****************************************************
  //****   ...

Read more »

h - 6.02 kB - 09/08/2019 at 14:52

Download

ZZZ_doubleResolution.h

this is code that can double resolution. you will want to change area that gets numbers from main memory. the output of a higher resolution cell is float temp=DoubleResolutionValue(x, y) and result is stored in temp. it is cached and manages hit and miss as well

h - 4.19 kB - 09/03/2019 at 23:20

Download

  • made it even faster. has option for not float version.

    jamesdanielv09/08/2019 at 15:04 0 comments

    again this is not my best method of interpolation. however it is the one i am using that has a good caching algorithm for pulling data from slow ram or functions, upsampling values and returning results all with only needing 1 call per sample to ram or function. this method drastically reduces math overhead.

    also i have a version i just included here

    https://cdn.hackaday.io/files/1674667164865344/ZZZ_doubleResolution(Nonfloat).h

    it does interpolation using unsigned integers. this allows for faster >> in place of division or fractional multiplication. to keep information resolution of values i add 1/2 resolution total before then doing an equivalent of divide. this allows for information to carry into the interpolation result.

    sub sample between x1 and x2

    (x1+x2+1)>>1 this divides by two, but if both of the values are odd numbers, the information is included in output result because of the addition. otherwise information would be lost. so this method of adding a 1 is better for interpolation. if more detail is needed then the information from ram, can be multiplied by 8 before conversion to an unit16_t. 

    the memory is read from a function called Readmlx90640To(){} it can be modified to whatever your project uses, or you can make a function named the same and then leave it as written here.

    for example my Readmlx90640To function is this:

    return  MLX90640_CalculateToRawPerPixel(value);
    }

    it is a time consuming function that returns calibrated data from a thermopile sensor. each result takes a long time to process. so we only want to get data 1 time only. 

View project log

Enjoy this project?

Share

Discussions

shelleyhale wrote 04/24/2021 at 04:22 point

Thanks for sharing your mlx90640 project and I like the methods you used in creating this project. As a new learner, this is so useful for me! Sometimes, I follow online solutions and reviews. Recently I have found this best kitchen chimney in India and I like their features and operational various terms for purchasing electrical appliances especially for the Indian kitchen. Thanks for sharing this post.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates