Skip to content

Instantly share code, notes, and snippets.

@rogerclarkmelbourne
Created September 29, 2017 22:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rogerclarkmelbourne/8b15184a30d256bccc46080f01163553 to your computer and use it in GitHub Desktop.
Save rogerclarkmelbourne/8b15184a30d256bccc46080f01163553 to your computer and use it in GitHub Desktop.
Arduino BMP rainbow test image to serial - test image generator
/*
* Simple rainbow test image generator
* By Roger Clark
* www.rogerclark.net
*/
typedef struct
{
unsigned char r;
unsigned char g;
unsigned char b;
} rgbCol;
typedef struct
{
unsigned char h;
unsigned char s;
unsigned char v;
} hsvCol;
rgbCol HsvToRgb(hsvCol hsv)
{
rgbCol rgb;
unsigned char region, remainder, p, q, t;
if (hsv.s == 0)
{
rgb.r = hsv.v;
rgb.g = hsv.v;
rgb.b = hsv.v;
return rgb;
}
region = hsv.h / 43;
remainder = (hsv.h - (region * 43)) * 6;
p = (hsv.v * (255 - hsv.s)) >> 8;
q = (hsv.v * (255 - ((hsv.s * remainder) >> 8))) >> 8;
t = (hsv.v * (255 - ((hsv.s * (255 - remainder)) >> 8))) >> 8;
switch (region)
{
case 0:
rgb.r = hsv.v; rgb.g = t; rgb.b = p;
break;
case 1:
rgb.r = q; rgb.g = hsv.v; rgb.b = p;
break;
case 2:
rgb.r = p; rgb.g = hsv.v; rgb.b = t;
break;
case 3:
rgb.r = p; rgb.g = q; rgb.b = hsv.v;
break;
case 4:
rgb.r = t; rgb.g = p; rgb.b = hsv.v;
break;
default:
rgb.r = hsv.v; rgb.g = p; rgb.b = q;
break;
}
return rgb;
}
void SendTestPattern()
{
unsigned char bmpFileHeader[14] ;//= {'B', 'M', 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0 };
unsigned char bmpInfoHeader[40] ;//= {40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 24, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
const int w = 320;
const int h = 240;
uint8_t lineBufSD[w*3];// buffer a line as it seems to send quicker than byte by byte
// create image data
int filesize = 54 + 3 * w * h; // w is image width, h is image height
// all header blocks need to be initialised to zero
memset(bmpFileHeader,0,sizeof(bmpFileHeader));
memset(bmpInfoHeader,0,sizeof(bmpInfoHeader));
bmpFileHeader[0]='B';
bmpFileHeader[1]='M';
bmpFileHeader[ 2] = (unsigned char)(filesize );
bmpFileHeader[ 3] = (unsigned char)(filesize >> 8);
bmpFileHeader[ 4] = (unsigned char)(filesize >> 16);
bmpFileHeader[ 5] = (unsigned char)(filesize >> 24);
bmpFileHeader[10]=54;
// specifies 3 byte RGB (actually BGR) format
bmpInfoHeader[0]=40;
bmpInfoHeader[ 4] = (unsigned char)( w );
bmpInfoHeader[ 5] = (unsigned char)( w >> 8);
bmpInfoHeader[ 6] = (unsigned char)( w >> 16);
bmpInfoHeader[ 7] = (unsigned char)( w >> 24);
bmpInfoHeader[ 8] = (unsigned char)( h );
bmpInfoHeader[ 9] = (unsigned char)( h >> 8);
bmpInfoHeader[10] = (unsigned char)( h >> 16);
bmpInfoHeader[11] = (unsigned char)( h >> 24);
bmpInfoHeader[12]=1;
bmpInfoHeader[14]=24;
Serial.write(bmpFileHeader, sizeof(bmpFileHeader)); // write file header
Serial.write(bmpInfoHeader, sizeof(bmpInfoHeader)); // " info header
rgbCol out;
hsvCol hue;
hue.s=255;// set saturation to 100%
hue.v=255;// set v to 100%
uint8_t *p;
for (int y = 0 ; y < h ; y++)
{
p=lineBufSD;
for(int x=0; x < w ; x++)
{
hue.h = (x<<8) / ( w + 1);// hue angle (8 bit 0 - 255)
out = HsvToRgb(hue);
*p++ = out.b; // blue
*p++ = out.g; // green
*p++ = out.r; //red
}
Serial.write(lineBufSD, 3 * w);// write line to host
}
}
void setup() {
}
void loop()
{
// wait for a command to send from the host
if (Serial.available())
{
// In this case the host just sends a '0'
if (Serial.read()=='0')
{
SendTestPattern();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment