Skip to content

Instantly share code, notes, and snippets.

@Addidis
Created October 14, 2011 04:39
Show Gist options
  • Save Addidis/1286262 to your computer and use it in GitHub Desktop.
Save Addidis/1286262 to your computer and use it in GitHub Desktop.
Beta source for drawbot firmware (don't use this unless you know what it is)
// Drawbot 2.1 Firmware
// Inspired by the Makeitlast contest where the original example is from
// This version by @Addidis
// See www.jeselectronics.com for more info
/////////////////////////////////////////////////////////////////////////////
// Include files
/////////////////////////////////////////////////////////////////////////////
#include <p18lf26k22.h> // This file includes definitions for all of the registers on our chip
#include <usart.h> //see the c18 documentation for these
#include <math.h>
#include "delays.h"
#include "AN991.h"
#include "i2c.h"
//#include "EEP.h" //internal eeprom lib (left empty for user to use)
#pragma config FOSC = INTIO67 //use INTOSC
#pragma config PLLCFG = OFF //clocked at 16MHz
#pragma config WDTEN = OFF //WDT off
#pragma config PBADEN = OFF
// Fix a compiler bug
#undef INTCON
#undef INTCONbits
#define numSteps 400 //Number of steps per revolution us the
#define sw1 PORTBbits.RB0 //todo: perhaps juggle these around
#define sw2 PORTBbits.RB4
#define sw3 PORTBbits.RB3
#define sw4 PORTBbits.RB2
#define sw5 PORTBbits.RB1
//led macros
#define mLED_1 LATCbits.LATC2
#define mLED_1_On() mLED_1 = 1;
#define mLED_1_Off() mLED_1 = 0;
#define mLED_1_Toggle() mLED_1 = !mLED_1;
/////////////////////////////////////////////////////////////////////////////
// Function declarations
// Declare any user functions that you want to use here
/////////////////////////////////////////////////////////////////////////////
void main (void);
void setup(void);
void loop(void);
void console(void);
void low_isr(void);
void high_isr(void);
void putc1USART( char data );
void puts1USART( char *data );
void putrs1USART ( const MEM_MODEL rom char *data);
void OpenI2C1( unsigned char sync_mode, unsigned char slew );
void drawcircle(float a, float b, int r);
void setHome(void);
void getvars(void);
////////////////////////////////////////////////////////////////////////////
//Variable declarations
////////////////////////////////////////////////////////////////////////////
// Bit masks for the motor state tables
int A_C1states[4] = {0x00, 0x01, 0x01, 0x00};
int A_C2states[4] = {0x02, 0x02, 0x00, 0x00};
int B_C1states[4] = {0x00, 0x04, 0x04, 0x00};
int B_C2states[4] = {0x08, 0x08, 0x00, 0x00};
//Step variables for tracking
int Astate = 0; // state of left motor
int Bstate = 0; // state of right motor
int stepUnit = 100; // x= numSteps/(pi*Diameterofspool)
int w; // width of drawing field
int h; // height of drawing field
int a1; // length of left string
int b1; // length of right string
int x1; // current x position
int y1; // current y position
volatile int pause = 1;
//eprom declarations
//See AN991 PDF
unsigned char Length = 1; //length for byte read
volatile unsigned char PageString[128]; //Holds the device page data to/from EEPROM
unsigned int PageSize = 0x80; //Page size in bytes 128
volatile unsigned short pageadd = 0; // variable for page address
volatile unsigned char ControlByte=0b10100110; //Control Byte
volatile unsigned char HighAdd=0; //High Order Address Byte
volatile unsigned char LowAdd=0; //Low Order Address Byte
typedef volatile union Pages { // Union to combine chars into ints
volatile int lc;
volatile unsigned char bc[2];
};
//serial
volatile unsigned char receiveCharacter = 0; // Stores the last character that was
unsigned char checksum = 0; //checksum for serial transfers
//Drawing variables
//First set are stored in DBI file header and retrieved on startup from eeprom
volatile unsigned int widthT = 0; //total width of paper
volatile unsigned int height = 0; //total height of paper
volatile unsigned int numofpixWide = 0; //from encoded image
volatile unsigned int numofpixHigh = 0; //from encoded image
volatile unsigned int speed = 0; //speed of drawing 10000 is kinda 50 %
volatile unsigned int caddystablizingdelay = 0; //delay after a move command
//these are calculated from the header data retrieved
int rightW = 0; //right side of the paper Calculated from header
int leftW = 0; //left side of the paper Calculated from header
volatile int offset = 100; // start the bottom of page at +100
volatile char speedmap = 0; //used to get variables from the draw data
volatile char delaymap = 0; //used to get variables from the draw data
//*********************************************************************************************************************
// Begin code
//*********************************************************************************************************************
void main (void)
{
// Call the setup function once to put everything in order
setup();
// Then call the loop() function over and over
while (1)
{
loop();
}
}
// Map function, from:
// http://www.arduino.cc/en/Reference/Map
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
void smalldelay(void)
{
Delay1KTCYx(10); //save a few bytes this way
}
void largedelay(void)
{
Delay10KTCYx(120); //save a few bytes this way
}
void setHome(void)
{
// set home position
x1 = w/2;
y1 = h;
// calculate starting lengths
a1 = sqrt(pow(x1, 2)+pow(y1, 2));
b1 = sqrt(pow((w-x1), 2)+pow(y1,2));
}
void setSpeed(void)
{
PIE1bits.RC1IE=0; //Turn off interrupts so we can catch the next byte here and not in interrupt routine
while (!DataRdy1USART()); //wait for byte
speed = map(RCREG, 1,127, 20000,500); //Retrieve and map value
PIE1bits.RC1IE=1; //Turn on interrupts
}
void setdelay(void)
{
PIE1bits.RC1IE=0; //Turn off interrupts so we can catch the next byte here and not in interrupt routine
while (!DataRdy1USART()); //wait for byte
caddystablizingdelay = map(RCREG, 1,127, 0,200); //Retrieve and map value
PIE1bits.RC1IE=1; //Turn on interrupts
}
void clearunion(void)
{
union Pages word;
word.lc=0;
}
void turnMotors(int stepDirA, int stepDirB,int delay)
{
// turn the left and right motors one step in the given direction
unsigned int count;
a1 += stepDirA;
b1 += stepDirB;
Astate-=stepDirA;
Bstate+=stepDirB;
if (Astate == -1) { Astate = 3; }
if (Bstate == -1) { Bstate = 3; }
Astate = Astate %4;
Bstate = Bstate %4;
PORTA = A_C1states[Astate] | A_C2states[Astate] |
B_C1states[Bstate] | B_C2states[Bstate] ;
for( count = 0; count < delay; count++) {} // delay is sent the speed variable
}
void moveTo(int x2, int y2, int delay)
{
// move from the current point (x1, y1) to (x2, y2)
// implement Breshenham's algorithm to straighten this out
int dirA =0;
int dirB=0;
int a2 = sqrt(pow(x2, 2)+pow(y2, 2));
int b2 = sqrt(pow((w-x2), 2)+pow(y2,2));
if (a2 > a1) { dirA = 1; }
if (a2 < a1) { dirA = -1; }
if (b2 > b1) { dirB = 1; }
if (b2 < b1) { dirB = -1; }
while ((a1!=a2) || (b1!=b2)) {
if (a1 == a2) { dirA = 0; }
if (b1 == b2) { dirB = 0; }
turnMotors(dirA, dirB, delay);
}
x1=x2;
y1=y2;
}
void testpaper(void)
{
LATCbits.LATC2 = 0; //led off
getvars(); //Make sure we use the dimensions from the image file
moveTo(w/2,h-height,800); //test top of paper
while (sw2==1){};
moveTo(w/2,h,800); //moveback
moveTo(w/2+leftW,h,800); //test left of paper
while (sw2==1){};
moveTo(w/2+rightW,h,800); //test right of paper
while (sw2==1){};
moveTo(w/2,h,800); //test top of paper
LATCbits.LATC2 = 1; //led on
}
void trimcady(void)
{
int i;
if (receiveCharacter != 0) // See if we got a command
{
switch (receiveCharacter)
{
case 'g': //Move caddy up 4 steps
for(i=0;i<4;i++){turnMotors(-1,-1,500);}
receiveCharacter = 0;
break;
case 'h': //move caddy down 4 steps
for(i=0;i<4;i++){turnMotors(1,1,500);}
receiveCharacter = 0;
break;
case 'j': //move caddy left 100 steps
for(i=0;i<4;i++){turnMotors(-1,1,500);}
receiveCharacter = 0;
break;
case 'k': //move caddy right
for(i=0;i<4;i++){turnMotors(1,-1,500);}
receiveCharacter = 0;
break;
}
}
}
void console(void)
{
int i;
int t;
union Pages word;
int numofpages;
if (receiveCharacter != 0)
{
trimcady(); //trim cady future update will add 1 step increment caddy movements while paused to realign after an adjustment
// See if we got a command
switch (receiveCharacter)
{
case 'a': //left stepper up 4 steps
for(i=0; i<=4; i++){turnMotors(-1,0,500);}
break;
case 'q': //Left stepper up one turn
for(i=0; i<400; i++){turnMotors(-1,0,500);}
break;
case 's': //left stepper down 4 steps
for(i=0; i<=4; i++){turnMotors(1,0,500);}
break;
case 'w': //stepper one direction b one turn
for(i=0; i<400; i++){turnMotors(1,0,500);}
break;
case 'f': //Right stepper down 4 steps
for(i=0; i<=4; i++){turnMotors(0,1,500);}
break;
case 'r': //stepper down one turn
for(i=0; i<400; i++){turnMotors(0,1,500);}
break;
case 'd': //stepper two up 4 steps
for(i=0; i<=4; i++) {turnMotors(0,-1,500);}
break;
case 'e': //stepper one direction b one turn
for(i=0; i<400; i++){turnMotors(0,-1,500);}
break;
case 0x11: //Set Speed of drawing (DBC only)
setSpeed();
break;
case 0x12: //Set delay between moves to reduce vibration (DBC only)
setdelay();
break;
case 0x05: //Set delay between moves to reduce vibration (DBC only)
setHome();
testpaper();
break;
case 0x01: //download drawdata (DBC only)
PIE1bits.RC1IE=0; //Turn off interrupts
LATCbits.LATC2 = 0; //Turn off led to tell user mode entered
while (!DataRdy1USART()); //wait for first byte of numberof pages to download
word.bc[1] = RCREG; //put first byte in union
while (!DataRdy1USART()); //wait for second byte of numberof pages to download
word.bc[0] = RCREG; //put second byte in union
for (t=0; t<(word.lc*PageSize); t+=PageSize){ //Loop threw pages
checksum=0;
for(i=0; i<128; i++){ //Get 128 bytes Stick them in the PageString
while (!DataRdy1USART()); //wait for byte
PageString[i] = RCREG; //Stick it in PageString
}
pageadd = t;
ControlByte = 0b10100110;
HighAdd = ((pageadd>>8)&0xff); //Makes it easy to deal with pageaddress
LowAdd = (pageadd&0xff);
HDPageWriteI2C(ControlByte, HighAdd, LowAdd, PageString ); //High Density Page Write the data
largedelay(); //eeprom writes slow. . .
HDSequentialReadI2C(ControlByte, HighAdd, LowAdd, PageString, PageSize ); //read back the page we just wrote to verify eprom endurance
for (i=0; i<PageSize; i++){checksum+= PageString[i];} //add all the bytes to checksum
Write1USART((char)checksum); //send checksum
while (!DataRdy1USART()); //wait for byte
if (RCREG==21){break;} //if the checksum is different break
mLED_1_Toggle(); //if not induce joy and continue
}
LATCbits.LATC2 = 1; //turn on led to tell user its finished
PIE1bits.RC1IE = 1; //Turn back on interrupts
getvars(); //get new vars
break;
case 0x13: //Write new config from DBC (DBC only)
PIE1bits.RC1IE=0; //Turn off interrupts
mLED_1_Toggle(); //led off
ControlByte = 0b10100110;
pageadd = 0; //header is on first page
HighAdd = ((pageadd>>8)&0xff);
LowAdd = (pageadd&0xff);
HDSequentialReadI2C(ControlByte, HighAdd, LowAdd, PageString, PageSize ); //Read the first page
Write1USART((char)0x06); //ack for new config to be sent
for (t=0; t<=16; t+=1){ //Loop threw pages
while (!DataRdy1USART()); //wait for byte
PageString[i] = RCREG; //Stick it in PageString buffer with the bytes we are not changing
mLED_1_Toggle(); //Induce joy
}
HDPageWriteI2C(ControlByte, HighAdd, LowAdd, PageString ); //High Density Page Write
largedelay(); //slow eprom write
getvars(); //get new vars
LATCbits.LATC2 = 1; //led on
PIE1bits.RC1IE = 1; //Turn on interrupts
break;
case '~': //Send data out serial (DBC or console app) I think this is fail sauce atm. Need to test it.
for (t=0; t<((numofpixWide*numofpixHigh)+16); t+=PageSize){ //Loop threw pages
ControlByte = 0b10100110;
pageadd = t;
HighAdd = ((pageadd>>8)&0xff);
LowAdd = (pageadd&0xff);
HDSequentialReadI2C(ControlByte, HighAdd, LowAdd, PageString, PageSize ); //High Density Page Read
for(i=0; i<128; i++){Write1USART((char)PageString[i]);} //write it to serial
}
break;
}
receiveCharacter=0; //clear byte
}
//***********************
// Switch handeling code.
//***********************
if (sw2==0) //if sw3 is pressed
{
smalldelay(); //wait a bit
if(sw2==0) //if its still pressed
{
receiveCharacter='a'; //move motor one direction A 4 steps
largedelay(); //Delay to see if its held down or not
if(sw2==0){receiveCharacter='q';} //Its still held down some one is impatient ;)
} //move motor one direction A untill released
}//end sw2
if (sw3==0) //if sw3 is pressed
{
smalldelay(); //wait a bit
if(sw3==0) //if its still pressed
{
receiveCharacter='s'; //move motor one direction B 4 steps
largedelay(); //Delay to see if its held down or not
if(sw3==0){receiveCharacter='w';} //Its still held down some one is impatient ;)
} //move motor one direction B untill released
}//end sw3
if (sw4==0) //if sw4 is pressed
{
smalldelay(); //wait a bit
if(sw4==0) //if its still pressed
{
receiveCharacter='d'; //move motor Two direction A 4 steps
largedelay(); //Delay to see if its held down or not
if(sw4==0){receiveCharacter='e';} //Its still held down some one is impatient ;)
} //move motor Two direction A untill released
}//end sw4
if (sw5==0) //if sw5 is pressed
{
smalldelay(); //wait a bit
if(sw5==0) //if its still pressed
{
receiveCharacter='f'; //move motor two direction B 4 steps
largedelay(); //Delay to see if its held down or not
if(sw5==0){receiveCharacter='r';} //Its still held down some one is impatient ;)
} //move motor one direction B untill released
}//end sw5
} //end trim motors
void setup(void)
{
OSCCONbits.IRCF=111;
//Set all unused pins as output low
//todo: unused pins
TRISA = 0x00; // Set all of the pins on Port A to be outputs, low
PORTA = 0x00;
TRISB = 0B00011111; // Set up buttons as inputs RB0-START&\PAUSE\RESUME RB1 RB2 RB3 RB4
//led
TRISCbits.TRISC2=0; //set as output
LATCbits.LATC2=1; //set output high
//I2C pin config
TRISCbits.TRISC3 = 1; //Must be set as inputs for an991 to take over
TRISCbits.TRISC4 = 1;
//I2C setup
ANSELCbits.ANSC3 = 0; // Disable analog mode for SCA
ANSELCbits.ANSC4 = 0; // Disable analog mode for SDA
SSP1STAT=0b10000000;
SSP1CON1=0b00101000;
SSP1ADD=0x27; //16mhz fosc/4 , 100Khz
SSP1CON2=0x00;
SSP1CON1bits.SSPEN=1; //Turn on MSSP
//Set up int0 for start &| pause resume
INTCONbits.GIE=1;
INTCON2bits.INTEDG0=1;
INTCONbits.INT0IF=0;
INTCONbits.INT0IE=1;
//serial port setup 9600 baud (see manual, page 275)
BAUDCON1= 0b00000000;
TXSTA1bits.BRGH = 0;
BAUD1CONbits.BRG16 = 0;
SPBRG1 = 0x19;
SPBRGH1 = 0x00;
// Serial port configuration
TRISCbits.TRISC6 = 1; // TX pin an input (p264 ds)
TRISCbits.TRISC7 = 1; // RX pin an input
ANSELCbits.ANSC7 = 0; // Specifically, an analog input
RCONbits.IPEN = 0; // Interrupt priority off
INTCONbits.PEIE = 1; // Peripheral Interrupt Enable bit
PIR1bits.RC1IF=0; // clear Interupt flag
PIE1bits.RC1IE = 1; // Turn on interrupts on serial receive
//turn on serial port
RCSTA1bits.CREN = 1; // Enable receive mode on the serial port
TXSTA1bits.TXEN = 1; // Enable transmitter
RCSTA1bits.SPEN = 1; // Enable receiver
receiveCharacter = RCREG; // some pic you need to clear this a few times for it to start functioning. Just a habbit I got into.
receiveCharacter = RCREG;
getvars();
// This is not the paper size.
w = 72*stepUnit; //This is the distance between the steppers in inches
h = 36*stepUnit; //This is how far down the bottom is in inches
setHome(); //The pen must start at w/2 , h or for this set up 3 feet from either motor , and 3 feet down.
}
void getvars(void)
{
union Pages word;
clearunion();
pageadd = 4; //byte reads so start where we need to
ControlByte = 0b10100110; //todo: once its all tested and working try to remove all of these, dont think we need it.
HighAdd = ((pageadd>>8)&0xff);
LowAdd = (pageadd&0xff);
HDByteReadI2C(ControlByte, HighAdd, LowAdd , &word.bc[1], Length); //get numofpixWideMSB
pageadd ++;
ControlByte = 0b10100110;
HighAdd = ((pageadd>>8)&0xff);
LowAdd = (pageadd&0xff);
HDByteReadI2C(ControlByte, HighAdd, LowAdd , &word.bc[0], Length); //get numofpixWideLSB
numofpixWide = word.lc;
clearunion();
pageadd++;
ControlByte = 0b10100110;
HighAdd = ((pageadd>>8)&0xff);
LowAdd = (pageadd&0xff);
HDByteReadI2C(ControlByte, HighAdd, LowAdd , &word.bc[1], Length); //get numofpixHighMSB
pageadd ++;
ControlByte = 0b10100110;
HighAdd = ((pageadd>>8)&0xff);
LowAdd = (pageadd&0xff);
HDByteReadI2C(ControlByte, HighAdd, LowAdd , &word.bc[0], Length); //get numofpixHighLSB
numofpixHigh = word.lc;
clearunion();
pageadd++;
ControlByte = 0b10100110;
HighAdd = ((pageadd>>8)&0xff);
LowAdd = (pageadd&0xff);
HDByteReadI2C(ControlByte, HighAdd, LowAdd , &word.bc[1], Length); //get paperwidthMSB
pageadd ++;
ControlByte = 0b10100110;
HighAdd = ((pageadd>>8)&0xff);
LowAdd = (pageadd&0xff);
HDByteReadI2C(ControlByte, HighAdd, LowAdd , &word.bc[0], Length); //get paperwidthLSB
widthT = word.lc;
clearunion();
pageadd++;
ControlByte = 0b10100110;
HighAdd = ((pageadd>>8)&0xff);
LowAdd = (pageadd&0xff);
HDByteReadI2C(ControlByte, HighAdd, LowAdd , &word.bc[1], Length); //get paperheightMSB
pageadd ++;
ControlByte = 0b10100110;
HighAdd = ((pageadd>>8)&0xff);
LowAdd = (pageadd&0xff);
HDByteReadI2C(ControlByte, HighAdd, LowAdd , &word.bc[0], Length); //get paperheightLSB
height = word.lc;
clearunion();
pageadd++;
ControlByte = 0b10100110;
HighAdd = ((pageadd>>8)&0xff);
LowAdd = (pageadd&0xff);
HDByteReadI2C(ControlByte, HighAdd, LowAdd , &word.bc[1], Length); //get speed
speedmap = word.bc[1];
clearunion();
pageadd++;
ControlByte = 0b10100110;
HighAdd = ((pageadd>>8)&0xff);
LowAdd = (pageadd&0xff);
HDByteReadI2C(ControlByte, HighAdd, LowAdd , &word.bc[1], Length); //get delay
delaymap = word.bc[1];
clearunion();
//set rightw
rightW = widthT/2; //right side of the paper
//set leftW
leftW = (widthT/2)- (widthT/2)-(widthT/2); //left side of the paper in grid units (inches)
//set speed
speed = map(speedmap, 1,127, 20000,500); //Retrieve and map value
//set delay
caddystablizingdelay = map(delaymap, 1,127, 0,200); //Retrieve and map value
}
//not used atm saving space
/*
void drawcircle(float a, float b, int r)
{
float t;
float x;
float y;
int x2;
int y2;
for(t=0;t<=8; t+=.25){
x = (a + (r * cos(t)));
y = (b + (r * sin(t)));
x2 = x;
y2=y;
moveTo(x2, y2,6500);
}
}
*/
void drawpixel(int startx, int starty, char shade, int direction)
{
int widthofpixel = widthT/numofpixWide;
int heightofpixel = (height-offset)/numofpixHigh;
// int rows = numofpixHigh/2;
int newh = h-offset;
Delay10KTCYx( caddystablizingdelay );
if(shade== '0'){ //Black
if(direction == 2){
widthofpixel = widthofpixel - widthofpixel - widthofpixel;
}
//The comments are not accurate after shade=0 , they are next up to be redone.
moveTo(startx,starty-heightofpixel,speed); //move up heightofpixel
moveTo(startx,starty,speed); //move back
moveTo(startx+widthofpixel/4,starty,speed); //move to 1/4 width of pixel
moveTo(startx+widthofpixel/4,starty-heightofpixel,speed);//move to 1/4 width of pixel top
moveTo(startx+widthofpixel/4,starty,speed); //move back
moveTo(startx+widthofpixel/2,starty,speed); //move to middle of pixel
moveTo(startx+widthofpixel/2,starty-heightofpixel,speed); //move to middle of pixel up to top
moveTo(startx+widthofpixel/2,starty,speed); //move back
moveTo(startx+(widthofpixel/4)*3,starty,speed); //move to middle of pixel
moveTo(startx+(widthofpixel/4)*3,starty-heightofpixel,speed); //move to middle of pixel up to top
moveTo(startx+(widthofpixel/4)*3,starty,speed); //move back
moveTo(startx+widthofpixel,starty,speed); //move to end of pixel
moveTo(startx+widthofpixel,starty-heightofpixel,speed); //moveto end of pixel top
moveTo(startx+widthofpixel,starty,speed); //move to end of pixel
}
if(shade== '1'){ //black--1
if(direction == 2){
widthofpixel = widthofpixel - widthofpixel - widthofpixel;
}
moveTo(startx,starty-heightofpixel/4*3,speed); //move up heightofpixel
moveTo(startx,starty,speed); //move back
moveTo(startx+widthofpixel/4,starty,speed); //move to 1/4 width of pixel
moveTo(startx+widthofpixel/4,starty-heightofpixel,speed);//move to 1/4 width of pixel top
moveTo(startx+widthofpixel/4,starty,speed); //move back
moveTo(startx+widthofpixel/2,starty,speed); //move to middle of pixel
moveTo(startx+widthofpixel/2,starty-heightofpixel,speed); //move to middle of pixel up to top
moveTo(startx+widthofpixel/2,starty,speed); //move back
moveTo(startx+(widthofpixel/4)*3,starty,speed); //move to middle of pixel
moveTo(startx+(widthofpixel/4)*3,starty-heightofpixel,speed); //move to middle of pixel up to top
moveTo(startx+(widthofpixel/4)*3,starty,speed); //move back
moveTo(startx+widthofpixel-1,starty,speed); //move to end of pixel
moveTo(startx+widthofpixel-1,starty-(heightofpixel/4)*3,speed); //moveto end of pixel top
moveTo(startx+widthofpixel-1,starty,speed); //move to end of pixel
}
if(shade== '2'){
if(direction == 2){
widthofpixel = widthofpixel - widthofpixel - widthofpixel;
}
moveTo(startx,starty-(heightofpixel/4)*2,speed); //move up heightofpixel
moveTo(startx,starty,speed); //move back
moveTo(startx+widthofpixel/4,starty,speed); //move to 1/4 width of pixel
moveTo(startx+widthofpixel/4,starty-heightofpixel,speed);//move to 1/4 width of pixel top
moveTo(startx+widthofpixel/4,starty,speed); //move back
moveTo(startx+widthofpixel/2,starty,speed); //move to middle of pixel
moveTo(startx+widthofpixel/2,starty-heightofpixel,speed); //move to middle of pixel up to top
moveTo(startx+widthofpixel/2,starty,speed); //move back
moveTo(startx+(widthofpixel/4)*3,starty,speed); //move to middle of pixel
moveTo(startx+(widthofpixel/4)*3,starty-heightofpixel,speed); //move to middle of pixel up to top
moveTo(startx+(widthofpixel/4)*3,starty,speed); //move back
moveTo(startx+widthofpixel-1,starty,speed); //move to end of pixel
moveTo(startx+widthofpixel-1,starty-(heightofpixel/4)*2,speed); //moveto end of pixel top
moveTo(startx+widthofpixel-1,starty,speed); //move to end of pixel
}
if(shade=='3'){
if(direction == 2){
widthofpixel = widthofpixel - widthofpixel - widthofpixel;
}
moveTo(startx,starty-(heightofpixel/4)*2,speed); //move up heightofpixel
moveTo(startx,starty,speed); //move back
moveTo(startx+widthofpixel/4,starty,speed); //move to 1/4 width of pixel
moveTo(startx+widthofpixel/4,starty-(heightofpixel/4)*3,speed);//move to 1/4 width of pixel top
moveTo(startx+widthofpixel/4,starty,speed); //move back
moveTo(startx+widthofpixel/2,starty,speed); //move to middle of pixel
moveTo(startx+widthofpixel/2,starty-heightofpixel,speed); //move to middle of pixel up to top
moveTo(startx+widthofpixel/2,starty,speed); //move back
moveTo(startx+(widthofpixel/4)*3,starty,speed); //move to middle of pixel
moveTo(startx+(widthofpixel/4)*3,starty-(heightofpixel/4)*3,speed); //move to middle of pixel up to top
moveTo(startx+(widthofpixel/4)*3,starty,speed); //move back
moveTo(startx+widthofpixel-1,starty,speed); //move to end of pixel
moveTo(startx+widthofpixel-1,starty-(heightofpixel/4)*2,speed); //moveto end of pixel top
moveTo(startx+widthofpixel-1,starty,speed); //move to end of pixel
}
if(shade=='4'){
if(direction == 2){
widthofpixel = widthofpixel - widthofpixel - widthofpixel;
}
moveTo(startx+widthofpixel/4,starty,speed); //move to 1/4 width of pixel
moveTo(startx+widthofpixel/4,starty-(heightofpixel/4)*3,speed); //move to 1/4 width of pixel top
moveTo(startx+widthofpixel/4,starty,speed); //move back
moveTo(startx+widthofpixel/2,starty,speed); //move to middle of pixel
moveTo(startx+widthofpixel/2,starty-heightofpixel,speed); //move to middle of pixel up to top
moveTo(startx+widthofpixel/2,starty,speed); //move back
moveTo(startx+(widthofpixel/4)*3,starty,speed); //move to middle of pixel
moveTo(startx+(widthofpixel/4)*3,starty-(heightofpixel/4)*3,speed); //move to middle of pixel up to top
moveTo(startx+(widthofpixel/4)*3,starty,speed); //move back
}
if(shade=='5'){
if(direction == 2){
widthofpixel = widthofpixel - widthofpixel - widthofpixel;
}
moveTo(startx+widthofpixel/4,starty,speed); //move to 1/4 width of pixel
moveTo(startx+widthofpixel/4,starty-(heightofpixel/4)*2,speed); //move to 1/4 width of pixel top
moveTo(startx+widthofpixel/4,starty,speed); //move back
moveTo(startx+widthofpixel/2,starty,speed); //move to middle of pixel
moveTo(startx+widthofpixel/2,starty-heightofpixel,speed); //move to middle of pixel up to top
moveTo(startx+widthofpixel/2,starty,speed); //move back
moveTo(startx+(widthofpixel/4)*3,starty,speed); //move to middle of pixel
moveTo(startx+(widthofpixel/4)*3,starty-(heightofpixel/4)*2,speed); //move to middle of pixel up to top
moveTo(startx+(widthofpixel/4)*3,starty,speed); //move back
}
if(shade=='6'){
if(direction == 2){
widthofpixel = widthofpixel - widthofpixel - widthofpixel;
}
moveTo(startx+widthofpixel/2,starty,speed); //move to middle of pixel
moveTo(startx+widthofpixel/2,starty-heightofpixel,speed); //move to middle of pixel up to top
moveTo(startx+widthofpixel/2,starty,speed); //move back
Delay10KTCYx(caddystablizingdelay);//delay to stabilize caddy
}
if(shade=='7'){
if(direction == 2){
widthofpixel = widthofpixel - widthofpixel - widthofpixel;
}
moveTo(startx+widthofpixel/2,starty,speed); //move to middle of pixel
moveTo(startx+widthofpixel/2,starty-(heightofpixel/4)*3,speed); //move to middle of pixel up to top
moveTo(startx+widthofpixel/2,starty,speed); //move back
Delay10KTCYx(caddystablizingdelay);//delay to stabilize caddy
}
if(shade=='8'){ //near white
if(direction == 2){
widthofpixel = widthofpixel - widthofpixel - widthofpixel;
}
moveTo(startx+widthofpixel/2,starty,speed); //move to middle of pixel
moveTo(startx+widthofpixel/2,starty-(heightofpixel/4)*2,speed); //move to middle of pixel up to top
moveTo(startx+widthofpixel/2,starty,speed); //move back
Delay10KTCYx(caddystablizingdelay);//delay to stabilize caddy
}
}
// This function is called repeatedly
void loop(void)
{
LATCbits.LATC2 = pause;
if(pause==0) // This is a flag so you can trim motors before drawing. Pause is actually handled in interrupt once drawing is started.
{
int widthofpixel = widthT/numofpixWide;
int heightofpixel = (height-offset)/numofpixHigh;
int rows = numofpixHigh/2;
int newh = h-offset;
int shade = 0;
int curentpixel;
int halfofpixelswide = numofpixWide/2;
pageadd = ((numofpixHigh-1)*numofpixWide)+16; //set pageadd to first byte of last row.
setHome(); //This is so if you trim the motors it doesnt remember where you started as the home position.
//Draw code
//loop to draw number of pixelsH /2 left to right, up one right to left to start , looped number of pixels high divided by 2
for(rows = 0; rows<numofpixHigh*heightofpixel; rows+=heightofpixel*2)
{
//draws from far left to middle of the first line in the row (direction 1)
for(curentpixel = halfofpixelswide*widthofpixel; curentpixel>0; curentpixel-=widthofpixel)
{
//read data from eeprom
ControlByte = 0b10100110;
HighAdd = ((pageadd>>8)&0xff);
LowAdd = (pageadd&0xff);
HDByteReadI2C(ControlByte, HighAdd, LowAdd , &shade, Length); //High Density Byte Read
pageadd++;
moveTo(w/2-curentpixel,newh-rows ,speed);
drawpixel(w/2-curentpixel,newh-rows,shade,1);
}
//draws from middle to far right of the first line in the row (direction 1)
for(curentpixel=0; curentpixel< halfofpixelswide*widthofpixel; curentpixel+=widthofpixel)
{
ControlByte = 0b10100110;
HighAdd = ((pageadd>>8)&0xff);
LowAdd = (pageadd&0xff);
HDByteReadI2C(ControlByte, HighAdd, LowAdd , &shade, Length);
pageadd++;
moveTo(w/2+curentpixel, newh-rows,speed);
drawpixel(w/2+curentpixel,newh-rows,shade,1);
}
pageadd-=(numofpixWide+1);
//draws from far right, to middle second line in the row (direction 2 )
for(curentpixel= (widthofpixel*halfofpixelswide); curentpixel>0; curentpixel-=widthofpixel)
{
ControlByte = 0b10100110;
HighAdd = ((pageadd>>8)&0xff);
LowAdd = (pageadd&0xff);
HDByteReadI2C(ControlByte, HighAdd, LowAdd , &shade, Length);
pageadd--;
moveTo(w/2+curentpixel, newh-rows-heightofpixel,speed);
drawpixel(w/2+curentpixel,newh-rows-heightofpixel,shade,2);
}
//draws from middle to left second line in the row (direction 2 )
for(curentpixel= 0; curentpixel<=widthofpixel*halfofpixelswide; curentpixel+=widthofpixel)
{
ControlByte = 0b10100110;
HighAdd = ((pageadd>>8)&0xff);
LowAdd = (pageadd&0xff);
HDByteReadI2C(ControlByte, HighAdd, LowAdd , &shade, Length);
pageadd--;
moveTo(w/2-curentpixel, newh-rows-heightofpixel,speed);
drawpixel(w/2-curentpixel, newh-rows-heightofpixel,shade,2);
}
pageadd-=(numofpixWide-2);
}
while (sw2==1){{Delay1KTCYx(500);Delay1KTCYx(500);mLED_1_Toggle();}}; // Only print once
}
else if (pause==1) //allow trimming on first power on, and any time drawing is not started yet
{
console();
}
}
//Interrupt vectors
//REFEREnce DS51288a-page 27
#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
{
_asm GOTO high_isr _endasm
}
#pragma code /* return to the default code section */
#pragma interrupt high_isr
void high_isr (void)
{
if(PIR1bits.RC1IF==1) //Was it the Serial recieve interupt
{
receiveCharacter = RCREG; //Get the byte
PIR1bits.RCIF=0; //clear the flag
if(receiveCharacter=='p'){ //This is so we can pause by remote&DBC
if(pause==0) //if the serial byte was pause hold here till resume is sent
{
while(RCREG!='a'){ //Hold in pause unless RCREG=='a' the resume key/button ,
if(RCREG==0x11){setSpeed();} //allow setting speed while paused
if(RCREG==0x12){setdelay();} //allow setting delay while paused
mLED_1_Toggle(); //induce joy
}
}
else pause=0; //if the serial byte was start , pause=0
receiveCharacter =0; //Clear receiveCharacter if we did stuff.
}
}//end serial interupt
if(INTCONbits.INT0IF==1) //int0 Start / Pause sw1
{
while(sw2!=0){largedelay();mLED_1_Toggle();} //Hold in infinite loop until sw2 is pressed induce joy so when people hit pause on accident panic is averted
if(pause==1)
{
pause =0;
}
INTCONbits.INT0IF=0;
}
// high Interrupt goes here check which interrupt caused the interrupt , do stuff , clear int flag etc
}
//I didnt use this so to save space im commenting it out
//but it's good to have here if some one wants it
/* //REFEREnce DS51288a-page 27
#pragma code low_vector=0x18
void interrupt_at_low_vector(void)
{
_asm GOTO low_isr _endasm
}
#pragma code // return to the default code section
#pragma interruptlow low_isr
void low_isr (void)
{
// low Interrupt goes here check which interrupt caused the interrupt , do stuff , clear int flag etc
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment