Close

Optimize: Round 1

A project log for 1K Challange Laser

Draw the hackaday logo with a laser with less than 1K of data.

cyrille-gindreauCyrille Gindreau 12/09/2016 at 20:170 Comments

How did we go from around 300 bytes to 1500 bytes when all we did was try to modularize our code? This is where the disassembly window started really becoming the star of the show.

Going through each assembly instruction, we quickly realized that instructions like multiply and divide and data structures like floats were the culprit. Looking at the memory map, we saw that all kinds of libraries were being brought in.

We got rid of floats and started using unsigned chars and ints

void drawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2){

	uint16_t dx1 = x1 > x2 ? x1 - x2 : x2 - x1;
	uint16_t dy1 = y1 > y2 ? y1 - y2 : y2 - y1;

	uint16_t steps1 = dx1 > dy1 ? dx1/4 : dy1/4;

	uint16_t Xincrement1 = (dx1*100) / steps1;
	uint16_t Yincrement1 = (dy1*100) / steps1;

	int x11 = x1*100;
	int y11 = y1*100;
	int i;

	for(i = 0; i < steps1; i++){

		x11 = x1 < x2 ? x11+Xincrement1 : x11 - Xincrement1;
		y11 = y1 < y2 ? y11+Yincrement1 : y11 - Yincrement1;

	    	writeMCP492x((int)((x11/100)*16), SSX);
	    	writeMCP492x((int)((y11/100)*16), SSY);
	}
}

With just a few little changes, this brought our size back down to 464 bytes.

Another optimization we made was that rather than calling this function with the coordinates directly, we modified the program a little bit to accept arrays of coordinates. The even numbers in the array would be X values while the odd would be Y values.

We also created an array of when the laser should be turned off. Turning off the laser would allow us to jump from one coordinate to another without being seen and without over cranking the galvos.

uint16_t myPoly[] = {230, 220, 245, 185, 150, 5, 65, 155, 150, 155, 130, 110, 150, 75, 230, 220, 25, 220, 5, 185, 175, 185, 150, 155, 130, 110, 110, 155, 5, 185, 110, 5, 150, 5};
uint16_t polyLength = 34;
uint16_t offIndices[] = {22, 26, 32};
uint16_t offLength = 3;
uint16_t offIter = 0;
uint16_t myIndex = 0;

while(1){
	 for(offIter = 0; offIter < offLength; offIter++){
		 if(myIndex == offIndices[offIter]){
			P1OUT &= ~LASER;
		 }
 	 }
 	 if(myIndex < polyLength-3){
 		 drawLine(myPoly[myIndex], myPoly[myIndex+1], myPoly[myIndex+2], myPoly[myIndex+3]);
    	 	myIndex = myIndex +2;
    	  } else {
    	 	drawLine(myPoly[myIndex], myPoly[myIndex+1], myPoly[0], myPoly[1]);
    	 	myIndex = 0;
    	  }
    	 P1OUT |= LASER;
}

This allowed for the creation of some more complex patterns while still saving as much space as possible.

Discussions