// Generic Dobby Interface (up to 28 shaft) // Arduino Uno has 14 digital pins (2 for computer I/O) so can control up to 12 Shafts // Arduino Mega2560 has lots of pins - can handle up to 32 shafts // This implementation includes a 2.5" LCD touchscreen display to control the loom without a computer (primarily for troubleshooting) // Generic stuff for loom interface // Setup for 28 output pins controlling shafts // LADV is digital pin to connect foot button for loom #define MAX_CHARS 200 char message[MAX_CHARS]=""; unsigned long ShaftQue=0; // Qued state of shafts of loom char LastAdvState=1; // Maps loom shaft to Arduino output pins (Mega 2560) char PinForShaft[32]={22,23,24,25,26, 29,30,31,32,34, 36,37,38,39,40, 43,44,45,46,47, -1,-1,-1,-1}; // 32 shaft map // there are 2 spares per driver package with 5 of 7 drivers set. if a driver blows change the above to move to another channel #define LADV 52 char term_char='\n'; unsigned long Bits[32]={1,2,4,8,0x10,0x20,0x40,0x80,0x100,0x200,0x400,0x800,0x1000,0x2000,0x4000,0x8000, 0x10000,0x20000,0x40000,0x80000,0x100000,0x200000,0x400000,0x800000,0x1000000,0x2000000,0x4000000,0x8000000, 0x10000000,0x20000000,0x40000000,0x80000000}; // Display/Touchscreen stuff: #include // Display overlay UNO pin usage: // LCD Data Bit : 7 6 5 4 3 2 1 0 // Uno dig. pin : 7 6 5 4 3 2 9 8 // Uno port/pin : PD7 PD6 PD5 PD4 PD3 PD2 PB1 PB0 // Mega dig. pin: 29 28 27 26 25 24 23 22 // : PH4 PH3 PE3 PG5 PE5 PE4 PH6 PH5 #define LCD_RD A0 #define LCD_WR A1 #define LCD_RS A2 #define LCD_CS A3 #define LCD_REST A4 // Touchscreen definitions: #define YP A3 // must be an analog pin, use "An" notation! #define XM A2 // must be an analog pin, use "An" notation! #define YM 9 // can be a digital pin #define XP 8 // can be a digital pin #define TS_THRESHOLD 10 // For better pressure precision, we need to know the resistance // between X+ and X- Use any multimeter to read it // For the one we're using, its 300 ohms across the X plate TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); // Touchscreen min & max values - note this is twisted from the LCD x & axes struct Point { unsigned int x; unsigned int y; }; struct Rect { unsigned int x1; unsigned int y1; unsigned int x2; unsigned int y2; }; #define MAX_BUTTONS 42 #define BUTTON_STRING_SIZE 9 #define GAP 5 Rect ButtonRect[MAX_BUTTONS]; // defines location/size of the buttons char ButtonString[MAX_BUTTONS][BUTTON_STRING_SIZE]; // Strings used within buttons char ButtonState[MAX_BUTTONS]; // State of button to show char ButtonStateLast[MAX_BUTTONS]; // Last button state drawn #define CHAR_WIDTH 6 #define FIRST_SHAFT 8 #define BUTTON_INACTIVE 0 #define BUTTON_BOLD 1 #define BUTTON_GREEN 2 // For better pressure precision, we need to know the resistance // between X+ and X- Use any multimeter to read it // For the one we're using, its 300 ohms across the X plate // Dimentions for 2.6" display #define LCD_WIDTH 320 #define LCD_HEIGHT 240 // dimentions for 3.5" display #define LCD_3p5 0 //#define LCD_WIDTH 480 //#define LCD_HEIGHT 320 #define WHITE RGB(255,255,255) #define BLACK RGB(0,0,0) #define RED RGB(255,0,0) #define ORANGE RGB(255,127,0) #define YELLOW RGB(255,255,0) #define GREEN RGB(0,255,0) #define BLUE RGB(0,0,255) #define VIOLET RGB(255,0,255) #define WR_MASK B00000010 #define RS_MASK B00000100 //typedef struct record Record; int RGB(int r,int g,int b) { int rgb; rgb=r/8; rgb=rgb<<5; rgb|=(g/8); rgb=rgb<<6; rgb|=b/8; return rgb; // return r << 16 | g << 8 | b; } // Generic stuff for loom interface void SendAdvance(char state) { // Loom independent command to send "advance" to the host Serial.write("Advance\n"); // Generic command to advance } void Advance(char state) { if(state==0) { // button is down SetShafts(ShaftQue); // shafts are active while button is pressed ButtonState[0]=BUTTON_GREEN; // Set Advance indicator SetShaftButtons(ShaftQue,BUTTON_GREEN); // Set active buttons DrawButtons(); // show display delay(500); // delay to avoid button bounce, etc } else { // button released SendAdvance(LastAdvState); // tell host to advance SetShafts(0); // button release, release shafts ButtonState[0]=BUTTON_INACTIVE; // clear Advance indicator SetShaftButtons(ShaftQue,BUTTON_BOLD); // button indicators back to que DrawButtons(); // show buttons } } void SimulateLoom() { char inChar; char command[MAX_CHARS]=""; int serial_chars=0; if((Serial.available()>0)) { // Someone talking to us, get command inChar=-1; while((Serial.available()>0)&&(serial_chars0)&&(shaft<=32)) { // 'shafts' notes this shaft is required shafts|=Bits[shaft-1]; shaft=0; } } else if(('0'<=character)&&(character<='9')) { // have digit character&=0x0f; // reduce to decimal shaft=shaft*10+character; } else if((character==' ')||(character=='\n')); // ignore spaces/returns else { Serial.println("Invalid Character detected in command:"); // debug display of command extracted Serial.println(command); // debug display of command extracted i=chars; // quit, got crap } i++; } return shafts; } void SetShaftButtons (unsigned long shafts, char state) // Set indicator buttons as indicated { unsigned long mask=1; int i; while(i<32) { if(shafts&mask) ButtonState[FIRST_SHAFT+i]=state; else ButtonState[FIRST_SHAFT+i]=BUTTON_INACTIVE; mask=mask<<1; i++; } } void SetShafts (unsigned long shafts) // set output bits to state desired { unsigned long mask=1; int shaft, pin; while(shaft<32) { pin=PinForShaft[shaft]; if(shafts&mask) digitalWrite(pin,1); else digitalWrite(pin,0); mask=mask<<1; shaft++; } } void GenericReceiver(char *command) { //unsigned long temp; //unsigned char chunk; if(command[0]=='?') Serial.write("Generic Dobby Interface - 20 Shaft Macomber Air Assist\n"); else if(('0'<=command[0])&&(command[0]<='9')) // go number, should be shafts { ShaftQue=get_shafts(command); // host request for shafts to set SetShaftButtons(ShaftQue, BUTTON_BOLD); } } void send_advance() // Touchscreen response function for "ADVANCE" command { SendAdvance(1); } /////////////////////////// generic functions for LCD display & touchscreen ///////////////// char check_touchscreen(TSPoint *p ) { char state=0; unsigned long temp; TSPoint tp= ts.getPoint(),tp2= ts.getPoint(); int i=0, i2=0; int TS_MINX, TS_MAXX, TS_MINY,TS_MAXY; pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if(tp.z>TS_THRESHOLD) { if(LCD_3p5) { // Large display TS_MINX=112; TS_MAXX=860; TS_MINY=70;TS_MAXY=780; tp.x=1024-tp.x; tp.y=1024-tp.y; tp.x=tp.x-TS_MINX; if(tp.x<0)tp.x=0; tp.y=tp.y-TS_MINY; if(tp.y<0)tp.y=0; } else { // 2.6 inch display //TS_MINX=190; TS_MAXX=730; TS_MINY=190; TS_MAXY=730; TS_MINX=150; TS_MAXX=850; TS_MINY=150; TS_MAXY=950; tp.x=tp.x-TS_MINX; if(tp.x<0)tp.x=0; //tp.y=tp.y-TS_MINY; if(tp.y<0)tp.y=0; tp.y=TS_MAXY-tp.y; if(tp.y<0)tp.y=0; TS_MAXX-=TS_MINX; TS_MAXY-=TS_MINY; } temp=tp.y;temp*=LCD_WIDTH;temp/=TS_MAXY; if(temp>LCD_WIDTH)temp=LCD_WIDTH; (*p).x=int(temp); temp=tp.x;temp*=LCD_HEIGHT;temp/=TS_MAXX; if(temp>=LCD_HEIGHT)temp=LCD_HEIGHT; (*p).y=int(temp); //(*p).x=tp.y; //(*p).y=tp.x; (*p).z=tp.z; //sprintf(message,"Touched, @ (%d,%d, %d :: pxls %d, %d)\n",tp2.x,tp2.y,tp2.z,(*p).x,(*p).y); //Serial.write(message); state=1; // got something while(i> 3) | ((d&0x3) << 5); PORTE &= ~(0x38); PORTE |= ((d & 0xC) << 2) | ((d & 0x20) >> 2); PORTG &= ~(0x20); PORTG |= (d & 0x10) << 1; PORTF &= ~WR_MASK; PORTF |= WR_MASK; } void Lcd_Write_Com(unsigned char VH) { PORTF &= ~RS_MASK;//RS=0 Lcd_Writ_Bus(VH); } void Lcd_Write_Data(unsigned char VH) { PORTF |= RS_MASK;//LCD_RS=1; Lcd_Writ_Bus(VH); } void Lcd_Write_Com_Data(unsigned char com,unsigned char dat) { Lcd_Write_Com(com); Lcd_Write_Data(dat); } void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2) { Lcd_Write_Com(0x2a); Lcd_Write_Data(x1>>8); Lcd_Write_Data(x1); Lcd_Write_Data(x2>>8); Lcd_Write_Data(x2); Lcd_Write_Com(0x2b); Lcd_Write_Data(y1>>8); Lcd_Write_Data(y1); Lcd_Write_Data(y2>>8); Lcd_Write_Data(y2); Lcd_Write_Com(0x2c); digitalWrite(LCD_RS,HIGH); } void Lcd_Init(void) { digitalWrite(LCD_REST,HIGH); delay(5); digitalWrite(LCD_REST,LOW); delay(15); digitalWrite(LCD_REST,HIGH); delay(15); digitalWrite(LCD_CS,HIGH); digitalWrite(LCD_WR,HIGH); digitalWrite(LCD_CS,LOW); //CS Lcd_Write_Com(0x11); delay(20); Lcd_Write_Com(0xD0); Lcd_Write_Data(0x07); Lcd_Write_Data(0x42); Lcd_Write_Data(0x18); Lcd_Write_Com(0xD1); Lcd_Write_Data(0x00); Lcd_Write_Data(0x07);//07 Lcd_Write_Data(0x10); Lcd_Write_Com(0xD2); Lcd_Write_Data(0x01); Lcd_Write_Data(0x02); Lcd_Write_Com(0xC0); Lcd_Write_Data(0x10); Lcd_Write_Data(0x3B); Lcd_Write_Data(0x00); Lcd_Write_Data(0x02); Lcd_Write_Data(0x11); Lcd_Write_Com(0xC5); Lcd_Write_Data(0x03); Lcd_Write_Com(0x36); Lcd_Write_Data(0x0A); Lcd_Write_Com(0x3A); Lcd_Write_Data(0x55); Lcd_Write_Com(0x2A); Lcd_Write_Data(0x00); Lcd_Write_Data(0x00); Lcd_Write_Data(0x01); Lcd_Write_Data(0x3F); Lcd_Write_Com(0x2B); Lcd_Write_Data(0x00); Lcd_Write_Data(0x00); Lcd_Write_Data(0x01); Lcd_Write_Data(0xE0); delay(120); Lcd_Write_Com(0x29); Lcd_Write_Com(0x002c); } void H_line(unsigned int x, unsigned int y, unsigned int l, unsigned int c) // Draw Horizontal Line { unsigned int i,j; unsigned char c1=c>>8, c2=c; Lcd_Write_Com(0x02c); //write_memory_start digitalWrite(LCD_RS,HIGH); digitalWrite(LCD_CS,LOW); l=l+x; Address_set(x,y,l,y); j=l*2; for(i=1;i<=j;i++) { Lcd_Write_Data(c1); Lcd_Write_Data(c2); } digitalWrite(LCD_CS,HIGH); } void V_line(unsigned int x, unsigned int y, unsigned int l, unsigned int c) // Draw Vertical Line { unsigned int i,j; unsigned char c1=c>>8, c2=c; Lcd_Write_Com(0x02c); //write_memory_start digitalWrite(LCD_RS,HIGH); digitalWrite(LCD_CS,LOW); l=l+y; Address_set(x,y,x,l); j=l*2; for(i=1;i<=j;i++) { Lcd_Write_Data(c1); Lcd_Write_Data(c2); } digitalWrite(LCD_CS,HIGH); } void Rect(unsigned int x,unsigned int y,unsigned int w,unsigned int h,unsigned int c) // open rectangle { H_line(x , y , h, c); H_line(x , y+w, h, c); V_line(x , y , w, c); V_line(x+h, y , w, c); } void Rectf(unsigned int x,unsigned int y,unsigned int w,unsigned int h,unsigned int c) // filled rectangle { unsigned int i; for(i=0;i>8); Lcd_Write_Data(data[di]); di+=dx; } d0++; } digitalWrite(LCD_CS,HIGH); } ////////// specific functions to display loom data on display ////////// void pointP(int button_no, unsigned int *data,struct Point point,unsigned int color) { int dx=ButtonRect[button_no].x2-ButtonRect[button_no].x1; int z=point.x+point.y*dx; data[z]=color; } void line(int button_no, unsigned int *data,struct Point from, struct Point to, unsigned int color) { struct Point point; int dx=to.x-from.x, dy=to.y-from.y; float fy=from.y, fdy=(float)dy/float(dx); float fx=from.x, fdx=(float)dx/float(dy); point.x=from.x; point.y=from.y; if(dx>dy) { while(point.x>1; } } void fill_char(int button_no, unsigned int *data, int x, unsigned char *CharMap, int scale, unsigned int color) { int i=0; while(i0) { x=(ButtonRect[button_no].x2-ButtonRect[button_no].x1)/2-(chars*CHAR_WIDTH*scale)/2; // starting position for first char i=0; while(i0)&&(dy>0)&&(ButtonState[button_no]!=ButtonStateLast[button_no])) { //sprintf(message,"button %d: %d,%d, %d,%d \n",button_no,ButtonRect[button_no].x1,ButtonRect[button_no].y1,ButtonRect[button_no].x2,ButtonRect[button_no].y2); //Serial.write(message); //delay(100); if(ButtonState[button_no]==BUTTON_GREEN){brush_color=GREEN; border=5;} else if(ButtonState[button_no]==BUTTON_BOLD){brush_color=YELLOW;border=6;} while(i>8, c2=c; Address_set(0,0,LCD_HEIGHT,LCD_WIDTH); digitalWrite(LCD_CS,LOW); for(i=0;i=0) { pinMode(PinForShaft[i], OUTPUT); digitalWrite(PinForShaft[i],0); } i++; } pinMode(LADV, INPUT_PULLUP); // Display initialization DDRH |= 0x78; DDRE |= 0x38; DDRG |= 0x20; pinMode(A0,OUTPUT); pinMode(A1,OUTPUT); pinMode(A2,OUTPUT); pinMode(A3,OUTPUT); pinMode(A4,OUTPUT); digitalWrite(A0, HIGH); digitalWrite(A1, HIGH); digitalWrite(A2, HIGH); digitalWrite(A3, HIGH); digitalWrite(A4, HIGH); Lcd_Init(); //LCD_Clear(0xf800); // Clear all buttons i=0; while(i