Project SOFIA
Search
K

Using SOFIA

In this section, I'll show you how to set up your environment to use Arduino IDE and SOFIA together. I'll also show you some of the main features you will find using SOFIA.

First of all...

I'd like to make some considerations about this project before start.
The first thing you need to know it that this project, from the development's point of view, is a prototype. You'll probably find some bugs while using it, or some functionality may be incomplete according to the device's datasheet.
Also, don't you expect it will run a big or complex project. Although (almost) all assemble instructions have been implemented, the simulation speed is still a problem, so I suggest you to use it for small projects and use small time scales in timers and delays (for instance, instead of use the delay function, use delayMicroseconds).
You can report bugs and issues at the project's page on Github.

Now, let's get started.

Setting up the IDE

The modified Arduino IDE developed for this project is only available for Linux (a Windows version may be released later) and it's necessary to build it. You can check a detailed explanation how to build the IDE from source here, but basically, what you'll have to do is:
  • Download the source code available on Github and extract it on your computer;
  • Install the dependencies. For Ubuntu, type:
sudo apt-get install git make gcc ant openjdk-8-jdk
Check here if you use a different OS.
  • Open a terminal and go to the build directory (extracted package).
  • Build and start the IDE using:
ant build && ant start
Or just type:
ant run
That's it. You now have an Arduino IDE to be used with SOFIA.
You may notice that the only difference between this IDE and the official version is the "Android" button at the top, as shown in figure 1.1. (There is also a "strange" new button on the right, but it's not working yet.)
Figure 1.1. Android button selected
To copy the generated hexadecimal file to your smartphone, click on the "Android" button. It will build your code and show a device selector, listing all smartphones connected to the USB ports (see figure 1.2).
Figure 1.2. Device selector
Now just select your phone from the list and click "Ok". The hexadecimal file will be copied to your device and will be available under sdcard/DCIM/SOFIA/code.hex. If you want, you can select the option "Set as default device", so you won't have to select your device every time.
If your phone does not appear in the device selector list, make sure that it is properly mounted on the system (it may not have been mounted automatically).

Setting up SOFIA

To get SOFIA, you can download it on Google Play Store. You can also get the code on Github.

Simulating your code

Now let's start the simulator. Figure 1.3 shows the initial screen you'll see when SOFIA starts. Touch the upper right menu button to access the import function and locate your file on the system (see figure 1.4).
Figure 1.3. Error loading the hexadecimal file
Figure 1.4. "Import code" function
When you import a file, SOFIA will (re)start the simulation. If you update the file after an import, don't forget to use the restart button to reload it.
The figure 1.5 shows how SOFIA looks like when the simulation starts. As you can see, there are several elements on the screen, each of them explained below.
Figure 1.5. Initial layout
  1. 1.
    Arduino board: Indicates which Arduino board is being simulated.
  2. 2.
    Pause button: Allow pause/resume the simulation.
  3. 3.
    Add IO: Allow user to add an input/output or a serial monitor.
  4. 4.
    More options: Reveals additional options.
  5. 5.
    Simulated time: Show simulated time in seconds.
  6. 6.
    Status indicator: Indicates status of the simulation.
  7. 7.
    Workspace: Inputs and outputs will appear in the workspace.
The figure 1.6 shows how SOFIA looks like with some inputs and outputs.
Figure 1.6. Some inputs and outputs, added using '+' button

Exploring SOFIA

So far so good, our environment is set, the simulation is running, what now?

Adding an output

Well, the first thing you might want to do is to add an output to measure the state of an output pin. You can do this by pressing '+' button and selecting output.
Using an output is very straightforward, you just select a pin you want to measure and then check it's state. As you can see in figure 1.7, an output may assume 3 states: On, Off or Hi-Z. It's much like if a LED is connected to the Arduino pin. The Hi-Z state indicates that a pin is configured as input and no internal pull-ups are enabled.
Figure 1.7. Outputs

Adding an input

An input may be either digital or analog. A digital input is shown in figure 1.8. For a digital input, you will have to set both a pin and a input mode. There are 5 available input modes you may choose:
  • Push-GND: This is the default option, it sends a low signal if the button is pressed, undefined otherwise.
  • Push-VDD: Sends a high signal if the button is pressed, undefined otherwise. It's the opposite of Push-GND.
  • Pull-Up: Sends a low signal if the button is pressed, high otherwise.
  • Pull-Down: Sends a high signal if the button is pressed, low otherwise. It's the opposite of Pull-Up.
  • Toggle: Toggle between low and high each time the button is pressed.
Figure 1.8. Digital input
By default, no pin is selected to avoid short-circuit, check section Short-circuit detection for more information.
An analog input is simpler than a digital input, all you have to set is the target pin. As you can see from the figure 1.9, an analog pin has a slider and a voltmeter on the right side.
Figure 1.9. Analog input
An analog input may be connected to a digital pin and a digital input may be connected to an analog pin, just like in real world.
Notice that If the input voltage of an analog pin is above the Maximum Low Voltage and below the Minimum High Voltage of the device (defined on the device's datasheet), the signal will be undefined.

Removing inputs and outputs

There are two ways to remove an input or output. The easiest way is to use the option Clear I/O (figure 1.10). This option will remove all inputs and outputs from screen.
Figure 1.10. "Clear I/O" option
If you want to remove a specific input or output, use long press. You can then select the items to be removed (see figure 1.11).
Figure 1.11. Selecting outputs to be removed

Measuring frequency

If you have set a high blinking frequency for an output in your code, SOFIA won't be able to simulate it correctly due to limitations on Android's screen refresh rate. The problem you will find doing this is that some frames will be skipped and your output may not appear to be blinking or do it randomly. In cases like these, you can use the frequency meter to make sure your output is blinking at the correct rate. (Actually, you can use the frequency meter in any case you want...)
Starting from SOFIA v1.11.1, the frequency and duty cycle meter is now enabled by default. If you are using an older version, enable this feature by selecting the output pin and pressing the measure button, as shown in figure 1.12.
Figure 1.12. Frequency meter icon
The frequency and the duty cycle information of the output will appear for every selected output (figure 1.13).
Figure 1.13. Frequency information displayed for the selected output

Short-circuit detection

SOFIA can also detect short-circuit between inputs and outputs or between inputs (once you can add multiple inputs/outputs on the same pin). If a short-circuit condition is found, the simulation will stop and a message will be displayed on the status indicator, as shown in figure 1.14.
Figure 1.14. Short-circuit condition
After removing the short-circuit condition, you can manually reset the system.

Serial Monitor

SOFIA has an integrated serial monitor, accessed by the '+' button. If you are using the Universal Synchronous Asynchronous Receiver Transceiver (USART) in your project, you will be able to read and send information using this monitor.
For instance, take the code below, that just prints whatever it receives through the serial port.
/*
* Based on the code example from:
* https://www.arduino.cc/en/Serial/Read
*/
int incomingByte = 0; // for incoming serial data
void setup() {
// opens serial port, sets data rate to 9600 bps
Serial.begin(9600);
}
void loop() {
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
// say what you got:
Serial.write(incomingByte);
}
}
To simulate a code like this, click on the '+' button and add a serial monitor. The monitor looks like figure 1.15.
Figure 1.15. Serial monitor
The monitor will be placed above the outputs, so you won't be able to see both at the same time. You can, however, use it simultaneously with inputs (figure 1.16).
Figure 1.16. Serial monitor with digital input
Now, just type your text in the field below and send it to the simulator. For this example, your text should appear on the monitor, as shown in figure 1.17.
Figure 1.17. Serial monitor working for this example
Close the monitor by clicking on the 'x' button (upper side right).

Memory Map

If you are interested in measure memory usage or just look inside the Arduino memory, you can use SOFIA's Memory Map. Access the memory map in the "Memory" option (figure 1.18).
Figure 1.18. "Memory" option
The memory map looks like shown in figure 1.19.
Figure 1.19. Memory Map
This map shows you the state of each bit in the internal SDRAM and the registers. Also, it shows you the memory usage in bytes (upper side left) and in percentage (upper side right).
Notice that, besides the registers, there are 2kB of SDRAM in Arduino UNO. To make your life easier, you can use the "search" button and search for the address/register you want to inspect, as shown in figure 1.20.
Figure 1.20. Using the "search" button to find an specific register
When using this feature, the simulation continues to run in the background, but it gets a little bit slower.

ADC Voltage Reference Configuration

When using the Analog to Digital Converter (ADC), it's possible to change the reference voltage for analog inputs. That is the voltage the input will be compared to in order to convert it to a digital code. By default, this reference is 5V.
To change the ADC voltage reference, first you need to use the function analogReference as shown in the code below.
void setup() {
...
//Change to External Analog Voltage Reference
analogReference(EXTERNAL);
...
}
By doing this, Arduino will use the voltage applied to the AREF pin as reference. To simulate it in SOFIA, open the Settings menu (figure 1.21).
Figure 1.21. Settings option
Figure 1.22 shows the settings menu. SOFIA still doesn't have much to configure, you can only configure your simulation to start paused and change the AREF value. Enter a new value for AREF and press "OK" to save it, SOFIA will remember this value when you exit the app.
Figure 1.22. Settings menu
If you are using an internal voltage reference, this configuration will have no effect.

That's it.

For now, that's all you can do with SOFIA. In the next section, I'll explain a little bit more about the project and show some datas about test coverage and other stuff.