empowering creative people

Light Sensing with an LDR and Pycom

One of the simplest sensors in any makers toolkit is a light sensor or LDR. An LDR works by changing its resistance from 1k ohm to 10K ohm depending on how much light is striking it. In this tutorial, we will show you how to use one with a Pycom Lopy4 and transmit your readings to TTN via LoRaWAN!

The Circuit

An LDR needs to be used with a 10k ohm resistor. This drops the voltage down to a level easily interpreted by the ADC on the Lopy4. We want to see values about the middle of the range when in a normally lit room. The Pycom Lopy4 has 12-bit ADC, so the maximum reading will be 4096. We will be using the Pycom Expansion Board 3.0 and the Lopy4, but any Pycom board will work! If you are connecting to your Pycom board directly refer to the relevant pinout diagram.


The Code

The following code takes light measurements every ten seconds, and then sends them to The Things Network via LoRaWAN

# Measuring light with an LDR
from network import LoRa
import socket
import utime
import binascii
import pycom
import ustruct
import machine
from machine import Pin

adc = machine.ADC()               # create an ADC object
apin = adc.channel(pin=Pin.exp_board.G31) # Lopy4 specific: (pin = 'P17')   create an analog pin on P17 & connect TMP36

# Light measurment
def light_measure():
    print("Reading LDR Sensor...")
    value = apin()
    print("ADC count = %d" %(value))

    # LoPy  has 1.1 V input range for ADC
    light = value
    print("light = %5.1f" % (light))

    return light

# disable LED heartbeat (so we can control the LED)
# set LED to red

# lora config
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.AS923)
# access info
app_eui = binascii.unhexlify('XXXXXXXX')
app_key = binascii.unhexlify('XXXXXXXXXXXXXXXXXXXXXXXX')

# attempt join - continues attempts background
lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0)

# wait for a connection
print('Waiting for LoRaWAN network connection...')
while not lora.has_joined():
	# if no connection in a few seconds, then reboot
	if utime.time() > 15:
		print("possible timeout")

# we're online, set LED to green and notify via print
print('Network joined!')

# setup the socket
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)

count = 0
# limit to 200 packets; just in case power is left on
while count < 200:

	# take light measurment, turn the light blue when measuring
	light = light_measure()

	print("light:  ", light)
	# encode the packet, so that it's in BYTES (TTN friendly)
	# could be extended like this struct.pack('f', light) + struct.pack('c',"example text")
    # 'h' packs it into a short, 'f' packs it into a float, must be decoded in TTN
	packet = ustruct.pack('h', light)

	# send the prepared packet via LoRa

	# example of unpacking a payload - unpack returns a sequence of
	#immutable objects (a list) and in this case the first object is the only object
	print ("Unpacked value is:", ustruct.unpack('h',packet)[0])

	# check for a downlink payload, up to 64 bytes
	rx_pkt = s.recv(64)

	# check if a downlink was received
	if len(rx_pkt) > 0:
		print("Downlink data on port 200:", rx_pkt)
		input("Downlink recieved, press Enter to continue")

	count += 1

Decoding the Payload

Now we have our data arriving in The Things Network as payloads, but we need to decode them! Under Payload Formats in TTN we will use the following javascript code to decode our payloads:

function Decoder(bytes, port) {
  // Decode an uplink message from a buffer
  // (array) of bytes to an object of fields.
  var decoded = {};

  // Decode bytes to int
  var testShort = (bytes[1] << 8) | bytes[0];

  // Decode int 
  decoded.Light = testShort;

  return decoded;

Going Further

If you want to learn more about Pycom check out our Pycom Tutorials. If you want to learn more about connecting to The Things Network and using LoRaWAN check out our The Things Network Tutorials. There are many more sensors and devices that can be used with the Pycom Lopy4, get out there and experiment!

One of the simplest sensors in any makers toolkit is a light sensor or LDR. An LDR works by changing its resistance from 1k o...

Have a question? Ask the Author of this guide today!