---
# System prepended metadata

title: LDR Light Sensor Tutorial - IoT 1dt305

---

# LDR Light Sensor Tutorial - IoT 1dt305

###### Lucas Arvidsson - La223ss
A implementation of a photon sensor that measures the bpm of current indicator LED in a private property power distribution central. This bpm value is used to calculate the current energy consumption (kW) depending on the imp/kWh of the distribution central. In this tutorial, a power distribution central with 1000 imp/kWh were used.
The calculated value is pushed to Pybytes for storage and graphical presentation.
***
Requirements for implementation:
>Hardware: 
- MicroPython or eqvivalent microcontroller with WiFi capability.
- Photon sensor
- Power distribution central with a imp/kWh sensor not exceeding 10 000 imp/kWh

>Software:
- Access to Pybytes
- Visual Studio Code or ecvivalent IDE

> Estimated time:
- Thirty minutes to one hour
***
This project was started because it brings value to a real life situation.
Since the distribution center is located outside the house, installing this IoT device will allow the residents to view the energy consumption through Pybytes without having to physically get themselves to the distribution central.
It also allows for the resident to get a quicker and easier direct feedback on how much energy that is consumed, which might lead to a possibly more economical electricity usage. 

## Material utilized
#### The following material is required for achieving the same results with the provided source code.
###### Battery can be replaced with a cabled power supply if the distribution central supports it.
### Pycom LoPy4
This project utilized the LoPy 4, a Micropython-programmable board. Although the board allows for Lora, Sigfox, WiFi and Bluetooth, only WiFi were utilized for the implementation.

The board is programmable with the Pymakr plugins which allows for fast IoT deveopment.

The LoPy4 were bought as a bundle from electrokit.com for 1.000 SEK but are unfortunately no longer available for purchase. Included with the LoPy4 were the pin jumper wires, resistors, LDR light sensor and expansion board 3.1.


![](https://i.imgur.com/ubRniGZ.png)
***
### Expansion Board 3.1
This project also utilized the expansion board 3.1, which along with a wide range of features allowed for powering the LoPy4 using USB or LiPo battery.

Included in the LoP4 bundle bought from electrokit.com (No longer available).

![](https://i.imgur.com/IxdQUP1.png)
***
### LDR Light sensor
To capture the current indicator LED, a Light Dependent Resistor (LDR) sensor were used.
The LDR is a sensor which has a resistance that changes depending on the light intensity that hits it.
The resistance is measured to capture the bpm of the current indicator.

Included in the LoP4 bundle bought from electrokit.com (No longer available).

![](https://i.imgur.com/NI3rRHp.png)

***
### Pin jumper wire x4
Pin jumper wires were utilized to connect the sensor and its required resistors with the microcontroller.

Included in the LoP4 bundle bought from electrokit.com (No longer available).

![](https://i.imgur.com/PNhkpvE.png)

***
### Resistor: 330 Ohm, 10k Ohm
A 10k Ohm pull down resistor were used for the LDR, and a 330 Ohm resistor were used for the red LED when simulating the current indicator during development.

Included in the LoP4 bundle bought from electrokit.com (No longer available).

![](https://i.imgur.com/pWtpsEc.png)

***
### JST battery holder & batteries

A battery holder with a JST connection for supplying the controller with power without being cabled. Will in most cases be required as the solution is intended to be installed inside a distribution central.

Bought from [electrokit.com](https://www.electrokit.com/produkt/batterihallare-2xaaa-med-jst-ph-kontakt/) for 25.00 SEK.
![](https://i.imgur.com/mOZXKbt.png)
***
### Solderless breadboard

The breadboard were utilized to wire the LDR light sensor curcuit and its connection to the microcontroller.

Included in the LoP4 bundle bought from electrokit.com (No longer available).
![](https://i.imgur.com/v12w23R.png)

***
#### Red LED (Not Required)
If there is a need to simulate the current indicator, a LED can be utilized. During the development of this project, a red LED with a forward voltage of 1.8 were used.

Included in the LoP4 bundle bought from electrokit.com (No longer available).

![](https://i.imgur.com/GqfuTUc.png)


## Setup

Steps taken for final implementation

### Software

> IDE: Visual Studio Code
> Extension: Pymakr

To install the Pymakr extension for visual studio code, simply click the extension icon on the left navigation bar, and search for "Pymakr". The correct extension is shown in the figure below:

![](https://i.imgur.com/RXrw58r.png)

Only a main. py file was utilized for this implementation, therefor that is all that needs to be uploaded to the pycom device. The code can be uploaded to the LoPy4 by pressing the "upload" button in the bottom navigation bar that becomes available after installing the Pymakr extension

![](https://i.imgur.com/ayJukpu.png)

#### Firmware

To ensure that the microcontroller functions as intended, the newest firmware should be installed. This was done utilizing Pycoms Firmware updating tool.
The same software can be utilized to correctly finish the setup for Pybytes


#### Pybytes
Navigate to pybytes.pycom.io and register an account.

Afterwards the pycom device has to be added and the WiFi network needs to be configured.

To configure a WiFi:

![](https://i.imgur.com/JmxuNGw.png)


![](https://i.imgur.com/52NTJoe.png)

Fill out the WiFi display name (SSID) and potentiall password:

![](https://i.imgur.com/B76GdOC.png)

To add the device:

![](https://i.imgur.com/vxyOpPM.png)

In my case, the LoPy4 device was selected

![](https://i.imgur.com/HWXVLhp.png)

![](https://i.imgur.com/0ZOf2MW.png)

Select the previously configure WiFi Network and give your device a name.

![](https://i.imgur.com/96ZHUCb.png)

On the new device's dashboard, navigate to the provisioning tab. Here you will find the activation token that the Firmware update tool will require to setup correctly Pybytes.

![](https://i.imgur.com/76ay3Xs.png)


### Updating firmware and configuring Pybytes

With the previously acquired Pybytes activation token, we can with the help of the Firmware update tool both update the firmware and correctly setup Pybytes.

Before proceeding, download the Firmware update tool for your operating system.
***
##### Firmware Updating Tool
- [Windows, macOS and Linux](https://docs.pycom.io/gettingstarted/installation/firmwaretool/)
***

### To update firmware and configure Pybytes:

![](https://i.imgur.com/n0quE9I.png)

Ensure the "Force update Pybytes registration" and "Enable Pybytes / SmartConfig support" are checked.

![](https://i.imgur.com/gEao3Qn.png)

Paste your previously acquired Pybytes activation token

![](https://i.imgur.com/oVo0il6.png)


Continue with the default settings for the rest of the setup.

After the setup is finished, you should be able use the IDE to upload the python code to the microcontroller.

## Electric circuit & wiring
***
### Production Circuit
The circuit setup itself is relatively simple, consiting of only a voltage supply (LoPy4), a LRD sensor, resistors and wiring.

![](https://i.imgur.com/pdGUWlt.png)

Although 3,3V were used, 5V can be used and would result in a bigger voltage range from the LRD sensors output. If the inside of the power distribution central always is bright enough to trigger the sensor, there is a posibility of using a pull down resistor with lower resistance or altering the source code responsible for identifying a impulse.

### Wiring
For simulating the current indicator LED together with the LDR sensor, the following setup were utilized. If there is a need for simulating the imp/kWh, this wiring is recommended.

![](https://i.imgur.com/bVqgNTj.png)

When wiring for production, only the LDR sensor, its resistor and wiring is necessary.


## Platform
### Pybytes

The cloud solution for storing and presenting the processed sensor data used is Pybytes, which the setup process for were previously detailed. Pybytes cloud is used, which is a plan that is forever free. 

Pybytes allows for table storage and simple graphical presentation in the shape of diagrams. Pybytes were chosen because of the final processed sensor data that is recieved being simple and the fact that there is a constant WiFi connection. There is also no need for further calculations, when the data is recieved, its ready for presentation. 

Because of the distribution central being part of the resident house, there is a constant connection to WiFi, which further simplified the processes of sending data to Pybytes.

If the solution were to be scaled, a platform integration for pybytes would need to be implemented since pybytes offer limited storage.

## Implementation


### Source Code

The source code is divided into the two parts production code and development code, with the latter being used when simulating the current indicator.
#### Production source code

The production code is intended to continiously send kW data to pybytes over Wifi. Calculating kW is achieved by tracking the time between the current indicator flashes (bpm) and converting to kW. The formula used is as follows: `kW = (3600 / imp/kWh) / bmp`

The data is sent to pybytes in constant intervals of 60 seconds, which is achieved by utilizing interupts from the Timer library.

    import pycom
    import machine
    from machine import Timer
    import time
    import _thread

    counter = 0 # Tracks the LED impulses
    bpmAverage = 0 # Average amount of blinks per interval

    # Interrupt, used to send data to pybytes with a constant interval
    # Currently sending data each minute. 
    class Data_Interupt:

        def __init__(self):
            self.__alarm = Timer.Alarm(self.transmit_average_kw, 60, periodic=True)

        def transmit_average_kw(self, alarm):
            global counter
            global bpmAverage

            bpmAverage = bpmAverage / counter
            kWAverage = (3600 / 1000) / bpmAverage
            pybytes.send_signal(2, kWAverage)
            counter = 0
            bpmAverage = 0


    # function for updating a counter each time the power indicator lights up, counter and bpm should be reset each interval
    def track_light():
        adc = machine.ADC()
        apin = adc.channel(pin='P16')

        global counter
        global bpmAverage

        light = False

        chrono = Timer.Chrono()
        chrono.start()
        print("starting light sensor...")
        print("Tracking...")

        while True:
            val = apin()    
            val= val/400
            val= val/10

            if val >= 0.4 and light == False:
                time = chrono.read_ms()/1000
                if time > 0.05:
                    bpmAverage += time
                    counter += 1
                light = True
                chrono.reset()


            elif val < 0.4 and light == True:
                light = False


    send_data = Data_Interupt()

    _thread.start_new_thread(track_light, ())

#### Development source code
To simulate the current indicator, simply change the Data_Interupt class as following:

    class Data_Interupt:

    def __init__(self):
    
        self.led = 1
        self.dac = machine.DAC('P22')
        self.__alarm = Timer.Alarm(self.transmit_average_kw, 60, periodic=True)
        self.__alarm2 = Timer.Alarm(self._led_handler, 1, periodic=True) # 1 Second intervall = 2 seconds between each blink

    def transmit_average_kw(self, alarm):
        global counter
        global bpmAverage

        bpmAverage = bpmAverage / counter # Average time between impulses, used since data is only sent each minute
        kWAverage = (3600 / 1000) / bpmAverage
        pybytes.send_signal(2, kWAverage)
        counter = 0
        bpmAverage = 0
        
    # Function used to simulate LED impulses
    def _led_handler(self, alarm): 
        self.led *= -1 
        self.dac.write(self.led)

A interupt simulating the current indicator with a given interval was added and a call back function that lights the LED.
### Data transmition
After the initial setup and activation of the pybytes platform previously covered in this tutorial, the sending of data simply requires the usage of `pybytes.send_signal(signalNumber, value)`, which is part of the Pybytes library. The signal parameter determines on which signal to send the value. The signal can later be graphicaly plotted on the pybytes platform. The value variable is the value that is being attributed to the signal number.

The data is sent from the microcontroller to pybytes with a interval of 60 seconds. The communication to pybytes is achieved utilizing WiFi as the wireless protocol with the MQTT transport protocol.
The data stored in pybytes are not later sent to any integrated platform such as webhooks or AWS.

## Data presentation

Pybytes recieves and store data through signals, which later can be graphically presented on the dashboard. This also means that Pybytes saves the data as often as the platform recieves signals, which is controlled by how often we send data. The project is by default set to send a signal with a 60 seconds interval.


![](https://i.imgur.com/y8u6XsY.png)

Pybytes's Dashboard provides a graphical presentation in the form of diagrams that is simple but enough for the use case of displaying energy consumption fluctuation over time.

![](https://i.imgur.com/YjZbr2O.png)

The data that is recieved on each signal is by default configured to persist for a month. If the data is to persist for longer, an integration to another platform, such as AWS or web hooks, where the data can be stored is required.

## Final Thoughts

The project were finished smoothly and without much difficulty. It also contributes to a real life quality of life improvement. Although WiFi were utilized for this project, if one were to improve upon this project i would recomend implementing LoRa instead for a longer battery lifetime. Althought the data currently sent to Pybytes is 8 bytes, the data do not require more than 1 byte of data to be decsriptive enough and does not need to be sent all that often. Therefor both Sigfox and LoRa is an option and possible improvement over WiFi. Even if one were to still use WiFi, limiting the data sent to 1 byte would still be a improvement.  

Final dashboard showing how the kW consumption changes over time:

![](https://i.imgur.com/u8z2s5h.png)
***
Final setup intended to be used in a power distribution central can be seen in the picture below. The extended LRD light sensors should be mounted in close proximity with the current indicator LED. A possible improvement to this setup would be a smaller alternative to the breadboard currently utilized.

![](https://i.imgur.com/CFJw3OP.png)
