With any system, its very helpful to have a console, so that messages can be displayed, as this helps with debugging. Soon after implementing that, the need for a more feature rich command line becomes apparent, so that things can be interacted with in a two-way manner, this is useful for inspecting things, configuring parameters, etc. The WiFI SSID's and password are a good example.

The original version 1 coop had a fairly good command line that allows things to be done such as calibrating sensors to make readings more accurate. This is a simple gain and offset type approach using the well known formula y=mx+c. It also allows manual control of the doors, displaying sensor values in both a formatted manner (ie what the sensor means) and raw manner (what the sensor value is). Both of these help with diagnostics when things go wrong.

Here's the current output to the "help" command on the system

Chicken House Controller command help
  clear                                           - Clear the screen
  config commit <object> <index>                  - commit current RAM settings to Preferences - only affects specified object
  config set <object> <index> <parameter> <value> - Change configurable parameters in RAM
                                                  - Valid parameters can be listed with the show command
  config show [<object> <index>]                  - Show configurable parameters
                                                  - If parameters are not specified, all data is shown
                                                  - If parameters are specified, only that object is shown
  config reset                                    - Reset all configuration to initial defaults in RAM and Preferences
                                                    Caution : settings will not be optimal for sensors - re-cal manually after !!
  cpu                                             - Display CPU Info
  doors                                           - Show all the door states
  debug <set> <object> <value>                    - Perform debugging specified <object>
  diag <object>                                   - Perform diagnostics on specified <object>
                                                    i2c - i2c bus probe, fp - Front Panel, io - Digital IO, adc - Analogue IO
                                                    objects may provide device specific detailed info
  errors                                          - Get the current status and errors
  info                                            - Provide information on the build
  lights <id> <state>                             - Show or set lights and light sensors
                                                  - <id> : 1=Inside. <state> is on or off. Time is 10 minutes
  module [<modulename> <action>]                  - module specific commands, obtain info, set parameters
                                                    <modulename> front-Front Panel, power- Power monitoring board
                                                    with no arguments, provides module help / overview
  logging <state>                                 - Show, Enable or disable logging to the current tty
  network <command>                               - Perform network operations - show network information, scan WiFi
  pi <command>                                    - Interact with the Raspberry Pi - show status, turn on / off and reset it
  pophole                                         - toggle the pop hole door (open <-> close)
  popmotor <direction> <time>                     - Force the pop hole motor to move - debug only, provides no current or endstop limits !!
                                                  - <direction> 0=Forward, 1=Backwards. <Time> 0-5 seconds
  power <action> <device> <state>                 - Power Information and control
                                                     - <action> - show, get, set. e.g. Show general power info
                                                     - <device> - A controllable device, such as the Raspberry Pi or a remote module
                                                     - <state> - <on> or <off>
  reboot                                          - Restart the microcontroller
  reset <object>                                  - Reset specified object.
                                                    <object> : pi - Raspberry Pi, modules - remote/expansion modules
  sd                                              - SD card operations, info, ls, cp, mv, rm, update, format, etc
  temp                                            - Show the current temperatures
  times                                           - Show the important times for today

 

SD card operations

The SD command provides functionality to manipulate a FAT16 or FAT32 formatted partition, right from formatting a card up to use the best of those file systems, based on its size, through to performing basic file manipulation using commands that look similar to basic implementations of Linux commands, such as cat ,ls, cp, mv, rm, mkdir, rmdir, etc. I also have hexdump and a simplified wget and wput so that I can transfer files in and out of the system from a remote WebDAV share on a Raspberry Pi, this will be handy when I need to get hold of log files, or send things like certificates to the system, so this is a pre-requisite for implementing an SSH console session and it makes it a lot simpler to manage data, than pasting long strings on the command line. It may even lead to automated configuration from a script on the SD Card at some point, not that the coop has any scripting capabilities at the moment, other than a slow feed in of serial data to the command line.

The SD card supports an insert notification via a switch in the body of the connector that uses the body of the card to force the contacts together. This in turn is used to generate an interrupt on insertion and removal. I can then detect if there is a file called firmware.bin and if so, it is used to upgrade the system, allowing for updates if no WiFi is available. The SD card update method is similar to how many other devices work (3D printers as an example). The presence of this capability can be useful for recovering from a bad firmware image, since the card is initialised early in the boot process and the presence of firmware.bin is checked for. if its present, updating takes priority. The ESP32's onboard serial LED shows varying colours during the install process to show that the firmware has been detected, is being programmed and has either succeeded or failed to update. After any update, the file is renamed to firmware.bak, to prevent endless loops of unnecessary firmware updates.

A problem identified during the creation of this feature is that only certain SanDisk SD Cards will work effectively with the Arduino SDCard library, some 32Gb cards are problematic, but 64Gb cards being fine. This seems to be a fairly well documented issue in various forums. The same cards work fine on Windows and Linux, however those OS's generally don't use the SPI interface, they use a faster protocol on the same pins, so this is likely to be a card issue, or a driver issue somewhere, such as not detecting bad blocks. My easy solution was to just use 64Gb cards instead, since they are cheap.

Here's an example of the SD command syntax. Note that there is no concept of the current working directory (cwd) in this implementation, so all filenames are absolute. This might get added at some point, but for the number of times its actually used, there is little benefit, so its way down the list of things to add sometime.

SDCard command help
Supported file system format is FAT16/FAT32 only
Filenames are not case sensitive.
Paths use forward slashes. The file system root is /
Filenames and pathnames are always absolute references. There is no cwd
Names with spaces must be enclosed in double quotes. Wildcards [?/*] are not supported
Command syntax is similar to Linux, but without the switches

cat <file>       - Catalogue (display) a file
cp <src> <dest>  - Copy a file to a new file
format           - Format the SD card - destroys existing data
hexdump <file>   - Display a file in hexdump format
info             - Display card information
ls <path>        - Display directory of card
mkdir <path>     - Make a directory on the SD card
mv <src> <dest>  - Move (rename) a file on the SD card
rm <file>        - Remove (delete) a file on the SD card
rmdir <path>     - Remove (delete) a directory on the SD card
upgrade          - Perform firmware upgrade from SD card - using /firmware.bin
wget             - Web Get, download a file from a URL (http only) to a file on the SD card
wput             - Web Put, upload a file on the SD card to a remote web server (http only)

 

Other commands on the CLI work in a similar manner, but most are focused on things like erasing to default, reading and writing calibration data, which exists both in RAM and in Preferences, so values can be altered many times, then written only once, reducing wear on the preferences storage. This was a requirement in the old firmware, since EEPROM's could only be written a fairly low number of times before they failed. It does no harm in the new firmware and it means that settings can be updated in bulk, tested, then written all in one go. This is useful if changing passwords or WiFi SSID's, where you want several things to be updated before writing, then rebooting.