Analog Discovery 2 + LabView Home Bundle - Review

Table of contents

RoadTest: Analog Discovery 2 + LabView Home Bundle

Author: jpnbino

Creation date:

Evaluation Type: Development Boards & Tools

Did you receive all parts the manufacturer stated would be included in the package?: True

What other parts do you consider comparable to this product?: As this product is highly flexible and full of features I chose not to compare to any other tool, because I couldn't find any that has all features or most of them.

What were the biggest problems encountered?:

Detailed Review:

I hope you all enjoy this RoadTest.


For those who enjoy the cutting blade sound I leave hear the unboxing video.



Quick questions

  • Is AD2 suitable for professional use?

Short: Yes, I believe and do.   

Long: In the last project in the company I was writing code to interface with sensors ( I2C, UART, SPI) and I used AD2 for this. Since the limitations of AD2 are within your need there is space for you to use it.

  • I am a newbie, Does it suits me?

Short: Yes, it’s perfect for you.

         Long: AD2 by concept was designed to be an educational tool targeting hobbyist, students, and enthusiasts. The tool is quite straightforward to use, requiring only you to download the Waveforms IDE and take the Tutorial Videos that cover ALL you need.


Getting started with LabView


As a fast way to learn about AD2 and LabView integration, I certainly would suggest trying first the watch tutorials of each program separately in case you are completely fresh to one or both of them. This would give a good understanding of the capability of each tool and moreover I didn’t find a material like getting started with both at the same time, but some blog posts. Actually, I tried to run the examples of integration that come installed with LabView, but even though I could run them and see the results, at first, I had no idea what was going on since I never touched it LabView before. Then, I came back to the examples after this tutorial.


LabView2014 can be downloaded through LabView Maker Hub website as a 45-Day evaluation, but after installation just enter the serial number for the home bundle. After that, I also installed the AD2 driver for Labview so that LabView communicates with AD2. After this, I had my LabView recognizing my AD2.

Running Example

  One important feature to note in LabView is that it works within two complementaries interfaces: Front Panel and Block Diagram. In the first, the user can see the graphical results of it’s work and in the second, the program ( which is fundamentally in block ). In the following video, I run an example that comes already installed in the installation directory.




In the video I showed only the front panel, therefore here goes the Block Diagram related to the example.

Block Diagram for Power Supply instrument

The instruments AD2 in LabView

       As in the previous video, I only ran the example and now I show what is behind the user interface used, what does the LabView program look like.


Resources about integration

There are some interesting resources to check which


In the second part of my roadtest, I go over the Waveforms software and develop a simple project in order to explore some AD2 capabilities.



  The goal of this short project is to record the light intensity in my room through the window. For that, will be used a Flora board, which has a TSL2561 light sensor, and an AD2 as a controller.



  In order to read the luminosity of the environment, a Flora is attached to the AD2 which reads out the I2C signals from the sensor and then through an algorithm parses the data received into the lux unit. After that, the data parsed is logged into a CSV file and then plotted into a graphic.


The light sensor

  The TSL2561 is a light-to-digital converter with I2C output. It reads the light intensity from the environment through two diodes, one sensible to visible light and infrared, and other sensible only to infrared allowing to remove the effect of the infrared in the measurement according to an experimental algorithm. The diodes signals are converted into the digital domain and made available to be read from the I2C bus. Figure 1 shows a block diagram of the sensor.


Figure 1: TSL2561 overview

Setting up the environment

  Figure 2 shows the Flora board used in this project. Header pins were soldered in order to make the pins more accessible.

Figure 2: Flora board with header pins soldered

  Then, the AD2 was connected according to Table 1. And the result is shown in Figure  3:


Table 1 - Connection map between AD2 and Flora.


AD2Flora Board

Figure 3: Connection between Flora board and AD2


Reading from I2C

  As a first step, I used the tool Protocol I2C in the Waveforms Software to test communication between Flora board and AD2.

Power from AD2

  As for this project, I’ll be using AD2 to deliver power to the Flora board, the positive power supply (in supplies instrument) must be turned on at 3 Volts as shown in Figure 4.


