Webduino - webserver library [PORTED]

@kennethlimcp,

Thanks ! Will review this.

2 Likes

Has anyone gotten the basics of this server working? @mdma are you back from vacay yet?

Hi James
Did you get the ā€œEpic Failā€ message that I was reporting previously? As a novice to the spark but fairly experienced in networking I wonder if it is a problem with the router set-up. I have pored over the code and cannot find reference to the ip and mac addresses of the spark, I initially expected to have to manually input them as I have had to do so with an ethernet shield that I have successfully set up with a Uno and temperature sensor to serve a basic website that can be accessed remotely. I suspect this is not necessary with the spark as I think that it is likely that the WiFi module will hold those details in itā€™s own memory. So far nobody has provided any clarification on this.
I have also asked if the spark can remember multiple networks and automatically connect to the best signal. Again no response.
I am not allowing it to bother me as the spark is so recent, I think it is incredible how far the team have come in two years. As the community builds and grows there will be a lot more questions asked and answered.
Maybe we will eventually get to the bottom of it.
One other possibility that springs to mind is that I am using new black sparks with the cc3000 update. Perhaps the server is not compatible with the new spark / update.
Regards

Hi @bevangg,

Yeah Iā€™m not letting it get to me, I ordered a couple of @kennethlimcp Fram/SD shields so Iā€™m hoping by the time those arrive some spark server issues will be resolved.

Thanks for the note though.

Hi @bevangg and @james211

Yes the TI CC3000 can remember up to 7 sets of WiFi SSID/Credentials and will automatically connect to any one of them. The TI module always uses DHCP so you donā€™t have to set any thing manually.

The new black PCB Spark Cores are shipping from the factory with ā€œdeep updateā€ already installed but the server should be compatible.

I just tried the webserver library in the web IDE. I made a new app, added the library webserver to it, and added the Web_HelloWorld.ino file to my main sketch. It automatically had added a #include "WebServer/WebServer.h" so I had two of those and you only need one. I also got rid of the default empty loop() and setup() functions since the app example provides those.

This worked fine for me on a core that has deep update! I had to discover the local IP address of the core which I did using a serial display I have hooked up to that core, but I was able to surf to it and get the ā€œHello, World!ā€ message on a web browser on the same subnet (thatā€™s important too).

Important points:

  • Discover the correct local IP address for your core
  • Make sure your computer with the browser is on the same subnet
  • Surf to http://<core local address> where <core local address> is something like 10.0.0.5 or 192.168.0.2 depending on your network.

Hi bko
Thanks for the reply
Could I ask you how does one add a new network to the CC3000? I have used the mobile connection method and could see no way of doing this.
As for the webserver setup it sounds as though I have done exactly what you have done and it still does not work properly. Can the spark use a fixed ip address as otherwise remote access is going to be tricky the way I have done it before?
I will look at it again in case I missed something.
Regards

Hi @bevangg

You can add networks to the CC3000 using either USB setup or via the iOS/Android app. Just put the core listening mode (flashing blue) and use the app to connect from the network you want add.

If you want your Spark core to have a fixed local IP address, configure your router to always give it the same address via DHCP. Most routers can do this based on the MAC address of the core.

One more point I forgot to mention: I also used Fing on iOS to scan for the core (it reports that the MAC address belongs to TI) and then scanned for ports and port 80 for http showed up. So if you have network/port scanner, it will likely find your core.

2 Likes

Hi bko
Thanks for the info, I will try over the weekend.
I got the IP for the spark over serial with this code:

    Serial.print("SSID: ");
    Serial.println(Network.SSID());
    Serial.print("Core IP: ");
    Serial.println(Network.localIP());    
    Serial.print("Gateway: ");
    Serial.println(Network.gatewayIP());
    Serial.print("Mask: ");
    Serial.println(Network.subnetMask());
    Serial.print("WiFi RSSI: ");
    Serial.println(Network.RSSI());

I was wondering if there is a way of getting the stored networks from the CC3000?
I have been using wireshark to analyse network packets, it gives ips, macs ports etc, I will see if that gives me any clues to what is wrong asap.
Thanks for pointing me in the right direction
Regards

Hi @bevangg

There is not a way to read out the WiFi SSID/Credentials from the TI part due I think to security concerns. There was a change in the Spark firmware to save encrypted SSID/Credentials into external flash so that the deep update process can restore them afterward since they get clobbered by the update. I am not sure that helps you since they are stored encrypted.

You can clear all the SSID/Credentials by holding the mode button for 10 seconds during a reset.

3 Likes

the hello world example works fine (with the change in include).
next I tried the web-demo and I get a compilation error (also changed the include statement)

What am I doing wrong?
kw

==============
In file included from ../inc/spark_wiring.h:30:0,
from ../inc/application.h:29,
from web_demo.cpp:2:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
In file included from web_demo.cpp:24:0:
WebServer/WebServer.h: In member function 'bool WebServer::readPOSTparam(char*, int, char*, int)':
WebServer/WebServer.h:1044:39: warning: narrowing conversion of 'ch1' from 'int' to 'char' inside { } [-Wnarrowing]
char hex[3] = { ch1, ch2, '\x0' };
^
WebServer/WebServer.h:1044:39: warning: narrowing conversion of 'ch2' from 'int' to 'char' inside { } [-Wnarrowing]
web_demo.cpp: In function 'void outputPins(WebServer&, WebServer::ConnectionType, bool)':
web_demo.cpp:106:30: error: 'itoa' was not declared in this scope
server << "Digital " << i << ": ";
^
make: *** [web_demo.o] Error 1
=============

