Previous: Output Values and Logging
Often there is a need to make changes to your server side data in your Arduino Sketch. Say, you just want make your own Internet of Things (IoT) light switch. You want your client side to be able to turn it on and off. You may even want to make it capable of setting a schedule. Another common situation arises when using various sensors. Many sensors need some kind of calibration. The calibration may vary from one sensor to another even of the same make. The production process of these sensors, especially commodity priced sensors, leads to a lot of variability. If you are just making a single IoT device for yourself, it’s simply a matter of setting some scaling or offset factors in the code and just compile it in. But, as soon as you want to make a second one (or sell them) you need to have some variables that can be modified in the Sketch. Wouldn’t it be great if you can modify them with your own user interface? Of course it would! InqPortal makes that simple.
Continuing the Temperature Scenario
We want to support making a linear adjustment to our temperature sensor’s output following the standard y = mx + b formula. All publishedRO() and publishRW() methods for numbers have the same analogous set of parameters. If you need any of the integers versions, they are handled the same as these two float variables. The InqPortal.h file you included at the top of your Sketch will pick the correct flavor of publish method based on your selection of variable type via method overloading. You don’t even have to think about it. Although true for all numeric types, character buffers must be handled slightly different. As such, we’re going to add a character buffer example just so we can highlight the differences. In this case, we’ll let our client applications set the room name where our thermometer is located.
Persisting Data
Persistence is the act of saving your important project settings even when the lights go out. The ESP8266 has persistent data areas and we use a small region of 4KB to store your important settings. This section makes the assumption that you are familiar with the C++ concept of a struct. If you are not familiar with a struct, you might want to brush up with some web surfing.
Remember: If you’re tired of typing, the full annotated FirstPortal is in the examples that come with the InqPortal library.
The first step to storing one or more variables even when the power goes off is to define the Form of your persisted data. We use a standard C++ struct. Within the curly braces of the struct you can use any numeric variables including s8, u8, s16, u16, s32, u32, float and double. You can also use the long names if you prefer. You also can use character buffers, but you can NOT use Arduino String variables. In our example above, we have defined our two line equation constants m and b and character array to hold a room name. In this example, we can use any name up to 31 characters long. We always have to reserve one byte for an ending NULL.
Now that we have the defined the form of our persisted data, we need to create an Instance of it. Also when we create the instance, we want to assign our default values as in the example above. These are the values our logic will use when the application starts up for the first time OR when you set the erase flash option “All Flash Contents” in the Arduino IDE. As the name implies, it clears everything including our persisted data region.
The third change we need to make is to tell our InqPortal server about our persisted data so that it can manage it for us. We change the already existing InqPortal instance from the plain constructor to one with the persistence information. The first parameter is the address of our persist struct. Note the (u8*)& prefix. This lets InqPortal know where the data is. The second parameter lets InqPortal know the size of our persist struct. From now on, whenever you make a change to a FirstPersist variable in your Sketch, it will automatically be persisted. If you also publish one or more of your FirstPersist variables and it is changed by a client, it will automatically be persisted, safe from power failure.
Using Our M and B Line Constants
Changes to add linear “calibration” constants to our server
Find our sendTemperature() method in our Sketch and make the linear equation changes using our constants from our FirstPersist data instance. At this point, we’re done with persisting our constants and all logic about using them. We can change and use them anywhere in our Sketch. What about the client making changes?
Publish Read/Write Variables
If you were comfortable adding the read-only published variable earlier in the tutorial, then adding these four lines will be a cake walk. We’ve added them before the runtime variable heading simply because I like the read/write ones at the top. If you want them presented later in the Admin table, arrange them how you prefer. Just like the publishRO() method call, the publishRW() methods have the same first three parameters. The first is the alias ID that the client will use and reference (Remember: The first letter must be capitalized). The second parameter is the address of the variable. Since we are referencing variables in our FirstPersist struct config, we must use the address of the instance within the struct. The third parameter is the user friendly label.
character arrays – As has been mentioned several times Arduino String variable types are not supported. We can use fixed length character arrays which basically do the same thing with far less computation overhead. They have to handled slightly different as far as publishRO() and publishRW() methods are concerned. It is very important to note that the second parameter does not have an ampersand & prefix. This is because the character array variable IS the address of the array. Don’t worry… the compiler will let you know if you forget and have an & prefixing the variable. (Like I just did while working through this tutorial) The second difference is the insertion of a third parameter. This is the size of the character array. Again… if you forget, the compiler will let you know the error of your ways. The fourth parameter is user friendly label.
Results of Persisting, Read/Write Publishing
The best way to show the result of these additions is to open multiple browsers of the Admin with all showing the App tab. It doesn’t matter if they’re all on the same computer or different devices. You’ll see the additions of a new heading and three more rows showing your user friendly name, alias ID, and now you’ll see input boxes that permit editing. Pressing the Update button sends the updates to your InqPortal server where it is validated. Once variables are updated in your Sketch, they are sent to all clients and if any of the variables are within the persisted region, the values are persisted immediately. As this example does no explicit validation, you can at least try sending a Room name longer than the 32 characters that you specified in the Sketch. This invalid input will be sent to the server, but will be truncated on the server and the corrected version resent back to all clients. You’ll see the field changes from your invalid, typed-in name to the truncated version. All these steps were handled for you by adding three lines of code.
Complete Server-Side Sketch
This completes the server-side Sketch that creates a complete webserver with file system, administrative and debugging functionality. Pretty good for about a dozen lines of coding wouldn’t you say? If you’re building a project for your own use or you don’t really care about a dedicated, custom UI, your finished with this tutorial. We have covered all the basics. There are some more advanced topics and ways of using different methods, but all the rudimentary topics have been covered. On the flip side, if you wanting to make a dedicated, custom UI and you have the gift for aesthetics, InqPortal can at least stub out all the technical basics in an HTML/CSS/JavaScript Starter Page. We start there with the next topic.