Figure 4: Supplies instrument in Waveforms


Internal sensor power-on

After powering up, Flora should be ready to exchange data. Then, it’s time to open the protocol instrument in the tab I2C ( in master mode ) and configure the communication channel. Figure 5 shows in red the configuration used. The Address value h39 corresponds to the 7bit address of the TSL2561 sensor according to its datasheet as shown in Figure 6 when the address pin is left floating which happens in Flora by default.

Figure 5: Protocol instrument - Master I2C


Figure 6: TSL2561 datasheet slave address info


Once the communication is properly set, a command 03h to the CONTROL register of the sensor must be sent to the sensor in order to power it up internally. It happens that TSL2561 has only one register (Figure 7)  for both address(lower nibble) and control( upper nibble), then Control Register is accessible as address 80h  for the configuration I’m using. The complete addresses available can be seen in Figure 8.

Figure 7: COMMAND register description


Figure 8: TSL2561 register address


  Therefore, in Protocol instrument, fulfill the fields SubAddress with 0x80 and the Write field with 0x03. After clicking write, the interface should look like Figure 9. It’s important to note that the ACK bit is omitted.


Figure 9:  Power-on sent to CONTROL register

  Now, that the sensor was acknowledged the next step is to read the registers that contain the digital values converted correspondents to the ambient light measured, namely Ch and Dh as Channel0, and Eh and Fh as Channel1. This can be accomplished by reading 4bytes in sequence starting from register Ch.


Therefore, fill the SubAddress with 0x8Ch and the field Bytes with 4 and then click Read. The resultant data stream should be like Figure 10. Note that, the data will differ as a consequence of different ambient illumination.


Figure 10: Reading 4 bytes from sensor

Logging the data

Up to now, the following tasks were accomplished:

  1. Power the sensor from AD2;
  2. AD2 through I2C Bus can properly send and receive data from the sensor.

     Then, the next step is to convert the data read from the sensor into luminosity intensity (lux) and record this data into a file. In order to achieve that, create a script is necessary. 
     Still, in the Protocol Instrument under the tab Sensor (Figure 11), scripts can be written in javascript and then run through the button ‘Execute’. There are also short instructions on how to use it. Even easier is to open an example under the tab Example and see how to interact with AD2. And based on the second option a script was written to fulfill the last project requirements.
Figure 11 - Script editor

Testing the Script

In order to test the script ( attached ) written, a test was set at 50 iterations and Rate at 1Hz ( see Figure 12). The test consists in approximate a light source to the tsl2561 sensor and leaves the script running in the meantime, the values measured are recorded in a CSV file and then imported into Excel and plotted into a graph for ease visual analyses.

Figure 12 - Configuration for script test

The video below shows how the test was executed. Table 2 (in attachment)shows the data generated by the script and Figure 13 shows the graphic plotted from it. The Orange line DATA0 represents the value of the registers Ch and Dh (Channel0), the Grey line DATA1 represents the value of the registers Eh and Fh (Channel1). Both DATA0 and DATA1 represent a 16-bit wide register. Finally, the blue line represents the calculated value of luminosity in the lux unit.


Figure 13: Graphic plotted from the data generated


     Also, in order to bring confidence to the experiment, a measurement with an MT-912 Lux Meter was performed and compared to the values obtained from the script. The results are shown in Figure 14 and Figure15, where Flora measured 77lux and the equipment measured 76,8 lux.

Figure 14: Test measurement for comparing with MT-912 Lux Meter.

Figure 15: Measurement set with MT-912 and Flora.

Logging Sunlight data

  Finally, to obtain data about the light coming from the sun to my room, a setup was made as in Figure 16. The sensor was pointed to outside from close to the window. Then, data was recorded (Table 3 attached ) during about 26 hours and the graphic was plotted in Figure 17.

Figure 16:  Setup for Sunlight measurement

Figure 17: Data plot representing luminosity intensity in the room

     As expected, during the day the light is more intense and in the morning even more, because my windows take the sun rising. Also, around 6:40 am to 9:30 am the sunlight intensity in my room was high enough to saturate the sensor which is represented by the flat part in the orange curve in this interval. After that, the light level is lower which represents that my room is not having direct light from the sun maybe due to clouds, obstacles or even its position. At night from 9:30 pm, as it is supposed to happen, the light level tends to zero.

