Kenichi explains a method for enabling a robot’s functions by triggering firmware. When using his Matanya robot, you can select triggers to execute a variety of essential features.
Storytelling is the process that gives us our history and helps creates our future. In early 2000, my wife and I ran eStory.com.sg, which was site that enabled storytellers to create, upload, store, and sell their work. But after running the site part time for over a year, we shelved it with the hope of revisiting the idea in the future. Fast forward to 2010. I created a personal robotic storyteller named Matanya, a 12″ tall humanoid robot with 16 servos, a micro OLED display for eye expression, and a custom microcontroller board (see Photo 1). My intention was to have the mini humanoid robot bring stories to life with voice, sound, human gestures, and a pair of expressive digital eyes (see Figure 1). It was successfully presented at the 2011 International Robot Exhibition (iREX) in Tokyo, and I’m happy to report that it was well received by the many visitors at my booth (see Photo 2).
In this article, I’ll present the Matanya robot design. In addition, I’ll explain how to implement a method in which the features of a robot or embedded device are enabled by the triggering of firmware and not features encapsulated in firmware.
I designed the Matanya robot in three phases. First, I created its content, which required a lot of effort and resources. Next, I designed a custom 79 × 55 × 20 mm microcontroller board to deliver the content. Finally, I built a website with the backend infrastructure to integrate the content, software, and robot. One area I’d like to focus on is the method in which the controller enables developers and writers to write and store code and content that later could be triggered by the robot’s users.
The main firmware, called Main Code (M-Code), contains the basic boot-up/diagnostic procedures and the menu system. We are all very familiar with a menu system on a PC, Mac, or Linux, but something different is needed for a robot. You use the Matanya robot’s arms to select options, as you can see in Figure 2.
The robot design features a Parallax P8X32A, which is a multicore, software-driven microcontroller that requires very minimal support of peripheral of ICs. The P8X32A is well suited for this type of application. A simple FAT-type of design was implemented to allow multiple codes from multiple developers to execute on this robot with no OS running on the P8X32A microcontroller. There are many ways one could implement such process. On my MTY controller, I had a real-time clock (RTC) IC, NAND flash IC, and a MicroSD socket. The Maxim Integrated DS1307 RTC comes with a 56-byte SRAM storage space, which is very useful for storing temporal data as its values are maintained by a 3-V coin-cell battery when the main controller is powered off. The MicroSD socket is for reading from and writing to a MicroSD card where content data including new firmware are stored. It is from here that all firmware will be loaded into the final storage, NAND flash.
Each piece of firmware is assigned an ID. You can create any naming convention you like for the firmware IDs, but each needs to be unique. Since the main code I wrote for my controller could only read in 8.3 format (eight characters + ‘.’ + 3 characters) without any space, you would create an eight alphanumeric character and a three character for all your firmware (e.g., AABBCC01.bin).
The firmware is stored in 32-KB blocks because that is the microcontroller’s maximum RAM size (see Figure 3). You must keep a record of the actual starting address for each piece of firmware. You could, however, design a system to automatically handle such firmware management. These starting addresses will then be used by the menu system in your M-Code to load the user-selected firmware. There are many types of NAND flash IC on the market (e.g., Microchip Technology SST25/26).
So, let me explain how the entire process works. Whenever the microcontroller is powered up, it checks if there is any connection to a host (e.g., PC) on pins P30 and P31. If it does, it will converse with the host and possibly download a program into the Main RAM and optionally into an external 32-KB EEPROM (Parallax, “Propeller Manual,” v1.2, 2012). You are not restricted to a 32-KB EEPROM. In my case, I used a 64-KB EEPROM instead. I will explain my reason for doing so very shortly. However, if the microcontroller doesn’t detect a host connection, it will look for an external EEPROM on pins P28 and P29 and load the entire 32-KB data image into its Main RAM. I would normally use an EEPROM double the required size. This is because I would store two types of firmware (see Figure 4).
The lower 32-KB will store bootloading firmware (see Figure 5). The starting address is the default location the microcontroller will load from if it does not detect any host connection. The bootloading firmware does the following. First, it loads all the objects or libraries, initializes, and then performs a simple test according to your board designs. Next, it checks if there is any new firmware in the external storage. In my case, it will be on the MicroSD card. For standard firmware, I usually name them. An example is bootload.bin for main code to be stored in the lower 32-KB EEPROM. CSelect.bin is for checking on a user’s selection and storing the selected firmware ID for loading to RAM. This will be stored in the upper 32-KB EEPROM. So if the bootloader detects any of these names, it loads to the defined memory address. I will also have codes that delete the firmware on the MicroSD card once it is loaded. This is to ensure the bootloader will not keep loading whenever the robot restarts. Finally, it will read a specific location where the firmware ID is stored. In my MTY controller, I dedicated 1 byte out of the 56-byte SRAM storage in the RTC IC for such a purpose. Whenever the user makes a selection through the repositioning of the robot’s arm, the selected firmware ID will be stored in this location. Then the microcontroller will restart and the bootloader will check this location to read and load the selected firmware into RAM.
By implementing such a system instead of using a microcontroller with huge RAM and EEPROM/flash just so it could house all the needed functionalities and features, I could achieve a very flexible controller with minimal resources other than an onboard NAND flash or MicroSD. If your design comes with an extensible port for add-on devices, such system will come in very handy as well. Also, it is always a good idea to implement some form of security on the firmware in these storage plus performing authentications before loading them into RAM. This should be another topic altogether.
Now I’ll present some hands-on experiments. I used a Parallax Propeller Activity Board. You could also use the QuickStart board, but ensure you have revision B, which is the revision that has the larger 64-KB EEPROM (see Photo 4). I initially intended to demonstrate on the QuickStart board, but realized all my boards were Rev A. The price difference between the two is $5. I personally think the Activity Board is more worthwhile. For the extra $5, you get an on-board MicroSD socket, an ADC, a DAC, a mini breadboard, an XBee socket, a mini audio stereo jack, and a power switch, which is useful whenever you are changing your circuit on the mini breadboard. For coding, I used the Propeller Tools software to write our codes. It is the first IDE from Parallax for this MCU. The latest IDE is the SimpleIDE, which is an open-source offering that is an official programming interface for Propeller C plus many other IDEs written by avid users and developers. You start by downloading Propeller Tools (www.parallax.com/downloads/propeller-tool-software). Refer to Table 1 to see how the files are organized.
On the Activity Board, I placed three LEDs, three 100-Ω resistors for the LEDs, three 1-kΩ resistors as pull-ups for the buttons, and three buttons (see Figure 6). They had to be connected as shown in the schematics. Once the components were connected, I was ready to start.
I launched Propeller Tools and opened the source file named #BootLoadPAD.spin. I placed as many comments as possible to help the code to be more readable. The file loads the other firmware (Code_0, Code_1, Code_2, and Code_3) and writes it to a designated address in upper EEPROM (the space from 32 to 64 KB). Let’s jump into line 47, PUB Main. This is the main section where the loading of objects or libraries are performed and the main execution of functions. Notice the four writeFirmware_x statements? These functions will load and write the binary into the assigned address in upper EEPROM. Once all the four firmware binaries are loaded and written, the last statement will execute the Code_0. The starting addresses for each piece of firmware are specified in the CONSTANT or CON section at the beginning of the source file. _AddressCode0 = $8000 is assigned to Code_0 and it will be written to location 32,768 in EEPROM. _AddressCode1 = $9000 is at 36,864 and so on. To compile and check its status, I pressed F8. When doing this, there should not be any errors; but if there are errors, they will be highlighted. Next, I pressed F11 to program the code onto the lower (default 32 KB) section in the EEPROM on the Activity Board.
If you do not want to write to EEPROM, you can just load to RAM by pressing F10. Once programmed, it will execute and write the four binary files into the upper sections. After writing, it will execute (boot) Code_0, which is the code that will wait for user’s selection on the three buttons. You can see the source by opening the file Code_0.spin. Press and hold each button to trigger the loading of the assigned firmware. Pressing button 1 loads Code_1.bin and the LED 1 (on P13) starts to blink. Pressing button 2 loads Code_2.bin and LED 2 (P14) blinks. Pressing button 3 loads Code_3.bin and blinks LED 3 (P15). To go back to the selection (Code_0.bin), just press the Reset button on the Activity Board.
Once you understand how this works, you can expand your project to add external storage, example using a MicroSD card or adding a NAND flash IC to store your firmware (app) binaries. You could further automate the assessing and assigning of starting address for each firmware (app) binaries in your boot up code. Just like on my personal robotic storyteller, Matanya, a user’s selection triggers the selected firmware thereby executing (booting) the required features. With such design, new features and functionalities can also be added to your project, especially when they are already deployed in the field.
Parallax, “Propeller Manual,” v1.2, 2012, www.parallax.com/downloads/propeller-manual.
PUBLISHED IN CIRCUIT CELLAR MAGAZINE • MARCH 2016 #308 – Get a PDF of the issue