program calikusu dim SPI_Ethernet_Rst as sbit at LATG13_bit ' for writing to output pin always use latch SPI_Ethernet_CS as sbit at LATG12_bit ' for writing to output pin always use latch SPI_Ethernet_Rst_Direction as sbit at TRISG13_bit SPI_Ethernet_CS_Direction as sbit at TRISG12_bit ' end ethernet NIC definitions dim myMacAddr as byte[6] ' my MAC address myIpAddr as byte[4] ' my IP address gwIpAddr as byte[4] ' gateway (router) IP address ipMask as byte[4] ' network mask (for example : 255.255.255.0) dnsIpAddr as byte[4] ' DNS server IP address '************************************************************ '* ROM constant strings '************************************************************ const httpHeader as string[31] = "HTTP/1.1 200 OK"+chr(10)+"Content-type: " ' HTTP header const httpMimeTypeHTML as string[13] = "text/html"+chr(10)+chr(10) ' HTML MIME type const httpMimeTypeScript as string[14] = "text/plain"+chr(10)+chr(10) ' TEXT MIME type const httpMethod as string[5] = "GET /" '* '* web page, splited into 2 parts as '* when coming short of ROM, fragmented data is handled more efficiently by linker '* '* this HTML page calls the boards to get its status, and builds itself with javascript '* const indexPage as string[735] = "" + ""+ "

dsPIC + ENC28J60 Mini Web Server

