Photon running simple webserver & local communication

I would like to have a simple web server running on the photon. The server will populate a page with analog values it is reading and also have the ability to control functions based on inputs from an user from this page.

If you load the code and type the IP of the photon you will see my page.
My issue is with submitting the boost on/off function without having to go through the cloud.
I also don’t want any other local servers running, so the system should work with nothing but a photon and a PC or Phone on the same network.

My code is reading voltage and current and can control a boost function if the voltage is too low. I have a web server established and can view the values locally and from the cloud. However, at this point, I can only call a function over the “cloud”. How would I go about calling a function locally? Let me know what you think.

Thanks

Here is the code currently running:

TCPClient webClient;
TCPServer webServer = TCPServer(80);
char myIpAddress[24];


int boost = D7; 

int analogpowerin = A0; 

int analogvalue; 

int booststate;

int manualmodesw = D0;

int manualmode;

double dcvalue;

int acvalue;

int analogampsin = A1;

double analogampsvalue;

int acamps = 26;



void setup() {

    Particle.variable("ipAddress", myIpAddress, STRING);
    IPAddress myIp = WiFi.localIP();
    sprintf(myIpAddress, "%d.%d.%d.%d", myIp[0], myIp[1], myIp[2], myIp[3]);
    
    webServer.begin();
    
    pinMode(manualmodesw, INPUT_PULLUP);
    pinMode(boost,OUTPUT);
    pinMode(D6, OUTPUT);
    pinMode(analogpowerin,INPUT);  
    Particle.variable("analogvalue", &analogvalue, INT);
    Particle.function("boost",boostToggle);
    Particle.variable("dcvalue", &dcvalue, DOUBLE);
    Particle.variable("acvalue", &acvalue, INT);
    Particle.variable("analogampsin", &analogampsin, INT);
    Particle.variable("analogampsvalue", &analogampsvalue, DOUBLE);
    Particle.variable("acamps", &acamps, INT);

}



void loop() {

    if (manualmode == HIGH)
    digitalWrite(D6, LOW);
        else 
        digitalWrite(D6, HIGH);
    if (booststate == HIGH)
    digitalWrite(D5, HIGH);
        else
        digitalWrite(D5, LOW);
   
   if (webClient.connected() && webClient.available()) {
        serveWebpage();
    }
    else {
        webClient = webServer.available();
    }

    analogvalue = analogRead(analogpowerin);
    booststate = digitalRead(boost);
    manualmode = digitalRead(manualmodesw);
    dcvalue = (analogvalue * .00081);
    acvalue = (dcvalue * 100 + 9);
    
    
    if (manualmode == HIGH)
        {
    
            if (analogvalue > 1380)
            digitalWrite(boost, LOW);
            
            else if(analogvalue < 1280)
            digitalWrite(boost, HIGH);
        }

}

void serveWebpage() {
    
    webClient.print("<html><body><center>This will soon be the place where you can view shore power information and control boost!!!!<br><br><br><br>AC Voltage = ");
    webClient.print(acvalue);
    delay(10);
    webClient.print("<br>AC Amps =");
    delay(10);
    webClient.print(acamps);
    delay(10);
    webClient.print("<br> Manual Mode:");
    delay(10);
    if (manualmode == HIGH)
        webClient.print("OFF<br>");
        else
            webClient.print("ON<br>");
    delay(10);
    webClient.print("<br>(Boost Control only available if Manual Mode is OFF!!!)<br>");
    delay(10);
    webClient.print("<br>Boost State:");
    delay(10);
    if (booststate == HIGH)
    webClient.print("BOOSTING<br>");
        else
            webClient.print("NOT BOOSTING<br>");
    webClient.print("<form action='https://api.particle.io/v1/devices/2e0047000747343232363230/boost?access_token=8ab7c29fd37fe48c089acd1184c2896649779d7e' method='POST'>");
    webClient.print("<br><input type='radio' name='args' value='on'>Turn the BOOST ON.<br>");
    delay(10);
    webClient.print("<br><input type='radio' name='args' value='off'>Turn the BOOST OFF.<br>");
    webClient.print("<br><input type='submit' value='Do it!'>");
    delay(10);
    webClient.print("</html>\n\n");
    webClient.flush();
    webClient.stop();
    delay(100);
}



