{"id":29242,"date":"2022-07-21T09:29:26","date_gmt":"2022-07-21T16:29:26","guid":{"rendered":"https:\/\/digilent.com\/blog\/?p=29242"},"modified":"2026-09-09T19:46:57","modified_gmt":"2026-09-10T02:46:57","slug":"build-a-smart-lamp-using-an-analog-discovery-pro-adp3450-part-2","status":"publish","type":"post","link":"https:\/\/digilent.com\/blog\/build-a-smart-lamp-using-an-analog-discovery-pro-adp3450-part-2\/","title":{"rendered":"Build a Smart Lamp Using an Analog Discovery Pro ADP3450"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">This project designs a smart RGB lamp which is powered by a battery and controlled through an app running on a smartphone. The lamp and smartphone communicate through Bluetooth Low Energy (BLE). Besides setting the luminosity and the color of the LED, the system also measures the ambient lighting, so users can switch off the light once it is no longer needed. Or do that even automatically, if needed.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Digilent&#8217;s Analog Discovery Pro <\/span><a href=\"https:\/\/digilent.com\/reference\/test-and-measurement\/analog-discovery-pro-3x50\/start\"><span style=\"font-weight: 400;\">ADP3450<\/span><\/a><span style=\"font-weight: 400;\"> running in Linux Mode is at the heart of the system: it collects the data from a <\/span><a href=\"https:\/\/digilent.com\/reference\/pmod\/pmodals\/start\"><span style=\"font-weight: 400;\">Pmod ALS<\/span><\/a><span style=\"font-weight: 400;\"> ambient light sensor and receives the settings from the smartphone&#8217;s app through a <\/span><a href=\"https:\/\/digilent.com\/reference\/pmod\/pmodble\/start\"><span style=\"font-weight: 400;\">Pmod BLE<\/span><\/a><span style=\"font-weight: 400;\">. It also applies the brightness and color of the LED based on these data sets or switches the on\/off state.<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/06\/smartlamp1-600x331.jpg\" alt=\"\" width=\"600\" height=\"331\" class=\"aligncenter size-medium wp-image-29229\" data-wp-pid=\"29229\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/06\/smartlamp1-600x331.jpg 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/06\/smartlamp1-1024x565.jpg 1024w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/06\/smartlamp1-1536x847.jpg 1536w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/06\/smartlamp1.jpg 1920w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/span><\/p>\n<h2><b>Getting a HAL for the Analog Discovery Pro<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">In our project, we control the Analog Discovery Pro (ADP) through the <\/span><a href=\"https:\/\/digilent.com\/reference\/software\/waveforms\/waveforms-sdk\/start\"><span style=\"font-weight: 400;\">WaveForms SDK<\/span><\/a><span style=\"font-weight: 400;\"> with a Python script. For this, we need several functions for each of the instruments, like read, write, initialization, and control functions. Communication over SPI (Serial Peripheral Interface) and UART (Universal Asynchronous Receiver-Transmitter) is also necessary. This means that we require some sort of abstraction to simplify the interaction with the hardware: a Hardware Abstraction Layer (HAL).<\/span><\/p>\n<p><span style=\"font-weight: 400;\">There are two ways to get the HAL functions for our project: One way is that you follow the directions given in the Getting Started with WaveForms SDK guide. The other way is that you download them from <\/span><a href=\"https:\/\/github.com\/Digilent\/WaveForms-SDK-Getting-Started-PY\/tree\/master\/WF_SDK\"><span style=\"font-weight: 400;\">Digilent&#8217;s GitHub repository<\/span><\/a><span style=\"font-weight: 400;\">. There, you will also find a list of the functionality each module provides and a couple of test routines.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Once you have created or downloaded the HAL functions for the SDK, create a new folder and copy the files into it. Also, duplicate the file dwfconstants.py from the Python examples folder of your WaveForms installation into the new directory. The default installation path is <\/span><span style=\"font-weight: 400;\">C:\\Program Files (x86)\\Digilent\\WaveFormsSDK\\samples\\py\\dwfconstants.py<\/span><span style=\"font-weight: 400;\">. This file contains all the constants used by the SDK.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">By running an app on your smartphone, you can set the brightness and the color of the LED, or turn it off. The core of the system is an <\/span><a href=\"https:\/\/digilent.com\/shop\/analog-discovery-pro-3000-series-portable-high-resolution-mixed-signal-oscilloscopes\/\"><span style=\"font-weight: 400;\">Analog Discovery Pro ADP3450<\/span><\/a><span style=\"font-weight: 400;\">, working in Linux Mode. It receives the settings from the smartphone&#8217;s app through a Pmod BLE, as well as the intensity of the ambient light, which is measured by a Pmod ALS light sensor.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Now we design the software modules for the Pmods. We will do this similarly to before, but this time the code we create will target the two Pmods we use for our project, and not the ADP3450 itself.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The <\/span><a href=\"https:\/\/digilent.com\/shop\/pmod-ble-bluetooth-low-energy-interface\/\"><span style=\"font-weight: 400;\">Pmod BLE<\/span><\/a><span style=\"font-weight: 400;\"> uses a UART for communication, and as we want to avoid an interruption of the PWM connected to the LED, we are going to implement it in two ways: the first one uses the UART instrument of Waveforms for sending and receiving data, and the other one employs the logic analyzer and the pattern generator.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">SPI is used to receive data from the <\/span><a href=\"https:\/\/digilent.com\/shop\/pmod-als-ambient-light-sensor\/\"><span style=\"font-weight: 400;\">Pmod ALS<\/span><\/a><span style=\"font-weight: 400;\">, and we use the Protocol Analyzer in WaveForms for that. As we will also need some I\/O functionality, the Static I\/O instrument is helpful.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Of course, you could write all the functions yourself, but it might be easier to download the module for the <\/span><a href=\"https:\/\/digilent.com\/reference\/_media\/test-and-measurement\/analog-discovery-pro-3x50\/pmod_ble.zip\"><span style=\"font-weight: 400;\">Pmod BLE from here<\/span><\/a><span style=\"font-weight: 400;\"> and the one for the <\/span><a href=\"https:\/\/digilent.com\/reference\/_media\/test-and-measurement\/analog-discovery-pro-3x50\/pmod_als.zip#-1\"><span style=\"font-weight: 400;\">Pmod ALS from here<\/span><\/a><span style=\"font-weight: 400;\">. These Python scripts contain all the routines for our project, like open(), read(), or close() routines. It is worth noting that not all the functionality in these programs was tested, so there might be errors. Use them at your own risk.<\/span><\/p>\n<h2><b>Making Sure the Pmods Work<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Before we can test the functionality of our Pmod, we need to connect them to the digital lines of the ADP3450. First, connect the Pmod ALS. Have a look at the test code to the right: it lists pin assignments. Link the CS pin of the Pmod to digital line 8 of the ADP3450, the SDO pin to line 9, and the SCK pin to line 10. Moreover, connect VCC to VIO and the ground lines.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Finally, copy the code to a file in your working directory. Run the script and point a flashlight to the sensor on the Pmod. The intensity level should change.<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">To test the Pmod ALS, the ambient light intensity is read and displayed continuously.<\/span><\/i><\/p>\n<blockquote><p><span style=\"font-weight: 400;\"># import modules<\/span><\/p>\n<p><span style=\"font-weight: 400;\">import Pmod_ALS as als<\/span><\/p>\n<p><span style=\"font-weight: 400;\">import WF_SDK as wf\u00a0 # import WaveForms instruments<\/span><\/p>\n<p><span style=\"font-weight: 400;\">from time import sleep<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\"># define pins<\/span><\/p>\n<p><span style=\"font-weight: 400;\">als.pins.cs = 8<\/span><\/p>\n<p><span style=\"font-weight: 400;\">als.pins.sdo = 9<\/span><\/p>\n<p><span style=\"font-weight: 400;\">als.pins.sck = 10<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">try:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0# initialize the interface<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0device_data = wf.device.open()<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0# check for connection errors<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0wf.device.check_error(device_data)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0als.open()<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0while True:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0# display measurements<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0light = als.read_percent(rx_mode=&#8221;static&#8221;, reopen=True)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print(&#8220;static: &#8221; + str(light) + &#8220;%&#8221;)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0light = als.read_percent(rx_mode=&#8221;spi&#8221;, reopen=True)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print(&#8220;spi: &#8221; + str(light) + &#8220;%&#8221;)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0sleep(0.5)<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">except KeyboardInterrupt:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0pass<\/span><\/p>\n<p><span style=\"font-weight: 400;\">finally:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0# close the device<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0als.close(reset=True)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0wf.device.close(device_data)<\/span><\/p>\n<p>&nbsp;<\/p><\/blockquote>\n<p><span style=\"font-weight: 400;\">Repeat the same exercise for the Pmod BLE. Again, the test script lists the connections. Copy the file to your hard drive as well and run it.<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">To test the Pmod BLE, all messages received on Bluetooth are displayed, the string &#8220;ok&#8221; is sent as a response.<\/span><\/i><\/p>\n<blockquote><p><span style=\"font-weight: 400;\"># import modules<\/span><\/p>\n<p><span style=\"font-weight: 400;\">import Pmod_BLE as ble<\/span><\/p>\n<p><span style=\"font-weight: 400;\">import WF_SDK as wf\u00a0 # import WaveForms instruments<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\"># define pins<\/span><\/p>\n<p><span style=\"font-weight: 400;\">ble.pins.tx = 4<\/span><\/p>\n<p><span style=\"font-weight: 400;\">ble.pins.rx = 3<\/span><\/p>\n<p><span style=\"font-weight: 400;\">ble.pins.rst = 5<\/span><\/p>\n<p><span style=\"font-weight: 400;\">ble.pins.status = 6<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\"># turn on messages<\/span><\/p>\n<p><span style=\"font-weight: 400;\">ble.settings.DEBUG = True<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">try:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0# initialize the interface<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0device_data = wf.device.open()<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0# check for connection errors<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0wf.device.check_error(device_data)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0ble.open()<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0ble.reset(rx_mode=&#8221;uart&#8221;, tx_mode=&#8221;uart&#8221;, reopen=True)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0ble.reboot()<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0while True:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0# check connection status<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if ble.get_status():<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0# receive data<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0data, sys_msg, error = ble.read(blocking=True, rx_mode=&#8221;logic&#8221;, reopen=False)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0# display data and system messages<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if data != &#8220;&#8221;:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print(&#8220;data: &#8221; + data)\u00a0 # display it<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ble.write_data(&#8220;ok&#8221;, tx_mode=&#8221;pattern&#8221;, reopen=False)\u00a0 # and send response<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0elif sys_msg != &#8220;&#8221;:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print(&#8220;system: &#8221; + sys_msg)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0elif error != &#8220;&#8221;:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print(&#8220;error: &#8221; + error)\u00a0 # display the error<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">except KeyboardInterrupt:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0pass<\/span><\/p>\n<p><span style=\"font-weight: 400;\">finally:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0# close the device<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0ble.close(reset=True)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0wf.device.close(device_data)<\/span><\/p>\n<p>&nbsp;<\/p><\/blockquote>\n<p><span style=\"font-weight: 400;\">In addition, download the <\/span><a href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.macdom.ble.blescanner&amp;_ga=2.112624192.574416802.1658216205-1945391217.1658216205\"><span style=\"font-weight: 400;\">BLE Scanner<\/span><\/a><span style=\"font-weight: 400;\"> application to your phone and start it. Turn on Bluetooth, if it is not already running, as well as location. The app should display the Pmod BLE after some time. Connect to it and jot down the long code (MAC address) below the device&#8217;s name. You will need it later.<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/07\/Figure-1-Connecting-the-BLE-Scanner-337x600.jpg\" alt=\"\" width=\"337\" height=\"600\" class=\"aligncenter size-medium wp-image-29245\" data-wp-pid=\"29245\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/07\/Figure-1-Connecting-the-BLE-Scanner-337x600.jpg 337w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/07\/Figure-1-Connecting-the-BLE-Scanner.jpg 393w\" sizes=\"auto, (max-width: 337px) 100vw, 337px\" \/><\/span><\/p>\n<p><span style=\"font-weight: 400;\">Open the Custom Service dialog and hit the &#8220;N&#8221; (notify) icon, and some system messages should show in the terminal of the test script. The &#8220;Got it&#8221; string should appear on the custom characteristic screen of the app. Now tap &#8220;W&#8221; and type in your text. Write down the value for the UUID and the characteristic. As before, you will need them later.<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/07\/Figure-2-Configuring-the-BLE-Scanner-337x600.jpg\" alt=\"\" width=\"337\" height=\"600\" class=\"aligncenter size-medium wp-image-29246\" data-wp-pid=\"29246\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/07\/Figure-2-Configuring-the-BLE-Scanner-337x600.jpg 337w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/07\/Figure-2-Configuring-the-BLE-Scanner.jpg 393w\" sizes=\"auto, (max-width: 337px) 100vw, 337px\" \/><\/span><\/p>\n<p><span style=\"font-weight: 400;\">With the Pmods tested, the next stage is creating the Android app, followed by the LED driver and battery charging circuitry.<\/span><\/p>\n<h2><b>Designing the Android App<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">For the smartphone app, we use the <\/span><a href=\"https:\/\/appinventor.mit.edu\/\"><span style=\"font-weight: 400;\">MIT App Inventor<\/span><\/a><span style=\"font-weight: 400;\">. You will need a Google account to log in. If you don&#8217;t have one or if you would rather not use it for this exercise, <\/span><a href=\"http:\/\/code.appinventor.mit.edu\/\"><span style=\"font-weight: 400;\">you can access it anonymously from this page<\/span><\/a><span style=\"font-weight: 400;\">. Make a note of the re-enter code displayed, so you can continue your work at a later stage.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The first step is to create the user interface. You can do that from scratch, but you can also download our <\/span><a href=\"https:\/\/digilent.com\/reference\/_media\/test-and-measurement\/analog-discovery-pro-3x50\/digilent_lamp_controller_project.zip\"><span style=\"font-weight: 400;\">pre-built project file<\/span><\/a><span style=\"font-weight: 400;\"> and import it. If you want to avoid bothering with the creation of the app at all, you can also <\/span><a href=\"https:\/\/digilent.com\/reference\/_media\/test-and-measurement\/analog-discovery-pro-3x50\/digilent_lamp_controller_apk.zip\"><span style=\"font-weight: 400;\">download and install the final application<\/span><\/a><span style=\"font-weight: 400;\">. As a shortcut, scan the QR code below with your phone.<\/span><\/p>\n<p><span style=\"font-weight: 400;\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.digilent.com\/blog\/wp-content\/uploads\/2022\/08\/Virtual-Phone.png\" alt=\"\" width=\"1500\" height=\"790\" class=\"aligncenter size-full wp-image-29331\" data-wp-pid=\"29331\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/08\/Virtual-Phone.png 1500w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/08\/Virtual-Phone-600x316.png 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/08\/Virtual-Phone-1024x539.png 1024w\" sizes=\"auto, (max-width: 1500px) 100vw, 1500px\" \/><\/span><\/p>\n<p><span style=\"font-weight: 400;\">Our application needs two switches for turning the lamp on and off, and setting the intensity to auto. It also requires three sliders for the three colors red, green, and blue. Done with that, go to the Extension menu on the left and place the Bluetooth LE component on the screen of your virtual phone.<\/span><\/p>\n<p><span style=\"font-weight: 400;\"> <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.digilent.com\/blog\/wp-content\/uploads\/2022\/08\/31.png\" alt=\"\" width=\"1500\" height=\"791\" class=\"aligncenter size-full wp-image-29330\" data-wp-pid=\"29330\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/08\/31.png 1500w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/08\/31-600x316.png 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/08\/31-1024x540.png 1024w\" sizes=\"auto, (max-width: 1500px) 100vw, 1500px\" \/><\/span><\/p>\n<p><span style=\"font-weight: 400;\">Now enter the Blocks view and create the logic behind your user interface elements and the non-visible components. Here, you define what happens once you interact with the screen and the different parts on it, like sliders, buttons, or labels. Also, think about what actions should take place when Bluetooth connects or disconnects, receives a message, or sends a message to the Pmod BLE.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Give a thought to the format you want to send the data in. Also review the data formats of the Pmods and how you intend to interpret them.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">If asked for the MAC address for the Pmod BLE, the service UUID, and the Characteristic UUID, refer to your notes from the section above. There, you jotted them down.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">If you believe you are all set, build the application and install it on your phone. Remember that it must allow installations from unknown sources.<\/span><\/p>\n<h2><b>Designing the LED Driver Circuit<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Now it is time to design and assemble the LED driver. Here, to achieve linear brightness changes, you will need to control the current through the LED; just controlling the voltage is not sufficient. The ADP3450 does not feature a current supply, so you will have to design a voltage-controlled current sink for each of the LED&#8217;s colors.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The various voltages are created through PWM signals on the digital lines of the ADP3450, which you should connect to a low-pass filter. Have a look at the schematic below. Calculate the power dissipation and choose an adequate resistor. Finally, attach everything to the battery as shown.<\/span><\/p>\n<h2><b>Building the Charger Circuit<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">As a last step, create the charger circuit for the lithium-polymer battery cell. Use an <\/span><a href=\"https:\/\/www.analog.com\/media\/en\/technical-documentation\/data-sheets\/lt3092.pdf\"><span style=\"font-weight: 400;\">LT 3092 <\/span><\/a><span style=\"font-weight: 400;\">programmable current source from Analog Devices for that and connect it with a USB-A plug to one of the USB ports at the back of the ADP3450. These provide enough power for charging the battery. Refer to the schematic below for details.<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.digilent.com\/blog\/wp-content\/uploads\/2022\/08\/Battery-Charger.jpg\" alt=\"\" width=\"426\" height=\"230\" class=\"aligncenter size-full wp-image-29332\" data-wp-pid=\"29332\" \/><\/span><\/p>\n<p><span style=\"font-weight: 400;\">Now we are going to create the main script containing the application running on the Analog Discovery Pro ADP3450 from Digilent, working in Linux Mode. Once everything is complete, you will be able to adjust the luminosity and color of the LED through your phone&#8217;s app.<\/span><\/p>\n<h2><b>Bringing the Software Together<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">As before, you can either write the application from scratch following the guidelines below, or you can <\/span><a href=\"https:\/\/digilent.com\/reference\/_media\/test-and-measurement\/analog-discovery-pro-3x50\/lamp_controller.zip\"><span style=\"font-weight: 400;\">download it from here<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">First, import all the modules you created during the previous parts of this blog series. Then define the constants needed and develop some helper functions, like one for decoding the incoming Bluetooth data. These functions make your life easier later on.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Once done, write the body of your program. For our solution, we used a try-except structure, but how you implement it is really up to you. Start with the initialization of the WaveForms instruments and the Pmods. Then move on and create an endless loop through a &#8220;while True&#8221; statement. Inside the loop, look for data packets received by the Pmod BLE and decode them. Query the ambient light brightness measured by the Pmod ALS as well. Eventually, you might want to read the voltage level of the battery and transmit it via Bluetooth to your smartphone.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">At the end, you will need to provide code that allows you to exit your program gracefully. Define an event you want to react to, e.g., pressing &#8220;Ctrl+C&#8221;, and include statements that turn off the lamp and close and reset the WaveForms instruments.<\/span><\/p>\n<h2><b>Putting the ADP3450 in Linux Mode<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Before you can run your script, you will need to put the Analog Discovery Pro ADP3450 in Linux Mode. For this, follow the steps detailed in the guide &#8220;Getting Started in Linux Mode with the Analog Discovery Pro (ADP3450\/ADP3250)&#8221;. When finished, follow the instructions in the guide &#8220;Connecting the Analog Discovery Pro (ADP3450\/ADP3250) to the Internet&#8221;. This will allow you to install the Python package installer (pip) directly on the mixed signal oscilloscope (MSO) using the command below:<\/span><\/p>\n<blockquote><p><span style=\"font-weight: 400;\">sudo apt install python3-pip<\/span><\/p><\/blockquote>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">Next, copy the HAL files you created for the WaveForms instruments earlier to your directory on the ADP3450. Before you can run the script, you have to execute the commands below from your terminal:<\/span><\/p>\n<blockquote><p><span style=\"font-weight: 400;\">sudo su<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cd \/etc\/systemd\/system<\/span><\/p>\n<p><span style=\"font-weight: 400;\">echo -n &#8220;&#8221; &gt; lamp.service<\/span><\/p>\n<p><span style=\"font-weight: 400;\">nano lamp.service<\/span><\/p><\/blockquote>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">Now type the following text in your editor, but change the path according to your setup. Then save the file.<\/span><\/p>\n<blockquote><p><span style=\"font-weight: 400;\">[Unit]<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Description=Smart Lamp Controller<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">[Service]<\/span><\/p>\n<p><span style=\"font-weight: 400;\">ExecStart=nohup python3 \/home\/digilent\/Smart-Lamp-Controller\/Python\/Lamp_Controller.py &amp;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">[Install]<\/span><\/p>\n<p><span style=\"font-weight: 400;\">WantedBy=multi-user.target<\/span><\/p><\/blockquote>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">And finally, enable the new service and reboot the MSO:<\/span><\/p>\n<blockquote><p><span style=\"font-weight: 400;\">systemctl start lamp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">systemctl enable lamp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">reboot<\/span><\/p><\/blockquote>\n<p>&nbsp;<\/p>\n<h2><b>Running the Script<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Once the ADP3450 has booted, start the script as well as the app you created on your smartphone. Wait until the phone detects the Pmod BLE, connect to it, and start playing with your sliders and switches in your app.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">If you want to make any changes to your script, you will need to stop it by pressing your key combination, make your changes, and restart it. Enjoy your smart lamp!<\/span><\/p>\n<p><span style=\"font-weight: 400;\">A more detailed description of this project is available here (Digilent&#8217;s reference guide: &#8220;Building a Battery-Powered Smart Lamp with the Analog Discovery Pro&#8221;).<\/span><\/p>\n<div class='watch-action'><div class='watch-position align-left'><div class='action-like'><a class='lbg-style6 like-29242 jlk' data-task='like' data-post_id='29242' data-nonce='bcaa7f4193' rel='nofollow'><img src='https:\/\/digilent.com\/blog\/wp-content\/plugins\/wti-like-post-pro\/images\/pixel.gif' title='Like' \/><span class='lc-29242 lc'>0<\/span><\/a><\/div><div class='action-unlike'><a class='unlbg-style6 unlike-29242 jlk' data-task='unlike' data-post_id='29242' data-nonce='bcaa7f4193' rel='nofollow'><img src='https:\/\/digilent.com\/blog\/wp-content\/plugins\/wti-like-post-pro\/images\/pixel.gif' title='Unlike' \/><span class='unlc-29242 unlc'>0<\/span><\/a><\/div><\/div> <div class='status-29242 status align-left'>Be the 1st to vote.<\/div><\/div><div class='wti-clear'><\/div>","protected":false},"excerpt":{"rendered":"<p>This project designs a smart RGB lamp which is powered by a battery and controlled through an app running on a smartphone. The lamp and smartphone communicate through Bluetooth Low &hellip; <\/p>\n","protected":false},"author":61,"featured_media":29229,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[4322,4312,1563],"tags":[4352,4353,4368],"ppma_author":[4506],"class_list":["post-29242","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-accessories","category-usb-scopes-analyzers-generators","category-guide","tag-adp3450","tag-linux","tag-pmod"],"jetpack_featured_media_url":"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/06\/smartlamp1.jpg","jetpack_sharing_enabled":true,"authors":[{"term_id":4506,"user_id":61,"is_guest":0,"slug":"richardoed","display_name":"Richard Oed","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/12de1ad12c6f52d1668873102baa76018ec3d4f2078318739209f4b75051c424?s=96&d=mm&r=g","author_category":"","user_url":"","last_name":"Oed","last_name_2":"","first_name":"Richard","first_name_2":"","job_title":"","description":""}],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/posts\/29242","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/users\/61"}],"replies":[{"embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/comments?post=29242"}],"version-history":[{"count":2,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/posts\/29242\/revisions"}],"predecessor-version":[{"id":32597,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/posts\/29242\/revisions\/32597"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/media\/29229"}],"wp:attachment":[{"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/media?parent=29242"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/categories?post=29242"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/tags?post=29242"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=29242"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}