"+ "Reload"+ ""+ "
"+ ""+ ""+ "
ADC
AN10
"+ ""+ "" const indexPage2 as string[470] = "
PORTB
"+ " "+ ""+ ""+ "
PORTD
"+ "This is HTTP request #" dim getRequest as byte[15] ' HTTP request buffer dyna as char[30] ' buffer for dynamic response httpCounter as word ' counter of HTTP requests txt as string[11] '******************************************* '* user defined functions '******************************************* '* '* this function is called by the library '* the user accesses to the HTTP request by successive calls to SPI_Ethernet_getByte() '* the user puts data in the transmit buffer by successive calls to SPI_Ethernet_putByte() '* the function must return the length in bytes of the HTTP reply, or 0 if nothing to transmit '* '* if you don"t need to reply to HTTP requests, '* just define this function with a return(0) as single statement '* '* sub function SPI_Ethernet_UserTCP(dim byref remoteHost as byte[4], dim remotePort, localPort, reqLength as word, dim byref flags as TEthPktFlags) as word dim i as word ' my reply length bitMask as byte ' for bit mask txt as string[11] result = 0 ' should we close tcp socket after response is sent? ' library closes tcp socket by default if canClose flag is not reset here ' canClose = 0 ' 0 - do not close socket ' otherwise - close socket if(localPort <> 80) then ' I listen only to web request on port 80 result = 0 exit end if ' get 10 first bytes only of the request, the rest does not matter here for i = 0 to 10 getRequest[i] = SPI_Ethernet_getByte() next i getRequest[i] = 0 ' copy httpMethod to ram for use in memcmp routine for i = 0 to 4 txt[i] = httpMethod[i] next i if(memcmp(@getRequest, @txt, 5) <> 0) then ' only GET method is supported here result = 0 exit end if Inc(httpCounter) ' one more request done if(getRequest[5] = "s") then ' if request path name starts with s, store dynamic data in transmit buffer ' the text string replied by this request can be interpreted as javascript statements ' by browsers result = SPI_Ethernet_putConstString(@httpHeader) ' HTTP header result = result + SPI_Ethernet_putConstString(@httpMimeTypeScript) ' with text MIME type ' add AN10 value to reply WordToStr(ADC1_Get_Sample(10), dyna) txt = "var AN10=" result = result + SPI_Ethernet_putString(@txt) result = result + SPI_Ethernet_putString(@dyna) txt = ";" result = result + SPI_Ethernet_putString(@txt) ' add PORTB value (buttons) to reply txt = "var PORTB=" result = result + SPI_Ethernet_putString(@txt) WordToStr(PORTB, dyna) result = result + SPI_Ethernet_putString(@dyna) txt = ";" result = result + SPI_Ethernet_putString(@txt) ' add PORTD value (LEDs) to reply txt = "var PORTD=" result = result + SPI_Ethernet_putString(@txt) WordToStr(PORTD, dyna) result = result + SPI_Ethernet_putString(@dyna) txt = ";" result = result + SPI_Ethernet_putString(@txt) ' add HTTP requests counter to reply WordToStr(httpCounter, dyna) txt = "var REQ=" result = result + SPI_Ethernet_putString(@txt) result = result + SPI_Ethernet_putString(@dyna) txt = ";" result = result + SPI_Ethernet_putString(@txt) else if(getRequest[5] = "t") then ' if request path name starts with t, toggle PORTD (LED) bit number that comes after bitMask = 0 if(isdigit(getRequest[6]) <> 0) then ' if 0 <= bit number <= 9, bits 8 & 9 does not exist but does not matter bitMask = getRequest[6] - "0" ' convert ASCII to integer bitMask = 1 << bitMask ' create bit mask PORTD = PORTD xor bitMask ' toggle PORTD with xor operator end if end if end if if(result = 0) then ' what do to by default result = SPI_Ethernet_putConstString(@httpHeader) ' HTTP header result = result + SPI_Ethernet_putConstString(@httpMimeTypeHTML) ' with HTML MIME type result = result + SPI_Ethernet_putConstString(@indexPage) ' HTML page first part result = result + SPI_Ethernet_putConstString(@indexPage2) ' HTML page second part end if ' return to the library with the number of bytes to transmit end sub ' * ' * this function is called by the library ' * the user accesses to the UDP request by successive calls to Ethernet_getByte() ' * the user puts data in the transmit buffer by successive calls to Ethernet_putByte() ' * the function must return the length in bytes of the UDP reply, or 0 if nothing to transmit ' * ' * if you don't need to reply to UDP requests, ' * just define this function with a return(0) as single statement ' * ' * sub function SPI_Ethernet_UserUDP(dim byref remoteHost as byte[4], dim remotePort, destPort, reqLength as word, dim byref flags as TEthPktFlags) as word dim txt as string[5] result = 0 ' reply is made of the remote host IP address in human readable format byteToStr(remoteHost[0], dyna) ' first IP address byte dyna[3] = "." byteToStr(remoteHost[1], txt) ' second dyna[4] = txt[0] dyna[5] = txt[1] dyna[6] = txt[2] dyna[7] = "." byteToStr(remoteHost[2], txt) ' second dyna[8] = txt[0] dyna[9] = txt[1] dyna[10] = txt[2] dyna[11] = "." byteToStr(remoteHost[3], txt) ' second dyna[12] = txt[0] dyna[13] = txt[1] dyna[14] = txt[2] dyna[15] = ":" ' add separator ' then remote host port number WordToStr(remotePort, txt) dyna[16] = txt[0] dyna[17] = txt[1] dyna[18] = txt[2] dyna[19] = txt[3] dyna[20] = txt[4] dyna[21] = "[" WordToStr(destPort, txt) dyna[22] = txt[0] dyna[23] = txt[1] dyna[24] = txt[2] dyna[25] = txt[3] dyna[26] = txt[4] dyna[27] = "]" dyna[28] = 0 ' the total length of the request is the length of the dynamic string plus the text of the request result = 28 + reqLength ' puts the dynamic string into the transmit buffer SPI_Ethernet_putBytes(@dyna, 28) ' then puts the request string converted into upper char into the transmit buffer while(reqLength <> 0) SPI_Ethernet_putByte(SPI_Ethernet_getByte()) Dec(reqLength) wend ' back to the library with the length of the UDP reply end sub ' Glcd module connections dim GLCD_D7 as sbit at RD7_bit GLCD_D6 as sbit at RD6_bit GLCD_D5 as sbit at RD5_bit GLCD_D4 as sbit at RD4_bit GLCD_D3 as sbit at RD3_bit GLCD_D2 as sbit at RD2_bit GLCD_D1 as sbit at RD1_bit GLCD_D0 as sbit at RD0_bit GLCD_D7_Direction as sbit at TRISD7_bit GLCD_D6_Direction as sbit at TRISD6_bit GLCD_D5_Direction as sbit at TRISD5_bit GLCD_D4_Direction as sbit at TRISD4_bit GLCD_D3_Direction as sbit at TRISD3_bit GLCD_D2_Direction as sbit at TRISD2_bit GLCD_D1_Direction as sbit at TRISD1_bit GLCD_D0_Direction as sbit at TRISD0_bit dim GLCD_CS1 as sbit at LATB3_bit GLCD_CS2 as sbit at LATB2_bit GLCD_RS as sbit at LATB4_bit GLCD_RW as sbit at LATB5_bit GLCD_EN as sbit at LATB6_bit GLCD_RST as sbit at LATB7_bit GLCD_CS1_Direction as sbit at TRISB3_bit GLCD_CS2_Direction as sbit at TRISB2_bit GLCD_RS_Direction as sbit at TRISB4_bit GLCD_RW_Direction as sbit at TRISB5_bit GLCD_EN_Direction as sbit at TRISB6_bit GLCD_RST_Direction as sbit at TRISB7_bit ' End Glcd module connections dim ADCresult as word ADCresult1 as word casi as word dim i,son as integer dim invert as word dim x1, x2,x3 as integer dim Y1, Y2, Y3,cnt as integer dim counter,HR as word dim cali as byte dim text as string[6] main: httpCounter = 0 myMacAddr[0] = 0x00 myMacAddr[1] = 0x14 myMacAddr[2] = 0xA5 myMacAddr[3] = 0x76 myMacAddr[4] = 0x19 myMacAddr[5] = 0x3F ' set IP address myIpAddr[0] = 198 myIpAddr[1] = 68 myIpAddr[2] = 20 myIpAddr[3] = 60 ' set gateway address gwIpAddr[0] = 198 gwIpAddr[1] = 68 gwIpAddr[2] = 20 gwIpAddr[3] = 6 ' set dns address dnsIpAddr[0] = 198 dnsIpAddr[1] = 68 dnsIpAddr[2] = 20 dnsIpAddr[3] = 1 ' set subnet mask ipMask[0] = 255 ipMask[1] = 255 ipMask[2] = 255 ipMask[3] = 0 ADPCFG = ADPCFG or 0xFBFF ' all digital but rb10(AN10) PORTB = 0 TRISB = 0xFFFF ' set PORTB as input for buttons and adc PORTD = 0 TRISD = 0 ' set PORTD as output, ' Configure AN pins as digital Glcd_Init() Glcd_Fill(0x00) TRISB.14=1 TRISB.10=1 TRISB.1=1 counter=0 X2 = 0 X3= 0 for i=0 to 10 Glcd_Fill(0x00) Glcd_Write_Text("ISMAILCALIKUSU", 1, 1, 2) Delay_ms(100) Glcd_Write_Text("MASTER THESIS",1,3,2) Delay_ms(100) Glcd_Write_Text("BIOMEDICAL",2,5,2) Delay_ms(100) Glcd_Write_Text("ENGINEERING",2,7,2) Delay_ms(1000) next i Glcd_Fill(0x00) ADC1_Init() '* '* starts ENC28J60 with as '* reset bit on RC0 '* CS bit on RC1 '* my MAC & IP address '* full duplex '* 'SPI2_Init() ' for faster SPI communication use Spi2_Init_Advanced settings Spi2_Init_Advanced(_SPI_MASTER, _SPI_8_BIT, _SPI_PRESCALE_SEC_1, _SPI_PRESCALE_PRI_4, _SPI_SS_DISABLE, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_IDLE_2_ACTIVE) SPI_Ethernet_Init(myMacAddr, myIpAddr, _SPI_Ethernet_FULLDUPLEX) ' init ethernet module SPI_Ethernet_setUserHandlers(@SPI_Ethernet_UserTCP, @SPI_Ethernet_UserUDP)' set user handlers ' dhcp will not be used here, so use preconfigured addresses SPI_Ethernet_confNetwork(ipMask, gwIpAddr, dnsIpAddr) HR=0 counter=0 while TRUE ' do forever SPI_Ethernet_doPacket() ' process incoming Ethernet packets ADCresult1=ADC1_Read(14) ADCresult= ADC1_Read(10) Y3=ADCresult1 *64/4096 Y2 = ADCresult * 64 /4096 Y3=not Y3 Y2=not Y2 IntToStr(HR, text) Glcd_Write_Text("ECG WAVE HR:"+text,2,0,1) Glcd_Write_Text("SPO2 WAVE ",2,4,1) Glcd_Dot(x3,y3+28,1) Glcd_Dot(x2,y2+58,1) delay_us(500) inc(x2) inc(x3) if x3>127 then x3=0 Glcd_Fill(0x00) end if x1=x2 if x2 > 127 then x2 = 0 Glcd_Fill(0x00) end if if counter>=20 then HR=60000/counter end if wend end.