The Netduino forums have been replaced by new forums at community.wildernesslabs.co.
This site has been preserved for archival purposes only
and the ability to make new accounts or posts has been turned off.
Webserver on NetduinoPlus + (wired or wireless) library
EDIT: The library has been upgraded to provide web server functionality with either TCP Socket or WiFly shield back-ends. Hence the project can run with either a NetduinoPlus with wired ethernet connectivity, or with a NetduinoPlus and a SFE WiFly shield.
Just like other community members, I wanted to start my home-automation project, namely a web-enabled aquarium controller. One pre-requisite being a wireless connectivity between the aquarium controller and the Wi-Fi router, I started with the attached WiFly driver. Now this small project tests the WiFly driver via an application that turns a Netduino board onto a security Honey Pot: that is a web-application, exposed to the Internet, which emulates the (authentication screen of the) administration console of my Wi-FI router. This Honey Pot is meant to attract hackers trying to break into this pseudo-router, capturing at the same time the username & passwords in use.
Why this odd project? Because my aquarium is meant to be accessible via the Internet, so I wanted to assess the potential for attacks on the web server, and at the same time, test the driver in a fun way. The attached VS-solution contains both the driver and the honey pot, for a Netduino-Plus (I know, it already has an Ethernet plug, but I wanted to start easy before moving everything to my Netduino-Mini, which is the final target).
In the current setting, the only requirements are: a Netduino-Plus with a WiFly shield on-top, a micro-SD for the storage of the log files, and a WiFI router with port-forwarding capability (they all do I would assume).
The steps to follow to build and install the Honey-Pot:
In "Program.cs", use the module.Open version that fully specifies the router SSID, passphrase, and port number on which the module will be listening, build and deploy
Run the project and verify (in VS log window) that your module correctly joins the router; take note of the DHCP-assigned IP address (192.168.1.3 in the examples below)
Test the application locally, from a web-browser. For example: http://192.168.1.3/time should return the default date-time
View the logs with http://192.168.1.3/log.csv should open an empty Excel spreadsheet (if your SD Card is disfunctioning or absent, this will be indicated there)
Configure your router so that external HTTP request on port (say, 80) are forwarded to your HoneyPot
Test your HoneyPot from the Internet, using the Internet-facing your IP address. Note that none of the local capabilities (time, log.csv, clear) should work from the Internet!
Indeed you can modify Program.cs to change the personae of your Honey-Pot. The one that I currently use is my Netgear router; you can change to whatever you feel for!
PS: The whole idea was to test the Http Library, so if you happen to using it for your own needs and had improvements/bug fixes, please let me know!
Attempt to access the Netduino HoneyPot from the Internet (after http://86.68.168.135)
This is how this attempt is logged (notice the username in column C and password in column D) (http://192.168.1.3/log.csv):
Here is how you select between TCP Socket or WiFly implementations:
Nice project JP! The library is looking great!!
I tested the latest code and for me it looks like the configuration code works as the WiFly will join my wireless network while using the version of module.Open that specifies the ssid, etc. At that point I see P104 flashing green slowly and can ping the WiFly shield at the ip listed in my router's device list.
One thing I'm having trouble doing is seeing the result of the getIp() function - it always returns an empty string. I traced through the code a bit and I find that throught the code execution line 237 of WiFly.cs never returns true [ while ((ReadRegister(WiflyRegister.LSR) & 0x01) > 0) ]. The output I see in the VS debugger also looks a little slim - I expect it should be showing more data from the WiFly shield itself. Here's what I get:
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
#### Exception System.IO.IOException - CLR_E_INVALID_DRIVER (1) ####
#### Message:
#### Microsoft.SPOT.IO.NativeIO::GetAttributes [IP: 0000] ####
#### System.IO.Directory::Exists [IP: 0015] ####
#### Log::.ctor [IP: 001e] ####
#### Program::Main [IP: 000e] ####
A first chance exception of type 'System.IO.IOException' occurred in Microsoft.SPOT.IO.dll
#### Exception System.IO.IOException - CLR_E_INVALID_DRIVER (1) ####
#### Message:
#### Microsoft.SPOT.IO.NativeIO::CreateDirectory [IP: 0000] ####
#### System.IO.Directory::CreateDirectory [IP: 000a] ####
#### Log::.ctor [IP: 0029] ####
#### Program::Main [IP: 000e] ####
A first chance exception of type 'System.IO.IOException' occurred in Microsoft.SPOT.IO.dll
Unexpected error: no SD Card in slot, or SD reader unreachable
Listening on
The errors related to not having an SD card appear properly trapped so I don't think that's an issue. I'll keep digging through the code but everything else seems fine, not sure what this could be.
The output I see in the VS debugger also looks a little slim - I expect it should be showing more data from the WiFly shield itself.
The first problem with the SD Card is real; however the exception does not prevent you from moving on (the web-auth part of the application keeps working, but without logging to the SD). Lets first concentrate on the WiFly problem.
The output that you have is typical of an incorrect communication between the SPI-UART and the module, which can be caused by at least two factors:
The oscillator value is incorrect: the default value (assumed by the driver) is 14MHz. You want to try the other one with "module.Type = WiFly.DeviceType.crystal_12_288_MHz;" before module.Open().
However I noticed a bug in WiFly.cs. For a crystal value of 12.288MHz, line 111 should read: WriteRegister(WiflyRegister.DLL, 21), instead of WriteRegister(WiflyRegister.DLL, 83) -- 83 is the value for 9600 bauds, which I forgot to update for 38400, did not need to as I run a 14MHz quartz.
Maybe just this change alone will make it work for you (I have updated the zip file as well)
If not, the baudrate values programmed to the DLL register are incorrect (see WiFly.cs lines 111 and 114, where I show the result of my own calculation). The combination that I use (DLL value to 24 matches baudrate 38400) are correct with my own quartz, but maybe you have an hybrid value.
I had this quartz problem at first: the WiFly Shield schematic that I have (v17 dated 9/1/2010) shows a quartz value of 14.7456MHz. I used this value to calculate the DLL register value, (14.7456*1024*1024)/(baudrate*16) yielding (for 38400 bauds) 25.165 that I rounded to 25. But this was causing communication problems, until I decided to try with 14.0MHz instead which gives 23.89, which I rounded to 24, and it worked. Hence the values that I provide, line 114, are now based upon this hypothesis of 14.0MHz. But maybe your actual value is alll different! So I would try 14.7456MHz first, or else find a way to have the right data, maybe from Roving Networks (their support is quite good in my experience). If you believe that you have a 12.288MHz quartz, try using the values of 20 or 21 at line 111 (again, the value of 83 is incorrect)
If all goes well you should have the following (make sure you use TraceCommands as below)
Thanks JP, looks like this is a UART problem so that narrows things down. I tried values between 20 and 25 for the DLL register without luck. Your comments about finding the correct quartz value make sense, I'll contact Roving and find out my exact osciallator value to eliminate that variable.
One thing I noticed in testing is that when SendCommand runs I see P105 flash red briefly. Should it flash green when things are working properly?
James
...I'll contact Roving and find out my exact osciallator value to eliminate that variable.
One thing I noticed in testing is that when SendCommand runs I see P105 flash red briefly. Should it flash green when things are working properly?
I misled you, you want to ask Sparkfun about the oscillator, as they are the maker of the shield. SFE are the one having put the SC16IS750 in front of the WiFly GSX module. I have attached its datasheet, see section 7.8 for the formula that I used to calculate the divisor value.
. As for the PIO5 RED led: I see it flash when characters are sent or received; otherwise you should have ony PIO5 flashing GREEN every 1.5 s.
Hi Guys,
First off, thanks JP for writing a driver for the WiFly shield! It looks much cleaner and complete than my attempt.
I also seem to be having an issue with the baud rate. I am using a Netduino and my wifly shield has a 14.7456 MHz crystal on it. Whenever the code is run using the baud rate set to 38400 "WriteRegister(WiflyRegister.DLL, 24); " and data is received from the shield the data is a bunch of strange characters. However, when I change the baud rate to 9600 "WriteRegister(WiflyRegister.DLL, 0x60); " and data is received from the shield it is legible and returns what is expected. At the 9600 baud rate it seems to miss some characters as it is receiving them. For example when it calls getIP() it should return 192.168.1.143, but instead it might return 192.18.1.143. I think the RN-131C has a default baud rate of 9600 and when the baud rate for the SPI is also set to that it seems to function properly. Could it possibly be that the the baud rate on the WiFly module is not being saved or being set correctly when the SPI is first set to 38400?
Thanks for you help,
Adam
Okay I got it to work! It was a simple issue with the baud rate. The first time the WiFly shield is hooked up it has a default baud rate of 9600, so by setting the SPI baud rate to 9600 the first time the program ran allowed it to communicate with the WiFly shield and could then tell the WiFly shield to run at 38400. Every time after that I have been able to set the SPI baud rate to 38400 and it has been working correctly and all of the data printed to the output window in Visual Studio looks correct without any missing letters.
Thanks again for writing this driver!
-Adam
Okay I got it to work! It was a simple issue with the baud rate. The first time the WiFly shield is hooked up it has a default baud rate of 9600, so by setting the SPI baud rate to 9600 the first time the program ran allowed it to communicate with the WiFly shield and could then tell the WiFly shield to run at 38400. Every time after that I have been able to set the SPI baud rate to 38400 and it has been working correctly and all of the data printed to the output window in Visual Studio looks correct without any missing letters.
Thanks again for writing this driver!
-Adam
As a bonus, here is an icon that you can use. It is best rendered with Chrome; Ok on Firefox; however this icon doesn't render with IE v8, could it be that IE doesn't accept JPG icons?
while (true)
{
HttpContext context = module.Connect();
String target = context.Request.Path;
if (target == "/favicon.ico")
{
context.Response.ContentType = "image/jpg";
context.Response.LastModified = "Mon, 27 Jan 2011 08:45:19 GMT";
context.Response.ContentLength = Resources.icon1.Length;
context.Response.BinaryWrite(Resources.icon1);
context.Response.Close();
continue;
}
// Other cases...
}
Hi,
trying to use the code with a regular Netduino. Getting "Failed to init SPI<->UART chip". Remember I had the WiFly bricked or mis-configured a few months ago. Is there a way to totally reset the WiFly or the chip, programmatically?
Cheers,
tamberg
trying to use the code with a regular Netduino. Getting "Failed to init SPI<->UART chip". Remember I had the WiFly bricked or mis-configured a few months ago. Is there a way to totally reset the WiFly or the chip, programmatically?
Cheers,
tamberg
As shown on the attached schematics, the WiFly shield from SFE is essentially an assembly of two chips: the WiFly GSX chip proper from Roving Networks, and the SC16IS750 chip from NXP, which function is to provide a bufferized access to the GSX, via SPI. The benefit of this SC16IS750 chip is obviously to avoid having to use a COM port (from Netduino standpoint) which number is limited. Arguably you could also chose to drive the GSX chip directly via its native UART interface, and this is precisely what you would do with the WiFly breakout from SFE(no SC16IS750). It's important to keep these two chips in mind for your diagnostic.
The infamous "Failed to init SPI<->UART chip" only means that the driver cannot readback from the scratchpad register of the SC16IS750 an arbitrary value that was written there just before. There are two possible reasons for that:
A failure during an SPI WriteRead operation (that is the first WriteRead occuring in the driver's code)
A defect on the SC16IS750 - scratchpad not functionning
At this point you have not passed the first gate and this error occurs regardless the state of the WiFly GSX.
In my own case I have hit this same error after upgrading my NetduinoPlus to the new firmware version 4.1.1 alpha-5. By downgrading back to firmware 4.1.0.5 the problem disappeared and everything worked as before. So I assumed that the problem did not come from the scratchpad, but was more probably a problem with SPI WriteRead on SPI1. Chris Walker has been informed of this problem and is trying to reproduce.
Obviously try downgrading to 4.1.0.5 if you happen to be running firmware 4.1.1 alpha-5, but this may not be your problem.
If so that would be a SC16IS750 malfunction. Reading the datasheet there is not much state there, all registers including the scratchpad are volatile (not stored in EEPROM), and hence are reset on power-up.
Does this help?
Thanks JP, looks like this is a UART problem so that narrows things down.
One key characteristic of the SFE WiFly shield is that there are two configurations that you must care about:
Configuration of the baudrate on the SC16IS750.
Configuration of the baudrate on the WiFly-GSX
The first configuration is dependent upon the frequency of the oscillator, as explained above, and the second configuration obviously needs to be in sync with the first one.
Here is a sequence (requiring 3 deployments in sequence) that I can suggest if you have UART problems. Assuming that you have a 14MHz oscillator:
Try 9600 bauds, as this is the default: write 96 to the WiflyRegister.DLL register, and make sure to send the command "set uart baud 9600"; build, deploy and run
At this point you should be able to send commands to the WiFly; however this 9600 baud rate is too low for http
On a second pass, send the command "set uart baud 19200", and make sure that this setting is saved to the EEROM (via the command "save"); build, deploy and run
Finally, configure the SC16IS750 for 19200 bauds, by writing 48 to WiflyRegister.DLL; build, deploy and run
After the WiFly reboots, you should be ready to go, at 19200 bauds
Indeed, change the values above (96 and 48) in accordance to your oscillator's frequency (i.e. 83 and 42 for 12.288 MHz)
I've been caught myself many times, and believed that my WiFly was disfunctioning, but that was because the SC16IS750 was programmed at a baudrate different from the one accepted by the WiFly UART. You may just encounter the exact same problem.
Good luck!
PS: a somehow unrelated topic: I upgraded the HttpLibrary (http://forums.netdui...ndpost__p__7870) to provide support for SFE WiFly shield, as well as for the wired Ethernet which comes with the NetduinoPlus
Any chance that the code in the .ZIP file has a bug? Looks like the latest download (I grabbed it yesterday afternoon) calls getip() before it calls Listen(). Is that correct? Also looks like you might have streamlined the code a little since this post (e.g., looks like Program.cs no longer makes a call to Open()?). Is that the case?
Thanks. Cool library. Can't wait to get it working.
Any chance that the code in the .ZIP file has a bug? Looks like the latest download (I grabbed it yesterday afternoon) calls getip() before it calls Listen(). Is that correct? Also looks like you might have streamlined the code a little since this post (e.g., looks like Program.cs no longer makes a call to Open()?). Is that the case?
Thanks. Cool library. Can't wait to get it working.
Yes this is normal, as the IP is established during the intialization of the device (note that the IP would display only with the WiFly implementation; I don't know if you use N+ socket or WiFly); then after it can be listened to. Now if you really want the latest version of the library (which I have changed ever since the zip you have downloaded), its here. I have just not taken the time to update the one from this project. And yes, Open is not necessary anymore, depending on how the device was configured before: with the WiFly, no need to call Open if the device can rejoin the router on reboot; i.e. if Open(ssid,passphrase) has be called previously, those params are save to the WiFly EEPROM. Let me know if you have issues, I'd be glad to help, if I can
JP
Hope this helps someone...I got the project working using a straight-up Netduino (not a Netduino Plus) and a WiFly RN-131G board (the full-on shield, not the GSX breakout board model). Biggest trick? The Netduino can't power the WiFly board via the USB cable. This thread was *very* helpful in explaining the power problem: http://www.tinyclr.com/forum/1/294/
In short, use the AC power, and you should be good to go. I did change the references in the project to use the SecretLabs.NETMF.Hardware.Netduino namespace/DLL instead of the SecretLabs.NETMF.Hardware.NetduinoPlus, but, I think, the code should run mostly as-is.
Yes this is normal, as the IP is established during the intialization of the device (note that the IP would display only with the WiFly implementation; I don't know if you use N+ socket or WiFly); then after it can be listened to. Now if you really want the latest version of the library (which I have changed ever since the zip you have downloaded), its here. I have just not taken the time to update the one from this project. And yes, Open is not necessary anymore, depending on how the device was configured before: with the WiFly, no need to call Open if the device can rejoin the router on reboot; i.e. if Open(ssid,passphrase) has be called previously, those params are save to the WiFly EEPROM. Let me know if you have issues, I'd be glad to help, if I can
JP
Thanks for the reply. I *think* I have things working (see my other post below). Big discovery was related to power supply.
Quiche31, I might be modifying or adding on to your library. See what I am trying to do here:
http://forums.netdui...socket-example/
I realize that it is going to be very identical to a simple web server - basically the same except adding in the WebSockets handshake and handling send and receive a little bit differently.
I realize that it is going to be very identical to a simple web server - basically the same except adding in the WebSockets handshake and handling send and receive a little bit differently.
Great! By all means, please do so. You are stretching the enveloppe with the WiFly, by doing socket-level communication (is it for the motorcycle?); please let us know how it goes!
I thought about that. I am going to be wired for my project and for now that will be easier to work with.
I need to have a persistent socket open to detect if the NetDuino sends data back. So it won't be much different than the Listen function. I have to move the while(true) inside the using. It has to be while(socket is not closed or timeout not reached) instead. The send would need to identify which socket to send to. Finally the WebSocket's handshake before the while loop. I have a rough idea of what needs to happen.
Yes. If I don't get it to work I can always use your web server code and host the webpage on the netduino. However, knowing that the Netduino is slower at updating the LEDs than the Arduino, even when using fluent interop, I want to limit what interrupts the animations. I am almost tempted to have my extra Arcuino be a dedicated LED driver and the Netduino do the web hosting and grab animation info from it's SD card. It will depend on how bad the it gets as I add this stuff in.
So for now I am going to just try the webserver method and see how it affects the animations. Then I will try the WebSockets. If that isn't satisfactory then I will go the dedicated LED driver route.