All devices can be programmed through arduino. The code is written with Arduino and C++ and can be found on our github repository. All devices can be updated remotely as well. There is no need to physically connect to the devices and program them that way. This can save an enormous amount of time. The code is split up in the code for the device, and a generic SmartClassroom library. That library takes care of a lot of generic function like reading settings, making the wifi connection, setting up the connection with the MQTT server, blinking, etc. That code is shared between all devices. Aside from that there is sc_aircon code for the airconditioning controllers, sc_lights for the lights, and sc_door for the RFID/door lock controller.
Aside from the actual code, the devices also contain a settings file. The settings file is meant to store settings that change per device. This for instance contains the Wifi SSID, usernames, password, etc. This is stored separately in a file on the microcontroller. When the microcontroller starts, it reads the settings, and uses the values to setup the wifi and such. The advantage of this setup is that the code can be identical for every device. Only the settings file changes. So when we want to flash the controllers with new code, they can all get the same code. The settings file will remain unchanged.
Compiling the code
To compile the code for the devices, it is easiest to use the commandline interface of arduino. This will result in a binary file that we can then send over the air to the different devices instead of uploading through the arduino IDE.
To be able to compile, you need the newest version of arduino, and the newest version of the ESP8266 board definitions already installed. Next clone our git smartclassroom_arduino repository. That contains all code for each device, and also the smart_classroom library. You need to copy that folder to your Arduino/libraries folder in your home directory, or make a symlink from there, which is nicer if you are running Linux.
To compile the aircon code, go to the smartclassroom_arduino/sc_aircon folder. In it execute the command
arduino --verify --preferences-file ../arduino_preferences_esp01.txt sc_aircon.ino
This will build the code and put the compiled version in the build/ subdirectory. For the lights the command is the same, just with the sc_lights.ino in the sc_lights folder. For the door, you need to use the other settings file called arduino_preferences_nodemcu.txt. All arduino settings (board, SPIFFS, etc) are already correctly set in the respective settings files.
NOTE: For the aircon, there are different versions of the code: one version for the Sanyo aircon and one for the other aircons (Daikin). At the top of the file there is a setting SANYO_AC. That should be 1 for the sanyo aircons (at the Nightowl Lab) and 0 for the Daikin aircons (at the Dorm). When you compile code, you therefore need to compile it twice and save both bin files separately one for each aircon type.
Uploading the settings
The settings are saved in the SPIFFS file settings.json. To upload SPIFFS to the microcontroller you need an additional tool.
- Go here and download a copy of 'ESP8266FS-0.2.0.zip,
- Unzip the file,
- Extract the file to ~/Arduino/tools/)
- Restart arduino
- In the "Tools" menu you should now see the option "Sketch data upload".
- This option will upload the settings file to the microcontroller. So we first need to set that up.
- Arduino will look for files in the folder where your arduino sketch is, for a folder called "data" and upload all files in there to the SPIFFS filesystem.
- In the git repository there already is a settings.sample.json file. Copy that to settings.json and then edit that and fill in all the relevant data. The mqtt_id is already correct so does not need to change.
- Now you can upload the data with the "Sketch data upload" menu item in tools. If you just uploaded code to the device, you need to reset your device first before you can upload the data.
- Also take note that the serial console NEEDS TO BE CLOSED!
Remote programming/flashing updates
The devices can be remotely updated by sending them an update command through MQTT. The lights controller subscribes to smartclassroom/Lights/update, the door controller to smartclassroom/Door/update and the aircon controller to smartclassroom/Aircon/update. The payload on these messages should be the http url where new firmware is located. As soon as a message arrives on these topics, the controller will attempt to download the firmware, flash itself and reboot. For this to work, the free memory of the device needs to be enough to store the whole file, so basically it means the bin file needs to be maximum half the size of the flash chip of the microcontroller (1M for the esp01, 4M of the nodemcu) excluding the SPIFFS size. This is because the data is stored in free memory first, before the existing code is overwritten.
The pine64 in the nightowl lab has a dashboard in its UI with a firmware update form. One of those works on the local mqtt server (for devices in the lab directly) while the other one sends the MQTT message to the central MQTT server for the production devices. Any http url will work as long as it exists, but the best is to upload the code to /srv/www/vhosts/updates on smart-classroom.foundationu.com. In that case, the file can be reached on http://smart-classroom.foundationu.com/updates/<filename>. Set this url in the form on http://pine64.nightowl.lan/ui/#/1 and set the device number to the right device type. This will send the MQTT message to the right server, which will cause the devices to download the update, flash itself and reboot. In addition to the production server, you can also upload the firmware to the acceptance server (smart-classroom-acc.nightowl.lan) in the same folder, which will be available to the devices in the nightowl lab, but not to the production devices.
If you want to know if the devices indeed downloaded the update, check /var/log/nginx/smart-classroom.foundationu.com.access.log, where you should see an entry for each device downloading the firmware.