-
mlx90640 sensor now working all 768 sensors in example program
09/26/2018 at 07:10 • 0 commentssome more work on mlx90640 sensor. i have it working using only 64 bytes of buffer, the same level as amg8833. the mlx90640 sensor has built in ram so i read just 32 words at a time, include a 10ms delay after serial data sends to make sure serial buffer is clear, and i2c data line works error free. (this can be tweeked later so that no serial data is sent while i2c is working, i plan to next get this data to be displayed thru the sp77xx display i have in spi mode, and then submit it as example code. this still does not have calibration data and just assumes the similar offsets from the first row, this seems about correct for now. not yet code ready for accurate sensor temps, but can be example code showing people how to use the sensor
mlx90640 sensor full read example made for uno controller. uses all 768 sensors to display 5 levels of data
https://github.com/jamesdanielv/thermal_cam_mlx90640
-
first example program on Arduino for working mlx90640
09/26/2018 at 03:40 • 0 commentshttps://github.com/jamesdanielv/thermal_cam_mlx90640
files can be found here. allows Arduino uno to run mlx90640 sensor. this is just a first step demo program that reads the first 16 pixels of the first page of data. it is just to show the sensor works. at start up it calibrates to zero out heat level, so anything it senses after start up will show on terminal. just the first row of data updates
-
first version with 128x128 for amg8833 sensor
09/26/2018 at 01:11 • 0 commentshttps://github.com/jamesdanielv/thermalcam/tree/updates-(possibly-unstable)
this version has amg8833 sensor working to 128x128! resolution upsampled. it is set by default in build dated 9-25-2018. it has some issues with blockiness again at this resolution but it can be solved easily within a few days. the 128x128 code is not optimized at all, in fact buffering is turned off currently for testing. to speed code up set setting of #define optimize 2 will give it about 5fps currently I have optimize mode set to 0 (non buffered write entire screen) which is the mode i have it in currently for troubleshooting blockiness issues. it currently is set to do about 2fps. however it does show a lot more detail than even 64x64, fingers are visible as well as shapes of objects.
coding changes can make it 50-100% faster, and the fact that i can buffer spi will make it about twice as fast as this is the first set of code to take more processing time than it does time to show the pixels. this means that buffering spi and having it write to display while it is processing next pixels will make sense now. the amg8833 detail is only somewhat accurate to 10fps, so 10fps seems a good stopping point for tweaking it at 128x128!
i coded in the ability for spi buffering into 64x64, i will apply it to 128x128, and. i feel the only benefit for my purposes is the 128x128 code, but will add it for those that have big ideas, such as advanced filtering or overlay with a regular camera. these features which i will not work on would make the processing time greater than the pixel processing, which means buffering will speed it up.
as for the mlx90640 sensor, i will release demo code for testing sensor within 48hrs, prob by next week i will have it working. eventually to a point that it will work upsampled to similar resolution, with enhancements making it detect detail to 64x48, and upsample it to at least 128x96.
-
starting to play around with mlx90640 sensor, but most work on amg8833
09/21/2018 at 02:57 • 1 commentgot the mlx90640 communication with Arduino. still don't have the temp outputs. this sensor is a thermopile sensor where as the amg8833 is a barometer type. the amg8833 sensor is more friendly to program for. for example the only code out there in the wild for mlx90640 currently works on pi, not Arduino or arm variants. my focus currently is to get the aruino and the amg8833 to work up to 128x128, then ill switch gears and put some effort into the mlx90640. code will need to be separate, because although both sensors use ic2 bus, the methods of use differer greatly. also mlx90640 can have up to 4 bad sensors in array and still be considered to be in spec. so interpolation between bad sensors will be needed at the get go, as well as uploading calibration data for each thermopile cell.
ill post my test code in a few days. i would like it to at least output temperature data, even if it is not calibrated.
currently my code for sensor uses ~400 bytes and fits into less than 6k of flash. it is only to test sensor.
-
resolved blockiness issues for up to 32x32. 64x64 next
09/17/2018 at 08:59 • 0 commentshttps://github.com/jamesdanielv/thermalcam/tree/updates-(possibly-unstable)
resolved errors in calc of pixel position and color for up to 64x64. 64x64 still has rounding errors for color that generate blockiness. think resolving it will require monitoring and adding back info lost from rounding errors. if this is the only issue with the 64x64 blockiness then it will be fixed soon.
-
now uses less than 23k flash.
09/12/2018 at 03:55 • 0 commentsupdate to code.
64x64 mode now uses 22066bytes in flash, uses about 1050 bytes ram max.
32x32 mode uses 21048 bytes flash, and uses about 954 bytes ram.
code is still being updated.
https://github.com/jamesdanielv/thermalcam/tree/updates-(possibly-unstable)
-
efficiency improvement with up to 64 pixel writes.
09/12/2018 at 03:16 • 0 commentsefficiency improvement with up to 64 pixel writes. the issue with pixel performance beyond 16 at a time was most likely do from loading and unloading of stack for function. the goal of the new commands was to reduce command overhead. this is accomplished by slightly changing how the pixel command functions.
//this is start, required to init display mode, x y address and size of display area
fillRectFast64colorStart(int16_t x, int16_t y, int16_t w, int16_t h,
uint16_t color0, uint16_t color1, uint16_t color2, uint16_t color3,
uint16_t color4, uint16_t color5, uint16_t color6, uint16_t color7)//this command below sends 8 colors or 16 bytes to stack at a time
fillRectFast64color(uint16_t color0, uint16_t color1, uint16_t color3, uint16_t color4,
uint16_t color5, uint16_t color6, uint16_t color7, uint16_t color8),tft.fillRectFast64colorEnd(); //finishes end of command and releases lcd to allow other devices
so a single 64 color write would look something like this
fillRectFast64colorStart(displayPixelWidth *j,displayPixelHeight* i, displayPixelWidth, displayPixelHeight,color, color, color, color,color, color, color, color); //first
fillRectFast64color(color, color, color, color,color, color, color, color);
fillRectFast64color(color, color, color, color,color, color, color, color);
fillRectFast64color(color, color, color, color,color, color, color, color);
fillRectFast64color(color, color, color, color,color, color, color, color);
fillRectFast64color(color, color, color, color,color, color, color, color);
fillRectFast64color(color, color, color, color,color, color, color, color);
fillRectFast64color(color, color, color, color,color, color, color, color);//last
fillRectFast64colorEnd(); //we close the lcd write and free up data lines for other communcations.
-
added spi buffer. testing it, eventually it will unload data while processing
09/11/2018 at 15:47 • 0 commentshttps://github.com/jamesdanielv/thermalcam/tree/updates-(possibly-unstable)
now have spi buffer, and 64x64 working in small program space .
if spi buffer it uses more bytes of ram but still fits comfortably on uno
starting work on 128x128 interpolated mode,
also still trying to resolve some of the blocking effects. although now they are less than they were
spi mode is currently slower because all it does is load it and then before next lcd command waits until all data unloaded. there is code i have made that unloads one byte at a time, trying to figure out best way to have it load SPDR in intervals, so most of spi is processed while non pixel placement code is running. in theory it should make it all run faster because most of the pixel write time is waiting for spi to be ready.
-
memory buffer for 64x64 mode has shrunk from 2560 to 132 bytes.
09/07/2018 at 23:59 • 0 commentsupdated 64x64 sub sample to require less memory. shrinking code today, it is just a little to big for the Arduino with 64x64, it is an easy fix as it samples faster than original code. memory usage total is about 1k or less for sketch but it is about 4k over size for arduino flash. still also working on color filtering. think it is not as good as it can be, it improved with enhancement enabled, but goal is to eliminate blockiness entirely. think i have an error in the nearest neighbor pixel in 64 sub sampling, i currently don't compare to sub sampled pixels, i process part of pixel that would average in sub sample.
to reduce mem i will place progmem color data in a loop (slows down a little, but saves about 2k), then
formulate directional changes, rather than have raw code unrolled, saves another 2-3k.
will upload changes in a within a day or so.
so primarily i will focus on fitting in Arduino as long as performance tweaks are minimally changed
secondary after code space shrink, further reduce so at least 4k spare
thirdly (is that a word?) will work on improving color filtering, however it seems ok with enhancement mode, but this could be from increased noise, although it is suppressed from averaging.
-
submitted first set of request changes to adafruit.com st77xx library
08/23/2018 at 19:16 • 1 commentjust suggested update to adafruit libray for st77xx display.
this is for 4 writes at a time feature. 16x writes feature will be submitted later on.
in order to do so i added in safety checks to ensure spi data had competed for different spi data rates. i ensured that most if not all the time the loop back function of while(!(SPSR & (1<<SPIF) )); or equivalent would jus pass thru when spi is at full speed, if spi speed is slower it will wait and loop back for spi data to complete. it reduces performance by 5%, but makes it easier for new users to manage, and it reduces troubleshooting issues. it still is about 4x-8x faster than normal, as spi data is burst twice as fast as normal, and pixel location and window size overhead is reduced by 4x.
here my submission to them below:
would you add a method that allows for up to 4 writes at a time together? #52
Open jamesdanielv opened this issue 6 minutes ago · 0 comments
it is unrolled a bit so some unconventional steps are used to make it more manageable, such as '#define' used to create complex commands. this code takes a large rectangle area, and subdivides it into 4 areas that can have different color values. while(!(SPSR & (1<<SPIF) )) is used as a safety check but should normally run thru without loop back or jmp performance tax, unless spi is at a lower speed. within this function spi is burst at about 80-100% increase speed from normal at max spi data rate, and overhead of pixel location and window size is reduced by 4x!
void Adafruit_ST77xx::fillRectFast4colors(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color0,uint16_t color1,uint16_t color2,uint16_t color3) { //this is needed for text but not fills with solid color! // rudimentary clipping (drawChar w/big text requires this) // if((x >= _width) || (y >= _height)) return; // if((x + w - 1) >= _width) w = _width - x; // if((y + h - 1) >= _height) h = _height - y;
setAddrWindow(x, y, x+w-1, y+h-1);
SPI_BEGIN_TRANSACTION(); //created complex commands in #define so code can be a lot cleaner //this is a complex command that complexspi= hi[0] value #define complexspi SPCRbackup = SPCR; SPCR = mySPCR; SPDR //this is small delay #define shortSpiDelay asm("nop\n\t");// asm("nop\n\t");// asm("nop\n\t"); //last comment out ';' not needed here, but can be added in commands later #define longSpiDelay asm("nop\n\t"); asm("nop\n\t");asm("nop\n\t"); asm("nop\n\t"); asm("nop\n\t"); asm("nop\n\t"); asm("nop\n\t"); asm("nop\n\t"); asm("nop\n\t"); asm("nop\n\t"); asm("nop\n\t");// asm("nop\n\t");// asm("nop\n\t");// asm("nop\n\t");// asm("nop\n\t")
digitalWriteFast(TFT_DC,HIGH);// old DC_HIGH(); digitalWriteFast(TFT_CS,LOW);// old CS_LOW();
// y=h; uint16_t countx;//we use these to understand what to draw! uint16_t county;
SPCR = SPCRbackup; //we place at top for next loop iteration county=h/2;
while (county !=0 ){countx=w/2;while (countx !=0) {while(!(SPSR & (1<<SPIF) ));;complexspi = highByte(color0);longSpiDelay;while(!(SPSR & (1<<SPIF) )); complexspi =lowByte(color0) ;shortSpiDelay;countx--;} while(!(SPSR & (1<<SPIF) ));
countx=w/2; while (countx !=0) {while(!(SPSR & (1<<SPIF) ));;complexspi =highByte(color1);longSpiDelay;while(!(SPSR & (1<<SPIF) )); complexspi=lowByte(color1);shortSpiDelay;countx--;} while(!(SPSR & (1<<SPIF) ));
county--; }//end of first half of rectange [0][1] drawn! county=h/2; while (county !=0){countx=w/2;while (countx !=0) {while(!(SPSR & (1<<SPIF) ));;complexspi = highByte(color2);longSpiDelay;while(!(SPSR & (1<<SPIF) )); complexspi =lowByte(color2);shortSpiDelay;countx--;} while(!(SPSR & (1<<SPIF) ));
countx=w/2;while (countx !=0) {while(!(SPSR & (1<<SPIF) ));;complexspi = highByte(color3);longSpiDelay;while(!(SPSR & (1<<SPIF) )); complexspi =lowByte(color3);shortSpiDelay; countx--;} county--; }//end of first half of rectange [2][3] drawn! while(!(SPSR & (1<<SPIF) )); digitalWriteFast(TFT_DC,HIGH);// old DC_HIGH(); digitalWriteFast(TFT_CS,HIGH);//old CS_HIGH(); SPI_END_TRANSACTION(); }