To improve the readability of the documentation, all parameters and return values of the functions have been removed from the titles. Instead, each function has been extended with a syntax entry.
A library category has been added to the documentation. In this category e.g. the internal IO and the cartridge libraries are described.
New example scripts for the Oxocard-Connect and the cartridges have been added. Especially worth mentioning is the electronics course, which can be done with the “Oxocard Connect Innovator Kit”.
New is the onTimer() event procedure, which can be called once with setTimer(ms:long) or repeatedly after a certain time with setInterval(ms:long).
The cartridge detection for Oxocard Connect has been improved. It now runs even if a script is already running.
The internal “io.npy” library has been added. It allows to control or read IOs with only two functions.
When restarting the board via NanoPy editor, scripts can now be exited with “while 1:”.
“No WiFi connected” or “No Editor paired” warning are now no longer displayed when a cartridge is inserted.
setPrecision(0) is now also supported and behaves the same as using round() on every value.
The “LED FADE” demo of the Oxocard-Connect has been renamed to “LED RUNNING”.
On serial connection, the Oxocard-Connect now automatically does a reset and must no longer be manually switched off and restarted via menu.
We keep our promise to make designs and code public step by step.
On github you can find the schematics and designs of all Oxocards and cartridges. The BOM (bill of material) files list all the components used. This allows Makers to migrate the Oxocard hardware to other software platforms.
The firmware of the Oxocards is currently not open source, but can now be flashed to Oxocards at any time. This is necessary if the cards have been overwritten e.g. with ESP-IDF or with Arduino. All cartridge firmware is open source.
User scripts that have been saved to the Oxocard can now also be imported:
# print_hello.npy which was loaded to the card via "My scripts" def printHelloWorld(): print "Hello World!" # main.npy import print_hello printHelloWorld() # output: "Hello World!"
Under settings there is a new rotation option, which can be used to determine the screen orientation.
All “Oxoscript” texts have been changed to “NanoPy” and all “.tc” file extensions to “.npy”.
The text input field of textInput() is now exited when a new script is loaded to the card.
User IOs are reset when a script is exited or a new script is loaded.
The timeout time on a snapshot has been increased to 30 seconds.
The compile error display can now be exited with any button press.
i2cReadByte() now also returns 0 if the read failed.
onClick() is now executed only once per click and not multiple times as originally intended.
NanoPy examples that used onClick() incorrectly have been corrected.
There are several variants of the popular Python programming language, which are now joined by the NanoPy language. NanoPy is a simplified version of Python. Unlike the original, it is statically typed and can therefore be run with significantly lower hardware requirements. It is specially optimized for small computers. The language is based on the Python dialect, but contains various simplifications that make it easier to get started and to program. Previously, the language was called Oxoscript. Because of the very close relationship to Python we decided to change the name.
AP_SSID and AP_PASSWORD have been changed to avoid conflicts when multiple cards are in access point mode at the same time.
If setAutostart(true) was called, a window is now shown for 3 seconds when the Oxocard is restarted, where you can turn off the autostart function again.
The Oxocard science has received the “Flying Cow” game and two new demos. With the “SENSING RADAR” demo you can do great sensor experiments, because you can see how the values have changed over time.
The WiFi selection window has been beautified and a “Rescan” function has been added.
strFind() and strSubstring() now also work with variables (previously only with constants).
Python or not: you decide
You are annoyed by the colons behind if/else/for/while/def and class? We have copied them from the Python language. If you like them, you can continue to write them. If not, you can just leave them out now :-).
for i in 10: if i < 5: print ("low number") else: print ("large number")
for i in 10 if i < 5 print ("low number") else print ("large number")
Many beginners have trouble with the many special characters that we have inherited from Python. Now you can write it like in Python, or you just omit the round brackets in function calls in the following cases:
clear() drawText(10,10, "Hello World") update()
Alternative with less brackets:
clear drawText 10,10, "Hello World" update
Because it is so nice, here is an example again (no colons, no parentheses for function calls without return value)
turnOn = false def onDraw if turnOn background 255,255,255 else: background 0,0,0 update def onClick b = getButtons() if b.left turnOn = false elif b.right turnOn = true
Return values can now also return open arrays
Until now it was only possible to return array with fixed size:
def test()->byte: return "Hello"
New the size can be open:
def test(t)->byte a:byte a="byte" b:byte b="byte" if t%2 == 0 return a else return b for i in 10 print test(i)
The sizeof function can now be applied to nested lists.
Experimental: new serialization function for objects
With « you can now convert objects into byte arrays and vice versa. This way you can store object directly into files for example. We will use this command soon mainly for extended communication examples, e.g. for communication between coprocessors, sensors (I2C), but also for radio protocols.
The example stores the contents of the object v in a byte array buf:
v = vector(x=10,y=20) buf << v
This can be used to write the data back:
buf = [0,0,32,65,0,0,160,65] v:vector v << buf print v.toString()
Download here now the free short documentation for the introduction to NanoPy:
We now have a Youtube channel where we regularly upload new videos. It’s worth a visit:
“print (1+2)+3” now leads to an error. For examples with bracket expressions, print must not be used without brackets. Correct: print ((1+2)+3)
“print 10.0%4” previously led to an error message.
“print 1+1” now outputs 2 and not 11.
The stringToInt and stringToFloat functions can now handle negative numbers.
We have developed a new game. You can find it under Examples > Games > Flying Cow :-)
Optimization of the sprite output.
When passing an array as parameter of a function correctly, no error message is displayed now.
Simple calculations can now also be carried out in constants, as long as they only contain numbers or other constants.
const ANGLE_30 = PI / 6 const SIZE = 100
These calculations can now also be used when declaring arrays. Previously, it was only possible to specify a fixed value or a constant.
const SIZE = 100 data:byte[SIZE * SIZE] data2:byte[SIZE / 2]
For nested classes with integrated array data types, the arrays were not initialised correctly in every case, which meant that the arrays always had the length 0. This is now fixed.
Here is an example of a class SelectionList, which contains a list of label objects, each of which contains a text variable with a length of 40 bytes:
class Label: i:float x:byte text:byte class SelectionList: labels:Label def addText(text:byte): labels.text = text sl:SelectionList sl.labels.x=1 sl.labels.i=1.5 sl.addText("ABC") print(sl.labels.text) print(sl.labels.i) print(sl.labels.x)
Join our new Discord server to chat directly with the developers and to be part of the Oxocard community.
The cards can now also be programmed via USB cable. For this the Oxocard must have at least firmware version 1.2.2. It only works with Chrome browser and depending on the operating system USB drivers still need to be installed. When you log out, the new login page appears with more information.
Now you can take pictures of the screen and display them in the browser. There is a new camera icon in the toolbar next to the debugging tools. This is active when the program is in the debug mode.
If you want to transfer sensor data to the PC/Mac, you can now do this via the terminal window. Simply send the data with the print command into the terminal window (Attention: the terminal window must be open, otherwise nothing will be transferred). In the window there is a new download button at the bottom, which exports the data to a TXT file.
For further processing with Excel, it is recommended to clear the terminal first. If several data are to be sent, simply separate the data with “;”. e.g. print(value1 + “;” + value2 + “;” … )
There are again many new examples to discover. These can be found within “Examples”: - 2D: many small apps show you how to build two-dimensional animations. - 3D: with the built in 3D engine you can show simple geometric objects in three dimensional space. - Games: here you can find more small games that can serve as a basis for your own experiments. - Science course: these examples are needed in the separately available science course. More information via firstname.lastname@example.org
A very powerful multimeter app has been added to the demos. With it, all built-in sensor values can be observed in a clear scale.
Under the folder “Examples/3D” you can now find a first set of 3D animations. The functions for this will be documented in the next days.
This class provides the following functions:
logValues was renamed to logValue
The file system of the Oxocard can now be manipulated with simple functions. Thus, for example, texts or sensor data can be collected and persisted. This means that they can be read and processed again even after a power failure.
open(C_WRITE, "my_file.txt") text = "Hello World!" for c in text: write(c) close() ... open(C_READ, "my_file.txt") text:byte # to hold "Hello World!" for i in 13: text[i] = read() close()
If the autostart function has been enabled, the system switches directly to the startup program when the Oxocard is restarted (after connecting to the Internet).
Turns off the oxocard.
Turns off the oxocard and restarts it after x seconds.
Added many new audio functions that now allow you to compose and play entire songs with code.
setBPM(180) beginSong() noteAdvanced(C_NOTE_G, C_DURATION_1_8, C_OCTAVE_C4, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_A, C_DURATION_1_4, C_OCTAVE_C4, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_A, C_DURATION_1_8, C_OCTAVE_C4, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_REST, C_DURATION_1_8, C_OCTAVE_C5, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_A, C_DURATION_1_8, C_OCTAVE_C4, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_B, C_DURATION_1_8, C_OCTAVE_C4, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_C, C_DURATION_1_4, C_OCTAVE_C5, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_C, C_DURATION_1_8, C_OCTAVE_C5, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_REST, C_DURATION_1_8, C_OCTAVE_C5, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_C, C_DURATION_1_8, C_OCTAVE_C5, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_D, C_DURATION_1_8, C_OCTAVE_C5, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_B, C_DURATION_1_4, C_OCTAVE_C4, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_B, C_DURATION_1_8, C_OCTAVE_C4, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_REST, C_DURATION_1_8, C_OCTAVE_C5, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_A, C_DURATION_1_8, C_OCTAVE_C4, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_G, C_DURATION_1_8, C_OCTAVE_C4, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_A, C_OCTAVE_C4, 1.5, C_ARTICULATION_STANDARD); noteAdvanced(C_NOTE_REST, C_DURATION_1_8, C_OCTAVE_C5, C_ARTICULATION_STANDARD); #... endSong() playSong(true)
x=5 y=10 for i in [x..y]: print(i)
Descending ranges are also possible:
for i in [-10..-20]: print(i)
Formats the decimal places when outputting float values:
f = 1.23931 setPrecision(2) print(f) # "1.24"
Limits the output in the drawing commands. Drawing is done only in the defined rectangle.
clipRectangle(0,0,240,120) clear() drawCircle(120,120,80) update()
Resets the clipping setting to the whole screen.
This function is identical to drawImageMono(..), but the image is drawn centered to the x/y coordinate (instead of top left). So in combination with the rotate() and scale() functions it is now possible to rotate or in/decrease an image centered.