int boostToggle(String command) {

    if (command=="on") {
        digitalWrite(boost,HIGH);
        return 1;
    }
    else if (command=="off") {
        digitalWrite(boost,LOW);
        return 0;
    }
    else {
        return -1; 
    }

}

I don’t see a </form>. It gets tricky trying to write HTML in C. You should look at the WebServer library in the online IDE, and specifically the WEB_PARMS.INO example. It looks very robust and has a param parser. In the while loop dumping the name and value, just add lines like:

 if(name == "BOOST") boost = (value == "ON") ? HIGH : LOW;

The parameters are POSTed directly to web server on the Particle, so they aren’t going through the api. The string for a toggled text button would be something like:

String s = "<form method='post'><input name='BOOST' type='submit' value='";
  s += boost ? "OFF" : "ON";
  s += "'></form>";

Or for a non-root page, <form method='post' action='page.html'>

I am in the middle of working on something very much like what you want to do.

To make local networking easier, use the mDNS library. With that library, you can enter something like http://myphoton.local in your web browser, and your computer and Photon will work out the IP address discovery and resolution automagically.

It looks like you’ve already figured out the web server stuff pretty much figured out. I was using a built-from-scratch web server like that and having reasonable luck with it. However, when I started trying to parse out the querystring, things were pretty hit-and-miss. I just started (as in within the past 15 minutes) toying around with the WebServer library. I haven’t gotten to pulling variables from form submissions, but I have full faith in the examples provided in the library.

Once I get it all working, I’ll be doing a Hackster article on it, but that may be a week or two away. I was able to have mDNS and a basic web page on the Photon from scratch in less than 15 minutes, and I am far from an advanced programmer!

5 Likes

Finally did the Hackster article on the mDNS + Webduino setup this week. It’s at https://www.hackster.io/wgbartley/iot-device-management-with-mdns-and-webduino-93982a?ref=user&ref_id=988&offset=0

6 Likes

You are a Hero :slight_smile:

/Dimi

I noticed your conclusion and i think that is a very good idea to extend using the particle-api-js, that package is very advanced :slight_smile:

I have been thinking of something similar for endusers (im far from it thou).
I have an very easy vision but i lack the skill for it thou so tutorial like this is gold worth.

I want to track water quality and when the water gets bad i want a notification about it,
there are 2 kind of customer for this.

  1. Companies, i want to use the particle cloud for companies.
  2. private users. I dont really want to have all end users on the cloud, a local solution on their WIFI would be a better approch imo.

For the private user i think your tutorial is a very good start and when im that far in my project i will test this out.
right now im concentrating on getting the company part done thou :slight_smile:

BR
Dimi

1 Like

How do you eat an elephant? One byte at a time.

1 Like

Hi Garrett!

You’re great. I follow your all projects esp. I love ‘Photon IoT Gateway’ project but this time, mDNS + Webduino setup not working for me.
Actually, (I think) mDNS is not working. When I enter the local IP of device then it works fine

but If I type http://mydevice.local then it shows

When my brain got stuck, for simplification I did copy+paste the Local HTML exact code like this

but the result is same as above.

What and where is the problem?

It looks like your computer doesn’t support mDNS. I have an iPhone, so I have iTunes installed on all of my computers (which also includes Bonjour that supports mDNS). I’m assuming you have Windows?

If you have 7-zip installed on your computer, you can download the iTunes exe from http://www.apple.com/itunes/download/. Once downloaded, open the exe file in 7-zip. In there, you should see a file named Bonjour64.msi (it will be named a little different if you need the 32-bit version). Extract that file and run it to install Bonjour only. It may require a reboot to work, but I believe that should get it working for you.

1 Like

Thanks a lot!
Exactly, it worked for me :smile: