Close
0%
0%

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

Similar projects worth following
I should note now i have the sensor working calibrated and outputting 64x48 on a 328p chip.
below is the description from when i started this project:
This is an offshoot off another project for a thermal cam pointer gun, there is interest both in the amg8833 sensor and the mlx90640. the mlx90640 is interesting because out of box it has physically 32x24 thermopile cells that detect temp. however it is a beast to setup and even sparkfun recommends more than 20k ram. the libraries included with it are ram intensive too. I decided to change that. for now, the examples i include read the internal settings , change mode settings and also can read the entire sensor (still working on adding calibration data)this should be enough for those wanting to try it out that only have arduino uno, or those that want to know how it functions.https://www.youtube.com/watch?v=LLbCHUhbZf4 example here <

this project is to show how to get mlx90640 working without first needing a powerful micro controller with more than 20k of ram. the idea is to have projects be able to be tested and workin on Arduino uno, and if more performance or features are needed then similar code can be used.

also i have code that is not include with the online melexis examples, such as setting sensor in step mode. this allows ram to be read from sensor rather than needing to store it all in mcu, also reading of sensor calibration files data is done in example. however i do not use the calibration data yet. the goal is to have that data stored in mcu eeprom, and read when needed for calc.

results currently of calibrated To sensor output data to Deg C:

*project has been reading sensor data for a while, but i had to go back and run a verification and modify code in /updated folder. this code outputs data the same way as original example code by melexis, it just manages memory more efficiently.

currently the project uses about 5k of ram for 32bit arm processors, and about 720bytes ram on arduino 8bit processors. the 8 bit processors still need math to be modified because of the lower precision of the float storage. i have a 64bit float math library i'm testing on it now. i have verified the results of my code to original and it outputs similar results (on arm). i see  a lot of pow and sqrt functions in the code, and i'm not sure 100% that they are needed and think that the math can be simplified to not needing so many exponent functions and sqrt . also most of the processor time was used just waiting in a while loop until 1 frame of 2 was finished being sampled, then store data in ram, this can take from 2sec down to 1/64. the processor was only doing calc after frame data was completed. so there is a lot of room for efficiency in the process. there is some ram overhead in the frame data, of about 128bytes as each frame has specific variables to manage

with this sensor it is important that it's i2c bus runs below or at maximum 1mhz for arm, and 800khz on Arduino. unlike other sensors this one requires a lot of writes to its registers. it is important that the data not be corrupted in its internal eprom, it is up to the software checks on the Arduino to verify the writes are completed ok, as the melexis sensor will operate with its ram values in its registers until it is reset then it will pull values from flash. i recently destroyed a sensor by pushing it to 4mhz. it initialized ok, but after i reset it, it no longer worked. i assumed it overwrote it's slave address, and i spent time trying to recover it. in the future i may modify code to write to registers slowly, and only increase speed during ram reads to sensor.  again the only verifications are in the Arduino verifying the current eprom address is written too, if it is not written it will rewrite data, it won't know if you wrote somewhere else. normally this wont be an issue as long as speed is within spec, and proper resistance is used for data bus (2.2k) such as sparcfun sensor. i cant emphasize it enough that 1mz data speeds should not be done on breadboarded devices (where resistors are mounted in). the slew rate difference from the added capacitance could cause data corruption. 

Also currently the code just reads from the sensor 1 word of ram data at a time. this is not efficient and will change to reading 32 words at a time. i do know there is some caching in the arm code for the i2c data, but with my own checks reading 32words at a time is still faster than reading 1 word at a time. the addressing requirements of i2c are about 10 bytes of sending, address, and read location, and then how many bytes to send, then just clocking thru 1bit at a time the data. there is no additional addressing requirements for the next ram location as long as it is requested in a group. for the individual reads there is significant overhead. 

the current state of the project is...

Read more »

MLX90640-Datasheet-Melexis.pdf

good bedtime reading of sensor specs and how to program it and get data from it. lots of floats, complex math and other things. don't blame me if your mind goes numb

Adobe Portable Document Format - 2.80 MB - 10/16/2018 at 21:45

Preview
Download

MLX90640 driver.pdf

this doc makes more sense, regrettably they didn't include commands that change device into step mode over continuous. my example programs show you how here. https://github.com/jamesdanielv/thermal_cam_mlx90640

Adobe Portable Document Format - 900.11 kB - 10/16/2018 at 21:45

Preview
Download

getEEpromDump.zip

this file extracts eeprom calibration data from mlx90460 chip, sends it to terminal where it can be loaded into progmem of Arduino. instructions will be avail on how to do this.

Zip Archive - 383.35 kB - 09/29/2018 at 08:49

Download

  • faster sqrt (or so it seems on single point precision)

    jamesdanielv09/19/2019 at 22:41 0 comments

    i'm working on reducing solve times for sqrt and div that i can not eliminate. currently the times for sqrt of all 768 cells are less than 100000 microseconds. now i'm trying to remove division and where it still is needed reduce time down drastically. for example there are 2 division operations that take most of the time and limit performance of detailed Temp measurement of 768 cells upsampled to 3072 cells at ~0.6 seconds at latest build . still not uploaded as it requires a lot of checks for modes, features and multiple processor testing. but it will be.

    ok. back on point reducing sqrt root.

    i have discussed this here:

    https://hackaday.io/project/167533-faster-speed-how-optimize-math-and-process-tasks

    and have implemented the choice to use it in the algorithms for the mlx90640, but i was also able to eliminate one of the sqrt(sqrt(x)) loops from the sensor math. but here is the sqrt function i'm using. it has an error rate average of less than 1%, but with some numbers it could go to 3%. it is more accurate than the original float i found that uses this method. there also is a fast method that corrects for the rounding error but i need to look at that in more detail. this one here is more based on my base 10 thinking. 

    if USE_FAST_SQUARERT_METHOD will need to be set as true.

    float Q_rsqrt( float val ) //a good enough square root method.

     if not enabled in Z_memManagment then it will work as regular sqrt and use math library
    {
      #if USE_FAST_SQUARERT_METHOD == true
       float invertDivide=0.66666666666 ;//   ~1/1.5 rounded down to float precision single float
      long tmp = *(long *)&val; 
      val*=0.22474487139;//number that keeps precision detail by keeping remainder. (base 10 thinking. prob                                      //better to think in base2
        long tmp2 = *(long *)&val;   
        tmp -= 127L<<23; //* Remove IEEE bias from exponent (-2^23) */1065353216
        tmp2 -= 127L<<23; //* Remove IEEE bias from exponent (-2^23) */1065353216
        
        tmp = tmp >> 1; //* divide by 2 *
        tmp2 = tmp2 >> 1; //* divide by 2 *

       tmp +=1065353216; /* restore the IEEE bias from the exponent (+2^23) */
       tmp2 +=1065353216; /* restore the IEEE bias from the exponent (+2^23) */
       float offset=*(float *)&tmp2;    
        val= *(float *)&tmp;      
        return (val+offset)*invertDivide;
      #else 
    //we do the more accurate but slower method if it is set
      return sqrt(val);
      #endif
    }

  • syncing the line numbers and adding START,END for exporting programs

    jamesdanielv09/13/2019 at 02:41 0 comments

    these updates will come with the changes i'm releasing 9/13/19. (not released it is 9/19 and still testing )

    I'm adding some extra stuff that makes sending data to another program easier. this is the low res ascii output but the same will be done for the raw data output (raw data output will be able to be 32x24 or 64x48) . when the frame is started it sends out a 'start' and when it ends it sends out 'END" and each line is numbered. this reduces the chance of a data error corrupting more than one line from scan. and it helps keep the data in sync on another device. 

  • buffering ram data from serial (it will be compressed for terminal output)

    jamesdanielv09/12/2019 at 13:57 0 comments

    i had to use the atmega with 8k of ram just so i could test the concept of caching all the ram data in the serial cache. i can do it with compression and get the same output speed as teensy-lc. part of the issue with serial data is that it is all sent after each mem read and calculation of To. in either process the mem read is not yet the fastest. I plan to optimize the mem Calculations as well.

    this is only visual. the main interest for this project is to get it outputting to lcd.

    anyway before i compress serial output, i wanted to see how much improvement it would have at output uncompressed. 

    these are done on 16mhz arduino 1280. with 8k of ram. uncompressed buffer is 3072 bytes. i will get the data output down to 96 bytes. but before i do that work, i wanted to be sure it improved output to serial terminal.

    unbuffered

    buffered faster output to display. (my hand was cold from walking the dog outside. so fingers dont show up that good. lol. sorry.)

  • a lot faster in image mode, but it only works if you normalize it

    jamesdanielv09/12/2019 at 02:24 0 comments

    ill release code that does normalizing of image data  9/13

    image mode is a lot faster, but you need to adjust the sensitivity and figure out how the range should apply. in my case i want it to work in a similar range as the deg C. it will have some cells still out of reasonable range, but this is ok for image data.

    here is a nano, using a 328p, the same chip class as the uno running image mode

    with normalizing. at first few frames it is saturated, but it self adjusts. then i do the hand count in front of sensor.  then i give the sensor a high five pose.

    here is how to normalize the sensor automatically.

    //this is code that adjusts the sensitivity. it has 10 in between values so it does not oscillate back and forth.
    void Normalize(){
      if (autoNormalizeAdjust>50){ autoNormalizeAdjust=50;} //this is the max level
      if (autoNormalizeAdjust>255){ autoNormalizeAdjust=0;}// was backed up to far and rolled around
     
    if (autoNormalizeAdjust==0){RamstoreNormalizeImageValue=(float)1/8;}
    if (autoNormalizeAdjust==10){RamstoreNormalizeImageValue=(float)1/16;}
    if (autoNormalizeAdjust==20){RamstoreNormalizeImageValue=(float)1/32;}
    if (autoNormalizeAdjust==30){RamstoreNormalizeImageValue=(float)1/64;} 
    if (autoNormalizeAdjust==40){RamstoreNormalizeImageValue=(float)1/128;} 
    if (autoNormalizeAdjust==50){RamstoreNormalizeImageValue=(float)1/256;} 

                
    }
    uint8_t shownormilzeMode(){
    return  autoNormalizeAdjust;
    }

    to determine if image is over exposed, or needs to be normalized, i check 5 pixels.

         *                *   it samples 5 cells. the total count needs to be odd, and still it could cause

                 *           oscillation, this is why i have 10 numbers between changing sensativity.

        *                *  it does take a few seconds for sensor to find its range however only during startup

                if (pixelNumber == 32*12+16 ||pixelNumber ==0 ||pixelNumber ==31 || pixelNumber ==767 ||pixelNumber ==767-32){//we only do this on center pixel and top and bottom

    here is how it knows it is saturated. image is the float value that holds the calculated value for return from get_image routine

                #if autoNormalizeImageMode == true

                if (Analog_resolution== 16){image=image*0.00003051757*RamstoreNormalizeImageValue;}
                if (Analog_resolution== 17){image=image*0.00001525878*RamstoreNormalizeImageValue;}
                if (Analog_resolution== 18){image=image*0.00000762939*RamstoreNormalizeImageValue;}
                if (Analog_resolution== 19){image=image*0.00000381469*RamstoreNormalizeImageValue;}
                if (pixelNumber == 32*12+16 ||pixelNumber ==0 ||pixelNumber ==31 || pixelNumber ==767 ||pixelNumber ==767-32){//we only do this on center pixel and top and bottom
                if (image+25 <24){autoNormalizeAdjust++;Normalize();}
                if (image+25>26){autoNormalizeAdjust--;Normalize();}
                                            } 
                #else //this is if it is not auto and we use value in Z_MemManagement.h
                if (Analog_resolution== 16){image=image*0.00003051757*NormalizeImageValue;}
                if (Analog_resolution== 17){image=image*0.00001525878*NormalizeImageValue;}
                if (Analog_resolution== 18){image=image*0.00000762939*NormalizeImageValue;}...

    Read more »

  • i explained why i'm reducing i2c cache from 64 words to 32 words here

    jamesdanielv09/10/2019 at 13:37 0 comments

    with i2c buffer set at 32, 

    here is the current microseconds used to output 768 reads to terminal (it would be faster to spi lcd)

    but most of the time taken is from the math of the To calc function

    +145000 getting cal values

    complex math in To is 500000 math 

    so total time is 645000 +getting ram from i2c. 

    850000 microseconds 32words buffer
    770000 64 word buffer
    790000 128 word buffer //we are above the range of benefit here. 

    what i want to do is 

    1) buffer serial data so it instantly shows on screen.

    2) use extra ram for LCD display functions.

    https://hackaday.io/project/167533-faster-speed-how-optimize-math-and-process-tasks/log/168596-speed-up-i2c-faster-than-it-can-be-normally-caching-data-you-use

    i use the mlx90640 sensor to store its ram values until i need them. the ram values always are updating so they need to be requested at each frame no matter what. i can read one ram cell at a time or all of them, but here is why you would only need to read between 32-64 at a time (assuming it all is with one capture and you are getting data quickly, or the sensor is in step mode)

    each word has an average of ~20,000 microseconds for my project.  (with overhead of my code)

    in the mlx90640 sensors case, each read of i2c requires a minimum of 7bytes +(2bytes each ram)

    reading more than one byte at a time is more efficient.

    1 word is at 22% efficient

    16 words  80% efficient or 3.6 times faster than 1 byte

     32 words is 90% efficient. 4.1 times faster than 1 byte

    64 words is 94% efficient 4.3 times faster than 1 byte

    128 words is 97% efficient 4.4 times faster than 1 byte

    btw here is the efficiency based on how many words are i2c cached.

    efficiency overhead.  data received at a time.   efficiency level 
    7(bytes) overhead 0word(0bytes):::::::::0
    7(bytes) overhead 1word(2bytes):::::::::0.2222222222222222
    7(bytes) overhead 2word(4bytes):::::::::0.36363636363636365
    7(bytes) overhead 3word(6bytes):::::::::0.46153846153846156
    7(bytes) overhead 4word(8bytes):::::::::0.5333333333333333
    7(bytes) overhead 5word(10bytes):::::::::0.5882352941176471
    7(bytes) overhead 6word(12bytes):::::::::0.631578947368421
    7(bytes) overhead 7word(14bytes):::::::::0.6666666666666666
    7(bytes) overhead 8word(16bytes):::::::::0.6956521739130435
    7(bytes) overhead 9word(18bytes):::::::::0.72
    7(bytes) overhead 10word(20bytes):::::::::0.7407407407407407
    7(bytes) overhead 11word(22bytes):::::::::0.7586206896551724
    7(bytes) overhead 12word(24bytes):::::::::0.7741935483870968
    7(bytes) overhead 13word(26bytes):::::::::0.7878787878787878
    7(bytes) overhead 14word(28bytes):::::::::0.8
    7(bytes) overhead 15word(30bytes):::::::::0.8108108108108109
    7(bytes) overhead 16word(32bytes):::::::::0.8205128205128205
    7(bytes) overhead 17word(34bytes):::::::::0.8292682926829268
    7(bytes) overhead 18word(36bytes):::::::::0.8372093023255814
    7(bytes) overhead 19word(38bytes):::::::::0.8444444444444444
    7(bytes) overhead 20word(40bytes):::::::::0.851063829787234
    7(bytes) overhead 21word(42bytes):::::::::0.8571428571428571
    7(bytes) overhead 22word(44bytes):::::::::0.8627450980392157
    7(bytes) overhead 23word(46bytes):::::::::0.8679245283018868
    7(bytes) overhead 24word(48bytes):::::::::0.8727272727272727
    7(bytes) overhead 25word(50bytes):::::::::0.8771929824561403
    7(bytes) overhead 26word(52bytes):::::::::0.8813559322033898
    7(bytes) overhead 27word(54bytes):::::::::0.8852459016393442
    7(bytes) overhead 28word(56bytes):::::::::0.8888888888888888
    7(bytes) overhead 29word(58bytes):::::::::0.8923076923076924
    7(bytes) overhead 30word(60bytes):::::::::0.8955223880597015
    7(bytes) overhead 31word(62bytes):::::::::0.8985507246376812
    7(bytes) overhead 32word(64bytes):::::::::0.9014084507042254
    7(bytes) overhead 33word(66bytes):::::::::0.9041095890410958
    7(bytes) overhead 34word(68bytes):::::::::0.9066666666666666
    7(bytes) overhead 35word(70bytes):::::::::0.9090909090909091
    7(bytes)...

    Read more »

  • reduced math time down further by about 50,000 microseconds on uno

    jamesdanielv09/09/2019 at 07:11 0 comments

    shaved another 50,000 microseconds off of math time for arduino 328p chip. it does however use 4 more bytes. as it requires another float to store the fractional result

    i recently posted a a project about different optimization techniques here

    https://hackaday.io/project/167533-math-optimizations-with-specific-tasks-and-ranges

    one of my guide rules was whenever possible fractionally multiply instead of divide.

    i have broken down the math to its basics, so i can simplify and cache.

    i have determined that the first sub_calc_To (my version of the math) still eats up 500,000 microseconds time to process. 

    this is how the code looks after it has been modified to be simpler

    and here is how it looks now with a time savings of 50,000 microseconds

    there are some notes and references to the data in the comments. this is more for me.

    any way the division has been cached, and the result turned into a fraction, and applied two times.

    notice the above version divides twice. the version below divides 1 time. division is at minimum 4 times slower and in many cases a lot longer. multiplication even with floats is faster. this is because even the most basic cpus contain logic for multiplication usually just an extended length register. division is harder beast to incorporate hardware for, so it is done in software very slowly. 

    removing the division to speed things up. we still need to do it once however. now i just need to check to see if this value happens more than one time! i have noticed that the time it takes to solve increases when more heat is on the cells. i'll look into it more.....

  • trying to resolve the bottleneck on cpu processors for cycles improvements.

    jamesdanielv09/09/2019 at 02:27 0 comments

    i'm using Arduino IDE 1.8.9. my main focus is speed on the uno and nano but this also improves performance on any cpu.

    i have broken down problems, created fast math optimizations and cached ares for better performance. now it is time to look at the engine closer:

    these two areas eat all the cpu cycles on nano. higher clock rate on any processor will improve performance

      sub_calc_irData 145,000

    the first sub_calc_To calculation 500,000

    i have troubleshoot_optimize set to true, it outputs some more stuff so i can make things work faster.

    i tried moving one of the progmem tables to ram. it only reduce cycle counts by 5000 microseconds

    this is caching the 1 /2^x table in ram and the 2^x table in ram only save about 5000 microseconds over 768 reads. this is below the variation of +/- 10,000 per frame  760,000 micro seconds on arduino nano so it could just be noise. moving on to next area. the progmem tables are fast enough. they are faster than the switch(x) {..} i had used earlier. 

    below is a sample frame using ram cached values. the process time goes up and down depending on pixel information. 

    set Replace_detailed_calc_with_image_data false will allow testing of detaled To mode output of pixels.

    just for comparing here is with the image mode of sensor read

    set Replace_detailed_calc_with_image_data true will allow testing of image mode

    this tells me two things

    1) the detailed calcs in the To eat up around 300000 microseconds on uno. teense-lc runs faster 

    2) that there is some other part of the system functions eating up a lot of cycles. 

    3) that there is something outside of the math calc of the temperature that is using a lot of cpu time

    in the MLX90640_CalculateToRawPerPixel(uint16_t pixelNumber ) my own version of the routine that returns 1 pixel at a time to help save ram on processor and utilize storage on sensor, there are several areas of note for cpu cycles

    also i moves some of the math values at the start down further so i could easily make sense of caching them.

    what i did to look at areas of function where things slow down was 

    return 5;  so it exited the function and returned something in this case 5. later on after some math functions are done i return some of those results. then time how long it takes to complete the function to that point.

    my code in this function is really dirt right now. i'm trying to simplify and make redundant processes improve. so everything is being broken down

    this is on nano. faster cpu will have different results.

    running thru all of To function ~760,000 cycles +/- 10000

    i took the line that reads the ram info and had the number replaced with 1.5

    sub_calc_irData = 1.5;//RamGetStoredInLocal(pixelNumber) ; 

    this lowered the time per frame about 20,000 cycles. seems the read currently is not the culprit

    i then had it again take values from ram and turned off my i2c cache reads. it took 840,000 cycles to complete. turning off the store of i2c cache slowed it down 80,000 cycles. so the cache is helping. currently i cache 64 i2c reads. and use about 128 bytes of ram for it.

    the memory reads with cache enabled per cell is 20,000 cycles. this is acceptable and is not the main bottleneck

    i then took out the serial write time, by disabling serial output but still loading its buffer. it only takes 690,00 cycles to complete a savings of ~60,000 microseconds. caching of serial is for output to update to screen faster. so it will be redone anyways but it is not the main bottleneck

    then i did it without sending serial data except for time counts output and turned off doubleres 

    without double res and without serial send of text it is 640000 microseconds. 

    this is useful...

    Read more »

  • let my mistake make you 20$.

    jamesdanielv09/08/2019 at 11:26 0 comments

    I had the pleasure of someone who claims to be from melexis management asking me to verify what i though was an error in the documentation of the melexis 90640 documentation. this person was very professional, and i think they just registered on github so that they could respond to me. lol. 

    If all you want is the 20$ read last paragraph. i'll pay it in paypal to whoever can confirm errors. not everyone just the first person. I don't have a tree growing cash in my yard, so 20$ total. thats it. thats all.

    In all it ended up I could not verify what i said about the documented errors. I could not find them again, and it is possible that It could have been me. read thru the document, and i think you will understand. there is a lot going on, things are very similar, and so on.

    anyone who has read any of my blogs, or seen my videos or read my project logs, know that when i have made a mistake, i like to share it, because we all learn from them. even if i'm a little embarrassed. no process or design can ever be perfect, and looking at things from the standpoint that things can always be made better and or improved within reason of resources and ability, it opens one self up to  feedback for corrections. even though this sensor blog with over 27 logs has only received about 1.8k views. 

    I am always happy to improve processes, and i felt it was fair of them to ask me to provide corrections, since i said in forum space that i though there were errors. I spent what i thought was a reasonable time going thru the documentation again.

    here is the documentation i referenced: 

    https://cdn.hackaday.io/files/1614996909573216/MLX90640%20driver.pdf

     It takes a long time to go thru the documentation. it is easy to verify different documents side by side, but the issues i thought were in section 11, and section 11.2.2.2 that showed an example of sensor setup. 

    I have apologized to the manager of the melexis company, and told them if i did find errors i would let them know directly. In my comments i also offered 20$ of my own money to anyone that is the first to find errors. i'll pay thru paypal.

    if anyone wants to read the comments they are here:

    https://github.com/sparkfun/SparkFun_MLX90640_Arduino_Example/issues/7

    If it no longer is avail i have a pdf of comments i'll upload. i was mainly trying to let sparkfun know that i have a version of code that works on the 328

  • some math changes and i2c buffering. better performance

    jamesdanielv09/07/2019 at 19:06 0 comments

    here is the output of the data from increased performance. the version currently uploaded and in /updates folder is https://github.com/jamesdanielv/thermal_cam_mlx90640

    it includes the start of math optimizations and a i2c cache. the i2c cache has less of a boost than i thought it would so i'm looking into it. if you were to read thru the MLX90640_CalculateToRawPerPixel section in the MLX90640_API.cpp it would look messy right now. i'm breaking down the math problems to the basic blocks, and looking for ways to cache areas and solve others more quickly.

    also from the better performance there seems to also be noise introduced. this is normally filtered as part of the gain and voltage calc, so i suspect that i need to sync the frame data w the ram info. also it is about time i have the device run in step mode again. this will probably solve it as well. so this version has more noise, but it will be cleaned up. adding a capacitor across leads going to sensor should help as well.

    below. there is a built in delay between frames, but look at how much faster data is sent to display. this is on teensy-lc that is lacking special math ability. optimizations also have a 2x performance boost on arduino. I'm still working on improving the serial output to terminal. teensy-lc does not use serial data.

    before i started focusing on optimizations:

    after start of optimizations:

  • improvements to serial output of data

    jamesdanielv09/07/2019 at 05:50 0 comments

    one of the biggest delays to getting terminal information to output is that it needs to work at separate times from the i2c bus and spi bus. spi bus is fast enough that this should not be an issue with outputting to lcd display. I want the terminal data to instantly show in terminal, so this may involve a ram buffer for the data to almost instantly show to terminal when i2c bus is idle.

    there are two ways i may do this; 1 safely burst the i2c bus. this can only be done on read operations. so some checks need to be built in. do not do this with current setup. the library has been throttle limited to a max of 1mhz. but it might be able to burst to 2mhz in special situations. currently it is not a good idea and will require a lot of checks to make sure it works safely, but some status checks and verifying it is only this speed at read operations are needed. there is also the possibility of tuning the i2c frequency to optimum performance. when data can normally not be sent or received quickly enough the slave device can slow down the master device. this is if everything is in sync. at high clock rates this is unknown,

    also there is a compressed buffer cache. normally reading output to terminal is low detail, the asci char generation is only 6 different char :

    i have a way of fitting this data 3 bytes per 1 byte of cache. this is only for output to terminal. data is much faster internally. it also only uses 256 bytes of cache. it can be better because some number information is not processed for byte 1 and byte3. byte 2 will most likely have information similar to 1 +3

    here is how i'll do it most likely

    3bits is first byte value temp range

    111|00|000

    1st data

    0 <26
    1 >25 & <30
    2 >29 & <31
    3 >30 & <33
    4 >32 & <36
    5 >35

    6&7 not used currently

    000|00|111

    3rd data

    0 <26 

    1 >25 & <30 

    2 >29 & <31 

    3 >30 & <33 

    4 >32 & <36 

    5 >35

    6&7 not used currently

    000|11|000

    2nd data

    00 lowest value

    01 1/2 of 1st and 1/2 of 3rd value

    10 1/4 of 3rd value

    11 highest value

    I'm just looking at options to speed up serial terminal output. this may not even be needed after caching of i2c data. i2c is 1/8 the speed of when it will be cached...

View all 34 project logs

  • 1
    here are some instructions. a faq page will be added to github once i look thru some of the questions

    download code here

    https://github.com/jamesdanielv/thermal_cam_mlx90640

    it should contain a file called MLX906040_example32ataTime.zip

    the code inside should take one row of data and output it to terminal. if this works you have your sensor working ok.

    then look at fullsensorreadToterminal.zip it should output entire sensor to asci art. 

    these are not calibrated results, just tests to verify it is working, and the orientation. after these tests are run and it seems to be working, you will want to run sketch in getEEpromDump.zip

    this will allow extraction of calibration data from sensor .  cut and paste this data into a text document somewhere.

    now we want to run calibrated program.  go to /updates folder and load the sketch Example1_BasicReadings.ino

    go to tab that loads factoryCalData.h and replace table values with calibration data from sensor that you go from cut and paste of getEEpromDump.zip

    load sketch and it should output ascii graphics map of camera into terminal.

    if you want to see raw values or have values at normal resolution 

    change :

    pixelmodeTrueTestModeFalse true to false. it will not do graphics and it will output raw data
    define DoubleResolution true to false. this will output data at 32x24 resolution.

    if you want to design code that reads the sensor custom

    these are the functions to use

    Readmlx90640To( ); example float temp=Readmlx90640To( x+y*32);

    DoubleResolutionValue(x,y);example: float temp=DoubleResolutionValue(x,y);

    DoubleResoluiton has special caching techniques for data. it uses 256 more bytes, so without it the code is about 750 bytes of ram at compile time.

    performance overall will improve as i figure out ways to optimize the math, and cache the data for the results, and make better use of the i2c bandwidth.

    for example when i first wrote the double resolution function it needed to read memory 5 times, and required several reads from the sensor. now it only requires 1 read per cell location and works about 5 times faster than without the caching. 

    if anything needs to be clarified further please let me know. i want this to be as clear and simple as possible. also code is a mess currently because it retains compatibility with original code so i can test features and functions. for example if the NEW_METHOD is set to false, it will again use about 20k of ram.

    Z_MemManagment.h handles the methods of how the memory is managed and process techniques

    factoryCalData.h stores values in a table copied from memory of sensor

    ZZZ_doubleResolution.h has the function that doubles resolution and has caching for speed as reading memory from cells is the slowest part of the process, next to the math calculations. the irony is the better arm processors that use the old method of memory management spend all that extra processing horsepower in a while loop waiting for capture of sensor to be complete. 

View all instructions

Enjoy this project?

Share

Discussions

jamesdanielv wrote 01/18/2019 at 16:29 point

just wanted to post that i'm in the middle of updating my upsample drivers so they are separate from the other code. this allows upsampling outside of my project, and makes code a lot simpler to understand. for example, you would just set size of area to update, and then input at lower resolution data into buffer. it will do all the optimizations at greater resolution and use very little memory.

after the upsample code rewrite and documenting it as a separate article, i can then again focus on these sensors. 

  Are you sure? yes | no

jamesdanielv wrote 12/04/2018 at 01:23 point

there are issues in how the calculations are done currently. they require 20k or more ram. as for non float in library you will need some floats for accuracy at least for comparing voltage and offsets, you can however choose to repurpose needed floats, as long as you do several setup routines within a function (vdd, gain, Ta, ect) .. i have broken down some routines and how they process in comments log. the files need to be zipped for now. but i will try to make an unzipped version available that is updated less frequently.

 they include all libraries to run code, and in some instances they are different than standard drivers for performance, for example  i have other code for amg8833 and lcd adafruit library can only get 1/10 performance because i can not use unrolling loops and combining tasks during spi processing is not possible with the way drivers are written, or the way i have optimized them. 

Also my drivers for melexis will be different than standard driver. possibly in the end an entire rewrite with different documentation. melexis drivers for example don't include functions to switch sensor into a frame and store mode, they just assume continuous operation at speed the i2c bus can send the data. this is not needed. 

if you can wait a week or two, ill have drivers completed enough at least for imaging that will reduce write calls to ram by about 20000%, yes about 2000 times less writes to ram. everything you do with melexis driver currently thrashes ram, even values that are suppose to be static. currently you could fix the float point issues but the over writes to ram far outweigh the float calculations. again the way the drivers are written seems unnecessarily evil.

  Are you sure? yes | no

Yevhenii wrote 11/15/2018 at 14:03 point

Please, do not place zip files to git :) unpacked sources :)

I also have 90640, planning to make fixed point library to speedup calculations (FYI, but it is almost empty now https://gitlab.com/riconec/mlx90640_fp_libc)

  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