Close

now works with about 5k of ram usage on teensy, *sort of works again uno 790 bytes ram

A project log for mlx90640 sensor works w 800 bytes

Everywhere i read people are excited to get mlx90640 working. here are examples using arduino w 800bytes ram, and 1k with calibrated DEG C

jamesdanielvjamesdanielv 08/21/2019 at 18:540 Comments

i've rewritten the memory management of the code for the mlx90640, so it uses about 5k of ram instead of 20k for teensy 3.1/3.2; for atmega and UNO it uses 790 bytes. functions don't use much ram.

https://github.com/jamesdanielv/thermal_cam_mlx90640/tree/master/Updates

look for code in updates folder. it should compile for teensy. if you want to compare to old method 

change NEW_METHOD false in Z_MemManagment.h . i've upped the teensy i2c speed to 1mhz. (don't use above  1mhz or you could accidentally reprogram device.) so new method reads faster. it currently is slower to read at same i2c clock as normal, however this will be fixed soon. many of the ram calls are in sequential order, and a cache will speed up access by about 8times because of the overhead of individual requests over i2c bus. 

as for the verified code working on the UNO, there is still some issues with the double floats used for original code for the 32 bit arm processor. with some simple tricks it will work on arduino calibrated, and with caching it should be almost as fast as arm. 

another note to the fact that it can work on uno, is since i utilize storage on the sensor, data does not need to be moved around function to function, and stored and read from multiple times. this greatly reduces amount of work on the processor. also the code spent a lot of time waiting for large data transfes, and waited for data to be collected by sensor twice, so most of its time it was idle.

the new method requires less waiting, and less ram. a few optimizations are going to be added to deal with complex math

first is a simple replacement for pow, it is ok in this code case because base exponents are 2 and 3 and 4 only. so the time it takes to process is minimal and this configuration is efficient enough

float SimplePow(float base, uint8_t exponent)
{//we create or own low memory multiplier

 float tempbase=base;if (exponent >0){for (uint8_t i=1;i< exponent;i++){////we have base number,we start at 1 not 0, because 1 is already done
  tempbase=tempbase*base;}}else{tempbase=1;}//we multiply unless exponent is 0 then result is 1
 return tempbase;//we return result
}

as for sqrt functions i'm switching over to the fast method:

float Q_rsqrt( float number ) //a good enough square root method.
{//https://en.wikipedia.org/wiki/Fast_inverse_square_root
  long i;float x2, y;const float threehalfs = 1.5F;
  x2 = number * 0.5F;
  y  = number;
  i  = * ( long * ) &y;                       // evil floating point bit level hacking
  i  = 0x5f3759df - ( i >> 1 );               // what the fuck? 
  y  = * ( float * ) &i;
  y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
//  y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed
  return y;
}

as for pow for areas that use 2^1 to 2^16 i', switching to a table 

these changes will be implemented once i fix the double float issues of the UNO.

UNO range is 4bytes of storage for floats, teensy 3.2 is 8bytes. the range can be compensated for, or i will create a library to process 64 bit floats. more to come!

Discussions