after my modifications, web page will not load...
Hello--
First time poster and new spinneret/propeller user...I have tried to modify your code that is posted on http://spinneret.servebeer.com:5000/gstart/get.htm , and I do not get my local web page any more.
I ran through all Mike Gs instructions by the numbers, had it working until I added a servo and what I thought was the html adding a button for the servo (on/off)...
my code looks like :
PRI Dispatcher2(id)
''do some processing before sending the response
if(strcomp(Request.GetName(id), string("servo")))
Demo (id)
StaticFileHandler(id)
return
PRI Demo(id) | qstr
'' Get the query string value
qstr := Request.Get(id, string("servo"))
if (strcomp( string("on"), qstr ))
ServoStatus(1)
else
ServoStatus(0)
return
PRI ServoStatus(state)
cognew(MoveMotor(26),@StackSpace4) 'Start a new cog and run the MoveMotor method on it that outputs pulses on Pin 7
'The new cog that is started above continuously reads the "position" variable as it's changed by the example Spin code below
repeat
position:=100 'Start sending 1ms servo signal high pulses (100 * 10us = 1ms)
waitcnt(clkfreq+cnt) 'Wait for 1 second (1ms high pulses continue to be generated by the other cog)
position:=138 'Start sending 1.38ms servo signal high pulses (Center position)
waitcnt(clkfreq+cnt) 'Wait for 1 second (1.38ms high pulses continue to be generated by the other cog)
position:=50 'Start sending 0.5ms servo signal high pulses (Clockwise position)
waitcnt(clkfreq+cnt) 'Wait for 1 second (0.5ms high pulses continue to be generated by the other cog)
position:=225 'Start sending 2.25ms servo signal high pulses (Counterclockwise position)
waitcnt(clkfreq+cnt)
return
PUB MoveMotor(Pin) 'This method outputs a continuous stream of servo signal pulses on "Pin"
dira[Pin]~~ 'Set the direction of "Pin" to be an output
repeat 'Send out a continous train of pulses
outa[Pin]~~ 'Set "Pin" High
waitcnt((clkfreq/100_000)*position+cnt) 'Wait for the specifed position (units = 10 microseconds)
outa[Pin]~ 'Set "Pin" Low
waitcnt(clkfreq/100+cnt) 'Wait 10ms between pulses
...the rest of the code is using exactly what Mike had; I did add the requisite StackSpace for the new cogs, the variables, etc....the code loaded on to the Spinneret, I kept the index.htm page as is, then I modified the led.htm web page to look like:
<html>
<head>
<title>GETing to the Server</title>
</head>
<body>
<div style="width:600px;margin:auto;">
<h1 style="text-align:center;color:blue;">LED</h1>
<div style="text-align:center;"><a href="index.htm">Hello World</a> | <a href="led.htm">LED</a></div>
<p><a href="led.htm?led=on">LED On</a> :: <a href="led.htm?led=off">LED Off</a></p>
<p>LED: <span id="placeholder"></span></p>
<p><a href="led.htm?servo=on">SERVO On</a> :: <a href="led.htm?SERVO=off">SERVO Off</a></p>
<p>LED: <span id="placeholder"></span></p>
</div>
</div>
</body>
</html>
All the networking pieces worked fine, got the web page, turned on the led via the web server, then I did the above mods and all is no go. I get this message:
The connection was reset
The connection to the server was reset while the page was loading.
Please help!
Even with my mods, I get the following on PST:
Mount SD Card - OK
Start RTC: 01/04/2000 10:40:43
W5100 Driver Started
Status Memory Lock ID : 1
HTTP Server Lock ID : 2
TCP Socket Listener ID : 0
TCP Socket Listener ID : 1
TCP Socket Listener ID : 2
TCP Socket Listener ID : 3
Started Socket Monitoring Service
Initial Socket States
3-14 2-14 1-14 0-14
clsd open lstn estb clwt clng udps
0000-0000-1111-0000-0000-0000-0000
Initial Socket Queue
FIFO[0] 00000000
//////////////////////////////////////////////////////////////
First time poster and new spinneret/propeller user...I have tried to modify your code that is posted on http://spinneret.servebeer.com:5000/gstart/get.htm , and I do not get my local web page any more.
I ran through all Mike Gs instructions by the numbers, had it working until I added a servo and what I thought was the html adding a button for the servo (on/off)...
my code looks like :
PRI Dispatcher2(id)
''do some processing before sending the response
if(strcomp(Request.GetName(id), string("servo")))
Demo (id)
StaticFileHandler(id)
return
PRI Demo(id) | qstr
'' Get the query string value
qstr := Request.Get(id, string("servo"))
if (strcomp( string("on"), qstr ))
ServoStatus(1)
else
ServoStatus(0)
return
PRI ServoStatus(state)
cognew(MoveMotor(26),@StackSpace4) 'Start a new cog and run the MoveMotor method on it that outputs pulses on Pin 7
'The new cog that is started above continuously reads the "position" variable as it's changed by the example Spin code below
repeat
position:=100 'Start sending 1ms servo signal high pulses (100 * 10us = 1ms)
waitcnt(clkfreq+cnt) 'Wait for 1 second (1ms high pulses continue to be generated by the other cog)
position:=138 'Start sending 1.38ms servo signal high pulses (Center position)
waitcnt(clkfreq+cnt) 'Wait for 1 second (1.38ms high pulses continue to be generated by the other cog)
position:=50 'Start sending 0.5ms servo signal high pulses (Clockwise position)
waitcnt(clkfreq+cnt) 'Wait for 1 second (0.5ms high pulses continue to be generated by the other cog)
position:=225 'Start sending 2.25ms servo signal high pulses (Counterclockwise position)
waitcnt(clkfreq+cnt)
return
PUB MoveMotor(Pin) 'This method outputs a continuous stream of servo signal pulses on "Pin"
dira[Pin]~~ 'Set the direction of "Pin" to be an output
repeat 'Send out a continous train of pulses
outa[Pin]~~ 'Set "Pin" High
waitcnt((clkfreq/100_000)*position+cnt) 'Wait for the specifed position (units = 10 microseconds)
outa[Pin]~ 'Set "Pin" Low
waitcnt(clkfreq/100+cnt) 'Wait 10ms between pulses
...the rest of the code is using exactly what Mike had; I did add the requisite StackSpace for the new cogs, the variables, etc....the code loaded on to the Spinneret, I kept the index.htm page as is, then I modified the led.htm web page to look like:
<html>
<head>
<title>GETing to the Server</title>
</head>
<body>
<div style="width:600px;margin:auto;">
<h1 style="text-align:center;color:blue;">LED</h1>
<div style="text-align:center;"><a href="index.htm">Hello World</a> | <a href="led.htm">LED</a></div>
<p><a href="led.htm?led=on">LED On</a> :: <a href="led.htm?led=off">LED Off</a></p>
<p>LED: <span id="placeholder"></span></p>
<p><a href="led.htm?servo=on">SERVO On</a> :: <a href="led.htm?SERVO=off">SERVO Off</a></p>
<p>LED: <span id="placeholder"></span></p>
</div>
</div>
</body>
</html>
All the networking pieces worked fine, got the web page, turned on the led via the web server, then I did the above mods and all is no go. I get this message:
The connection was reset
The connection to the server was reset while the page was loading.
Please help!
Even with my mods, I get the following on PST:
Mount SD Card - OK
Start RTC: 01/04/2000 10:40:43
W5100 Driver Started
Status Memory Lock ID : 1
HTTP Server Lock ID : 2
TCP Socket Listener ID : 0
TCP Socket Listener ID : 1
TCP Socket Listener ID : 2
TCP Socket Listener ID : 3
Started Socket Monitoring Service
Initial Socket States
3-14 2-14 1-14 0-14
clsd open lstn estb clwt clng udps
0000-0000-1111-0000-0000-0000-0000
Initial Socket Queue
FIFO[0] 00000000
//////////////////////////////////////////////////////////////