Project Closing

All goals for this project were successfully accomplished. The results obtained in the form of plots from the measurements look already intuitive for a first sight evaluation and this analysis was possible due to the possibility of exporting data easily with javascript. Also, the project proved that tsl2561 sensor is only suitable for indoor application due to its saturation point.

Considerations on the use of Waveforms

  During the project execution, some features were missing or could be improved and some observations were found, then in this section they are described.

Running Script

  • As a long running of the script was needed ( around 26 hours ), some issues were found. The first issue is that the script doesn't run in the background (Figure 18), because of that if one needs the screen for another task, has to use with the scripting window popped up.

  Figure 18: Executing the Script window popped up


  • The second observation is related to the consumption of the CPU. During the script execution, the process was taking 35% of the CPU ( Core i5, 7th gen ), see figure 19.

Figure 19: CPU consumption while running Script



  • Another observation to point out is that while the script is running only the button Cancel is possible and if one is recording data and click, then all data already recorded is lost. I would suggest an option to jump to the function finish(), see Figure 20.

Figure 20: Main functions in sensor script

  • At last, every time a script is saved, it is saved as a new file and there no autosave or prompt to save alterations and as a consequence, if the code is not continuously saved, then it is lost.





  • I came to check and realized that the script was not appended anymore.

    // TSL2561 Sensor application
    Description: Reads out data from the TSL2561 sensor through I2C Bus. The
    values read from the sensor are then converted into light intensity unit
    ( lux ) and logs this value into a csv file.
    Note: The algorithm to convert digital values into 'lux' unit is based on
    the TSL2561 datasheet(
    from page 23
    Enviroment: Waveforms 3.10.9
    The constants are provided by the datasheet. 
    These constant apply only for T, FN and CL Package
    const LUX_SCALE = 14 // scale by 2^14
    const RATIO_SCALE = 9 // scale ratio by 2^9
    // Integration time scaling factors
    const CH_SCALE = 10 // scale channel values by 2^10
    const CHSCALE_TINT0 = 0x7517 // 322/11 * 2^CH_SCALE
    const CHSCALE_TINT1 = 0x0fe7 // 322/81 * 2^CH_SCALE
    const K1T = 0x0040 // 0.125 * 2^RATIO_SCALE
    const B1T = 0x01f2 // 0.0304 * 2^LUX_SCALE
    const M1T = 0x01be // 0.0272 * 2^LUX_SCALE
    const K2T = 0x0080 // 0.250 * 2^RATIO_SCALE
    const B2T = 0x0214 // 0.0325 * 2^LUX_SCALE
    const M2T = 0x02d1 // 0.0440 * 2^LUX_SCALE
    const K3T = 0x00c0 // 0.375 * 2^RATIO_SCALE
    const B3T = 0x023f // 0.0351 * 2^LUX_SCALE
    const M3T = 0x037b // 0.0544 * 2^LUX_SCALE
    const K4T = 0x0100 // 0.50 * 2^RATIO_SCALE
    const B4T = 0x0270 // 0.0381 * 2^LUX_SCALE
    const M4T = 0x03fe // 0.0624 * 2^LUX_SCALE
    const K5T = 0x0138 // 0.61 * 2^RATIO_SCALE
    const B5T = 0x016f // 0.0224 * 2^LUX_SCALE
    const M5T = 0x01fc // 0.0310 * 2^LUX_SCALE
    const K6T = 0x019a // 0.80 	* 2^RATIO_SCALE
    const B6T = 0x00d2 // 0.0128 * 2^LUX_SCALE
    const M6T = 0x00fb // 0.0153 * 2^LUX_SCALE
    const K7T = 0x029a // 1.3 * 2^RATIO_SCALE
    const B7T = 0x0018 // 0.00146 * 2^LUX_SCALE
    const M7T = 0x0012 // 0.00112 * 2^LUX_SCALE
    const K8T = 0x029a // 1.3 * 2^RATIO_SCALE
    const B8T = 0x0000 // 0.000 * 2^LUX_SCALE
    const M8T = 0x0000 // 0.000 * 2^LUX_SCALE
    const tsl2561_address = 0x39;
    /*  Initializes variables with a value out of range of the
    sensor to make an error easier to spot.*/
    //  visible + IR values ( CHANNEL0 )
    var DATA0_REG = 777777; 
    //  IR value only ( CHANNEL1 )
    var DATA1_REG =  777777; 
    // Calculated lux value
    var lux = 777777;   
    function initialize(){
        //Clear() returns True if the bus is free
        if(Clear()!=true) return "I2C bus error. Check the pull-ups.";
        //POWER TSL2561 on
        if(!Write(tsl2561_address, 0x80, 0x03)) return "Communication error."; 
        /*wait for 500ms, because the sensor takes 412ms to make a complete
    	measurement of the environment light 
        // write file header
        if(!FileWriteLine("~/Desktop/default.csv", ["LUX","DATA0", "DATA1"])) return "File write failed";
        return true;
    // Converts the values in channel0 and channel1 to lux measurement
    // Function full description can be found in the datasheet.
    function CalculateLux(gain, int_time, ch0, ch1, type)
    var chScale;
    var channel1;
    var channel0;
    var ratio1 = 0;
    var ratio;
    //auxiliar variables
    var b, m;
    //Auxiliary variable
    var temp;
    //Holds the lux value
    var lux;
    chScale = (1 << CH_SCALE);
    // scale if gain is NOT 16X
    if (!gain) 
    	chScale = chScale << 4; // scale 1X to 16X
    // scale the channel values
    channel0 = (ch0 * chScale) >> CH_SCALE;
    channel1 = (ch1 * chScale) >> CH_SCALE;
    // find the ratio of the channel values (Channel1/Channel0)
    // protect against divide by zero
    if (channel0 != 0) 
    		ratio1 = (channel1 << (RATIO_SCALE+1)) / channel0;
    // round the ratio value
    ratio = (ratio1 + 1) >> 1;
     // T, FN and CL package
    if ((ratio >= 0) && (ratio <= K1T))
    {b=B1T; m=M1T;}
    else if (ratio <= K2T)
    {b=B2T; m=M2T;}
    else if (ratio <= K3T)
    {b=B3T; m=M3T;}
    else if (ratio <= K4T)
    {b=B4T; m=M4T;}
    else if (ratio <= K5T)
    {b=B5T; m=M5T;}
    else if (ratio <= K6T)
    {b=B6T; m=M6T;}
    else if (ratio <= K7T)
    {b=B7T; m=M7T;}
    else if (ratio > K8T)
    {b=B8T; m=M8T;}
    temp = ((channel0 * b) - (channel1 * m));
    // do not allow negative lux value
    if (temp < 0) temp = 0;
    // round lsb (2^(LUX_SCALE?1))
    temp += (1 << (LUX_SCALE - 1));
    // strip off fractional portion
    lux = temp >> LUX_SCALE;
    function loop(){
    	//holds the data from registers Ch to Fh read from tsl2561
        var data;  
    	//Reads out 4 bytes in sequence from the I2C line
        data = Read(tsl2561_address, [0xAC], 4);
    	// Extracts the  DATA0LOW and DATA0HIGH registers values from data 
        DATA0_REG  =   (( data[1] << 8 ) + ( data[0] ));
    	// Extracts the  DATA1LOW and DATA1HIGH registers values from data 
        DATA1_REG  =   (( data[3] << 8 ) + ( data[2] ));
    	//Converts the values read from the 
        lux = CalculateLux( 0,2,DATA0_REG, DATA1_REG, 0);
        //Add the register values and the calculated lux value to the csv file
        if(!FileAppendLine("~/Desktop/default.csv", [lux, DATA0_REG, DATA1_REG ])){
            return "File write failed";
        return true;
    function finish(){
    	//Ends the script.
        return "Lux value calculated   "+lux+"[Lux]"+";   DATA0_REG = "+ DATA0_REG+";  DATA1_REG = "+DATA1_REG+";";