Okay so I went and did some memory analysis and saw that I was using 98% of my SRAM. After some optimisation I managed to knock this down a little, however it wasn’t enough.
I did a little searching into storing the static bitmap data into the flash memory and came across a nice library that provides some convenient data structures to do just that.
http://arduiniana.org/libraries/flash/
With having done this my SRAM usage is down to ~30% however, strangely simply declaring my table at the start of my code breaks the strip. I have a function to test the most fundamental functionality - setting the colours then turning the pixels on. This only works when the declaration of the table is commented out.
I’d really like to work with this flash memory for storing my image since I don’t have the means to get a better chip at the moment. My last resort here is perhaps to implement an algorithm to convert my RGB to 8 bit colour or indexed colour. I would prefer to keep my full colour space though.
Any pointers?
I’ll post my full code since I seem to be obscuring things with snippets here in there. It’s just quite long that’s all.
#include <Adafruit_NeoPixel.h>
#include <avr/interrupt.h>
#include <Flash.h>
#define PIN 6
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(32, PIN, NEO_GRB + NEO_KHZ800);
uint32_t r = strip.Color(255, 0, 0);
uint32_t b = strip.Color(0, 0, 255);
uint32_t orange = strip.Color(255, 100, 0);
uint32_t yellow = strip.Color(255, 255, 0);
uint32_t green = strip.Color(0, 255, 0);
uint32_t purple = strip.Color(255, 0, 255);
uint32_t pink = strip.Color(105, 0, 255);
//uint32_t colours[] = {r, yellow, green, b, purple, pink};
const int columnSize = 24;
const int rowSize = 32;
unsigned long startTime;
volatile int revs;
int prevRevs = 0;
int revsThisLoop;
double timeIndices[columnSize];
FLASH_TABLE(unsigned int, image, 24, /*Table Width*/
{r, r, r, r, r, r, r, r, r, r, r, r, r, r, r, r},
{r, r, r, r, r, r, r, r, r, r, r, r, r, r, r, r},
{r, r, r, r, r, r, r, r, r, r, r, r, r, r, r, r},
{b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b},
{b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b},
{b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b},
{b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b},
{r, r, r, r, r, r, b, b, b, b, r, r, r, r, r, r},
{r, r, r, r, r, r, b, b, b, b, r, r, r, r, r, r},
{r, r, r, r, r, r, b, b, b, b, r, r, r, r, r, r},
{r, r, r, r, r, r, b, b, b, b, r, r, r, r, r, r},
{r, r, r, r, r, r, b, b, b, b, r, r, r, r, r, r},
{r, r, r, r, r, r, b, b, b, b, r, r, r, r, r, r},
{r, r, r, r, r, r, b, b, b, b, r, r, r, r, r, r},
{r, r, r, r, r, r, b, b, b, b, r, r, r, r, r, r},
{r, r, r, r, r, r, b, b, b, b, r, r, r, r, r, r},
{r, r, r, r, r, r, b, b, b, b, r, r, r, r, r, r},
{r, r, r, r, r, r, b, b, b, b, r, r, r, r, r, r},
{r, r, r, r, r, r, b, b, b, b, r, r, r, r, r, r},
{r, r, r, r, r, r, b, b, b, b, r, r, r, r, r, r},
{r, r, r, r, r, r, b, b, b, b, r, r, r, r, r, r},
{r, r, r, r, r, r, b, b, b, b, r, r, r, r, r, r},
{r, r, r, r, r, r, b, b, b, b, r, r, r, r, r, r},
{r, r, b, b, b, b, b, b, b, b, r, r, r, r, r, r},
{r, r, b, b, b, b, b, b, b, b, r, r, r, r, r, r},
{r, r, b, b, b, b, b, b, b, b, r, r, r, r, r, r},
{r, r, b, b, b, b, b, b, b, b, r, r, r, r, r, r},
{r, r, r, r, r, r, r, r, r, r, r, r, r, r, r, r},
{r, r, r, r, r, r, r, r, r, r, r, r, r, r, r, r} );
//unsigned int image[rowSize][columnSize];
int i, j;
boolean updated;
//Interrupt Service Routine called when Hall Effect Sensor goes high
//Counts number of revolutions
void revCount()
{
revs++;
}
void setup()
{
Serial.begin(9600);
strip.begin();
//Initialize all pixels to 'off'
strip.show();
//Initialize the hall effect sensor pin as an input:
//pinMode(0, INPUT);
//Trigger interrupt routine 'revCount' on rising edge of hall reading
//attachInterrupt(0, revCount, FALLING);
//revs = 0;
startTime = 0;
updated = false;
init_indices();
//drawImage();
}
void init_indices()
{
for (i = 0; i < columnSize; i++)
timeIndices[i] = 0;
}
//Translates an array of RGB pixel values to 'screen buffer'
void mapToScreen(_FLASH_TABLE<unsigned int> &bitmap)
{
for(i = 0; i < columnSize; i++){
//Introduce delay corresponding to column i
delayMicroseconds(500);
for(j = 0; j < rowSize; j++)
{
strip.setPixelColor(j, bitmap[j][i]);
}
strip.show();
}
}
void loop()
{
//Note the time the previous iteration of loop ran
//startTime = millis()
//Revolutions per loop
//revsThisLoop = (int)revs - prevRevs;
//Note revs this loop for future calculations
//prevRevs = revs;
if(updated != true)
{
//updateTimeIndices(0.05);
//updateTimeIndices( getPeriod((millis() - startTime), revsThisLoop) );
}
//Tests strip functionality by lighting up pixels in a novel fashion
rainbowFlag(5);
//mapToScreen(image);
}
void updateTimeIndices(double period)
{
//Time taken to traverse arc that represents the screen width
double screenWidth = 0.312795 * period;
for (i = 0; i < columnSize; i++)
{
if(i == 0)
timeIndices[i] = 1000000 * ( (1 * screenWidth) / columnSize );
else
timeIndices[i] = 1000000 * ( (i * screenWidth) / columnSize );
}
updated = true;
}
double getPeriod(unsigned long loopTime, int noOfRevs)
{
//Period is number of revs per loop / time taken per loop (s)
return (double)noOfRevs / ((double)loopTime / 1000);
}
//
//void drawImage() //Draws a smiley face sprite
//{
// for(i = 0; i <= columnSize; i++){
// for(j = 0; j <= rowSize; j++)
// {
// switch(i)
// {
// case 5:
// case 20:
// if(j >= 16 && j <=22)
// image[j][i] = b;
// else
// image[j][i] = r;
// break;
// case 6:
// case 19:
// if(j == 15 || j == 23)
// image[j][i] = b;
// else
// image[j][i] = r;
// break;
// case 7:
// case 18:
// if(j == 14 || j == 24)
// image[j][i] = b;
// else
// image[j][i] = r;
// break;
// case 8:
// case 17:
// if(j == 13 || j == 17 || j == 25)
// image[j][i] = b;
// else
// image[j][i] = r;
// break;
// case 9:
// case 16:
// if(j == 13 || j == 16 || j == 21 || j == 22 || j == 25)
// image[j][i] = b;
// else
// image[j][i] = r;
// break;
// case 10:
// case 15:
// if(j == 12 || j == 15 || j == 21 || j == 22 || j == 26)
// image[j][i] = b;
// else
// image[j][i] = r;
// break;
// case 11:
// case 12:
// case 13:
// case 14:
// if(j == 12 || j == 14 || j == 26 )
// image[j][i] = b;
// else
// image[j][i] = r;
// break;
// default:
// image[j][i] = r;
// break;
// }//switch
// }//inner for
// }//outer for
//}//draw image
void rainbowFlag(uint8_t wait)
{
for (int i = 0; i <= 31; i++) // update strip once
{
if(i <= 5) //red
{
delay(wait);
strip.setPixelColor(i, r);
strip.show();
delay(wait);
}
if(i > 5 && i <= 10) //orange
{
delay(wait);
strip.setPixelColor(i, orange);
strip.show();
delay(wait);
}
if(i > 10 && i <=15) // yellow
{
delay(wait);
strip.setPixelColor(i, yellow);
strip.show();
delay(wait);
}
if(i > 15 && i <=20) // green
{
delay(wait);
strip.setPixelColor(i, green);
strip.show();
delay(wait);
}
if(i > 20 && i <=25) // blue
{
delay(wait);
strip.setPixelColor(i, b);
strip.show();
delay(wait);
}
if(i > 25 && i <=31) //purple
{
delay(wait);
strip.setPixelColor(i, purple);
strip.show();
delay(wait);
}
}//strip updated
}
Thanks in advance