Comments
This section of code is looking for a file named servo. Did you change the name of Led.htm to servo.htm or create a file named servo.htm? If not, Dispatcher2 will return without sending a response to the browser. The socket will close and browser will complain.
PRI Dispatcher2(id) ''do some processing before sending the response if(strcomp(Request.GetName(id), string("servo"))) Demo (id) StaticFileHandler(id) returnThis code block takes several seconds to complete which might cause a timeout. Plus it invokes a new COG service on each request. I would start the servo service when the web server starts. Change the logic so setting the position variable to something other than, say, -1 will output a PWM control signal.
PRI ServoStatus(state) cognew(MoveMotor(26),@StackSpace4) 'Start a new cog and run the MoveMotor method on it that outputs pulses on Pin 7 'The new cog that is started above continuously reads the "position" variable as it's changed by the example Spin code below repeat position:=100 'Start sending 1ms servo signal high pulses (100 * 10us = 1ms) waitcnt(clkfreq+cnt) 'Wait for 1 second (1ms high pulses continue to be generated by the other cog) position:=138 'Start sending 1.38ms servo signal high pulses (Center position) waitcnt(clkfreq+cnt) 'Wait for 1 second (1.38ms high pulses continue to be generated by the other cog) position:=50 'Start sending 0.5ms servo signal high pulses (Clockwise position) waitcnt(clkfreq+cnt) 'Wait for 1 second (0.5ms high pulses continue to be generated by the other cog) position:=225 'Start sending 2.25ms servo signal high pulses (Counterclockwise position) waitcnt(clkfreq+cnt) returnMike--Thanks for your help--- to the above, I had written " <p><a href="led.htm?servo=on">SERVO On</a> :: <a href="led.htm?SERVO=off">SERVO Off</a></p> "
Is that part correct (the html section)?
I'll work on the rest of your suggestions now that I am home from work....
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 MAX_PACKET_SIZE = $5C0 '1472 '$800 = 2048 RxTx_BUFFER = $800 '$600 = 1536 TEMP_BUFFER = $600 '$5B4 = 1460 TCP_PROTOCOL = %0001 '$300 = 768 UDP_PROTOCOL = %0010 '$200 = 512 TCP_CONNECT = $04 '$100 = 256 DELAY = $05 MAX_TRIES = $05 LCD_PIN = 22 ' for Parallax 4x20 serial LCD on P0 LCD_BAUD = 19_200 LCD_LINES = 2 LCD_BKSPC = $08 ' move cursor left LCD_RT = $09 ' move cursor right LCD_LF = $0A ' move cursor down 1 line LCD_CLS = $0C ' clear LCD (follow with 5 ms delay) LCD_CR = $0D ' move pos 0 of next line LCD_BL_ON = $11 ' backlight on LCD_BL_OFF = $12 ' backlight off LCD_OFF = $15 ' LCD off LCD_ON1 = $16 ' LCD on; cursor off, blink off LCD_ON2 = $17 ' LCD on; cursor off, blink on LCD_ON3 = $18 ' LCD on; cursor on, blink off LCD_ON4 = $19 ' LCD on; cursor on, blink on LCD_LINE0 = $80 ' move to line 1, column 0 LCD_LINE1 = $94 ' move to line 2, column 0 LCD_LINE2 = $A8 ' move to line 3, column 0 LCD_LINE3 = $BC ' move to line 4, column 0 #$F8, LCD_CC0, LCD_CC1, LCD_CC2, LCD_CC3 #$FC, LCD_CC4, LCD_CC5, LCD_CC6, LCD_CC7 #0, DONE, PUT, CD DAT mac byte $00, $08, $DC, $16, $F3, $3A subnet byte 255, 255 ,255, 0 gateway byte 192, 168, 1, 1 ip byte 192, 168, 1, 25 port word 5555 remoteIp byte 65, 98, 8, 151 {65.98.8.151} remotePort word 80 uport word 5555 emailIp byte 0, 0, 0, 0 emailPort word 25 status byte $00, $00, $00, $00 rxdata byte $0[RxTx_BUFFER] txdata byte $0[RxTx_BUFFER] udpdata byte $0[TEMP_BUFFER] fileErrorHandle long $0 debug byte $0 lastFile byte $0[12], 0 closedState byte %0000 openState byte %0000 listenState byte %0000 establishedState byte %0000 closingState byte %0000 closeWaitState byte %0000 lastEstblState byte %0000 lastEstblStateDebug byte %0000 udpListen byte %0000 tcpMask byte %1111 udpMask byte %1000 fifoSocketDepth byte $0 fifoSocket long $00_00_00_00 debugSemId byte $00 debugCounter long $00 stringMethods long $00 closingTimeout long $00, $00, $00, $00 udpLen long $00 time byte "00/00/0000 00:00:00", 0 httpDate byte "Wed, 01 Feb 2000 01:00:00 GMT", 0 globalCache byte $1 dynamicContentPtr long @txdata Bullet byte $00, $04, $0E, $1F, $0E, $04, $00, $00 VAR long StackSpace[20] long StackSpace2[20] long StackSpace3[20] long position 'The assembly program will read this variable from the main RAM to determine the ' servo signal's high pulse duration long StackSpace4[5] 'Alot some stack space for the cog running MoveMotor to use OBJ pst : "Parallax Serial Terminal" Socket : "W5100_Indirect_Driver" SDCard : "S35390A_SD-MMC_FATEngineWrapper" Request : "Request" Response : "Response" str : "StringMethods" rtc : "S35390A_RTCEngine" lcd : "debug_lcd" PUB Initialize | id, size, st debug := 1 SDCard.Start stringMethods := str.Start Request.Constructor(stringMethods) Response.Constructor(stringMethods, @txdata) pst.Start(115_200) pause(200) 'Mount the SD card pst.str(string("Mount SD Card - ")) SDCard.mount(fileErrorHandle) pst.str(string("OK",13)) pst.str(string("Start RTC: ")) rtc.RTCEngineStart(29, 28, -1) pause(200) pst.str(FillTime) 'Start the W5100 driver if(Socket.Start) pst.str(string(13, "W5100 Driver Started", 13)) pst.str(string(13, "Status Memory Lock ID : ")) pst.dec(Socket.GetLockId) pst.char(13) if(debugSemId := locknew) == -1 pst.str(string("Error, no HTTP server locks available", 13)) else pst.str(string("HTTP Server Lock ID : ")) pst.dec(debugSemId) pst.char(13) 'Set the Socket addresses SetMac(@mac) SetGateway(@gateway) SetSubnet(@subnet) SetIP(@ip) ' Initailize TCP sockets (defalut setting; TCP, Port, remote ip and remote port) repeat id from 0 to 3 InitializeSocket(id) Request.Release(id) pause(50) ' Set all TCP sockets to listen pst.char(13) repeat id from 0 to 3 Socket.Listen(id) pst.str(string("TCP Socket Listener ID : ")) pst.dec(id) pst.char(13) pause(50) pst.Str(string(13,"Started Socket Monitoring Service", 13)) cognew(StatusMonitor, @StackSpace) pause(250) pst.Str(string(13, "Initial Socket States",13)) StackDump pst.Str(string(13, "Initial Socket Queue",13)) QueueDump pst.str(string(13,"//////////////////////////////////////////////////////////////",13)) Main PUB Main | packetSize, id, i, reset, j, temp ''HTTP Service cognew(SONG, @StackSpace2) pause(250) repeat repeat until fifoSocket == 0 bytefill(@rxdata, 0, RxTx_BUFFER) if(debug) pst.str(string(13, "----- Start of Request----------------------------",13)) pause(DELAY) else pause(DELAY) ' Pop the next socket handle id := DequeueSocket if(id < 0) next if(debug) pst.str(string(13,"ID: ")) pst.dec(id) pst.str(string(13, "Request Count : ")) pst.dec(debugCounter) pst.char(13) packetSize := Socket.rxTCP(id, @rxdata) reset := false if ((packetSize < 12) AND (strsize(@rxdata) < 12)) repeat i from 0 to MAX_TRIES 'pst.str(string(13,"* Retry *")) 'Wait for a few moments and try again waitcnt((clkfreq/500) + cnt) packetSize := Socket.rxTCP(id, @rxdata) if(packetSize > 12) quit if(i == MAX_TRIES) 'Clean up resource request Request.Release(id) Socket.Disconnect(id) reset := true if(debug) StackDump pst.char(13) QueueDump pst.str(string(13,"* Timeout *",13)) if(reset) next Request.InitializeRequest(id, @rxdata) if(debug) pst.char(13) HeaderLine1(id) else pause(DELAY) ' Process router Dispatcher(id) 'Clean up request resource Request.Release(id) ' This starts the close process -> 0x00 ' use close to force a close Socket.Disconnect(id) bytefill(@txdata, 0, RxTx_BUFFER) debugCounter++ GotoMain PRI GotoMain Main PRI Dispatcher(id) ''do some processing before sending the response if(strcomp(Request.GetName(id), string("led"))) Led(id) StaticFileHandler(id) return PRI Led(id) | qstr '' Get the query string value qstr := Request.Get(id, string("led")) if (strcomp( string("on"), qstr )) LedStatus(1) else LedStatus(0) return PRI LedStatus(state) dira[27]~~ outa[27] := state return PRI Dispatcher2(id) ''do some processing before sending the response if(strcomp(Request.GetName(id), string("servo"))) Demo (id) StaticFileHandler(id) return PRI Demo(id) | qstr '' Get the query string value qstr := Request.Get(id, string("servo")) if (strcomp( string("on"), qstr )) ServoStatus(1) else ServoStatus(0) return PRI ServoStatus(state) cognew(MoveMotor(26),@StackSpace4) 'Start a new cog and run the MoveMotor method on it that outputs pulses on Pin 7 'The new cog that is started above continuously reads the "position" variable as it's changed by the example Spin code below repeat position:=100 'Start sending 1ms servo signal high pulses (100 * 10us = 1ms) waitcnt(clkfreq+cnt) 'Wait for 1 second (1ms high pulses continue to be generated by the other cog) position:=138 'Start sending 1.38ms servo signal high pulses (Center position) waitcnt(clkfreq+cnt) 'Wait for 1 second (1.38ms high pulses continue to be generated by the other cog) position:=50 'Start sending 0.5ms servo signal high pulses (Clockwise position) waitcnt(clkfreq+cnt) 'Wait for 1 second (0.5ms high pulses continue to be generated by the other cog) position:=225 'Start sending 2.25ms servo signal high pulses (Counterclockwise position) waitcnt(clkfreq+cnt) return PUB MoveMotor(Pin) 'This method outputs a continuous stream of servo signal pulses on "Pin" dira[Pin]~~ 'Set the direction of "Pin" to be an output repeat 'Send out a continous train of pulses outa[Pin]~~ 'Set "Pin" High waitcnt((clkfreq/100_000)*position+cnt) 'Wait for the specifed position (units = 10 microseconds) outa[Pin]~ 'Set "Pin" Low waitcnt(clkfreq/100+cnt) 'Wait 10ms between pulses PRI StaticFileHandler(id) | fileSize, i, headerLen, temp, j ''Serve up static files from the SDCard 'pst.str(string(13,"Static File Handler",13)) SDCard.changeDirectory(@approot) pst.char(13) 'Make sure the directory exists ifnot(ChangeDirectory(id)) 'send 404 error WriteError(id) SDCard.changeDirectory(@approot) return ' Make sure the file exists ifnot(FileExists(Request.GetFileName(id))) 'send 404 error WriteError(id) SDCard.changeDirectory(@approot) return ' Open the file for reading SDCard.openFile(Request.GetFileName(id), "r") fileSize := SDCard.getFileSize 'WriteResponseHeader(id) 'BuildHeader(extension, statusCode, expirer) headerLen := Response.BuildHeader(Request.GetExtension(id), 200, globalCache) Socket.txTCP(id, @txdata, headerLen) if fileSize < MAX_PACKET_SIZE ' send the file in one packet SDCard.readFromFile(@txdata, fileSize) Socket.txTCP(id, @txdata, fileSize) else ' send the file in a bunch of packets repeat SDCard.readFromFile(@txdata, MAX_PACKET_SIZE) Socket.txTCP(id, @txdata, MAX_PACKET_SIZE) fileSize -= MAX_PACKET_SIZE ' once the remaining fileSize is less then the max packet size, just send that remaining bit and quit the loop if fileSize < MAX_PACKET_SIZE and fileSize > 0 SDCard.readFromFile(@txdata, fileSize) Socket.txTCP(id, @txdata, fileSize) quit ' Bailout if(i++ > 1_000_000) WriteError(id) quit SDCard.closeFile SDCard.changeDirectory(@approot) return PRI WriteError(id) | headerOffset '' Simple 404 error pst.str(string(13, "Write 404 Error",13 )) headerOffset := Response.BuildHeader(Request.GetExtension(id), 404, false) Socket.txTCP(id, @txdata, headerOffset) return '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '' Write data to a buffer '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' PRI PushDynamicContent(content) ' Write the content to memory ' and update the pointer bytemove(dynamicContentPtr, content, strsize(content)) dynamicContentPtr := dynamicContentPtr + strsize(content) return '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '' directory and file handlers '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' PRI ChangeDirectory(id) | i, found 'Handle directory structure for this Request if(Request.GetDepth(id) > 1) repeat i from 0 to Request.GetDepth(id)-2 'Return if the directory is not found ifnot(FileExists(Request.GetPathNode(id, i))) return false found := SDCard.changeDirectory(Request.GetPathNode(id, i)) return true PRI FileExists(fileToCompare) | filenamePtr 'Start file find at the top of the list SDCard.startFindFile 'Verify that the file exists repeat while filenamePtr <> 0 filenamePtr := SDCard.nextFile if(str.MatchPattern(filenamePtr, fileToCompare, 0, false ) == 0 ) return true return false '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '' Time Methods and Formats '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' PRI GetTime(id) | ptr, headerOffset ptr := @udpdata FillHttpDate bytemove(ptr, string("<p>"),3) ptr += 3 bytemove(ptr, @httpDate, strsize(@httpDate)) ptr += strsize(@httpDate) bytemove(ptr, string("</p>"),4) ptr += 3 headerOffset := Response.BuildHeader(Request.GetExtension(id), 200, false) Socket.txTCP(id, @txdata, headerOffset) StringSend(id, @udpdata) bytefill(@udpdata, 0, TEMP_BUFFER) return PRI FillTime | ptr, num 'ToString(integerToConvert, destinationPointer) '00/00/0000 00:00:00 ptr := @time rtc.readTime FillTimeHelper(rtc.clockMonth, ptr) ptr += 3 FillTimeHelper(rtc.clockDate, ptr) ptr += 3 FillTimeHelper(rtc.clockYear, ptr) ptr += 5 FillTimeHelper(rtc.clockHour , ptr) ptr += 3 FillTimeHelper(rtc.clockMinute , ptr) ptr += 3 FillTimeHelper(rtc.clockSecond, ptr) return @time PRI FillHttpDate | ptr, num, temp 'ToString(integerToConvert, destinationPointer) 'Wed, 01 Feb 2000 01:00:00 GMT ptr := @httpDate rtc.readTime temp := rtc.getDayString bytemove(ptr, temp, strsize(temp)) ptr += strsize(temp) + 2 FillTimeHelper(rtc.clockDate, ptr) ptr += 3 temp := rtc.getMonthString bytemove(ptr, temp, strsize(temp)) ptr += strsize(temp) + 1 FillTimeHelper(rtc.clockYear, ptr) ptr += 5 FillTimeHelper(rtc.clockHour , ptr) ptr += 3 FillTimeHelper(rtc.clockMinute , ptr) ptr += 3 FillTimeHelper(rtc.clockSecond, ptr) return @httpDate PRI FillTimeHelper(number, ptr) | offset offset := 0 if(number < 10) offset := 1 str.ToString(@number, @tempNum) bytemove(ptr+offset, @tempNum, strsize(@tempNum)) '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '' SDCard Logger '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' PRI AppendLog(logToAppend) '' logToAppend: Pointer to a string of test we'd like to log SDCard.changeDirectory(@approot) if(FileExists(@logfile)) SDCard.openFile(@logfile, "A") else SDCard.newFile(@logfile) SDCard.writeData(string(13,10,"----- Start "),14) SDCard.writeData(FillTime, 19) SDCard.writeData(string(" -----"),6) SDCard.writeData(@crlf_crlf, 2) SDCard.writeData(logToAppend, strsize(logToAppend)) SDCard.writeData(@crlf_crlf, 2) SDCard.writeData(string("----- End "),10) SDCard.writeData(FillTime, 19) SDCard.writeData(string(" -----"),6) SDCard.writeData(@crlf_crlf, 2) SDCard.closeFile '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '' Memory Management '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' PRI Set(DestAddress, SrcAddress, Count) bytemove(DestAddress, SrcAddress, Count) bytefill(DestAddress+Count, $0, 1) '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '' Socekt helpers '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' PRI GetTcpSocketMask(id) return id & tcpMask PRI DecodeId(value) | tmp if(%0001 & value) return 0 if(%0010 & value) return 1 if(%0100 & value) return 2 if(%1000 & value) return 3 return -1 PRI QueueSocket(id) | tmp if(fifoSocketDepth > 4) return false tmp := |< id 'Unique check ifnot(IsUnique(tmp)) return false tmp <<= (fifoSocketDepth++) * 8 fifoSocket |= tmp return true PRI IsUnique(encodedId) | tmp tmp := encodedId & $0F repeat 4 if(encodedId & fifoSocket) return false encodedId <<= 8 return true PRI DequeueSocket | tmp if(fifoSocketDepth == 0) return -2 repeat until not lockset(debugSemId) tmp := fifoSocket & $0F fifoSocket >>= 8 fifoSocketDepth-- lockclr(debugSemId) return DecodeId(tmp) PRI ResetSocket(id) Socket.Disconnect(id) Socket.Close(id) PRI IsolateTcpSocketById(id) | tmp tmp := |< id tcpMask &= tmp PRI SetTcpSocketMaskById(id, state) | tmp '' The tcpMask contains the socket the the StatusMonitor monitors tmp := |< id if(state == 1) tcpMask |= tmp else tmp := !tmp tcpMask &= tmp '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '' W5100 Helper methods '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' PRI GetCommandRegisterAddress(id) return Socket#_S0_CR + (id * $0100) PRI GetStatusRegisterAddress(id) return Socket#_S0_SR + (id * $0100) PRI SetMac(_firstOctet) Socket.WriteMACaddress(true, _firstOctet) return PRI SetGateway(_firstOctet) Socket.WriteGatewayAddress(true, _firstOctet) return PRI SetSubnet(_firstOctet) Socket.WriteSubnetMask(true, _firstOctet) return PRI SetIP(_firstOctet) Socket.WriteIPAddress(true, _firstOctet) return PRI StringSend(id, _dataPtr) Socket.txTCP(id, _dataPtr, strsize(_dataPtr)) return PRI SendChar(id, _dataPtr) Socket.txTCP(id, _dataPtr, 1) return PRI SendChars(id, _dataPtr, _length) Socket.txTCP(id, _dataPtr, _length) return PRI InitializeSocket(id) Socket.Initialize(id, TCP_PROTOCOL, port, remotePort, @remoteIp) return PRI InitializeSocketForEmail(id) Socket.Initialize(id, TCP_PROTOCOL, port, emailPort, @emailIp) return PRI InitializeUPDSocket(id) Socket.Initialize(id, UDP_PROTOCOL, uport, remotePort, @remoteIp) return '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '' Debug/Display Methods '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' PRI QueueDump '' Display socket IDs in the queue '' ie 00000401 -> socket Zero is next to pop off pst.str(string("FIFO[")) pst.dec(fifoSocketDepth) pst.str(string("] ")) pst.hex(fifoSocket, 8) PRI StackDump | clsd, open, lstn, estb, clwt, clng, id, ulst '' This method is purely for debugging '' It displays the status of all socket registers repeat until not lockset(debugSemId) clsd := closedState open := openState lstn := listenState estb := establishedState clwt := closeWaitState clng := closingState ulst := udpListen lockclr(debugSemId) pst.char(13) repeat id from 3 to 0 pst.dec(id) pst.str(string("-")) pst.hex(status[id], 2) pst.str(string(" ")) pause(1) pst.str(string(13,"clsd open lstn estb clwt clng udps", 13)) pst.bin(clsd, 4) pst.str(string("-")) pst.bin(open, 4) pst.str(string("-")) pst.bin(lstn, 4) pst.str(string("-")) pst.bin(estb, 4) pst.str(string("-")) pst.bin(clwt, 4) pst.str(string("-")) pst.bin(clng, 4) pst.str(string("-")) pst.bin(ulst, 4) pst.char(13) PRI HeaderLine1(id) | i pst.str(Request.GetMethod(id)) pst.char($20) i := 0 repeat Request.GetDepth(id) pst.char($2F) pst.str(Request.GetPathNode(id, i++)) PRI Pause(Duration) waitcnt(((clkfreq / 1_000 * Duration - 3932) #> 381) + cnt) return PRI StatusMonitor | id, tmp, value '' StatusMonitor is the heartbeat of the project '' Here we monitor the state of the Wiznet 5100's 4 sockets repeat Socket.GetStatus32(@status[0]) ' Encode status register states repeat until not lockset(debugSemId) closedState := openState := listenState := establishedState := { } closeWaitState := closingState := 0 repeat id from 0 to 3 case(status[id]) $00: closedState |= |< id closedState &= tcpMask $13: openState |= |< id openState &= tcpMask $14: listenState |= |< id listenState &= tcpMask $17: establishedState |= |< id establishedState &= tcpMask $18,$1A,$1B: closingState |= |< id closingState &= tcpMask $1C: closeWaitState |= |< id closeWaitState &= tcpMask $1D: closingState |= |< id closingState &= tcpMask $22: udpListen |= |< id udpListen &= udpMask if(lastEstblState <> establishedState) value := establishedState repeat while value > 0 tmp := DecodeId(value) if(tmp > -1) QueueSocket(tmp) tmp := |< tmp tmp := !tmp value &= tmp lastEstblState := establishedState lockclr(debugSemId) ' Initialize a closed socket if(closedState > 0) id := DecodeId(closedState) if(id > -1) InitializeSocket(id & tcpMask) 'Start a listener on an initialized/open socket if(openState > 0) id := DecodeId(openState) if(id > -1) Socket.Listen(id & tcpMask) ' Close the socket if the status is close/wait ' response processor should close the socket with disconnect ' there could be a timeout so we have a forced close. ' TODO: CCheck for a port that gets stuck in a closing state 'if(closeWaitState > 0) 'id := DecodeId(closeWaitState) 'if(id > -1) 'Socket.Close(id & tcpMask) 'pause(100) return PRI SONG repeat if lcd.init(LCD_PIN, LCD_BAUD, LCD_LINES) lcd.cls ' start lcd lcd.cursor(0) pause (250) ' curs lcd.str(string(128,"Happy Birthday", 13, "to Mutha")) waitcnt(clkfreq*3 + cnt) lcd.cls lcd.cursor(0) pause (250) lcd.str(string(128,"Happy Birthday", 13, "to Muthaaaa!!!!")) waitcnt(clkfreq*3 + cnt) lcd.cls lcd.cursor(0) pause (250) ' curs lcd.str(string(128,"Happy Birthday")) waitcnt(clkfreq*3 + cnt) lcd.cls lcd.cursor(0) pause (250) ' curs lcd.str(string(128,"to", 13, "Mu--thaaaaa!!!!")) waitcnt(clkfreq*3 + cnt) lcd.cls lcd.cursor(0) pause (250) ' curs lcd.str(string(128,"Haaaappy", 13, "Biiiirthdayyyyy")) waitcnt(clkfreq*3 + cnt) lcd.cls lcd.cursor(0) pause (250) ' curs lcd.str(string(128,"toooooooo", 13, "MUTHAAAA!!!!")) waitcnt(clkfreq*3 + cnt) lcd.cls DAT approot byte "\", 0 defaultpage byte "index.htm", 0 logfile byte "log.txt", 0 'binFile byte "filename.bin", 0 FS byte "/", 0 fn byte "filename=", 0 doublequote byte $22, 0 crlf byte 13, 10, 0 crlf_crlf byte 13, 10, 13, 10, 0 uploadfile byte $0[12], 0 uploadfolder byte "uploads", 0 tempNum byte "0000",0 multipart byte "Content-Type: multipart/form-data; boundary=",0 boundary byte $2D, $2D boundary1 byte $0[64] 'loadme file "TogglePin0.binary" {{ ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ TERMS OF USE: MIT License │ ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ │is furnished to do so, subject to the following conditions: │ │ │ │The above copyright notice and this permission notice shall be included in all copies or substantial ions of the Software.│ │ │ │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ }}I'm not sure... This section of code is looking for a file named servo.htm. Do you have a file name servo.htm on the SD card?
if(strcomp(Request.GetName(id), string("servo")))PRI Dispatcher2(id) ''do some processing before sending the response if(strcomp(Request.GetName(id), string("servo"))) Demo (id) StaticFileHandler(id) returnThis is a bug in your code as posted on the forum.
Makes perfect sense now. I'll probably get to this over the weekend. Sounds like I'll just create another web page called servo.htm, and for now call it good. Later on I'll figure out how to add multiple bottons on one page controlling multiple functions..... Wanted to thank you either way.