Yocto-serial : user's guide

Yocto-Serial : User's guide

1. Introduction
1.1 Prerequisites
1.2 Optional accessories
2. Presentation
2.1 Common elements
2.2 Specific elements
3. First steps
3.1 Localization
3.2 Test of the module
3.3 Configuration
4. Assembly and connections
4.1 Fixing
4.2 USB power distribution
5. The serial port
5.1 Configurable parameters
5.2 Text-line based protocol
5.3 Frame-based binary protocol
5.4 MODBUS protocol
5.5 ASCII data stream
5.6 Binary data stream
5.7 Serial communication analyzer
6. Automatic measures
6.1 Communication jobs
6.2 Tasks
6.3 Commands
6.4 The genericSensor functions
6.5 Configuration example
7. Programming, general concepts
7.1 Programming paradigm
7.2 The Yocto-Serial module
7.3 Module control interface
7.4 SerialPort function interface
7.5 External power supply control interface
7.6 GenericSensor function interface
7.7 DataLogger function interface
7.8 Files function interface
7.9 What interface: Native, DLL or Service ?
7.10 Programming, where to start?
8. Using the Yocto-Serial in command line
8.1 Installing
8.2 Use: general description
8.3 Control of the SerialPort function
8.4 Control of the module part
8.5 Limitations
9. Using Yocto-Serial with Javascript
9.1 Getting ready
9.2 Control of the SerialPort function
9.3 Control of the module part
9.4 Error handling
10. Using Yocto-Serial with PHP
10.1 Getting ready
10.2 Control of the SerialPort function
10.3 Control of the module part
10.4 HTTP callback API and NAT filters
10.5 Error handling
11. Using Yocto-Serial with C++
11.1 Control of the SerialPort function
11.2 Control of the module part
11.3 Error handling
11.4 Integration variants for the C++ Yoctopuce library
12. Using Yocto-Serial with Objective-C
12.1 Control of the SerialPort function
12.2 Control of the module part
12.3 Error handling
13. Using Yocto-Serial with Visual Basic .NET
13.1 Installation
13.2 Using the Yoctopuce API in a Visual Basic project
13.3 Control of the SerialPort function
13.4 Control of the module part
13.5 Error handling
14. Using Yocto-Serial with C#
14.1 Installation
14.2 Using the Yoctopuce API in a Visual C# project
14.3 Control of the SerialPort function
14.4 Control of the module part
14.5 Error handling
15. Using Yocto-Serial with Delphi
15.1 Preparation
15.2 Control of the SerialPort function
15.3 Control of the module part
15.4 Error handling
16. Using the Yocto-Serial with Python
16.1 Source files
16.2 Dynamic library
16.3 Control of the SerialPort function
16.4 Control of the module part
16.5 Error handling
17. Using the Yocto-Serial with Java
17.1 Getting ready
17.2 Control of the SerialPort function
17.3 Control of the module part
17.4 Error handling
18. Using the Yocto-Serial with Android
18.1 Native access and VirtualHub
18.2 Getting ready
18.3 Compatibility
18.4 Activating the USB port under Android
18.5 Control of the SerialPort function
18.6 Control of the module part
18.7 Error handling
19. Advanced programming
19.1 Event programming
19.2 The data logger
19.3 Sensor calibration
20. Using with unsupported languages
20.1 Command line
20.2 VirtualHub and HTTP GET
20.3 Using dynamic libraries
20.4 Porting the high level library
21. High-level API Reference
21.1 General functions
21.2 Module control interface
21.3 SerialPort function interface
21.4 External power supply control interface
21.5 Files function interface
21.6 GenericSensor function interface
21.7 DataLogger function interface
21.8 Recorded data sequence
21.9 Measured value
22. Troubleshooting
22.1 Linux and USB
22.2 ARM Platforms: HF and EL
23. Characteristics
24. Index

1. Introduction

The Yocto-Serial is a 51x20mm USB module used to communicate with electronic devices using a serial communication at 3.3V or 5V CMOS/TTL levels. It also features a voltage output to power that device with 3.3V or 5V. Its buffer memory enables it to communicate asynchronously, if need be. The Yocto-Serial can also work as a serial communication analyzer. In the opposite to most common USB/serial adaptors, it does not need drivers and, most importantly, its use does not require any virtual COM port.

On top of offering low level serial communications, the Yocto-Serial can autonomously question and analyze the serial output of any appliance to then present the results in the manner of a Yoctopuce sensor. In other words, the Yocto-Serial can transform any sensor equipped with a serial output into the software equivalent of a Yoctopuce sensor, data logger included.

Beware, the Yocto-Serial is not a classic serial to USB adaptor: it does not create a virtual COM port and you cannot therefore use it with an application designed to use a COM port.


The Yocto-Serial module

Yoctopuce thanks you for buying this Yocto-Serial and sincerely hopes that you will be satisfied with it. The Yoctopuce engineers have put a large amount of effort to ensure that your Yocto-Serial is easy to install anywhere and easy to drive from a maximum of programming languages. If you are nevertheless disappointed with this module, do not hesitate to contact Yoctopuce support1.

By design, all Yoctopuce modules are driven the same way. Therefore, user's guides for all the modules of the range are very similar. If you have already carefully read through the user's guide of another Yoctopuce module, you can jump directly to the description of the module functions.

1.1. Prerequisites

In order to use your Yocto-Serial module, you should have the following items at hand.

A computer

Yoctopuce modules are intended to be driven by a computer (or possibly an embedded microprocessor). You will write the control software yourself, according to your needs, using the information provided in this manual.

Yoctopuce provides software libraries to drive its modules for the following operating systems: Windows, Mac OS X, Linux, and Android. Yoctopuce modules do not require installing any specific system driver, as they leverage the standard HID driver2 provided with every operating system.

Windows versions currently supported are: Windows XP, Windows 2003, Windows Vista, Windows 7 and Windows 8.1. Both 32 bit and 64 bit versions are supported. Yoctopuce is frequently testing its modules on Windows XP and Windows 7.

Mac OS X versions currently supported are: 10.6 (Snow Leopard), Mac OS X 10.7 (Lion), 10.8 (Mountain Lion), and 10.9 (Maverick). Yoctopuce is frequently testing its modules on Mac OS X 10.9 and 10.7.

Linux kernels currently supported are the 2.6 branch and the 3.0 branch. Other versions of the Linux kernel, and even other UNIX variants, are very likely to work as well, as Linux support is implemented through the standard libusb API. Yoctopuce is frequently testing its modules on Linux kernel 2.6.

Android versions currently supported are: Android 3.1 and later. Moreover, it is necessary for the tablet or phone to support the Host USB mode. Yoctopuce is frequently testing its modules on Android 4.x on a Nexus 7 and a Samsung Galaxy S3 with the Java for Android library.

A USB cable, type A-micro B

USB connectors exist in three sizes: the "standard" size that you probably use to connect your printer, the very common mini size to connect small devices, and finally the micro size often used to connect mobile phones, as long as they do not exhibit an apple logo. All USB modules manufactured by Yoctopuce use micro size connectors.


The most common USB 2 connectors: A, B, Mini B, Micro A, Micro B.3

To connect your Yocto-Serial module to a computer, you need a USB cable of type A-micro B. The price of this cable may vary a lot depending on the source, look for it under the name USB A to micro B Data cable. Make sure not to buy a simple USB charging cable without data connectivity. The correct type of cable is available on the Yoctopuce shop.


You must plug in your Yocto-Serial module with a USB cable of type A - micro B.

If you insert a USB hub between the computer and the Yocto-Serial module, make sure to take into account the USB current limits. If you do not, be prepared to face unstable behaviors and unpredictable failures. You can find more details on this topic in the chapter about assembly and connections.

1.2. Optional accessories

The accessories below are not necessary to use the Yocto-Serial module but might be useful depending on your project. These are mostly common products that you can buy from your favorite hacking store. To save you the tedious job of looking for them, most of them are also available on the Yoctopuce shop.

Screws and spacers

In order to mount the Yocto-Serial module, you can put small screws in the 2.5mm assembly holes, with a screw head no larger than 4.5mm. The best way is to use threaded spacers, which you can then mount wherever you want. You can find more details on this topic in the chapter about assembly and connections.

Micro-USB hub

If you intend to put several Yoctopuce modules in a very small space, you can connect them directly to a micro-USB hub. Yoctopuce builds a USB hub particularly small for this purpose (down to 20mmx36mm), on which you can directly solder a USB cable instead of using a USB plug. For more details, see the micro-USB hub information sheet.

YoctoHub-Ethernet and YoctoHub-Wireless

You can add network connectivity to your Yocto-Serial, thanks to the YoctoHub-Ethernet and the YoctoHub-Wireless. The YoctoHub-Ethernet provides Ethernet connectivity and the YoctoHub-Wireless provides WiFi connectivity. Both can drive up to three devices and behave exactly like a regular computer running a VirtualHub.

Enclosures

Your Yocto-Serial has been designed to be installed as is in your project. Nevertheless, Yoctopuce sells enclosures specifically designed for Yoctopuce devices. These enclosures have removable mounting brackets and magnets allowing them to stick on ferromagnetic surfaces. More details are available on the Yoctopuce web site 4. The suggested enclosure model for your Yocto-Serial is the YoctoBox-Long-Thick-Black.


You can install your Yocto-Serial in an optional enclosure

2. Presentation


1:USB connector (micro-B) 6:3.3V / 5V power output
2:Yocto-led 7:CTS
3:Yocto-button 8:RTS
4:Transmit led 9:TD
5:Receive led 10:RD
11:Ground

2.1. Common elements

All Yocto-modules share a number of common functionalities.

USB connector

Yoctopuce modules all come with a micro-B USB socket. The corresponding cables are not the most common, but the sockets are the smallest available.

Warning: the USB connector is simply soldered in surface and can be pulled out if the USB plug acts as a lever. In this case, if the tracks stayed in position, the connector can be soldered back with a good iron and using flux to avoid bridges. Alternatively, you can solder a USB cable directly in the 1.27mm-spaced holes near the connector.

Yocto-button

The Yocto-button has two functionalities. First, it can activate the Yocto-beacon mode (see below under Yocto-led). Second, if you plug in a Yocto-module while keeping this button pressed, you can then reprogram its firmware with a new version. Note that there is a simpler UI-based method to update the firmware, but this one works even in case of severely damaged firmware.

Yocto-led

Normally, the Yocto-led is used to indicate that the module is working smoothly. The Yocto-led then emits a low blue light which varies slowly, mimicking breathing. The Yocto-led stops breathing when the module is not communicating any more, as for instance when powered by a USB hub which is disconnected from any active computer.

When you press the Yocto-button, the Yocto-led switches to Yocto-beacon mode. It starts flashing faster with a stronger light, in order to facilitate the localization of a module when you have several identical ones. It is indeed possible to trigger off the Yocto-beacon by software, as it is possible to detect by software that a Yocto-beacon is on.

The Yocto-led has a third functionality, which is less pleasant: when the internal software which controls the module encounters a fatal error, the Yocto-led starts emitting an SOS in morse 5. If this happens, unplug and re-plug the module. If it happens again, check that the module contains the latest version of the firmware, and, if it is the case, contact Yoctopuce support6.

Current sensor

Each Yocto-module is able to measure its own current consumption on the USB bus. Current supply on a USB bus being quite critical, this functionality can be of great help. You can only view the current consumption of a module by software.

Serial number

Each Yocto-module has a unique serial number assigned to it at the factory. For Yocto-Serial modules, this number starts with YSERIAL1. The module can be software driven using this serial number. The serial number cannot be modified.

Logical name

The logical name is similar to the serial number: it is a supposedly unique character string which allows you to reference your module by software. However, in the opposite of the serial number, the logical name can be modified at will. The benefit is to enable you to build several copies of the same project without needing to modify the driving software. You only need to program the same logical name in each copy. Warning: the behavior of a project becomes unpredictable when it contains several modules with the same logical name and when the driving software tries to access one of these modules through its logical name. When leaving the factory, modules do not have an assigned logical name. It is yours to define.

2.2. Specific elements

The connector

The Yocto-Serial modules contains a serial port following CMOS/TLL standards, which can be configured for 3.3V or 5V logical levels. In the opposite to classic serial adaptors, the Yocto-Serial is not a simple gateway to a virtual COM port with an identity varying over time. Instead, the Yocto-Serial autonomously manages the serial port: it contains 16KB input and output buffers, it automatically manages flow control, and it can recognize some usual message formats to ease reading by software. You can find more details in the chapter of this documentation devoted to the serial port.

Activity leds

The Yocto-Serial contains two green LEDs reflecting the serial port activity. The receiving led lights up feebly when a CTS signal is received (RTS line activated by the external device). It lights up strongly when it receives a character. The transmitting led lights up feebly when the module sends the RTS signal and strongly when it sends a character.

3. First steps

When reading this chapter, your Yocto-Serial should be connected to your computer, which should have recognized it. It is time to make it work.

Go to the Yoctopuce web site and download the Virtual Hub software7. It is available for Windows, Linux, and Mac OS X. Normally, the Virtual Hub software serves as an abstraction layer for languages which cannot access the hardware layers of your computer. However, it also offers a succinct interface to configure your modules and to test their basic functions. You access this interface with a simple web browser8. Start the Virtual Hub software in a command line, open your preferred web browser and enter the URL http://127.0.0.1:4444. The list of the Yoctopuce modules connected to your computer is displayed.


Module list as displayed in your web bowser.

3.1. Localization

You can then physically localize each of the displayed modules by clicking on the beacon button. This puts the Yocto-led of the corresponding module in Yocto-beacon mode. It starts flashing, which allows you to easily localize it. The second effect is to display a little blue circle on the screen. You obtain the same behavior when pressing the Yocto-button of the module.

3.2. Test of the module

The first item to check is that your module is working well: click on the serial number corresponding to your module. This displays a window summarizing the properties of your Yocto-Serial.


Properties of the Yocto-Serial module.

This window allows you, among other things, to play with your module to check how it is working. You can find there a simplified terminal emulator enabling you to test the communications of your module.

3.3. Configuration

When, in the module list, you click on the configure button corresponding to your module, the configuration window is displayed.


Yocto-Serial module configuration.

Firmware

The module firmware can easily be updated with the help of the interface. To do so, you must beforehand have the adequate firmware on your local disk. Firmware destined for Yoctopuce modules are available as .byn files and can be downloaded from the Yoctopuce web site.

To update a firmware, simply click on the upgrade button on the configuration window and follow the instructions. If the update fails for one reason or another, unplug and re-plug the module and start the update process again. This solves the issue in most cases. If the module was unplugged while it was being reprogrammed, it does probably not work anymore and is not listed in the interface. However, it is always possible to reprogram the module correctly by using the Virtual Hub software 9 in command line 10.

Logical name of the module

The logical name is a name that you choose, which allows you to access your module, in the same way a file name allows you to access its content. A logical name has a maximum length of 19 characters. Authorized characters are A..Z, a..z, 0..9, _, and -. If you assign the same logical name to two modules connected to the same computer and you try to access one of them through this logical name, behavior is undetermined: you have no way of knowing which of the two modules answers.

Luminosity

This parameter allows you to act on the maximal intensity of the leds of the module. This enables you, if necessary, to make it a little more discreet, while limiting its power consumption. Note that this parameter acts on all the signposting leds of the module, including the Yocto-led. If you connect a module and no led turns on, it may mean that its luminosity was set to zero.

Logical names of functions

Each Yoctopuce module has a serial number and a logical name. In the same way, each function on each Yoctopuce module has a hardware name and a logical name, the latter can be freely chosen by the user. Using logical names for functions provides a greater flexibility when programming modules.

Serial port configuration

You can configure the workings of the serial port in this window. You can select the speed, the encoding, the parity, the number of stop bits, and the flow control and the voltage to use.

You can also select the protocol that you want to use on the serial line. You can find more details about the different protocols in the chapter entitled 5. Serial port.

You can choose the voltage level used by the serial port. The Yocto-Serial features 5 modes:

This setting is saved in the flash memory. Make sure to check the voltage twice before connecting a device to the Yocto-Serial, as a wrong setting is likely to damage the connected device. The Yocto-Serial is shipped with this setting set to OFF.

Power output configuration

Le Yocto-Serial features a power output allowing it to power the connected circuit with 3.3V or 5V. You can count on ~200mA when the chosen voltage is 3.3V and ~450mA when the chosen voltage is 5V.

This setting is also saved to the flash memory, make sure you check it twice before connecting a device to the Yocto-Serial. Using the wrong voltage might destroy your hardware. The Yocto-Serial is shipped with this setting set to OFF. When configuring both the serial port level and the power output, make sure that voltage on the serial port is never greater than the power supply. Therefore, it is preferable to turn on the power output, then power the serial port, as most electronic devices don't like receiving a signal voltage on their input pins above their power supply.

4. Assembly and connections

This chapter provides important information regarding the use of the Yocto-Serial module in real-world situations. Make sure to read it carefully before going too far into your project if you want to avoid pitfalls.

4.1. Fixing

While developing your project, you can simply let the module hang at the end of its cable. Check only that it does not come in contact with any conducting material (such as your tools). When your project is almost at an end, you need to find a way for your modules to stop moving around.


Examples of assembly on supports

The Yocto-Serial module contains 2.5mm assembly holes. You can use these holes for screws. The screw head diameter must not be larger than 4.5mm or they will damage the module circuits. Make sure that the lower surface of the module is not in contact with the support. We recommend using spacers, but other methods are possible. Nothing prevents you from fixing the module with a glue gun; it will not be good-looking, but it will hold.

If your intend to screw your module directly against a conducting part, for example a metallic frame, insert an isolating layer in between. Otherwise you are bound to induce a short circuit: there are naked pads under your module. Simple packaging tape should be enough for electric insulation.

4.2. USB power distribution

Although USB means Universal Serial BUS, USB devices are not physically organized as a flat bus but as a tree, using point-to-point connections. This has consequences on power distribution: to make it simple, every USB port must supply power to all devices directly or indirectly connected to it. And USB puts some limits.

In theory, a USB port provides 100mA, and may provide up to 500mA if available and requested by the device. In the case of a hub without external power supply, 100mA are available for the hub itself, and the hub should distribute no more than 100mA to each of its ports. This is it, and this is not much. In particular, it means that in theory, it is not possible to connect USB devices through two cascaded hubs without external power supply. In order to cascade hubs, it is necessary to use self-powered USB hubs, that provide a full 500mA to each subport.

In practice, USB would not have been as successful if it was really so picky about power distribution. As it happens, most USB hub manufacturers have been doing savings by not implementing current limitation on ports: they simply connect the computer power supply to every port, and declare themselves as self-powered hub even when they are taking all their power from the USB bus (in order to prevent any power consumption check in the operating system). This looks a bit dirty, but given the fact that computer USB ports are usually well protected by a hardware current limitation around 2000mA, it actually works in every day life, and seldom makes hardware damage.

What you should remember: if you connect Yoctopuce modules through one, or more, USB hub without external power supply, you have no safe-guard and you depend entirely on your computer manufacturer attention to provide as much current as possible on the USB ports, and to detect overloads before they lead to problems or to hardware damages. When modules are not provided enough current, they may work erratically and create unpredictable bugs. If you want to prevent any risk, do not cascade hubs without external power supply, and do not connect peripherals requiring more than 100mA behind a bus-powered hub.

In order to help controlling and planning overall power consumption for your project, all Yoctopuce modules include a built-in current sensor that tells (with 5mA precision) the consumption of the module on the USB bus.

5. The serial port

In the opposite to classic RS232 adapters, the Yocto-Serial serial port is not a simple gateway to a virtual COM port. It is based on an active communication management by the module and offers a full programming interface like for all Yoctopuce modules. In particular,

Thanks to these functions, you can use the Yocto-Serial to, for example, perform serial communications from a simple command line or from HTTP request on a REST interface, without risking to lose messages.

The serial port of the Yocto-Serial can communicate with CMOS/TTL circuits using 3.3V or 5V logical levels. The TX/RX lines can work with standard levels (idle high) or inverted levels (idle low). CTS/RTS only works with standard levels.

5.1. Configurable parameters

The Yocto-Serial serial port can generate communication speeds from 110 bits/s to 250'000 Kbits/s. You can configure it to use 7 or 8 bits of data, with or without parity (even or odd), with 1 or 2 stop bits.11

Depending on the configuration of the device connected to the serial port, you can enable a flow control function in the Yocto-Serial. Hardware flow control (based on CTS/RTS lines) is the most efficient, but it is not available on all devices.12 Software flow control (based on sending XON/XOFF codes) is also supported.

There is a third variant called "Simplex", to support transmissions in half-duplex where only one interface can speak at a time: The RTS line is signaled when the Yocto-Serial must transmit information on the serial bus, and the transmission happens only when the CTS line confirms that the bus is available. The CTS line is released at the end of the transmission. This mode is used by some RS232 to RS485 adapters, among others.

You can also configure in the module the protocol family to be used on the serial port. This allows the module to make a pre-analysis of the data directly when it receives them and to optimize the information exchange with the application code, in particular to signal the reception of new data at the most appropriate time (that is when a full message is received). Details of supported protocol families are available in the following sections.

5.2. Text-line based protocol

Called Line-based ASCII protocol in the configuration interface, it is a very common family for measuring tools. The host machine sends its configuration commands in the shape of commands ending by a line feed. The measuring tool sends its measures and its receipts as lines of text as well. Among the machines using this kind of protocol, you can find:

The most useful API functions in this working mode are:

In line mode, if you register a value notification callback, it is called after each newly received message.

5.3. Frame-based binary protocol

CalledFrame-based binary protocol in the configuration interface, this family includes all proprietary protocols based on exchanging binary messages (non-textual).The MODBUS RTU protocol is a particular case which is explicitly managed (see below). But any other variant of binary frame exchanges can be used here. The Yocto-Serial is able to separate the distinct received messages thanks to a measure of the delay in the successive byte reception. When you select a protocol based on binary frames, you can specify the space delimiting the separation between two frames.

If your binary protocol does not specify any constraint on the space between frames and space between the characters of a frame, you had better use the "Binary data stream" family below.

The most useful API functions in this working mode are:

In binary frame mode, if you register a value notification callback, it is called for each newly received frame.

5.4. MODBUS protocol

The MODBUS protocol is much used in the industry and for monitoring the technical infrastructure of buildings. The protocol has two variants: the MODBUS ASCII mode where messages are exchanged as lines of hexadecimal code, and the MODBUS RTU mode where messages are exchanged directly as binary frames. To dialog with a MODBUS device, you imperatively must use the same mode as configured in the device. In theory, all the devices conforming to the standard must support the MODBUS RTU mode.

MODBUS messages correspond to relatively simple operations to read and write in binary registers (called bits or coils) and to 16 bit words. The host systematically initiates the exchange, to which the "slave" answers. The Yocto-Serial transparently manages the ASCII and RTU modes and computes by itself the validation bytes (LRC and CRC) specified in the MODBUS protocol. The most useful API functions in MODBUS mode are:

In MODBUS mode, if you register a value notification callback, it is called each time an answer is received.

5.5. ASCII data stream

Called Generic ASCII stream in the configuration interface, it is the most primitive text communication variant, similar to a file access. As the Yocto-Serial has a 16KB read buffer, it is even possible to move the read position pointer freely within this window. Note that the read position pointer is specific to each application: if two applications read access the serial port through the network simultaneously, moving the read position pointer of one application does not have any impact on data availability for the other application.

The most useful API functions to to work with an ASCII data stream are:

In stream mode, if you register a value notification callback, it is called each time a byte is received.

5.6. Binary data stream

Called Generic byte stream in the configuration interface, it is the binary equivalent of the ASCII data stream. You access it as you would a binary file, with the possibility to move the read position pointer freely inside the 16KB read buffer. Note that the read position pointer is specific to each application: if two applications read access the serial port through the network simultaneously, moving the read position pointer of one application does not have any impact on data availability for the other application.

The most useful API functions to to work with a binary data stream are:

In stream mode, if you register a value notification callback, it is called each time a byte is received.

5.7. Serial communication analyzer

You can use the Yocto-Serial as a serial protocol analyzer by connecting it on the cable that directly connect two devices communicating via a serial protocol. In this specific mode, the Yocto-Serial transmitting signals are not wired (ensuring trouble-free operations), and the TD and RD lines to be monitored are two receiving signals on the Yocto-Serial. It is then able to read the traffic going through both ways on the serial cable, identifying the direction of the communication.


Wiring to use the Yocto-Serial in analyzer mode

6. Automatic measures

On top of offering the means to perform low level serial communications, the Yocto-Serial can work at a superior abstraction level. It can autonomously question a device through the serial port and present the values read as measures, in the same manner as all the Yoctopuce sensors. This includes the possibility to store the measures on the internal flash memory (data logger). Potentially, this enables you to transform any device equipped with a serial port into a native Yoctopuce sensor, with all the advantages this brings in terms of ease for software integration.


The Yocto-Serial can automatically send and receive data on the serial port.

6.1. Communication jobs

The Yocto-Serial contains a file system on which you can store jobs, which are in fact simple text file in the JSON format. A job describes write and read actions to be performed on the serial port. In the VirtualHub interface, the window describing the Yocto-Serial properties allows you to select which job must be run, while the configuration window enables you to select which job must be run when the module starts. The Yocto-Serial runs only one job at a time, but a job can perform actions in parallel.

Job structure

A job is essentially a set of tasks which are independent from one another. Each task can send data on the serial port and/or react to the arrival of data on the serial port.

Job definition and management

You can define jobs with the VirtualHub, in the Yocto-Serial configuration window. Click on the manage files button and a window containing the list of defined jobs appears.


Job management window

This window enables you to select which job to run, to edit, or to delete. It also allows you to define a new hob, either with the help of an interface or by directly uploading it on the module file system. To create a new job, click on define a new job. This opens the job creation window.


Job creation window

As a job is only a set of tasks, this window only allows you to give a name to the job and to manage the tasks it contains.

Creating a job by software

While there is no explicit API to define a job by software, a job is only a text file put in the file system of the Yocto-Serial. To configure the Yocto-Serial by software, you simply need to upload the correct file on the Yocto-Serial with the YFiles class and to program its running with the selectJob() or set_startupJob() functions of the YSerialPort class. The easiest way to create a job file without risking to make an error consists in using the VirtualHub to configure the desired job on a Yocto-Serial module, and then to download the corresponding file.

6.2. Tasks

Each task is a simple list of commands to run sequentially: sending data on the serial port, waiting, reading data, and so on. There are two types of tasks: reactive tasks and periodic tasks.

Reactive tasks

A reactive task is triggered by the device connected to the Yocto-Serial: the task is automatically run as soon as data corresponding to predefined patterns appear on the port. Most often, a task simply consists in interpreting these data and in assigning them to one or several genericSensor functions available on the Yocto-Serial. Reactive tasks are particularly useful to interface devices that send a continuous flow of measures on their serial port. If the module detects data with a pattern corresponding to two distinct tasks, both tasks are run in parallel.

The VirtualHub allows you to easily create a good number of reactive tasks, such as:

But you can also define personalized tasks by typing the task commands directly.


Reactive task creation interface

You can assign data that are read to any Yocto-Serial genericSensor functions. From the developer stand point, the device that is connected to the Yocto-Serial through its serial port appears like any usual Yoctopuce sensor. All the normal Yoctopuce sensor features (callbacks, data logger, averaging, and so on) are then available without any additional effort.

Beware, the serial protocol defined in the Yocto-Serial configuration must correspond to the needs of the job. For instant, you cannot detect a MODBUS transaction if the Yocto-Serial is configured in line-based ASCII mode.

Periodic tasks

A periodic task is a task that is run at a regular interval, at the Yocto-Serial initiative. They are generally used to send commands to the device connected to the Yocto-Serial. Here again, the VirtualHub allows you to easily define a number of common tasks:

You can also define a task manually, one command after the other, or start by using a predefined task as above and edit it afterwards to add commands.

You can also assign data read in a periodic task to the Yocto-Serial genericSensor functions. Beware, the serial protocol defined in the Yocto-Serial configuration must correspond to the needs of the job: for example, you cannot detect a MODBUS transaction if the Yocto-Serial is configured in line-based ASCII mode.


Periodic task creation interface

Although periodic tasks are designed to be run at regular intervals, you can define a "periodic" task that is run only once. Periodic tasks are run in the order in which they are defined. You can therefore define a job containing a first non recurrent task to configure your device, and a second task, recurrent, to question it in a loop.

You can mix periodic and reactive tasks in a same job. You must however pay careful attention to their triggering events in order to prevent them from perturbing each other. The Yocto-Serial always waits until the end of a periodic task before running the next one. However, reactive tasks can be triggered at any time, even in parallel to a periodic task.

6.3. Commands

You can use the following commands in a (periodic or reactive) task:

EXPECT

The expect command waits for the data corresponding to a given pattern to appear on the serial line. If the module is configured in binary mode, the correspondence is established on a hexadecimal representation of the binary data.

The expect command takes a character string as argument. We support some regular expressions:

WAIT

The wait command waits for a given number of milliseconds before running the following command.

LOG

The log command displays a character string in the logs of the Yocto-Serial.

WRITE

The write command sends a character string as is on the serial line. The string is sent without additional carriage return.

WRITELINE

The writeLine command sends a character string on the serial line, followed by a line break (CR-LF).

WRITEHEX

The writeHex command sends a binary message on the serial line. The parameter is the hexadecimal representation of the message to be sent (lower and upper case are supported).

WRITEMODBUS

The writeModbus command sends a MODBUS command. The parameter is a hexadecimal representation of the command to be sent, without checksum. For example:

If, for a reason or another, a command generates an error, you can find the traces of this error in the logs of the Yocto-Serial.

6.4. The genericSensor functions

9 genericSensor functions are available in the Yocto-Serial. Jobs running on the module can freely assign them values. You can access these genericSensor functions from the Yoctopuce API with the YGenericSensor class. You can also configure these functions to tailor their behavior depending on the nature of the reported values.


genericSensor configuration window

Unit

You can define the measuring system in which the value stored by the genericSensor is specified.

Resolution

You can define the resolution in which the value reported by the genericSensor must be represented.

Mapping

You can automatically apply a linear transformation to the values stored in a genericSensor. Indeed, some devices do not directly provide a physical quantity on their serial output. Let us imagine a voltmeter transmitting values between 0 and 65535 for measures between 0 and 10V. You can have the genericSensor function automatically perform an inverse conversion as illustrated below.


Linear conversion example.

This mechanism is also very useful for automatic conversions, for instance to convert feet into meters.

6.5. Configuration example

Here is a job example to interface a commercial sensor.

SST LuminOx LOX-02 oxygen sensor

The LuminOx LOX-02 oxygen sensor can measure ambient oxygen level using the principle of fluorescence quenching by oxygen, as well as temperature and pressure. It must be powered by 5V, and transmit data in serial mode using 3.3V logical levels.

The format of the data stream sent by the sensor is as follows:

O xxxx.x T yxx.x P xxxx % xxx.xx e xxxx\r\n

The number following letter O corresponds to the oxygen pressure in air in mBar, the number following letter T corresponds to the air temperature in Celsius degrees, the number following letter P corresponds to the atmospheric pressure and the number following the % sign corresponds to the matching oxygen level. The number following letter e is an eventual error code.

Step 1

Configure the Yocto-Serial to provide a 5V power supply for the sensor, and to communicate in "Line-based ASCII protocol", 9600, 8N1, using 3.3V TTL signals.


Serial port configuration for a LuminOx LOX-02

Step 2

Create a job containing a single reactive task, waiting for a custom record, that sends the four interesting values to the functions genericSensor1 to genericSensor4:


Task example to read a LuminOx LOX-02 sensor

The complete string argument to the EXPECT command is:

O ($1:FLOAT) T ($2:FLOAT) P ($3:FLOAT) % ($4:FLOAT).*

Step 3

Run the job to check that it works by displaying the functions of each module in the VirtualHub main page. If the result is not what you expected, check the module logs.

7. Programming, general concepts

The Yoctopuce API was designed to be at the same time simple to use and sufficiently generic for the concepts used to be valid for all the modules in the Yoctopuce range, and this in all the available programming languages. Therefore, when you have understood how to drive your Yocto-Serial with your favorite programming language, learning to use another module, even with a different language, will most likely take you only a minimum of time.

7.1. Programming paradigm

The Yoctopuce API is object oriented. However, for simplicity's sake, only the basics of object programming were used. Even if you are not familiar with object programming, it is unlikely that this will be a hinderance for using Yoctopuce products. Note that you will never need to allocate or deallocate an object linked to the Yoctopuce API: it is automatically managed.

There is one class per Yoctopuce function type. The name of these classes always starts with a Y followed by the name of the function, for example YTemperature, YRelay, YPressure, etc.. There is also a YModule class, dedicated to managing the modules themselves, and finally there is the static YAPI class, that supervises the global workings of the API and manages low level communications.


Structure of the Yoctopuce API.

In the Yoctopuce API, priority was put on the ease of access to the module functions by offering the possibility to make abstractions of the modules implementing them. Therefore, it is quite possible to work with a set of functions without ever knowing exactly which module are hosting them at the hardware level. This tremendously simplifies programming projects with a large number of modules.

From the programming stand point, your Yocto-Serial is viewed as a module hosting a given number of functions. In the API, these functions are objects which can be found independently, in several ways.

Access to the functions of a module

Access by logical name

Each function can be assigned an arbitrary and persistent logical name: this logical name is stored in the flash memory of the module, even if this module is disconnected. An object corresponding to an Xxx function to which a logical name has been assigned can then be directly found with this logical name and the YXxx.FindXxx method. Note however that a logical name must be unique among all the connected modules.

Access by enumeration

You can enumerate all the functions of the same type on all the connected modules with the help of the classic enumeration functions FirstXxx and nextXxxx available for each YXxx class.

Access by hardware name

Each module function has a hardware name, assigned at the factory and which cannot be modified. The functions of a module can also be found directly with this hardware name and the YXxx.FindXxx function of the corresponding class.

Difference between Find and First

The YXxx.FindXxxx and YXxx.FirstXxxx methods do not work exactly the same way. If there is no available module, YXxx.FirstXxxx returns a null value. On the opposite, even if there is no corresponding module, YXxx.FindXxxx returns a valid object, which is not online but which could become so if the corresponding module is later connected.

Function handling

When the object corresponding to a function is found, its methods are available in a classic way. Note that most of these subfunctions require the module hosting the function to be connected in order to be handled. This is generally not guaranteed, as a USB module can be disconnected after the control software has started. The isOnline method, available in all the classes, is then very helpful.

Access to the modules

Even if it is perfectly possible to build a complete project while making a total abstraction of which function is hosted on which module, the modules themselves are also accessible from the API. In fact, they can be handled in a way quite similar to the functions. They are assigned a serial number at the factory which allows you to find the corresponding object with YModule.Find(). You can also assign arbitrary logical names to the modules to make finding them easier. Finally, the YModule class contains the YModule.FirstModule() and nextModule() enumeration methods allowing you to list the connected modules.

Functions/Module interaction

From the API standpoint, the modules and their functions are strongly uncorrelated by design. Nevertheless, the API provides the possibility to go from one to the other. Thus, the get_module() method, available for each function class, allows you to find the object corresponding to the module hosting this function. Inversely, the YModule class provides several methods allowing you to enumerate the functions available on a module.

7.2. The Yocto-Serial module

The Yocto-Serial is an isolated RS232 interface with built-in datalogger.

module : Module

attributetypemodifiable ?
productName  String  read-only
serialNumber  String  read-only
logicalName  String  modifiable
productId  Hexadecimal number  read-only
productRelease  Hexadecimal number  read-only
firmwareRelease  String  read-only
persistentSettings  Enumerated  modifiable
luminosity  0..100%  modifiable
beacon  On/Off  modifiable
upTime  Time  read-only
usbCurrent  Used current (mA)  read-only
rebootCountdown  Integer  modifiable
userVar  Integer  modifiable

serialPort : SerialPort
attributetypemodifiable ?
logicalName  String  modifiable
advertisedValue  String  read-only
serialMode  Serial parameters  modifiable
protocol  Type of messaging protocol  modifiable
voltageLevel  Enumerated  modifiable
rxCount  Integer  read-only
txCount  Integer  read-only
errCount  Integer  read-only
rxMsgCount  Integer  read-only
txMsgCount  Integer  read-only
lastMsg  String  read-only
currentJob  String  modifiable
startupJob  String  modifiable
command  String  modifiable

powerOutput : PowerOutput
attributetypemodifiable ?
logicalName  String  modifiable
advertisedValue  String  read-only
voltage  Enumerated  modifiable

genericSensor1 : GenericSensor
genericSensor2 : GenericSensor
genericSensor3 : GenericSensor
genericSensor4 : GenericSensor
genericSensor5 : GenericSensor
genericSensor6 : GenericSensor
genericSensor7 : GenericSensor
genericSensor8 : GenericSensor
genericSensor9 : GenericSensor
attributetypemodifiable ?
logicalName  String  modifiable
advertisedValue  String  read-only
unit  String  modifiable
currentValue  Fixed-point number  read-only
lowestValue  Fixed-point number  modifiable
highestValue  Fixed-point number  modifiable
currentRawValue  Fixed-point number  read-only
logFrequency  Frequency  modifiable
reportFrequency  Frequency  modifiable
calibrationParam  Calibration parameters  modifiable
resolution  Fixed-point number  modifiable
signalValue  Fixed-point number  read-only
signalUnit  String  read-only
signalRange  Value range  modifiable
valueRange  Value range  modifiable
signalBias  Fixed-point number  modifiable
signalSampling  Enumerated  modifiable

dataLogger : DataLogger
attributetypemodifiable ?
logicalName  String  modifiable
advertisedValue  String  read-only
currentRunIndex  Integer  read-only
timeUTC  UTC time  modifiable
recording  On/Off  modifiable
autoStart  On/Off  modifiable
beaconDriven  On/Off  modifiable
clearHistory  Boolean  modifiable

files : Files
attributetypemodifiable ?
logicalName  String  modifiable
advertisedValue  String  read-only
filesCount  Integer  read-only
freeSpace  Integer  read-only

7.3. Module control interface

This interface is identical for all Yoctopuce USB modules. It can be used to control the module global parameters, and to enumerate the functions provided by each module.

productName

Character string containing the commercial name of the module, as set by the factory.

serialNumber

Character string containing the serial number, unique and programmed at the factory. For a Yocto-Serial module, this serial number always starts with YSERIAL1. You can use the serial number to access a given module by software.

logicalName

Character string containing the logical name of the module, initially empty. This attribute can be modified at will by the user. Once initialized to an non-empty value, it can be used to access a given module. If two modules with the same logical name are in the same project, there is no way to determine which one answers when one tries accessing by logical name. The logical name is limited to 19 characters among A..Z,a..z,0..9,_, and -.

productId

USB device identifier of the module, preprogrammed to 84 at the factory.

productRelease

Release number of the module hardware, preprogrammed at the factory.

firmwareRelease

Release version of the embedded firmware, changes each time the embedded software is updated.

persistentSettings

State of persistent module settings: loaded from flash memory, modified by the user or saved to flash memory.

luminosity

Lighting strength of the informative leds (e.g. the Yocto-Led) contained in the module. It is an integer value which varies between 0 (leds turned off) and 100 (maximum led intensity). The default value is 50. To change the strength of the module leds, or to turn them off completely, you only need to change this value.

beacon

Activity of the localization beacon of the module.

upTime

Time elapsed since the last time the module was powered on.

usbCurrent

Current consumed by the module on the USB bus, in milli-amps.

rebootCountdown

Countdown to use for triggering a reboot of the module.

userVar

32bit integer variable available for user storage.

7.4. SerialPort function interface

The SerialPort function interface allows you to fully drive a Yoctopuce serial port, to send and receive data, and to configure communication parameters (baud rate, bit count, parity, flow control and protocol). Note that Yoctopuce serial ports are not exposed as virtual COM ports. They are meant to be used in the same way as all Yoctopuce devices.

logicalName

Character string containing the logical name of the serial port, initially empty. This attribute can be modified at will by the user. Once initialized to an non-empty value, it can be used to access the serial port directly. If two serial ports with the same logical name are used in the same project, there is no way to determine which one answers when one tries accessing by logical name. The logical name is limited to 19 characters among A..Z,a..z,0..9,_, and -.

advertisedValue

Short character string summarizing the current state of the serial port, that is automatically advertised up to the parent hub. For a serial port, the advertised value is a hexadecimal signature that changes after each character received. This signature is made of the lower 16 bits of the receive counter, plus the ASCII code of the last character received.

serialMode

Baud rate, data bits, parity, and stop bits.

protocol

Type of protocol used on the serial link.

voltageLevel

Voltage level used on the serial connection.

rxCount

Total number of bytes received since last reset.

txCount

Total number of bytes transmitted since last reset.

errCount

Total number of communication errors detected since last reset.

rxMsgCount

Total number of messages received since last reset.

txMsgCount

Total number of messages transmitted since last reset.

lastMsg

Last message fully received (for Line, Frame and Modbus protocols).

currentJob

Name of the job file currently in use.

startupJob

Name of the job file to use when the device is powered on.

command

Magic attribute used to send commands to the serial port. If a command is not interpreted as expected, check the device logs.

7.5. External power supply control interface

Yoctopuce application programming interface allows you to control the power ouput featured on some device such as the Yocto-Serial.

logicalName

Character string containing the logical name of the power ouput control, initially empty. This attribute can be modified at will by the user. Once initialized to an non-empty value, it can be used to access the power ouput control directly. If two dual power ouput controls with the same logical name are used in the same project, there is no way to determine which one answers when one tries accessing by logical name. The logical name is limited to 19 characters among A..Z,a..z,0..9,_, and -.

advertisedValue

Short character string summarizing the current state of the power ouput control, that will be automatically advertised up to the parent hub. For a dual power ouput control, the advertised value is the current voltage level: OFF, 3V3 ou 5V.

voltage

Power output voltage.

7.6. GenericSensor function interface

The Yoctopuce application programming interface allows you to read an instant measure of the sensor, as well as the minimal and maximal values observed.

logicalName

Character string containing the logical name of the generic sensor, initially empty. This attribute can be modified at will by the user. Once initialized to an non-empty value, it can be used to access the generic sensor directly. If two generic sensors with the same logical name are used in the same project, there is no way to determine which one answers when one tries accessing by logical name. The logical name is limited to 19 characters among A..Z,a..z,0..9,_, and -.

advertisedValue

Short character string summarizing the current state of the generic sensor, that is automatically advertised up to the parent hub. For a generic sensor, the advertised value is the current value of the measure.

unit

Short character string representing the measuring unit for the measured value.

currentValue

Current value of the measure, in the specified unit, as a floating point number.

lowestValue

Minimal value of the measure, in the specified unit, as a floating point number.

highestValue

Maximal value of the measure, in the specified unit, as a floating point number.

currentRawValue

Uncalibrated, unrounded raw value returned by the sensor, as a floating point number.

logFrequency

Datalogger recording frequency, or "OFF" when measures should not be stored in the data logger flash memory.

reportFrequency

Timed value notification frequency, or "OFF" when timed value notifications are disabled for this function.

calibrationParam

Extra calibration parameters (for instance to compensate for the effects of an enclosure), as an array of 16 bit words.

resolution

Measure resolution (i.e. precision of the numeric representation, not necessarily of the measure itself).

signalValue

Current value of the electrical signal generated by the sensor, as a floating point number.

signalUnit

Short character string representing the measuring unit of the electrical signal used by the sensor.

signalRange

Electric signal range used by the sensor.

valueRange

Physical value range measured by the sensor, used to convert the signal.

signalBias

Electric signal bias for zero shift adjustment.

signalSampling

Signal sampling method to use.

7.7. DataLogger function interface

Yoctopuce sensors include a non-volatile memory capable of storing ongoing measured data automatically, without requiring a permanent connection to a computer. The DataLogger function controls the global parameters of the internal data logger.

logicalName

Character string containing the logical name of the data logger, initially empty. This attribute can be modified at will by the user. Once initialized to an non-empty value, it can be used to access the data logger directly. If two data loggers with the same logical name are used in the same project, there is no way to determine which one answers when one tries accessing by logical name. The logical name is limited to 19 characters among A..Z,a..z,0..9,_, and -.

advertisedValue

Short character string summarizing the current state of the data logger, that is automatically advertised up to the parent hub. For a data logger, the advertised value is its recording state (ON or OFF).

currentRunIndex

Current run number, corresponding to the number of time the module was powered on with the dataLogger enabled at some point.

timeUTC

Current UTC time, in case it is desirable to bind an absolute time reference to the data stored by the data logger. This time must be set up by software.

recording

Activation state of the data logger. The data logger can be enabled and disabled at will, using this attribute, but its state on power on is determined by the autoStart persistent attribute.

autoStart

Automatic start of the data logger on power on. Setting this attribute ensures that the data logger is always turned on when the device is powered up, without need for a software command.

beaconDriven

Synchronize the sate of the localization beacon and the state of the data logger. If this attribute is set, it is possible to start the recording with the Yocto-button or the attribute beacon of the function YModule. In the same way, if the attribute recording is changed, the sate of the localization beacon is updated. Note: when this attribute is set the localization beacon pulses slower than usual.

clearHistory

Attribute that can be set to true to clear recorded data.

7.8. Files function interface

The filesystem interface makes it possible to store files on some devices, for instance to design a custom web UI (for networked devices) or to add fonts (on display devices).

logicalName

Character string containing the logical name of the filesystem, initially empty. This attribute can be modified at will by the user. Once initialized to an non-empty value, it can be used to access the filesystem directly. If two filesystems with the same logical name are used in the same project, there is no way to determine which one answers when one tries accessing by logical name. The logical name is limited to 19 characters among A..Z,a..z,0..9,_, and -.

advertisedValue

Short character string summarizing the current state of the filesystem, that is automatically advertised up to the parent hub. For a filesystem, the advertised value is the number of files loaded in the filesystem.

filesCount

Number of files currently loaded in the filesystem.

freeSpace

Free space for uploading new files to the filesystem, in bytes.

7.9. What interface: Native, DLL or Service ?

There are several methods to control you Yoctopuce module by software.

Native control

In this case, the software driving your project is compiled directly with a library which provides control of the modules. Objectively, it is the simplest and most elegant solution for the end user. The end user then only needs to plug the USB cable and run your software for everything to work. Unfortunately, this method is not always available or even possible.


The application uses the native library to control the locally connected module

Native control by DLL

Here, the main part of the code controlling the modules is located in a DLL. The software is compiled with a small library which provides control of the DLL. It is the fastest method to code module support in a given language. Indeed, the "useful" part of the control code is located in the DLL which is the same for all languages: the effort to support a new language is limited to coding the small library which controls the DLL. From the end user stand point, there are few differences: one must simply make sure that the DLL is installed on the end user's computer at the same time as the main software.


The application uses the DLL to natively control the locally connected module

Control by service

Some languages do simply not allow you to easily gain access to the hardware layers of the machine. It is the case for Javascript, for instance. To deal with this case, Yoctopuce provides a solution in the form of a small piece of software called Virtual Hub13. It can access the modules, and your application only needs to use a library which offers all necessary functions to control the modules via this virtual hub. The end users will have to start the virtual hub before running the project control software itself, unless they decide to install the hub as a service/deamon, in which case the virtual hub starts automatically when the machine starts up.


The application connects itself to the virtual hub to gain access to the module

The service control method comes with a non-negligible advantage: the application does not need to run on the machine on which the modules are connected. The application can very well be located on another machine which connects itself to the service to drive the modules. Moreover, the native libraries and DLL mentioned above are also able to connect themselves remotely to one or several virtual hubs.


When a virtual hub is used, the control application does not need to reside on the same machine as the module.

Whatever the selected programming language and the control paradigm used, programming itself stays strictly identical. From one language to another, functions bear exactly the same name, and have the same parameters. The only differences are linked to the constraints of the languages themselves.

Language Native  Native with DLL  Virtual hub 
C++
Objective-C -
Delphi -
Python -
VisualBasic .Net -
C# .Net -
Javascript - -
Node.js - -
PHP - -
Java - -
Java for Android -
Command line -

Support methods for different languages

Limitations of the Yoctopuce libraries

Natives et DLL libraries have a technical limitation. On the same computer, you cannot concurrently run several applications accessing Yoctopuce devices directly. If you want to run several projects on the same computer, make sure your control applications use Yoctopuce devices through a VirtualHub software. The modification is trivial: it is just a matter of parameter change in the yRegisterHub() call.

7.10. Programming, where to start?

At this point of the user's guide, you should know the main theoretical points of your Yocto-Serial. It is now time to practice. You must download the Yoctopuce library for your favorite programming language from the Yoctopuce web site14. Then skip directly to the chapter corresponding to the chosen programming language.

All the examples described in this guide are available in the programming libraries. For some languages, the libraries also include some complete graphical applications, with their source code.

When you have mastered the basic programming of your module, you can turn to the chapter on advanced programming that describes some techniques that will help you make the most of your Yocto-Serial.

8. Using the Yocto-Serial in command line

When you want to perform a punctual operation on your Yocto-Serial, such as reading a value, assigning a logical name, and so on, you can obviously use the Virtual Hub, but there is a simpler, faster, and more efficient method: the command line API.

The command line API is a set of executables, one by type of functionality offered by the range of Yoctopuce products. These executables are provided pre-compiled for all the Yoctopuce officially supported platforms/OS. Naturally, the executable sources are also provided15.

8.1. Installing

Download the command line API16. You do not need to run any setup, simply copy the executables corresponding to your platform/OS in a directory of your choice. You may add this directory to your PATH variable to be able to access these executables from anywhere. You are all set, you only need to connect your Yocto-Serial, open a shell, and start working by typing for example:

C:\>YSerialPort any set_serialMode "9600,8N1"
C:\>YSerialPort any set_protocol "Line"
C:\>YSerialPort any reset
C:\>YSerialPort any writeLine "my line of data"
C:\>YSerialPort any readLine
C:\>YSerialPort any reset
 

To use the command API on Linux, you need either have root privileges or to define an udev rule for your system. See the Troubleshooting chapter for more details.

8.2. Use: general description

All the command line API executables work on the same principle. They must be called the following way


C:\>Executable [options] [target] command [parameter]

[options] manage the global workings of the commands, they allow you, for instance, to pilot a module remotely through the network, or to force the module to save its configuration after executing the command.

[target] is the name of the module or of the function to which the command applies. Some very generic commands do not need a target. You can also use the aliases "any" and "all", or a list of names separated by comas without space.

command is the command you want to run. Almost all the functions available in the classic programming APIs are available as commands. You need to respect neither the case nor the underlined characters in the command name.

[parameters] logically are the parameters needed by the command.

At any time, the command line API executables can provide a rather detailed help. Use for instance:


C:\>executable /help

to know the list of available commands for a given command line API executable, or even:


C:\>executable command /help

to obtain a detailed description of the parameters of a command.

8.3. Control of the SerialPort function

To control the SerialPort function of your Yocto-Serial, you need the YSerialPort executable file.

For instance, you can launch:

C:\>YSerialPort any set_serialMode "9600,8N1"
C:\>YSerialPort any set_protocol "Line"
C:\>YSerialPort any reset
C:\>YSerialPort any writeLine "my line of data"
C:\>YSerialPort any readLine
C:\>YSerialPort any reset
 

This example uses the "any" target to indicate that we want to work on the first SerialPort function found among all those available on the connected Yoctopuce modules when running. This prevents you from having to know the exact names of your function and of your module.

But you can use logical names as well, as long as you have configured them beforehand. Let us imagine a Yocto-Serial module with the YSERIAL1-123456 serial number which you have called "MyModule", and its serialPort function which you have renamed "MyFunction". The five following calls are strictly equivalent (as long as MyFunction is defined only once, to avoid any ambiguity).


C:\>YSerialPort YSERIAL1-123456.serialPort describe

C:\>YSerialPort YSERIAL1-123456.MyFunction describe

C:\>YSerialPort MyModule.serialPort describe

C:\>YSerialPort MyModule.MyFunction describe

C:\>YSerialPort MyFunction describe

To work on all the SerialPort functions at the same time, use the "all" target.


C:\>YSerialPort all describe

For more details on the possibilities of the YSerialPort executable, use:


C:\>YSerialPort /help

8.4. Control of the module part

Each module can be controlled in a similar way with the help of the YModule executable. For example, to obtain the list of all the connected modules, use:


C:\>YModule inventory

You can also use the following command to obtain an even more detailed list of the connected modules:


C:\>YModule all describe

Each xxx property of the module can be obtained thanks to a command of the get_xxxx() type, and the properties which are not read only can be modified with the set_xxx() command. For example:


C:\>YModule YSERIAL1-12346 set_logicalName MonPremierModule

C:\>YModule YSERIAL1-12346 get_logicalName

Changing the settings of the module

When you want to change the settings of a module, simply use the corresponding set_xxx command. However, this change happens only in the module RAM: if the module restarts, the changes are lost. To store them permanently, you must tell the module to save its current configuration in its nonvolatile memory. To do so, use the saveToFlash command. Inversely, it is possible to force the module to forget its current settings by using the revertFromFlash method. For example:


C:\>YModule YSERIAL1-12346 set_logicalName MonPremierModule
C:\>YModule YSERIAL1-12346 saveToFlash

Note that you can do the same thing in a single command with the -s option.


C:\>YModule -s  YSERIAL1-12346 set_logicalName MonPremierModule

Warning: the number of write cycles of the nonvolatile memory of the module is limited. When this limit is reached, nothing guaranties that the saving process is performed correctly. This limit, linked to the technology employed by the module micro-processor, is located at about 100000 cycles. In short, you can use the saveToFlash() function only 100000 times in the life of the module. Make sure you do not call this function within a loop.

8.5. Limitations

The command line API has the same limitation than the other APIs: there can be only one application at a given time which can access the modules natively. By default, the command line API works in native mode.

You can easily work around this limitation by using a Virtual Hub: run the VirtualHub17 on the concerned machine, and use the executables of the command line API with the -r option. For example, if you use:


C:\>YModule  inventory

you obtain a list of the modules connected by USB, using a native access. If another command which accesses the modules natively is already running, this does not work. But if you run a Virtual Hub, and you give your command in the form:


C:\>YModule -r 127.0.0.1 inventory

it works because the command is not executed natively anymore, but through the Virtual Hub. Note that the Virtual Hub counts as a native application.

9. Using Yocto-Serial with Javascript

Javascript is probably not the first language that comes to mind to control hardware, but its ease of use is a great advantage: with Javascript, you only need a text editor and a web browser to realize your first tests.

Javascript is one of those languages which do not allow you to directly access the hardware layers of your computer. Therefore you need to run the Yoctopuce TCP/IP to USB gateway, named VirtualHub, on the machine on which your modules are connected.

9.1. Getting ready

Go to the Yoctopuce web site and download the following items:

Decompress the library files in a folder of your choice, connect your modules, run the VirtualHub software, and you are ready to start your first tests. You do not need to install any driver.

9.2. Control of the SerialPort function

A few lines of code are enough to use a Yocto-Serial. Here is the skeleton of a JavaScript code snipplet to use the SerialPort function.


<SCRIPT type="text/javascript" src="yocto_api.js"></SCRIPT>
<SCRIPT type="text/javascript" src="yocto_serialport.js"></SCRIPT>

// Get access to your device, through the VirtualHub running locally
yRegisterHub('http://127.0.0.1:4444/');
var serialport = yFindSerialPort("YSERIAL1-123456.serialPort");

// Check that the module is online to handle hot-plug
if(serialport.isOnline())
{
    // Use serialport.get_serialMode(), ...
}

Let us look at these lines in more details.

yocto_api.js and yocto_serialport.js

These two Javascript includes provide access to functions allowing you to manage Yoctopuce modules. yocto_api.js must always be included, yocto_serialport.js is necessary to manage modules containing a serial port, such as Yocto-Serial.

yRegisterHub

The yRegisterHub function allows you to indicate on which machine the Yoctopuce modules are located, more precisely on which machine the VirtualHub software is running. In our case, the 127.0.0.1:4444 address indicates the local machine, port 4444 (the standard port used by Yoctopuce). You can very well modify this address, and enter the address of another machine on which the VirtualHub software is running.

yFindSerialPort

The yFindSerialPort function allows you to find a serial port from the serial number of the module on which it resides and from its function name. You can also use logical names, as long as you have initialized them. Let us imagine a Yocto-Serial module with serial number YSERIAL1-123456 which you have named "MyModule", and for which you have given the serialPort function the name "MyFunction". The following five calls are strictly equivalent, as long as "MyFunction" is defined only once.


var serialport = yFindSerialPort("YSERIAL1-123456.serialPort");
var serialport = yFindSerialPort("YSERIAL1-123456.MyFunction");
var serialport = yFindSerialPort("MyModule.serialPort");
var serialport = yFindSerialPort("MyModule.MyFunction");
var serialport = yFindSerialPort("MyFunction");

yFindSerialPort returns an object which you can then use at will to control the serial port.

isOnline

The isOnline() method of the object returned by yFindSerialPort allows you to know if the corresponding module is present and in working order.

reset

The reset() method of the objet returned by yFindSerialPort clear all internal buffers of the serial port.

readLine

The readLine() method returns the next CR/LF terminated line received on the serial port, or an empty string if no more lines are found (this function is non-blocking).

writeLine

The writeLine() method puts the specified string in the serial port output buffer, followed by CR/LF.

A real example

Open your preferred text editor20, copy the code sample below, save it in the same directory as the Yoctopuce library files and then use your preferred web browser to access this page. The code is also provided in the directory Examples/Doc-GettingStarted-Yocto-Serial of the Yoctopuce library.

In this example, you will recognize the functions explained above, but this time used with all side materials needed to make it work nicely as a small demo.

The example is coded to be used either from a web server, or directly by opening the file on the local machine. Note that this latest solution does not work with some versions of Internet Explorer, in particular IE 9 on Windows 7, which is not able to open network connections when working on a local file. In order to use Internet Explorer, you should load the example from a web server. No such problem exists with Chrome, Firefox or Safari.

If your Yocto-Serial is not connected on the host running the browser, replace in the example the address 127.0.0.1 by the IP address of the host on which the Yocto-Serial is connected and where you run the VirtualHub.

<HTML>
<HEAD>
    <TITLE>MODBUS javascript demo</TITLE>
    <SCRIPT type="text/javascript" src="../yocto_api.js"></SCRIPT>
    <SCRIPT type="text/javascript" src="../yocto_serialport.js"></SCRIPT>
    <SCRIPT language='javascript1.5' type='text/JavaScript'>
        <!--
        var slave;
        var reg;
        var serialport;

        function init(addr) {
            if (yRegisterHub(addr) != YAPI_SUCCESS)
                alert("Cannot contact VirtualHub on " + addr);

            serialport = yFirstSerialPort();

            if (serialport == null) {
                document.write('No Yocto-SerialPort  found on ' + addr);
            } else {
                document.getElementById('main').style.display = '';
                serialport.set_serialMode("9600,8N1");
                serialport.set_protocol("Line");
                serialport.reset();
            }
        }

        function send_data() {
            var tosend = document.getElementById('line_input').value;
            serialport.writeLine(tosend);
            setTimeout(read_data, 500)
        }

        function read_data() {
            var line = serialport.readLine();
            console.log("return :" + line);
            document.getElementById('returned_value').innerHTML = line;
        }


        -->
    </SCRIPT>
</HEAD>
<BODY onload='init("127.0.0.1")'>
<b>** make sure voltage levels are properly configured **</b>
<span id='main' style='display:none'>
 Type line to send<br>
 slave:<input id="line_input" onchange='javascript:send_data()'><br>
 <span id="returned_value"></span><br>
 </span>
</BODY>
</HTML>
 

9.3. Control of the module part

Each module can be controlled in a similar manner, you can find below a simple sample program displaying the main parameters of the module and enabling you to activate the localization beacon.

<HTML>
<HEAD>
 <TITLE>Module Control</TITLE>
 <SCRIPT type="text/javascript" src="yocto_api.js"></SCRIPT>
 <SCRIPT language='javascript1.5'  type='text/JavaScript'>
 <!--
 // Use explicit error handling rather than exceptions
 yDisableExceptions();

 // Setup the API to use the VirtualHub on local machine
 if(yRegisterHub('http://127.0.0.1:4444/') != YAPI_SUCCESS) {
     alert("Cannot contact VirtualHub on 127.0.0.1");
 }

 var module;

 function refresh()
 {
     var serial = document.getElementById('serial').value;
     if(serial == '') {
         // Detect any conected module suitable for the demo
         module = yFirstModule().nextModule();
         if(module) {
             serial = module.get_serialNumber();
             document.getElementById('serial').value = serial;
         }
     }

     module = yFindModule(serial);
     if(module.isOnline()) {
         document.getElementById('msg').value = '';
         var html = 'serial: '+module.get_serialNumber()+'<br>';
         html += 'logical name: '+module.get_logicalName()+'<br>';
         html += 'luminosity:'+module.get_luminosity()+'%<br>';
         html += 'beacon:';
         if (module.get_beacon()==Y_BEACON_ON)  
             html+="ON <a href='javascript:beacon(Y_BEACON_OFF)'>switch off</a><br>";
         else  
             html+="OFF <a href='javascript:beacon(Y_BEACON_ON)'>switch on</a><br>";        
         html += 'upTime: '+parseInt(module.get_upTime()/1000)+' sec<br>';
         html += 'USB current: '+module.get_usbCurrent()+' mA<br>';
         html += 'logs:<br><pre>'+module.get_lastLogs()+'</pre><br>';
         document.getElementById('data').innerHTML = html;
     } else {
         document.getElementById('msg').value = 'Module not connected';        
     }
     setTimeout('refresh()',1000);
 }

 function beacon(state)
 {
     module.set_beacon(state);
 }
 -->
 </SCRIPT>
</HEAD>  
<BODY onload='refresh();'>
 Module to use: <input id='serial'>
 <input id='msg' style='color:red;border:none;' readonly><br>
 <span id='data'></span>
</BODY>
</HTML>
 

Each property xxx of the module can be read thanks to a method of type get_xxxx(), and properties which are not read-only can be modified with the help of the set_xxx() method. For more details regarding the used functions, refer to the API chapters.

Changing the module settings

When you want to modify the settings of a module, you only need to call the corresponding set_xxx() function. However, this modification is performed only in the random access memory (RAM) of the module: if the module is restarted, the modifications are lost. To memorize them persistently, it is necessary to ask the module to save its current configuration in its permanent memory. To do so, use the saveToFlash() method. Inversely, it is possible to force the module to forget its current settings by using the revertFromFlash() method. The short example below allows you to modify the logical name of a module.

<HTML>
<HEAD>
 <TITLE>Change module settings</TITLE>
 <SCRIPT type="text/javascript" src="yocto_api.js"></SCRIPT>
 <SCRIPT    type='text/JavaScript'>
 <!--
 // Use explicit error handling rather than exceptions
 yDisableExceptions();

 // Setup the API to use the VirtualHub on local machine
 if(yRegisterHub('http://127.0.0.1:4444/') != YAPI_SUCCESS) {
     alert("Cannot contact VirtualHub on 127.0.0.1");
 }

 var module;

 function refresh()
 {
     var serial = document.getElementById('serial').value;
     if(serial == '') {
         // Detect any conected module suitable for the demo
         module = yFirstModule().nextModule();
         if(module) {
             serial = module.get_serialNumber();
             document.getElementById('serial').value = serial;
         }
     }

     module = yFindModule(serial);
     if(module.isOnline()) {
         document.getElementById('msg').value = '';
         document.getElementById('curName').value = module.get_logicalName();
     } else {
         document.getElementById('msg').value = 'Module not connected';        
     }
     setTimeout('refresh()',1000);
 }

 function save()
 {
     var newname = document.getElementById('newName').value;
     if (!yCheckLogicalName(newname)) {
         alert('invalid logical name');
         return;
     }
     module.set_logicalName(newname);
     module.saveToFlash();
 }  
 -->
 </SCRIPT>
</HEAD>  
<BODY onload='refresh();'>
 Module to use: <input id='serial'>
 <input id='msg' style='color:red;border:none;' readonly><br>
 Current name: <input id='curName' readonly><br>
 New logical name: <input id='newName'>
 <a href='javascript:save();'>Save</a>
</BODY>
</HTML>
 

Warning: the number of write cycles of the nonvolatile memory of the module is limited. When this limit is reached, nothing guaranties that the saving process is performed correctly. This limit, linked to the technology employed by the module micro-processor, is located at about 100000 cycles. In short, you can use the saveToFlash() function only 100000 times in the life of the module. Make sure you do not call this function within a loop.

Listing the modules

Obtaining the list of the connected modules is performed with the yFirstModule() function which returns the first module found. Then, you only need to call the nextModule() function of this object to find the following modules, and this as long as the returned value is not NULL. Below a short example listing the connected modules.

<HTML>
<HEAD>
 <TITLE>Modules inventory</TITLE>
 <SCRIPT type="text/javascript" src="yocto_api.js"></SCRIPT>
 <SCRIPT    type='text/JavaScript'>
 <!--
 // Use explicit error handling rather than exceptions
 yDisableExceptions();

 // Setup the API to use the VirtualHub on local machine
 if(yRegisterHub('http://127.0.0.1:4444/') != YAPI_SUCCESS) {
     alert("Cannot contact VirtualHub on 127.0.0.1");
 }

 function refresh()
 {
     yUpdateDeviceList();

     var htmlcode = '';
     var module = yFirstModule();
     while(module) {
         htmlcode += module.get_serialNumber()
                     +'('+module.get_productName()+")<br>";
         module = module.nextModule();
     }
     document.getElementById('list').innerHTML=htmlcode;
     setTimeout('refresh()',500);
 }
 -->
 </SCRIPT>
</HEAD>  
<BODY onload='refresh();'>
 <H1>Device list</H1>
 <tt><span id='list'></span></tt>
</BODY>
</HTML>
 

9.4. Error handling

When you implement a program which must interact with USB modules, you cannot disregard error handling. Inevitably, there will be a time when a user will have unplugged the device, either before running the software, or even while the software is running. The Yoctopuce library is designed to help you support this kind of behavior, but your code must nevertheless be conceived to interpret in the best possible way the errors indicated by the library.

The simplest way to work around the problem is the one used in the short examples provided in this chapter: before accessing a module, check that it is online with the isOnline function, and then hope that it will stay so during the fraction of a second necessary for the following code lines to run. This method is not perfect, but it can be sufficient in some cases. You must however be aware that you cannot completely exclude an error which would occur after the call to isOnline and which could crash the software. The only way to prevent this is to implement one of the two error handling techniques described below.

The method recommended by most programming languages for unpredictable error handling is the use of exceptions. By default, it is the behavior of the Yoctopuce library. If an error happens while you try to access a module, the library throws an exception. In this case, there are three possibilities:

As this latest situation is not the most desirable, the Yoctopuce library offers another possibility for error handling, allowing you to create a robust program without needing to catch exceptions at every line of code. You simply need to call the yDisableExceptions() function to commute the library to a mode where exceptions for all the functions are systematically replaced by specific return values, which can be tested by the caller when necessary. For each function, the name of each return value in case of error is systematically documented in the library reference. The name always follows the same logic: a get_state() method returns a Y_STATE_INVALID value, a get_currentValue method returns a Y_CURRENTVALUE_INVALID value, and so on. In any case, the returned value is of the expected type and is not a null pointer which would risk crashing your program. At worst, if you display the value without testing it, it will be outside the expected bounds for the returned value. In the case of functions which do not normally return information, the return value is YAPI_SUCCESS if everything went well, and a different error code in case of failure.

When you work without exceptions, you can obtain an error code and an error message explaining the source of the error. You can request them from the object which returned the error, calling the errType() and errMessage() methods. Their returned values contain the same information as in the exceptions when they are active.

10. Using Yocto-Serial with PHP

PHP is, like Javascript, an atypical language when interfacing with hardware is at stakes. Nevertheless, using PHP with Yoctopuce modules provides you with the opportunity to very easily create web sites which are able to interact with their physical environment, and this is not available to every web server. This technique has a direct application in home automation: a few Yoctopuce modules, a PHP server, and you can interact with your home from anywhere on the planet, as long as you have an internet connection.

PHP is one of those languages which do not allow you to directly access the hardware layers of your computer. Therefore you need to run a virtual hub on the machine on which your modules are connected.

To start your tests with PHP, you need a PHP 5.3 (or more) server21, preferably locally on you machine. If you wish to use the PHP server of your internet provider, it is possible, but you will probably need to configure your ADSL router for it to accept and forward TCP request on the 4444 port.

10.1. Getting ready

Go to the Yoctopuce web site and download the following items:

Decompress the library files in a folder of your choice accessible to your web server, connect your modules, run the VirtualHub software, and you are ready to start your first tests. You do not need to install any driver.

10.2. Control of the SerialPort function

A few lines of code are enough to use a Yocto-Serial. Here is the skeleton of a PHP code snipplet to use the SerialPort function.


include('yocto_api.php');
include('yocto_serialport.php');

// Get access to your device, through the VirtualHub running locally
yRegisterHub('http://127.0.0.1:4444/',$errmsg);
$serialport = yFindSerialPort("YSERIAL1-123456.serialPort");

// Check that the module is online to handle hot-plug
if(serialport->isOnline())
{
    // Use serialport->get_serialMode(), ...
}

Let's look at these lines in more details.

yocto_api.php and yocto_serialport.php

These two PHP includes provides access to the functions allowing you to manage Yoctopuce modules. yocto_api.php must always be included, yocto_serialport.php is necessary to manage modules containing a serial port, such as Yocto-Serial.

yRegisterHub

The yRegisterHub function allows you to indicate on which machine the Yoctopuce modules are located, more precisely on which machine the VirtualHub software is running. In our case, the 127.0.0.1:4444 address indicates the local machine, port 4444 (the standard port used by Yoctopuce). You can very well modify this address, and enter the address of another machine on which the VirtualHub software is running.

yFindSerialPort

The yFindSerialPort function allows you to find a serial port from the serial number of the module on which it resides and from its function name. You can use logical names as well, as long as you have initialized them. Let us imagine a Yocto-Serial module with serial number YSERIAL1-123456 which you have named "MyModule", and for which you have given the serialPort function the name "MyFunction". The following five calls are strictly equivalent, as long as "MyFunction" is defined only once.


$serialport = yFindSerialPort("YSERIAL1-123456.serialPort");
$serialport = yFindSerialPort("YSERIAL1-123456.MyFunction");
$serialport = yFindSerialPort("MyModule.serialPort");
$serialport = yFindSerialPort("MyModule.MyFunction");
$serialport = yFindSerialPort("MyFunction");

yFindSerialPort returns an object which you can then use at will to control the serial port.

isOnline

The isOnline() method of the object returned by yFindSerialPort allows you to know if the corresponding module is present and in working order.

reset

The reset() method of the objet returned by yFindSerialPort clear all internal buffers of the serial port.

readLine

The readLine() method returns the next CR/LF terminated line received on the serial port, or an empty string if no more lines are found (this function is non-blocking).

writeLine

The writeLine() method puts the specified string in the serial port output buffer, followed by CR/LF.

A real example

Open your preferred text editor24, copy the code sample below, save it with the Yoctopuce library files in a location which is accessible to you web server, then use your preferred web browser to access this page. The code is also provided in the directory Examples/Doc-GettingStarted-Yocto-Serial of the Yoctopuce library.

In this example, you will recognize the functions explained above, but this time used with all side materials needed to make it work nicely as a small demo.

<HTML>
<HEAD>
    <TITLE>Hello World</TITLE>
</HEAD>
<BODY>
<FORM method='get'>
    <?php
    include('../yocto_api.php');
    include('../yocto_serialport.php');

    // Use explicit error handling rather than exceptions
    yDisableExceptions();

    $address = '127.0.0.1';

    // Setup the API to use the VirtualHub on local machine,
    if(yRegisterHub($address, $errmsg) != YAPI_SUCCESS) {
        die("Cannot contact $address");
    }

    $serialPort = YSerialPort::FirstSerialPort();
    if($serialPort == null)
        die("No module found on $address (check USB cable)");
    print('<b>** make sure voltage levels are properly configured **</b>');
    print('Type line to send<br>');
    print("<input name='tosend'>");
    if(isset($_GET["tosend"])) {
        $tosend = $_GET["tosend"];
        $serialPort->writeLine($tosend);
        YAPI::Sleep(500);
        do {
            $line = $serialPort->readLine();
            if($line != "") {
               print("Received: " . $line . "<br/>");
            }
        } while ($line != '');
    } else {
        $serialPort->set_serialMode("9600,8N1");
        $serialPort->set_protocol("Line");
        $serialPort->reset();
    }
    ?>
    <input type='submit'>

</FORM>
</BODY>
</HTML>
 

10.3. Control of the module part

Each module can be controlled in a similar manner, you can find below a simple sample program displaying the main parameters of the module and enabling you to activate the localization beacon.

<HTML>
<HEAD>
 <TITLE>Module Control</TITLE>
</HEAD>
<BODY>
<FORM method='get'>
<?php
  include('yocto_api.php');

  // Use explicit error handling rather than exceptions
  yDisableExceptions();

  // Setup the API to use the VirtualHub on local machine
  if(yRegisterHub('http://127.0.0.1:4444/',$errmsg) != YAPI_SUCCESS) {
      die("Cannot contact VirtualHub on 127.0.0.1 : ".$errmsg);
  }

  @$serial = $_GET['serial'];
  if ($serial != '') {
      // Check if a specified module is available online
      $module = yFindModule("$serial");  
      if (!$module->isOnline()) {
          die("Module not connected (check serial and USB cable)");
      }
  } else {
      // or use any connected module suitable for the demo
      $module = yFirstModule();
      if($module) { // skip VirtualHub
          $module = $module->nextModule();
      }
      if(is_null($module)) {
          die("No module connected (check USB cable)");
      } else {
          $serial = $module->get_serialnumber();
      }
  }
  Print("Module to use: <input name='serial' value='$serial'><br>");

  if (isset($_GET['beacon'])) {
      if ($_GET['beacon']=='ON')
          $module->set_beacon(Y_BEACON_ON);
      else  
          $module->set_beacon(Y_BEACON_OFF);
  }          
  printf('serial: %s<br>',$module->get_serialNumber());
  printf('logical name: %s<br>',$module->get_logicalName());
  printf('luminosity: %s<br>',$module->get_luminosity());
  print('beacon: ');
  if($module->get_beacon() == Y_BEACON_ON) {
      printf("<input type='radio' name='beacon' value='ON' checked>ON ");
      printf("<input type='radio' name='beacon' value='OFF'>OFF<br>");
  } else {
      printf("<input type='radio' name='beacon' value='ON'>ON ");
      printf("<input type='radio' name='beacon' value='OFF' checked>OFF<br>");
  }
  printf('upTime: %s sec<br>',intVal($module->get_upTime()/1000));
  printf('USB current: %smA<br>',$module->get_usbCurrent());
  printf('logs:<br><pre>%s</pre>',$module->get_lastLogs());
?>  
<input type='submit' value='refresh'>
</FORM>
</BODY>
</HTML>
 

Each property xxx of the module can be read thanks to a method of type get_xxxx(), and properties which are not read-only can be modified with the help of the set_xxx() method. For more details regarding the used functions, refer to the API chapters.

Changing the module settings

When you want to modify the settings of a module, you only need to call the corresponding set_xxx() function. However, this modification is performed only in the random access memory (RAM) of the module: if the module is restarted, the modifications are lost. To memorize them persistently, it is necessary to ask the module to save its current configuration in its permanent memory. To do so, use the saveToFlash() method. Inversely, it is possible to force the module to forget its current settings by using the revertFromFlash() method. The short example below allows you to modify the logical name of a module.

<HTML>
<HEAD>
 <TITLE>save settings</TITLE>
<BODY>
<FORM method='get'>
<?php
  include('yocto_api.php');
 
  // Use explicit error handling rather than exceptions
  yDisableExceptions();

  // Setup the API to use the VirtualHub on local machine
  if(yRegisterHub('http://127.0.0.1:4444/',$errmsg) != YAPI_SUCCESS) {
      die("Cannot contact VirtualHub on 127.0.0.1");
  }

  @$serial = $_GET['serial'];
  if ($serial != '') {
      // Check if a specified module is available online
      $module = yFindModule("$serial");  
      if (!$module->isOnline()) {
          die("Module not connected (check serial and USB cable)");
      }
  } else {
      // or use any connected module suitable for the demo
      $module = yFirstModule();
      if($module) { // skip VirtualHub
          $module = $module->nextModule();
      }
      if(is_null($module)) {
          die("No module connected (check USB cable)");
      } else {
          $serial = $module->get_serialnumber();
      }
  }
  Print("Module to use: <input name='serial' value='$serial'><br>");

  if (isset($_GET['newname'])){
      $newname = $_GET['newname'];
      if (!yCheckLogicalName($newname))
          die('Invalid name');
      $module->set_logicalName($newname);
      $module->saveToFlash();
  }
  printf("Current name: %s<br>", $module->get_logicalName());
  print("New name: <input name='newname' value='' maxlength=19><br>");
?>
<input type='submit'>
</FORM>
</BODY>
</HTML>
 

Warning: the number of write cycles of the nonvolatile memory of the module is limited. When this limit is reached, nothing guaranties that the saving process is performed correctly. This limit, linked to the technology employed by the module micro-processor, is located at about 100000 cycles. In short, you can use the saveToFlash() function only 100000 times in the life of the module. Make sure you do not call this function within a loop.

Listing the modules

Obtaining the list of the connected modules is performed with the yFirstModule() function which returns the first module found. Then, you only need to call the nextModule() function of this object to find the following modules, and this as long as the returned value is not NULL. Below a short example listing the connected modules.

<HTML>
<HEAD>
    <TITLE>inventory</TITLE>
</HEAD>
<BODY>
<H1>Device list</H1>
<pre>
    <?php
    include('yocto_api.php');
    yRegisterHub("http://127.0.0.1:4444/");
    /** @var YModule $module */
    $module = yFirstModule();
    while (!is_null($module)) {
        printf("%s (%s)<br>", $module->get_serialNumber(),
            $module->get_productName());
        $module->set_beacon(YModule::BEACON_ON);
        $settings = $module->get_allSettings();
        $module->set_allSettings($settings);
        $module = $module->nextModule();
    }
    ?>
</pre>
</BODY>
</HTML>
 

10.4. HTTP callback API and NAT filters

The PHP library is able to work in a specific mode called HTTP callback Yocto-API. With this mode, you can control Yoctopuce devices installed behind a NAT filter, such as a DSL router for example, and this without needing to open a port. The typical application is to control Yoctopuce devices, located on a private network, from a public web site.

The NAT filter: advantages and disadvantages

A DSL router which translates network addresses (NAT) works somewhat like a private phone switchboard (a PBX): internal extensions can call each other and call the outside; but seen from the outside, there is only one official phone number, that of the switchboard itself. You cannot reach the internal extensions from the outside.


Typical DSL configuration: LAN machines are isolated from the outside by the DSL router

Transposed to the network, we have the following: appliances connected to your home automation network can communicate with one another using a local IP address (of the 192.168.xxx.yyy type), and contact Internet servers through their public address. However, seen from the outside, you have only one official IP address, assigned to the DSL router only, and you cannot reach your network appliances directly from the outside. It is rather restrictive, but it is a relatively efficient protection against intrusions.


Responses from request from LAN machines are routed.


But requests from the outside are blocked.

Seeing Internet without being seen provides an enormous security advantage. However, this signifies that you cannot, a priori, set up your own web server at home to control a home automation installation from the outside. A solution to this problem, advised by numerous home automation system dealers, consists in providing outside visibility to your home automation server itself, by adding a routing rule in the NAT configuration of the DSL router. The issue of this solution is that it exposes the home automation server to external attacks.

The HTTP callback API solves this issue without having to modify the DSL router configuration. The module control script is located on an external site, and it is the VirtualHub which is in charge of calling it a regular intervals.


The HTTP callback API uses the VirtualHub which initiates the requests.

Configuration

The callback API thus uses the VirtualHub as a gateway. All the communications are initiated by the VirtualHub. They are thus outgoing communications and therefore perfectly authorized by the DSL router.

You must configure the VirtualHub so that it calls the PHP script on a regular basis. To do so:

  1. Launch a VirtualHub
  2. Access its interface, usually 127.0.0.1:4444
  3. Click on the configure button of the line corresponding to the VirtualHub itself
  4. Click on the edit button of the Outgoing callbacks section


Click on the "configure" button on the first line


Click on the "edit" button of the "Outgoing callbacks" section


And select "Yocto-API callback".

You then only need to define the URL of the PHP script and, if need be, the user name and password to access this URL. Supported authentication methods are basic and digest. The second method is safer than the first one because it does not allow transfer of the password on the network.

Usage

From the programmer standpoint, the only difference is at the level of the yRegisterHub function call. Instead of using an IP address, you must use the callback string (or http://callback which is equivalent).


include("yocto_api.php");
yRegisterHub("callback");

The remainder of the code stays strictly identical. On the VirtualHub interface, at the bottom of the configuration window for the HTTP callback API , there is a button allowing you to test the call to the PHP script.

Be aware that the PHP script controlling the modules remotely through the HTTP callback API can be called only by the VirtualHub. Indeed, it requires the information posted by the VirtualHub to function. To code a web site which controls Yoctopuce modules interactively, you must create a user interface which stores in a file or in a database the actions to be performed on the Yoctopuce modules. These actions are then read and run by the control script.

Common issues

For the HTTP callback API to work, the PHP option allow_url_fopen must be set. Some web site hosts do not set it by default. The problem then manifests itself with the following error:

error: URL file-access is disabled in the server configuration

To set this option, you must create, in the repertory where the control PHP script is located, an .htaccess file containing the following line:
php_flag "allow_url_fopen" "On"
Depending on the security policies of the host, it is sometimes impossible to authorize this option at the root of the web site, or even to install PHP scripts receiving data from a POST HTTP. In this case, place the PHP script in a subdirectory.

Limitations

This method that allows you to go through NAT filters cheaply has nevertheless a price. Communications being initiated by the VirtualHub at a more or less regular interval, reaction time to an event is clearly longer than if the Yoctopuce modules were driven directly. You can configure the reaction time in the specific window of the VirtualHub, but it is at least of a few seconds in the best case.

The HTTP callback Yocto-API mode is currently available in PHP and Node.JS only.

10.5. Error handling

When you implement a program which must interact with USB modules, you cannot disregard error handling. Inevitably, there will be a time when a user will have unplugged the device, either before running the software, or even while the software is running. The Yoctopuce library is designed to help you support this kind of behavior, but your code must nevertheless be conceived to interpret in the best possible way the errors indicated by the library.

The simplest way to work around the problem is the one used in the short examples provided in this chapter: before accessing a module, check that it is online with the isOnline function, and then hope that it will stay so during the fraction of a second necessary for the following code lines to run. This method is not perfect, but it can be sufficient in some cases. You must however be aware that you cannot completely exclude an error which would occur after the call to isOnline and which could crash the software. The only way to prevent this is to implement one of the two error handling techniques described below.

The method recommended by most programming languages for unpredictable error handling is the use of exceptions. By default, it is the behavior of the Yoctopuce library. If an error happens while you try to access a module, the library throws an exception. In this case, there are three possibilities:

As this latest situation is not the most desirable, the Yoctopuce library offers another possibility for error handling, allowing you to create a robust program without needing to catch exceptions at every line of code. You simply need to call the yDisableExceptions() function to commute the library to a mode where exceptions for all the functions are systematically replaced by specific return values, which can be tested by the caller when necessary. For each function, the name of each return value in case of error is systematically documented in the library reference. The name always follows the same logic: a get_state() method returns a Y_STATE_INVALID value, a get_currentValue method returns a Y_CURRENTVALUE_INVALID value, and so on. In any case, the returned value is of the expected type and is not a null pointer which would risk crashing your program. At worst, if you display the value without testing it, it will be outside the expected bounds for the returned value. In the case of functions which do not normally return information, the return value is YAPI_SUCCESS if everything went well, and a different error code in case of failure.

When you work without exceptions, you can obtain an error code and an error message explaining the source of the error. You can request them from the object which returned the error, calling the errType() and errMessage() methods. Their returned values contain the same information as in the exceptions when they are active.

11. Using Yocto-Serial with C++

C++ is not the simplest language to master. However, if you take care to limit yourself to its essential functionalities, this language can very well be used for short programs quickly coded, and it has the advantage of being easily ported from one operating system to another. Under Windows, all the examples and the project models are tested with Microsoft Visual Studio 2010 Express, freely available on the Microsoft web site25. Under Mac OS X, all the examples and project models are tested with XCode 4, available on the App Store. Moreover, under Max OS X and under Linux, you can compile the examples using a command line with GCC using the provided GNUmakefile. In the same manner under Windows, a Makefile allows you to compile examples using a command line, fully knowing the compilation and linking arguments.

Yoctopuce C++ libraries26 are integrally provided as source files. A section of the low-level library is written in pure C, but you should not need to interact directly with it: everything was done to ensure the simplest possible interaction from C++. The library is naturally also available as binary files, so that you can link it directly if you prefer.

You will soon notice that the C++ API defines many functions which return objects. You do not need to deallocate these objects yourself, the API does it automatically at the end of the application.

In order to keep them simple, all the examples provided in this documentation are console applications. Naturally, the libraries function in a strictly identical manner if you integrate them in an application with a graphical interface. You will find in the last section of this chapter all the information needed to create a wholly new project linked with the Yoctopuce libraries.

11.1. Control of the SerialPort function

A few lines of code are enough to use a Yocto-Serial. Here is the skeleton of a C++ code snipplet to use the SerialPort function.


#include "yocto_api.h"
#include "yocto_serialport.h"

[...]
String  errmsg;
YSerialPort *serialport;

// Get access to your device, connected locally on USB for instance
yRegisterHub("usb", errmsg);
serialport = yFindSerialPort("YSERIAL1-123456.serialPort");

// Hot-plug is easy: just check that the device is online
if(serialport->isOnline())
{
    // Use serialport->get_serialMode(), ...
}

Let's look at these lines in more details.

yocto_api.h et yocto_serialport.h

These two include files provide access to the functions allowing you to manage Yoctopuce modules. yocto_api.h must always be used, yocto_serialport.h is necessary to manage modules containing a serial port, such as Yocto-Serial.

yRegisterHub

The yRegisterHub function initializes the Yoctopuce API and indicates where the modules should be looked for. When used with the parameter "usb", it will use the modules locally connected to the computer running the library. If the initialization does not succeed, this function returns a value different from YAPI_SUCCESS and errmsg contains the error message.

yFindSerialPort

The yFindSerialPort function allows you to find a serial port from the serial number of the module on which it resides and from its function name. You can use logical names as well, as long as you have initialized them. Let us imagine a Yocto-Serial module with serial number YSERIAL1-123456 which you have named "MyModule", and for which you have given the serialPort function the name "MyFunction". The following five calls are strictly equivalent, as long as "MyFunction" is defined only once.


YSerialPort *serialport = yFindSerialPort("YSERIAL1-123456.serialPort");
YSerialPort *serialport = yFindSerialPort("YSERIAL1-123456.MyFunction");
YSerialPort *serialport = yFindSerialPort("MyModule.serialPort");
YSerialPort *serialport = yFindSerialPort("MyModule.MyFunction");
YSerialPort *serialport = yFindSerialPort("MyFunction");

yFindSerialPort returns an object which you can then use at will to control the serial port.

isOnline

The isOnline() method of the object returned by yFindSerialPort allows you to know if the corresponding module is present and in working order.

reset

The reset() method of the objet returned by yFindSerialPort clear all internal buffers of the serial port.

readLine

The readLine() method returns the next CR/LF terminated line received on the serial port, or an empty string if no more lines are found (this function is non-blocking).

writeLine

The writeLine() method puts the specified string in the serial port output buffer, followed by CR/LF.

A real example

Launch your C++ environment and open the corresponding sample project provided in the directory Examples/Doc-GettingStarted-Yocto-Serial of the Yoctopuce library. If you prefer to work with your favorite text editor, open the file main.cpp, and type make to build the example when you are done.

In this example, you will recognize the functions explained above, but this time used with all side materials needed to make it work nicely as a small demo.

#include "yocto_api.h"
#include "yocto_serialport.h"
#include <iostream>
#include <stdlib.h>

using namespace std;

int main(int argc, const char * argv[])
{
    string errmsg;
    string target;
    YSerialPort *serialPort;

    // Setup the API to use local USB devices
    if (yRegisterHub("usb", errmsg) != YAPI_SUCCESS) {
        cerr << "RegisterHub error: " << errmsg << endl;
        return 1;
    }

    if (argc > 1) {
        target = (string) argv[1];
        serialPort = yFindSerialPort(target + ".serialPort");
    } else {
        serialPort = yFirstSerialPort();
        if (serialPort == NULL) {
            cerr <<"No module connected (check USB cable)"<<endl;
            return 1;
        }
    }

    cout << "****************************" << endl;
    cout << "* make sure voltage levels *" << endl;
    cout << "* are properly configured  *" << endl;
    cout << "****************************" << endl;
   
    serialPort->set_serialMode("9600,8N1");
    serialPort->set_protocol("Line");
    serialPort->reset();

    string line;
    do {
        ySleep(500, errmsg);
        do {
            line = serialPort->readLine();
            if(line != "") {
                cout << "Received: " << line << endl;
            }
        } while(line != "");

        cout << "Type line to send, or Ctrl-C to exit:";
        cin >> line;
        serialPort->writeLine(line);
    } while(line != "");

    yFreeAPI();
    return 0;
}
 

11.2. Control of the module part

Each module can be controlled in a similar manner, you can find below a simple sample program displaying the main parameters of the module and enabling you to activate the localization beacon.

#include <iostream>
#include <stdlib.h>

#include "yocto_api.h"

using namespace std;

static void usage(const char *exe)
{
    cout << "usage: " << exe << " <serial or logical name> [ON/OFF]" << endl;
    exit(1);
}


int main(int argc, const char * argv[])
{
    string      errmsg;

    // Setup the API to use local USB devices
    if(yRegisterHub("usb", errmsg) != YAPI_SUCCESS) {
        cerr << "RegisterHub error: " << errmsg << endl;
        return 1;
    }

    if(argc < 2)
        usage(argv[0]);

    YModule *module = yFindModule(argv[1]);  // use serial or logical name
 
    if (module->isOnline()) {
        if (argc > 2) {
            if (string(argv[2]) == "ON")
                module->set_beacon(Y_BEACON_ON);
            else  
                module->set_beacon(Y_BEACON_OFF);
        }          
        cout << "serial:       " << module->get_serialNumber() << endl;
        cout << "logical name: " << module->get_logicalName() << endl;
        cout << "luminosity:   " << module->get_luminosity() << endl;
        cout << "beacon:       ";
        if (module->get_beacon()==Y_BEACON_ON)  
           cout << "ON" << endl;
        else  
           cout << "OFF" << endl;
        cout << "upTime:       " << module->get_upTime()/1000 << " sec" << endl;
        cout << "USB current:  " << module->get_usbCurrent() << " mA" << endl;
        cout << "Logs:"<< endl << module->get_lastLogs() << endl;
    } else {
        cout << argv[1] << " not connected (check identification and USB cable)"
             << endl;
    }
    return 0;
}
 

Each property xxx of the module can be read thanks to a method of type get_xxxx(), and properties which are not read-only can be modified with the help of the set_xxx() method. For more details regarding the used functions, refer to the API chapters.

Changing the module settings

When you want to modify the settings of a module, you only need to call the corresponding set_xxx() function. However, this modification is performed only in the random access memory (RAM) of the module: if the module is restarted, the modifications are lost. To memorize them persistently, it is necessary to ask the module to save its current configuration in its permanent memory. To do so, use the saveToFlash() method. Inversely, it is possible to force the module to forget its current settings by using the revertFromFlash() method. The short example below allows you to modify the logical name of a module.

#include <iostream>
#include <stdlib.h>

#include "yocto_api.h"

using namespace std;

static void usage(const char *exe)
{
    cerr << "usage: " << exe << " <serial> <newLogicalName>" << endl;
    exit(1);
}

int main(int argc, const char * argv[])
{
    string      errmsg;

    // Setup the API to use local USB devices
    if(yRegisterHub("usb", errmsg) != YAPI_SUCCESS) {
        cerr << "RegisterHub error: " << errmsg << endl;
        return 1;
    }

    if(argc < 2)
        usage(argv[0]);

    YModule *module = yFindModule(argv[1]);  // use serial or logical name
 
    if (module->isOnline()) {
        if (argc >= 3){
            string newname =  argv[2];
            if (!yCheckLogicalName(newname)){
                cerr << "Invalid name (" << newname << ")" << endl;
                usage(argv[0]);
            }
            module->set_logicalName(newname);
            module->saveToFlash();
        }
        cout << "Current name: " << module->get_logicalName() << endl;
    } else {
        cout << argv[1] << " not connected (check identification and USB cable)"
             << endl;
    }
    return 0;
}
 

Warning: the number of write cycles of the nonvolatile memory of the module is limited. When this limit is reached, nothing guaranties that the saving process is performed correctly. This limit, linked to the technology employed by the module micro-processor, is located at about 100000 cycles. In short, you can use the saveToFlash() function only 100000 times in the life of the module. Make sure you do not call this function within a loop.

Listing the modules

Obtaining the list of the connected modules is performed with the yFirstModule() function which returns the first module found. Then, you only need to call the nextModule() function of this object to find the following modules, and this as long as the returned value is not NULL. Below a short example listing the connected modules.

#include <iostream>

#include "yocto_api.h"

using namespace std;

int main(int argc, const char * argv[])
{
    string      errmsg;

    // Setup the API to use local USB devices
    if(YAPI::RegisterHub("usb", errmsg) != YAPI_SUCCESS) {
        cerr << "RegisterHub error: " << errmsg << endl;
        return 1;
    }

    cout << "Device list: " << endl;

    YModule *module = YModule::FirstModule();
    while (module != NULL) {
        cout << module->get_serialNumber() << " ";
        cout << module->get_productName()  << endl;
        module = module->nextModule();
    }
    return 0;
}
 

11.3. Error handling

When you implement a program which must interact with USB modules, you cannot disregard error handling. Inevitably, there will be a time when a user will have unplugged the device, either before running the software, or even while the software is running. The Yoctopuce library is designed to help you support this kind of behavior, but your code must nevertheless be conceived to interpret in the best possible way the errors indicated by the library.

The simplest way to work around the problem is the one used in the short examples provided in this chapter: before accessing a module, check that it is online with the isOnline function, and then hope that it will stay so during the fraction of a second necessary for the following code lines to run. This method is not perfect, but it can be sufficient in some cases. You must however be aware that you cannot completely exclude an error which would occur after the call to isOnline and which could crash the software. The only way to prevent this is to implement one of the two error handling techniques described below.

The method recommended by most programming languages for unpredictable error handling is the use of exceptions. By default, it is the behavior of the Yoctopuce library. If an error happens while you try to access a module, the library throws an exception. In this case, there are three possibilities:

As this latest situation is not the most desirable, the Yoctopuce library offers another possibility for error handling, allowing you to create a robust program without needing to catch exceptions at every line of code. You simply need to call the yDisableExceptions() function to commute the library to a mode where exceptions for all the functions are systematically replaced by specific return values, which can be tested by the caller when necessary. For each function, the name of each return value in case of error is systematically documented in the library reference. The name always follows the same logic: a get_state() method returns a Y_STATE_INVALID value, a get_currentValue method returns a Y_CURRENTVALUE_INVALID value, and so on. In any case, the returned value is of the expected type and is not a null pointer which would risk crashing your program. At worst, if you display the value without testing it, it will be outside the expected bounds for the returned value. In the case of functions which do not normally return information, the return value is YAPI_SUCCESS if everything went well, and a different error code in case of failure.

When you work without exceptions, you can obtain an error code and an error message explaining the source of the error. You can request them from the object which returned the error, calling the errType() and errMessage() methods. Their returned values contain the same information as in the exceptions when they are active.

11.4. Integration variants for the C++ Yoctopuce library

Depending on your needs and on your preferences, you can integrate the library into your projects in several distinct manners. This section explains how to implement the different options.

Integration in source format

Integrating all the sources of the library into your projects has several advantages:

To integrate the source code, the easiest way is to simply include the Sources directory of your Yoctopuce library into your IncludePath, and to add all the files of this directory (including the sub-directory yapi) to your project.

For your project to build correctly, you need to link with your project the prerequisite system libraries, that is:

Integration as a static library

Integration of the Yoctopuce library as a static library is a simpler manner to build a small executable which uses Yoctopuce modules. You can quickly compile the program with a single command. You do not need to install a dynamic library specific to Yoctopuce, everything is in the executable.

To integrate the static Yoctopuce library to your project, you must include the Sources directory of the Yoctopuce library into your IncludePath, and add the sub-directory Binaries/... corresponding to your operating system into your libPath.

Then, for you project to build correctly, you need to link with your project the Yoctopuce library and the prerequisite system libraries:

Note, under Linux, if you wish to compile in command line with GCC, it is generally advisable to link system libraries as dynamic libraries, rather than as static ones. To mix static and dynamic libraries on the same command line, you must pass the following arguments:

gcc (...) -Wl,-Bstatic -lyocto-static -Wl,-Bdynamic -lm -lpthread -lusb-1.0 -lstdc++

Integration as a dynamic library

Integration of the Yoctopuce library as a dynamic library allows you to produce an executable smaller than with the two previous methods, and to possibly update this library, if a patch reveals itself necessary, without needing to recompile the source code of the application. On the other hand, it is an integration mode which systematically requires you to copy the dynamic library on the target machine where the application will run (yocto.dll for Windows, libyocto.so.1.0.1 for Mac OS X and Linux).

To integrate the dynamic Yoctopuce library to your project, you must include the Sources directory of the Yoctopuce library into your IncludePath, and add the sub-directory Binaries/... corresponding to your operating system into your LibPath.

Then, for you project to build correctly, you need to link with your project the dynamic Yoctopuce library and the prerequisite system libraries:

With GCC, the command line to compile is simply:

gcc (...) -lyocto -lm -lpthread -lusb-1.0 -lstdc++

12. Using Yocto-Serial with Objective-C

Objective-C is language of choice for programming on Mac OS X, due to its integration with the Cocoa framework. In order to use the Objective-C library, you need XCode version 4.2 (earlier versions will not work), available freely when you run Lion. If you are still under Snow Leopard, you need to be registered as Apple developer to be able to download XCode 4.2. The Yoctopuce library is ARC compatible. You can therefore implement your projects either using the traditional retain / release method, or using the Automatic Reference Counting.

Yoctopuce Objective-C libraries27 are integrally provided as source files. A section of the low-level library is written in pure C, but you should not need to interact directly with it: everything was done to ensure the simplest possible interaction from Objective-C.

You will soon notice that the Objective-C API defines many functions which return objects. You do not need to deallocate these objects yourself, the API does it automatically at the end of the application.

In order to keep them simple, all the examples provided in this documentation are console applications. Naturally, the libraries function in a strictly identical manner if you integrate them in an application with a graphical interface. You can find on Yoctopuce blog a detailed example28 with video shots showing how to integrate the library into your projects.

12.1. Control of the SerialPort function

Launch Xcode 4.2 and open the corresponding sample project provided in the directory Examples/Doc-GettingStarted-Yocto-Serial of the Yoctopuce library.

#import <Foundation/Foundation.h>
#import "yocto_api.h"
#import "yocto_serialport.h"


int main(int argc, const char * argv[])
{
   
    @autoreleasepool{
        NSError *error;
        // Setup the API to use local USB devices
        if([YAPI RegisterHub:@"usb": &error] != YAPI_SUCCESS) {
            NSLog(@"RegisterHub error: %@", [error localizedDescription]);
            return 1;
        }
       
        YSerialPort *serialPort;
        if (argc > 1) {
            NSString     *target = [NSString stringWithUTF8String:argv[1]];
            serialPort = [YSerialPort FindSerialPort:target];
        } else {
            serialPort = [YSerialPort FirstSerialPort];
            if (serialPort == NULL) {
                NSLog(@"No module connected (check USB cable)");
                return 1;
            }
        }
       
        [serialPort set_serialMode:@"9600,8N1"];
        [serialPort set_protocol:@"Line"];
        [serialPort reset];
       
        NSLog(@"****************************");
        NSLog(@"* make sure voltage levels *");
        NSLog(@"* are properly configured  *");
        NSLog(@"****************************");
       
        NSString *line;
        do {
            char input[256] = {0};
            [YAPI Sleep:500 :&error];
            do {
                line = [serialPort readLine];
                if(![line isEqualToString:@""]) {
                    NSLog(@"Received: %@",line);
                }
            } while(![line isEqualToString:@""]);
           
            NSLog(@"Type line to send, or Ctrl-C to exit: ");
            fgets(input,sizeof(input), stdin);
            line = [NSString stringWithUTF8String:input];
            [serialPort writeLine:line];
        } while(![line isEqualToString:@""]);
       
        [YAPI FreeAPI];
    }
    return 0;
}
 

There are only a few really important lines in this example. We will look at them in details.

yocto_api.h et yocto_serialport.h

These two import files provide access to the functions allowing you to manage Yoctopuce modules. yocto_api.h must always be used, yocto_serialport.h is necessary to manage modules containing a serial port, such as Yocto-Serial.

[YAPI RegisterHub]

The [YAPI RegisterHub] function initializes the Yoctopuce API and indicates where the modules should be looked for. When used with the parameter @"usb", it will use the modules locally connected to the computer running the library. If the initialization does not succeed, this function returns a value different from YAPI_SUCCESS and errmsg contains the error message.

[SerialPort FindSerialPort]

The [SerialPort FindSerialPort] function allows you to find a serial port from the serial number of the module on which it resides and from its function name. You can use logical names as well, as long as you have initialized them. Let us imagine a Yocto-Serial module with serial number YSERIAL1-123456 which you have named "MyModule", and for which you have given the serialPort function the name "MyFunction". The following five calls are strictly equivalent, as long as "MyFunction" is defined only once.


YSerialPort *serialport = [SerialPort FindSerialPort:@"YSERIAL1-123456.serialPort"];
YSerialPort *serialport = [SerialPort FindSerialPort:@"YSERIAL1-123456.MyFunction"];
YSerialPort *serialport = [SerialPort FindSerialPort:@"MyModule.serialPort"];
YSerialPort *serialport = [SerialPort FindSerialPort:@"MyModule.MyFunction"];
YSerialPort *serialport = [SerialPort FindSerialPort:@"MyFunction"];

[SerialPort FindSerialPort] returns an object which you can then use at will to control the serial port.

isOnline

The isOnline method of the object returned by [SerialPort FindSerialPort] allows you to know if the corresponding module is present and in working order.

reset

The reset() method of the objet returned by YSerialPort.FindSerialPort clear all internal buffers of the serial port.

readLine

The readLine() method returns the next CR/LF terminated line received on the serial port, or an empty string if no more lines are found (this function is non-blocking).

writeLine

The writeLine() method puts the specified string in the serial port output buffer, followed by CR/LF.

12.2. Control of the module part

Each module can be controlled in a similar manner, you can find below a simple sample program displaying the main parameters of the module and enabling you to activate the localization beacon.

#import <Foundation/Foundation.h>
#import "yocto_api.h"

static void usage(const char *exe)
{
    NSLog(@"usage: %s <serial or logical name> [ON/OFF]\n",exe);
    exit(1);
}


int main (int argc, const char * argv[])
{
    NSError *error;
   
    @autoreleasepool {
        // Setup the API to use local USB devices
        if([YAPI RegisterHub:@"usb": &error] != YAPI_SUCCESS) {
            NSLog(@"RegisterHub error: %@", [error localizedDescription]);
            return 1;
        }
        if(argc < 2)
            usage(argv[0]);
        NSString *serial_or_name =[NSString stringWithUTF8String:argv[1]];
        // use serial or logical name
        YModule *module = [YModule FindModule:serial_or_name];  
        if ([module isOnline]) {
            if (argc > 2) {
                if (strcmp(argv[2], "ON")==0)
                    [module setBeacon:Y_BEACON_ON];
                else  
                    [module setBeacon:Y_BEACON_OFF];
            }        
            NSLog(@"serial:       %@\n", [module serialNumber]);
            NSLog(@"logical name: %@\n", [module logicalName]);
            NSLog(@"luminosity:   %d\n", [module luminosity]);
            NSLog(@"beacon:       ");
            if ([module beacon] == Y_BEACON_ON)
               NSLog(@"ON\n");
            else  
               NSLog(@"OFF\n");
            NSLog(@"upTime:       %ld sec\n", [module upTime]/1000);
            NSLog(@"USB current:  %d mA\n",  [module usbCurrent]);
            NSLog(@"logs:  %@\n",  [module get_lastLogs]);
        } else {
            NSLog(@"%@ not connected (check identification and USB cable)\n",
                serial_or_name);
        }
    }
    return 0;
}
 

Each property xxx of the module can be read thanks to a method of type get_xxxx, and properties which are not read-only can be modified with the help of the set_xxx: method. For more details regarding the used functions, refer to the API chapters.

Changing the module settings

When you want to modify the settings of a module, you only need to call the corresponding set_xxx: function. However, this modification is performed only in the random access memory (RAM) of the module: if the module is restarted, the modifications are lost. To memorize them persistently, it is necessary to ask the module to save its current configuration in its permanent memory. To do so, use the saveToFlash method. Inversely, it is possible to force the module to forget its current settings by using the revertFromFlash method. The short example below allows you to modify the logical name of a module.

#import <Foundation/Foundation.h>
#import "yocto_api.h"

static void usage(const char *exe)
{
    NSLog(@"usage: %s <serial> <newLogicalName>\n",exe);
    exit(1);
}


int main (int argc, const char * argv[])
{
    NSError *error;

    @autoreleasepool {
        // Setup the API to use local USB devices
        if([YAPI RegisterHub:@"usb" :&error] != YAPI_SUCCESS) {
            NSLog(@"RegisterHub error: %@", [error localizedDescription]);
            return 1;
        }

        if(argc < 2)
            usage(argv[0]);

        NSString *serial_or_name =[NSString stringWithUTF8String:argv[1]];
        // use serial or logical name
        YModule *module = [YModule FindModule:serial_or_name];
     
        if (module.isOnline) {
            if (argc >= 3){
                NSString *newname =  [NSString stringWithUTF8String:argv[2]];
                if (![YAPI CheckLogicalName:newname]){
                    NSLog(@"Invalid name (%@)\n", newname);
                    usage(argv[0]);
                }
                module.logicalName = newname;
                [module saveToFlash];
            }
            NSLog(@"Current name: %@\n", module.logicalName);
        } else {
            NSLog(@"%@ not connected (check identification and USB cable)\n",
                serial_or_name);
        }
    }
    return 0;
}
 

Warning: the number of write cycles of the nonvolatile memory of the module is limited. When this limit is reached, nothing guaranties that the saving process is performed correctly. This limit, linked to the technology employed by the module micro-processor, is located at about 100000 cycles. In short, you can use the saveToFlash function only 100000 times in the life of the module. Make sure you do not call this function within a loop.

Listing the modules

Obtaining the list of the connected modules is performed with the yFirstModule() function which returns the first module found. Then, you only need to call the nextModule() function of this object to find the following modules, and this as long as the returned value is not NULL. Below a short example listing the connected modules.

#import <Foundation/Foundation.h>
#import "yocto_api.h"

int main (int argc, const char * argv[])
{
    NSError *error;
   
    @autoreleasepool {
        // Setup the API to use local USB devices
        if([YAPI RegisterHub:@"usb" :&error] != YAPI_SUCCESS) {
            NSLog(@"RegisterHub error: %@\n", [error localizedDescription]);
            return 1;
        }

        NSLog(@"Device list:\n");

        YModule *module = [YModule FirstModule];
        while (module != nil) {
            NSLog(@"%@ %@",module.serialNumber, module.productName);
            module = [module nextModule];
        }
    }
    return 0;
}
 

12.3. Error handling

When you implement a program which must interact with USB modules, you cannot disregard error handling. Inevitably, there will be a time when a user will have unplugged the device, either before running the software, or even while the software is running. The Yoctopuce library is designed to help you support this kind of behavior, but your code must nevertheless be conceived to interpret in the best possible way the errors indicated by the library.

The simplest way to work around the problem is the one used in the short examples provided in this chapter: before accessing a module, check that it is online with the isOnline function, and then hope that it will stay so during the fraction of a second necessary for the following code lines to run. This method is not perfect, but it can be sufficient in some cases. You must however be aware that you cannot completely exclude an error which would occur after the call to isOnline and which could crash the software. The only way to prevent this is to implement one of the two error handling techniques described below.

The method recommended by most programming languages for unpredictable error handling is the use of exceptions. By default, it is the behavior of the Yoctopuce library. If an error happens while you try to access a module, the library throws an exception. In this case, there are three possibilities:

As this latest situation is not the most desirable, the Yoctopuce library offers another possibility for error handling, allowing you to create a robust program without needing to catch exceptions at every line of code. You simply need to call the yDisableExceptions() function to commute the library to a mode where exceptions for all the functions are systematically replaced by specific return values, which can be tested by the caller when necessary. For each function, the name of each return value in case of error is systematically documented in the library reference. The name always follows the same logic: a get_state() method returns a Y_STATE_INVALID value, a get_currentValue method returns a Y_CURRENTVALUE_INVALID value, and so on. In any case, the returned value is of the expected type and is not a null pointer which would risk crashing your program. At worst, if you display the value without testing it, it will be outside the expected bounds for the returned value. In the case of functions which do not normally return information, the return value is YAPI_SUCCESS if everything went well, and a different error code in case of failure.

When you work without exceptions, you can obtain an error code and an error message explaining the source of the error. You can request them from the object which returned the error, calling the errType() and errMessage() methods. Their returned values contain the same information as in the exceptions when they are active.

13. Using Yocto-Serial with Visual Basic .NET

VisualBasic has long been the most favored entrance path to the Microsoft world. Therefore, we had to provide our library for this language, even if the new trend is shifting to C#. All the examples and the project models are tested with Microsoft VisualBasic 2010 Express, freely available on the Microsoft web site29.

13.1. Installation

Download the Visual Basic Yoctopuce library from the Yoctopuce web site30. There is no setup program, simply copy the content of the zip file into the directory of your choice. You mostly need the content of the Sources directory. The other directories contain the documentation and a few sample programs. All sample projects are Visual Basic 2010, projects, if you are using a previous version, you may have to recreate the projects structure from scratch.

13.2. Using the Yoctopuce API in a Visual Basic project

The Visual Basic.NET Yoctopuce library is composed of a DLL and of source files in Visual Basic. The DLL is not a .NET DLL, but a classic DLL, written in C, which manages the low level communications with the modules31. The source files in Visual Basic manage the high level part of the API. Therefore, your need both this DLL and the .vb files of the sources directory to create a project managing Yoctopuce modules.

Configuring a Visual Basic project

The following indications are provided for Visual Studio Express 2010, but the process is similar for other versions. Start by creating your project. Then, on the Solution Explorer panel, right click on your project, and select "Add" and then "Add an existing item".

A file selection window opens. Select the yocto_api.vb file and the files corresponding to the functions of the Yoctopuce modules that your project is going to manage. If in doubt, select all the files.

You then have the choice between simply adding these files to your project, or to add them as links (the Add button is in fact a scroll-down menu). In the first case, Visual Studio copies the selected files into your project. In the second case, Visual Studio simply keeps a link on the original files. We recommend you to use links, which makes updates of the library much easier.

Then add in the same manner the yapi.dll DLL, located in the Sources/dll directory32. Then, from the Solution Explorer window, right click on the DLL, select Properties and in the Properties panel, set the Copy to output folder to always. You are now ready to use your Yoctopuce modules from Visual Studio.

In order to keep them simple, all the examples provided in this documentation are console applications. Naturally, the libraries function in a strictly identical manner if you integrate them in an application with a graphical interface.

13.3. Control of the SerialPort function

A few lines of code are enough to use a Yocto-Serial. Here is the skeleton of a Visual Basic code snipplet to use the SerialPort function.


[...]
Dim errmsg As String errmsg
Dim serialport As YSerialPort
 
REM Get access to your device, connected locally on USB for instance
yRegisterHub("usb", errmsg)
serialport = yFindSerialPort("YSERIAL1-123456.serialPort")

REM Hot-plug is easy: just check that the device is online
If (serialport.isOnline()) Then
   REM Use serialport.get_serialMode(), ...
End If

Let's look at these lines in more details.

yRegisterHub

The yRegisterHub function initializes the Yoctopuce API and indicates where the modules should be looked for. When used with the parameter "usb", it will use the modules locally connected to the computer running the library. If the initialization does not succeed, this function returns a value different from YAPI_SUCCESS and errmsg contains the error message.

yFindSerialPort

The yFindSerialPort function allows you to find a serial port from the serial number of the module on which it resides and from its function name. You can use logical names as well, as long as you have initialized them. Let us imagine a Yocto-Serial module with serial number YSERIAL1-123456 which you have named "MyModule", and for which you have given the serialPort function the name "MyFunction". The following five calls are strictly equivalent, as long as "MyFunction" is defined only once.


serialport = yFindSerialPort("YSERIAL1-123456.serialPort")
serialport = yFindSerialPort("YSERIAL1-123456.MyFunction")
serialport = yFindSerialPort("MyModule.serialPort")
serialport = yFindSerialPort("MyModule.MyFunction")
serialport = yFindSerialPort("MyFunction")

yFindSerialPort returns an object which you can then use at will to control the serial port.

isOnline

The isOnline() method of the object returned by yFindSerialPort allows you to know if the corresponding module is present and in working order.

reset

The reset() method of the objet returned by yFindSerialPort clear all internal buffers of the serial port.

readLine

The readLine() method returns the next CR/LF terminated line received on the serial port, or an empty string if no more lines are found (this function is non-blocking).

writeLine

The writeLine() method puts the specified string in the serial port output buffer, followed by CR/LF.

A real example

Launch Microsoft VisualBasic and open the corresponding sample project provided in the directory Examples/Doc-GettingStarted-Yocto-Serial of the Yoctopuce library.

In this example, you will recognize the functions explained above, but this time used with all side materials needed to make it work nicely as a small demo.

Module Module1

  Private Sub Usage()
    Dim execname = System.AppDomain.CurrentDomain.FriendlyName
    Console.WriteLine("Usage")
    Console.WriteLine(execname + " <serial_number>  <frequency> <dutyCycle>")
    Console.WriteLine(execname + " <logical_name> <frequency> <dutyCycle>")
    Console.WriteLine(execname + " any  <frequency> <dutyCycle>   (use any discovered device)")
    Console.WriteLine("     <frequency>: integer between 1Hz and 1000000Hz")
    Console.WriteLine("     <dutyCycle>: floating point number between 0.0 and 100.0")
    System.Threading.Thread.Sleep(2500)
    End
  End Sub


  Sub Main()
    Dim argv() As String = System.Environment.GetCommandLineArgs()
    Dim errmsg As String = ""
    Dim target As String
    Dim serialPort As YSerialPort
    Dim line As String


    If (YAPI.RegisterHub("usb", errmsg) <> YAPI.SUCCESS) Then
      Console.WriteLine("RegisterHub error: " + errmsg)
      Environment.Exit(0)
    End If
    If (argv.Length > 1) Then
      target = argv(1)
      serialPort = YSerialPort.FindSerialPort(target + ".serialPort")
      If (Not serialPort.isOnline()) Then
        Console.WriteLine("No module connected (check cable)")
        Environment.Exit(0)
      End If
    Else
      serialPort = YSerialPort.FirstSerialPort()
      If (serialPort Is Nothing) Then
        Console.WriteLine("No module connected (check USB cable)")
        Environment.Exit(0)
      End If
    End If
    serialport.set_serialMode("9600,8N1")
    serialport.set_protocol("Line")
    serialport.reset()
    Console.WriteLine("****************************")
    Console.WriteLine("* make sure voltage levels *")
    Console.WriteLine("* are properly configured  *")
    Console.WriteLine("****************************")
    Do
      YAPI.Sleep(500, errmsg)
      Do
        line = serialPort.readLine()
        If (line <> "") Then
          Console.WriteLine("Received: " + line)
        End If
      Loop While (line <> "")
      Console.WriteLine("Type line to send, or Ctrl-C to exit: ")
      line = Console.ReadLine()
      serialPort.writeLine(line)
    Loop While (line <> "")
    YAPI.FreeAPI()
  End Sub

End Module
 

13.4. Control of the module part

Each module can be controlled in a similar manner, you can find below a simple sample program displaying the main parameters of the module and enabling you to activate the localization beacon.


Imports System.IO
Imports System.Environment

Module Module1

  Sub usage()
    Console.WriteLine("usage: demo <serial or logical name> [ON/OFF]")  
    End
  End Sub

  Sub Main()
    Dim argv() As String = System.Environment.GetCommandLineArgs()
    Dim errmsg As String = ""
    Dim m As ymodule

    If (yRegisterHub("usb", errmsg) <> YAPI_SUCCESS) Then
      Console.WriteLine("RegisterHub error:" + errmsg)
      End
    End If

    If argv.Length < 2 Then usage()

    m = yFindModule(argv(1)) REM use serial or logical name

    If (m.isOnline()) Then
      If argv.Length > 2 Then
        If argv(2) = "ON" Then m.set_beacon(Y_BEACON_ON)
        If argv(2) = "OFF" Then m.set_beacon(Y_BEACON_OFF)
      End If
      Console.WriteLine("serial:       " + m.get_serialNumber())
      Console.WriteLine("logical name: " + m.get_logicalName())
      Console.WriteLine("luminosity:   " + Str(m.get_luminosity()))
      Console.Write("beacon:       ")
      If (m.get_beacon() = Y_BEACON_ON) Then
        Console.WriteLine("ON")
      Else
        Console.WriteLine("OFF")
      End If
      Console.WriteLine("upTime:       " + Str(m.get_upTime() / 1000) + " sec")
      Console.WriteLine("USB current:  " + Str(m.get_usbCurrent()) + " mA")
      Console.WriteLine("Logs:")
      Console.WriteLine(m.get_lastLogs())
    Else
      Console.WriteLine(argv(1) + " not connected (check identification and USB cable)")
    End If



  End Sub

End Module
 

Each property xxx of the module can be read thanks to a method of type get_xxxx(), and properties which are not read-only can be modified with the help of the set_xxx() method. For more details regarding the used functions, refer to the API chapters.

Changing the module settings

When you want to modify the settings of a module, you only need to call the corresponding set_xxx() function. However, this modification is performed only in the random access memory (RAM) of the module: if the module is restarted, the modifications are lost. To memorize them persistently, it is necessary to ask the module to save its current configuration in its permanent memory. To do so, use the saveToFlash() method. Inversely, it is possible to force the module to forget its current settings by using the revertFromFlash() method. The short example below allows you to modify the logical name of a module.

Module Module1


  Sub usage()

    Console.WriteLine("usage: demo <serial or logical name> <new logical name>")
    End
  End Sub

  Sub Main()
    Dim argv() As String = System.Environment.GetCommandLineArgs()
    Dim errmsg As String = ""
    Dim newname As String
    Dim m As YModule

    If (argv.Length <> 3) Then usage()

    REM Setup the API to use local USB devices
    If yRegisterHub("usb", errmsg) <> YAPI_SUCCESS Then
      Console.WriteLine("RegisterHub error: " + errmsg)
      End
    End If

    m = yFindModule(argv(1)) REM use serial or logical name
    If m.isOnline() Then

      newname = argv(2)
      If (Not yCheckLogicalName(newname)) Then
        Console.WriteLine("Invalid name (" + newname + ")")
        End
      End If
      m.set_logicalName(newname)
      m.saveToFlash() REM do not forget this

      Console.Write("Module: serial= " + m.get_serialNumber)
      Console.Write(" / name= " + m.get_logicalName())
    Else
      Console.Write("not connected (check identification and USB cable")
    End If

  End Sub

End Module
 

Warning: the number of write cycles of the nonvolatile memory of the module is limited. When this limit is reached, nothing guaranties that the saving process is performed correctly. This limit, linked to the technology employed by the module micro-processor, is located at about 100000 cycles. In short, you can use the saveToFlash() function only 100000 times in the life of the module. Make sure you do not call this function within a loop.

Listing the modules

Obtaining the list of the connected modules is performed with the yFirstModule() function which returns the first module found. Then, you only need to call the nextModule() function of this object to find the following modules, and this as long as the returned value is not Nothing. Below a short example listing the connected modules.

Module Module1

  Sub Main()
    Dim M As ymodule
    Dim errmsg As String = ""

    REM Setup the API to use local USB devices
    If yRegisterHub("usb", errmsg) <> YAPI_SUCCESS Then
      Console.WriteLine("RegisterHub error: " + errmsg)
      End
    End If

    Console.WriteLine("Device list")
    M = yFirstModule()
    While M IsNot Nothing
      Console.WriteLine(M.get_serialNumber() + " (" + M.get_productName() + ")")
      M = M.nextModule()
    End While

  End Sub

    End Module
 

13.5. Error handling

When you implement a program which must interact with USB modules, you cannot disregard error handling. Inevitably, there will be a time when a user will have unplugged the device, either before running the software, or even while the software is running. The Yoctopuce library is designed to help you support this kind of behavior, but your code must nevertheless be conceived to interpret in the best possible way the errors indicated by the library.

The simplest way to work around the problem is the one used in the short examples provided in this chapter: before accessing a module, check that it is online with the isOnline function, and then hope that it will stay so during the fraction of a second necessary for the following code lines to run. This method is not perfect, but it can be sufficient in some cases. You must however be aware that you cannot completely exclude an error which would occur after the call to isOnline and which could crash the software. The only way to prevent this is to implement one of the two error handling techniques described below.

The method recommended by most programming languages for unpredictable error handling is the use of exceptions. By default, it is the behavior of the Yoctopuce library. If an error happens while you try to access a module, the library throws an exception. In this case, there are three possibilities:

As this latest situation is not the most desirable, the Yoctopuce library offers another possibility for error handling, allowing you to create a robust program without needing to catch exceptions at every line of code. You simply need to call the yDisableExceptions() function to commute the library to a mode where exceptions for all the functions are systematically replaced by specific return values, which can be tested by the caller when necessary. For each function, the name of each return value in case of error is systematically documented in the library reference. The name always follows the same logic: a get_state() method returns a Y_STATE_INVALID value, a get_currentValue method returns a Y_CURRENTVALUE_INVALID value, and so on. In any case, the returned value is of the expected type and is not a null pointer which would risk crashing your program. At worst, if you display the value without testing it, it will be outside the expected bounds for the returned value. In the case of functions which do not normally return information, the return value is YAPI_SUCCESS if everything went well, and a different error code in case of failure.

When you work without exceptions, you can obtain an error code and an error message explaining the source of the error. You can request them from the object which returned the error, calling the errType() and errMessage() methods. Their returned values contain the same information as in the exceptions when they are active.

14. Using Yocto-Serial with C#

C# (pronounced C-Sharp) is an object-oriented programming language promoted by Microsoft, it is somewhat similar to Java. Like Visual-Basic and Delphi, it allows you to create Windows applications quite easily. All the examples and the project models are tested with Microsoft C# 2010 Express, freely available on the Microsoft web site33.

14.1. Installation

Download the Visual C# Yoctopuce library from the Yoctopuce web site34. There is no setup program, simply copy the content of the zip file into the directory of your choice. You mostly need the content of the Sources directory. The other directories contain the documentation and a few sample programs. All sample projects are Visual C# 2010, projects, if you are using a previous version, you may have to recreate the projects structure from scratch.

14.2. Using the Yoctopuce API in a Visual C# project

The Visual C#.NET Yoctopuce library is composed of a DLL and of source files in Visual C#. The DLL is not a .NET DLL, but a classic DLL, written in C, which manages the low level communications with the modules35. The source files in Visual C# manage the high level part of the API. Therefore, your need both this DLL and the .cs files of the sources directory to create a project managing Yoctopuce modules.

Configuring a Visual C# project

The following indications are provided for Visual Studio Express 2010, but the process is similar for other versions. Start by creating your project. Then, on the Solution Explorer panel, right click on your project, and select "Add" and then "Add an existing item".

A file selection window opens. Select the yocto_api.cs file and the files corresponding to the functions of the Yoctopuce modules that your project is going to manage. If in doubt, select all the files.

You then have the choice between simply adding these files to your project, or to add them as links (the Add button is in fact a scroll-down menu). In the first case, Visual Studio copies the selected files into your project. In the second case, Visual Studio simply keeps a link on the original files. We recommend you to use links, which makes updates of the library much easier.

Then add in the same manner the yapi.dll DLL, located in the Sources/dll directory36. Then, from the Solution Explorer window, right click on the DLL, select Properties and in the Properties panel, set the Copy to output folder to always. You are now ready to use your Yoctopuce modules from Visual Studio.

In order to keep them simple, all the examples provided in this documentation are console applications. Naturally, the libraries function in a strictly identical manner if you integrate them in an application with a graphical interface.

14.3. Control of the SerialPort function

A few lines of code are enough to use a Yocto-Serial. Here is the skeleton of a C# code snipplet to use the SerialPort function.


[...]
string errmsg ="";
YSerialPort serialport;
 
// Get access to your device, connected locally on USB for instance
YAPI.RegisterHub("usb", errmsg);
serialport = YSerialPort.FindSerialPort("YSERIAL1-123456.serialPort");

// Hot-plug is easy: just check that the device is online
if (serialport.isOnline())
 {  // Use serialport.get_serialMode(); ...
 }

Let's look at these lines in more details.

YAPI.RegisterHub

The YAPI.RegisterHub function initializes the Yoctopuce API and indicates where the modules should be looked for. When used with the parameter "usb", it will use the modules locally connected to the computer running the library. If the initialization does not succeed, this function returns a value different from YAPI.SUCCESS and errmsg contains the error message.

YSerialPort.FindSerialPort

The YSerialPort.FindSerialPort function allows you to find a serial port from the serial number of the module on which it resides and from its function name. You can use logical names as well, as long as you have initialized them. Let us imagine a Yocto-Serial module with serial number YSERIAL1-123456 which you have named "MyModule", and for which you have given the serialPort function the name "MyFunction". The following five calls are strictly equivalent, as long as "MyFunction" is defined only once.


serialport = YSerialPort.FindSerialPort("YSERIAL1-123456.serialPort");
serialport = YSerialPort.FindSerialPort("YSERIAL1-123456.MyFunction");
serialport = YSerialPort.FindSerialPort("MyModule.serialPort");
serialport = YSerialPort.FindSerialPort("MyModule.MyFunction");
serialport = YSerialPort.FindSerialPort("MyFunction");

YSerialPort.FindSerialPort returns an object which you can then use at will to control the serial port.

isOnline

The isOnline() method of the object returned by YSerialPort.FindSerialPort allows you to know if the corresponding module is present and in working order.

reset

The reset() method of the objet returned by YSerialPort.FindSerialPort clear all internal buffers of the serial port.

readLine

The readLine() method returns the next CR/LF terminated line received on the serial port, or an empty string if no more lines are found (this function is non-blocking).

writeLine

The writeLine() method puts the specified string in the serial port output buffer, followed by CR/LF.

A real example

Launch Microsoft Visual C# and open the corresponding sample project provided in the directory Examples/Doc-GettingStarted-Yocto-Serial of the Yoctopuce library.

In this example, you will recognize the functions explained above, but this time used with all side materials needed to make it work nicely as a small demo.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string errmsg = "";
            string target;
            YSerialPort serialPort;

            if (YAPI.RegisterHub("usb", ref errmsg) != YAPI.SUCCESS)
            {
                Console.WriteLine("RegisterHub error: " + errmsg);
                Environment.Exit(0);
            }

            if (args.Length > 0)
            {
                target = args[0];
                serialPort = YSerialPort.FindSerialPort(target + ".serialPort");
                if (!serialPort.isOnline())
                {
                    Console.WriteLine("No module connected (check cable)");
                    Environment.Exit(0);
                }
            }
            else
            {
                serialPort = YSerialPort.FirstSerialPort();
                if (serialPort == null)
                {
                    Console.WriteLine("No module connected (check USB cable)");
                    Environment.Exit(0);
                }
            }
           
            Console.WriteLine("****************************");
            Console.WriteLine("* make sure voltage levels *");
            Console.WriteLine("* are properly configured  *");
            Console.WriteLine("****************************");
   
            serialPort.set_serialMode("9600,8N1");
            serialPort.set_protocol("Line");
            serialPort.reset();

            string line;
            do
            {
                YAPI.Sleep(500, ref errmsg);
                do
                {
                    line = serialPort.readLine();
                    if (line != "")
                    {
                        Console.WriteLine("Received: " + line);
                    }
                } while (line != "");
                Console.WriteLine("Type line to send, or Ctrl-C to exit: ");
                line = Console.ReadLine();
                serialPort.writeLine(line);
            } while (line != "");
            YAPI.FreeAPI();
        }
    }
}
 

14.4. Control of the module part

Each module can be controlled in a similar manner, you can find below a simple sample program displaying the main parameters of the module and enabling you to activate the localization beacon.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace ConsoleApplication1
{
  class Program
  {
    static void usage()
    { string execname = System.AppDomain.CurrentDomain.FriendlyName;
      Console.WriteLine("Usage:");
      Console.WriteLine(execname+" <serial or logical name> [ON/OFF]");
      System.Threading.Thread.Sleep(2500);
      Environment.Exit(0);
    }

    static void Main(string[] args)
    {
      YModule m;
      string errmsg = "";

      if (YAPI.RegisterHub("usb", ref errmsg) !=  YAPI.SUCCESS)
      {
        Console.WriteLine("RegisterHub error: " + errmsg);
        Environment.Exit(0);
      }

     
      if (args.Length < 1)  usage();

      m = YModule.FindModule(args[0]); // use serial or logical name

      if (m.isOnline())
      {
        if (args.Length >= 2)
        {
          if (args[1].ToUpper() == "ON") { m.set_beacon(YModule.BEACON_ON); }
          if (args[1].ToUpper() == "OFF") { m.set_beacon(YModule.BEACON_OFF); }
        }
     
        Console.WriteLine("serial:       " + m.get_serialNumber());
        Console.WriteLine("logical name: " + m.get_logicalName());
        Console.WriteLine("luminosity:   " + m.get_luminosity().ToString());
        Console.Write("beacon:       ");
        if (m.get_beacon() == YModule.BEACON_ON)
          Console.WriteLine("ON");
        else
          Console.WriteLine("OFF");
        Console.WriteLine("upTime:       " + (m.get_upTime() / 1000 ).ToString()+ " sec");
        Console.WriteLine("USB current:  " + m.get_usbCurrent().ToString() + " mA");
        Console.WriteLine("Logs:\r\n"+ m.get_lastLogs());

      }
    else
      Console.WriteLine(args[0] + " not connected (check identification and USB cable)");
   
   }
  }
}
 

Each property xxx of the module can be read thanks to a method of type YModule.get_xxxx(), and properties which are not read-only can be modified with the help of the YModule.set_xxx() method. For more details regarding the used functions, refer to the API chapters.

Changing the module settings

When you want to modify the settings of a module, you only need to call the corresponding YModule.set_xxx() function. However, this modification is performed only in the random access memory (RAM) of the module: if the module is restarted, the modifications are lost. To memorize them persistently, it is necessary to ask the module to save its current configuration in its permanent memory. To do so, use the YModule.saveToFlash() method. Inversely, it is possible to force the module to forget its current settings by using the YModule.revertFromFlash() method. The short example below allows you to modify the logical name of a module.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
  class Program
  {
    static void usage()
    { string execname = System.AppDomain.CurrentDomain.FriendlyName;
      Console.WriteLine("Usage:");
      Console.WriteLine("usage: demo <serial or logical name> <new logical name>");
      System.Threading.Thread.Sleep(2500);
      Environment.Exit(0);
    }

    static void Main(string[] args)
    {
      YModule m;
      string errmsg = "";
      string newname;

      if (args.Length != 2) usage();

      if (YAPI.RegisterHub("usb", ref errmsg) !=  YAPI.SUCCESS)
      {
        Console.WriteLine("RegisterHub error: " + errmsg);
        Environment.Exit(0);
      }

      m = YModule.FindModule(args[0]); // use serial or logical name

      if (m.isOnline())
      {
        newname = args[1];
        if (!YAPI.CheckLogicalName(newname))
        {
          Console.WriteLine("Invalid name (" + newname + ")");
          Environment.Exit(0);
        }

        m.set_logicalName(newname);
        m.saveToFlash(); // do not forget this

        Console.Write("Module: serial= " + m.get_serialNumber());
        Console.WriteLine(" / name= " + m.get_logicalName());
      }
      else
        Console.Write("not connected (check identification and USB cable");
    }
  }
}
 

Warning: the number of write cycles of the nonvolatile memory of the module is limited. When this limit is reached, nothing guaranties that the saving process is performed correctly. This limit, linked to the technology employed by the module micro-processor, is located at about 100000 cycles. In short, you can use the YModule.saveToFlash() function only 100000 times in the life of the module. Make sure you do not call this function within a loop.

Listing the modules

Obtaining the list of the connected modules is performed with the YModule.yFirstModule() function which returns the first module found. Then, you only need to call the nextModule() function of this object to find the following modules, and this as long as the returned value is not null. Below a short example listing the connected modules.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      YModule m;
      string errmsg = "";

      if (YAPI.RegisterHub("usb", ref errmsg) !=  YAPI.SUCCESS)
      {
        Console.WriteLine("RegisterHub error: " + errmsg);
        Environment.Exit(0);
      }

      Console.WriteLine("Device list");
      m = YModule.FirstModule();
      while (m!=null)
      { Console.WriteLine(m.get_serialNumber() + " (" + m.get_productName() + ")");
       m = m.nextModule();
      }

    }
  }
}
 

14.5. Error handling

When you implement a program which must interact with USB modules, you cannot disregard error handling. Inevitably, there will be a time when a user will have unplugged the device, either before running the software, or even while the software is running. The Yoctopuce library is designed to help you support this kind of behavior, but your code must nevertheless be conceived to interpret in the best possible way the errors indicated by the library.

The simplest way to work around the problem is the one used in the short examples provided in this chapter: before accessing a module, check that it is online with the isOnline function, and then hope that it will stay so during the fraction of a second necessary for the following code lines to run. This method is not perfect, but it can be sufficient in some cases. You must however be aware that you cannot completely exclude an error which would occur after the call to isOnline and which could crash the software. The only way to prevent this is to implement one of the two error handling techniques described below.

The method recommended by most programming languages for unpredictable error handling is the use of exceptions. By default, it is the behavior of the Yoctopuce library. If an error happens while you try to access a module, the library throws an exception. In this case, there are three possibilities:

As this latest situation is not the most desirable, the Yoctopuce library offers another possibility for error handling, allowing you to create a robust program without needing to catch exceptions at every line of code. You simply need to call the yDisableExceptions() function to commute the library to a mode where exceptions for all the functions are systematically replaced by specific return values, which can be tested by the caller when necessary. For each function, the name of each return value in case of error is systematically documented in the library reference. The name always follows the same logic: a get_state() method returns a Y_STATE_INVALID value, a get_currentValue method returns a Y_CURRENTVALUE_INVALID value, and so on. In any case, the returned value is of the expected type and is not a null pointer which would risk crashing your program. At worst, if you display the value without testing it, it will be outside the expected bounds for the returned value. In the case of functions which do not normally return information, the return value is YAPI_SUCCESS if everything went well, and a different error code in case of failure.

When you work without exceptions, you can obtain an error code and an error message explaining the source of the error. You can request them from the object which returned the error, calling the errType() and errMessage() methods. Their returned values contain the same information as in the exceptions when they are active.

15. Using Yocto-Serial with Delphi

Delphi is a descendent of Turbo-Pascal. Originally, Delphi was produced by Borland, Embarcadero now edits it. The strength of this language resides in its ease of use, as anyone with some notions of the Pascal language can develop a Windows application in next to no time. Its only disadvantage is to cost something37.

Delphi libraries are provided not as VCL components, but directly as source files. These files are compatible with most Delphi versions. 38

To keep them simple, all the examples provided in this documentation are console applications. Obviously, the libraries work in a strictly identical way with VCL applications.

You will soon notice that the Delphi API defines many functions which return objects. You do not need to deallocate these objects yourself, the API does it automatically at the end of the application.

15.1. Preparation

Go to the Yoctopuce web site and download the Yoctopuce Delphi libraries39. Uncompress everything in a directory of your choice, add the subdirectory sources in the list of directories of Delphi libraries.40

By default, the Yoctopuce Delphi library uses the yapi.dll DLL, all the applications you will create with Delphi must have access to this DLL. The simplest way to ensure this is to make sure yapi.dll is located in the same directory as the executable file of your application.

15.2. Control of the SerialPort function

Launch your Delphi environment, copy the yapi.dll DLL in a directory, create a new console application in the same directory, and copy-paste the piece of code below:

program helloworld;
{$APPTYPE CONSOLE}
uses
  SysUtils,
  yocto_api,
  yocto_serialport;

var
 errmsg,target,channel:string;
 serialport:TYserialport;
 line:string;

begin
  if (YRegisterHub('usb', errmsg) <> YAPI_SUCCESS)  then
    begin
      writeln('RegisterHub error: ' + errmsg);
      halt;
    end;

  if (paramcount>1) then
    begin
      target := paramstr(1);
      serialport := YFindSerialPort(target + '.serialPort');
    end
  else
    begin
      serialport := YFirstSerialPort();
      if (serialport = nil) then
         begin
           writeln('No module connected (check USB cable)');
           halt;
         end;
    end;
   
  writeln('****************************');
  writeln('* make sure voltage levels *');
  writeln('* are properly configured  *');
  writeln('****************************');  
   
  serialport.set_serialMode('9600,8N1');
  serialPort.set_protocol('Line');
  serialPort.reset();
  repeat
    ySleep(500, errmsg);
    repeat
      line := serialPort.readLine();
      if (line <> '') then
        begin
          writeln('Received: ' + line);
        end;
    until (line = '');
    writeln('Type line to send, or Ctrl-C to exit: ');
    readLn(line);
    serialPort.writeLine(line);
  until (line = '');
  yFreeAPI();
end.
 

There are only a few really important lines in this sample example. We will look at them in details.

yocto_api and yocto_serialport

These two units provide access to the functions allowing you to manage Yoctopuce modules. yocto_api must always be used, yocto_serialport is necessary to manage modules containing a serial port, such as Yocto-Serial.

yRegisterHub

The yRegisterHub function initializes the Yoctopuce API and specifies where the modules should be looked for. When used with the parameter 'usb', it will use the modules locally connected to the computer running the library. If the initialization does not succeed, this function returns a value different from YAPI_SUCCESS and errmsg contains the error message.

yFindSerialPort

The yFindSerialPort function allows you to find a serial port from the serial number of the module on which it resides and from its function name. You can also use logical names, as long as you have initialized them. Let us imagine a Yocto-Serial module with serial number YSERIAL1-123456 which you have named "MyModule", and for which you have given the serialPort function the name "MyFunction". The following five calls are strictly equivalent, as long as "MyFunction" is defined only once.


serialport := yFindSerialPort("YSERIAL1-123456.serialPort");
serialport := yFindSerialPort("YSERIAL1-123456.MyFunction");
serialport := yFindSerialPort("MyModule.serialPort");
serialport := yFindSerialPort("MyModule.MyFunction");
serialport := yFindSerialPort("MyFunction");

yFindSerialPort returns an object which you can then use at will to control the serial port.

isOnline

The isOnline() method of the object returned by yFindSerialPort allows you to know if the corresponding module is present and in working order.

reset

The reset() method of the objet returned by yFindSerialPort clear all internal buffers of the serial port.

readLine

The readLine() method returns the next CR/LF terminated line received on the serial port, or an empty string if no more lines are found (this function is non-blocking).

writeLine

The writeLine() method puts the specified string in the serial port output buffer, followed by CR/LF.

15.3. Control of the module part

Each module can be controlled in a similar manner, you can find below a simple sample program displaying the main parameters of the module and enabling you to activate the localization beacon.

program modulecontrol;
{$APPTYPE CONSOLE}
uses
  SysUtils,
  yocto_api;

const
  serial = 'YSERIAL1-123456'; // use serial number or logical name

procedure refresh(module:Tymodule) ;
  begin
    if (module.isOnline())  then
     begin
       Writeln('');
       Writeln('Serial       : ' + module.get_serialNumber());
       Writeln('Logical name : ' + module.get_logicalName());
       Writeln('Luminosity   : ' + intToStr(module.get_luminosity()));
       Write('Beacon    :');
       if  (module.get_beacon()=Y_BEACON_ON) then Writeln('on')
                                             else Writeln('off');
       Writeln('uptime       : ' + intToStr(module.get_upTime() div 1000)+'s');
       Writeln('USB current  : ' + intToStr(module.get_usbCurrent())+'mA');
       Writeln('Logs         : ');
       Writeln(module.get_lastlogs());
       Writeln('');
       Writeln('r : refresh / b:beacon ON / space : beacon off');
     end
    else Writeln('Module not connected (check identification and USB cable)');
  end;


procedure beacon(module:Tymodule;state:integer);
  begin
    module.set_beacon(state);
    refresh(module);
  end;

var
  module : TYModule;
  c      : char;
  errmsg : string;

begin
  // Setup the API to use local USB devices
  if yRegisterHub('usb', errmsg)<>YAPI_SUCCESS then
  begin
    Write('RegisterHub error: '+errmsg);
    exit;
  end;

  module := yFindModule(serial);
  refresh(module);

  repeat
    read(c);
    case c of
     'r': refresh(module);
     'b': beacon(module,Y_BEACON_ON);
     ' ': beacon(module,Y_BEACON_OFF);
    end;
  until  c = 'x';
end.

Each property xxx of the module can be read thanks to a method of type get_xxxx(), and properties which are not read-only can be modified with the help of the set_xxx() method. For more details regarding the used functions, refer to the API chapters.

Changing the module settings

When you want to modify the settings of a module, you only need to call the corresponding set_xxx() function. However, this modification is performed only in the random access memory (RAM) of the module: if the module is restarted, the modifications are lost. To memorize them persistently, it is necessary to ask the module to save its current configuration in its permanent memory. To do so, use the saveToFlash() method. Inversely, it is possible to force the module to forget its current settings by using the revertFromFlash() method. The short example below allows you to modify the logical name of a module.

program savesettings;
{$APPTYPE CONSOLE}
uses
  SysUtils,
  yocto_api;

const
  serial = 'YSERIAL1-123456'; // use serial number or logical name

var
  module  : TYModule;
  errmsg  : string;
  newname : string;
 
begin
  // Setup the API to use local USB devices
  if yRegisterHub('usb', errmsg)<>YAPI_SUCCESS then
  begin
    Write('RegisterHub error: '+errmsg);
    exit;
  end;

  module := yFindModule(serial);
  if (not(module.isOnline)) then
   begin
     writeln('Module not connected (check identification and USB cable)');
     exit;
   end;

  Writeln('Current logical name : '+module.get_logicalName());
  Write('Enter new name : ');
  Readln(newname);
  if (not(yCheckLogicalName(newname))) then
   begin
     Writeln('invalid logical name');
     exit;
   end;
  module.set_logicalName(newname);
  module.saveToFlash();
 
  Writeln('logical name is now : '+module.get_logicalName());
end.
 

Warning: the number of write cycles of the nonvolatile memory of the module is limited. When this limit is reached, nothing guaranties that the saving process is performed correctly. This limit, linked to the technology employed by the module micro-processor, is located at about 100000 cycles. In short, you can use the saveToFlash() function only 100000 times in the life of the module. Make sure you do not call this function within a loop.

Listing the modules

Obtaining the list of the connected modules is performed with the yFirstModule() function which returns the first module found. Then, you only need to call the nextModule() function of this object to find the following modules, and this as long as the returned value is not nil. Below a short example listing the connected modules.

program inventory;
{$APPTYPE CONSOLE}
uses
  SysUtils,
  yocto_api;

var
  module : TYModule;
  errmsg : string;

begin
  // Setup the API to use local USB devices
  if yRegisterHub('usb', errmsg)<>YAPI_SUCCESS then
  begin
    Write('RegisterHub error: '+errmsg);
    exit;
  end;

  Writeln('Device list');

  module := yFirstModule();
  while module<>nil  do
   begin
     Writeln( module.get_serialNumber()+' ('+module.get_productName()+')');
     module := module.nextModule();
   end;

end.

15.4. Error handling

When you implement a program which must interact with USB modules, you cannot disregard error handling. Inevitably, there will be a time when a user will have unplugged the device, either before running the software, or even while the software is running. The Yoctopuce library is designed to help you support this kind of behavior, but your code must nevertheless be conceived to interpret in the best possible way the errors indicated by the library.

The simplest way to work around the problem is the one used in the short examples provided in this chapter: before accessing a module, check that it is online with the isOnline function, and then hope that it will stay so during the fraction of a second necessary for the following code lines to run. This method is not perfect, but it can be sufficient in some cases. You must however be aware that you cannot completely exclude an error which would occur after the call to isOnline and which could crash the software. The only way to prevent this is to implement one of the two error handling techniques described below.

The method recommended by most programming languages for unpredictable error handling is the use of exceptions. By default, it is the behavior of the Yoctopuce library. If an error happens while you try to access a module, the library throws an exception. In this case, there are three possibilities:

As this latest situation is not the most desirable, the Yoctopuce library offers another possibility for error handling, allowing you to create a robust program without needing to catch exceptions at every line of code. You simply need to call the yDisableExceptions() function to commute the library to a mode where exceptions for all the functions are systematically replaced by specific return values, which can be tested by the caller when necessary. For each function, the name of each return value in case of error is systematically documented in the library reference. The name always follows the same logic: a get_state() method returns a Y_STATE_INVALID value, a get_currentValue method returns a Y_CURRENTVALUE_INVALID value, and so on. In any case, the returned value is of the expected type and is not a null pointer which would risk crashing your program. At worst, if you display the value without testing it, it will be outside the expected bounds for the returned value. In the case of functions which do not normally return information, the return value is YAPI_SUCCESS if everything went well, and a different error code in case of failure.

When you work without exceptions, you can obtain an error code and an error message explaining the source of the error. You can request them from the object which returned the error, calling the errType() and errMessage() methods. Their returned values contain the same information as in the exceptions when they are active.

16. Using the Yocto-Serial with Python

Python is an interpreted object oriented language developed by Guido van Rossum. Among its advantages is the fact that it is free, and the fact that it is available for most platforms, Windows as well as UNIX. It is an ideal language to write small scripts on a napkin. The Yoctopuce library is compatible with Python 2.6+ and 3+. It works under Windows, Mac OS X, and Linux, Intel as well as ARM. The library was tested with Python 2.6 and Python 3.2. Python interpreters are available on the Python web site41.

16.1. Source files

The Yoctopuce library classes42 for Python that you will use are provided as source files. Copy all the content of the Sources directory in the directory of your choice and add this directory to the PYTHONPATH environment variable. If you use an IDE to program in Python, refer to its documentation to configure it so that it automatically finds the API source files.

16.2. Dynamic library

A section of the low-level library is written in C, but you should not need to interact directly with it: it is provided as a DLL under Windows, as a .so files under UNIX, and as a .dylib file under Mac OS X. Everything was done to ensure the simplest possible interaction from Python: the distinct versions of the dynamic library corresponding to the distinct operating systems and architectures are stored in the cdll directory. The API automatically loads the correct file during its initialization. You should not have to worry about it.

If you ever need to recompile the dynamic library, its complete source code is located in the Yoctopuce C++ library.

In order to keep them simple, all the examples provided in this documentation are console applications. Naturally, the libraries function in a strictly identical manner if you integrate them in an application with a graphical interface.

16.3. Control of the SerialPort function

A few lines of code are enough to use a Yocto-Serial. Here is the skeleton of a Python code snipplet to use the SerialPort function.


[...]

errmsg=YRefParam()
#Get access to your device, connected locally on USB for instance
YAPI.RegisterHub("usb",errmsg)
serialport = YSerialPort.FindSerialPort("YSERIAL1-123456.serialPort")

# Hot-plug is easy: just check that the device is online
if serialport.isOnline():
    #Use serialport.get_serialMode()
    ...
   
[...]    

Let's look at these lines in more details.

YAPI.RegisterHub

The yAPI.RegisterHub function initializes the Yoctopuce API and indicates where the modules should be looked for. When used with the parameter "usb", it will use the modules locally connected to the computer running the library. If the initialization does not succeed, this function returns a value different from YAPI.SUCCESS and errmsg contains the error message.

YSerialPort.FindSerialPort

The YSerialPort.FindSerialPort function allows you to find a serial port from the serial number of the module on which it resides and from its function name. You can use logical names as well, as long as you have initialized them. Let us imagine a Yocto-Serial module with serial number YSERIAL1-123456 which you have named "MyModule", and for which you have given the serialPort function the name "MyFunction". The following five calls are strictly equivalent, as long as "MyFunction" is defined only once.


serialport = YSerialPort.FindSerialPort("YSERIAL1-123456.serialPort")
serialport = YSerialPort.FindSerialPort("YSERIAL1-123456.MyFunction")
serialport = YSerialPort.FindSerialPort("MyModule.serialPort")
serialport = YSerialPort.FindSerialPort("MyModule.MyFunction")
serialport = YSerialPort.FindSerialPort("MyFunction")

YSerialPort.FindSerialPort returns an object which you can then use at will to control the serial port.

isOnline

The isOnline() method of the object returned by YSerialPort.FindSerialPort allows you to know if the corresponding module is present and in working order.

reset

The reset() method of the objet returned by YSerialPort.FindSerialPort clear all internal buffers of the serial port.

readLine

The readLine() method returns the next CR/LF terminated line received on the serial port, or an empty string if no more lines are found (this function is non-blocking).

writeLine

The writeLine() method puts the specified string in the serial port output buffer, followed by CR/LF.

A real example

Launch Python and open the corresponding sample script provided in the directory Examples/Doc-GettingStarted-Yocto-Serial of the Yoctopuce library.

In this example, you will recognize the functions explained above, but this time used with all side materials needed to make it work nicely as a small demo.

#!/usr/bin/python
# -*- coding: utf-8 -*-
import os,sys
import os, sys
sys.path.append(os.path.join("..", "..", "Sources"))
from yocto_api import *
from yocto_serialport import *

# Setup the API to use local USB devices. You can
# use an IP address instead of 'usb' if the device
# is connected to a network.

errmsg = YRefParam()
if YAPI.RegisterHub("usb", errmsg) != YAPI.SUCCESS:
    sys.exit("init error" + errmsg.value)

if len(sys.argv) > 1:
    serialPort = YSerialPort.FindSerialPort(sys.argv[1] + ".serialPort")
    if not serialPort.isOnline():
        sys.exit('Module not connected')
else:
    serialPort = YSerialPort.FirstSerialPort()
    if serialPort is None:
        sys.exit('No module connected (check cable)')

    serialPort.set_serialMode("9600,8N1")
    serialPort.set_protocol("Line")
    serialPort.reset()
   
    print("****************************")
    print("* make sure voltage levels *")
    print("* are properly configured  *")
    print("****************************")

while True:
    print("Type line to send, or Ctrl-C to exit:")
    line = input(": ")  # use raw_input in python 2.x
    if line == "":
        break
    serialPort.writeLine(line)
    YAPI.Sleep(500)
    line = serialPort.readLine()
    if (line != ""):
        print("Received: " + line)
YAPI.FreeAPI()
 

16.4. Control of the module part

Each module can be controlled in a similar manner, you can find below a simple sample program displaying the main parameters of the module and enabling you to activate the localization beacon.

#!/usr/bin/python
# -*- coding: utf-8 -*-
import os, sys
from yocto_api import *


def usage():
    sys.exit("usage: demo <serial or logical name> [ON/OFF]")


errmsg = YRefParam()
if YAPI.RegisterHub("usb", errmsg) != YAPI.SUCCESS:
    sys.exit("RegisterHub error: " + str(errmsg))

if len(sys.argv) < 2:
    usage()

m = YModule.FindModule(sys.argv[1])  # # use serial or logical name

if m.isOnline():
    if len(sys.argv) > 2:
        if sys.argv[2].upper() == "ON":
            m.set_beacon(YModule.BEACON_ON)
        if sys.argv[2].upper() == "OFF":
            m.set_beacon(YModule.BEACON_OFF)

    print("serial:       " + m.get_serialNumber())
    print("logical name: " + m.get_logicalName())
    print("luminosity:   " + str(m.get_luminosity()))
    if m.get_beacon() == YModule.BEACON_ON:
        print("beacon:       ON")
    else:
        print("beacon:       OFF")
    print("upTime:       " + str(m.get_upTime() / 1000) + " sec")
    print("USB current:  " + str(m.get_usbCurrent()) + " mA")
    print("logs:\n" + m.get_lastLogs())
else:
    print(sys.argv[1] + " not connected (check identification and USB cable)")



 

Each property xxx of the module can be read thanks to a method of type YModule.get_xxxx(), and properties which are not read-only can be modified with the help of the YModule.set_xxx() method. For more details regarding the used functions, refer to the API chapters.

Changing the module settings

When you want to modify the settings of a module, you only need to call the corresponding YModule.set_xxx() function. However, this modification is performed only in the random access memory (RAM) of the module: if the module is restarted, the modifications are lost. To memorize them persistently, it is necessary to ask the module to save its current configuration in its permanent memory. To do so, use the YModule.saveToFlash() method. Inversely, it is possible to force the module to forget its current settings by using the YModule.revertFromFlash() method. The short example below allows you to modify the logical name of a module.

#!/usr/bin/python
# -*- coding: utf-8 -*-
import os, sys
from yocto_api import *


def usage():
    sys.exit("usage: demo <serial or logical name> <new logical name>")


if len(sys.argv) != 3:
    usage()

errmsg = YRefParam()
if YAPI.RegisterHub("usb", errmsg) != YAPI.SUCCESS:
    sys.exit("RegisterHub error: " + str(errmsg))

m = YModule.FindModule(sys.argv[1])  # use serial or logical name
if m.isOnline():
    newname = sys.argv[2]
    if not YAPI.CheckLogicalName(newname):
        sys.exit("Invalid name (" + newname + ")")
    m.set_logicalName(newname)
    m.saveToFlash()  # do not forget this
    print("Module: serial= " + m.get_serialNumber() + " / name= " + m.get_logicalName())
else:
    sys.exit("not connected (check identification and USB cable")

 

Warning: the number of write cycles of the nonvolatile memory of the module is limited. When this limit is reached, nothing guaranties that the saving process is performed correctly. This limit, linked to the technology employed by the module micro-processor, is located at about 100000 cycles. In short, you can use the YModule.saveToFlash() function only 100000 times in the life of the module. Make sure you do not call this function within a loop.

Listing the modules

Obtaining the list of the connected modules is performed with the YModule.yFirstModule() function which returns the first module found. Then, you only need to call the nextModule() function of this object to find the following modules, and this as long as the returned value is not null. Below a short example listing the connected modules.

#!/usr/bin/python
# -*- coding: utf-8 -*-
import os,sys

from yocto_api import *

errmsg = YRefParam()

# Setup the API to use local USB devices
if YAPI.RegisterHub("usb", errmsg) != YAPI.SUCCESS:
    sys.exit("init error" + str(errmsg))

print('Device list')

module = YModule.FirstModule()
while module is not None:
    print(module.get_serialNumber() + ' (' + module.get_productName() + ')')
    module = module.nextModule()
 

16.5. Error handling

When you implement a program which must interact with USB modules, you cannot disregard error handling. Inevitably, there will be a time when a user will have unplugged the device, either before running the software, or even while the software is running. The Yoctopuce library is designed to help you support this kind of behavior, but your code must nevertheless be conceived to interpret in the best possible way the errors indicated by the library.

The simplest way to work around the problem is the one used in the short examples provided in this chapter: before accessing a module, check that it is online with the isOnline function, and then hope that it will stay so during the fraction of a second necessary for the following code lines to run. This method is not perfect, but it can be sufficient in some cases. You must however be aware that you cannot completely exclude an error which would occur after the call to isOnline and which could crash the software. The only way to prevent this is to implement one of the two error handling techniques described below.

The method recommended by most programming languages for unpredictable error handling is the use of exceptions. By default, it is the behavior of the Yoctopuce library. If an error happens while you try to access a module, the library throws an exception. In this case, there are three possibilities:

As this latest situation is not the most desirable, the Yoctopuce library offers another possibility for error handling, allowing you to create a robust program without needing to catch exceptions at every line of code. You simply need to call the yDisableExceptions() function to commute the library to a mode where exceptions for all the functions are systematically replaced by specific return values, which can be tested by the caller when necessary. For each function, the name of each return value in case of error is systematically documented in the library reference. The name always follows the same logic: a get_state() method returns a Y_STATE_INVALID value, a get_currentValue method returns a Y_CURRENTVALUE_INVALID value, and so on. In any case, the returned value is of the expected type and is not a null pointer which would risk crashing your program. At worst, if you display the value without testing it, it will be outside the expected bounds for the returned value. In the case of functions which do not normally return information, the return value is YAPI_SUCCESS if everything went well, and a different error code in case of failure.

When you work without exceptions, you can obtain an error code and an error message explaining the source of the error. You can request them from the object which returned the error, calling the errType() and errMessage() methods. Their returned values contain the same information as in the exceptions when they are active.

17. Using the Yocto-Serial with Java

Java is an object oriented language created by Sun Microsystem. Beside being free, its main strength is its portability. Unfortunately, this portability has an excruciating price. In Java, hardware abstraction is so high that it is almost impossible to work directly with the hardware. Therefore, the Yoctopuce API does not support native mode in regular Java. The Java API needs a Virtual Hub to communicate with Yoctopuce devices.

17.1. Getting ready

Go to the Yoctopuce web site and download the following items:

The library is available as source files as well as a jar file. Decompress the library files in a folder of your choice, connect your modules, run the VirtualHub software, and you are ready to start your first tests. You do not need to install any driver.

In order to keep them simple, all the examples provided in this documentation are console applications. Naturally, the libraries function in a strictly identical manner if you integrate them in an application with a graphical interface.

17.2. Control of the SerialPort function

A few lines of code are enough to use a Yocto-Serial. Here is the skeleton of a Java code snippet to use the SerialPort function.


[...]

// Get access to your device, connected locally on USB for instance
YAPI.RegisterHub("127.0.0.1");
serialport = YSerialPort.FindSerialPort("YSERIAL1-123456.serialPort");

// Hot-plug is easy: just check that the device is online
if (serialport.isOnline())
   { //Use serialport.get_serialMode()
     ...
   }

[...]

Let us look at these lines in more details.

YAPI.RegisterHub

The yAPI.RegisterHub function initializes the Yoctopuce API and indicates where the modules should be looked for. The parameter is the address of the Virtual Hub able to see the devices. If the initialization does not succeed, an exception is thrown.

YSerialPort.FindSerialPort

The YSerialPort.FindSerialPort function allows you to find a serial port from the serial number of the module on which it resides and from its function name. You can use logical names as well, as long as you have initialized them. Let us imagine a Yocto-Serial module with serial number YSERIAL1-123456 which you have named "MyModule", and for which you have given the serialPort function the name "MyFunction". The following five calls are strictly equivalent, as long as "MyFunction" is defined only once.


serialport = YSerialPort.FindSerialPort("YSERIAL1-123456.serialPort")
serialport = YSerialPort.FindSerialPort("YSERIAL1-123456.MyFunction")
serialport = YSerialPort.FindSerialPort("MyModule.serialPort")
serialport = YSerialPort.FindSerialPort("MyModule.MyFunction")
serialport = YSerialPort.FindSerialPort("MyFunction")

YSerialPort.FindSerialPort returns an object which you can then use at will to control the serial port.

isOnline

The isOnline() method of the object returned by YSerialPort.FindSerialPort allows you to know if the corresponding module is present and in working order.

reset

The reset() method of the objet returned by YSerialPort.FindSerialPort clear all internal buffers of the serial port.

readLine

The readLine() method returns the next CR/LF terminated line received on the serial port, or an empty string if no more lines are found (this function is non-blocking).

writeLine

The writeLine() method puts the specified string in the serial port output buffer, followed by CR/LF.

A real example

Launch you Java environment and open the corresponding sample project provided in the directory Examples/Doc-GettingStarted-Yocto-Serial of the Yoctopuce library.

In this example, you will recognize the functions explained above, but this time used with all the side materials needed to make it work nicely as a small demo.

import com.yoctopuce.YoctoAPI.YAPI;
import com.yoctopuce.YoctoAPI.YAPI_Exception;
import com.yoctopuce.YoctoAPI.YSerialPort;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Demo {


    public static void main(String[] args)
    {
        try {
            // setup the API to use local VirtualHub
            YAPI.RegisterHub("127.0.0.1");
        } catch (YAPI_Exception ex) {
            System.out.println("Cannot contact VirtualHub on 127.0.0.1 (" + ex.getLocalizedMessage() + ")");
            System.out.println("Ensure that the VirtualHub application is running");
            System.exit(1);
        }

        YSerialPort serialPort;
        if (args.length > 0) {
            String target = args[0];
            serialPort = YSerialPort.FindSerialPort(target + ".serialPort");
        } else {
            serialPort = YSerialPort.FirstSerialPort();
            if (serialPort == null) {
                System.out.println("No module connected (check USB cable)");
                System.exit(1);
            }
        }

        System.out.println("****************************");
        System.out.println("* make sure voltage levels *");
        System.out.println("* are properly configured  *");
        System.out.println("****************************");
         
        InputStreamReader inputStreamReader = new InputStreamReader(System.in);
        BufferedReader console = new BufferedReader(inputStreamReader);
        try {
            serialPort.set_serialMode("9600,8N1");
            serialPort.set_protocol("Line");
            serialPort.reset();
            String line;
            do {
                YAPI.Sleep(500);
                do {
                    line = serialPort.readLine();
                    if (!line.equals("")) {
                        System.out.println("Received: " + line);
                    }
                } while (!line.equals(""));
                System.out.println("Type line to send, or Ctrl-C to exit:");
                line = console.readLine();
                serialPort.writeLine(line);
            } while (!line.equals(""));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        YAPI.FreeAPI();
    }
}
 

17.3. Control of the module part

Each module can be controlled in a similar manner, you can find below a simple sample program displaying the main parameters of the module and enabling you to activate the localization beacon.


import com.yoctopuce.YoctoAPI.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Demo {

    public static void main(String[] args)
    {
        try {
            // setup the API to use local VirtualHub
            YAPI.RegisterHub("127.0.0.1");
        } catch (YAPI_Exception ex) {
            System.out.println("Cannot contact VirtualHub on 127.0.0.1 (" + ex.getLocalizedMessage() + ")");
            System.out.println("Ensure that the VirtualHub application is running");
            System.exit(1);
        }
        System.out.println("usage: demo [serial or logical name] [ON/OFF]");

        YModule module;
        if (args.length == 0) {
            module = YModule.FirstModule();
            if (module == null) {
                System.out.println("No module connected (check USB cable)");
                System.exit(1);
            }
        } else {
            module = YModule.FindModule(args[0]);  // use serial or logical name
        }

        try {
            if (args.length > 1) {
                if (args[1].equalsIgnoreCase("ON")) {
                    module.setBeacon(YModule.BEACON_ON);
                } else {
                    module.setBeacon(YModule.BEACON_OFF);
                }
            }
            System.out.println("serial:       " + module.get_serialNumber());
            System.out.println("logical name: " + module.get_logicalName());
            System.out.println("luminosity:   " + module.get_luminosity());
            if (module.get_beacon() == YModule.BEACON_ON) {
                System.out.println("beacon:       ON");
            } else {
                System.out.println("beacon:       OFF");
            }
            System.out.println("upTime:       " + module.get_upTime() / 1000 + " sec");
            System.out.println("USB current:  " + module.get_usbCurrent() + " mA");
            System.out.println("logs:\n" + module.get_lastLogs());
        } catch (YAPI_Exception ex) {
            System.out.println(args[1] + " not connected (check identification and USB cable)");
        }
        YAPI.FreeAPI();
    }
}
 

Each property xxx of the module can be read thanks to a method of type YModule.get_xxxx(), and properties which are not read-only can be modified with the help of the YModule.set_xxx() method. For more details regarding the used functions, refer to the API chapters.

Changing the module settings

When you want to modify the settings of a module, you only need to call the corresponding YModule.set_xxx() function. However, this modification is performed only in the random access memory (RAM) of the module: if the module is restarted, the modifications are lost. To memorize them persistently, it is necessary to ask the module to save its current configuration in its permanent memory. To do so, use the YModule.saveToFlash() method. Inversely, it is possible to force the module to forget its current settings by using the YModule.revertFromFlash() method. The short example below allows you to modify the logical name of a module.

import com.yoctopuce.YoctoAPI.*;

public class Demo {

    public static void main(String[] args)
    {
        try {
            // setup the API to use local VirtualHub
            YAPI.RegisterHub("127.0.0.1");
        } catch (YAPI_Exception ex) {
            System.out.println("Cannot contact VirtualHub on 127.0.0.1 (" + ex.getLocalizedMessage() + ")");
            System.out.println("Ensure that the VirtualHub application is running");
            System.exit(1);
        }

        if (args.length != 2) {
            System.out.println("usage: demo <serial or logical name> <new logical name>");
            System.exit(1);
        }

        YModule m;
        String newname;

        m = YModule.FindModule(args[0]); // use serial or logical name

        try {
            newname = args[1];
            if (!YAPI.CheckLogicalName(newname))
                {
                    System.out.println("Invalid name (" + newname + ")");
                    System.exit(1);
                }

            m.set_logicalName(newname);
            m.saveToFlash(); // do not forget this

            System.out.println("Module: serial= " + m.get_serialNumber());
            System.out.println(" / name= " + m.get_logicalName());
        } catch (YAPI_Exception ex) {
            System.out.println("Module " + args[0] + "not connected (check identification and USB cable)");
            System.out.println(ex.getMessage());
            System.exit(1);
        }

        YAPI.FreeAPI();
    }
}
 

Warning: the number of write cycles of the nonvolatile memory of the module is limited. When this limit is reached, nothing guaranties that the saving process is performed correctly. This limit, linked to the technology employed by the module micro-processor, is located at about 100000 cycles. In short, you can use the YModule.saveToFlash() function only 100000 times in the life of the module. Make sure you do not call this function within a loop.

Listing the modules

Obtaining the list of the connected modules is performed with the YModule.yFirstModule() function which returns the first module found. Then, you only need to call the nextModule() function of this object to find the following modules, and this as long as the returned value is not null. Below a short example listing the connected modules.

import com.yoctopuce.YoctoAPI.*;

public class Demo {

    public static void main(String[] args)
    {
        try {
            // setup the API to use local VirtualHub
            YAPI.RegisterHub("127.0.0.1");
        } catch (YAPI_Exception ex) {
            System.out.println("Cannot contact VirtualHub on 127.0.0.1 (" + ex.getLocalizedMessage() + ")");
            System.out.println("Ensure that the VirtualHub application is running");
            System.exit(1);
        }

        System.out.println("Device list");
        YModule module = YModule.FirstModule();
        while (module != null) {
            try {
                System.out.println(module.get_serialNumber() + " (" + module.get_productName() + ")");
            } catch (YAPI_Exception ex) {
                break;
            }
            module = module.nextModule();
        }

        YAPI.FreeAPI();
    }
}
 

17.4. Error handling

When you implement a program which must interact with USB modules, you cannot disregard error handling. Inevitably, there will be a time when a user will have unplugged the device, either before running the software, or even while the software is running. The Yoctopuce library is designed to help you support this kind of behavior, but your code must nevertheless be conceived to interpret in the best possible way the errors indicated by the library.

The simplest way to work around the problem is the one used in the short examples provided in this chapter: before accessing a module, check that it is online with the isOnline function, and then hope that it will stay so during the fraction of a second necessary for the following code lines to run. This method is not perfect, but it can be sufficient in some cases. You must however be aware that you cannot completely exclude an error which would occur after the call to isOnline and which could crash the software.

In the Java API, error handling is implemented with exceptions. Therefore you must catch and handle correctly all exceptions that might be thrown by the API if you do not want your software to crash as soon as you unplug a device.

18. Using the Yocto-Serial with Android

To tell the truth, Android is not a programming language, it is an operating system developed by Google for mobile appliances such as smart phones and tablets. But it so happens that under Android everything is programmed with the same programming language: Java. Nevertheless, the programming paradigms and the possibilities to access the hardware are slightly different from classical Java, and this justifies a separate chapter on Android programming.

18.1. Native access and VirtualHub

In the opposite to the classical Java API, the Java for Android API can access USB modules natively. However, as there is no VirtualHub running under Android, it is not possible to remotely control Yoctopuce modules connected to a machine under Android. Naturally, the Java for Android API remains perfectly able to connect itself to a VirtualHub running on another OS.

18.2. Getting ready

Go to the Yoctopuce web site and download the Java for Android programming library45. The library is available as source files, and also as a jar file. Connect your modules, decompress the library files in the directory of your choice, and configure your Android programming environment so that it can find them.

To keep them simple, all the examples provided in this documentation are snippets of Android applications. You must integrate them in your own Android applications to make them work. However, your can find complete applications in the examples provided with the Java for Android library.

18.3. Compatibility

In an ideal world, you would only need to have a smart phone running under Android to be able to make Yoctopuce modules work. Unfortunately, it is not quite so in the real world. A machine running under Android must fulfil to a few requirements to be able to manage Yoctopuce USB modules natively.

Android 4.x

Android 4.0 (api 14) and following are officially supported. Theoretically, support of USB host functions since Android 3.1. But be aware that the Yoctopuce Java for Android API is regularly tested only from Android 4 onwards.

USB host support

Naturally, not only must your machine have a USB port, this port must also be able to run in host mode. In host mode, the machine literally takes control of the devices which are connected to it. The USB ports of a desktop computer, for example, work in host mode. The opposite of the host mode is the device mode. USB keys, for instance, work in device mode: they must be controlled by a host. Some USB ports are able to work in both modes, they are OTG (On The Go) ports. It so happens that many mobile devices can only work in device mode: they are designed to be connected to a charger or a desktop computer, and nothing else. It is therefore highly recommended to pay careful attention to the technical specifications of a product working under Android before hoping to make Yoctopuce modules work with it.

Unfortunately, having a correct version of Android and USB ports working in host mode is not enough to guaranty that Yoctopuce modules will work well under Android. Indeed, some manufacturers configure their Android image so that devices other than keyboard and mass storage are ignored, and this configuration is hard to detect. As things currently stand, the best way to know if a given Android machine works with Yoctopuce modules consists in trying.

Supported hardware

The library is tested and validated on the following machines:

If your Android machine is not able to control Yoctopuce modules natively, you still have the possibility to remotely control modules driven by a VirtualHub on another OS, or a YoctoHub 46.

18.4. Activating the USB port under Android

By default, Android does not allow an application to access the devices connected to the USB port. To enable your application to interact with a Yoctopuce module directly connected on your tablet on a USB port, a few additional steps are required. If you intend to interact only with modules connected on another machine through the network, you can ignore this section.

In your AndroidManifest.xml, you must declare using the "USB Host" functionality by adding the <uses-feature android:name="android.hardware.usb.host" /> tag in the manifest section.


<manifest ...>
    ...
    <uses-feature android:name="android.hardware.usb.host" />;
    ...
</manifest>

When first accessing a Yoctopuce module, Android opens a window to inform the user that the application is going to access the connected module. The user can deny or authorize access to the device. If the user authorizes the access, the application can access the connected device as long as it stays connected. To enable the Yoctopuce library to correctly manage these authorizations, your must provide a pointer on the application context by calling the EnableUSBHost method of the YAPI class before the first USB access. This function takes as arguments an object of the android.content.Context class (or of a subclass). As the Activity class is a subclass of Context, it is simpler to call YAPI.EnableUSBHost(this); in the method onCreate of your application. If the object passed as parameter is not of the correct type, a YAPI_Exception exception is generated.


...
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    try {
                // Pass the application Context to the Yoctopuce Library
        YAPI.EnableUSBHost(this);
        } catch (YAPI_Exception e) {
                Log.e("Yocto",e.getLocalizedMessage());
        }
}
...

Autorun

It is possible to register your application as a default application for a USB module. In this case, as soon as a module is connected to the system, the application is automatically launched. You must add <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/> in the section <intent-filter> of the main activity. The section <activity> must have a pointer to an XML file containing the list of USB modules which can run the application.


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    <uses-feature android:name="android.hardware.usb.host" />
    ...
    <application ... >
        <activity
            android:name=".MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
                android:resource="@xml/device_filter" />
        </activity>
    </application>

</manifest>

The XML file containing the list of modules allowed to run the application must be saved in the res/xml directory. This file contains a list of USB vendorId and deviceID in decimal. The following example runs the application as soon as a Yocto-Relay or a YoctoPowerRelay is connected. You can find the vendorID and the deviceID of Yoctopuce modules in the characteristics section of the documentation.


<?xml version="1.0" encoding="utf-8"?>

<resources>
    <usb-device vendor-id="9440" product-id="12" />
    <usb-device vendor-id="9440" product-id="13" />
</resources>

18.5. Control of the SerialPort function

A few lines of code are enough to use a Yocto-Serial. Here is the skeleton of a Java code snippet to use the SerialPort function.


[...]

// Retrieving the object representing the module (connected here locally by USB)
YAPI.EnableUSBHost(this);
YAPI.RegisterHub("usb");
serialport = YSerialPort.FindSerialPort("YSERIAL1-123456.serialPort");

// Hot-plug is easy: just check that the device is online
if (serialport.isOnline())
   { //Use serialport.get_serialMode()
     ...
   }

[...]

Let us look at these lines in more details.

YAPI.EnableUSBHost

The YAPI.EnableUSBHost function initializes the API with the Context of the current application. This function takes as argument an object of the android.content.Context class (or of a subclass). If you intend to connect your application only to other machines through the network, this function is facultative.

YAPI.RegisterHub

The yAPI.RegisterHub function initializes the Yoctopuce API and indicates where the modules should be looked for. The parameter is the address of the virtual hub able to see the devices. If the string "usb" is passed as parameter, the API works with modules locally connected to the machine. If the initialization does not succeed, an exception is thrown.

YSerialPort.FindSerialPort

The YSerialPort.FindSerialPort function allows you to find a serial port from the serial number of the module on which it resides and from its function name. You can use logical names as well, as long as you have initialized them. Let us imagine a Yocto-Serial module with serial number YSERIAL1-123456 which you have named "MyModule", and for which you have given the serialPort function the name "MyFunction". The following five calls are strictly equivalent, as long as "MyFunction" is defined only once.


serialport = YSerialPort.FindSerialPort("YSERIAL1-123456.serialPort")
serialport = YSerialPort.FindSerialPort("YSERIAL1-123456.MyFunction")
serialport = YSerialPort.FindSerialPort("MyModule.serialPort")
serialport = YSerialPort.FindSerialPort("MyModule.MyFunction")
serialport = YSerialPort.FindSerialPort("MyFunction")

YSerialPort.FindSerialPort returns an object which you can then use at will to control the serial port.

isOnline

The isOnline() method of the object returned by YSerialPort.FindSerialPort allows you to know if the corresponding module is present and in working order.

reset

The reset() method of the objet returned by YSerialPort.FindSerialPort clear all internal buffers of the serial port.

readLine

The readLine() method returns the next CR/LF terminated line received on the serial port, or an empty string if no more lines are found (this function is non-blocking).

writeLine

The writeLine() method puts the specified string in the serial port output buffer, followed by CR/LF.

A real example

Launch you Java environment and open the corresponding sample project provided in the directory Examples//Doc-Examples of the Yoctopuce library.

In this example, you can recognize the functions explained above, but this time used with all the side materials needed to make it work nicely as a small demo.

package com.yoctopuce.doc_examples;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.TextView;

import com.yoctopuce.YoctoAPI.YAPI;
import com.yoctopuce.YoctoAPI.YAPI_Exception;
import com.yoctopuce.YoctoAPI.YPwmOutput;
import com.yoctopuce.YoctoAPI.YSerialPort;

public class GettingStarted_Yocto_Serial extends Activity implements OnItemSelectedListener
{

    private YSerialPort serialPort = null;
    private ArrayAdapter<String> aa;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.gettingstarted_yocto_serial);
        Spinner my_spin = (Spinner) findViewById(R.id.spinner1);
        my_spin.setOnItemSelectedListener(this);
        aa = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
        aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        my_spin.setAdapter(aa);
    }

    @Override
    protected void onStart()
    {
        super.onStart();
        aa.clear();
        try {
            YAPI.EnableUSBHost(this);
            YAPI.RegisterHub("usb");
            YSerialPort s = YSerialPort.FirstSerialPort();
            while (s != null) {
                String hwid = s.get_hardwareId();
                aa.add(hwid);
                s = s.nextSerialPort();
            }
        } catch (YAPI_Exception e) {
            e.printStackTrace();
        }
        aa.notifyDataSetChanged();
    }

    @Override
    protected void onStop()
    {
        super.onStop();
        YAPI.FreeAPI();
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
    {
        String hwid = (String) parent.getItemAtPosition(pos);
        serialPort = YSerialPort.FindSerialPort(hwid);
        try {
            serialPort.set_serialMode("9600,8N1");
            serialPort.set_protocol("Line");
            serialPort.reset();
        }catch (YAPI_Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> arg0)
    {
    }

    /** Called when the user touches the button State A */
    public void update(View view)
    {
        if (serialPort == null)
            return;

        try {

            EditText editText = (EditText) findViewById(R.id.editText1);
            String line = editText.getText().toString();
            serialPort.writeLine(line);
            YAPI.Sleep(500);
            String response = "";
            String outline;
            do {
                outline = serialPort.readLine();
                response += outline;
            } while (!outline.equals(""));
            TextView textView = (TextView) findViewById(R.id.response);
            textView.setText(response);
        } catch (YAPI_Exception e) {
            e.printStackTrace();
        }
    }
}
 

18.6. Control of the module part

Each module can be controlled in a similar manner, you can find below a simple sample program displaying the main parameters of the module and enabling you to activate the localization beacon.

package com.yoctopuce.doc_examples;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.TextView;

import com.yoctopuce.YoctoAPI.YAPI;
import com.yoctopuce.YoctoAPI.YAPI_Exception;
import com.yoctopuce.YoctoAPI.YModule;

public class ModuleControl extends Activity implements OnItemSelectedListener
{

    private ArrayAdapter<String> aa;
    private YModule module = null;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.modulecontrol);
        Spinner my_spin = (Spinner) findViewById(R.id.spinner1);
        my_spin.setOnItemSelectedListener(this);
        aa = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
        aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        my_spin.setAdapter(aa);
    }

    @Override
    protected void onStart()
    {
        super.onStart();

        try {
            aa.clear();
            YAPI.EnableUSBHost(this);
            YAPI.RegisterHub("usb");
            YModule r = YModule.FirstModule();
            while (r != null) {
                String hwid = r.get_hardwareId();
                aa.add(hwid);
                r = r.nextModule();
            }
        } catch (YAPI_Exception e) {
            e.printStackTrace();
        }
        // refresh Spinner with detected relay
        aa.notifyDataSetChanged();
    }

    @Override
    protected void onStop()
    {
        super.onStop();
        YAPI.FreeAPI();
    }

    private void DisplayModuleInfo()
    {
        TextView field;
        if (module == null)
            return;
        try {
            field = (TextView) findViewById(R.id.serialfield);
            field.setText(module.getSerialNumber());
            field = (TextView) findViewById(R.id.logicalnamefield);
            field.setText(module.getLogicalName());
            field = (TextView) findViewById(R.id.luminosityfield);
            field.setText(String.format("%d%%", module.getLuminosity()));
            field = (TextView) findViewById(R.id.uptimefield);
            field.setText(module.getUpTime() / 1000 + " sec");
            field = (TextView) findViewById(R.id.usbcurrentfield);
            field.setText(module.getUsbCurrent() + " mA");
            Switch sw = (Switch) findViewById(R.id.beaconswitch);
            sw.setChecked(module.getBeacon() == YModule.BEACON_ON);
            field = (TextView) findViewById(R.id.logs);
            field.setText(module.get_lastLogs());

        } catch (YAPI_Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
    {
        String hwid = parent.getItemAtPosition(pos).toString();
        module = YModule.FindModule(hwid);
        DisplayModuleInfo();
    }

    @Override
    public void onNothingSelected(AdapterView<?> arg0)
    {
    }

    public void refreshInfo(View view)
    {
        DisplayModuleInfo();
    }

    public void toggleBeacon(View view)
    {
        if (module == null)
            return;
        boolean on = ((Switch) view).isChecked();

        try {
            if (on) {
                module.setBeacon(YModule.BEACON_ON);
            } else {
                module.setBeacon(YModule.BEACON_OFF);
            }
        } catch (YAPI_Exception e) {
            e.printStackTrace();
        }
    }
}
 

Each property xxx of the module can be read thanks to a method of type YModule.get_xxxx(), and properties which are not read-only can be modified with the help of the YModule.set_xxx() method. For more details regarding the used functions, refer to the API chapters.

Changing the module settings

When you want to modify the settings of a module, you only need to call the corresponding YModule.set_xxx() function. However, this modification is performed only in the random access memory (RAM) of the module: if the module is restarted, the modifications are lost. To memorize them persistently, it is necessary to ask the module to save its current configuration in its permanent memory. To do so, use the YModule.saveToFlash() method. Inversely, it is possible to force the module to forget its current settings by using the YModule.revertFromFlash() method. The short example below allows you to modify the logical name of a module.

package com.yoctopuce.doc_examples;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.yoctopuce.YoctoAPI.YAPI;
import com.yoctopuce.YoctoAPI.YAPI_Exception;
import com.yoctopuce.YoctoAPI.YModule;

public class SaveSettings extends Activity implements OnItemSelectedListener
{

    private ArrayAdapter<String> aa;
    private YModule module = null;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.savesettings);
        Spinner my_spin = (Spinner) findViewById(R.id.spinner1);
        my_spin.setOnItemSelectedListener(this);
        aa = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
        aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        my_spin.setAdapter(aa);
    }

    @Override
    protected void onStart()
    {
        super.onStart();

        try {
            aa.clear();
            YAPI.EnableUSBHost(this);
            YAPI.RegisterHub("usb");
            YModule r = YModule.FirstModule();
            while (r != null) {
                String hwid = r.get_hardwareId();
                aa.add(hwid);
                r = r.nextModule();
            }
        } catch (YAPI_Exception e) {
            e.printStackTrace();
        }
        // refresh Spinner with detected relay
        aa.notifyDataSetChanged();
    }

    @Override
    protected void onStop()
    {
        super.onStop();
        YAPI.FreeAPI();
    }

    private void DisplayModuleInfo()
    {
        TextView field;
        if (module == null)
            return;
        try {
            YAPI.UpdateDeviceList();// fixme
            field = (TextView) findViewById(R.id.logicalnamefield);
            field.setText(module.getLogicalName());
        } catch (YAPI_Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
    {
        String hwid = parent.getItemAtPosition(pos).toString();
        module = YModule.FindModule(hwid);
        DisplayModuleInfo();
    }

    @Override
    public void onNothingSelected(AdapterView<?> arg0)
    {
    }

    public void saveName(View view)
    {
        if (module == null)
            return;

        EditText edit = (EditText) findViewById(R.id.newname);
        String newname = edit.getText().toString();
        try {
            if (!YAPI.CheckLogicalName(newname)) {
                Toast.makeText(getApplicationContext(), "Invalid name (" + newname + ")", Toast.LENGTH_LONG).show();
                return;
            }
            module.set_logicalName(newname);
            module.saveToFlash(); // do not forget this
            edit.setText("");
        } catch (YAPI_Exception ex) {
            ex.printStackTrace();
        }
        DisplayModuleInfo();
    }

}
 

Warning: the number of write cycles of the nonvolatile memory of the module is limited. When this limit is reached, nothing guaranties that the saving process is performed correctly. This limit, linked to the technology employed by the module micro-processor, is located at about 100000 cycles. In short, you can use the YModule.saveToFlash() function only 100000 times in the life of the module. Make sure you do not call this function within a loop.

Listing the modules

Obtaining the list of the connected modules is performed with the YModule.yFirstModule() function which returns the first module found. Then, you only need to call the nextModule() function of this object to find the following modules, and this as long as the returned value is not null. Below a short example listing the connected modules.

package com.yoctopuce.doc_examples;

import android.app.Activity;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.yoctopuce.YoctoAPI.YAPI;
import com.yoctopuce.YoctoAPI.YAPI_Exception;
import com.yoctopuce.YoctoAPI.YModule;

public class Inventory extends Activity
{

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.inventory);
    }

    public void refreshInventory(View view)
    {
        LinearLayout layout = (LinearLayout) findViewById(R.id.inventoryList);
        layout.removeAllViews();

        try {
            YAPI.UpdateDeviceList();
            YModule module = YModule.FirstModule();
            while (module != null) {
                String line = module.get_serialNumber() + " (" + module.get_productName() + ")";
                TextView tx = new TextView(this);
                tx.setText(line);
                tx.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
                layout.addView(tx);
                module = module.nextModule();
            }
        } catch (YAPI_Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onStart()
    {
        super.onStart();
        try {
            YAPI.EnableUSBHost(this);
            YAPI.RegisterHub("usb");
        } catch (YAPI_Exception e) {
            e.printStackTrace();
        }
        refreshInventory(null);
    }

    @Override
    protected void onStop()
    {
        super.onStop();
        YAPI.FreeAPI();
    }

}
 

18.7. Error handling

When you implement a program which must interact with USB modules, you cannot disregard error handling. Inevitably, there will be a time when a user will have unplugged the device, either before running the software, or even while the software is running. The Yoctopuce library is designed to help you support this kind of behavior, but your code must nevertheless be conceived to interpret in the best possible way the errors indicated by the library.

The simplest way to work around the problem is the one used in the short examples provided in this chapter: before accessing a module, check that it is online with the isOnline function, and then hope that it will stay so during the fraction of a second necessary for the following code lines to run. This method is not perfect, but it can be sufficient in some cases. You must however be aware that you cannot completely exclude an error which would occur after the call to isOnline and which could crash the software.

In the Java API for Android, error handling is implemented with exceptions. Therefore you must catch and handle correctly all exceptions that might be thrown by the API if you do not want your software to crash soon as you unplug a device.

19. Advanced programming

The preceding chapters have introduced, in each available language, the basic programming functions which can be used with your Yocto-Serial module. This chapter presents in a more generic manner a more advanced use of your module. Examples are provided in the language which is the most popular among Yoctopuce customers, that is C#. Nevertheless, you can find complete examples illustrating the concepts presented here in the programming libraries of each language.

To remain as concise as possible, examples provided in this chapter do not perform any error handling. Do not copy them "as is" in a production application.

19.1. Event programming

The methods to manage Yoctopuce modules which we presented to you in preceding chapters were polling functions, consisting in permanently asking the API if something had changed. While easy to understand, this programming technique is not the most efficient, nor the most reactive. Therefore, the Yoctopuce programming API also provides an event programming model. This technique consists in asking the API to signal by itself the important changes as soon as they are detected. Each time a key parameter is modified, the API calls a callback function which you have defined in advance.

Detecting module arrival and departure

Hot-plug management is important when you work with USB modules because, sooner or later, you will have to connect or disconnect a module when your application is running. The API is designed to manage module unexpected arrival or departure in a transparent way. But your application must take this into account if it wants to avoid pretending to use a disconnected module.

Event programming is particularly useful to detect module connection/disconnection. Indeed, it is simpler to be told of new connections rather than to have to permanently list the connected modules to deduce which ones just arrived and which ones left. To be warned as soon as a module is connected, you need three pieces of code.

The callback

The callback is the function which is called each time a new Yoctopuce module is connected. It takes as parameter the relevant module.


 static void deviceArrival(YModule m)
{
  Console.WriteLine("New module  : " + m.get_serialNumber());
}

Initialization

You must then tell the API that it must call the callback when a new module is connected.


YAPI.RegisterDeviceArrivalCallback(deviceArrival);

Note that if modules are already connected when the callback is registered, the callback is called for each of the already connected modules.

Triggering callbacks

A classis issue of callback programming is that these callbacks can be triggered at any time, including at times when the main program is not ready to receive them. This can have undesired side effects, such as dead-locks and other race conditions. Therefore, in the Yoctopuce API, module arrival/departure callbacks are called only when the UpdateDeviceList() function is running. You only need to call UpdateDeviceList() at regular intervals from a timer or from a specific thread to precisely control when the calls to these callbacks happen:


// waiting loop managing callbacks
while (true)
{
    // module arrival / departure callback
    YAPI.UpdateDeviceList(ref errmsg);
    // non active waiting time managing other callbacks
    YAPI.Sleep(500, ref errmsg);
}

In a similar way, it is possible to have a callback when a module is disconnected. You can find a complete example implemented in your favorite programming language in the Examples/Prog-EventBased directory of the corresponding library.

Be aware that in most programming languages, callbacks must be global procedures, and not methods. If you wish for the callback to call the method of an object, define your callback as a global procedure which then calls your method.

Detecting a modification in the value of a sensor

The Yoctopuce API also provides a callback system allowing you to be notified automatically with the value of any sensor, either when the value has changed in a significant way or periodically at a preset frequency. The code necessary to do so is rather similar to the code used to detect when a new module has been connected.

This technique is useful in particular if you want to detect very quick value changes (within a few milliseconds), as it is much more efficient than reading repeatedly the sensor value and therefore gives better performances.

Calliback invocation

To enable a better control, value change callbacks are only called when the YAPI.Sleep() and YAPI.HandleEvents() functions are running. Therefore, you must call one of these functions at a regular interval, either from a timer or from a parallel thread.


while (true)
{
  // inactive waiting loop allowing you to trigger
  // value change callbacks
  YAPI.Sleep(500, ref errmsg);
}

In programming environments where only the interface thread is allowed to interact with the user, it is often appropriate to call YAPI.HandleEvents() from this thread.

The value change callback

This type of callback is called when a generic sensor changes in a significant way. It takes as parameter the relevant function and the new value, as a character string. 47


static void valueChangeCallback(YGenericSensor fct, string value)
{
  Console.WriteLine(fct.get_hardwareId() + "=" + value);
}

In most programming languages, callbacks are global procedures, not methods. If you wish for the callback to call a method of an object, define your callback as a global procedure which then calls your method. If you need to keep a reference to your object, you can store it directly in the YGenericSensor object using function set_userData. You can then retrieve it in the global callback procedure using get_userData.

Setting up a value change callback

The callback is set up for a given GenericSensor function with the help of the registerValueCallback method. The following example sets up a callback for the first available GenericSensor function.


YGenericSensor f = YGenericSensor.FirstGenericSensor();
f.registerValueCallback(genericSensor1ChangeCallBack)

Note that each module function can thus have its own distinct callback. By the way, if you like to work with value change callbacks, you will appreciate the fact that value change callbacks are not limited to sensors, but are also available for all Yoctopuce devices (for instance, you can also receive a callback any time a relay state changes).

The timed report callback

This type of callback is automatically called at a predefined time interval. The callback frequency can be configured individually for each sensor, with frequencies going from hundred calls per seconds down to one call per hour. The callback takes as parameter the relevant function and the measured value, as an YMeasure object. Contrarily to the value change callback that only receives the latest value, an YMeasure object provides both minimal, maximal and average values since the timed report callback. Moreover, the measure includes precise timestamps, which makes it possible to use timed reports for a time-based graph even when not handled immediately.


static void periodicCallback(YGenericSensor fct, YMeasure measure)
{
  Console.WriteLine(fct.get_hardwareId() + "=" +
                    measure.get_averageValue());
}

Setting up a timed report callback

The callback is set up for a given GenericSensor function with the help of the registerTimedReportCallback method. The callback will only be invoked once a callback frequency as been set using set_reportFrequency (which defaults to timed report callback turned off). The frequency is specified as a string (same as for the data logger), by specifying the number of calls per second (/s), per minute (/m) or per hour (/h). The maximal frequency is 100 times per second (i.e. "100/s"), and the minimal frequency is 1 time per hour (i.e. "1/h"). When the frequency is higher than or equal to 1/s, the measure represents an instant value. When the frequency is below, the measure will include distinct minimal, maximal and average values based on a sampling performed automatically by the device.

The following example sets up a timed report callback 4 times per minute for t he first available GenericSensor function.


YGenericSensor f = YGenericSensor.FirstGenericSensor();
f.set_reportFrequency("4/m");
f.registerTimedReportCallback(periodicCallback);

As for value change callbacks, each module function can thus have its own distinct timed report callback.

Generic callback functions

It is sometimes desirable to use the same callback function for various types of sensors (e.g. for a generic sensor graphing application). This is possible by defining the callback for an object of class YSensor rather than YGenericSensor. Thus, the same callback function will be usable with any subclass of YSensor (and in particular with YGenericSensor). With the callback function, you can use the method get_unt() to get the physical unit of the sensor, if you need to display it.

A complete example

You can find a complete example implemented in your favorite programming language in the Examples/Prog-EventBased directory of the corresponding library.

19.2. The data logger

Your Yocto-Serial is equipped with a data logger able to store non-stop the measures performed by the module. The maximal frequency is 100 times per second (i.e. "100/s"), and the minimal frequency is 1 time per hour (i.e. "1/h"). When the frequency is higher than or equal to 1/s, the measure represents an instant value. When the frequency is below, the measure will include distinct minimal, maximal and average values based on a sampling performed automatically by the device.

The data logger flash memory can store about 500'000 instant measures, or 125'000 averaged measures. When the memory is about to be saturated, the oldest measures are automatically erased.

Make sure not to leave the data logger running at high speed unless really needed: the flash memory can only stand a limited number of erase cycles (typically 100'000 cycles). When running at full speed, the datalogger can burn more than 100 cycles per day ! Also be aware that it is useless to record measures at a frequency higher than the refresh frequency of the physical sensor itself.

Starting/stopping the datalogger

The data logger can be started with the set_recording() method.


YDataLogger l = YDataLogger.FirstDataLogger();
l.set_recording(YDataLogger.RECORDING_ON);

It is possible to make the data recording start automatically as soon as the module is powered on.


YDataLogger l = YDataLogger.FirstDataLogger();
l.set_autoStart(YDataLogger.AUTOSTART_ON);
l.get_module().saveToFlash();  // do not forget to save the setting

Note: Yoctopuce modules do not need an active USB connection to work: they start working as soon as they are powered on. The Yocto-Serial can store data without necessarily being connected to a computer: you only need to activate the automatic start of the data logger and to power on the module with a simple USB charger.

Erasing the memory

The memory of the data logger can be erased with the forgetAllDataStreams() function. Be aware that erasing cannot be undone.


YDataLogger l = YDataLogger.FirstDataLogger();
l.forgetAllDataStreams();

Choosing the logging frequency

The logging frequency can be set up individually for each sensor, using the method set_logFrequency(). The frequency is specified as a string (same as for timed report callbacks), by specifying the number of calls per second (/s), per minute (/m) or per hour (/h). The default value is "1/s".

The following example configures the logging frequency at 15 measures per minute for the first sensor found, whatever its type:


YSensor sensor = YSensor.FirstSensor();
sensor.set_logFrequency("15/m");

To avoid wasting flash memory, it is possible to disable logging for specified functions. In order to do so, simply use the value "OFF":


sensor.set_logFrequency("OFF");

Limitation: The Yocto-Serial cannot use a different frequency for timed-report callbacks and for recording data into the datalogger. You can disable either of them individually, but if you enable both timed-report callbacks and logging for a given function, the two will work at the same frequency.

Retrieving the data

To load recorded measures from the Yocto-Serial flash memory, you must call the get_recordedData() method of the desired sensor, and specify the time interval for which you want to retrieve measures. The time interval is given by the start and stop UNIX timestamp. You can also specify 0 if you don't want any start or stop limit.

The get_recordedData() method does not return directly am array of measured values, since in some cases it would cause a huge load that could affect the responsiveness of the application. Instead, this function will return an YDataSet object that can be used to retrieve immediately an overview of the measured data (summary), and then to load progressively the details when desired.

Here are the main methods used to retrieve recorded measures:

  1. dataset = sensor.get_recordedData(0,0): select the desired time interval
  2. dataset.loadMore(): load data from the device, progressively
  3. dataset.get_summary(): get a single measure summarizing the full time interval
  4. dataset.get_preview(): get an array of measures representing a condensed version of the whole set of measures on the selected time interval (reduced by a factor of approx. 200)
  5. dataset.get_measures(): get an array with all detailled measures (that grows while loadMore is being called repeteadly)

Measures are instances of YMeasure 48. They store simultaneously the minimal, average and maximal value at a given time, that you can retrieve using methods get_minValue(), get_averageValue() and get_maxValue() respectively. Here is a small example that uses the functions above:


// We will retrieve all measures, without time limit
YDataSet dataset = sensor.get_recordedData(0, 0);

// First call to loadMore() loads the summary/preview
dataset.loadMore();
YMeasure summary = dataset.get_summary();
string timeFmt = "dd MMM yyyy hh:mm:ss,fff";
string logFmt = "from {0} to {1} : average={2:0.00}{3}";
Console.WriteLine(String.Format(logFmt,
    summary.get_startTimeUTC_asDateTime().ToString(timeFmt),
    summary.get_endTimeUTC_asDateTime().ToString(timeFmt),
    summary.get_averageValue(), sensor.get_unit()));

// Next calls to loadMore() will retrieve measures
Console.WriteLine("loading details");
int progress;
do {
    Console.Write(".");
    progress = dataset.loadMore();
} while(progress < 100);

// All measures have now been loaded
List<YMeasure> details = dataset.get_measures();
foreach (YMeasure m in details) {
    Console.WriteLine(String.Format(logFmt,
        m.get_startTimeUTC_asDateTime().ToString(timeFmt),
        m.get_endTimeUTC_asDateTime().ToString(timeFmt),
        m.get_averageValue(), sensor.get_unit()));
}

You will find a complete example demonstrating how to retrieve data from the logger for each programming language directly in the Yoctopuce library. The example can be found in directory Examples/Prog-DataLogger.

Timestamp

As the Yocto-Serial does not have a battery, it cannot guess alone the current time when powered on. Nevertheless, the Yocto-Serial will automatically try to adjust its real-time reference using the host to which it is connected, in order to properly attach a timestamp to each measure in the datalogger:

When none of these conditions applies (for instance if the module is simply connected to an USB charger), the Yocto-Serial will do its best effort to attach a reasonable timestamp to the measures, using the timestamp found on the latest recorded measures. It is therefore possible to "preset to the real time" an autonomous Yocto-Serial by connecting it to an Android mobile phone, starting the data logger, then connecting the device alone on an USB charger. Nevertheless, be aware that without external time source, the internal clock of the Yocto-Serial might be be subject to a clock skew (theoretically up to 0.3%).

19.3. Sensor calibration

Your Yocto-Serial module is equipped with a digital sensor calibrated at the factory. The values it returns are supposed to be reasonably correct in most cases. There are, however, situations where external conditions can impact the measures.

The Yoctopuce API provides the mean to re-caliber the values measured by your Yocto-Serial. You are not going to modify the hardware settings of the module, but rather to transform afterwards the measures taken by the sensor. This transformation is controlled by parameters stored in the flash memory of the module, making it specific for each module. This re-calibration is therefore a fully software matter and remains perfectly reversible.

Before deciding to re-calibrate your Yocto-Serial module, make sure you have well understood the phenomena which impact the measures of your module, and that the differences between true values and measured values do not result from a incorrect use or an inadequate location of the module.

The Yoctopuce modules support two types of calibration. On the one hand, a linear interpolation based on 1 to 5 reference points, which can be performed directly inside the Yocto-Serial. On the other hand, the API supports an external arbitrary calibration, implemented with callbacks.

1 to 5 point linear interpolation

These transformations are performed directly inside the Yocto-Serial which means that you only have to store the calibration points in the module flash memory, and all the correction computations are done in a perfectly transparent manner: The function get_currentValue() returns the corrected value while the function get_currentRawValue() keeps returning the value before the correction.

Calibration points are simply (Raw_value, Corrected_value) couples. Let us look at the impact of the number of calibration points on the corrections.

1 point correction

The 1 point correction only adds a shift to the measures. For example, if you provide the calibration point (a, b), all the measured values are corrected by adding to them b-a, so that when the value read on the sensor is a, the genericSensor1 function returns b.


Measure correction with 1 calibration point, here (5,10)

The application is very simple: you only need to call the calibrateFromPoints() method of the function you wish to correct. The following code applies the correction illustrated on the graph above to the first genericSensor1 function found. Note the call to the saveToFlash method of the module hosting the function, so that the module does not forget the calibration as soon as it is disconnected.


Double[] ValuesBefore = {5};
Double[] ValuesAfter  = {10};
YGenericSensor f = YGenericSensor.FirstGenericSensor();
f.calibrateFromPoints(ValuesBefore, ValuesAfter);
f.get_module().saveToFlash();

2 point correction

2 point correction allows you to perform both a shift and a multiplication by a given factor between two points. If you provide the two points (a, b) and (c, d), the function result is multiplied (d-b)/(c-a) in the [a, c] range and shifted, so that when the value read by the sensor is a or c, the genericSensor1 function returns respectively b and d. Outside of the [a, c] range, the values are simply shifted, so as to preserve the continuity of the measures: an increase of 1 on the value read by the sensor induces an increase of 1 on the returned value.


Measure correction with the two calibration points (10,5) and (25,10).

The code allowing you to program this calibration is very similar to the preceding code example.


Double[] ValuesBefore = {10,25};
Double[] ValuesAfter  = {5,10};
YGenericSensor f = YGenericSensor.FirstGenericSensor();
f.calibrateFromPoints(ValuesBefore, ValuesAfter);
f.get_module().saveToFlash();

Note that the values before correction must be sorted in a strictly ascending order, otherwise they are simply ignored.

3 to 5 point correction

3 to 5 point corrections are only a generalization of the 2 point method, allowing you to create up to 4 correction ranges for an increased precision. These ranges cannot be disjoint.


Correction example with 3 calibration points

Back to normal

To cancel the effect of a calibration on a function, call the calibrateFromPoints() method with two empty arrays.


Double[] ValuesBefore = {};
Double[] ValuesAfter  = {};
YGenericSensor f = YGenericSensor.FirstGenericSensor();
f.calibrateFromPoints(ValuesBefore, ValuesAfter);
f.get_module().saveToFlash();

You will find, in the Examples\Prog-Calibration directory of the Delphi, VB, and C# libraries, an application allowing you to test the effects of the 1 to 5 point calibration.

Arbitrary interpolation

It is also possible to compute the interpolation instead of letting the module do it, in order to calculate a spline interpolation, for instance. To do so, you only need to store a callback in the API. This callback must specify the number of calibration points it is expecting.


public static double CustomInterpolation3Points(double rawValue, int calibType,
                  int[] parameters, double[] beforeValues, double[] afterValues)
  {  double result;
     // the value to be corrected is rawValue
     // calibration points are in beforeValues and afterValues
     result = ....    // interpolation of your choice
     return result;
   }
YAPI.RegisterCalibrationHandler(3, CustomInterpolation3Points);

Note that these interpolation callbacks are global, and not specific to each function. Thus, each time someone requests a value from a module which contains in its flash memory the correct number of calibration points, the corresponding callback is called to correct the value before returning it, enabling thus a perfectly transparent measure correction.

20. Using with unsupported languages

Yoctopuce modules can be driven from most common programming languages. New languages are regularly added, depending on the interest expressed by Yoctopuce product users. Nevertheless, some languages are not, and will never be, supported by Yoctopuce. There can be several reasons for this: compilers which are not available anymore, unadapted environments, etc.

However, there are alternative methods to access Yoctopuce modules from an unsupported programming language.

20.1. Command line

The easiest method to drive Yoctopuce modules from an unsupported programming language is to use the command line API through system calls. The command line API is in fact made of a group of small executables which are easy to call. Their output is also easy to analyze. As most programming languages allow you to make system calls, the issue is solved with a few lines of code.

However, if the command line API is the easiest solution, it is neither the fastest nor the most efficient. For each call, the executable must initialize its own API and make an inventory of USB connected modules. This requires about one second per call.

20.2. VirtualHub and HTTP GET

The VirtualHub is available on almost all current platforms. It is generally used as a gateway to provide access to Yoctopuce modules from languages which prevent direct access to hardware layers of a computer (JavaScript, PHP, Java, ...).

In fact, the VirtualHub is a small web server able to route HTTP requests to Yoctopuce modules. This means that if you can make an HTTP request from your programming language, you can drive Yoctopuce modules, even if this language is not officially supported.

REST interface

At a low level, the modules are driven through a REST API. Thus, to control a module, you only need to perform appropriate requests on the VirtualHub. By default, the VirtualHub HTTP port is 4444.

An important advantage of this technique is that preliminary tests are very easy to implement. You only need a VirtualHub and a simple web browser. If you copy the following URL in your preferred browser, while the VirtualHub is running, you obtain the list of the connected modules.


http://127.0.0.1:4444/api/services/whitePages.txt

Note that the result is displayed as text, but if you request whitePages.xml, you obtain an XML result. Likewise, whitePages.json allows you to obtain a JSON result. The html extension even allows you to display a rough interface where you can modify values in real time. The whole REST API is available in these different formats.

Driving a module through the REST interface

Each Yoctopuce module has its own REST interface, available in several variants. Let us imagine a Yocto-Serial with the YSERIAL1-12345 serial number and the myModule logical name. The following URL allows you to know the state of the module.


http://127.0.0.1:4444/bySerial/YSERIAL1-12345/api/module.txt

You can naturally also use the module logical name rather than its serial number.


http://127.0.0.1:4444/byName/myModule/api/module.txt

To retrieve the value of a module property, simply add the name of the property below module. For example, if you want to know the signposting led luminosity, send the following request:


http://127.0.0.1:4444/bySerial/YSERIAL1-12345/api/module/luminosity

To change the value of a property, modify the corresponding attribute. Thus, to modify the luminosity, send the following request:


http://127.0.0.1:4444/bySerial/YSERIAL1-12345/api/module?luminosity=100

Driving the module functions through the REST interface

The module functions can be manipulated in the same way. To know the state of the genericSensor1 function, build the following URL:


http://127.0.0.1:4444/bySerial/YSERIAL1-12345/api/genericSensor1.txt

Note that if you can use logical names for the modules instead of their serial number, you cannot use logical names for functions. Only hardware names are authorized to access functions.

You can retrieve a module function attribute in a way rather similar to that used with the modules. For example:


http://127.0.0.1:4444/bySerial/YSERIAL1-12345/api/genericSensor1/logicalName

Rather logically, attributes can be modified in the same manner.


http://127.0.0.1:4444/bySerial/YSERIAL1-12345/api/genericSensor1?logicalName=myFunction

You can find the list of available attributes for your Yocto-Serial at the beginning of the Programming chapter.

Accessing Yoctopuce data logger through the REST interface

This section only applies to devices with a built-in data logger.

The preview of all recorded data streams can be retrieved in JSON format using the following URL:


http://127.0.0.1:4444/bySerial/YSERIAL1-12345/dataLogger.json

Individual measures for any given stream can be obtained by appending the desired function identifier as well as start time of the stream:


http://127.0.0.1:4444/bySerial/YSERIAL1-12345/dataLogger.json?id=genericSensor1&utc=1389801080

20.3. Using dynamic libraries

The low level Yoctopuce API is available under several formats of dynamic libraries written in C. The sources are available with the C++ API. If you use one of these low level libraries, you do not need the VirtualHub anymore.

FilenamePlatform
libyapi.dylibMax OS X
libyapi-amd64.soLinux Intel (64 bits)
libyapi-armel.soLinux ARM EL
libyapi-armhf.soLinux ARM HL
libyapi-i386.soLinux Intel (32 bits)
yapi64.dllWindows (64 bits)
yapi.dllWindows (32 bits)

These dynamic libraries contain all the functions necessary to completely rebuild the whole high level API in any language able to integrate these libraries. This chapter nevertheless restrains itself to describing basic use of the modules.

Driving a module

The three essential functions of the low level API are the following:


int yapiInitAPI(int connection_type, char *errmsg);
int yapiUpdateDeviceList(int forceupdate, char *errmsg);
int yapiHTTPRequest(char *device, char *request, char* buffer,int buffsize,int *fullsize, char *errmsg);

The yapiInitAPI function initializes the API and must be called once at the beginning of the program. For a USB type connection, the connection_type parameter takes value 1. The errmsg parameter must point to a 255 character buffer to retrieve a potential error message. This pointer can also point to null. The function returns a negative integer in case of error, zero otherwise.

The yapiUpdateDeviceList manages the inventory of connected Yoctopuce modules. It must be called at least once. To manage hot plug and detect potential newly connected modules, this function must be called at regular intervals. The forceupdate parameter must take value 1 to force a hardware scan. The errmsg parameter must point to a 255 character buffer to retrieve a potential error message. This pointer can also point to null. The function returns a negative integer in case of error, zero otherwise.

Finally, the yapiHTTPRequest function sends HTTP requests to the module REST API. The device parameter contains the serial number or the logical name of the module which you want to reach. The request parameter contains the full HTTP request (including terminal line breaks). buffer points to a character buffer long enough to contain the answer. buffsize is the size of the buffer. fullsize is a pointer to an integer to which will be assigned the actual size of the answer. The errmsg parameter must point to a 255 character buffer to retrieve a potential error message. This pointer can also point to null. The function returns a negative integer in case of error, zero otherwise.

The format of the requests is the same as the one described in the VirtualHub et HTTP GET section. All the character strings used by the API are strings made of 8-bit characters: Unicode and UTF8 are not supported.

The resutlt returned in the buffer variable respects the HTTP protocol. It therefore includes an HTTP header. This header ends with two empty lines, that is a sequence of four ASCII characters 13, 10, 13, 10.

Here is a sample program written in pascal using the yapi.dll DLL to read and then update the luminosity of a module.


// Dll functions import
function  yapiInitAPI(mode:integer;
                      errmsg : pansichar):integer;cdecl;
                      external 'yapi.dll' name 'yapiInitAPI';
function  yapiUpdateDeviceList(force:integer;errmsg : pansichar):integer;cdecl;
                      external 'yapi.dll' name 'yapiUpdateDeviceList';
function  yapiHTTPRequest(device:pansichar;url:pansichar; buffer:pansichar;
                      buffsize:integer;var fullsize:integer;
                      errmsg : pansichar):integer;cdecl;
                      external 'yapi.dll' name 'yapiHTTPRequest';

var
 errmsgBuffer  : array [0..256] of ansichar;
 dataBuffer    : array [0..1024] of ansichar;
 errmsg,data   : pansichar;
 fullsize,p    : integer;

const
  serial      = 'YSERIAL1-12345';
  getValue = 'GET /api/module/luminosity HTTP/1.1'#13#10#13#10;
  setValue = 'GET /api/module?luminosity=100 HTTP/1.1'#13#10#13#10;

begin
  errmsg  :=  @errmsgBuffer;
  data    :=  @dataBuffer;
  // API  initialization
  if(yapiInitAPI(1,errmsg)<0) then
   begin
    writeln(errmsg);
    halt;
  end;

  // forces a device inventory
  if( yapiUpdateDeviceList(1,errmsg)<0) then
    begin
     writeln(errmsg);
     halt;
   end;

  // requests the  module luminosity
  if (yapiHTTPRequest(serial,getValue,data,sizeof(dataBuffer),fullsize,errmsg)<0) then
   begin
     writeln(errmsg);
     halt;
   end;

  // searches for the HTTP header end
  p := pos(#13#10#13#10,data);

  // displays the response minus the HTTP header
  writeln(copy(data,p+4,length(data)-p-3));

  // changes the luminosity
  if (yapiHTTPRequest(serial,setValue,data,sizeof(dataBuffer),fullsize,errmsg)<0) then
   begin
     writeln(errmsg);
     halt;
   end;

end.

Module inventory

To perform an inventory of Yoctopuce modules, you need two functions from the dynamic library:


 int yapiGetAllDevices(int *buffer,int maxsize,int *neededsize,char *errmsg);
 int yapiGetDeviceInfo(int devdesc,yDeviceSt *infos, char *errmsg);

The yapiGetAllDevices function retrieves the list of all connected modules as a list of handles. buffer points to a 32-bit integer array which contains the returned handles. maxsize is the size in bytes of the buffer. To neededsize is assigned the necessary size to store all the handles. From this, you can deduce either the number of connected modules or that the input buffer is too small. The errmsg parameter must point to a 255 character buffer to retrieve a potential error message. This pointer can also point to null. The function returns a negative integer in case of error, zero otherwise.

The yapiGetDeviceInfo function retrieves the information related to a module from its handle. devdesc is a 32-bit integer representing the module and which was obtained through yapiGetAllDevices. infos points to a data structure in which the result is stored. This data structure has the following format:

Name TypeSize (bytes)Description
vendorid int4Yoctopuce USB ID
deviceid int4Module USB ID
devrelease int4Module version
nbinbterfaces int4Number of USB interfaces used by the module
manufacturer char[]20Yoctopuce (null terminated)
productname char[]28Model (null terminated)
serial char[]20Serial number (null terminated)
logicalname char[]20Logical name (null terminated)
firmware char[]22Firmware version (null terminated)
beacon byte1Beacon state (0/1)

The errmsg parameter must point to a 255 character buffer to retrieve a potential error message.

Here is a sample program written in pascal using the yapi.dll DLL to list the connected modules.


// device description structure
type yDeviceSt = packed record
   vendorid        : word;
   deviceid        : word;
   devrelease      : word;
   nbinbterfaces   : word;
   manufacturer    : array [0..19] of ansichar;
   productname     : array [0..27] of ansichar;
   serial          : array [0..19] of ansichar;
   logicalname     : array [0..19] of ansichar;
   firmware        : array [0..21] of ansichar;
   beacon          : byte;
 end;

// Dll function import
function  yapiInitAPI(mode:integer;
                      errmsg : pansichar):integer;cdecl;
                      external 'yapi.dll' name 'yapiInitAPI';

function  yapiUpdateDeviceList(force:integer;errmsg : pansichar):integer;cdecl;
                      external 'yapi.dll' name 'yapiUpdateDeviceList';

function  yapiGetAllDevices( buffer:pointer;
                             maxsize:integer;
                             var neededsize:integer;
                             errmsg : pansichar):integer; cdecl;
                             external 'yapi.dll' name 'yapiGetAllDevices';

function  apiGetDeviceInfo(d:integer; var infos:yDeviceSt;
                             errmsg : pansichar):integer;  cdecl;
                             external 'yapi.dll' name 'yapiGetDeviceInfo';


var
 errmsgBuffer  : array [0..256] of ansichar;
 dataBuffer    : array [0..127] of integer;   // max of 128 USB devices
 errmsg,data   : pansichar;
 neededsize,i  : integer;
 devinfos      : yDeviceSt;

begin
  errmsg  :=  @errmsgBuffer;

  // API  initialization
  if(yapiInitAPI(1,errmsg)<0) then
   begin
    writeln(errmsg);
    halt;
  end;

   // forces a device inventory
  if( yapiUpdateDeviceList(1,errmsg)<0) then
    begin
     writeln(errmsg);
     halt;
   end;

  // loads all device handles into dataBuffer
  if yapiGetAllDevices(@dataBuffer,sizeof(dataBuffer),neededsize,errmsg)<0 then
    begin
     writeln(errmsg);
     halt;
    end;

  // gets device info from each handle
  for i:=0 to  neededsize div sizeof(integer)-1 do
   begin
     if (apiGetDeviceInfo(dataBuffer[i], devinfos, errmsg)<0) then
       begin
         writeln(errmsg);
         halt;
       end;
     writeln(pansichar(@devinfos.serial)+' ('+pansichar(@devinfos.productname)+')');
   end;

end.

VB6 and yapi.dll

Each entry point from the yapi.dll is duplicated. You will find one regular C-decl version and one Visual Basic 6 compatible version, prefixed with vb6_.

20.4. Porting the high level library

As all the sources of the Yoctopuce API are fully provided, you can very well port the whole API in the language of your choice. Note, however, that a large portion of the API source code is automatically generated.

Therefore, it is not necessary for you to port the complete API. You only need to port the yocto_api file and one file corresponding to a function, for example yocto_relay. After a little additional work, Yoctopuce is then able to generate all other files. Therefore, we highly recommend that you contact Yoctopuce support before undertaking to port the Yoctopuce library in another language. Collaborative work is advantageous to both parties.

21. High-level API Reference

This chapter summarizes the high-level API functions to drive your Yocto-Serial. Syntax and exact type names may vary from one language to another, but, unless otherwise stated, all the functions are available in every language. For detailed information regarding the types of arguments and return values for a given language, refer to the definition file for this language (yocto_api.* as well as the other yocto_* files that define the function interfaces).

For languages which support exceptions, all of these functions throw exceptions in case of error by default, rather than returning the documented error value for each function. This is by design, to facilitate debugging. It is however possible to disable the use of exceptions using the yDisableExceptions() function, in case you prefer to work with functions that return error values.

This chapter does not repeat the programming concepts described earlier, in order to stay as concise as possible. In case of doubt, do not hesitate to go back to the chapter describing in details all configurable attributes.

21.1. General functions

These general functions should be used to initialize and configure the Yoctopuce library. In most cases, a simple call to function yRegisterHub() should be enough. The module-specific functions yFind...() or yFirst...() should then be used to retrieve an object that provides interaction with the module.

In order to use the functions described here, you should include:

js
<script type='text/javascript' src='yocto_api.js'></script>
nodejs
var yoctolib = require('yoctolib');
var YAPI = yoctolib.YAPI;
var YModule = yoctolib.YModule;
php
require_once('yocto_api.php');
cpp
#include "yocto_api.h"
m
#import "yocto_api.h"
pas
uses yocto_api;
vb
yocto_api.vb
cs
yocto_api.cs
java
import com.yoctopuce.YoctoAPI.YModule;
py
from yocto_api import *
Global functions
yCheckLogicalName(name)

Checks if a given string is valid as logical name for a module or a function.

yDisableExceptions()

Disables the use of exceptions to report runtime errors.

yEnableExceptions()

Re-enables the use of exceptions for runtime error handling.

yEnableUSBHost(osContext)

This function is used only on Android.

yFreeAPI()

Frees dynamically allocated memory blocks used by the Yoctopuce library.

yGetAPIVersion()

Returns the version identifier for the Yoctopuce library in use.

yGetTickCount()

Returns the current value of a monotone millisecond-based time counter.

yHandleEvents(errmsg)

Maintains the device-to-library communication channel.

yInitAPI(mode, errmsg)

Initializes the Yoctopuce programming library explicitly.

yPreregisterHub(url, errmsg)

Fault-tolerant alternative to RegisterHub().

yRegisterDeviceArrivalCallback(arrivalCallback)

Register a callback function, to be called each time a device is plugged.

yRegisterDeviceRemovalCallback(removalCallback)

Register a callback function, to be called each time a device is unplugged.

yRegisterHub(url, errmsg)

Setup the Yoctopuce library to use modules connected on a given machine.

yRegisterHubDiscoveryCallback(hubDiscoveryCallback)

Register a callback function, to be called each time an Network Hub send an SSDP message.

yRegisterLogFunction(logfun)

Registers a log callback function.

ySelectArchitecture(arch)

Select the architecture or the library to be loaded to access to USB.

ySetDelegate(object)

(Objective-C only) Register an object that must follow the protocol YDeviceHotPlug.

ySetTimeout(callback, ms_timeout, arguments)

Invoke the specified callback function after a given timeout.

ySleep(ms_duration, errmsg)

Pauses the execution flow for a specified duration.

yTriggerHubDiscovery(errmsg)

Force a hub discovery, if a callback as been registered with yRegisterDeviceRemovalCallback it will be called for each net work hub that will respond to the discovery.

yUnregisterHub(url)

Setup the Yoctopuce library to no more use modules connected on a previously registered machine with RegisterHub.

yUpdateDeviceList(errmsg)

Triggers a (re)detection of connected Yoctopuce modules.

yUpdateDeviceList_async(callback, context)

Triggers a (re)detection of connected Yoctopuce modules.

YAPI.CheckLogicalName()
yCheckLogicalName()
yCheckLogicalName()YAPI.CheckLogicalName()yCheckLogicalName()yCheckLogicalName()[YAPI CheckLogicalName: ]yCheckLogicalName()yCheckLogicalName()YAPI.CheckLogicalName()YAPI.CheckLogicalName()YAPI.CheckLogicalName()

Checks if a given string is valid as logical name for a module or a function.

js
function yCheckLogicalName(name)
nodejs
function CheckLogicalName(name)
php
function yCheckLogicalName($name)
cpp
bool yCheckLogicalName(const string& name)
m
+(BOOL) CheckLogicalName:(NSString *) name
pas
function yCheckLogicalName(name: string): boolean
vb
function yCheckLogicalName(ByVal name As String) As Boolean
cs
bool CheckLogicalName(string name)
java
boolean CheckLogicalName(String name)
py
def CheckLogicalName(name)

A valid logical name has a maximum of 19 characters, all among A..Z, a..z, 0..9, _, and -. If you try to configure a logical name with an incorrect string, the invalid characters are ignored.

Parameters :

namea string containing the name to check.

Returns :

true if the name is valid, false otherwise.

YAPI.DisableExceptions()
yDisableExceptions()
yDisableExceptions()YAPI.DisableExceptions()yDisableExceptions()yDisableExceptions()[YAPI DisableExceptions]yDisableExceptions()yDisableExceptions()YAPI.DisableExceptions()YAPI.DisableExceptions()

Disables the use of exceptions to report runtime errors.

js
function yDisableExceptions()
nodejs
function DisableExceptions()
php
function yDisableExceptions()
cpp
void yDisableExceptions()
m
+(void) DisableExceptions
pas
procedure yDisableExceptions()
vb
procedure yDisableExceptions()
cs
void DisableExceptions()
py
def DisableExceptions()

When exceptions are disabled, every function returns a specific error value which depends on its type and which is documented in this reference manual.

YAPI.EnableExceptions()
yEnableExceptions()
yEnableExceptions()YAPI.EnableExceptions()yEnableExceptions()yEnableExceptions()[YAPI EnableExceptions]yEnableExceptions()yEnableExceptions()YAPI.EnableExceptions()YAPI.EnableExceptions()

Re-enables the use of exceptions for runtime error handling.

js
function yEnableExceptions()
nodejs
function EnableExceptions()
php
function yEnableExceptions()
cpp
void yEnableExceptions()
m
+(void) EnableExceptions
pas
procedure yEnableExceptions()
vb
procedure yEnableExceptions()
cs
void EnableExceptions()
py
def EnableExceptions()

Be aware than when exceptions are enabled, every function that fails triggers an exception. If the exception is not caught by the user code, it either fires the debugger or aborts (i.e. crash) the program. On failure, throws an exception or returns a negative error code.

YAPI.EnableUSBHost()
yEnableUSBHost()
YAPI.EnableUSBHost()

This function is used only on Android.

java
void EnableUSBHost(Object osContext)

Before calling yRegisterHub("usb") you need to activate the USB host port of the system. This function takes as argument, an object of class android.content.Context (or any subclass). It is not necessary to call this function to reach modules through the network.

Parameters :

On failure, throws an exception.
osContextan object of class android.content.Context (or any subclass).

YAPI.FreeAPI()
yFreeAPI()
yFreeAPI()YAPI.FreeAPI()yFreeAPI()yFreeAPI()[YAPI FreeAPI]yFreeAPI()yFreeAPI()YAPI.FreeAPI()YAPI.FreeAPI()YAPI.FreeAPI()

Frees dynamically allocated memory blocks used by the Yoctopuce library.

js
function yFreeAPI()
nodejs
function FreeAPI()
php
function yFreeAPI()
cpp
void yFreeAPI()
m
+(void) FreeAPI
pas
procedure yFreeAPI()
vb
procedure yFreeAPI()
cs
void FreeAPI()
java
void FreeAPI()
py
def FreeAPI()

It is generally not required to call this function, unless you want to free all dynamically allocated memory blocks in order to track a memory leak for instance. You should not call any other library function after calling yFreeAPI(), or your program will crash.

YAPI.GetAPIVersion()
yGetAPIVersion()
yGetAPIVersion()YAPI.GetAPIVersion()yGetAPIVersion()yGetAPIVersion()[YAPI GetAPIVersion]yGetAPIVersion()yGetAPIVersion()YAPI.GetAPIVersion()YAPI.GetAPIVersion()YAPI.GetAPIVersion()

Returns the version identifier for the Yoctopuce library in use.

js
function yGetAPIVersion()
nodejs
function GetAPIVersion()
php
function yGetAPIVersion()
cpp
string yGetAPIVersion()
m
+(NSString*) GetAPIVersion
pas
function yGetAPIVersion(): string
vb
function yGetAPIVersion() As String
cs
String GetAPIVersion()
java
String GetAPIVersion()
py
def GetAPIVersion()

The version is a string in the form "Major.Minor.Build", for instance "1.01.5535". For languages using an external DLL (for instance C#, VisualBasic or Delphi), the character string includes as well the DLL version, for instance "1.01.5535 (1.01.5439)".

If you want to verify in your code that the library version is compatible with the version that you have used during development, verify that the major number is strictly equal and that the minor number is greater or equal. The build number is not relevant with respect to the library compatibility.

Returns :

a character string describing the library version.

YAPI.GetTickCount()
yGetTickCount()
yGetTickCount()YAPI.GetTickCount()yGetTickCount()yGetTickCount()[YAPI GetTickCount]yGetTickCount()yGetTickCount()YAPI.GetTickCount()YAPI.GetTickCount()YAPI.GetTickCount()

Returns the current value of a monotone millisecond-based time counter.

js
function yGetTickCount()
nodejs
function GetTickCount()
php
function yGetTickCount()
cpp
u64 yGetTickCount()
m
+(u64) GetTickCount
pas
function yGetTickCount(): u64
vb
function yGetTickCount() As Long
cs
ulong GetTickCount()
java
long GetTickCount()
py
def GetTickCount()

This counter can be used to compute delays in relation with Yoctopuce devices, which also uses the millisecond as timebase.

Returns :

a long integer corresponding to the millisecond counter.

YAPI.HandleEvents()
yHandleEvents()
yHandleEvents()YAPI.HandleEvents()yHandleEvents()yHandleEvents()[YAPI HandleEvents: ]yHandleEvents()yHandleEvents()YAPI.HandleEvents()YAPI.HandleEvents()YAPI.HandleEvents()

Maintains the device-to-library communication channel.

js
function yHandleEvents(errmsg)
nodejs
function HandleEvents(errmsg)
php
function yHandleEvents(&$errmsg)
cpp
YRETCODE yHandleEvents(string& errmsg)
m
+(YRETCODE) HandleEvents:(NSError**) errmsg
pas
function yHandleEvents(var errmsg: string): integer
vb
function yHandleEvents(ByRef errmsg As String) As YRETCODE
cs
YRETCODE HandleEvents(ref string errmsg)
java
int HandleEvents()
py
def HandleEvents(errmsg=None)

If your program includes significant loops, you may want to include a call to this function to make sure that the library takes care of the information pushed by the modules on the communication channels. This is not strictly necessary, but it may improve the reactivity of the library for the following commands.

This function may signal an error in case there is a communication problem while contacting a module.

Parameters :

errmsga string passed by reference to receive any error message.

Returns :

YAPI_SUCCESS when the call succeeds.

On failure, throws an exception or returns a negative error code.

YAPI.InitAPI()
yInitAPI()
yInitAPI()YAPI.InitAPI()yInitAPI()yInitAPI()[YAPI InitAPI: ]yInitAPI()yInitAPI()YAPI.InitAPI()YAPI.InitAPI()YAPI.InitAPI()

Initializes the Yoctopuce programming library explicitly.

js
function yInitAPI(mode, errmsg)
nodejs
function InitAPI(mode, errmsg)
php
function yInitAPI($mode, &$errmsg)
cpp
YRETCODE yInitAPI(int mode, string& errmsg)
m
+(YRETCODE) InitAPI:(int) mode :(NSError**) errmsg
pas
function yInitAPI(mode: integer, var errmsg: string): integer
vb
function yInitAPI(ByVal mode As Integer, ByRef errmsg As String) As Integer
cs
int InitAPI(int mode, ref string errmsg)
java
int InitAPI(int mode)
py
def InitAPI(mode, errmsg=None)

It is not strictly needed to call yInitAPI(), as the library is automatically initialized when calling yRegisterHub() for the first time.

When Y_DETECT_NONE is used as detection mode, you must explicitly use yRegisterHub() to point the API to the VirtualHub on which your devices are connected before trying to access them.

Parameters :

modean integer corresponding to the type of automatic device detection to use. Possible values are Y_DETECT_NONE, Y_DETECT_USB, Y_DETECT_NET, and Y_DETECT_ALL.
errmsga string passed by reference to receive any error message.

Returns :

YAPI_SUCCESS when the call succeeds.

On failure, throws an exception or returns a negative error code.

YAPI.PreregisterHub()
yPreregisterHub()
yPreregisterHub()YAPI.PreregisterHub()yPreregisterHub()yPreregisterHub()[YAPI PreregisterHub: ]yPreregisterHub()yPreregisterHub()YAPI.PreregisterHub()YAPI.PreregisterHub()YAPI.PreregisterHub()

Fault-tolerant alternative to RegisterHub().

js
function yPreregisterHub(url, errmsg)
nodejs
function PreregisterHub(url, errmsg)
php
function yPreregisterHub($url, &$errmsg)
cpp
YRETCODE yPreregisterHub(const string& url, string& errmsg)
m
+(YRETCODE) PreregisterHub:(NSString *) url :(NSError**) errmsg
pas
function yPreregisterHub(url: string, var errmsg: string): integer
vb
function yPreregisterHub(ByVal url As String,
  ByRef errmsg As String) As Integer
cs
int PreregisterHub(string url, ref string errmsg)
java
int PreregisterHub(String url)
py
def PreregisterHub(url, errmsg=None)

This function has the same purpose and same arguments as RegisterHub(), but does not trigger an error when the selected hub is not available at the time of the function call. This makes it possible to register a network hub independently of the current connectivity, and to try to contact it only when a device is actively needed.

Parameters :

urla string containing either "usb","callback" or the root URL of the hub to monitor
errmsga string passed by reference to receive any error message.

Returns :

YAPI_SUCCESS when the call succeeds.

On failure, throws an exception or returns a negative error code.

YAPI.RegisterDeviceArrivalCallback()
yRegisterDeviceArrivalCallback()
yRegisterDeviceArrivalCallback()YAPI.RegisterDeviceArrivalCallback()yRegisterDeviceArrivalCallback()yRegisterDeviceArrivalCallback()[YAPI RegisterDeviceArrivalCallback: ]yRegisterDeviceArrivalCallback()yRegisterDeviceArrivalCallback()YAPI.RegisterDeviceArrivalCallback()YAPI.RegisterDeviceArrivalCallback()YAPI.RegisterDeviceArrivalCallback()

Register a callback function, to be called each time a device is plugged.

js
function yRegisterDeviceArrivalCallback(arrivalCallback)
nodejs
function RegisterDeviceArrivalCallback(arrivalCallback)
php
function yRegisterDeviceArrivalCallback($arrivalCallback)
cpp
void yRegisterDeviceArrivalCallback(yDeviceUpdateCallback arrivalCallback)
m
+(void) RegisterDeviceArrivalCallback:(yDeviceUpdateCallback) arrivalCallback
pas
procedure yRegisterDeviceArrivalCallback(arrivalCallback: yDeviceUpdateFunc)
vb
procedure yRegisterDeviceArrivalCallback(ByVal arrivalCallback As yDeviceUpdateFunc)
cs
void RegisterDeviceArrivalCallback(yDeviceUpdateFunc arrivalCallback)
java
void RegisterDeviceArrivalCallback(DeviceArrivalCallback arrivalCallback)
py
def RegisterDeviceArrivalCallback(arrivalCallback)

This callback will be invoked while yUpdateDeviceList is running. You will have to call this function on a regular basis.

Parameters :

to unregister a previously registered callback.
arrivalCallbacka procedure taking a YModule parameter, or null

YAPI.RegisterDeviceRemovalCallback()
yRegisterDeviceRemovalCallback()
yRegisterDeviceRemovalCallback()YAPI.RegisterDeviceRemovalCallback()yRegisterDeviceRemovalCallback()yRegisterDeviceRemovalCallback()[YAPI RegisterDeviceRemovalCallback: ]yRegisterDeviceRemovalCallback()yRegisterDeviceRemovalCallback()YAPI.RegisterDeviceRemovalCallback()YAPI.RegisterDeviceRemovalCallback()YAPI.RegisterDeviceRemovalCallback()

Register a callback function, to be called each time a device is unplugged.

js
function yRegisterDeviceRemovalCallback(removalCallback)
nodejs
function RegisterDeviceRemovalCallback(removalCallback)
php
function yRegisterDeviceRemovalCallback($removalCallback)
cpp
void yRegisterDeviceRemovalCallback(yDeviceUpdateCallback removalCallback)
m
+(void) RegisterDeviceRemovalCallback:(yDeviceUpdateCallback) removalCallback
pas
procedure yRegisterDeviceRemovalCallback(removalCallback: yDeviceUpdateFunc)
vb
procedure yRegisterDeviceRemovalCallback(ByVal removalCallback As yDeviceUpdateFunc)
cs
void RegisterDeviceRemovalCallback(yDeviceUpdateFunc removalCallback)
java
void RegisterDeviceRemovalCallback(DeviceRemovalCallback removalCallback)
py
def RegisterDeviceRemovalCallback(removalCallback)

This callback will be invoked while yUpdateDeviceList is running. You will have to call this function on a regular basis.

Parameters :

to unregister a previously registered callback.
removalCallbacka procedure taking a YModule parameter, or null

YAPI.RegisterHub()
yRegisterHub()
yRegisterHub()YAPI.RegisterHub()yRegisterHub()yRegisterHub()[YAPI RegisterHub: ]yRegisterHub()yRegisterHub()YAPI.RegisterHub()YAPI.RegisterHub()YAPI.RegisterHub()

Setup the Yoctopuce library to use modules connected on a given machine.

js
function yRegisterHub(url, errmsg)
nodejs
function RegisterHub(url, errmsg)
php
function yRegisterHub($url, &$errmsg)
cpp
YRETCODE yRegisterHub(const string& url, string& errmsg)
m
+(YRETCODE) RegisterHub:(NSString *) url :(NSError**) errmsg
pas
function yRegisterHub(url: string, var errmsg: string): integer
vb
function yRegisterHub(ByVal url As String,
  ByRef errmsg As String) As Integer
cs
int RegisterHub(string url, ref string errmsg)
java
int RegisterHub(String url)
py
def RegisterHub(url, errmsg=None)

The parameter will determine how the API will work. Use the following values:

usb: When the usb keyword is used, the API will work with devices connected directly to the USB bus. Some programming languages such a Javascript, PHP, and Java don't provide direct access to USB hardware, so usb will not work with these. In this case, use a VirtualHub or a networked YoctoHub (see below).

x.x.x.x or hostname: The API will use the devices connected to the host with the given IP address or hostname. That host can be a regular computer running a VirtualHub, or a networked YoctoHub such as YoctoHub-Ethernet or YoctoHub-Wireless. If you want to use the VirtualHub running on you local computer, use the IP address 127.0.0.1.

callback: that keyword make the API run in "HTTP Callback" mode. This a special mode allowing to take control of Yoctopuce devices through a NAT filter when using a VirtualHub or a networked YoctoHub. You only need to configure your hub to call your server script on a regular basis. This mode is currently available for PHP and Node.JS only.

Be aware that only one application can use direct USB access at a given time on a machine. Multiple access would cause conflicts while trying to access the USB modules. In particular, this means that you must stop the VirtualHub software before starting an application that uses direct USB access. The workaround for this limitation is to setup the library to use the VirtualHub rather than direct USB access.

If access control has been activated on the hub, virtual or not, you want to reach, the URL parameter should look like:

http://username:password@address:port

You can call RegisterHub several times to connect to several machines.

Parameters :

urla string containing either "usb","callback" or the root URL of the hub to monitor
errmsga string passed by reference to receive any error message.

Returns :

YAPI_SUCCESS when the call succeeds.

On failure, throws an exception or returns a negative error code.

YAPI.RegisterHubDiscoveryCallback()
yRegisterHubDiscoveryCallback()
yRegisterHubDiscoveryCallback()[YAPI RegisterHubDiscoveryCallback: ]yRegisterHubDiscoveryCallback()yRegisterHubDiscoveryCallback()YAPI.RegisterHubDiscoveryCallback()YAPI.RegisterHubDiscoveryCallback()YAPI.RegisterHubDiscoveryCallback()

Register a callback function, to be called each time an Network Hub send an SSDP message.

cpp
void yRegisterHubDiscoveryCallback(YHubDiscoveryCallback hubDiscoveryCallback)
m
+(void) RegisterHubDiscoveryCallback: (YHubDiscoveryCallback) hubDiscoveryCallback
pas
procedure yRegisterHubDiscoveryCallback(hubDiscoveryCallback: YHubDiscoveryCallback)
vb
procedure yRegisterHubDiscoveryCallback(ByVal hubDiscoveryCallback As YHubDiscoveryCallback)
cs
void RegisterHubDiscoveryCallback(YHubDiscoveryCallback hubDiscoveryCallback)
java
void RegisterHubDiscoveryCallback(HubDiscoveryCallback hubDiscoveryCallback)
py
def RegisterHubDiscoveryCallback(hubDiscoveryCallback)

The callback has two string parameter, the first one contain the serial number of the hub and the second contain the URL of the network hub (this URL can be passed to RegisterHub). This callback will be invoked while yUpdateDeviceList is running. You will have to call this function on a regular basis.

Parameters :

to unregister a previously registered callback.
hubDiscoveryCallbacka procedure taking two string parameter, or null

YAPI.RegisterLogFunction()
yRegisterLogFunction()
yRegisterLogFunction()[YAPI RegisterLogFunction: ]yRegisterLogFunction()yRegisterLogFunction()YAPI.RegisterLogFunction()YAPI.RegisterLogFunction()YAPI.RegisterLogFunction()

Registers a log callback function.

cpp
void yRegisterLogFunction(yLogFunction logfun)
m
+(void) RegisterLogFunction:(yLogCallback) logfun
pas
procedure yRegisterLogFunction(logfun: yLogFunc)
vb
procedure yRegisterLogFunction(ByVal logfun As yLogFunc)
cs
void RegisterLogFunction(yLogFunc logfun)
java
void RegisterLogFunction(LogCallback logfun)
py
def RegisterLogFunction(logfun)

This callback will be called each time the API have something to say. Quite useful to debug the API.

Parameters :

to unregister a previously registered callback.
logfuna procedure taking a string parameter, or null

YAPI.SelectArchitecture()
ySelectArchitecture()
YAPI.SelectArchitecture()

Select the architecture or the library to be loaded to access to USB.

py
def SelectArchitecture(arch)

By default, the Python library automatically detects the appropriate library to use. However, for Linux ARM, it not possible to reliably distinguish between a Hard Float (armhf) and a Soft Float (armel) install. For in this case, it is therefore recommended to manually select the proper architecture by calling SelectArchitecture() before any other call to the library.

Parameters :

archA string containing the architecture to use. Possibles value are: "armhf","armel", "i386","x86_64","32bit", "64bit"

Returns :

nothing.

On failure, throws an exception.

YAPI.SetDelegate()
ySetDelegate()
[YAPI SetDelegate: ]

(Objective-C only) Register an object that must follow the protocol YDeviceHotPlug.

m
+(void) SetDelegate:(id) object

The methods yDeviceArrival and yDeviceRemoval will be invoked while yUpdateDeviceList is running. You will have to call this function on a regular basis.

Parameters :

to unregister a previously registered object.
objectan object that must follow the protocol YAPIDelegate, or nil

YAPI.SetTimeout()
ySetTimeout()
ySetTimeout()YAPI.SetTimeout()

Invoke the specified callback function after a given timeout.

js
function ySetTimeout(callback, ms_timeout, arguments)
nodejs
function SetTimeout(callback, ms_timeout, arguments)

This function behaves more or less like Javascript setTimeout, but during the waiting time, it will call yHandleEvents and yUpdateDeviceList periodically, in order to keep the API up-to-date with current devices.

Parameters :

callbackthe function to call after the timeout occurs. On Microsoft Internet Explorer, the callback must be provided as a string to be evaluated.
ms_timeoutan integer corresponding to the duration of the timeout, in milliseconds.
argumentsadditional arguments to be passed to the callback function can be provided, if needed (not supported on Microsoft Internet Explorer).

Returns :

YAPI_SUCCESS when the call succeeds.

On failure, throws an exception or returns a negative error code.

YAPI.Sleep()
ySleep()
ySleep()YAPI.Sleep()ySleep()ySleep()[YAPI Sleep: ]ySleep()ySleep()YAPI.Sleep()YAPI.Sleep()YAPI.Sleep()

Pauses the execution flow for a specified duration.

js
function ySleep(ms_duration, errmsg)
nodejs
function Sleep(ms_duration, errmsg)
php
function ySleep($ms_duration, &$errmsg)
cpp
YRETCODE ySleep(unsigned ms_duration, string& errmsg)
m
+(YRETCODE) Sleep:(unsigned) ms_duration :(NSError **) errmsg
pas
function ySleep(ms_duration: integer, var errmsg: string): integer
vb
function ySleep(ByVal ms_duration As Integer,
  ByRef errmsg As String) As Integer
cs
int Sleep(int ms_duration, ref string errmsg)
java
int Sleep(long ms_duration)
py
def Sleep(ms_duration, errmsg=None)

This function implements a passive waiting loop, meaning that it does not consume CPU cycles significantly. The processor is left available for other threads and processes. During the pause, the library nevertheless reads from time to time information from the Yoctopuce modules by calling yHandleEvents(), in order to stay up-to-date.

This function may signal an error in case there is a communication problem while contacting a module.

Parameters :

ms_durationan integer corresponding to the duration of the pause, in milliseconds.
errmsga string passed by reference to receive any error message.

Returns :

YAPI_SUCCESS when the call succeeds.

On failure, throws an exception or returns a negative error code.

YAPI.TriggerHubDiscovery()
yTriggerHubDiscovery()
yTriggerHubDiscovery()[YAPI TriggerHubDiscovery: ]yTriggerHubDiscovery()yTriggerHubDiscovery()YAPI.TriggerHubDiscovery()YAPI.TriggerHubDiscovery()YAPI.TriggerHubDiscovery()

Force a hub discovery, if a callback as been registered with yRegisterDeviceRemovalCallback it will be called for each net work hub that will respond to the discovery.

cpp
YRETCODE yTriggerHubDiscovery(string& errmsg)
m
+(YRETCODE) TriggerHubDiscovery: (NSError**) errmsg
pas
function yTriggerHubDiscovery(var errmsg: string): integer
vb
function yTriggerHubDiscovery(ByRef errmsg As String) As Integer
cs
int TriggerHubDiscovery(ref string errmsg)
java
int TriggerHubDiscovery()
py
def TriggerHubDiscovery(errmsg=None)

Parameters :

errmsga string passed by reference to receive any error message.

Returns :

YAPI_SUCCESS when the call succeeds. On failure, throws an exception or returns a negative error code.

YAPI.UnregisterHub()
yUnregisterHub()
yUnregisterHub()YAPI.UnregisterHub()yUnregisterHub()yUnregisterHub()[YAPI UnregisterHub: ]yUnregisterHub()yUnregisterHub()YAPI.UnregisterHub()YAPI.UnregisterHub()YAPI.UnregisterHub()

Setup the Yoctopuce library to no more use modules connected on a previously registered machine with RegisterHub.

js
function yUnregisterHub(url)
nodejs
function UnregisterHub(url)
php
function yUnregisterHub($url)
cpp
void yUnregisterHub(const string& url)
m
+(void) UnregisterHub:(NSString *) url
pas
procedure yUnregisterHub(url: string)
vb
procedure yUnregisterHub(ByVal url As String)
cs
void UnregisterHub(string url)
java
void UnregisterHub(String url)
py
def UnregisterHub(url)

Parameters :

root URL of the hub to monitor
urla string containing either "usb" or the

YAPI.UpdateDeviceList()
yUpdateDeviceList()
yUpdateDeviceList()YAPI.UpdateDeviceList()yUpdateDeviceList()yUpdateDeviceList()[YAPI UpdateDeviceList: ]yUpdateDeviceList()yUpdateDeviceList()YAPI.UpdateDeviceList()YAPI.UpdateDeviceList()YAPI.UpdateDeviceList()

Triggers a (re)detection of connected Yoctopuce modules.

js
function yUpdateDeviceList(errmsg)
nodejs
function UpdateDeviceList(errmsg)
php
function yUpdateDeviceList(&$errmsg)
cpp
YRETCODE yUpdateDeviceList(string& errmsg)
m
+(YRETCODE) UpdateDeviceList:(NSError**) errmsg
pas
function yUpdateDeviceList(var errmsg: string): integer
vb
function yUpdateDeviceList(ByRef errmsg As String) As YRETCODE
cs
YRETCODE UpdateDeviceList(ref string errmsg)
java
int UpdateDeviceList()
py
def UpdateDeviceList(errmsg=None)

The library searches the machines or USB ports previously registered using yRegisterHub(), and invokes any user-defined callback function in case a change in the list of connected devices is detected.

This function can be called as frequently as desired to refresh the device list and to make the application aware of hot-plug events.

Parameters :

errmsga string passed by reference to receive any error message.

Returns :

YAPI_SUCCESS when the call succeeds.

On failure, throws an exception or returns a negative error code.

YAPI.UpdateDeviceList_async()
yUpdateDeviceList_async()
yUpdateDeviceList_async()YAPI.UpdateDeviceList_async()

Triggers a (re)detection of connected Yoctopuce modules.

js
function yUpdateDeviceList_async(callback, context)
nodejs
function UpdateDeviceList_async(callback, context)

The library searches the machines or USB ports previously registered using yRegisterHub(), and invokes any user-defined callback function in case a change in the list of connected devices is detected.

This function can be called as frequently as desired to refresh the device list and to make the application aware of hot-plug events.

This asynchronous version exists only in Javascript. It uses a callback instead of a return value in order to avoid blocking Firefox Javascript VM that does not implement context switching during blocking I/O calls.

Parameters :

callbackcallback function that is invoked when the result is known. The callback function receives three arguments: the caller-specific context object, the result code (YAPI_SUCCESS if the operation completes successfully) and the error message.
contextcaller-specific object that is passed as-is to the callback function

Returns :

nothing : the result is provided to the callback.

21.2. Module control interface

This interface is identical for all Yoctopuce USB modules. It can be used to control the module global parameters, and to enumerate the functions provided by each module.

In order to use the functions described here, you should include:

js
<script type='text/javascript' src='yocto_api.js'></script>
nodejs
var yoctolib = require('yoctolib');
var YAPI = yoctolib.YAPI;
var YModule = yoctolib.YModule;
php
require_once('yocto_api.php');
cpp
#include "yocto_api.h"
m
#import "yocto_api.h"
pas
uses yocto_api;
vb
yocto_api.vb
cs
yocto_api.cs
java
import com.yoctopuce.YoctoAPI.YModule;
py
from yocto_api import *
Global functions
yFindModule(func)

Allows you to find a module from its serial number or from its logical name.

yFirstModule()

Starts the enumeration of modules currently accessible.

YModule methods
module→checkFirmware(path, onlynew)

Tests whether the byn file is valid for this module.

module→describe()

Returns a descriptive text that identifies the module.

module→download(pathname)

Downloads the specified built-in file and returns a binary buffer with its content.

module→functionCount()

Returns the number of functions (beside the "module" interface) available on the module.

module→functionId(functionIndex)

Retrieves the hardware identifier of the nth function on the module.

module→functionName(functionIndex)

Retrieves the logical name of the nth function on the module.

module→functionValue(functionIndex)

Retrieves the advertised value of the nth function on the module.

module→get_allSettings()

Returns all the settings of the module.

module→get_beacon()

Returns the state of the localization beacon.

module→get_errorMessage()

Returns the error message of the latest error with this module object.

module→get_errorType()

Returns the numerical error code of the latest error with this module object.

module→get_firmwareRelease()

Returns the version of the firmware embedded in the module.

module→get_hardwareId()

Returns the unique hardware identifier of the module.

module→get_icon2d()

Returns the icon of the module.

module→get_lastLogs()

Returns a string with last logs of the module.

module→get_logicalName()

Returns the logical name of the module.

module→get_luminosity()

Returns the luminosity of the module informative leds (from 0 to 100).

module→get_persistentSettings()

Returns the current state of persistent module settings.

module→get_productId()

Returns the USB device identifier of the module.

module→get_productName()

Returns the commercial name of the module, as set by the factory.

module→get_productRelease()

Returns the hardware release version of the module.

module→get_rebootCountdown()

Returns the remaining number of seconds before the module restarts, or zero when no reboot has been scheduled.

module→get_serialNumber()

Returns the serial number of the module, as set by the factory.

module→get_upTime()

Returns the number of milliseconds spent since the module was powered on.

module→get_usbCurrent()

Returns the current consumed by the module on the USB bus, in milli-amps.

module→get_userData()

Returns the value of the userData attribute, as previously stored using method set_userData.

module→get_userVar()

Returns the value previously stored in this attribute.

module→isOnline()

Checks if the module is currently reachable, without raising any error.

module→isOnline_async(callback, context)

Checks if the module is currently reachable, without raising any error.

module→load(msValidity)

Preloads the module cache with a specified validity duration.

module→load_async(msValidity, callback, context)

Preloads the module cache with a specified validity duration (asynchronous version).

module→nextModule()

Continues the module enumeration started using yFirstModule().

module→reboot(secBeforeReboot)

Schedules a simple module reboot after the given number of seconds.

module→registerLogCallback(callback)

Registers a device log callback function.

module→revertFromFlash()

Reloads the settings stored in the nonvolatile memory, as when the module is powered on.

module→saveToFlash()

Saves current settings in the nonvolatile memory of the module.

module→set_allSettings(settings)

Restores all the settings of the module.

module→set_beacon(newval)

Turns on or off the module localization beacon.

module→set_logicalName(newval)

Changes the logical name of the module.

module→set_luminosity(newval)

Changes the luminosity of the module informative leds.

module→set_userData(data)

Stores a user context provided as argument in the userData attribute of the function.

module→set_userVar(newval)

Returns the value previously stored in this attribute.

module→triggerFirmwareUpdate(secBeforeReboot)

Schedules a module reboot into special firmware update mode.

module→updateFirmware(path)

Prepares a firmware update of the module.

module→wait_async(callback, context)

Waits for all pending asynchronous commands on the module to complete, and invoke the user-provided callback function.

YModule.FindModule()
yFindModule()
yFindModule()YModule.FindModule()yFindModule()yFindModule()[YModule FindModule: ]yFindModule()yFindModule()YModule.FindModule()YModule.FindModule()YModule.FindModule()

Allows you to find a module from its serial number or from its logical name.

js
function yFindModule(func)
nodejs
function FindModule(func)
php
function yFindModule($func)
cpp
YModule* yFindModule(string func)
m
+(YModule*) FindModule: (NSString*) func
pas
function yFindModule(func: string): TYModule
vb
function yFindModule(ByVal func As String) As YModule
cs
YModule FindModule(string func)
java
YModule FindModule(String func)
py
def FindModule(func)

This function does not require that the module is online at the time it is invoked. The returned object is nevertheless valid. Use the method YModule.isOnline() to test if the module is indeed online at a given time. In case of ambiguity when looking for a module by logical name, no error is notified: the first instance found is returned. The search is performed first by hardware name, then by logical name.

Parameters :

funca string containing either the serial number or the logical name of the desired module

Returns :

a YModule object allowing you to drive the module or get additional information on the module.

YModule.FirstModule()
yFirstModule()
yFirstModule()YModule.FirstModule()yFirstModule()yFirstModule()[YModule FirstModule]yFirstModule()yFirstModule()YModule.FirstModule()YModule.FirstModule()YModule.FirstModule()

Starts the enumeration of modules currently accessible.

js
function yFirstModule()
nodejs
function FirstModule()
php
function yFirstModule()
cpp
YModule* yFirstModule()
m
+(YModule*) FirstModule
pas
function yFirstModule(): TYModule
vb
function yFirstModule() As YModule
cs
YModule FirstModule()
java
YModule FirstModule()
py
def FirstModule()

Use the method YModule.nextModule() to iterate on the next modules.

Returns :

a pointer to a YModule object, corresponding to the first module currently online, or a null pointer if there are none.

module→checkFirmware()module.checkFirmware()module.checkFirmware()module→checkFirmware()module→checkFirmware()[module checkFirmware: ]module.checkFirmware()module.checkFirmware()module.checkFirmware()module.checkFirmware()module.checkFirmware()YModule checkFirmware

Tests whether the byn file is valid for this module.

js
function checkFirmware(path, onlynew)
nodejs
function checkFirmware(path, onlynew)
php
function checkFirmware($path, $onlynew)
cpp
string checkFirmware(string path, bool onlynew)
m
-(NSString*) checkFirmware: (NSString*) path
  : (bool) onlynew
pas
function checkFirmware(path: string, onlynew: boolean): string
vb
function checkFirmware() As String
cs
string checkFirmware(string path, bool onlynew)
java
String checkFirmware(String path, boolean onlynew)
py
def checkFirmware(path, onlynew)
cmd
YModule target checkFirmware path onlynew

This method is useful to test if the module needs to be updated. It is possible to pass a directory as argument instead of a file. In this case, this method returns the path of the most recent appropriate byn file. If the parameter onlynew is true, the function discards firmware that are older or equal to the installed firmware.

Parameters :

paththe path of a byn file or a directory that contains byn files
onlynewreturns only files that are strictly newer

Returns :

: the path of the byn file to use or a empty string if no byn files matches the requirement

On failure, throws an exception or returns a string that start with "error:".

module→describe()module.describe()module.describe()module→describe()module→describe()[module describe]module.describe()module.describe()module.describe()module.describe()module.describe()

Returns a descriptive text that identifies the module.

js
function describe()
nodejs
function describe()
php
function describe()
cpp
string describe()
m
-(NSString*) describe
pas
function describe(): string
vb
function describe() As String
cs
string describe()
java
String describe()
py
def describe()

The text may include either the logical name or the serial number of the module.

Returns :

a string that describes the module

module→download()module.download()module.download()module→download()module→download()[module download: ]module.download()module.download()module.download()YModule download

Downloads the specified built-in file and returns a binary buffer with its content.

js
function download(pathname)
nodejs
function download(pathname)
php
function download($pathname)
cpp
string download(string pathname)
m
-(NSMutableData*) download: (NSString*) pathname
pas
function download(pathname: string): TByteArray
vb
function download() As Byte
py
def download(pathname)
cmd
YModule target download pathname

Parameters :

pathnamename of the new file to load

Returns :

a binary buffer with the file content

On failure, throws an exception or returns YAPI_INVALID_STRING.

module→functionCount()module.functionCount()module.functionCount()module→functionCount()module→functionCount()[module functionCount]module.functionCount()module.functionCount()module.functionCount()module.functionCount()

Returns the number of functions (beside the "module" interface) available on the module.

js
function functionCount()
nodejs
function functionCount()
php
function functionCount()
cpp
int functionCount()
m
-(int) functionCount
pas
function functionCount(): integer
vb
function functionCount() As Integer
cs
int functionCount()
py
def functionCount()

Returns :

the number of functions on the module

On failure, throws an exception or returns a negative error code.

module→functionId()module.functionId()module.functionId()module→functionId()module→functionId()[module functionId: ]module.functionId()module.functionId()module.functionId()module.functionId()

Retrieves the hardware identifier of the nth function on the module.

js
function functionId(functionIndex)
nodejs
function functionId(functionIndex)
php
function functionId($functionIndex)
cpp
string functionId(int functionIndex)
m
-(NSString*) functionId: (int) functionIndex
pas
function functionId(functionIndex: integer): string
vb
function functionId(ByVal functionIndex As Integer) As String
cs
string functionId(int functionIndex)
py
def functionId(functionIndex)

Parameters :

functionIndexthe index of the function for which the information is desired, starting at 0 for the first function.

Returns :

a string corresponding to the unambiguous hardware identifier of the requested module function

On failure, throws an exception or returns an empty string.

module→functionName()module.functionName()module.functionName()module→functionName()module→functionName()[module functionName: ]module.functionName()module.functionName()module.functionName()module.functionName()

Retrieves the logical name of the nth function on the module.

js
function functionName(functionIndex)
nodejs
function functionName(functionIndex)
php
function functionName($functionIndex)
cpp
string functionName(int functionIndex)
m
-(NSString*) functionName: (int) functionIndex
pas
function functionName(functionIndex: integer): string
vb
function functionName(ByVal functionIndex As Integer) As String
cs
string functionName(int functionIndex)
py
def functionName(functionIndex)

Parameters :

functionIndexthe index of the function for which the information is desired, starting at 0 for the first function.

Returns :

a string corresponding to the logical name of the requested module function

On failure, throws an exception or returns an empty string.

module→functionValue()module.functionValue()module.functionValue()module→functionValue()module→functionValue()[module functionValue: ]module.functionValue()module.functionValue()module.functionValue()module.functionValue()

Retrieves the advertised value of the nth function on the module.

js
function functionValue(functionIndex)
nodejs
function functionValue(functionIndex)
php
function functionValue($functionIndex)
cpp
string functionValue(int functionIndex)
m
-(NSString*) functionValue: (int) functionIndex
pas
function functionValue(functionIndex: integer): string
vb
function functionValue(ByVal functionIndex As Integer) As String
cs
string functionValue(int functionIndex)
py
def functionValue(functionIndex)

Parameters :

functionIndexthe index of the function for which the information is desired, starting at 0 for the first function.

Returns :

a short string (up to 6 characters) corresponding to the advertised value of the requested module function

On failure, throws an exception or returns an empty string.

module→get_allSettings()
module→allSettings()
module.get_allSettings()module.get_allSettings()module→get_allSettings()module→get_allSettings()[module allSettings]module.get_allSettings()module.get_allSettings()module.get_allSettings()YModule get_allSettings

Returns all the settings of the module.

js
function get_allSettings()
nodejs
function get_allSettings()
php
function get_allSettings()
cpp
string get_allSettings()
m
-(NSMutableData*) allSettings
pas
function get_allSettings(): TByteArray
vb
function get_allSettings() As Byte
py
def get_allSettings()
cmd
YModule target get_allSettings

Useful to backup all the logical names and calibrations parameters of a connected module.

Returns :

a binary buffer with all the settings.

On failure, throws an exception or returns YAPI_INVALID_STRING.

module→get_beacon()
module→beacon()
module.get_beacon()module.get_beacon()module→get_beacon()module→get_beacon()[module beacon]module.get_beacon()module.get_beacon()module.get_beacon()module.get_beacon()module.get_beacon()YModule get_beacon

Returns the state of the localization beacon.

js
function get_beacon()
nodejs
function get_beacon()
php
function get_beacon()
cpp
Y_BEACON_enum get_beacon()
m
-(Y_BEACON_enum) beacon
pas
function get_beacon(): Integer
vb
function get_beacon() As Integer
cs
int get_beacon()
java
int get_beacon()
py
def get_beacon()
cmd
YModule target get_beacon

Returns :

either Y_BEACON_OFF or Y_BEACON_ON, according to the state of the localization beacon

On failure, throws an exception or returns Y_BEACON_INVALID.

module→get_errorMessage()
module→errorMessage()
module.get_errorMessage()module.get_errorMessage()module→get_errorMessage()module→get_errorMessage()[module errorMessage]module.get_errorMessage()module.get_errorMessage()module.get_errorMessage()module.get_errorMessage()module.get_errorMessage()

Returns the error message of the latest error with this module object.

js
function get_errorMessage()
nodejs
function get_errorMessage()
php
function get_errorMessage()
cpp
string get_errorMessage()
m
-(NSString*) errorMessage
pas
function get_errorMessage(): string
vb
function get_errorMessage() As String
cs
string get_errorMessage()
java
String get_errorMessage()
py
def get_errorMessage()

This method is mostly useful when using the Yoctopuce library with exceptions disabled.

Returns :

a string corresponding to the latest error message that occured while using this module object

module→get_errorType()
module→errorType()
module.get_errorType()module.get_errorType()module→get_errorType()module→get_errorType()module.get_errorType()module.get_errorType()module.get_errorType()module.get_errorType()module.get_errorType()

Returns the numerical error code of the latest error with this module object.

js
function get_errorType()
nodejs
function get_errorType()
php
function get_errorType()
cpp
YRETCODE get_errorType()
pas
function get_errorType(): YRETCODE
vb
function get_errorType() As YRETCODE
cs
YRETCODE get_errorType()
java
int get_errorType()
py
def get_errorType()

This method is mostly useful when using the Yoctopuce library with exceptions disabled.

Returns :

a number corresponding to the code of the latest error that occured while using this module object

module→get_firmwareRelease()
module→firmwareRelease()
module.get_firmwareRelease()module.get_firmwareRelease()module→get_firmwareRelease()module→get_firmwareRelease()[module firmwareRelease]module.get_firmwareRelease()module.get_firmwareRelease()module.get_firmwareRelease()module.get_firmwareRelease()module.get_firmwareRelease()YModule get_firmwareRelease

Returns the version of the firmware embedded in the module.

js
function get_firmwareRelease()
nodejs
function get_firmwareRelease()
php
function get_firmwareRelease()
cpp
string get_firmwareRelease()
m
-(NSString*) firmwareRelease
pas
function get_firmwareRelease(): string
vb
function get_firmwareRelease() As String
cs
string get_firmwareRelease()
java
String get_firmwareRelease()
py
def get_firmwareRelease()
cmd
YModule target get_firmwareRelease

Returns :

a string corresponding to the version of the firmware embedded in the module

On failure, throws an exception or returns Y_FIRMWARERELEASE_INVALID.

module→get_hardwareId()
module→hardwareId()
module.get_hardwareId()module.get_hardwareId()module→get_hardwareId()module→get_hardwareId()[module hardwareId]module.get_hardwareId()module.get_hardwareId()module.get_hardwareId()module.get_hardwareId()

Returns the unique hardware identifier of the module.

js
function get_hardwareId()
nodejs
function get_hardwareId()
php
function get_hardwareId()
cpp
string get_hardwareId()
m
-(NSString*) hardwareId
vb
function get_hardwareId() As String
cs
string get_hardwareId()
java
String get_hardwareId()
py
def get_hardwareId()

The unique hardware identifier is made of the device serial number followed by string ".module".

Returns :

a string that uniquely identifies the module

module→get_icon2d()
module→icon2d()
module.get_icon2d()module.get_icon2d()module→get_icon2d()module→get_icon2d()[module icon2d]module.get_icon2d()module.get_icon2d()module.get_icon2d()YModule get_icon2d

Returns the icon of the module.

js
function get_icon2d()
nodejs
function get_icon2d()
php
function get_icon2d()
cpp
string get_icon2d()
m
-(NSMutableData*) icon2d
pas
function get_icon2d(): TByteArray
vb
function get_icon2d() As Byte
py
def get_icon2d()
cmd
YModule target get_icon2d

The icon is a PNG image and does not exceeds 1536 bytes.

Returns :

a binary buffer with module icon, in png format. On failure, throws an exception or returns YAPI_INVALID_STRING.

module→get_lastLogs()
module→lastLogs()
module.get_lastLogs()module.get_lastLogs()module→get_lastLogs()module→get_lastLogs()[module lastLogs]module.get_lastLogs()module.get_lastLogs()module.get_lastLogs()module.get_lastLogs()module.get_lastLogs()YModule get_lastLogs

Returns a string with last logs of the module.

js
function get_lastLogs()
nodejs
function get_lastLogs()
php
function get_lastLogs()
cpp
string get_lastLogs()
m
-(NSString*) lastLogs
pas
function get_lastLogs(): string
vb
function get_lastLogs() As String
cs
string get_lastLogs()
java
String get_lastLogs()
py
def get_lastLogs()
cmd
YModule target get_lastLogs

This method return only logs that are still in the module.

Returns :

a string with last logs of the module. On failure, throws an exception or returns YAPI_INVALID_STRING.

module→get_logicalName()
module→logicalName()
module.get_logicalName()module.get_logicalName()module→get_logicalName()module→get_logicalName()[module logicalName]module.get_logicalName()module.get_logicalName()module.get_logicalName()module.get_logicalName()module.get_logicalName()YModule get_logicalName

Returns the logical name of the module.

js
function get_logicalName()
nodejs
function get_logicalName()
php
function get_logicalName()
cpp
string get_logicalName()
m
-(NSString*) logicalName
pas
function get_logicalName(): string
vb
function get_logicalName() As String
cs
string get_logicalName()
java
String get_logicalName()
py
def get_logicalName()
cmd
YModule target get_logicalName

Returns :

a string corresponding to the logical name of the module

On failure, throws an exception or returns Y_LOGICALNAME_INVALID.

module→get_luminosity()
module→luminosity()
module.get_luminosity()module.get_luminosity()module→get_luminosity()module→get_luminosity()[module luminosity]module.get_luminosity()module.get_luminosity()module.get_luminosity()module.get_luminosity()module.get_luminosity()YModule get_luminosity

Returns the luminosity of the module informative leds (from 0 to 100).

js
function get_luminosity()
nodejs
function get_luminosity()
php
function get_luminosity()
cpp
int get_luminosity()
m
-(int) luminosity
pas
function get_luminosity(): LongInt
vb
function get_luminosity() As Integer
cs
int get_luminosity()
java
int get_luminosity()
py
def get_luminosity()
cmd
YModule target get_luminosity

Returns :

an integer corresponding to the luminosity of the module informative leds (from 0 to 100)

On failure, throws an exception or returns Y_LUMINOSITY_INVALID.

module→get_persistentSettings()
module→persistentSettings()
module.get_persistentSettings()module.get_persistentSettings()module→get_persistentSettings()module→get_persistentSettings()[module persistentSettings]module.get_persistentSettings()module.get_persistentSettings()module.get_persistentSettings()module.get_persistentSettings()module.get_persistentSettings()YModule get_persistentSettings

Returns the current state of persistent module settings.

js
function get_persistentSettings()
nodejs
function get_persistentSettings()
php
function get_persistentSettings()
cpp
Y_PERSISTENTSETTINGS_enum get_persistentSettings()
m
-(Y_PERSISTENTSETTINGS_enum) persistentSettings
pas
function get_persistentSettings(): Integer
vb
function get_persistentSettings() As Integer
cs
int get_persistentSettings()
java
int get_persistentSettings()
py
def get_persistentSettings()
cmd
YModule target get_persistentSettings

Returns :

a value among Y_PERSISTENTSETTINGS_LOADED, Y_PERSISTENTSETTINGS_SAVED and Y_PERSISTENTSETTINGS_MODIFIED corresponding to the current state of persistent module settings

On failure, throws an exception or returns Y_PERSISTENTSETTINGS_INVALID.

module→get_productId()
module→productId()
module.get_productId()module.get_productId()module→get_productId()module→get_productId()[module productId]module.get_productId()module.get_productId()module.get_productId()module.get_productId()module.get_productId()YModule get_productId

Returns the USB device identifier of the module.

js
function get_productId()
nodejs
function get_productId()
php
function get_productId()
cpp
int get_productId()
m
-(int) productId
pas
function get_productId(): LongInt
vb
function get_productId() As Integer
cs
int get_productId()
java
int get_productId()
py
def get_productId()
cmd
YModule target get_productId

Returns :

an integer corresponding to the USB device identifier of the module

On failure, throws an exception or returns Y_PRODUCTID_INVALID.

module→get_productName()
module→productName()
module.get_productName()module.get_productName()module→get_productName()module→get_productName()[module productName]module.get_productName()module.get_productName()module.get_productName()module.get_productName()module.get_productName()YModule get_productName

Returns the commercial name of the module, as set by the factory.

js
function get_productName()
nodejs
function get_productName()
php
function get_productName()
cpp
string get_productName()
m
-(NSString*) productName
pas
function get_productName(): string
vb
function get_productName() As String
cs
string get_productName()
java
String get_productName()
py
def get_productName()
cmd
YModule target get_productName

Returns :

a string corresponding to the commercial name of the module, as set by the factory

On failure, throws an exception or returns Y_PRODUCTNAME_INVALID.

module→get_productRelease()
module→productRelease()
module.get_productRelease()module.get_productRelease()module→get_productRelease()module→get_productRelease()[module productRelease]module.get_productRelease()module.get_productRelease()module.get_productRelease()module.get_productRelease()module.get_productRelease()YModule get_productRelease

Returns the hardware release version of the module.

js
function get_productRelease()
nodejs
function get_productRelease()
php
function get_productRelease()
cpp
int get_productRelease()
m
-(int) productRelease
pas
function get_productRelease(): LongInt
vb
function get_productRelease() As Integer
cs
int get_productRelease()
java
int get_productRelease()
py
def get_productRelease()
cmd
YModule target get_productRelease

Returns :

an integer corresponding to the hardware release version of the module

On failure, throws an exception or returns Y_PRODUCTRELEASE_INVALID.

module→get_rebootCountdown()
module→rebootCountdown()
module.get_rebootCountdown()module.get_rebootCountdown()module→get_rebootCountdown()module→get_rebootCountdown()[module rebootCountdown]module.get_rebootCountdown()module.get_rebootCountdown()module.get_rebootCountdown()module.get_rebootCountdown()module.get_rebootCountdown()YModule get_rebootCountdown

Returns the remaining number of seconds before the module restarts, or zero when no reboot has been scheduled.

js
function get_rebootCountdown()
nodejs
function get_rebootCountdown()
php
function get_rebootCountdown()
cpp
int get_rebootCountdown()
m
-(int) rebootCountdown
pas
function get_rebootCountdown(): LongInt
vb
function get_rebootCountdown() As Integer
cs
int get_rebootCountdown()
java
int get_rebootCountdown()
py
def get_rebootCountdown()
cmd
YModule target get_rebootCountdown

Returns :

an integer corresponding to the remaining number of seconds before the module restarts, or zero when no reboot has been scheduled

On failure, throws an exception or returns Y_REBOOTCOUNTDOWN_INVALID.

module→get_serialNumber()
module→serialNumber()
module.get_serialNumber()module.get_serialNumber()module→get_serialNumber()module→get_serialNumber()[module serialNumber]module.get_serialNumber()module.get_serialNumber()module.get_serialNumber()module.get_serialNumber()module.get_serialNumber()YModule get_serialNumber

Returns the serial number of the module, as set by the factory.

js
function get_serialNumber()
nodejs
function get_serialNumber()
php
function get_serialNumber()
cpp
string get_serialNumber()
m
-(NSString*) serialNumber
pas
function get_serialNumber(): string
vb
function get_serialNumber() As String
cs
string get_serialNumber()
java
String get_serialNumber()
py
def get_serialNumber()
cmd
YModule target get_serialNumber

Returns :

a string corresponding to the serial number of the module, as set by the factory

On failure, throws an exception or returns Y_SERIALNUMBER_INVALID.

module→get_upTime()
module→upTime()
module.get_upTime()module.get_upTime()module→get_upTime()module→get_upTime()[module upTime]module.get_upTime()module.get_upTime()module.get_upTime()module.get_upTime()module.get_upTime()YModule get_upTime

Returns the number of milliseconds spent since the module was powered on.

js
function get_upTime()
nodejs
function get_upTime()
php
function get_upTime()
cpp
s64 get_upTime()
m
-(s64) upTime
pas
function get_upTime(): int64
vb
function get_upTime() As Long
cs
long get_upTime()
java
long get_upTime()
py
def get_upTime()
cmd
YModule target get_upTime

Returns :

an integer corresponding to the number of milliseconds spent since the module was powered on

On failure, throws an exception or returns Y_UPTIME_INVALID.

module→get_usbCurrent()
module→usbCurrent()
module.get_usbCurrent()module.get_usbCurrent()module→get_usbCurrent()module→get_usbCurrent()[module usbCurrent]module.get_usbCurrent()module.get_usbCurrent()module.get_usbCurrent()module.get_usbCurrent()module.get_usbCurrent()YModule get_usbCurrent

Returns the current consumed by the module on the USB bus, in milli-amps.

js
function get_usbCurrent()
nodejs
function get_usbCurrent()
php
function get_usbCurrent()
cpp
int get_usbCurrent()
m
-(int) usbCurrent
pas
function get_usbCurrent(): LongInt
vb
function get_usbCurrent() As Integer
cs
int get_usbCurrent()
java
int get_usbCurrent()
py
def get_usbCurrent()
cmd
YModule target get_usbCurrent

Returns :

an integer corresponding to the current consumed by the module on the USB bus, in milli-amps

On failure, throws an exception or returns Y_USBCURRENT_INVALID.

module→get_userData()
module→userData()
module.get_userData()module.get_userData()module→get_userData()module→get_userData()[module userData]module.get_userData()module.get_userData()module.get_userData()module.get_userData()module.get_userData()

Returns the value of the userData attribute, as previously stored using method set_userData.

js
function get_userData()
nodejs
function get_userData()
php
function get_userData()
cpp
void * get_userData()
m
-(void*) userData
pas
function get_userData(): Tobject
vb
function get_userData() As Object
cs
object get_userData()
java
Object get_userData()
py
def get_userData()

This attribute is never touched directly by the API, and is at disposal of the caller to store a context.

Returns :

the object stored previously by the caller.

module→get_userVar()
module→userVar()
module.get_userVar()module.get_userVar()module→get_userVar()module→get_userVar()[module userVar]module.get_userVar()module.get_userVar()module.get_userVar()module.get_userVar()module.get_userVar()YModule get_userVar

Returns the value previously stored in this attribute.

js
function get_userVar()
nodejs
function get_userVar()
php
function get_userVar()
cpp
int get_userVar()
m
-(int) userVar
pas
function get_userVar(): LongInt
vb
function get_userVar() As Integer
cs
int get_userVar()
java
int get_userVar()
py
def get_userVar()
cmd
YModule target get_userVar

On startup and after a device reboot, the value is always reset to zero.

Returns :

an integer corresponding to the value previously stored in this attribute

On failure, throws an exception or returns Y_USERVAR_INVALID.

module→isOnline()module.isOnline()module.isOnline()module→isOnline()module→isOnline()[module isOnline]module.isOnline()module.isOnline()module.isOnline()module.isOnline()module.isOnline()

Checks if the module is currently reachable, without raising any error.

js
function isOnline()
nodejs
function isOnline()
php
function isOnline()
cpp
bool isOnline()
m
-(BOOL) isOnline
pas
function isOnline(): boolean
vb
function isOnline() As Boolean
cs
bool isOnline()
java
boolean isOnline()
py
def isOnline()

If there are valid cached values for the module, that have not yet expired, the device is considered reachable. No exception is raised if there is an error while trying to contact the requested module.

Returns :

true if the module can be reached, and false otherwise

module→isOnline_async()module.isOnline_async()module.isOnline_async()

Checks if the module is currently reachable, without raising any error.

js
function isOnline_async(callback, context)
nodejs
function isOnline_async(callback, context)

If there are valid cached values for the module, that have not yet expired, the device is considered reachable. No exception is raised if there is an error while trying to contact the requested module.

This asynchronous version exists only in Javascript. It uses a callback instead of a return value in order to avoid blocking Firefox Javascript VM that does not implement context switching during blocking I/O calls.

Parameters :

callbackcallback function that is invoked when the result is known. The callback function receives three arguments: the caller-specific context object, the receiving module object and the boolean result
contextcaller-specific object that is passed as-is to the callback function

Returns :

nothing : the result is provided to the callback.

module→load()module.load()module.load()module→load()module→load()[module load: ]module.load()module.load()module.load()module.load()module.load()

Preloads the module cache with a specified validity duration.

js
function load(msValidity)
nodejs
function load(msValidity)
php
function load($msValidity)
cpp
YRETCODE load(int msValidity)
m
-(YRETCODE) load: (int) msValidity
pas
function load(msValidity: integer): YRETCODE
vb
function load(ByVal msValidity As Integer) As YRETCODE
cs
YRETCODE load(int msValidity)
java
int load(long msValidity)
py
def load(msValidity)

By default, whenever accessing a device, all module attributes are kept in cache for the standard duration (5 ms). This method can be used to temporarily mark the cache as valid for a longer period, in order to reduce network trafic for instance.

Parameters :

msValidityan integer corresponding to the validity attributed to the loaded module parameters, in milliseconds

Returns :

YAPI_SUCCESS when the call succeeds.

On failure, throws an exception or returns a negative error code.

module→load_async()module.load_async()module.load_async()

Preloads the module cache with a specified validity duration (asynchronous version).

js
function load_async(msValidity, callback, context)
nodejs
function load_async(msValidity, callback, context)

By default, whenever accessing a device, all module attributes are kept in cache for the standard duration (5 ms). This method can be used to temporarily mark the cache as valid for a longer period, in order to reduce network trafic for instance.

This asynchronous version exists only in Javascript. It uses a callback instead of a return value in order to avoid blocking Firefox javascript VM that does not implement context switching during blocking I/O calls. See the documentation section on asynchronous Javascript calls for more details.

Parameters :

msValidityan integer corresponding to the validity of the loaded module parameters, in milliseconds
callbackcallback function that is invoked when the result is known. The callback function receives three arguments: the caller-specific context object, the receiving module object and the error code (or YAPI_SUCCESS)
contextcaller-specific object that is passed as-is to the callback function

Returns :

nothing : the result is provided to the callback.

module→nextModule()module.nextModule()module.nextModule()module→nextModule()module→nextModule()[module nextModule]module.nextModule()module.nextModule()module.nextModule()module.nextModule()module.nextModule()

Continues the module enumeration started using yFirstModule().

js
function nextModule()
nodejs
function nextModule()
php
function nextModule()
cpp
YModule * nextModule()
m
-(YModule*) nextModule
pas
function nextModule(): TYModule
vb
function nextModule() As YModule
cs
YModule nextModule()
java
YModule nextModule()
py
def nextModule()

Returns :

a pointer to a YModule object, corresponding to the next module found, or a null pointer if there are no more modules to enumerate.

module→reboot()module.reboot()module.reboot()module→reboot()module→reboot()[module reboot: ]module.reboot()module.reboot()module.reboot()module.reboot()module.reboot()YModule reboot

Schedules a simple module reboot after the given number of seconds.

js
function reboot(secBeforeReboot)
nodejs
function reboot(secBeforeReboot)
php
function reboot($secBeforeReboot)
cpp
int reboot(int secBeforeReboot)
m
-(int) reboot: (int) secBeforeReboot
pas
function reboot(secBeforeReboot: LongInt): LongInt
vb
function reboot() As Integer
cs
int reboot(int secBeforeReboot)
java
int reboot(int secBeforeReboot)
py
def reboot(secBeforeReboot)
cmd
YModule target reboot secBeforeReboot

Parameters :

secBeforeRebootnumber of seconds before rebooting

Returns :

YAPI_SUCCESS when the call succeeds.

On failure, throws an exception or returns a negative error code.

module→registerLogCallback()module→registerLogCallback()[module registerLogCallback: ]module.registerLogCallback()module.registerLogCallback()module.registerLogCallback()module.registerLogCallback()

Registers a device log callback function.

cpp
void registerLogCallback(YModuleLogCallback callback)
m
-(void) registerLogCallback: (YModuleLogCallback) callback
vb
function registerLogCallback(ByVal callback As YModuleLogCallback) As Integer
cs
int registerLogCallback(LogCallback callback)
java
void registerLogCallback(LogCallback callback)
py
def registerLogCallback(callback)

This callback will be called each time that a module sends a new log message. Mostly useful to debug a Yoctopuce module.

Parameters :

callbackthe callback function to call, or a null pointer. The callback function should take two arguments: the module object that emitted the log message, and the character string containing the log.

module→revertFromFlash()module.revertFromFlash()module.revertFromFlash()module→revertFromFlash()module→revertFromFlash()[module revertFromFlash]module.revertFromFlash()module.revertFromFlash()module.revertFromFlash()module.revertFromFlash()module.revertFromFlash()YModule revertFromFlash

Reloads the settings stored in the nonvolatile memory, as when the module is powered on.

js
function revertFromFlash()
nodejs
function revertFromFlash()
php
function revertFromFlash()
cpp
int revertFromFlash()
m
-(int) revertFromFlash
pas
function revertFromFlash(): LongInt
vb
function revertFromFlash() As Integer
cs
int revertFromFlash()
java
int revertFromFlash()
py
def revertFromFlash()
cmd
YModule target revertFromFlash

Returns :

YAPI_SUCCESS when the call succeeds.

On failure, throws an exception or returns a negative error code.

module→saveToFlash()module.saveToFlash()module.saveToFlash()module→saveToFlash()module→saveToFlash()[module saveToFlash]module.saveToFlash()module.saveToFlash()module.saveToFlash()module.saveToFlash()module.saveToFlash()YModule saveToFlash

Saves current settings in the nonvolatile memory of the module.

js
function saveToFlash()
nodejs
function saveToFlash()
php
function saveToFlash()
cpp
int saveToFlash()
m
-(int) saveToFlash
pas
function saveToFlash(): LongInt
vb
function saveToFlash() As Integer
cs
int saveToFlash()
java
int saveToFlash()
py
def saveToFlash()
cmd
YModule target saveToFlash

Warning: the number of allowed save operations during a module life is limited (about 100000 cycles). Do not call this function within a loop.

Returns :

YAPI_SUCCESS when the call succeeds.

On failure, throws an exception or returns a negative error code.

module→set_allSettings()
module→setAllSettings()
module.set_allSettings()module.set_allSettings()module→set_allSettings()module→set_allSettings()[module setAllSettings: ]module.set_allSettings()module.set_allSettings()module.set_allSettings()module.set_allSettings()module.set_allSettings()YModule set_allSettings

Restores all the settings of the module.

js
function set_allSettings(settings)
nodejs
function set_allSettings(settings)
php
function set_allSettings($settings)
cpp
int set_allSettings(string settings)
m
-(int) setAllSettings: (NSData*) settings
pas
function set_allSettings(settings: TByteArray): LongInt
vb
procedure set_allSettings()
cs
int set_allSettings()
java
int set_allSettings()
py
def set_allSettings(settings)
cmd
YModule target set_allSettings settings

Useful to restore all the logical names and calibrations parameters of a module from a backup.

Parameters :

settingsa binary buffer with all the settings.

Returns :

YAPI_SUCCESS when the call succeeds.

On failure, throws an exception or returns a negative error code.

module→set_beacon()
module→setBeacon()
module.set_beacon()module.set_beacon()module→set_beacon()module→set_beacon()[module setBeacon: ]module.set_beacon()module.set_beacon()module.set_beacon()module.set_beacon()module.set_beacon()YModule set_beacon

Turns on or off the module localization beacon.

js
function set_beacon(newval)
nodejs
function set_beacon(newval)
php
function set_beacon($newval)
cpp
int set_beacon(Y_BEACON_enum newval)
m
-(int) setBeacon: (Y_BEACON_enum) newval
pas
function set_beacon(newval: Integer): integer
vb
function set_beacon(ByVal newval As Integer) As Integer
cs
int set_beacon(int newval)
java
int set_beacon(int newval)
py
def set_beacon(newval)
cmd
YModule target set_beacon newval

Parameters :

newvaleither Y_BEACON_OFF or Y_BEACON_ON

Returns :

YAPI_SUCCESS if the call succeeds.

On failure, throws an exception or returns a negative error code.

module→set_logicalName()
module→setLogicalName()
module.set_logicalName()module.set_logicalName()module→set_logicalName()module→set_logicalName()[module setLogicalName: ]module.set_logicalName()module.set_logicalName()module.set_logicalName()module.set_logicalName()module.set_logicalName()YModule set_logicalName

Changes the logical name of the module.

js
function set_logicalName(newval)
nodejs
function set_logicalName(newval)
php
function set_logicalName($newval)
cpp
int set_logicalName(const string& newval)
m
-(int) setLogicalName: (NSString*) newval
pas
function set_logicalName(newval: string): integer
vb
function set_logicalName(ByVal newval As String) As Integer
cs
int set_logicalName(string newval)
java
int set_logicalName(String newval)
py
def set_logicalName(newval)
cmd
YModule target set_logicalName newval

You can use yCheckLogicalName() prior to this call to make sure that your parameter is valid. Remember to call the saveToFlash() method of the module if the modification must be kept.

Parameters :

newvala string corresponding to the logical name of the module

Returns :

YAPI_SUCCESS if the call succeeds.

On failure, throws an exception or returns a negative error code.

module→set_luminosity()
module→setLuminosity()
module.set_luminosity()module.set_luminosity()module→set_luminosity()module→set_luminosity()[module setLuminosity: ]module.set_luminosity()module.set_luminosity()module.set_luminosity()module.set_luminosity()module.set_luminosity()YModule set_luminosity

Changes the luminosity of the module informative leds.

js
function set_luminosity(newval)
nodejs
function set_luminosity(newval)
php
function set_luminosity($newval)
cpp
int set_luminosity(int newval)
m
-(int) setLuminosity: (int) newval
pas
function set_luminosity(newval: LongInt): integer
vb
function set_luminosity(ByVal newval As Integer) As Integer
cs
int set_luminosity(int newval)
java
int set_luminosity(int newval)
py
def set_luminosity(newval)
cmd
YModule target set_luminosity newval

The parameter is a value between 0 and 100. Remember to call the saveToFlash() method of the module if the modification must be kept.

Parameters :

newvalan integer corresponding to the luminosity of the module informative leds

Returns :

YAPI_SUCCESS if the call succeeds.

On failure, throws an exception or returns a negative error code.

module→set_userData()
module→setUserData()
module.set_userData()module.set_userData()module→set_userData()module→set_userData()[module setUserData: ]module.set_userData()module.set_userData()module.set_userData()module.set_userData()module.set_userData()

Stores a user context provided as argument in the userData attribute of the function.

js
function set_userData(data)
nodejs
function set_userData(data)
php
function set_userData($data)
cpp
void set_userData(void* data)
m
-(void) setUserData: (void*) data
pas
procedure set_userData(data: Tobject)
vb
procedure set_userData(ByVal data As Object)
cs
void set_userData(object data)
java
void set_userData(Object data)
py
def set_userData(data)

This attribute is never touched by the API, and is at disposal of the caller to store a context.

Parameters :

dataany kind of object to be stored

module→set_userVar()
module→setUserVar()
module.set_userVar()module.set_userVar()module→set_userVar()module→set_userVar()[module setUserVar: ]module.set_userVar()module.set_userVar()module.set_userVar()module.set_userVar()module.set_userVar()YModule set_userVar

Returns the value previously stored in this attribute.

js
function set_userVar(newval)
nodejs
function set_userVar(newval)
php
function set_userVar($newval)
cpp
int set_userVar(int newval)
m
-(int) setUserVar: (int) newval
pas
function set_userVar(newval: LongInt): integer
vb
function set_userVar(ByVal newval As Integer) As Integer
cs
int set_userVar(int newval)
java
int set_userVar(int newval)
py
def set_userVar(newval)
cmd
YModule target set_userVar newval

On startup and after a device reboot, the value is always reset to zero.

Parameters :

newvalan integer

Returns :

YAPI_SUCCESS if the call succeeds.

On failure, throws an exception or returns a negative error code.

module→triggerFirmwareUpdate()module.triggerFirmwareUpdate()module.triggerFirmwareUpdate()module→triggerFirmwareUpdate()module→triggerFirmwareUpdate()[module triggerFirmwareUpdate: ]module.triggerFirmwareUpdate()module.triggerFirmwareUpdate()module.triggerFirmwareUpdate()module.triggerFirmwareUpdate()module.triggerFirmwareUpdate()YModule triggerFirmwareUpdate

Schedules a module reboot into special firmware update mode.

js
function triggerFirmwareUpdate(secBeforeReboot)
nodejs
function triggerFirmwareUpdate(secBeforeReboot)
php
function triggerFirmwareUpdate($secBeforeReboot)
cpp
int triggerFirmwareUpdate(int secBeforeReboot)
m
-(int) triggerFirmwareUpdate: (int) secBeforeReboot
pas
function triggerFirmwareUpdate(secBeforeReboot: LongInt): LongInt
vb
function triggerFirmwareUpdate() As Integer
cs
int triggerFirmwareUpdate(int secBeforeReboot)
java
int triggerFirmwareUpdate(int secBeforeReboot)
py
def triggerFirmwareUpdate(secBeforeReboot)
cmd
YModule target triggerFirmwareUpdate secBeforeReboot

Parameters :

secBeforeRebootnumber of seconds before rebooting

Returns :

YAPI_SUCCESS when the call succeeds.

On failure, throws an exception or returns a negative error code.

module→updateFirmware()module.updateFirmware()module.updateFirmware()module→updateFirmware()module→updateFirmware()[module updateFirmware: ]module.updateFirmware()module.updateFirmware()module.updateFirmware()module.updateFirmware()module.updateFirmware()YModule updateFirmware

Prepares a firmware update of the module.

js
function updateFirmware(path)
nodejs
function updateFirmware(path)
php
function updateFirmware($path)
cpp
YFirmwareUpdate updateFirmware(string path)
m
-(YFirmwareUpdate*) updateFirmware: (NSString*) path
pas
function updateFirmware(path: string): TYFirmwareUpdate
vb
function updateFirmware() As YFirmwareUpdate
cs
YFirmwareUpdate updateFirmware(string path)
java
YFirmwareUpdate updateFirmware(String path)
py
def updateFirmware(path)
cmd
YModule target updateFirmware path

This method returns a YFirmwareUpdate object which handles the firmware update process.

Parameters :

paththe path of the byn file to use.

Returns :

: A YFirmwareUpdate object.

module→wait_async()module.wait_async()module.wait_async()

Waits for all pending asynchronous commands on the module to complete, and invoke the user-provided callback function.

js
function wait_async(callback, context)
nodejs
function wait_async(callback, context)

The callback function can therefore freely issue synchronous or asynchronous commands, without risking to block the Javascript VM.

Parameters :

callbackcallback function that is invoked when all pending commands on the module are completed. The callback function receives two arguments: the caller-specific context object and the receiving function object.
contextcaller-specific object that is passed as-is to the callback function

Returns :

nothing.

21.3. SerialPort function interface

The SerialPort function interface allows you to fully drive a Yoctopuce serial port, to send and receive data, and to configure communication parameters (baud rate, bit count, parity, flow control and protocol). Note that Yoctopuce serial ports are not exposed as virtual COM ports. They are meant to be used in the same way as all Yoctopuce devices.

In order to use the functions described here, you should include:

js
<script type='text/javascript' src='yocto_serialport.js'></script>
nodejs
var yoctolib = require('yoctolib');
var YSerialPort = yoctolib.YSerialPort;
php
require_once('yocto_serialport.php');
cpp
#include "yocto_serialport.h"
m
#import "yocto_serialport.h"
pas
uses yocto_serialport;
vb
yocto_serialport.vb
cs
yocto_serialport.cs
java
import com.yoctopuce.YoctoAPI.YSerialPort;
py
from yocto_serialport import *
Global functions
yFindSerialPort(func)

Retrieves a serial port for a given identifier.

yFirstSerialPort()

Starts the enumeration of serial ports currently accessible.

YSerialPort methods
serialport→describe()

Returns a short text that describes unambiguously the instance of the serial port in the form TYPE(NAME)=SERIAL.FUNCTIONID.

serialport→get_CTS()

Reads the level of the CTS line.

serialport→get_advertisedValue()

Returns the current value of the serial port (no more than 6 characters).

serialport→get_currentJob()

Returns the name of the job file currently in use.

serialport→get_errCount()

Returns the total number of communication errors detected since last reset.

serialport→get_errorMessage()

Returns the error message of the latest error with the serial port.

serialport→get_errorType()

Returns the numerical error code of the latest error with the serial port.

serialport→get_friendlyName()

Returns a global identifier of the serial port in the format MODULE_NAME.FUNCTION_NAME.

serialport→get_functionDescriptor()

Returns a unique identifier of type YFUN_DESCR corresponding to the function.

serialport→get_functionId()

Returns the hardware identifier of the serial port, without reference to the module.

serialport→get_hardwareId()

Returns the unique hardware identifier of the serial port in the form SERIAL.FUNCTIONID.

serialport→get_lastMsg()

Returns the latest message fully received (for Line, Frame and Modbus protocols).

serialport→get_logicalName()

Returns the logical name of the serial port.

serialport→get_module()

Gets the YModule object for the device on which the function is located.

serialport→get_module_async(callback, context)

Gets the YModule object for the device on which the function is located (asynchronous version).

serialport→get_protocol()

Returns the type of protocol used over the serial line, as a string.

serialport→get_rxCount()

Returns the total number of bytes received since last reset.

serialport→get_rxMsgCount()

Returns the total number of messages received since last reset.

serialport→get_serialMode()

Returns the serial port communication parameters, as a string such as "9600,8N1".

serialport→get_startupJob()

Returns the job file to use when the device is powered on.

serialport→get_txCount()

Returns the total number of bytes transmitted since last reset.

serialport→get_txMsgCount()

Returns the total number of messages send since last reset.

serialport→get_userData()

Returns the value of the userData attribute, as previously stored using method set_userData.

serialport→get_voltageLevel()

Returns the voltage level used on the serial line.

serialport→isOnline()

Checks if the serial port is currently reachable, without raising any error.

serialport→isOnline_async(callback, context)

Checks if the serial port is currently reachable, without raising any error (asynchronous version).

serialport→load(msValidity)

Preloads the serial port cache with a specified validity duration.

serialport→load_async(msValidity, callback, context)

Preloads the serial port cache with a specified validity duration (asynchronous version).

serialport→modbusReadBits(slaveNo, pduAddr, nBits)

Reads one or more contiguous internal bits (or coil status) from a MODBUS serial device.

serialport→modbusReadInputBits(slaveNo, pduAddr, nBits)

Reads one or more contiguous input bits (or discrete inputs) from a MODBUS serial device.

serialport→modbusReadInputRegisters(slaveNo, pduAddr, nWords)

Reads one or more contiguous input registers (read-only registers) from a MODBUS serial device.

serialport→modbusReadRegisters(slaveNo, pduAddr, nWords)

Reads one or more contiguous internal registers (holding registers) from a MODBUS serial device.

serialport→modbusWriteAndReadRegisters(slaveNo, pduWriteAddr, values, pduReadAddr, nReadWords)

Sets several contiguous internal registers (holding registers) on a MODBUS serial device, then performs a contiguous read of a set of (possibly different) internal registers.

serialport→modbusWriteBit(slaveNo, pduAddr, value)

Sets a single internal bit (or coil) on a MODBUS serial device.

serialport→modbusWriteBits(slaveNo, pduAddr, bits)

Sets several contiguous internal bits (or coils) on a MODBUS serial device.

serialport→modbusWriteRegister(slaveNo, pduAddr, value)

Sets a single internal register (or holding register) on a MODBUS serial device.

serialport→modbusWriteRegisters(slaveNo, pduAddr, values)

Sets several contiguous internal registers (or holding registers) on a MODBUS serial device.

serialport→nextSerialPort()

Continues the enumeration of serial ports started using yFirstSerialPort().

serialport→queryLine(query, maxWait)

Sends a text line query to the serial port, and reads the reply, if any.

serialport→queryMODBUS(slaveNo, pduBytes)

Sends a message to a specified MODBUS slave connected to the serial port, and reads the reply, if any.

serialport→readHex(nBytes)

Reads data from the receive buffer as a hexadecimal string, starting at current stream position.

serialport→readLine()

Reads a single line (or message) from the receive buffer, starting at current stream position.

serialport→readMessages(pattern, maxWait)

Searches for incoming messages in the serial port receive buffer matching a given pattern, starting at current position.

serialport→readStr(nChars)

Reads data from the receive buffer as a string, starting at current stream position.

serialport→read_seek(absPos)

Changes the current internal stream position to the specified value.

serialport→read_tell()

Returns the current absolute stream position pointer of the YSerialPort object.

serialport→registerValueCallback(callback)

Registers the callback function that is invoked on every change of advertised value.

serialport→reset()

Clears the serial port buffer and resets counters to zero.

serialport→selectJob(jobfile)

Load and start processing the specified job file.

serialport→set_RTS(val)

Manually sets the state of the RTS line.

serialport→set_currentJob(newval)

Changes the job to use when the device is powered on.

serialport→set_logicalName(newval)

Changes the logical name of the serial port.

serialport→set_protocol(newval)

Changes the type of protocol used over the serial line.

serialport→set_serialMode(newval)

Changes the serial port communication parameters, with a string such as "9600,8N1".

serialport→set_startupJob(newval)

Changes the job to use when the device is powered on.

serialport→set_userData(data)

Stores a user context provided as argument in the userData attribute of the function.

serialport→set_voltageLevel(newval)

Changes the voltage type used on the serial line.

serialport→uploadJob(jobfile, jsonDef)

Saves the job definition string (JSON data) into a job file.

serialport→wait_async(callback, context)

Waits for all pending asynchronous commands on the module to complete, and invoke the user-provided callback function.

serialport→writeArray(byteList)

Sends a byte sequence (provided as a list of bytes) to the serial port.

serialport→writeBin(buff)

Sends a binary buffer to the serial port, as is.

serialport→writeHex(hexString)

Sends a byte sequence (provided as a hexadecimal string) to the serial port.

serialport→writeLine(text)

Sends an ASCII string to the serial port, followed by a line break (CR LF).

serialport→writeMODBUS(hexString)

Sends a MODBUS message (provided as a hexadecimal string) to the serial port.

serialport→writeStr(text)

Sends an ASCII string to the serial port, as is.

YSerialPort.FindSerialPort()
yFindSerialPort()
yFindSerialPort()YSerialPort.FindSerialPort()yFindSerialPort()yFindSerialPort()[YSerialPort FindSerialPort: ]yFindSerialPort()yFindSerialPort()YSerialPort.FindSerialPort()YSerialPort.FindSerialPort()YSerialPort.FindSerialPort()

Retrieves a serial port for a given identifier.

js
function yFindSerialPort(func)
nodejs
function FindSerialPort(func)
php
function yFindSerialPort($func)
cpp
YSerialPort* yFindSerialPort(const string& func)
m
+(YSerialPort*) FindSerialPort:(NSString*) func
pas
function yFindSerialPort(func: string): TYSerialPort
vb
function yFindSerialPort(ByVal func As String) As YSerialPort
cs
YSerialPort FindSerialPort(string func)
java
YSerialPort FindSerialPort(String func)
py
def FindSerialPort(func)

The identifier can be specified using several formats:

This function does not require that the serial port is online at the time it is invoked. The returned object is nevertheless valid. Use the method YSerialPort.isOnline() to test if the serial port is indeed online at a given time. In case of ambiguity when looking for a serial port by logical name, no error is notified: the first instance found is returned. The search is performed first by hardware name, then by logical name.

Parameters :

funca string that uniquely characterizes the serial port

Returns :

a YSerialPort object allowing you to drive the serial port.

YSerialPort.FirstSerialPort()
yFirstSerialPort()
yFirstSerialPort()YSerialPort.FirstSerialPort()yFirstSerialPort()yFirstSerialPort()[YSerialPort FirstSerialPort]yFirstSerialPort()yFirstSerialPort()YSerialPort.FirstSerialPort()YSerialPort.FirstSerialPort()YSerialPort.FirstSerialPort()

Starts the enumeration of serial ports currently accessible.

js
function yFirstSerialPort()
nodejs
function FirstSerialPort()
php
function yFirstSerialPort()
cpp
YSerialPort* yFirstSerialPort()
m
+(YSerialPort*) FirstSerialPort
pas
function yFirstSerialPort(): TYSerialPort
vb
function yFirstSerialPort() As YSerialPort
cs
YSerialPort FirstSerialPort()
java
YSerialPort FirstSerialPort()
py
def FirstSerialPort()

Use the method YSerialPort.nextSerialPort() to iterate on next serial ports.

Returns :

a pointer to a YSerialPort object, corresponding to the first serial port currently online, or a null pointer if there are none.

serialport→describe()serialport.describe()serialport.describe()serialport→describe()serialport→describe()[serialport describe]serialport.describe()serialport.describe()serialport.describe()serialport.describe()serialport.describe()

Returns a short text that describes unambiguously the instance of the serial port in the form TYPE(NAME)=SERIAL.FUNCTIONID.

js
function describe()
nodejs
function describe()
php
function describe()
cpp
string describe()
m
-(NSString*) describe
pas
function describe(): string
vb
function describe() As String
cs
string describe()
java
String describe()
py
def describe()

More precisely, TYPE is the type of the function, NAME it the name used for the first access to the function, SERIAL is the serial number of the module if the module is connected or "unresolved", and FUNCTIONID is the hardware identifier of the function if the module is connected. For example, this method returns Relay(MyCustomName.relay1)=RELAYLO1-123456.relay1 if the module is already connected or Relay(BadCustomeName.relay1)=unresolved if the module has not yet been connected. This method does not trigger any USB or TCP transaction and can therefore be used in a debugger.

Returns :

a string that describes the serial port (ex: Relay(MyCustomName.relay1)=RELAYLO1-123456.relay1)

serialport→get_CTS()
serialport→CTS()
serialport.get_CTS()serialport.get_CTS()serialport→get_CTS()serialport→get_CTS()[serialport CTS]serialport.get_CTS()serialport.get_CTS()serialport.get_CTS()serialport.get_CTS()serialport.get_CTS()YSerialPort get_CTS

Reads the level of the CTS line.

js
function get_CTS()
nodejs
function get_CTS()
php
function get_CTS()
cpp
int get_CTS()
m
-(int) CTS
pas
function get_CTS(): LongInt
vb
function get_CTS() As Integer
cs
int get_CTS()
java
int get_CTS()
py
def get_CTS()
cmd
YSerialPort target get_CTS

The CTS line is usually driven by the RTS signal of the connected serial device.

Returns :

1 if the CTS line is high, 0 if the CTS line is low.

On failure, throws an exception or returns a negative error code.

serialport→get_advertisedValue()
serialport→advertisedValue()
serialport.get_advertisedValue()serialport.get_advertisedValue()serialport→get_advertisedValue()serialport→get_advertisedValue()[serialport advertisedValue]serialport.get_advertisedValue()serialport.get_advertisedValue()serialport.get_advertisedValue()serialport.get_advertisedValue()serialport.get_advertisedValue()YSerialPort get_advertisedValue

Returns the current value of the serial port (no more than 6 characters).

js
function get_advertisedValue()
nodejs
function get_advertisedValue()
php
function get_advertisedValue()
cpp
string get_advertisedValue()
m
-(NSString*) advertisedValue
pas
function get_advertisedValue(): string
vb
function get_advertisedValue() As String
cs
string get_advertisedValue()
java
String get_advertisedValue()
py
def get_advertisedValue()
cmd
YSerialPort target get_advertisedValue

Returns :

a string corresponding to the current value of the serial port (no more than 6 characters).

On failure, throws an exception or returns Y_ADVERTISEDVALUE_INVALID.

serialport→get_currentJob()
serialport→currentJob()
serialport.get_currentJob()serialport.get_currentJob()serialport→get_currentJob()serialport→get_currentJob()[serialport currentJob]serialport.get_currentJob()serialport.get_currentJob()serialport.get_currentJob()serialport.get_currentJob()serialport.get_currentJob()YSerialPort get_currentJob

Returns the name of the job file currently in use.

js
function get_currentJob()
nodejs
function get_currentJob()
php
function get_currentJob()
cpp
string get_currentJob()
m
-(NSString*) currentJob
pas
function get_currentJob(): string
vb
function get_currentJob() As String
cs
string get_currentJob()
java
String get_currentJob()
py
def get_currentJob()
cmd
YSerialPort target get_currentJob

Returns :

a string corresponding to the name of the job file currently in use

On failure, throws an exception or returns Y_CURRENTJOB_INVALID.

serialport→get_errCount()
serialport→errCount()
serialport.get_errCount()serialport.get_errCount()serialport→get_errCount()serialport→get_errCount()[serialport errCount]serialport.get_errCount()serialport.get_errCount()serialport.get_errCount()serialport.get_errCount()serialport.get_errCount()YSerialPort get_errCount

Returns the total number of communication errors detected since last reset.

js
function get_errCount()
nodejs
function get_errCount()
php
function get_errCount()
cpp
int get_errCount()
m
-(int) errCount
pas
function get_errCount(): LongInt
vb
function get_errCount() As Integer
cs
int get_errCount()
java
int get_errCount()
py
def get_errCount()
cmd
YSerialPort target get_errCount

Returns :

an integer corresponding to the total number of communication errors detected since last reset

On failure, throws an exception or returns Y_ERRCOUNT_INVALID.

serialport→get_errorMessage()
serialport→errorMessage()
serialport.get_errorMessage()serialport.get_errorMessage()serialport→get_errorMessage()serialport→get_errorMessage()[serialport errorMessage]serialport.get_errorMessage()serialport.get_errorMessage()serialport.get_errorMessage()serialport.get_errorMessage()serialport.get_errorMessage()

Returns the error message of the latest error with the serial port.

js
function get_errorMessage()
nodejs
function get_errorMessage()
php
function get_errorMessage()
cpp
string get_errorMessage()
m
-(NSString*) errorMessage
pas
function get_errorMessage(): string
vb
function get_errorMessage() As String
cs
string get_errorMessage()
java
String get_errorMessage()
py
def get_errorMessage()

This method is mostly useful when using the Yoctopuce library with exceptions disabled.

Returns :

a string corresponding to the latest error message that occured while using the serial port object

serialport→get_errorType()
serialport→errorType()
serialport.get_errorType()serialport.get_errorType()serialport→get_errorType()serialport→get_errorType()serialport.get_errorType()serialport.get_errorType()serialport.get_errorType()serialport.get_errorType()serialport.get_errorType()

Returns the numerical error code of the latest error with the serial port.

js
function get_errorType()
nodejs
function get_errorType()
php
function get_errorType()
cpp
YRETCODE get_errorType()
pas
function get_errorType(): YRETCODE
vb
function get_errorType() As YRETCODE
cs
YRETCODE get_errorType()
java
int get_errorType()
py
def get_errorType()

This method is mostly useful when using the Yoctopuce library with exceptions disabled.

Returns :

a number corresponding to the code of the latest error that occurred while using the serial port object

serialport→get_friendlyName()
serialport→friendlyName()
serialport.get_friendlyName()serialport.get_friendlyName()serialport→get_friendlyName()serialport→get_friendlyName()[serialport friendlyName]serialport.get_friendlyName()serialport.get_friendlyName()serialport.get_friendlyName()

Returns a global identifier of the serial port in the format MODULE_NAME.FUNCTION_NAME.

js
function get_friendlyName()
nodejs
function get_friendlyName()
php
function get_friendlyName()
cpp
string get_friendlyName()
m
-(NSString*) friendlyName
cs
string get_friendlyName()
java
String get_friendlyName()
py
def get_friendlyName()

The returned string uses the logical names of the module and of the serial port if they are defined, otherwise the serial number of the module and the hardware identifier of the serial port (for example: MyCustomName.relay1)

Returns :

a string that uniquely identifies the serial port using logical names (ex: MyCustomName.relay1)

On failure, throws an exception or returns Y_FRIENDLYNAME_INVALID.

serialport→get_functionDescriptor()
serialport→functionDescriptor()
serialport.get_functionDescriptor()serialport.get_functionDescriptor()serialport→get_functionDescriptor()serialport→get_functionDescriptor()[serialport functionDescriptor]serialport.get_functionDescriptor()serialport.get_functionDescriptor()serialport.get_functionDescriptor()serialport.get_functionDescriptor()serialport.get_functionDescriptor()

Returns a unique identifier of type YFUN_DESCR corresponding to the function.

js
function get_functionDescriptor()
nodejs
function get_functionDescriptor()
php
function get_functionDescriptor()
cpp
YFUN_DESCR get_functionDescriptor()
m
-(YFUN_DESCR) functionDescriptor
pas
function get_functionDescriptor(): YFUN_DESCR
vb
function get_functionDescriptor() As YFUN_DESCR
cs
YFUN_DESCR get_functionDescriptor()
java
String get_functionDescriptor()
py
def get_functionDescriptor()

This identifier can be used to test if two instances of YFunction reference the same physical function on the same physical device.

Returns :

an identifier of type YFUN_DESCR.

If the function has never been contacted, the returned value is Y_FUNCTIONDESCRIPTOR_INVALID.

serialport→get_functionId()
serialport→functionId()
serialport.get_functionId()serialport.get_functionId()serialport→get_functionId()serialport→get_functionId()[serialport functionId]serialport.get_functionId()serialport.get_functionId()serialport.get_functionId()serialport.get_functionId()

Returns the hardware identifier of the serial port, without reference to the module.

js
function get_functionId()
nodejs
function get_functionId()
php
function get_functionId()
cpp
string get_functionId()
m
-(NSString*) functionId
vb
function get_functionId() As String
cs
string get_functionId()
java
String get_functionId()
py
def get_functionId()

For example relay1

Returns :

a string that identifies the serial port (ex: relay1)

On failure, throws an exception or returns Y_FUNCTIONID_INVALID.

serialport→get_hardwareId()
serialport→hardwareId()
serialport.get_hardwareId()serialport.get_hardwareId()serialport→get_hardwareId()serialport→get_hardwareId()[serialport hardwareId]serialport.get_hardwareId()serialport.get_hardwareId()serialport.get_hardwareId()serialport.get_hardwareId()

Returns the unique hardware identifier of the serial port in the form SERIAL.FUNCTIONID.

js
function get_hardwareId()
nodejs
function get_hardwareId()
php
function get_hardwareId()
cpp
string get_hardwareId()
m
-(NSString*) hardwareId
vb
function get_hardwareId() As String
cs
string get_hardwareId()
java
String get_hardwareId()
py
def get_hardwareId()

The unique hardware identifier is composed of the device serial number and of the hardware identifier of the serial port (for example RELAYLO1-123456.relay1).

Returns :

a string that uniquely identifies the serial port (ex: RELAYLO1-123456.relay1)

On failure, throws an exception or returns Y_HARDWAREID_INVALID.

serialport→get_lastMsg()
serialport→lastMsg()
serialport.get_lastMsg()serialport.get_lastMsg()serialport→get_lastMsg()serialport→get_lastMsg()[serialport lastMsg]serialport.get_lastMsg()serialport.get_lastMsg()serialport.get_lastMsg()serialport.get_lastMsg()serialport.get_lastMsg()YSerialPort get_lastMsg

Returns the latest message fully received (for Line, Frame and Modbus protocols).

js
function get_lastMsg()
nodejs
function get_lastMsg()
php
function get_lastMsg()
cpp
string get_lastMsg()
m
-(NSString*) lastMsg
pas
function get_lastMsg(): string
vb
function get_lastMsg() As String
cs
string get_lastMsg()
java
String get_lastMsg()
py
def get_lastMsg()
cmd
YSerialPort target get_lastMsg

Returns :

a string corresponding to the latest message fully received (for Line, Frame and Modbus protocols)

On failure, throws an exception or returns Y_LASTMSG_INVALID.

serialport→get_logicalName()
serialport→logicalName()
serialport.get_logicalName()serialport.get_logicalName()serialport→get_logicalName()serialport→get_logicalName()[serialport logicalName]serialport.get_logicalName()serialport.get_logicalName()serialport.get_logicalName()serialport.get_logicalName()serialport.get_logicalName()YSerialPort get_logicalName

Returns the logical name of the serial port.

js
function get_logicalName()
nodejs
function get_logicalName()
php
function get_logicalName()
cpp
string get_logicalName()
m
-(NSString*) logicalName
pas
function get_logicalName(): string
vb
function get_logicalName() As String
cs
string get_logicalName()
java
String get_logicalName()
py
def get_logicalName()
cmd
YSerialPort target get_logicalName

Returns :

a string corresponding to the logical name of the serial port.

On failure, throws an exception or returns Y_LOGICALNAME_INVALID.

serialport→get_module()
serialport→module()
serialport.get_module()serialport.get_module()serialport→get_module()serialport→get_module()[serialport module]serialport.get_module()serialport.get_module()serialport.get_module()serialport.get_module()serialport.get_module()

Gets the YModule object for the device on which the function is located.

js
function get_module()
nodejs
function get_module()
php
function get_module()
cpp
YModule * get_module()
m
-(YModule*) module
pas
function get_module(): TYModule
vb
function get_module() As YModule
cs
YModule get_module()
java
YModule get_module()
py
def get_module()

If the function cannot be located on any module, the returned instance of YModule is not shown as on-line.

Returns :

an instance of YModule

serialport→get_module_async()
serialport→module_async()
serialport.get_module_async()serialport.get_module_async()

Gets the YModule object for the device on which the function is located (asynchronous version).

js
function get_module_async(callback, context)
nodejs
function get_module_async(callback, context)

If the function cannot be located on any module, the returned YModule object does not show as on-line.

This asynchronous version exists only in Javascript. It uses a callback instead of a return value in order to avoid blocking Firefox javascript VM that does not implement context switching during blocking I/O calls. See the documentation section on asynchronous Javascript calls for more details.

Parameters :

callbackcallback function that is invoked when the result is known. The callback function receives three arguments: the caller-specific context object, the receiving function object and the requested YModule object
contextcaller-specific object that is passed as-is to the callback function

Returns :

nothing : the result is provided to the callback.

serialport→get_protocol()
serialport→protocol()
serialport.get_protocol()serialport.get_protocol()serialport→get_protocol()serialport→get_protocol()[serialport protocol]serialport.get_protocol()serialport.get_protocol()serialport.get_protocol()serialport.get_protocol()serialport.get_protocol()YSerialPort get_protocol

Returns the type of protocol used over the serial line, as a string.

js
function get_protocol()
nodejs
function get_protocol()
php
function get_protocol()
cpp
string get_protocol()
m
-(NSString*) protocol
pas
function get_protocol(): string
vb
function get_protocol() As String
cs
string get_protocol()
java
String get_protocol()
py
def get_protocol()
cmd
YSerialPort target get_protocol

Possible values are "Line" for ASCII messages separated by CR and/or LF, "Frame:[timeout]ms" for binary messages separated by a delay time, "Modbus-ASCII" for MODBUS messages in ASCII mode, "Modbus-RTU" for MODBUS messages in RTU mode, "Char" for a continuous ASCII stream or "Byte" for a continuous binary stream.

Returns :

a string corresponding to the type of protocol used over the serial line, as a string

On failure, throws an exception or returns Y_PROTOCOL_INVALID.

serialport→get_rxCount()
serialport→rxCount()
serialport.get_rxCount()serialport.get_rxCount()serialport→get_rxCount()serialport→get_rxCount()[serialport rxCount]serialport.get_rxCount()serialport.get_rxCount()serialport.get_rxCount()serialport.get_rxCount()serialport.get_rxCount()YSerialPort get_rxCount

Returns the total number of bytes received since last reset.

js
function get_rxCount()
nodejs
function get_rxCount()
php
function get_rxCount()
cpp
int get_rxCount()
m
-(int) rxCount
pas
function get_rxCount(): LongInt
vb
function get_rxCount() As Integer
cs
int get_rxCount()
java
int get_rxCount()
py
def get_rxCount()
cmd
YSerialPort target get_rxCount

Returns :

an integer corresponding to the total number of bytes received since last reset

On failure, throws an exception or returns Y_RXCOUNT_INVALID.

serialport→get_rxMsgCount()
serialport→rxMsgCount()
serialport.get_rxMsgCount()serialport.get_rxMsgCount()serialport→get_rxMsgCount()serialport→get_rxMsgCount()[serialport rxMsgCount]serialport.get_rxMsgCount()serialport.get_rxMsgCount()serialport.get_rxMsgCount()serialport.get_rxMsgCount()serialport.get_rxMsgCount()YSerialPort get_rxMsgCount

Returns the total number of messages received since last reset.

js
function get_rxMsgCount()
nodejs
function get_rxMsgCount()
php
function get_rxMsgCount()
cpp
int get_rxMsgCount()
m
-(int) rxMsgCount
pas
function get_rxMsgCount(): LongInt
vb
function get_rxMsgCount() As Integer
cs
int get_rxMsgCount()
java
int get_rxMsgCount()
py
def get_rxMsgCount()
cmd
YSerialPort target get_rxMsgCount

Returns :

an integer corresponding to the total number of messages received since last reset

On failure, throws an exception or returns Y_RXMSGCOUNT_INVALID.

serialport→get_serialMode()
serialport→serialMode()
serialport.get_serialMode()serialport.get_serialMode()serialport→get_serialMode()serialport→get_serialMode()[serialport serialMode]serialport.get_serialMode()serialport.get_serialMode()serialport.get_serialMode()serialport.get_serialMode()serialport.get_serialMode()YSerialPort get_serialMode

Returns the serial port communication parameters, as a string such as "9600,8N1".

js
function get_serialMode()
nodejs
function get_serialMode()
php
function get_serialMode()
cpp
string get_serialMode()
m
-(NSString*) serialMode
pas
function get_serialMode(): string
vb
function get_serialMode() As String
cs
string get_serialMode()
java
String get_serialMode()
py
def get_serialMode()
cmd
YSerialPort target get_serialMode

The string includes the baud rate, the number of data bits, the parity, and the number of stop bits. An optional suffix is included if flow control is active: "CtsRts" for hardware handshake, "XOnXOff" for logical flow control and "Simplex" for acquiring a shared bus using the RTS line (as used by some RS485 adapters for instance).

Returns :

a string corresponding to the serial port communication parameters, as a string such as "9600,8N1"

On failure, throws an exception or returns Y_SERIALMODE_INVALID.

serialport→get_startupJob()
serialport→startupJob()
serialport.get_startupJob()serialport.get_startupJob()serialport→get_startupJob()serialport→get_startupJob()[serialport startupJob]serialport.get_startupJob()serialport.get_startupJob()serialport.get_startupJob()serialport.get_startupJob()serialport.get_startupJob()YSerialPort get_startupJob

Returns the job file to use when the device is powered on.

js
function get_startupJob()
nodejs
function get_startupJob()
php
function get_startupJob()
cpp
string get_startupJob()
m
-(NSString*) startupJob
pas
function get_startupJob(): string
vb
function get_startupJob() As String
cs
string get_startupJob()
java
String get_startupJob()
py
def get_startupJob()
cmd
YSerialPort target get_startupJob

Returns :

a string corresponding to the job file to use when the device is powered on

On failure, throws an exception or returns Y_STARTUPJOB_INVALID.

serialport→get_txCount()
serialport→txCount()
serialport.get_txCount()serialport.get_txCount()serialport→get_txCount()serialport→get_txCount()[serialport txCount]serialport.get_txCount()serialport.get_txCount()serialport.get_txCount()serialport.get_txCount()serialport.get_txCount()YSerialPort get_txCount

Returns the total number of bytes transmitted since last reset.

js
function get_txCount()
nodejs
function get_txCount()
php
function get_txCount()
cpp
int get_txCount()
m
-(int) txCount
pas
function get_txCount(): LongInt
vb
function get_txCount() As Integer
cs
int get_txCount()
java
int get_txCount()
py
def get_txCount()
cmd
YSerialPort target get_txCount

Returns :

an integer corresponding to the total number of bytes transmitted since last reset

On failure, throws an exception or returns Y_TXCOUNT_INVALID.

serialport→get_txMsgCount()
serialport→txMsgCount()
serialport.get_txMsgCount()serialport.get_txMsgCount()serialport→get_txMsgCount()serialport→get_txMsgCount()[serialport txMsgCount]serialport.get_txMsgCount()serialport.get_txMsgCount()serialport.get_txMsgCount()serialport.get_txMsgCount()serialport.get_txMsgCount()YSerialPort get_txMsgCount

Returns the total number of messages send since last reset.

js
function get_txMsgCount()
nodejs
function get_txMsgCount()
php
function get_txMsgCount()
cpp
int get_txMsgCount()
m
-(int) txMsgCount
pas
function get_txMsgCount(): LongInt
vb
function get_txMsgCount() As Integer
cs
int get_txMsgCount()
java
int get_txMsgCount()
py
def get_txMsgCount()
cmd
YSerialPort target get_txMsgCount

Returns :

an integer corresponding to the total number of messages send since last reset

On failure, throws an exception or returns Y_TXMSGCOUNT_INVALID.

serialport→get_userData()
serialport→userData()
serialport.get_userData()serialport.get_userData()serialport→get_userData()serialport→get_userData()[serialport userData]serialport.get_userData()serialport.get_userData()serialport.get_userData()serialport.get_userData()serialport.get_userData()

Returns the value of the userData attribute, as previously stored using method set_userData.

js
function get_userData()
nodejs
function get_userData()
php
function get_userData()
cpp
void * get_userData()
m
-(void*) userData
pas
function get_userData(): Tobject
vb
function get_userData() As Object
cs
object get_userData()
java
Object get_userData()
py
def get_userData()

This attribute is never touched directly by the API, and is at disposal of the caller to store a context.

Returns :

the object stored previously by the caller.

serialport→get_voltageLevel()
serialport→voltageLevel()
serialport.get_voltageLevel()serialport.get_voltageLevel()serialport→get_voltageLevel()serialport→get_voltageLevel()[serialport voltageLevel]serialport.get_voltageLevel()serialport.get_voltageLevel()serialport.get_voltageLevel()serialport.get_voltageLevel()serialport.get_voltageLevel()YSerialPort get_voltageLevel

Returns the voltage level used on the serial line.

js
function get_voltageLevel()
nodejs
function get_voltageLevel()
php
function get_voltageLevel()
cpp
Y_VOLTAGELEVEL_enum get_voltageLevel()
m
-(Y_VOLTAGELEVEL_enum) voltageLevel
pas
function get_voltageLevel(): Integer
vb
function get_voltageLevel() As Integer
cs
int get_voltageLevel()
java
int get_voltageLevel()
py
def get_voltageLevel()
cmd
YSerialPort target get_voltageLevel

Returns :

a value among Y_VOLTAGELEVEL_OFF, Y_VOLTAGELEVEL_TTL3V, Y_VOLTAGELEVEL_TTL3VR, Y_VOLTAGELEVEL_TTL5V, Y_VOLTAGELEVEL_TTL5VR, Y_VOLTAGELEVEL_RS232 and Y_VOLTAGELEVEL_RS485 corresponding to the voltage level used on the serial line

On failure, throws an exception or returns Y_VOLTAGELEVEL_INVALID.

serialport→isOnline()serialport.isOnline()serialport.isOnline()serialport→isOnline()serialport→isOnline()[serialport isOnline]serialport.isOnline()serialport.isOnline()serialport.isOnline()serialport.isOnline()serialport.isOnline()

Checks if the serial port is currently reachable, without raising any error.

js
function isOnline()
nodejs
function isOnline()
php
function isOnline()
cpp
bool isOnline()
m
-(BOOL) isOnline
pas
function isOnline(): boolean
vb
function isOnline() As Boolean
cs
bool isOnline()
java
boolean isOnline()
py
def isOnline()

If there is a cached value for the serial port in cache, that has not yet expired, the device is considered reachable. No exception is raised if there is an error while trying to contact the device hosting the serial port.

Returns :

true if the serial port can be reached, and false otherwise

serialport→isOnline_async()serialport.isOnline_async()serialport.isOnline_async()

Checks if the serial port is currently reachable, without raising any error (asynchronous version).

js
function isOnline_async(callback, context)
nodejs
function isOnline_async(callback, context)

If there is a cached value for the serial port in cache, that has not yet expired, the device is considered reachable. No exception is raised if there is an error while trying to contact the device hosting the requested function.

This asynchronous version exists only in Javascript. It uses a callback instead of a return value in order to avoid blocking the Javascript virtual machine.

Parameters :

callbackcallback function that is invoked when the result is known. The callback function receives three arguments: the caller-specific context object, the receiving function object and the boolean result
contextcaller-specific object that is passed as-is to the callback function

Returns :

nothing : the result is provided to the callback.

serialport→load()serialport.load()serialport.load()serialport→load()serialport→load()[serialport load: ]serialport.load()serialport.load()serialport.load()serialport.load()serialport.load()

Preloads the serial port cache with a specified validity duration.

js
function load(msValidity)
nodejs
function load(msValidity)
php
function load($msValidity)
cpp
YRETCODE load(int msValidity)
m
-(YRETCODE) load: (int) msValidity
pas
function load(msValidity: integer): YRETCODE
vb
function load(ByVal msValidity As Integer) As YRETCODE
cs
YRETCODE load(int msValidity)
java
int load(long msValidity)
py
def load(msValidity)

By default, whenever accessing a device, all function attributes are kept in cache for the standard duration (5 ms). This method can be used to temporarily mark the cache as valid for a longer period, in order to reduce network traffic for instance.

Parameters :

msValidityan integer corresponding to the validity attributed to the loaded function parameters, in milliseconds

Returns :

YAPI_SUCCESS when the call succeeds.

On failure, throws an exception or returns a negative error code.

serialport→load_async()serialport.load_async()serialport.load_async()

Preloads the serial port cache with a specified validity duration (asynchronous version).

js
function load_async(msValidity, callback, context)
nodejs
function load_async(msValidity, callback, context)

By default, whenever accessing a device, all function attributes are kept in cache for the standard duration (5 ms). This method can be used to temporarily mark the cache as valid for a longer period, in order to reduce network trafic for instance.

This asynchronous version exists only in Javascript. It uses a callback instead of a return value in order to avoid blocking the Javascript virtual machine.

Parameters :

msValidityan integer corresponding to the validity of the loaded function parameters, in milliseconds
callbackcallback function that is invoked when the result is known. The callback function receives three arguments: the caller-specific context object, the receiving function object and the error code (or YAPI_SUCCESS)
contextcaller-specific object that is passed as-is to the callback function

Returns :

nothing : the result is provided to the callback.

serialport→modbusReadBits()serialport.modbusReadBits()serialport.modbusReadBits()serialport→modbusReadBits()serialport→modbusReadBits()[serialport modbusReadBits: ]serialport.modbusReadBits()serialport.modbusReadBits()serialport.modbusReadBits()serialport.modbusReadBits()serialport.modbusReadBits()YSerialPort modbusReadBits

Reads one or more contiguous internal bits (or coil status) from a MODBUS serial device.

js
function modbusReadBits(slaveNo, pduAddr, nBits)
nodejs
function modbusReadBits(slaveNo, pduAddr, nBits)
php
function modbusReadBits($slaveNo, $pduAddr, $nBits)
cpp
vector<int> modbusReadBits(int slaveNo, int pduAddr, int nBits)
m
-(NSMutableArray*) modbusReadBits: (int) slaveNo : (int) pduAddr : (int) nBits
pas
function modbusReadBits(slaveNo: LongInt,
  pduAddr: LongInt,
  nBits: LongInt): TLongIntArray
vb
function modbusReadBits() As List
cs
List<int> modbusReadBits(int slaveNo, int pduAddr, int nBits)
java
ArrayList<Integer> modbusReadBits(int slaveNo,
  int pduAddr,
  int nBits)
py
def modbusReadBits(slaveNo, pduAddr, nBits)
cmd
YSerialPort target modbusReadBits slaveNo pduAddr nBits

This method uses the MODBUS function code 0x01 (Read Coils).

Parameters :

slaveNothe address of the slave MODBUS device to query
pduAddrthe relative address of the first bit/coil to read (zero-based)
nBitsthe number of bits/coils to read

Returns :

a vector of integers, each corresponding to one bit.

On failure, throws an exception or returns an empty array.

serialport→modbusReadInputBits()serialport.modbusReadInputBits()serialport.modbusReadInputBits()serialport→modbusReadInputBits()serialport→modbusReadInputBits()[serialport modbusReadInputBits: ]serialport.modbusReadInputBits()serialport.modbusReadInputBits()serialport.modbusReadInputBits()serialport.modbusReadInputBits()serialport.modbusReadInputBits()YSerialPort modbusReadInputBits

Reads one or more contiguous input bits (or discrete inputs) from a MODBUS serial device.

js
function modbusReadInputBits(slaveNo, pduAddr, nBits)
nodejs
function modbusReadInputBits(slaveNo, pduAddr, nBits)
php
function modbusReadInputBits($slaveNo, $pduAddr, $nBits)
cpp
vector<int> modbusReadInputBits(int slaveNo, int pduAddr, int nBits)
m
-(NSMutableArray*) modbusReadInputBits: (int) slaveNo
  : (int) pduAddr
  : (int) nBits
pas
function modbusReadInputBits(slaveNo: LongInt,
  pduAddr: LongInt,
  nBits: LongInt): TLongIntArray
vb
function modbusReadInputBits() As List
cs
List<int> modbusReadInputBits(int slaveNo,
  int pduAddr,
  int nBits)
java
ArrayList<Integer> modbusReadInputBits(int slaveNo,
  int pduAddr,
  int nBits)
py
def modbusReadInputBits(slaveNo, pduAddr, nBits)
cmd
YSerialPort target modbusReadInputBits slaveNo pduAddr nBits

This method uses the MODBUS function code 0x02 (Read Discrete Inputs).

Parameters :

slaveNothe address of the slave MODBUS device to query
pduAddrthe relative address of the first bit/input to read (zero-based)
nBitsthe number of bits/inputs to read

Returns :

a vector of integers, each corresponding to one bit.

On failure, throws an exception or returns an empty array.

serialport→modbusReadInputRegisters()serialport.modbusReadInputRegisters()serialport.modbusReadInputRegisters()serialport→modbusReadInputRegisters()serialport→modbusReadInputRegisters()[serialport modbusReadInputRegisters: ]serialport.modbusReadInputRegisters()serialport.modbusReadInputRegisters()serialport.modbusReadInputRegisters()serialport.modbusReadInputRegisters()serialport.modbusReadInputRegisters()YSerialPort modbusReadInputRegisters

Reads one or more contiguous input registers (read-only registers) from a MODBUS serial device.

js
function modbusReadInputRegisters(slaveNo, pduAddr, nWords)
nodejs
function modbusReadInputRegisters(slaveNo, pduAddr, nWords)
php
function modbusReadInputRegisters($slaveNo, $pduAddr, $nWords)
cpp
vector<int> modbusReadInputRegisters(int slaveNo, int pduAddr, int nWords)
m
-(NSMutableArray*) modbusReadInputRegisters: (int) slaveNo
  : (int) pduAddr
  : (int) nWords
pas
function modbusReadInputRegisters(slaveNo: LongInt,
  pduAddr: LongInt,
  nWords: LongInt): TLongIntArray
vb
function modbusReadInputRegisters() As List
cs
List<int> modbusReadInputRegisters(int slaveNo,
  int pduAddr,
  int nWords)
java
ArrayList<Integer> modbusReadInputRegisters(int slaveNo,
  int pduAddr,
  int nWords)
py
def modbusReadInputRegisters(slaveNo, pduAddr, nWords)
cmd
YSerialPort target modbusReadInputRegisters slaveNo pduAddr nWords

This method uses the MODBUS function code 0x04 (Read Input Registers).

Parameters :

slaveNothe address of the slave MODBUS device to query
pduAddrthe relative address of the first input register to read (zero-based)
nWordsthe number of input registers to read

Returns :

a vector of integers, each corresponding to one 16-bit input value.

On failure, throws an exception or returns an empty array.

serialport→modbusReadRegisters()serialport.modbusReadRegisters()serialport.modbusReadRegisters()serialport→modbusReadRegisters()serialport→modbusReadRegisters()[serialport modbusReadRegisters: ]serialport.modbusReadRegisters()serialport.modbusReadRegisters()serialport.modbusReadRegisters()serialport.modbusReadRegisters()serialport.modbusReadRegisters()YSerialPort modbusReadRegisters

Reads one or more contiguous internal registers (holding registers) from a MODBUS serial device.

js
function modbusReadRegisters(slaveNo, pduAddr, nWords)
nodejs
function modbusReadRegisters(slaveNo, pduAddr, nWords)
php
function modbusReadRegisters($slaveNo, $pduAddr, $nWords)
cpp
vector<int> modbusReadRegisters(int slaveNo, int pduAddr, int nWords)
m
-(NSMutableArray*) modbusReadRegisters: (int) slaveNo
  : (int) pduAddr
  : (int) nWords
pas
function modbusReadRegisters(slaveNo: LongInt,
  pduAddr: LongInt,
  nWords: LongInt): TLongIntArray
vb
function modbusReadRegisters() As List
cs
List<int> modbusReadRegisters(int slaveNo,
  int pduAddr,
  int nWords)
java
ArrayList<Integer> modbusReadRegisters(int slaveNo,
  int pduAddr,
  int nWords)
py
def modbusReadRegisters(slaveNo, pduAddr, nWords)
cmd
YSerialPort target modbusReadRegisters slaveNo pduAddr nWords

This method uses the MODBUS function code 0x03 (Read Holding Registers).

Parameters :

slaveNothe address of the slave MODBUS device to query
pduAddrthe relative address of the first holding register to read (zero-based)
nWordsthe number of holding registers to read

Returns :

a vector of integers, each corresponding to one 16-bit register value.

On failure, throws an exception or returns an empty array.

serialport→modbusWriteAndReadRegisters()serialport.modbusWriteAndReadRegisters()serialport.modbusWriteAndReadRegisters()serialport→modbusWriteAndReadRegisters()serialport→modbusWriteAndReadRegisters()[serialport modbusWriteAndReadRegisters: ]serialport.modbusWriteAndReadRegisters()serialport.modbusWriteAndReadRegisters()serialport.modbusWriteAndReadRegisters()serialport.modbusWriteAndReadRegisters()serialport.modbusWriteAndReadRegisters()YSerialPort modbusWriteAndReadRegisters

Sets several contiguous internal registers (holding registers) on a MODBUS serial device, then performs a contiguous read of a set of (possibly different) internal registers.

js
function modbusWriteAndReadRegisters(slaveNo, pduWriteAddr, values, pduReadAddr, nReadWords)
nodejs
function modbusWriteAndReadRegisters(slaveNo, pduWriteAddr, values, pduReadAddr, nReadWords)
php
function modbusWriteAndReadRegisters($slaveNo, $pduWriteAddr, $values, $pduReadAddr, $nReadWords)
cpp
vector<int> modbusWriteAndReadRegisters(int slaveNo,
  int pduWriteAddr,
  vector<int> values,
  int pduReadAddr,
  int nReadWords)
m
-(NSMutableArray*) modbusWriteAndReadRegisters: (int) slaveNo
  : (int) pduWriteAddr
  : (NSMutableArray*) values
  : (int) pduReadAddr
  : (int) nReadWords
pas
function modbusWriteAndReadRegisters(slaveNo: LongInt,
  pduWriteAddr: LongInt,
  values: TLongIntArray,
  pduReadAddr: LongInt,
  nReadWords: LongInt): TLongIntArray
vb
procedure modbusWriteAndReadRegisters()
cs
List<int> modbusWriteAndReadRegisters(int slaveNo,
  int pduWriteAddr,
  List<int> values,
  int pduReadAddr,
  int nReadWords)
java
ArrayList<Integer> modbusWriteAndReadRegisters(int slaveNo,
  int pduWriteAddr,
  ArrayList<Integer> values,
  int pduReadAddr,
  int nReadWords)
py
def modbusWriteAndReadRegisters(slaveNo, pduWriteAddr, values, pduReadAddr, nReadWords)
cmd
YSerialPort target modbusWriteAndReadRegisters slaveNo pduWriteAddr values pduReadAddr nReadWords

This method uses the MODBUS function code 0x17 (Read/Write Multiple Registers).

Parameters :

slaveNothe address of the slave MODBUS device to drive
pduWriteAddrthe relative address of the first internal register to set (zero-based)
valuesthe vector of 16 bit values to set
pduReadAddrthe relative address of the first internal register to read (zero-based)
nReadWordsthe number of 16 bit values to read

Returns :

a vector of integers, each corresponding to one 16-bit register value read.

On failure, throws an exception or returns an empty array.

serialport→modbusWriteBit()serialport.modbusWriteBit()serialport.modbusWriteBit()serialport→modbusWriteBit()serialport→modbusWriteBit()[serialport modbusWriteBit: ]serialport.modbusWriteBit()serialport.modbusWriteBit()serialport.modbusWriteBit()serialport.modbusWriteBit()serialport.modbusWriteBit()YSerialPort modbusWriteBit

Sets a single internal bit (or coil) on a MODBUS serial device.

js
function modbusWriteBit(slaveNo, pduAddr, value)
nodejs
function modbusWriteBit(slaveNo, pduAddr, value)
php
function modbusWriteBit($slaveNo, $pduAddr, $value)
cpp
int modbusWriteBit(int slaveNo, int pduAddr, int value)
m
-(int) modbusWriteBit: (int) slaveNo : (int) pduAddr : (int)