itoa(....) is not defined, just replaced it with
pinName[0] = 'd0';
pinName[1] = 'd1';
pinName[2] = 'd2';
pinName[3] = 'd3';
pinName[4] = 'd4';
pinName[5] = 'd5';
pinName[6] = 'd6';
pinName[7] = 'd7';
pinName[8] = 'd8';

works fine

@mdma Thanks a ton for porting over this library!! I have it up and running and have tested with the samples. Iā€™m struggling a bit with trying to figure out how to support a PUT http request. I canā€™t seem to find any examples on the internet with Webduino. I see the functions for parsing out the data for a POST request and I know with a PUT the data is in the message body. I canā€™t find how to get access to the message body content from webduino. Do you have any suggestions?

1 Like

Hi @kw123

It is defined over in the String class as a helper there. You can use it by including this in your sketch:

extern char* itoa(int a, char* buffer, unsigned char radix);

By the way, itoa is not part of ANSI C and although provided by lots of libraries, it is not a required function.

2 Likes

thanks, that seems to work.
here my next questionā€¦

I am using web-parms.ino,
seems to work fine as is and I can change the return strings in PUT GET and also write to serialā€¦
BUT I failed to do something like:

while (server.readPOSTparam(name, NAMELEN, value, VALUELEN))
    {
      int dot1 = value.indexOf('.');    <<<<<+++++ this throws an error
      server.print(name);
      server.print(name);
      server.printP(Parsed_item_separator);
      server.print(value);
      server.printP(Tail_end);
    }


error message:
WebServer/WebServer.h:1044:39: warning: narrowing conversion of 'ch2' from 'int' to 'char' inside { } [-Wnarrowing]
web_parms.cpp: In function 'void parsedCmd(WebServer&, WebServer::ConnectionType, char*, bool)':
web_parms.cpp:198:24: error: request for member 'indexOf' in 'value', which is of non-class type 'char [32]'

what class type is value, is it not a character string?

Here is what I would like to do:
receive a string from a client, parse the string, and write / read the pins depending on the text received. should I be doing this in void loop() {}?

any help appreciatedā€¦
KW

Hi @kw123

I think you are confusing C style char array strings with the Arduino String class object, which is whole different animal.

1 Like

got that, but how to I get the pointer value into a regular character string that I deal with and then later back into a pointer to send it back ā€¦
I know this is likely a basic question, but I am not ā€œfluentā€ in cā€¦

kw

still very proficient in fortan and assembler, pl1 and now 90% python.

I am still not sure what all Parsed_item_separator() does in this case since you then print the whole value.

Try this C instead of the String method:

char *idx = strchr(value,'.');  //pointer to dot in memory
int dot1 = (int)(idx - value);  //subtract pointers to get the index value[dot1] == '.'

This is probably not the best way to do what you are trying to do, but you would need to post more code to get more help.

1 Like

the code posted is from the original web-parks.ino file. just added my 1 line to it . donā€™t need the old code when I am done.

here is what I like to do:

(A) write a value to pin x with :
curl -d ā€œwrite=d1.15ā€ "http://192.168.1.204/parsed.html"
string value points to here.: "d1.15"
parse that string with separator "."
use the elements to determine which pin is requested (here d1) and write ā€œ15ā€ to pin d1.

the other would be:

(B) read value from pin x and send it back with:
curl -d ā€œread=d1ā€ "http://192.168.1.204/parsed.html"
get pin name (d1) as before and read current value of pin and send value back using pointer ā€œvalueā€ with
server.print(value);

HI @kw123

First off, a digital pin like D1 can only HIGH or LOW with digitalWrite(), it canā€™t be 15. Maybe you are thinking of analogWrite() which produces a PWM waveform high for a fraction of the time and low for the rest depending on the parameter.

Ok so you have a C char array ā€œd1.15ā€ and you want to parse it. There are lot so ways to do that and you are started on one so lets go that way.

//assume value contains "d1.15"
//first check "d" versus "a"
bool isDigital = false;

if (value[0] == 'd') {
  isDigital = true;
}
//find dot
char *dot = strchr(value,'.');
char pinName[10];
char pinValue[10];

if (dot) {
  strncpy(pinName,value+1,(int)(dot-value-1));
  strcpy(pinValue,dot+1);
}

You might find this easier (but more memory intensive) using Arduino String objects.

1 Like

thanks so much ā€¦ yes d is 1 or 0, but I wanted to use it also for analog pins.

so the whole string (ā€œnameā€ points to read or write ) ā€œvalueā€ points to e.g. d1 a1 d1.1 a1.200

read=d1
read=a1.20 // this is for averaging the value of a1 for 20 reads 10 msec apart.
write=d1.0
write=a1.2000

in addition the following commands:
set=d1.read
set=d1.write
set=a1.read
set=a1.write
to define pins as read or write.

Then it will be integrated into an ā€œINDIGOā€ home automation plugin to be able to define everything from within that plugin (python) to set sprinklers, open close doors, read temp, light, set fan speedā€¦

again thanks for your help. just needed a ā€œpointerā€ā€¦
kw

1 Like