Hello and welcome to my Remote Light video with Raspberry Pi and Python.
This video will show you how to connect 2 Raspberry Pi devices over a local area network
to control an LED remotely.
This simple concept leads into the Smart Home territory
and it can be a foundation for remote controlled vehicles,
which I will actually demonstrate in an upcoming video.
I will start with just one system with a very simple setup – a button controlled LED.
The circuit consists of a standard push button with an LED and a 220 Ohm resistor.
I use a breadboard connected to the Pi using a cobbler and a ribbon cable.
Let’s write a small program in Python that will turn the LED on and off using the push button.
If you are new to Python programming with Raspberry Pi, you may want to check out a couple of my introductory videos before continuing.
Here is the setup in action...
The LED state is toggled with every button press.
A remote-controlled version of this setup requires a second Raspberry Pi with its own breadboard,
where the LED will be moved to the second breadboard.
The secondary (or otherwise remote system) needs to be configured for remote GPIO access.
This is a setting changed using the raspi-config program. Let me do this right now.
Not all python Libraries support remote GPIO access.
One I recommend for that is called PiGPIO.
This library has a server daemon included which runs on the remote system.
The controlling program will be run on the local system and will control the LED through that daemon.
Let’s enable this daemon permanently.
This needs to be done only once and after this is configured, this service will be started automatically
whenever the remote system boots.
I can now go ahead and connect the breadboard to the remote system and that concludes the setup on the receiving end.
The rest of the work will be performed on the local system.
The gpiozero library is actually an overlay over a number of lower-level libraries and it includes access to PiGPIO.
Selection of the underlying library is done by providing what gpiozero calls a PinFactory.
Adding a custom PinFactory will bring the needed remote access functionality to my program.
The PiGPIO factory here will be initialized for remote access by specifying the remote host name.
You could use an IP address here but a host name is more flexible as it does not change every time the remote system boots.
The assumption of course is that the Raspberry Pi systems involved have a different network name
but they are connected to the same network.
The LED declaration needs to be updated so my program knows that it is physically located on the remote system.
The rest of the code remains unchanged.
Let’s give it a go...
As you can see, the remote access concept is super simple.
This makes it extremely powerful,
as virtually any project that can be coded using Python can be adapted to work over network.
You are not limited to LEDs at all – you can get sensor readings, control motors etc.
A better light control would include a dimming capability.
This will call for adding a potentiometer and and analog-to-digital converter
to interface that potentiometer with the local system.
You can use any analog-to-digital converter chip you have.
Gpiozero Library has direct support for the MCP3000 family of chips
and this is what I will use here.
The MCP3002 chip is a 2-channel, 10 bit converter which will work very well in an LED dimming setup.
Note that all changes are done on the local system and the remote system is unchanged.
The MCP3002 chip uses the SPI protocol which, is enabled using the raspi-config program.
This protocol uses 4 wires for communication
and Raspberry Pi supports both hardware and software implementation.
The hardware solution is faster and more reliable and I will use that one.
Let’s add the necessary code to include the analog potentiometer input to the system.
I will add a small testing loop for a moment,
to test that the new components are connected and functioning correctly.
This loop will display the potentiometer position as a float value between 0 and 1, 10 times a second.
Everything seems in order.
The value read does not quite reach 0 and it may not always reach 1 on the other end.
This is normal as the ADC chip has a 1% error margin the power supply stability plays a factor too.
You can always round the reading if that becomes a problem.
Once you successfully test your circuit you can go ahead and delete this loop from your program
as it will not be used afterwards.
The analog input will be tied to the LED using gpiozero source-values mechanism,
where the LED itself will automatically communicate with the ADC chip,
matching its brightness to the potentiometer position.
This is a very efficient, multi-threaded model
but if you are concerned about system load or network traffic
you can modify the default 1 millisecond communication interval.
I will set mine to 2 milliseconds,
which means that the LED brightness will be updated 50 times a second.
Let’s have a look at the new setup in action...
The LED brightness now depends on the potentiometer input.
The button appears to be broken now.
It actually still works and the LED toggles when I press the button,
but the LED is immediately reset, as it’s updated 50 times a second automatically.
In order to have both switch control and dimming I need to add a bit more code.
The existing LED toggle needs to be replaced with a function which will not just simply toggle the LED,
but control the LED on-off state by enabling and disabling the ongoing dimming process.
The source_delay can stay where it is, as it will not change while the program runs.
This function will be called with every button press and will alternately turn the LED on and off,
but now the dimming will not interfere with the switching operation.
The LED will have brightness matching the potentiometer when it's turned on.
If you are keen on details, you may have noticed that the LED dims poorly on the low end.
This is normal as LED dimming is not linear and the process needs to be compensated using a formula
which will straighten out the brightness curve.
I will just hard code these calculations here. If you are interested in more detail,
I have a separate video that explains the details of pulse-width signal modulation.
The source-values connection needs to be replaced with a generator function
which will take the existing (non-compensated) analog readings and re-calculate
them so the dimming process is much slower on the low end than towards the top.
That's all for this tutorial!
Stay tuned for a follow-up video
where I will show you how to control motors remotely using a joystick
so you can build your own remote-controlled vehicle.
Thanks for watching!