Communicate between Raspberry Pi 4 and Esp32 via Bluetooth

Welcome to the next tutorial of our raspberry pi 4 programming course. A previous article covered connecting a Remote Control Radio Frequency Module (433 MHz) to a Raspberry Pi 4. To turn things on and off wirelessly, we programmed a Raspberry Pi 4 to act as a radio-frequency (RF) remote control. However, this guide will study how to wirelessly pair a Raspberry Pi 4 and an ESP32. After reading this article, you'll get a good grounding in the fundamentals of Bluetooth module operation between two ESP32 and Pi 4 communication.

When it comes to sharing data over short distances using Ultra High-Frequency Radio Waves, Bluetooth is one of the most reliable and effective short-range wireless communication solutions. Since Bluetooth Technology was initially conceived as a cable substitution technology, its implementation in embedded devices is inevitable. While popular microcontrollers like the ESP32, Raspberry Pi, and Arduino Mega all come equipped with Bluetooth modules by default, others can be made Bluetooth-ready by adding modules like the HC 05 or JDY-30.

Required Components

You will require the following things:

  • Raspberry Pi

  • Arduino IDE

  • Two ESP32 Development Boards*

  • NRF Application

  • USB Cable for ESP32

What is the PyQt library?

PyQt is binding for the Qt C++ libraries & development tools that allow for the creation of GUIs independent of the underlying platform (GUIs). Other robust technologies accessed through Qt include networking, threading, regex, Database queries, SVG, OpenGL, and XML.

Since PyQt6 is the library's future, it will be used in this lesson. All references to PyQt from this point forward should be taken to mean PyQt6. Based on Qt v6, PyQt6 is an implementation of Qt. As such, it offers classes and utilities for working with graphical user interfaces, XML, networking, regex, threads, Database queries, and the web, among other technologies supported by Qt. Many of the Qt classes' bindings have been implemented in a set of Modules that make up the PyQt6 package at the Python level. If you're using Python 3.6.1 or later, you can install PyQt6.

In addition to Windows and Linux, PyQt6 works on mac, Android, and Android. This is appealing if you need a Graphical framework to create cross-platform apps that look and feel natural on all of them.

Platform-Specific Installation

There are PyQt6 binary packages available in the repositories of several Linux systems. If this describes your situation, the library can be installed through your distribution package manager. For instance, this is a command you can use on Ubuntu:

sudo apt install python3-pyqt6

This command will set up your system so you can utilize the PyQt6 library in any GUI applications you undertake. It's important to remember that you need root access to perform this; thus, the sudo command will be used.

Bluetooth Low Energy (BLE)

Raspberry Pi and ESP32 are the only microcontrollers that ship with Bluetooth Low-Energy Technology modules. While traditional Bluetooth is optimized for data transfers over long distances and wide bandwidths, BLE is optimized for short-range and low-power usage. As a result of its superior efficiency in conserving energy, it consumes less power than traditional Bluetooth by a factor of over one hundred, with just a negligible drop in performance. Unlike traditional Bluetooth, which stays on even when not in use, BLE goes into a sleep state whenever it is not actively involved in a connection or data transfer.

It can function in one of four ways:

  • A peripheral device publicizes data and facilitates communication with other, further-flung gadgets.

  • A broadcaster is a gadget explicitly designed to disseminate information.

  • Observer - Data-only monitoring hardware.

  • A central device serves a dual purpose: scan for and connect to other devices.

Before the introduction of BLE, the first two modes were used by detectors and other industrial machinery, while personal computers and mobile phones used the latter two modes. Most BLE, however, now supports all four transfer methods thanks to technological advances. These transfer methods are available on the ESP32 and the Raspberry Pi. In the table below, you can observe the vast distinction between the traditional and BLE.

What is ESP32?

The ESP32 is a new System-on-a-Chip (SoC) microcontroller by Espressif Systems, the company responsible for the widely used ESP8266 SoC. For those looking for a 32-bit alternative to the ESP8266 SoC, Tensilica has you covered with their Xtensa LX6 Microprocessor, which comes in single-core and dual-core flavours and boasts built-in WiFi and Bluetooth.

A power amplifier, a low-noise reception amplifier, an antenna-selection switch, filters, and a balun for regulating the signal intensity are all included on the ESP32, just as they are on the ESP8266. Since the ESP32 requires so few external components, hardware development is streamlined.

The ESP32 is produced with TSMC's ultra-low-power 40 nm technology, another essential feature to keep in mind. As a result, employing ESP32 for the development of battery-operated applications like smartwatches, fitness trackers, baby monitors, and other similar devices should be a breeze.

Numerous ESP32 Coding Methods

If high-quality hardware like ESP32 can be programmed (coded) in multiple ways, it will be more accessible to a broader audience. As may be expected, the ESP32 is compatible with various development environments.

These are only a few examples of widely-used IDEs (integrated development environments):

  • Arduino IDE

  • PlatformIO IDE (VS Code)

  • LUA

  • MicroPython

  • Espressif IDF (IoT Development Framework)

  • JavaScript

Because of how comfortable it is, we'll be using the Arduino IDE to code the ESP32 we'll use in future projects. Other options are available to you as well.

Layout

Using the ESP32 DevKit Board as an example, we can examine its design to learn about the components that typically make up an ESP32 Development Board.

In the accompanying picture, you can see how the ESP32 Development Board I own is laid out.

Note: The market is flooded with ESP32 Boards that use the ESP-WROOM-32 Module. Different boards have different designs, pinouts, and sets of features.

The pin count on my board is 30. Some boards have 36 pins, while others have somewhat fewer. Therefore, before making any connections or turning on the board, you should verify that the pins are in the correct positions.

Depicted in the illustration are the components that make up the ESP32 Board:

  • ESP-WROOM-32 Module

  • Two rows of IO Pins (with 15 pins on each side)

  • CP2012 USB – UART Bridge IC

  • Micro–USB Connector (for power and programming)

  • AMS1117 3.3V Regulator IC

  • Enable Button (for Reset)

  • Boot Button (for flashing)

  • Power LED (Red)

  • User LED (Blue – connected to GPIO2)

  • Some passive components

The DTR and RTS pins on the USB-to-UART IC are utilized to automatically put the ESP32 into programming mode (when necessary) and to put the board to sleep after programming.

Pinout of ESP32 Board

A specialized ESP32 Pinout guide is something I intend to create. Meanwhile, check out the ESP32 Development Board's wiring diagram.

ESP Boards with 30 pins are supported with this pinout. Both the 30-pin and 36-pin versions of the ESP Board's pinout will be covered in this tutorial.

Now that you have a basic understanding of ESP32, it's time to see how it can be used. There is only so much more I can add to this chapter than what's already been said. The many sections of this guide should have stimulated some thought processes in your head. You probably already have an essential list of uses for ESP32 written out. Furthermore, most of your suggested services are doable.

Although ESP32 is a viable option for many uses, it is better suited for some. In this chapter, I'll explain the criteria you should use to decide whether or not to use ESP32 in a given application. This chapter is geared at production, so if you're thinking of hundreds or even thousands of devices, you're probably looking in the wrong place. If you only need to connect a few devices and ESP32 has what you need, utilize it without hesitation. You can confidently use ESP32 for prototyping and Proof of Concept (PoC).

ESP32's built-in support for wireless networking is a strong selling point. Thus, the ESP32 is the ideal microcontroller for a stationary application where reliable WiFi connectivity is not a primary concern, such as a lab-based environmental monitoring system. You won't need to buy a separate networking module because the WiFi stack is built right into the Module. If you plan on using the ESP32 in a mobile asset tracking application, however, you'll need a GSM or LTE module to maintain a constant connection to the server. As a result, ESP32 loses its cost advantage, and you may be better suited with a less expensive microcontroller that can still accomplish your goals.

Furthermore, ESP32's built-in hardware encryption accelerator makes it an excellent choice for any project that needs to communicate securely (HTTPS). Therefore, if you need to protect sensitive data from being intercepted, using an ESP32 microcontroller is preferable to using one of the many others that don't have this feature. The military industry is one possible use case for Industrial IoT.

Due to its dual-core architecture, the ESP32 is an excellent choice for data-intensive applications like those that require processing and transmission of data to occur on separate cores, as is the case with receiving information at a high baud rate. Industrial IoT is home to several such implementations. A microcontroller with less impressive specifications may be better suited for an actual application in which a secure connection isn't even necessary. So why bother with two cores if you can get by with only one?

The available GPIOs and peripherals are another consideration. There are three Universal Asynchronous Receiver/Transmitter (UART) channels on an ESP32. You may need to choose a different microcontroller if your application requires more than three UART channels. Similarly, the ESP32's 34 programmable GPIOs are plenty for most uses. However, if more general-purpose input/output (GPIO) pins are needed for your application, you may need to look at a different microcontroller.

With 1.5 MB of SPIFFS by default, the ESP32 offers more excellent onboard storage than competing microcontrollers. ESP32 eliminates the need for an additional Flash Chip or SD Card if your data storage needs are under 1.5 MB. As a bonus, the ESP32 handles wear-levelling within SPIFFS on its own. Nonetheless, the ESP32's competitive edge is nullified once more if it doesn't satisfy your data storage needs.

The 520 KiloByte of RAM on an ESP32 is likewise plenty of space for the vast majority of uses. This only becomes a stumbling block for resource-intensive tasks like image/video processing.

Connection Between Two ESP32s

Using the ESP32's built-in Bluetooth Low Energy (BLE) functionality, two microcontrollers may establish a highly efficient wireless link. With a Bluetooth connection between the two boards, one will take on the server role, while the other will take on the client role. For this project, one ESP32 will function as the server, broadcasting the data and establishing the connection, while the other ESP32 will take on the client's part, receiving the data broadcast by the server. Over the BLE connection, we will be exchanging strings between two esp32s.

ESP32 as a Server

The first ESP32 we build will serve as a Bluetooth host. To the client, it will supply the link and the information. Here is its source code:

#include "bleutils.h"

#include "bleserver.h"

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"

#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

void setup() {

  Serial.begin(115200);

  Serial.println("Starting BLE work!");

  BLEDevice::init("ESP32 AS A BLE");

  BLEServer *pServer = BLEDevice::createServer();

  BLEService *pService = pServer->createService(SERVICE_UUID);

  BLECharacteristic *pCharacteristic = pService->createCharacteristic(

                                         CHARACTERISTIC_UUID,

                                         BLECharacteristic::PROPERTY_READ |

                                         BLECharacteristic::PROPERTY_WRITE

                                       );

  pCharacteristic->setValue("Hi,other ESP32 here is your data");

  pService->start();

  // BLEAdvertising *pAdvertising = pServer->getAdvertising();  // this still is working for backward compatibility

  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();

  pAdvertising->addServiceUUID(SERVICE_UUID);

  pAdvertising->setScanResponse(true);

  pAdvertising->setMinPreferred(0x06);  

  pAdvertising->setMinPreferred(0x12);

  BLEDevice::startAdvertising();

  Serial.println("Characteristic defined!");

}

void loop() {

  // put your main code here to run repeatedly:

  delay(2000);

}

Code objects such as characteristics, BLE objects, and Advertising objects are all created using the BLE class. It begins with a Characteristic UUID and a Service UUID. The Universally Unique Identifier (UUID) is a string of bytes that can specify a Bluetooth device's features and capabilities. First, we initialized three objects of the BLEserver, BLE characteristic, and BLEService classes with the necessary data. Then, after setting up our Bluetooth server's UUID, attributes, and Services, we started it using the BLE device class's start advertising function. Any information, from sensor readings to business metrics, can be pre-set and advertised. Following the activation of this server, nRF Connect can be used to gain access to it from any mobile device.

  1. Launch the scanner and link it to your Bluetooth device.

  1. Once you've established a connection with your ESP32, inspect the feature and see your text displayed.

ESP32 as a Client

The second esp32 will function as a client, requesting information from the host device. The only information needed to establish a connection to the server esp32 and use its given services is the UUIDs of those services and the characteristics they identify.

Its program is as follows:

#include "BLEDevice.h"

//#include "BLEScan.h"

// The remote service we wish to connect to.

static BLEUUID serviceUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b");

// The Characteristic of the remote service we are interested in.

static BLEUUID    charUUID("beb5483e-36e1-4688-b7f5-ea07361b26a8");

static boolean doConnect = false;

static boolean connected = false;

static boolean doScan = false;

static BLERemoteCharacteristic* pRemoteCharacteristic;

static BLEAdvertisedDevice* myDevice;

static void notifyCallback(

  BLERemoteCharacteristic* pBLERemoteCharacteristic,

  uint8_t* pData,

  size_t length,

  bool isNotify) {

    Serial.print("Notify callback for characteristic ");

    Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());

    Serial.print(" of data length ");

    Serial.println(length);

    Serial.print("data: ");

    Serial.println((char*)pData);

}

class MyClientCallback : public BLEClientCallbacks {

  void onConnect(BLEClient* pclient) {

  }

  void onDisconnect(BLEClient* pclient) {

    connected = false;

    Serial.println("onDisconnect");

  }

};

bool connectToServer() {

    Serial.print("Forming a connection to ");

    Serial.println(myDevice->getAddress().toString().c_str());

    BLEClient*  pClient  = BLEDevice::createClient();

    Serial.println(" - Created client");

    pClient->setClientCallbacks(new MyClientCallback());

    // Connect to the remove BLE Server.

    pClient->connect(myDevice);  // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)

    Serial.println(" - Connected to server");

    // Obtain a reference to the service we are after in the remote BLE server.

    BLERemoteService* pRemoteService = pClient->getService(serviceUUID);

    if (pRemoteService == nullptr) {

      Serial.print("Failed to find our service UUID: ");

      Serial.println(serviceUUID.toString().c_str());

      pClient->disconnect();

      return false;

    }

    Serial.println(" - Found our service");

    // Obtain a reference to the Characteristic in the service of the remote BLE server.

    pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);

    if (pRemoteCharacteristic == nullptr) {

      Serial.print("Failed to find our characteristic UUID: ");

      Serial.println(charUUID.toString().c_str());

      pClient->disconnect();

      return false;

    }

    Serial.println(" - Found our characteristic");

    // Read the value of the Characteristic.

    if(pRemoteCharacteristic->canRead()) {

      std::string value = pRemoteCharacteristic->readValue();

      Serial.print("The characteristic value was: ");

      Serial.println(value.c_str());

    }

    if(pRemoteCharacteristic->canNotify())

      pRemoteCharacteristic->registerForNotify(notifyCallback);

    connected = true;

    return true;

}

/**

* Scan for BLE servers and find the first one that advertises the service we are looking for.

*/

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {

/**

   * Called for each advertising BLE server.

   */

  void onResult(BLEAdvertisedDevice advertisedDevice) {

    Serial.print("BLE Advertised Device found: ");

    Serial.println(advertisedDevice.toString().c_str());

    // We have found a device, let us now see if it contains the service we are looking for.

    if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {

      BLEDevice::getScan()->stop();

      myDevice = new BLEAdvertisedDevice(advertisedDevice);

      doConnect = true;

      doScan = true;

    } // Found our server

  } // onResult

}; // MyAdvertisedDeviceCallbacks

void setup() {

  Serial.begin(115200);

  Serial.println("Starting Arduino BLE Client application...");

  BLEDevice::init("");

  // Retrieve a Scanner and set the callback we want to use to be informed when we

  // have detected a new device. Specify that we want active scanning and start the

  // scan to run for 5 seconds.

  BLEScan* pBLEScan = BLEDevice::getScan();

  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());

  pBLEScan->setInterval(1349);

  pBLEScan->setWindow(449);

  pBLEScan->setActiveScan(true);

  pBLEScan->start(5, false);

} //End of setup.

// This is the Arduino main loop function.

void loop() {

  // If the flag "doConnect" is true then we have scanned for and found the desired

  // BLE Server with which we wish to connect. Now we connect to it. Once we are

  // connected, we set the connected flag to be true.

  if (doConnect == true) {

    if (connectToServer()) {

      Serial.println("We are now connected to the BLE Server.");

    } else {

      Serial.println("We have failed to connect to the server; there is nothin more we will do.");

    }

    doConnect = false;

  }

  // If we are connected to a peer BLE Server, update the Characteristic each time we are reached

  // with the current time since boot.

  if (connected) {

    String newValue = "Time since boot: " + String(millis()/1000);

    Serial.println("Setting new characteristic value to \"" + newValue + "\"");

    // Set the Characteristic's value to be the array of bytes that is a string.

    pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());

  }else if(doScan){

    BLEDevice::getScan()->start(0);  // this is just an example of starting the scan after disconnect; most likely, there is a better way to do it in Arduino.

  }

  delay(1000); // Delay a second between loops.

} //End of loop

The functionality of this code depends on human input. At the outset of the code, we established the definitions of Characteristic and service UUID. Initially, BLERemoteCharacteristic and BLEAdvertisedDevice objects are created, and the connection to the server () function is used to establish a connection with the server (other esp32). In the End, it pulls in the server's data via the Characteristic and service variables. This is what these numbers will look like on the serial monitor:

Connection of ESP32 to Raspberry Pi

To link our ESP32 to Bluetooth, we will use a UART connection. Because of this, it will have bidirectional communication with the Pi 4.

As for the program, it goes like this:

#include "bledevice.h"

#include "bleserver.h"

#include "bleutils.h"

#include "ble2902.h"

BLEServer *pServer = NULL;

BLECharacteristic * pTxCharacteristic;

bool deviceConnected = false;

bool oldDeviceConnected = false;

uint8_t txValue = 0;

// See the following for generating UUIDs:

// https://www.uuidgenerator.net/

#define SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID

#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"

#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

class MyServerCallbacks: public BLEServerCallbacks {

    void onConnect(BLEServer* pServer) {

      deviceConnected = true;

    };

    void onDisconnect(BLEServer* pServer) {

      deviceConnected = false;

    }

};

class MyCallbacks: public BLECharacteristicCallbacks {

    void onWrite(BLECharacteristic *pCharacteristic) {

      std::string rxValue = pCharacteristic->getValue();

      if (rxValue.length() > 0) {

        Serial.println("*********");

        Serial.print("Received Value: ");

        for (int i = 0; i < rxValue.length(); i++)

          Serial.print(rxValue[i]);

        Serial.println();

        Serial.println("*********");

      }

    }

};

void setup() {

  Serial.begin(115200);

  // Create the BLE Device

  BLEDevice::init("UART Service For ESP32");

  // Create the BLE Server

  pServer = BLEDevice::createServer();

  pServer->setCallbacks(new MyServerCallbacks());

  // Create the BLE Service

  BLEService *pService = pServer->createService(SERVICE_UUID);

  // Create a BLE Characteristic

  pTxCharacteristic = pService->createCharacteristic(

                                        CHARACTERISTIC_UUID_TX,

                                        BLECharacteristic::PROPERTY_NOTIFY

                                    );                  

  pTxCharacteristic->addDescriptor(new BLE2902());

  BLECharacteristic * pRxCharacteristic = pService->createCharacteristic(

                                             CHARACTERISTIC_UUID_RX,

                                            BLECharacteristic::PROPERTY_WRITE

                                        );

  pRxCharacteristic->setCallbacks(new MyCallbacks());

  // Start the service

  pService->start();

  // Start advertising

  pServer->getAdvertising()->start();

  Serial.println("Waiting a client connection to notify...");

}

void loop() {

    if (deviceConnected) {

        pTxCharacteristic->setValue(&txValue, 1);

        pTxCharacteristic->notify();

        txValue++;

        delay(10); // Bluetooth stack will go into congestion, if too many packets are sent

    }

    // disconnecting

    if (!deviceConnected && oldDeviceConnected) {

        delay(500); // give the Bluetooth stack the chance to get things ready

        pServer->startAdvertising(); // restart advertising

        Serial.println("start advertising");

        oldDeviceConnected = deviceConnected;

    }

    // connecting

    if (deviceConnected && !oldDeviceConnected) {

        // do stuff here on connecting

        oldDeviceConnected = deviceConnected;

    }

}

One part of the algorithm was responsible for broadcasting a loop of completely random data. One is transmitting information, while the other is receiving it. First, we settled on RX and TX as our two distinguishing features; afterwards, we gave each of them the precise definitions and values we'd come to expect. Since we're using UART, sending and receiving data simultaneously is not a problem. Use the NRF Application to check the functionality of a single end of a connection. Open the NRF Connector app and upload the code above.

Enter the value you wish to transmit to the serial monitor after you have connected. The serial monitor will be updated with your input.

Raspberry Pi Connection

The Raspberry Pi is currently executing a Python script written in bluepy. This code creates a simple GUI for communicating with the esp. 32. The PYQT and bluepy packages need to be installed before continuing. You may run this code to see a graphical user interface as soon as everything is set up. After that, either input the information you wish to transmit to the ESP32 through BLE or view the information sent to the ESP32. It's a universal asynchronous receiver/transmitter (UART) link (universally asynchronous receiver-transmitter).   Incoming info from esp32 will be displayed in the first message box, while outgoing data from Raspberry Pi can be written in the other text box.

As seen on the ESP32 serial connection display, we have the following:

import sys

import time 

import requests

from PyQt5.QtCore import QObject, QRunnable, QThreadPool, QTimer, pyqtSignal, pyqtSlot

from PyQt5.QtWidgets import (

    QApplication, QLabel, QMainWindow,  QPlainTextEdit, QPushButton, QVBoxLayout, QWidget,

    ) 

from bluepy import btle

class WorkerSignals(QObject):

    signalMsg = pyqtSignal(str)

    signalRes = pyqtSignal(str)  

class MyDelegate(btle.DefaultDelegate): 

    def __init__(self, sgn):

        btle.DefaultDelegate.__init__(self)

        self.sgn = sgn

    def handleNotification(self, cHandle, data):

        try:

            dataDecoded = data.decode()

            self.sgn.signalRes.emit(dataDecoded)

        except UnicodeError:

            print("UnicodeError: ", data)

class WorkerBLE(QRunnable):   

    def __init__(self):

        super().__init__()

        self.signals = WorkerSignals()

        self.rqsToSend = False        

    @pyqtSlot()

    def run(self):

        self.signals.signalMsg.emit("WorkerBLE start")  

        #---------------------------------------------

        p = btle.Peripheral("3c:71:bf:0d:dd:6a")

        p.setDelegate( MyDelegate(self.signals) )

        svc = p.getServiceByUUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")

        self.ch_Tx = svc.getCharacteristics("6E400002-B5A3-F393-E0A9-E50E24DCCA9E")[0]

        ch_Rx = svc.getCharacteristics("6E400003-B5A3-F393-E0A9-E50E24DCCA9E")[0]

        setup_data = b"\x01\00"

        p.writeCharacteristic(ch_Rx.valHandle+1, setup_data)

        # BLE loop --------

        while True:

            """

            if p.waitForNotifications(1.0):

                # handleNotification() was called

                continue

            print("Waiting...")

            """       

            p.waitForNotifications(1.0)       

            if self.rqsToSend:

                self.rqsToSend = False

                try:

                    self.ch_Tx.write(self.bytestosend, True)

                except btle.BTLEException:

                    print("btle.BTLEException");           

        #---------------------------------------------hellohello

        self.signals.signalMsg.emit("WorkerBLE end")     

    def toSendBLE(self, tosend):

        self.bytestosend = bytes(tosend, 'utf-8')

        self.rqsToSend = True

        """

        try:

            self.ch_Tx.write(bytestosend, True)

        except BTLEException:

            print("BTLEException");

        """          

class MainWindow(QMainWindow):    

    def __init__(self):

        super().__init__()

        layout = QVBoxLayout()    

        buttonStartBLE = QPushButton("Start BLE")

        buttonStartBLE.pressed.connect(self.startBLE)        

        self.console = QPlainTextEdit()

        self.console.setReadOnly(True)       

        self.outconsole = QPlainTextEdit()        

        buttonSendBLE = QPushButton("Send message")

        buttonSendBLE.pressed.connect(self.sendBLE)

        layout.addWidget(buttonStartBLE)

        layout.addWidget(self.console)

        layout.addWidget(self.outconsole)

        layout.addWidget(buttonSendBLE)

        w = QWidget()

        w.setLayout(layout)       

        self.setCentralWidget(w)   

        self.show()

        self.threadpool = QThreadPool()

        print(

            "Multithreading with Maximum %d threads" % self.threadpool.maxThreadCount())            

    def startBLE(self):

        self.workerBLE = WorkerBLE()

        self.workerBLE.signals.signalMsg.connect(self.slotMsg)

        self.workerBLE.signals.signalRes.connect(self.slotRes)

        self.threadpool.start(self.workerBLE)      

    def sendBLE(self):

        strToSend = self.outconsole.toPlainText()

        self.workerBLE.toSendBLE(strToSend)    

    def slotMsg(self, msg):

        print(msg)      

    def slotRes(self, res):

        self.console.appendPlainText(res)   

app = QApplication(sys.argv)

window = MainWindow()

app.exec()

Industrial applications

When there isn't enough electricity to go around, BLE comes in handy. Let's talk about some of the real-world uses for it:

Intelligent Farming Methods: Battery-powered microcontrollers with ble capabilities, like the ESP32 or Raspberry Pi, can be used for weeks to relay data from sensors from one ESP32 to another to optimize plant development.

In-Game Medical Staff: Using Bluetooth, a microcontroller can transmit data to a mobile phone or show the data locally on a screen, such as a user's heart rate, running speed, or any other data detected by sensors. All of these values can be tracked effectively and with no wire required.

Biomedical Condition Tracking: The BLE capabilities of a microcontroller enables the direct transfer of data from wristbands measuring vital signs like heart rate and blood pressure to a computer.

One of the many benefits of small microcontrollers is home automation. From lighting management to fingerprint door locks, the possibilities for using BLE devices are endless. It has several fascinating uses, including:

  • Alarms that go off at a predetermined time to remind you to turn off the stove, water pump, heater, or geyser

  • Safeguarding with mobile-operated surveillance cameras

  • Remotely operate garage doors using a mobile device

  • Measurements are taken from a variety of home sensors 

Conclusion

Using the information shown here, we successfully established a Bluetooth connection between our Pi 4 and Esp32. We learned about esp32's internals and how to use the Raspberry Pi 4 to write programs for it. In conclusion, ESP32's specifications are adequate to support the vast majority of your proposed uses. If you're looking for an upgrade from the ESP8266, the ESP32 is the next generation and supports Bluetooth 4.2 and Bluetooth Low Energy. It includes additional CPU cores, faster WiFi, more GPIO, and these technologies. In addition to having a hall effect sensor and a temperature sensor already included, the ESP32 also features touch-sensing pins that can rouse the ESP32 from a deep sleep. When increasing output, it's vital to include good specifications but not anything too fancy. To rephrase, using a less expensive microcontroller may be more cost-effective if the intended result can be achieved with more basic specifications. The cost savings become noticeable when output increases by several orders of magnitude. While it may not be the best microcontroller for mass production, the ESP32 is perfect for proof-of-concept development and prototype prototyping. Next, we'll see how to connect a 4-by-4 keypad to a Raspberry Pi 4 for electronic door locks.

Interface Remote Control RF Module (433mhz) with Pi 4

Welcome to the next tutorial of our raspberry pi 4 programming course. The last guide covered connecting a Sharp infrared distance measurement sensor to a Raspberry Pi 4. Infrared (IR) sensors were demonstrated to be widely used for nearby object recognition and motion tracking. But in this session, we'll utilize Raspberry Pi 4 to create a radio-frequency (RF) remote control that can be used to operate the gadgets wirelessly. With the help of this RF remote control, we can Power On/Off the devices.

Components

Transmitter Side

  • RF Transmitter

  • HT12E IC

  • 4 Push Buttons

  • 750k resistor

  • 9 Volt battery

Receiver Side

  • Raspberry Pi

  • 16x2 LCD

  • 10K POT

  • Breadboard

  • 1K Resistor (Five)

  • 33K resistor

  • HT12D IC

  • RF Receiver 

  • LEDs (Five)

  • 4 10K resistor 

  • Jumper wires

RF Module

This ASK Hybrid Transmitter/Receiver module communicates at 433Mhz. For optimal range and frequency stability, this module utilizes a crystal-stabilized oscillator. The module requires only a single external antenna.

This module is for you if you need RF communication over a great distance at a low cost. The high levels of background noise at this frequency and in its Analog technology mean that this module cannot directly transmit data via the UART communication of a PC or microcontroller. Using encoder and decoder ICs, we may utilize this module to retrieve information from background static.

At full Power, a transmitter's range is over 100 meters; at 5 volts, it's around 50-60 meters when employing a single-code wire antenna measuring just 17 centimetres.

There are two primary limitations placed on the wireless system designer: the system must function within a particular range and send a certain quantity of data within a given data rate. The RF module is incredibly compact and can run on a broad voltage spectrum (from 3V to 12V).

Transmitter and receiver RF modules operating at 433 MHz constitute the bulk of the RF modules. Because the carrier frequency is completely suppressed during transmission of logic zero, the transmitter's power consumption is significantly reduced during battery operation. A logic one signal turns the carrier on to around 4.5mA at 3 volts when it is off at 0 volts. The data is transmitted serially from the transmitter to the tuned receiver. Two microcontrollers are suitably interfaced with the transmitter and receiver for communication.

RF Transmitter Features

  • Range of Operation: 433 MHz

  • Power at the Output: 4-16 dBm

  • Power supply input: 3 to 12-volt dc

Pin Description of RF Tx

  • GND stands for "ground," which indicates a supply connection to the earth.

  • Data in - When serial data is received from an encoder, it is input via this pin.

  • VCC - This jack must be wired to Vcc - +5 Volt.

  • Antenna - The data transmission antenna wraps around this pin.

RF Receiver Features

  • The sensitivity is -105 dBm.

  • IF Rate of 1 megahertz.

  • Less need for a power supply.

  • The current is 3.5 mA.

  • Five-volt power source.

Pin Description of RF Rx

  • GND - Ground

  • Data In - This pin give

  • s output serial data to Decoder

  • Vcc - +5 Volt should be connected to this pin

  • Vcc - +5 Volt should be connected to this pin

  • GND - Ground

  • GND - Ground

  • Antenna - A wrapped connection to this pin for proper Reception of data

Encoder IC usage

The output pin on an HT12E is used for its principal purpose, which is to transmit a 12-bit encoded signal. The IC's built-in Oscillator makes it simple to put it to use. The IC may operate from 2.4V – 12V, although in most cases, +5V is supplied to the Vcc (pin 18), while pin 9 is left unconnected. Connect pin 14 (Transmission Enable) to the ground terminal to start the transmission process. This IC has an integrated oscillator, which is necessary for data decoding. To activate it, we need only connect pins 15 and 16 (OSC1 and OSC2) with a 1M resistor. The address, which is 8 bits long, must be established using pins A0–A7, and the data to be transmitted, which is 4 bits long, must be given to pins AD0–AD1. Your Decoder must have the same address for the two devices to communicate. Below is a simple HT12E IC wiring diagram.

Through the use of a series of ground connections on the address pins, I have programmed the eight-bit address data in the circuit above to read 0b00000000. Any eight pins can be made high by connecting it to 5V to improve security. A +5V supply, such as that provided by a voltage regulator such as 7805, is used to power the entire IC. Any Digital IC capable of supplying the required 4-bit data will do, and its pins AD3, AD2, AD1, and AD0 will be linked to those. They can be connected to switches for manual data transmission and Reception. In this example, I have set all four data bits to be zero (low), and the HT12D decoder IC's output will be the same type of bits. Similarly, if we modify these four bits, the HT12D's output will change accordingly.

The Dout pin is where you'll find the encoded 12-bit value (pin 17). The HT12D has to receive this information to decode it, and it can do so via wire or a wireless channel (such as RF or IR). Following this, you will know the necessary to configure the HT12D.

HT12D RF decoder usage.

HT12D's main job is to interpret the 12-bit signal through the input pin. The IC's built-in Oscillator makes it simple to put it to use. The IC's ground (pin 9) and power (pin 18) terminals should be connected to 5V. This IC has an integrated oscillator, which is necessary for data decoding. It's activated by connecting pins 15 and 16 (OSC1 and OSC2) using a 470K resistor. Received data in increments of 4 bits are available on pins AD0 and AD1, and an address in increments of 8 bits must be programmed using pins A0 through A7. The Decoder's address must match the encoder's if you want to use it successfully. See below for a simplified circuit depiction of the HT12D IC.

Through the use of a series of ground connections on the address pins, I have programmed the eight-bit address data in the circuit above to read 0b00000000. Any eight pins can be made high by connecting it to 5V to improve security. A +5V supply, such as that provided by a voltage regulator such as 7805, is used to power the entire IC. Any Digital IC capable of reading 4-bit data will work with the AD3, AD2, AD1, and AD0 pins. As a bonus, they can be hooked up to an LED so you can see the data being transmitted in real-time. Due to the uncertainty of the Encoder IC's Input signal, the four-bit output data is represented as a question mark. If there is any good information received, it can be read off of these four pins.

The HT12E Encoder IC's description is provided to help you learn how to encode a 4-bit data stream for transmission to the IC's input pin.

Working Explanation

In this setup, four buttons on the transmitter side (the remote) activate corresponding LEDs on the receiver side. Whenever one of the four buttons is pressed, a signal is sent to an encoder IC, which then passes it on to a radio frequency (RF) transmitter, which broadcasts it into the surrounding environment. The RF receiver picks up the signal, which then transmits the 4-bit decoded signal to the Raspberry Pi through the Decoder IC HT12D. The Raspberry Pi will then interpret these data snippets, perform the appropriate action, and activate the corresponding LED. Once a key is pressed, a buzzer will sound for one second. In addition, a 16x2 LCD shows whether the LEDs are on or off.

For the demonstration, this project only uses four LEDs; to initiate any action, press the appropriate button on the "RF Remote." The LEDs may be swapped out for AC home appliances via the relay, and the same "RF Remote" can be used to operate both sets of lights wirelessly. Consequently, you may use the same circuit for your RF-based Raspberry Pi-based home automation project. You can see all of the Home Automation Projects we've produced in the past, including Bluetooth, DTMF, GSM control, and more, right here: Home Automation Projects.

Circuit Explanation

This RF remote control for the Raspberry Pi features an easy-to-assemble circuit consisting of just the Pi board, a few buttons, an LCD, an RF pair, and an encoder/decoder IC. Raspberry Pi manages the LCD, processes input, and communicates results. However, any Raspberry Pi model should do in this case; Raspberry Pi 3 was utilized. The circuit consists of an RF receiver section and an RF transmitter section. The below figure depicts both circuits.

LCD pins rs, en, d4, d5, d6, and d7 from the receiver are wired to GPIO pins 11, 10, 6, 5, 4, 1, and 4 in 4-bit Mode. The RF receiver picks up the signal and decodes it by the HT12D IC once it has been sent from the RF transmitter. Decoder IC pins D8, D9, D10, and D11 of the HT12D are linked straight to wiringPI GPIO pins 25, 24, 23, and 22. LEDs are wired to wiringPi GPIO pins 26, 27, 28, and 29 for output. When a key is pressed, the buzzer connected to wiringPi GPIO 0 sounds an alarm.

The HT12E Encoder IC is part of the RF transmitter circuit, with four buttons used to toggle the LEDs on and off. Every address line in an encoder/decoder IC is grounded.

Installation of wiringPi Library in pi 4

To access the Raspberry Pi's GPIO pins in C, we must use the wiringPi Library, much like how Python programmers include the import RPi.GPIO as an IO header file. You can use Terminal or an SSH client like Putty to execute the commands below one by one to complete the installation. If you want more information on how to work with and set up the Raspberry Pi, read our introduction to  Raspberry Pi tutorial.

sudo apt-get install git-core

sudo apt-get update

sudo apt-get upgrade

git clone git://git.drogon.net/wiringPi

cd wiringPi

git pull origin

cd wiringPi

./build

Test the installation of wiringPi Library by using the below commands:

gpio -v

gpio readall

Programming Explanation

We start by including the necessary header files and defining the LCD's pins, and then we initialize certain variables and connection pins for receiving input and displaying LED indications.

#include "wiringpi.h"

#include "wiringserial.h"

#include "stdio.h"

#include "string.h"

#define RS 11

#define EN 10

#define D4 6

#define D5 5

#define D6 4

#define D7 1

#define led1 26

#define led2 27

#define led3 28

#define led4 29

#define buzz 0

#define d1 25

#define d2 24

#define d3 23

#define d4 22

int am = 0;

int flag1=am ,flag2=am ,flag3=am ,flag4=am;

Then, in the void setup() procedures, we tell all the GPIO Pins what to do.

void setup()

{

   if (wiringPiSetup () == -1)

   {

     clear();

     print("Unable to start"); 

     setCursor(0,1);

     print("wiringPi");

   }

  pinMode(led1, OUTPUT);

  pinMode(led2, OUTPUT);

  pinMode(led3, OUTPUT);

  pinMode(led4, OUTPUT);

We have used the digitalRead and digitalWrite functions in the code to receive and send the Decoder's output to an LED and a device, respectively.

while(1)

   {

        setCursor(0,0);

        print("D1  D2  D3  D4");

        if(digitalRead(d1)==0)

        {

          flag1++;

          setCursor(0,1);

          if(flag1%2==1)

          {

            print("ON ");

            digitalWrite(led1,HIGH);

          }

Additional functions utilized in this project are listed below. To send a command to the LCD, use the void lcdcmd method, and to provide data to the LCD, use the void write function. You can call the void clear() function to reset the LCD. The cursor is used to deliver a string to the LCD instead of printing it. To start the LCD up in 4-bit Mode, call the void to begin, and use the void buzzer() function to make the buzzer sound. Find the complete code for this RF remote control using a Raspberry Pi below.

Full code

#include "wiringpi.h"

#include "wiringserial.h"

#include "stdio.h"

#include "string.h"

#define RS 11

#define EN 10

#define D4 6

#define D5 5

#define D6 4

#define D7 1

#define led1 26

#define led2 27

#define led3 28

#define led4 29

#define buzz 0

#define d1 25

#define d2 24

#define d3 23

#define d4 22

int am = 0;

int flag1=am ,flag2=am ,flag3=am ,flag4=am;

  void lcdcmd(unsigned int ch)

  {

    int temp=0x80;

    digitalWrite(D4, temp & ch<<3);

    digitalWrite(D5, temp & ch<<2);

    digitalWrite(D6, temp & ch<<1);

    digitalWrite(D7, temp & ch);

    digitalWrite(RS, LOW);

    digitalWrite(EN, HIGH);

    delay(10);

    digitalWrite(EN, LOW);

    digitalWrite(D4, temp & ch<<7);

    digitalWrite(D5, temp & ch<<6);

    digitalWrite(D6, temp & ch<<5);

    digitalWrite(D7, temp & ch<<4);

    digitalWrite(RS, LOW);

    digitalWrite(EN, HIGH);

    delay(10);

    digitalWrite(EN, LOW);

  }

    void write(unsigned int ch)

  {

    int temp=0x80;

    digitalWrite(D4, temp & ch<<3);

    digitalWrite(D5, temp & ch<<2);

    digitalWrite(D6, temp & ch<<1);

    digitalWrite(D7, temp & ch);

    digitalWrite(RS, HIGH);

    digitalWrite(EN, HIGH);

    delay(10);

    digitalWrite(EN, LOW);

    digitalWrite(D4, temp & ch<<7);

    digitalWrite(D5, temp & ch<<6);

    digitalWrite(D6, temp & ch<<5);

    digitalWrite(D7, temp & ch<<4);

    digitalWrite(RS, HIGH);

    digitalWrite(EN, HIGH);

    delay(10);

    digitalWrite(EN, LOW);

  }

  void clear()

  {

     lcdcmd(0x01);

  }

  void setCursor(int x, int y)

  {

    int set=0;

    if(y==0)

    set=128+x;

    if(y==1)

    set=192+x;

    lcdcmd(set);

  }

  void print(char *str)

  {

    while(*str)

    {


     write(*str);

     str++;

    }

  }

  void begin(int x, int y)

  {

    lcdcmd(0x02);

    lcdcmd(0x28);

    lcdcmd(0x06);

    lcdcmd(0x0e);

    lcdcmd(0x01);

  }

 void buzzer()

{

     digitalWrite(buzz, HIGH);

     delay(1000);

     digitalWrite(buzz, LOW);

}

  void setup()

{

   if (wiringPiSetup () == -1)

   {

     clear();

     print("Unable to start"); 

     setCursor(0,1);

     print("wiringPi");

   }

  pinMode(led1, OUTPUT);

  pinMode(led2, OUTPUT);

  pinMode(led3, OUTPUT);

  pinMode(led4, OUTPUT);

  pinMode(buzz, OUTPUT);

  pinMode(RS, OUTPUT);

  pinMode(EN, OUTPUT);

  pinMode(D4, OUTPUT);

  pinMode(D5, OUTPUT);

  pinMode(D6, OUTPUT);

  pinMode(D7, OUTPUT);

  pinMode(d1, INPUT);

  pinMode(d2, INPUT);

  pinMode(d3, INPUT);

  pinMode(d4, INPUT);

  digitalWrite(led1, LOW);

  digitalWrite(led2, LOW);

  digitalWrite(led3, LOW);

  digitalWrite(led4, LOW);

  digitalWrite(buzz, LOW);

  begin(16,2);

}

//void loop()

void main()

{

   setup();

   clear();

   print("  RF Module ");

   setCursor(0,1);

   print(" Interfacing ");

   delay(2000);

   clear();

   print("Raspberry Pi");

   setCursor(0,1);

   print("Circuit Digest");

   delay(2000);

   clear();

   print("System Ready");

   delay(1000);

   clear();

  setCursor(0,1);

  print("OFF OFF OFF OFF");

   while(1)

   {

        setCursor(0,0);

        print("D1  D2  D3  D4");

        if(digitalRead(d1)==0)

        {

          flag1++;

          setCursor(0,1);

          if(flag1%2==1)

          {

            print("ON ");

            digitalWrite(led1,HIGH);

          }

          else

          {

            print("OFF");

            digitalWrite(led1,LOW);

          }

          buzzer();

          while(digitalRead(d1)==0);

        }

        else if(digitalRead(d2)==0)

        {

          flag2++;

          setCursor(4,1);

          if(flag2%2==1)

          {

            print("ON ");

            digitalWrite(led2,HIGH);

          }

          else

          {

            print("OFF");

            digitalWrite(led2,LOW);

          }

          buzzer();

          while(digitalRead(d2)==0);

        }

         else if(digitalRead(d3)==0)

        {

          flag3++;

          setCursor(8,1);

          if(flag3%2==1)

          { 

            print("ON ");

            digitalWrite(led3,HIGH);

          }

          else

          {

            print("OFF");

            digitalWrite(led3,LOW);

          }

         buzzer();

          while(digitalRead(d3)==0);

        }

        else if(digitalRead(d4)==0)

        {

          flag4++;

          setCursor(12,1);

          if(flag4%2==1)

          {

            print("ON ");

            digitalWrite(led4,HIGH);

          }

          else

          {

            print("OFF");

            digitalWrite(led4,LOW);

          }

          buzzer();

          while(digitalRead(d4)==0);

        }

}

}

Conclusion

Transmitted modules, which plug into the Raspberry Pi, allow for the transmission of radio frequency signals at a range of 433 MHz to remote receivers. Devices like remote controllers, headphones, baby phones, and additional Raspberry Pis can pick up these signals. An RF module's performance will vary from that of other radio-frequency devices depending on several parameters, such as the strength of the transmitter, which directly affects the range of the signal it can collect. The downside is that this will significantly reduce the battery life of the transmitter device. Using this device with a higher transmission power will also cause interference with nearby RF appliances. The subsequent tutorial will cover the Bluetooth connection between a Raspberry Pi 4 and an ESP32.

Interface Sharp Infrared Distance Measurement Sensor with Raspberry Pi 4

Hello friends, I hope all are fine. Today, we are going to share the 3rd chapter of Section-III in our Raspberry Pi Programming Course. In our previous lecture, we interfaced the Soil Moisture Sensor with Raspberry Pi 4. Today, we are going to Interface the Infrared(IR) sensor with RPi4.

IR Sensor is typically employed for the presence/motion detection of objects in the immediate area. With their low power consumption, straightforward design, and user-friendly features, IR sensors are a popular choice for detection purposes. Infrared(IR) impulses are invisible to the naked eye and lie between the visible and microwave parts of the electromagnetic spectrum. So let's get started:

Components Required

To learn how an IR sensor detects the existence of an object, we'll set up a basic circuit to detect any object. The following electronic components are required for this task:

  • Raspberry Pi 4
  • IR sensor module
  • LED
  • Breadboard
  • Jumper wires

What is IR Sensor?

  • The IR sensor(Infrared sensor) consists of a transmitter and a receiver; the transmitter sends out infrared radiations, which are reflected by the barriers/receiver and get back to the receiver of the sensor.
  • The sensor computes the incoming signal and sets the module's output.
  • With an IR sensor and a Raspberry Pi 4, we can see what's around us, how fast things are moving, and how far away things are from the sensor.
  • There are three connections on this IR sensor: Vcc, Ground, and output.
  • Vcc is linked to 5V, Ground is grounded, and output is the pin, from where we read the sensor's data.

Working Principle

An infrared sensor incorporates an infrared LED(light-emitting diode) and a photodiode, which, when joined together, can function as a photo-coupler or optocoupler. This sensor employs Plank's radiation, Stephan Boltzmann, and Wein's displacement principles of physics.

The infrared LED is a transmitter that produces IR radiations. Visually, the IR LED is identical to a regular LED, although the IR radiation is invisible to the naked eye. Radiation sent out by an infrared source is primarily detected by an infrared receiver. Photodiodes are one physical shape that these infrared detectors can take. Unlike regular photodiodes, IR photodiodes only respond to infrared light. Variations in voltage, wavelength, package size, etc., are the primary categories separating the many types of infrared receivers.

The wavelength of the IR receiver must be the same as that of the IR transmitter whenever the two are utilized together. In this case, an infrared LED acts as the sender, and an infrared photodiode acts as the receiver. An infrared LED produces infrared light, which an infrared photodiode can detect. The amount of IR light collected correlates with the photo-resistance diodes and the resulting shift in output voltage. It is on this concept that the IR detector operates.

Some of the infrared radiation sent out by the transmitter will be reflected back to the receiver. The IR receiver can calibrate the sensor output to the level of the response.

Infrared Detector Varieties

You can choose between active or passive IR sensors when shopping for an infrared detector.

  1. Active IR Sensor

The active infrared sensor, we are going to use in today's project, incorporates both the transmitter and the receiver.

These detectors can receive and process data via radiation from an external source. The signal processor can then be used to extract the data that is required for further analysis. The reflectance sensor and the break beam sensor are the two most common active infrared sensors.

  1. Passive IR Sensor

Passive infrared sensors consist solely of detectors and lack any transmitter. A transmitter or infrared source is used in these sensors. An infrared detector can pick up the object's radiation. The signal is then processed by a signal-understanding device to extract the necessary data.

The pyroelectric detector, the bolometer, the thermocouple-thermopile, etc., are all excellent examples of this type of sensor. Thermal infrared sensors and quantum infrared sensors are two examples of these devices. The wavelength is not a factor for the thermal IR detector. For these sensors to function, they use a hot energy source. Infrared quantum sensors have a fast response and detection times; their sensitivity is wavelength-dependent. To take accurate readings, these sensors must be regularly cooled.

Schematic of an Infrared Detector

The infrared sensor is one of the most common and fundamental sensor circuits in modern electronics. One of the most prominent uses for this sensor is obstacle detection. The following elements are used in IR circuit:

  • LM358 IC 2 IR transmitter and receiver pair
  • Resistors of the range of kilo-ohms.
  • Variable resistors.
  • LED (Light Emitting Diode).

An infrared (IR) sensor located in the transmitter part constantly broadcasts IR waves that are picked up by an infrared (IR) receiver module. How the receiver receives IR photons affects what comes out of its IR output terminal. Because this deviation cannot be examined separately, it can be sent into a comparator circuit. An LM339 operational amplifier (op-amp) is employed in this application as a comparator.

Without a signal, the comparator IC's inverting input has a greater potential than its non-inverting counterpart (LM339). As a result, the LED doesn't light up and the comparator's output drops low. The input's inverting potential will drop when the IR receiver module detects an incoming signal. As a result, the comparator's (LM 339) output gets high, and the LED lights up.

The IR LED Devices, such as the Photodiode, require a current of at least 10 mA, which is maintained by Resistors R1 (100), R2 (10k), and R3 (330). Output terminal adjustments are made with resistor VR2 (preset=5k). Circuit sensitivity is adjusted by resistor VR1 (preset=10k). Learn more about IR detectors by reading up on the topic.

A Transistor-Based Infrared Circuit

Below is a schematic of the IR sensor's transistor-based circuit, demonstrating how to use two transistors for obstacle detection. This circuit's primary function is to detect obstacles in the path of an infrared LED. So, two transistors, such as NPN and PNP types, are all you need to use to construct this circuit. Transistors of the BC547 and BC557 types are utilized, respectively, for NPN and PNP operations.

For the above circuit to work, one IR LED must be ON at all times, while the other IR LED is connected to the base terminal of the PNP transistor. Infrared (IR) LEDs-2, 100-ohm, and 200-ohm resistors, BC547 and BC557 transistors, and a simple LED are all needed for this design.

When an infrared LED is identified, a tiny current is distributed through the sensor, thanks to the object's reflected light. By doing so, the NPN and PNP transistors are turned on, and the LED lights up. You may use this circuit to make automatic lamps that turn on when someone walks into the room.

IR Sensor with Raspberry Pi 4

  • The presence-detection circuit is depicted as follows in the schematic:

  • To construct the circuit depicted in the preceding diagram, we will first attach the Pi 4, the IR sensor, and the LED to the breadboard.

  • We'll hook up the Infrared sensor and LED to the Raspberry Pi using the table as a guide.

Python Code for IR Sensor Object Detection with RPi 4

If you want to use the Raspberry Pi's infrared (IR) sensor to identify an object, you'll need to create a Python script; to do so, launch the nano text editor and navigate to the file named "irsensor.py."

nano ir_sensor.py

This is the Python code we will be writing now:

import RPi.GPIO as GPIO

#importing the library of RPi.GPIO

import time

#importing the library of time

sensor = 16

#declaring BCM pin 16, which is GPIO 23 of Raspberry Pi

led = 18

#declaring BCM pin 18, which is GPIO 24 of Raspberry Pi

GPIO.setmode(GPIO.BOARD)

#declaring the BCM mode of pins

GPIO.setup(sensor,GPIO.IN)

#set the behavior of the sensor as input

GPIO.setup(led,GPIO.OUT)

#set the behavior of led as output

try: 

    while True:

        #initiated an infinite while loop

        if GPIO.input(sensor):

            #checking input on the sensor

            GPIO.output(led, False)

            #led turned on

            while GPIO.input(sensor):

                #checking input on the sensor again

                time.sleep(0.2)

                #generate a time delay of 0.2 seconds

        else:

            GPIO.output(led,True)

            #led turned off if there is no input on the sensor

            except KeyboardInterrupt:

            # terminate the program

            GPIO.cleanup()

            #cleanup the GPIO pins for any other program use

Code explanation

Time and the RPi.GPIO library has been imported, and pins 16 and 18 have been designated with the sensor and the LED, respectively. Setmode = GPIO.BOARD; sensor = input; led = output; these PINs correspond to the board's PINs.

Then, when an object is detected, the sensor's input is checked in an infinite while loop to determine whether or not the LED's brightness should increase. Now run the Python file in your terminal, and you should see the led blink when an object is detected.

When the subject is not in range, and the LED is turned off:

The LED will light up as the object passes over the IR sensor.

Uses for Infrared Sensors

Infrared (IR) sensors can be broken down into several categories depending on their intended use. Examples of how various sensor technologies are typically put to use. It is possible to get numerous motors working in unison using a speed sensor. The sensor's temperature readings are used in factories for climate regulation. The passive infrared (PIR) sensor is employed in an automated door opening system, whereas the ultrasonic (US) sensor measures distance.

The infrared (IR) sensors detailed below can be found in various sensor-based applications and electrical gadgets.

  1. Radiation Thermometers

Features of radiation thermometers, which use infrared (IR) sensors to determine an object's temperature, vary with the object's material and temperature.

  • remote sensing and measurement, where no physical contact is required

  • quicker response

  • Simple Pattern Sizing

  1. Flame Monitors

The light given off by the flames may be detected, and the fire's progress can be tracked with such gadgets. Flames emit a wide spectrum of light, from ultraviolet to infrared. Numerous types of detectors, including PBS, PbSe, Two-color detectors, and pyroelectric detectors, are utilized in flame monitors.

  1. Gas Analyzers

Gas analyzers use IR sensors to analyze gas based on their absorption characteristics in the IR region. Two techniques are utilized: dispersive and non-dispersive. In the dispersive method, the emitted light is separated spectroscopically, and the absorption is analyzed to determine the gas composition and sample quantity. The non-dispersive method, also known as NDIR technology, is the more widely used technique. It employs optical filters similar to sunglasses to filter out unwanted radiation and determines the absorption without spectroscopically separating the emitted light. NDIR analyzers are commonly used for carbonated drinks, while non-dispersive analyzers are frequently used for automotive exhaust gas analysis and fuel leak detection.

  1. IR Imaging Devices

An IR imaging device generally applies IR waves due to its invisible property. It finds use in thermal cameras, night vision equipment, and others. All objects, including water, rocks, soil, vegetation, the atmosphere, and human tissue, emit IR radiation, which the Thermal infrared sensors measure within the IR spectrum to create a map of the object/area's temperature distribution. Thermal cameras are often made up of Sb (indium antimonite), Gd Hg (mercury-doped germanium), and Hg Cd Te (mercury-cadmium-telluride) sensors. 

Conclusion

The IR sensor's transmitter continuously sends out infrared beams, which bounce back when they encounter an object. The receiver of the IR module then detects these beams, resulting in a high output from the IR sensor. IR technology has various applications in daily life and industries, such as televisions, where an IR sensor detects signals from a remote control. In this article, we have integrated the IR module with the Raspberry Pi 4 and demonstrated the functioning of the IR module through a simple object detection project.

So, that was all for today. In the next lecture, we will interface PIR Sensor with Raspberry Pi 4. Till then, take care. Have fun!!!

Interface a Ws2812 RGB with Raspberry Pi 4

Thank you for joining us today for our in-depth Raspberry Pi programming tutorial. The previous guide covered the steps necessary to connect a fingerprint scanner to a Raspberry Pi 4. In addition, we developed a python script to complement the sensor's ability to identify fingerprints. Yet, in this guide, we'll discover how to interface a ws2812 RGB to a Raspberry Pi 4.

Bright, colorful lights are the best, and this tutorial shows you how to set up Fully Configurable WS2812B led strips to run on a Pi 4 computer as quickly and flexibly as possible. In that manner, you can have the ambiance of your home reflect your tastes.

In most cases, when people talk about a "WS2812B Strip," they mean a long piece of extensible PCB with a bunch of different RGB LED Nodes spread out and dotting all along the top. As a bonus, WS2812B strips can be addressed individually. Each RGB node can independently set its own color and brightness. The functionality of non-addressable RGB strips will be identical to that of WS2812B strips. WS2812B Strips are superior in every way, allowing for more imaginative LED light shows. It is possible to create more complex animations, stripes, and chases by individually programming the actions of each LED Node.

The "WS" in WS2812B indicates that this is the second major revision of this design; "World Semi" refers to the chip's original equipment manufacturer, "2812" to its specific part number, and "B" to its revision number. Each WS2812B LED Node contains an integrated circuit chip, as shown below.

Fully Configurable Strip LEDs now come in wide varieties. It's important to remember whether the strip operates on 5 volts or 12-volt power. To power our 5V-powered Raspberry Pi Computer, we need to use a 5V power supply. Or we'll have to install extra gear to meet the 12v Dc power specifications. LED Node densities also vary across WS2812B LED strips. Since our strip consists of WS2812B nodes soldered onto rigid PCBs, it may also be controlled by the Python script included in this article. ws2812B LED strips are the ideal LEDs to use because of the benefits above. What this manual entails is listed below.

The control mechanism implemented in this tutorial works with WS2812B LED nodes, whether they are rigidly coupled on a PCB or flexibly arranged over a long strip. No prior experience with Raspberry Pi has required, thanks to our comprehensive online raspberry pi 4 for the introduction. You should be able to follow these guidelines if you've read at least chapter 1. 

Where To Buy?
No.ComponentsDistributorLink To Buy
1Jumper WiresAmazonBuy Now
2Raspberry Pi 4AmazonBuy Now

WS2812B protocol

Let's go over the protocol for these addressable LEDs so you can see how they function. Each WS2812B unit's red, green, and blue LEDs can be independently controlled to one of 256 brightness levels. Each LED module needs 24 bits of data or three groups of eight brightness bits. Here's a quick rundown of the steps involved:

  • The first LED in the string receives this data stream from the microcontroller, which consists of eight green bits, eight red bits, and eight blue bits.

  • In the case of several LEDs, the data sequence for the second LED begins with green, red, and blue information immediately after the information for the first LED. The process repeats itself until each LED is turned on.

  • The first LED acts as a receiver for data for all subsequent LEDs in the chain and then sends that data to the second LED without applying the same sequence.

  • When the original "number one" LED unit runs out of binary LED sequences, it passes the baton to the next available unit.

What You Need

What follows are detailed instructions for configuring a single Raspberry Pi board to manage many individually addressable LEDs.

  • A pi 4

  • 5v led strip

  • A DC barrel jack to 2-pin terminal block adapter. 

More than 30 WS2812B strip Nodes will necessitate the usage of an external power supply. Even with highly efficient LEDs, producing brilliant light takes a lot of energy. On average, each pixel will consume 20mA, and while projecting white light at full brightness, each pixel will consume 60mA. This information shows us that 30 Pixels can consume 600mA on average and 1.8A at full brightness. As a side note, staring directly into a room with the lights set to full white causes blind spots in my vision. Because of this, I typically set the brightness of my WS2812B lights to 20%. Ensure your WS2812B strip's power source is adequate for the illumination level you intend to achieve.

In today's world, 3.3V data logic is compatible with most WS2812B LED nodes. The GPIO Pins on a Raspberry Pi have an operational voltage range of 0 to 3.3V; therefore, this works out perfectly. This surface-mounted WS2812B strip Node has seen five minor changes since its inception. Since the earlier WS2812B strip can only work on 5V Data Logic, a logical level shifter may be necessary if you're experiencing strange or intermittent issues.

Assembling Hardware

We'll configure our Raspberry PI to look and act like a desktop PC because that's how most people use computers at home and because it's the most user-friendly setup for novice makers. To convert our Raspberry Pi into a desktop computer, we'll need to install a micro-SD card pre-flashed with the operating system. Then hook it up to a monitor via HDMI and a mouse/keyboard combo. Also, this is a good moment to install a small heatsink on the Raspberry Pi Board's central processing unit IC. Look at the image below to see the setup adjacent to a short WS2812B LED strip with three wires protruding from it. The WS2812B has three wires that have not yet been connected to the Raspberry Pi. WS2812B LED Strip PCBs are often marked with arrows to indicate the direction of data flow. It is a common problem in troubleshooting when this is ignored.

How to Configure Hardware for WS2812B Chains with fewer than 30 Nodes We need to plug in the 5V WS2812B Strip's three wires to the Raspberry Pi before turning the power on. Link the Raspberry Pi's 5V Power Input Pin with the Red Power Cable. Join the white wire labeled "Ground" to the Pi's Ground pin. Join the Raspberry Pi's Green Input Pin to its GPIO 18 port. It is important to remember that the Green Input Pin could be any GPIO pin as long as the appropriate adjustments are made in your Python programs. In this manual, GPIO 18 will be used for the Data Line in all scripts. The picture below shows how these three wires are joined together. This straightforward system can provide power and data transmission for a limited amount of LEDs.

Hardware Configuration for a WS2812B Strip with more than 30 Nodes in Length. However, the Pi 4 Power Pin Out is not powerful enough to power a full LED strip. It's important to know the power requirements of fully addressable WS2812B LEDs, especially when used in large quantities. 150 fully illuminated RGBW LEDs should be manageable by a high-quality 5v 4A power supply.

Following the diagram below, we will connect a 5V 4A power source via a DC barrel jack. Our WS2812B LEDs are pre-soldered with one green data wire, two red power wires, and two white ground wires. The white wire should be attached to the DC barrel jack's negative terminal using a screwdriver. Join the Red Wire to the Terminal With the Positive Screw Down. The White Connectors all link to one other, indicating a Common Ground shared by the Raspberry Pi and the power source. The two devices can't be connected without ground, which will prevent voltage fluctuations and data transmission mistakes.

Furthermore, the WS2812B Strip is no longer connected to the Pi 4 computer via a red power wire. We have found an alternative to using a Raspberry Pi to run our system. See the diagram below for details on connecting a Raspberry Pi to a string of WS2812B LEDs so that they may be controlled remotely.

There are several great best practices to keep in mind if you're planning on powering many LED strips. If you need to run more than a 5-meter roll of LEDs, I recommend consulting the adafruit documentation on the subject. It's important to think about heat and currents.

Now that everything is hooked up how you like it, you can turn on the Pi 4 System by inserting a USB-C cable.

Set up of software.

You'll need to install a few packages if you're starting with a clean install of Raspberry Pi OS. Since this is the case, WS2812B LEDs will function properly. When you plug the Raspberry Pi into an electrical outlet and finish the initial boot-up wizard, you will be taken to the operating system's familiar desktop.

Click the black button in the upper left corner to open a new terminal window. An interactive terminal will launch. Below is a picture of this happening, with a huge red arrow indicating the pressed terminal icon.

With this terminal window, we can search for specific programs and download them from the internet. Here are the command lines you use in the terminal to install everything you need. Type | Y | to confirm installs if prompted.

sudo pip3 install rpi_ws281x

sudo pip3 install adafruit-circuitpython-neopixel

sudo python3 -m pip install --force-reinstall adafruit-blinka

You now have the software and programming packages installed on your Device to power and run WS2812B properly.

Flashing led demonstration

You may trigger the Raspberry Pi to turn on the associated WS2812B LED strips in various ways. To begin, I will utilize the simplest and quickest technique, which involves hooking up this Raspberry Pi to a monitor, mouse, and keyboard so that I can execute Python scripts directly to control it. Below, you'll find the best and most fun Python script to start with: | strandtest.py |. Even though it's far more involved than the rest of the Python scripts in this tutorial, we felt it was essential to include it first because it provides a comprehensive overview of the various possible patterns and lighting styles.

import time

from rpi_ws281x import *

import argparse

LED_COUNT      = 30     

LED_PIN        = 18      

LED_FREQ_HZ    = 800000  # LED signal frequency in hertz (usually 800khz)

LED_DMA        = 10      # DMA channel to use for generating a signal (try 10)

LED_BRIGHTNESS = 65      # Set to 0 for darkest and 255 for brightest

LED_INVERT     = False   # True to invert the signal (when using NPN transistor level shift)

LED_CHANNEL    = 0       # set to '1' for GPIOs 13, 19, 41, 45 or 53

def colorWipe(strip, color, wait_ms=50):

    """Wipe color across display a pixel at a time."""

    for i in range(strip.numPixels()):

        strip.setPixelColor(i, color)

        strip.show()

        time.sleep(wait_ms/1000.0)

def theaterChase(strip, color, wait_ms=50, iterations=10):

    """Movie theater light style chaser animation."""

    for j in range(iterations):

        for q in range(3):

            for i in range(0, strip.numPixels(), 3):

                strip.setPixelColor(i+q, color)

            strip.show()

            time.sleep(wait_ms/1000.0)

            for i in range(0, strip.numPixels(), 3):

                strip.setPixelColor(i+q, 0)

def wheel(pos):

    """Generate rainbow colors across 0-255 positions."""

    if pos < 85:

        return Color(pos * 3, 255 - pos * 3, 0)

    elif pos < 170:

        pos -= 85

        return Color(255 - pos * 3, 0, pos * 3)

    else:

        pos -= 170

        return Color(0, pos * 3, 255 - pos * 3)

def rainbow(strip, wait_ms=20, iterations=1):

    """Draw rainbow that fades across all pixels at once."""

    for j in range(256*iterations):

        for i in range(strip.numPixels()):

            strip.setPixelColor(i, wheel((i+j) & 255))

        strip.show()

        time.sleep(wait_ms/1000.0)

def rainbowCycle(strip, wait_ms=20, iterations=5):

    """Draw rainbow that uniformly distributes itself across all pixels."""

    for j in range(256*iterations):

        for i in range(strip.numPixels()):

            strip.setPixelColor(i, wheel((int(i * 256 / strip.numPixels()) + j) & 255))

        strip.show()

        time.sleep(wait_ms/1000.0)

def theaterChaseRainbow(strip, wait_ms=50):

    """Rainbow movie theater light style chaser animation."""

    for j in range(256):

        for q in range(3):

            for i in range(0, strip.numPixels(), 3):

                strip.setPixelColor(i+q, wheel((i+j) % 255))

            strip.show()

            time.sleep(wait_ms/1000.0)

            for i in range(0, strip.numPixels(), 3):

                strip.setPixelColor(i+q, 0)

# Main program logic follows:

if __name__ == '__main__':

    # Process arguments

    parser = argparse.ArgumentParser()

    parser.add_argument('-c', '--clear', action='store_true', help='clear the display on exit')

    args = parser.parse_args()

    # Create NeoPixel object with appropriate configuration.

    strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)

    # Intialize the library (must be called once before other functions).

    strip.begin()

    print ('Press Ctrl-C to quit.')

    if not args.clear:

        print('Use "-c" argument to clear LEDs on exit')

    try:

        while True:

            print ('Color wipe animations.')

            colorWipe(strip, Color(255, 0, 0))  # Red wipe

            colorWipe(strip, Color(0, 255, 0))  # Blue wipe

            colorWipe(strip, Color(0, 0, 255))  # Green wipe

            print ('Theater chase animations.')

            theaterChase(strip, Color(127, 127, 127))  # White theater chase

            theaterChase(strip, Color(127,   0,   0))  # Red theater chase

            theaterChase(strip, Color(  0,   0, 127))  # Blue theater chase

            print ('Rainbow animations.')

            rainbow(strip)

            rainbowCycle(strip)

            theaterChaseRainbow(strip)

    except KeyboardInterrupt:

        if args.clear:

            colorWipe(strip, Color(0,0,0), 10)

Get started with Python using an IDE like Thonny IDE. You can use any Python Interpreter you like, as Thonny IDE is one of many. Thonny IDE can be accessed through the Application Menu under the Programming submenu. Then, copy the above code inside Thonny Python Editor and save it as strandtest.py on your desktop. Proceed by clicking the large green Run button. See what happens when you do that in the image below.

With that, you should see vibrant hues coming from your LED strip. If individual LEDs on your WS2812B LED Strip aren't lighting up, but the others are, open the Python script, locate the variable labeled LED COUNT, and raise its value till it's in line with the number of LEDs on your strip. The script can be saved and re-run by clicking the Run button. To accommodate the enormous quantity of WS2812B LED Strip, I set this variable to 150. In the next image, you can see a long WS2812B strip that has been wired to an external power source and is controlled by the modified Python script.

Basic Code for WS2812B LED Tape

Now you can check if your Device is properly constructed and functioning with the help of the above strandtest.py script. Moreover, the resulting illumination is just breathtaking. Maker may be left wanting more, though. This is of special importance to the readability of the code, which facilitates its adaptation to specific tasks. This section will show you how to control the WS2812B strip with a few basic Python programs easily modified to suit your needs.

To get started, look at OneStripNeopixels.py, a very basic WS2812B Control Script.

import time

import board

import neopixel

#Initialise, a strips variable, provide the GPIO Data Pin

# utilized and the amount of LED Nodes on the strip and brightness (0 to 1 value)

pixels1 = neopixel.NeoPixel(board.D18, 55, brightness=1)

#Also, create an arbitrary count variable

x=0

pixels1.fill((0, 220, 0))

#LED Node 10 and the color Blue were selected

pixels1[10] = (0, 20, 255)

#Showing a different color

time.sleep(4)

#Below will loop until variable x has a value of 35

while x<35:

    pixels1[x] = (255, 0, 0)

    pixels1[x-5] = (255, 0, 100)

    pixels1[x-10] = (0, 0, 255)

    #Add 1 to the counter

    x=x+1

    #Add a small time pause which will translate to 'smoothly' changing color

    time.sleep(0.05)

#Below section is the same process as the above loop, just in reverse

while x>-15:

    pixels1[x] = (255, 0, 0)

    pixels1[x+5] = (255, 0, 100)

    pixels1[x+10] = (0, 255, 0)

    x=x-1

    time.sleep(0.05)

#Add a brief time delay to appreciate what has happened    

time.sleep(4)

#Complete the script by returning all the LEDs to the off

pixels1.fill((0, 0, 0))

The Python script has been thoroughly commented on, so you should have no trouble following along. The script in the previous paragraph includes readily apparent dials and switches. You'll learn the fundamentals of making a captivating LED Pattern, including how to adjust the number of LED Nodes, the brightness of the LED strips, whether to illuminate the entire board or just a section of it and how to illuminate individual LEDs. Each Node color can be customized by entering a corresponding Red, Blue, or Green numeric value. A number can have any value between zero and 255. The term "RGB Color Code" is commonly used to describe this. While experimenting with different hues can be a lot of fun, the best method to find the precise shade you need is to use a website that lists RGB color codes. Choose any color on this site, and you'll get its corresponding RGB color code in three numbers. After you've located the three-digit color code, you can easily enter it into the Python program.

You can copy and paste the script into Thonny IDE and run it. Once you've saved the file, you can press the run button to activate the script. Below are some screenshots displaying the output.

Control Several LED Strips at Once

Next is to hook up a few different LED Strips to the Pi 4 SBC and run a Python script to manage everything. Hardware-wise, I've replicated the procedure described in Hardware Configuration for Small, fewer than 30 Nodes long WS2812B, adding a second, similarly-sized WS2812B LED Strip.

I wired an additional WS2812B strip of lights up to the GPIO in the manner described below. The Raspberry Pi's other 5V Pin was connected to the red power line. The Raspberry Pi's White Ground Wire was attached to the board's second Ground Port. In this case, GPIO 21 received the green data wire. Check out the diagram of the wired components below; using two WS2812B LED strips of varying density is fine.

Using Thonny IDE as previously, run the python script titled TwoStripsNeopixels.py to control these two WS2812B Strips in a no-frills fashion. Look at this thoroughly documented Python script down here.

#include all necessary packages to get LEDs to work with Raspberry Pi

import time

import board

import neopixel

#Initialise two strips variables, provide the GPIO Data Pin

# utilized and the amount of LED Nodes and brightness (0 to 1 value)

pixels1 = neopixel.NeoPixel(board.D18, 30, brightness=1)

pixels2 = neopixel.NeoPixel(board.D21, 6, brightness=1)

#Focusing on a particular strip, use the command Fill to make it all a single color

#based on decimal code R, G, B. Number can be anything from 255 - 0. Use an RGB Colour

#Code Chart Website to quickly identify a desired fill color.

pixels1.fill((0, 255, 0))

pixels2.fill((0, 0, 255))

#Sleep for one second, and then code repeats for different color combinations. Light changes

#Could happen instead in response to certain buttons being pressed or due to threshold values

time.sleep(1.5)

pixels1.fill((200, 200, 0))

pixels2.fill((0, 200, 200))

time.sleep(1.5)

pixels1.fill((50, 70, 215))

pixels2.fill((215, 50, 70))

time.sleep(1.5)

pixels1.fill((0, 0, 0))

pixels2.fill((0, 0, 0))

Note that a Pi 4Computer has four Data Wire locations that can control individual WS2812B LED Strips, provided the corresponding Python script is updated correctly. The pinouts are numbered as follows: GPIO18, GPIO21, GPIO12, and GPIO10. With some tweaking and development of this technique, you can use a single Raspberry Pi as a standalone controller for four individually addressable WS2812B strips.

Ensure the right number of LED Nodes has been assigned to both LED WS2812B Strips before running the script. Once the script is ready to be executed, click the Thonny IDE's large green Run button. Both strands will suddenly come to life, each filled with a unique color. In the picture below, you can see this in action.

Conclusion

In this tutorial, we looked at connecting a WS2812B led strip to a Raspberry Pi. We also programmed the LEDs to blink in various patterns and colors using Python. You may now explore with your raspberry pi and these led strips to create patterns or whatever you like. Next, we'll look at connecting a Pi 4 to a sharp infrared distance measurement sensor.

Interface a Fingerprint Sensor with Raspberry Pi 4

Hello friends, I hope you all are going great. Today, I am going to share the 10th tutorial of Section-III in our Raspberry Pi Programming Course. In our previous tutorial, we interfaced a Gas Sensor MQ-2 with Raspberry Pi 4. Today, we will be interfacing a Fingerprint Sensor with Raspberry Pi today.

After appearing only in science fiction films until recently, fingerprint sensors are often employed to confirm an individual's identity in various contexts. Today, fingerprint-based systems are used for everything from checking in at the office to verifying an employee's identity at the bank, withdrawing cash from an ATM, and proving one's identity at a government agency. For identifying purposes, fingerprint-detecting technology has been used for some time now.

Fingerprint recognition systems, in general, have advantages over other biometric technologies in terms of speed, affordability, and reliability. Ridges on a fingerprint model make for distinctive whorls and loops, making each fingerprint one-of-a-kind.

There are five different kinds of fingerprints: the whorl, the right circle, the left loop, the tented, and the arch. Most fingerprint identification systems have difficulty telling similar fingerprint types apart. Numerous fingerprint recognition methods exist, and neural networks are utilized to find ridge ends and other details needed to find a match.

Project Description

In today's project, we will design a security system using an optical fingerprint sensor with Raspberry Pi 4. We will use a 16x2 LCD to display the results. Moreover, we will use four buttons: one to enroll a new fingerprint, one to delete a previously stored one, and two more to adjust the index position of fingerprints currently in use.

When the fingerprint reader is ready to accept a finger for matching, an LED will light up. When the user will place his finger on the sensor, the sensor will start scanning it. If the fingerprint matches with any of the stored prints, the lock will open up, otherwise, it will generate a warning.

Components Required

These are the components required to design a fingerprint-based security system using Raspberry Pi 4:

  • Raspberry Pi 4
  • USB to Serial converter
  • Fingerprint Module
  • Push buttons
  • 16x2 LCD (Optional)
  • Bread Board
  • Jumper wires
  • LED
  • 10k pot
  • Resistor 150 ohm -1 k ohm

What is the Fingerprint Scanner?

  • A fingerprint scanner is an electronic/optical sensor, used to scan and detect fingerprints.
  • It can enroll multiple fingerprints in its built-in memory, a normal sensor can save around 100 fingerprints in its database.
  • Moreover, it also has the capability to match a fresh fingerprint with the fingerprints in its database.
  • This device's unique fingerprint biometric technology allows for increased precision, superior performance, and unbreakable security.

If you're concerned about safety, a fingerprint scanner is an excellent alternative to a keycode because the password can be easily scanned but is challenging to get a person's fingerprint. Therefore, normally a fingerprint scanner/reader in conjunction with biometric software for verification, identification, and authentication is used in highly secured places.

Optical, ultrasonic, and capacitive fingerprint readers are the three most typical kinds today. We used optical fingerprint sensors. It uses a camera-like gadget to snap an image of a fingerprint on a glass surface from a predetermined distance. Some optical sensors have added components of primitive artificial intelligence to verify that a living finger is being put on the reader, providing an extra layer of protection.

Fingerprint Sensor Working Principle

Processing plays a crucial role in the fingerprint sensor's operation. There are two essential parts of fingerprint processing i.e.

  • Enrollment of Fingerprint.
  • Matching of Fingerprint.

Each user must place their finger twice during the enrollment process.

This way, the system verifies the fingerprints for processing, creates a fingerprint pattern and saves the information. While in the matching process, the user lays a finger on the sensor and the system checks it against the templates stored in its memory.

Circuit Diagram of Fingerprint Sensor with Raspberry Pi 4

  • The fingerprint module, we are using is UART-based. So, we need to connect a USB-to-Serial adapter to connect the fingerprint module to the Raspberry Pi.
  • Here's the circuit diagram of the Fingerprint Sensor with Raspberry Pi 4:


So, let's design it on real hardware. It's easy to set up:

  • We used a USB-to-serial converter to link the Raspberry Pi's USB port with the fingerprint module.
  • All notifications are shown on a 16x2 LCD.
  • LCDs often have a 10k pot for adjusting contrast.
  • Each 16x2 LCD's RS, EN, d4, d5, d6, and d7 connections are wired to the Raspberry Pi GPIO pin: 18, 23, 24, 25, 8, and 7 respectively.
  • GPIO 5, 6, 13, and 19 on the Raspberry Pi are wired to four buttons.
  • LED is wired to RPI's Pin 26.
  • Here are the images of our hardware setup:

Fingerprint Sensor Python Library Installation

Now that we've finished hooking everything up, we can power on the Raspberry Pi and open the terminal. Now, let's look at how to install a fingerprint library for the Python code:

  • Step 1: This library requires administrator access to be installed. So, let's use the following command to get root access:

sudo bash

  • Step 2: Then, using the provided commands, you may download the necessary packages:

wget –O – http://apt.pm-codeworks.de/pm-codeworks.de.gpg | apt-key add –

wget http://apt.pm-codeworks.de/pm-codeworks.list -P /etc/apt/sources.list.d/

  • Step 3: The next step is to update our Pi 4 and deploy the acquired fingerprint sensor library:

sudo apt-get update

sudo apt-get install python-fingerprint –yes

  • Step 4: Once the library has been installed, you can verify the USB port where your fingerprint reader is attached by typing the following command:

ls /dev/ttyUSB*

On the other side of the screen, change the USB port number with the number of the USB connection you have.

Python Code For Fingerprint Sensor

Python code Operation

Running the Python code will display some introductory prompts on the LCD, after which the user will be instructed to place a finger on the fingerprint reader. Now if the fingerprints are matched with the stored prints in the sensor's database. LCDs will read something like "Fount at Pos:2" if your fingerprint has been stored there, or "No Match Found" if it has not been.

Users can enroll a fingerprint by pressing the register button and then reading the on-screen prompts.

If you want to erase a fingerprint, LCD will ask where it is located. The user can now erase a previously saved fingerprint by selecting it using the two increment/decrement push buttons and then pressing the enroll button (which now acts as the Ok button). Watch the video that is provided as part of the final deliverable to get a better grasp on the subject.

Python Code Designing

Using the fingerprint library methods in Python, connecting a fingerprint sensor with the Raspberry Pi is a breeze. If the user insists on creating the interface on their own, things could get tricky.

Since we already used the library, all that's left to do is call the appropriate library function. Defining the pins for the LCD, LED, and push buttons requires first importing libraries of fingerprint, GPIO, and time into the code.

import time

from pyfingerprint.pyfingerprint import PyFingerprint

import RPi.GPIO as gpio

RS =18

EN =23

D4 =24

D5 =25

D6 =8

D7 =7

enrol=5

delet=6

inc=13

dec=19

led=26

HIGH=1

LOW=0

  • The following step is to initialize and assign functions to the pins:

gpio.setwarnings(False)

gpio.setmode(gpio.BCM)

gpio.setup(RS, gpio.OUT)

gpio.setup(EN, gpio.OUT)

gpio.setup(D4, gpio.OUT)

gpio.setup(D5, gpio.OUT)

gpio.setup(D6, gpio.OUT)

gpio.setup(D7, gpio.OUT)

gpio.setup(enrol, gpio.IN, pull_up_down=gpio.PUD_UP)

gpio.setup(delet, gpio.IN, pull_up_down=gpio.PUD_UP)

gpio.setup(inc, gpio.IN, pull_up_down=gpio.PUD_UP)

gpio.setup(dec, gpio.IN, pull_up_down=gpio.PUD_UP)

gpio.setup(led, gpio.OUT)

  • Having successfully initialized the fingerprint sensor, let's move on:

try:

    f = PyFingerprint('/dev/ttyUSB0', 57600, 0xFFFFFFFF, 0x00000000)

    if ( f.verifyPassword() == False ):

        raise ValueError('The given fingerprint sensor password is wrong!')

except Exception as e:

    print('Exception message: ' + str(e))

    exit(1)

  • We've built some functions to initialize and control the LCD; the complete code is included below.

def begin(), def lcdcmd(ch), def lcdwrite(ch), def lcdprint(Str), def setCursor(x,y)

We have placed fingerprint enrolling, searching, and erasing functions after completing the authoring of all LCD driver functions.

  • Call the def enrollFinger() method to enroll or save fresh fingerprints.
  • The def searchFinger() function retrieves fingerprints from a database.
  • When the appropriate button is pressed, the def deleteFinger() function is called to remove the already stored fingerprint.

The Python source code for all of the functions above is included below.

Next, we'll ask the user to place their finger on the sensor to verify their identity, and the system will determine if that print is valid before displaying the findings.

begin()

lcdcmd(0x01)

lcdprint("FingerPrint ")

lcdcmd(0xc0)

lcdprint("Interfacing ")

time.sleep(3)

lcdcmd(0x01)

lcdprint("Circuit Digest")

lcdcmd(0xc0)

lcdprint("Welcomes You  ")

time.sleep(3)

flag=0

lcdclear()

while 1:

    gpio.output(led, HIGH)

    lcdcmd(1)

    lcdprint("Place Finger")

    if gpio.input(enrol) == 0:

        gpio.output(led, LOW)

        enrollFinger()

    elif gpio.input(delet) == 0:

        gpio.output(led, LOW)

        while gpio.input(delet) == 0:

            time.sleep(0.1)

        deleteFinger()

    else:

        searchFinger()

Output

Complete code

import time

from pyfingerprint.pyfingerprint import PyFingerprint

import RPi.GPIO as gpio

RS =18

EN =23

D4 =24

D5 =25

D6 =8

D7 =7

enrol=5

delet=6

inc=13

dec=19

led=26

HIGH=1

LOW=0

gpio.setwarnings(False)

gpio.setmode(gpio.BCM)

gpio.setup(RS, gpio.OUT)

gpio.setup(EN, gpio.OUT)

gpio.setup(D4, gpio.OUT)

gpio.setup(D5, gpio.OUT)

gpio.setup(D6, gpio.OUT)

gpio.setup(D7, gpio.OUT)

gpio.setup(enrol, gpio.IN, pull_up_down=gpio.PUD_UP)

gpio.setup(delet, gpio.IN, pull_up_down=gpio.PUD_UP)

gpio.setup(inc, gpio.IN, pull_up_down=gpio.PUD_UP)

gpio.setup(dec, gpio.IN, pull_up_down=gpio.PUD_UP)

gpio.setup(led, gpio.OUT)

try:

    f = PyFingerprint('/dev/ttyUSB0', 57600, 0xFFFFFFFF, 0x00000000)

    if ( f.verifyPassword() == False ):

        raise ValueError('The given fingerprint sensor password is wrong!')

except Exception as e:

    print('Exception message: ' + str(e))

    exit(1)

def begin():

  lcdcmd(0x33) 

  lcdcmd(0x32) 

  lcdcmd(0x06)

  lcdcmd(0x0C) 

  lcdcmd(0x28) 

  lcdcmd(0x01) 

  time.sleep(0.0005)

def lcdcmd(ch): 

  gpio.output(RS, 0)

  gpio.output(D4, 0)

  gpio.output(D5, 0)

  gpio.output(D6, 0)

  gpio.output(D7, 0)

  if ch&0x10==0x10:

    gpio.output(D4, 1)

  if ch&0x20==0x20:

    gpio.output(D5, 1)

  if ch&0x40==0x40:

    gpio.output(D6, 1)

  if ch&0x80==0x80:

    gpio.output(D7, 1)

  gpio.output(EN, 1)

  time.sleep(0.005)

  gpio.output(EN, 0)

  # Low bits

  gpio.output(D4, 0)

  gpio.output(D5, 0)

  gpio.output(D6, 0)

  gpio.output(D7, 0)

  if ch&0x01==0x01:

    gpio.output(D4, 1)

  if ch&0x02==0x02:

    gpio.output(D5, 1)

  if ch&0x04==0x04:

    gpio.output(D6, 1)

  if ch&0x08==0x08:

    gpio.output(D7, 1)

  gpio.output(EN, 1)

  time.sleep(0.005)

  gpio.output(EN, 0)

def lcdwrite(ch): 

  gpio.output(RS, 1)

  gpio.output(D4, 0)

  gpio.output(D5, 0)

  gpio.output(D6, 0)

  gpio.output(D7, 0)

  if ch&0x10==0x10:

    gpio.output(D4, 1)

  if ch&0x20==0x20:

    gpio.output(D5, 1)

  if ch&0x40==0x40:

    gpio.output(D6, 1)

  if ch&0x80==0x80:

    gpio.output(D7, 1)

  gpio.output(EN, 1)

  time.sleep(0.005)

  gpio.output(EN, 0)

  # Low bits

  gpio.output(D4, 0)

  gpio.output(D5, 0)

  gpio.output(D6, 0)

  gpio.output(D7, 0)

  if ch&0x01==0x01:

    gpio.output(D4, 1)

  if ch&0x02==0x02:

    gpio.output(D5, 1)

  if ch&0x04==0x04:

    gpio.output(D6, 1)

  if ch&0x08==0x08:

    gpio.output(D7, 1)

  gpio.output(EN, 1)

  time.sleep(0.005)

  gpio.output(EN, 0)

def lcdclear():

  lcdcmd(0x01)

def lcdprint(Str):

  l=0;

  l=len(Str)

  for i in range(l):

    lcdwrite(ord(Str[i]))

def setCursor(x,y):

    if y == 0:

        n=128+x

    elif y == 1:

        n=192+x

    lcdcmd(n)

def enrollFinger():

    lcdcmd(1)

    lcdprint("Enrolling Finger")

    time.sleep(2)

    print('Waiting for finger...')

    lcdcmd(1)

    lcdprint("Place Finger")

    while ( f.readImage() == False ):

        pass

    f.convertImage(0x01)

    result = f.searchTemplate()

    positionNumber = result[0]

    if ( positionNumber >= 0 ):

        print('Template already exists at position #' + str(positionNumber))

        lcdcmd(1)

        lcdprint("Finger ALready")

        lcdcmd(192)

        lcdprint("   Exists     ")

        time.sleep(2)

        return

    print('Remove finger...')

    lcdcmd(1)

    lcdprint("Remove Finger")

    time.sleep(2)

    print('Waiting for same finger again...')

    lcdcmd(1)

    lcdprint("Place Finger")

    lcdcmd(192)

    lcdprint("   Again    ")

    while ( f.readImage() == False ):

        pass

    f.convertImage(0x02)

    if ( f.compareCharacteristics() == 0 ):

        print "Fingers do not match"

        lcdcmd(1)

        lcdprint("Finger Did not")

        lcdcmd(192)

        lcdprint("   Mactched   ")

        time.sleep(2)

        return

    f.createTemplate()

    positionNumber = f.storeTemplate()

    print('Finger enrolled successfully!')

    lcdcmd(1)

    lcdprint("Stored at Pos:")

    lcdprint(str(positionNumber))

    lcdcmd(192)

    lcdprint("successfully")

    print('New template position #' + str(positionNumber))

    time.sleep(2)

def searchFinger():

    try:

        print('Waiting for finger...')

        while( f.readImage() == False ):

            #pass

            time.sleep(.5)

            return

        f.convertImage(0x01)

        result = f.searchTemplate()

        positionNumber = result[0]

        accuracyScore = result[1]

        if positionNumber == -1 :

            print('No match found!'

            lcdcmd(1)

            lcdprint("No Match Found")

            time.sleep(2)

            return

        else:

            print('Found template at position #' + str(positionNumber))

            lcdcmd(1)

            lcdprint("Found at Pos:")

            lcdprint(str(positionNumber))

            time.sleep(2)

    except Exception as e:

        print('Operation failed!')

        print('Exception message: ' + str(e))

        exit(1)

def deleteFinger():

    positionNumber = 0

    count=0

    lcdcmd(1)

    lcdprint("Delete Finger")

    lcdcmd(192)

    lcdprint("Position: ")

    lcdcmd(0xca)

    lcdprint(str(count))

    while gpio.input(enrol) == True:   # here enrol key means ok

        if gpio.input(inc) == False:

            count=count+1

            if count>1000:

                count=1000

            lcdcmd(0xca)

            lcdprint(str(count))

            time.sleep(0.2)

        elif gpio.input(dec) == False:

            count=count-1

            if count<0:

                count=0

            lcdcmd(0xca)

            lcdprint(str(count))

            time.sleep(0.2)

    positionNumber=count

    if f.deleteTemplate(positionNumber) == True :

        print('Template deleted!')

        lcdcmd(1)

        lcdprint("Finger Deleted");

        time.sleep(2)

begin()

lcdcmd(0x01)

lcdprint("FingerPrint ")

lcdcmd(0xc0)

lcdprint("Interfacing ")

time.sleep(3)

lcdcmd(0x01)

lcdprint("Circuit Digest")

lcdcmd(0xc0)

lcdprint("Welcomes You  ")

time.sleep(3)

flag=0

lcdclear()

while 1:

    gpio.output(led, HIGH)


    lcdcmd(1)

    lcdprint("Place Finger")

    if gpio.input(enrol) == 0:

        gpio.output(led, LOW)

        enrollFinger()

    elif gpio.input(delet) == 0:

        gpio.output(led, LOW)

        while gpio.input(delet) == 0:

            time.sleep(0.1)

        deleteFinger()

    else:

        searchFinger()

Conclusion

In this case, biometric authentication was implemented. To verify the identity of a user, fingerprint authentication uses an automated comparison of their fingerprint with a fingerprint template. In the next tutorial, we will discuss how to interface a Heartbeat Sensor with Raspberry Pi 4. Stay tuned. Have fun!!!

How to Mine Cryptocurrency with Raspberry Pi 4?

Welcome to today's article on our comprehensive Raspberry Pi 4 programming guide. As we saw in the previous article, the Raspberry Pi 4 may power a single seven-segment display. In addition, we also interfaced a Raspberry Pi with 4 Seven-Segment Display Modules to display the time. However, this guide will show you how to construct a Raspberry Pi 4 crypto miner that uses very little electricity.

Cryptocurrencies have been the subject of widespread conversation for some time now. It's possible to use your computer to create them, and they can be used as currency. Because of this, the Raspberry Pi can also be used for Bitcoin mining. It's also possible to mine other cryptocurrencies. One drawback of mining is that the cost of electricity often exceeds the revenue it brings in. So, let's check out how to construct a solar-powered, money-making cryptocurrency miner with a Raspberry Pi.

Where To Buy?
No.ComponentsDistributorLink To Buy
1Raspberry Pi 4AmazonBuy Now

Components

  • A pool account

  • Bitcoin Wallet

  • Raspberry Pi

  • Raspbian image SD card

  • USB Bitcoin miner

Mining for cryptocurrency: what exactly is that?

Crypto mining, the digital equivalent of the gold mining industry, involves a combination of complex mathematical calculations and blind luck. Mining is crucial for cryptocurrencies as it is the only way to update the distributed ledger (Blockchain).

Despite Bitcoin's popularity, there are other digital currencies available. All cryptocurrencies use blockchains to ensure that all transactions are legitimate and that users cannot spend the same cryptocurrency more than once.

Blockchain

To simplify things for the unfamiliar in the web3 environment, let's say that a blockchain is a distributed ledger that maintains track of all transactions made over it. Similar to how a bank keeps a record of who gave money to whom, how much was sent, and when it was sent, blockchain stores this unchangeable data within distributed blocks linked together via a network.

Users, known as miners or validator nodes, provide the network's computational power to verify all of the blockchain's transactions. This blog post will not delve further into smart contracts, which are computer programs that can be set up to run automatically on a blockchain if and only if specific criteria are met.

Bitcoin and Ethereum miners are sometimes pictured as a large server farm full of powerful graphics processing unit (GPU) or application-specific integrated circuit (ASIC) devices that work tirelessly to solve complex cryptographic puzzles issued by the blockchain in exchange for financial rewards. The consensus technique for validating submissions and awarding incentives varies from blockchain to blockchain.

Which Cryptocurrency is Ideal for Raspberry Pi Mining?

Raspberry Pi users can choose from several different coins to mine, but not all are profitable. The most profitable option is the one you should choose. The USB miner is crucial to mining since it dramatically boosts productivity. In mining, you have two primary options:

For anyone interested in beginning mining using a USB miner like NEWPAC, selecting a cryptocurrency that uses the SHA-256 algorithm is a must. Bitcoin (BTC), Bitcoin Cash (BCH), Bitcoin SV (BSV), and many others are just some of the cryptocurrencies that use the SHA-256 algorithm. However, Bitcoin is the most lucrative and should be explored first if you plan to mine using a Raspberry Pi.

The Raspberry Pi's central processing unit (CPU) can be used to begin mining in the absence of a dedicated USB miner. In such a scenario, you should go with Monero (XMR), the coin that can be mined with the least effort using a Raspberry Pi.

Can you make money mining Bitcoin in 2020 with a Raspberry Pi 4?

After calculating electricity and equipment costs, I found that bitcoin mining with a regular computer could have been more worthwhile. Most bitcoins are now mined using specialized computers called ASIC bitcoin miners; nevertheless, amateurs and enthusiasts still have some success mining by joining a mining pool. What if we set up a mining rig powered by a Raspberry Pi and solar panels and "deducted" the cost of the equipment? As the number of miners for Bitcoins increases, the difficulty of mining rises, and the rewards for miners decrease, the industry has become very competitive. Despite this discouraging information, I've decided to move on with this plan and shift my focus to alternative crypto assets.

Mining Pools

Since we are utilizing a Raspberry Pi rather than an ASIC bitcoin miner, individual crypto mining was not an option. Despite my best efforts, I could not locate any mining pools that supported the Raspberry Pi operating system among the many available for Windows and macOS. Since Linux miners are written for the x86 architecture, Raspberry Pi cannot participate in the mining process. Linux mining software that runs on x86 processors like those found on most personal computers is supported.

Please note that the purpose of this paper is to promote further study of blockchain technology and cryptocurrencies, not to create any of those assets. The techniques outlined here are workarounds that need to be endorsed by the developers. Instead, you can download the free software linked with your preferred mining pool and install it on your personal computer.

How to Use a Raspberry Pi to Mine Cryptocurrency

We'll first sign up for an account on minergate, a crypto mining pool with over 3.5 million users worldwide that supports Bitcoin, Gold, Zcash, Ethereum, Ethereum, and monero. Since Monero is the only crypto I have had success with, this guide will focus solely on that one.

  • Turn on your Raspberry Pi.

  • Press Ctrl-T or launch a Terminal window in Raspberry Pi OS using Desktop. Please use the standard login procedures while using Raspberry Pi Lite.

  • If you're already in the Terminal, you can install the updates and prerequisites immediately.

sudo apt-get update && sudo apt-get upgrade -y

sudo apt install git automake autoconf libcurl4-openssl-dev libjansson-dev libssl-dev libgmp-dev 

cd cpuminer-multi

  • Please use the below three commands to compile the mining code. This process will take a few minutes if you're using a Raspberry Pi 4.

sudo ./autogen.sh

sudo ./configure

sudo ./build.sh

  • Let's begin monero mining once we've installed and set up the mining program on our Raspberry Pi. To activate the miner, run the following line in the Terminal, substituting YOUR EMAIL with the address you used to create your minergate account.

./cpuminer -a cryptonight -o stratum+tcp://xmr.pool.minergate.com:45700 -u YOUR_EMAIL

The mining software will begin running, and if you're lucky, you'll see some 'accepted' shares marked with a "yes."

    Please log in to minegate/internal so we can inspect your Minergate Dashboard. This can be done on a PC or laptop using the Chromium web browser or on a Raspberry Pi using the Raspberry Pi Desktop interface. Find the Monero icon at the bottom of your screen. The ONLINE status will be displayed if Monero is connected and functioning correctly. Congratulations! You have started Monero mining!

    What are Monero's benefits?

    Now that we have a basic understanding of blockchain and cryptocurrencies, the issue of which currency is superior naturally emerges. The original cryptocurrency was Bitcoin, but there are now thousands of others, each with unique characteristics.

    Though Bitcoin transactions may be traced back to specific senders and recipients through their hash values, this is a significant drawback of the cryptocurrency.

    Monero is a cryptocurrency with unique rules in this regard. It's likewise mineable and based on a blockchain, but unlike bitcoin, the transactions here are anonymous and difficult to track. This is why most exchanges will not let you buy or sell Monero and why mining is the best option if you want some.

    Many more cryptocurrencies exist besides Bitcoin and Monero, such as the technically superior coins Ethereum and the humorous currency Dogecoin. The Raspberry Pi can be used to mine a large number of them.

    How to Automatically Start Crypto Mining with Your Raspberry Pi 4

    We'll utilize the Crontab approach to ensure that our cryptocurrency miner is always running on our Raspberry Pi.

    crontab -e

    If you haven't already, you'll see the message "no crontab for pi, Choose an editor" when you try to set the crontab.

    • Select 1 and press Enter.

    • Clicking here will launch a new crontab file; once it has opened, go to the bottom and add the following command, substituting YOUR EMAIL with the email you used to sign up for your Minergate account.

    @reboot sudo /cpuminer-multi/cpuminer -a cryptonight -o stratum+tcp://xmr.pool.minergate.com:45700 -u YOUR_EMAIL

    • To keep your crontab, hit Ctrl-X and then y.

    • Type "sudo reboot" into the Terminal to restart the Pi.

    How much Monero can Pi 4 mine? 

    After being powered on for almost 8 hours, my Raspberry Pi 4 has successfully calculated 357 good shares. Successful miners receive compensation when their shares are valued. If I do the math and get the appropriate answer, but my Pi is slower than another computer, I get a bad share. Only the first miner will be compensated if a miner submits a valid response before anyone else. Every invalid share is a penalty for the miner because of the possibility of fraud. I began to worry when my first four shares were flagged as invalid.

    357 good shares = 0.000001410642 Monero = 0.00015569 USD

    For 8 hours, I earned $0.000100, which is less than a penny. I was required to have at least 0.05 Monero (equivalent to about $5.811 USD) to make a withdrawal. (As of the date this article was published, the exchange rate was.) To attain the minimum withdrawal criterion of 0.05 Monero would take me 3,762 years at a rate of accumulating 0.000001410642 Monero per 8 hours.

    What We've Learned About Mining Cryptocurrency with a Raspberry Pi 4

    As was mentioned at the outset of this piece, the aim of this activity was education regarding bitcoin, not financial gain.

    • Mined cryptocurrency rewards are divided up based on hash rates and shares. My hash rate swung between 1.6 and 33.3 hashes per second. The pool averaged 10.27 MH/s, around 3 million times faster than my Pi. As a point of comparison, 1 MH/s equals 1,000,000 hashes/ sec.

    • Additionally, a tiny commission is added to your transactions by the Minergate. Choose a Pay Per Share structure or one based on chance (with more significant potential gain).

    • Many 'time out' and send line failed' errors appeared on my Pi as I wrote this essay. On occasion, a Pi reboot was required, but on other occasions, the miner resumed operations without any more intervention.

    • Even though my Raspberry Pi wasn't a "money maker" in the cryptocurrency mining game, we still had a great time seeing it effectively compute and accumulate excellent shares.

    How lucrative is Raspberry Pi mining?

    A person can easily mine bitcoins at home with minimal equipment. A powered external USB hub may be the way to go if you want to avoid shelling out the cash for a desktop PC. Bitcoin mining can be facilitated and made more profitable by using a powered external USB hub. Raspberry Pi version B, compatible with most PCs, is also readily available and inexpensive. You can use Bitcoins to buy and sell on websites or keep them safe in a digital wallet

     when you have Bitcoins. 

    Remember that large commercial Bitcoin miners employing thousands of computers will be your main competition. Still, a Pi 4 mining system is a fantastic (and entertaining) method of earning Bitcoins with little work. Because of the high cost of maintaining the hardware, mining Bitcoin using a Pi 4 is not financially sound. For Bitcoin mining, you'll also need hardware that's up to the task.

    To be sure, a Pi 4 mining system can be a fantastic (and entertaining) method of earning Bitcoins without much effort on your part. However, even if you only make a few Satoshi, you'll still gain valuable experience and knowledge, so it's a good use of time. Be mindful of your monthly electricity costs, though.

    Although you might make a few dollars mining on a Raspberry Pi, you won't become filthy rich overnight. Your electric bill may skyrocket if you've amassed a sizable Raspberry Pi fleet for mining. You can generate a small profit with a solar panel designed for the Raspberry Pi. The revenues won't make you rich, though; mining Monero with a Pi 4 and 100H/s of hashing power will net you just $1 per year. Making an annual average of $20 from mining using a USB miner is possible with Bitcoin.

    Conclusion

    We have developed a cryptocurrency miner that generates no additional costs whatsoever. The hash rate is a severe drawback of this design. Bitcoin mining on the Pi 4  is only profitable if the values of cryptocurrencies are supposed to remain the same. The upfront investment in equipment is more than the yearly return on investment from mining. One's perspective could alter if one were to speculate on the possibility of dramatically increasing prices. Those who are just sitting on unused hardware are in the same boat. A little setup is not worthwhile. The following guide will teach you how to set up a fingerprint sensor on your Raspberry Pi 4.

    Interface 7-Segment Display with Raspberry Pi 4

    Thank you for being here for today's tutorial of our in-depth Raspberry Pi programming tutorial. The previous tutorial taught us how to install a PIR sensor on a Raspberry Pi 4 to create a motion detector. However, this tutorial will teach you how to connect a single seven-segment display to a Raspberry Pi 4. In the following sections, we will show you how to connect a Raspberry Pi to a 4-digit Seven-Segment Display Module so that the time can be shown on it.

    Seven-segment displays are a simple type of Display that use eight light-emitting diodes to show off decimal numbers. It's common to find it in gadgets like digital clocks, calculators, and electronic meters that show numbers. Raspberry Pi, built around an ARM chip, is widely acknowledged as an excellent Development Platform. Its strong processing power can do amazing things in the hands of electronics enthusiasts and students. If we can figure out how to have it talk to the outside world and process data via an output, then we'll have a real chance of accomplishing all this. We analyze the data by viewing it on an LCD screen or other Display. Numerous sensors can detect specific parameters in the physical world and convert them to the digital world. It would never make sense to utilize a PI LCD panel to display a minimal quantity of information. Here, a 7-Segment or 16x2-Alphanumeric LCD panel is the preferred method of presentation.

    There are few uses for a 7-segment display that don't need an LCD panel, even though a 16x2 LCD is preferable in most. If all you need to do is show some numbers, then an LCD, which has the downside of having a small character size, is excessive. Compared to a regular LCD screen, seven segments have the upper hand in dim environments and can be seen from wider angles. Let's get started.

    Where To Buy?
    No.ComponentsDistributorLink To Buy
    1BreadboardAmazonBuy Now
    2Jumper WiresAmazonBuy Now
    3Raspberry Pi 4AmazonBuy Now

    Components

    • Jumper wires

    • Seven segment display

    • 1KΩresistors

    • Breadboard

    The 7-Segment and 4-Digit Display Modules

    The seven segments of a 7 Segment Display are each lit up by an individual LED to show the digits. To show the number 5, for example, you would make the glow pins for segments a, f, g, c, and d on the 7-segment high. This particular 7-segment display is a Common Cathode version, although there is also a Common Anode version.

    One 7-Segment Display Interfacing with Pi 4

    The wiring diagram for connecting a 7-segment display to a Raspberry Pi is shown below. Here, 7-Segment Common Cathode has been utilized.

    So, we'll simulate an 8-bit PORT on PI using its eight GPIO pins. Here, GPIO12 is the Most Significant Bit (MSB), while GPIO13 is the Least Significant Bit (LSB) (Most Significant Bit).

    If we wish to show the number 1, we must activate both segments B and C. We must supply voltage to GPIO6 and GPIO16 to power segments B and C. Accordingly, the hexadecimal value of "PORT" is "06," and the byte value of "PORT" is "0b00000110." If we raise both pins to their highest positions, the number "1" will be shown.

    The value for every displayable digit has been recorded and saved in a Character String with the label 'DISPLAY .'We have then used the Function 'PORT' to call those values one at a time and display the relevant digit.

    Explanation of the Code

    Once everything is wired up according to the schematic, we can power up the PI and begin using PYTHON to write the program. Below is a function that allows us to program the GPIO pins on the PI, and we'll go over the few commands we'll be using in the PYTHON program to do so. We are also changing the name of the GPIO pins in the hardware from "GPIO" to "IO," which will be used throughout the code.

    import RPi.GPIO as IO

    The general-purpose input/output (GPIO) pins we need to use may be occupied with other tasks. If that's the case, the program's execution will be interrupted by warnings. The below command instructs the PI to continue running the software regardless of the warnings.

    IO.setwarnings(False)

    Pin numbers on the board and pin functions can be used to refer to PI's GPIOs. This GPIO5 is similar to the one labeled "PIN 29" on the board. Here we specify whether the number 29 or the number 5 will stand in for the pin.

    IO.setmode (IO.BCM)

    To use the LCD's data and control pins, we have assigned those functions to eight of the GPIO pins.

    IO.setup(13,IO.OUT)

    IO.setup(6,IO.OUT)

    IO.setup(16,IO.OUT)

    IO.setup(20,IO.OUT)

    IO.setup(21,IO.OUT)

    IO.setup(19,IO.OUT)

    IO.setup(26,IO.OUT)

    IO.setup(12,IO.OUT)

    If the condition between the brackets evaluates to true, the looped statements will be run once. The value of PIN13 would be HIGH if and only if bit0 of the 8-bit 'pin' is true. There are eight 'if else' conditions, one for each of bits 0 through 7, so that each LED in the seven-segment Display can be set to either the High or Low state, depending on the value of the corresponding bit.

    if(pin&0x01 == 0x01):

       IO.output(13,1)

    else:

       IO.output(13,0)

    As x increases from 0 to 9, the loop will be run 10 times for each command.

    for x in range(10):

    The following command can create an infinite loop, with which the statements included within the loop will be run repeatedly.

    While 1:

    All other commands and functions have been commented on in the following code.

    Single 7-segment Display complete code

    import RPi.GPIO as IO            # calling for the header file, which helps us use GPIO's of PI

    import time                              # calling for time to provide delays in the program

    DISPLAY = [0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67]            # string of characters storing PORT values for each digit.

    IO.setwarnings(False)            # do not show any warnings.

    IO.setmode (IO.BCM)           # programming the GPIO by BCM pin numbers. (like PIN29 as‘GPIO5’)

    IO.setup(13,IO.OUT)             # initialize GPIO Pins as outputs

    IO.setup(6,IO.OUT)

    IO.setup(16,IO.OUT)

    IO.setup(20,IO.OUT)

    IO.setup(21,IO.OUT)

    IO.setup(19,IO.OUT)

    IO.setup(26,IO.OUT)

    IO.setup(12,IO.OUT)

    def PORT(pin):                    # assigning GPIO logic by taking the 'pin' value

        if(pin&0x01 == 0x01):

            IO.output(13,1)            # if  bit0 of 8bit 'pin' is true, pull PIN13 high

        else:

            IO.output(13,0)            # if  bit0 of 8bit 'pin' is false, pull PIN13 low

        if(pin&0x02 == 0x02):

            IO.output(6,1)             # if  bit1 of 8bit 'pin' is true, pull PIN6 high

        else:

            IO.output(6,0)            #if  bit1 of 8bit 'pin' is false, pull PIN6 low

        if(pin&0x04 == 0x04):

            IO.output(16,1)

        else:

            IO.output(16,0)

        if(pin&0x08 == 0x08):

            IO.output(20,1)

        else:

            IO.output(20,0)   

        if(pin&0x10 == 0x10):

            IO.output(21,1)

        else:

            IO.output(21,0)

        if(pin&0x20 == 0x20):

            IO.output(19,1)

        else:

            IO.output(19,0)

        if(pin&0x40 == 0x40):

            IO.output(26,1)

        else:

            IO.output(26,0)

        if(pin&0x80 == 0x80):

            IO.output(12,1)            # if  bit7 of 8bit 'pin' is true, pull PIN12 high

        else:

            IO.output(12,0)            # if  bit7 of 8bit 'pin' is false, pull PIN12 low

    While 1:

        for x in range(10):            # execute the loop ten times incrementing x value from zero to nine

            pin = DISPLAY[x]        # assigning value to 'pin' for each digit

            PORT(pin);                  # showing each digit on display 

            time.sleep(1)

    Output

    The process of displaying a single number character on a 7-segment display is complete. However, we'd need more than a single 7-segment display to express information with more than one digit. Therefore, we will use a 4-digit seven-segment display circuit for this session.

    Four individual Seven-Segment Displays have been linked up here. For a 4-digit 7-segment display, we know that each module will have 10 pins, so there will be 40 pins total. Soldering that many pins onto a dot board would be a hassle for anyone; thus, I recommend that anyone using a 7-segment display do so by purchasing a module or creating their PCB. See below for a diagram of the relevant connections:

    In the preceding diagrams, we can see that the A-lines of all four displays are linked together as one A, and the same is true for B, C.... up until DP, which is essential for understanding how the 4-digit seven-segment module functions. Put another way, if trigger A is activated, the state of all 4 A's should be high.

    Nonetheless, this never occurs. The four extra pins labeled D0 through D3 (D0, D1, D2, and D3) let us select which of the four displays is driven high. As an illustration, if I want my output to appear solely on the second Display, I would set D1 to high and leave D0, D2, and D3 at low. Using pins D0–D3 and A–DP, we can easily choose which displays should be on and which characters should be shown.

    Using a Pi 4  to interface with a 4-digit, 7-segment display module

    Let's check the many options for interfacing this 4-digit seven-segment Display with the Raspberry Pi. As can be seen in the diagram below, there are 16 pins on the 7-segment module. Even if your module's resources are limited, it will provide at least the following.

    • Segmented pins, either 7 or 8 segments (pins 1 to 8)

    • Pin holder to the ground (here pin 11)

    • A 4-digit code to unlock the door (pins 13 to 16)

    See below for the wiring diagram of a digital clock built with a Raspberry Pi and a 4-digit Seven-segment display module:

    You can also use the following table to ensure your connections are correct and follow the diagrams.

    Locating the module's pins is the first step in making electrical connections. Identifying the Raspberry Pi's GPIO pins can be tricky; I've included an image to help.

    Raspberry Pi programming

    Here, RPi is programmed in the Python programming language. The Raspberry Pi can be programmed in a wide variety of ways. Since Python 3 has become the de facto standard, we've opted to use that version as our integrated development environment (IDE). At the bottom of this guide, you'll find the whole Python code.

    We'll go over the PYTHON instructions we'll be using for this project: first, we'll import the library's GPIO file; next, using the below function, we'll be able to program the Pi 4's GPIO pins. We are also changing the name of the GPIO pins in the hardware from "GPIO" to "IO," which will be used throughout the code. We've brought in time and DateTime to get the current time from Rasp Pi.

    import RPi.GPIO as GPIO

    import time, DateTime

    The GPIO pins we're trying to use are already being used for something else. The program's execution will be interrupted with warnings if this is the case. The PI will be instructed to disregard the errors and continue with the software using the below command.

    IO.setwarnings(False)

    The physical pin number and the corresponding function number can refer to PI's GPIOs. As with 'PIN 29,' GPIO5 is a physical component on the circuit board. In this case, we specify whether the number "29" or "5" will stand in for the pin. GPIO. In BCM notation, GPIO5 pin 29 will be represented by a 5.

    IO.setmode (GPIO.BCM)

    As is customary, we'll start by setting the pins to their default values; in this case, both the segment and digit pins will be used as outputs. In our code, we organize the segment pins into arrays and set their values to zero by declaring them to be GPIO.OUT.

    segment8 = (26,19,13,6,5,11,9,10)

    for segment in segment8:

        GPIO.setup(segment, GPIO.OUT)

        GPIO.output(segment, 0)

    We do the same thing with the digital pins, but we set them to output and set them to zero by default.

    #Digit 1

        GPIO.setup(7, GPIO.OUT)

        GPIO.output(7, 0) #Off initially

        #Digit 2

        GPIO.setup(8, GPIO.OUT)

        GPIO.output(8, 0) #Off initially

        #Digit 3

        GPIO.setup(25, GPIO.OUT)

        GPIO.output(25, 0) #Off initially

        #Digit 4

        GPIO.setup(24, GPIO.OUT)

        GPIO.output(24, 0) #Off initially

    Numbers on a seven-segment display must be formed into arrays. To show a single digit, we need to toggle the on/off status of all but the dot pin of the 7-segment Display. For the numeral 5, for instance, we can use this setup:

    For all alphabets and numerals, there is an equivalent sequence number. You can write on your own or utilize the handy table provided.

    Using this information, we can create arrays for each digit in our Python code, as demonstrated below.

    null = [0,0,0,0,0,0,0]

    zero = [1,1,1,1,1,1,0]

    one = [0,1,1,0,0,0,0]

    two = [1,1,0,1,1,0,1]

    three = [1,1,1,1,0,0,1]

    four = [0,1,1,0,0,1,1]

    five = [1,0,1,1,0,1,1]

    six = [1,0,1,1,1,1,1]

    seven = [1,1,1,0,0,0,0]

    eight = [1,1,1,1,1,1,1]

    nine = [1,1,1,1,0,1,1]

    Let's bypass the function in the code that would otherwise be executed before entering the while loop and begin displaying characters on our 7-segment Display. If you hook up a Raspberry Pi to the internet, it will read the current time and divide it into four separate variables. For instance, when the time is 10.45, the values assigned to h1 and h2 will be 1 and 0, while m1 and m2 will be 4 and 5, respectively.

    now = DateTime.DateTime.now()

        hour = now.hour

        minute = now.minute

        h1 = hour/10

        h2 = hour % 10

        m1 = minute /10

        m2 = minute % 10

        print (h1,h2,m1,m2)

    These four numbers will be displayed on one of our four digits. The lines below can be used to convert a variable's value to a decimal. Here, we show the value in variables on the 7-segment Display by using the function print segment (variable) with the digit 1 set to the highest possible value. You may be asking why we turn off this digit and why there's a delay after that.

    GPIO.output(7, 1) #Turn on Digit One

    print_segment (h1) #Print h1 on segment

    time.sleep(delay_time)

    GPIO.output(7, 0) #Turn off Digit One

    This is because the user will only be able to see the full four-digit number if all four digits are shown at once, and we all know that this isn't possible.

    How, then, can we simultaneously show all four digits? With luck, our MPU is considerably quicker than the human eye. Therefore we offer one number at a time but exceptionally quickly. The MPU and segment display are given 2ms (variable delay time) to process each digit before we go on to the next. A human being cannot detect this 2ms lag; therefore, it appears as though all four digits illuminate simultaneously.

    Understanding how to use print segment(variable) is the final puzzle piece. Arrays that have been declared outside of this function are used within it. As a result, the value of any variable passed to this function must be inside the range (0-9) so that the character variable can use in a meaningful comparison. Here, we check the variable against the value 1. The same is true for all comparisons with numbers between zero and nine. Assigning each value from the arrays to the appropriate segment pins is what we do if a match is found.

    def print_segment(character):

        if character == 1:

            for i in range(7):

                GPIO.output(segment8[i], one[i])

    Show the time on a 4-digit 7-segment display.

    Use the provided schematic and code to connect your components and set up your Raspberry Pi. Once you've finished setting everything up, you can open the software and check the 7-segment Display to see the time. However, before doing this, you should check a few things.

    • If you want to be sure your Raspberry Pi isn't stuck in the past, you should update its time.

    • If you want to utilize a 7-segment display on your Raspberry Pi, you'll need to plug it into an adapter rather than a computer's USB connection because of the large amount of current it consumes.

    Complete code

    import RPi.GPIO as GPIO

    import time, DateTime

    now = datetime.datetime.now()

    GPIO.setmode(GPIO.BCM)

    GPIO.setwarnings(False)

     #GPIO ports for the 7seg pins

    segment8 =  (26,19,13,6,5,11,9,10)

    for segment in segment8:

        GPIO.setup(segment, GPIO.OUT)

        GPIO.output(segment, 0)

        #Digit 1

        GPIO.setup(7, GPIO.OUT)

        GPIO.output(7, 0) #Off initially

        #Digit 2

        GPIO.setup(8, GPIO.OUT)

        GPIO.output(8, 0) #Off initially

        #Digit 3

        GPIO.setup(25, GPIO.OUT)

        GPIO.output(25, 0) #Off initially

        #Digit 4

        GPIO.setup(24, GPIO.OUT)

        GPIO.output(24, 0) #Off initially

    null = [0,0,0,0,0,0,0]

    zero = [1,1,1,1,1,1,0]

    one = [0,1,1,0,0,0,0]

    two = [1,1,0,1,1,0,1]

    three = [1,1,1,1,0,0,1]

    four = [0,1,1,0,0,1,1]

    five = [1,0,1,1,0,1,1]

    six = [1,0,1,1,1,1,1]

    seven = [1,1,1,0,0,0,0]

    eight = [1,1,1,1,1,1,1]

    nine = [1,1,1,1,0,1,1]

    def print_segment(charector):

        if charector == 1:

            for i in range(7):

                GPIO.output(segment8[i], one[i])

        if charector == 2:

            for i in range(7):

                GPIO.output(segment8[i], two[i])

        if charector == 3:

            for i in range(7):

                GPIO.output(segment8[i], three[i])

        if charector == 4:

            for i in range(7):

                GPIO.output(segment8[i], four[i])

        if charector == 5:

            for i in range(7):

                GPIO.output(segment8[i], five[i])

        if charector == 6:

            for i in range(7):

                GPIO.output(segment8[i], six[i])

        if charector == 7:

            for i in range(7):

                GPIO.output(segment8[i], seven[i])

        if charector == 8:

            for i in range(7):

                GPIO.output(segment8[i], eight[i])

        if charector == 9:

            for i in range(7):

                GPIO.output(segment8[i], nine[i])

        if charector == 0:

            for i in range(7):

                GPIO.output(segment8[i], zero[i])               

        return;

    while 1:

        now = DateTime.DateTime.now()

        hour = now.hour

        minute = now.minute

        h1 = hour/10

        h2 = hour % 10

        m1 = minute /10

        m2 = minute % 10

        print (h1,h2,m1,m2)

        delay_time = 0.001 #delay to create the virtual effect

        GPIO.output(7, 1) #Turn on Digit One

        print_segment (h1) #Print h1 on segment

        time.sleep(delay_time)

        GPIO.output(7, 0) #Turn off Digit One

        GPIO.output(8, 1) #Turn on Digit One

        print_segment (h2) #Print h1 on segment

        GPIO.output(10, 1) #Display point On

        time.sleep(delay_time)

        GPIO.output(10, 0) #Display point Off

        GPIO.output(8, 0) #Turn off Digit One

        GPIO.output(25, 1) #Turn on Digit One

        print_segment (m1) #Print h1 on segment

        time.sleep(delay_time)

        GPIO.output(25, 0) #Turn off Digit One

        GPIO.output(24, 1) #Turn on Digit One

        print_segment (m2) #Print h1 on segment

        time.sleep(delay_time)

        GPIO.output(24, 0) #Turn off Digit One

        #time.sleep(1)

    Output

    A similar section should appear below if everything is functioning as it should.

    7-segment Display limitations

    Typically, only 16 hexadecimal digits can be shown on a seven-segment display. Some show the digits 0-9, whereas others can show more. Seven-segment displays can only show a maximum of 16 values due to a lack of input leads. However, LED technology does allow for more than this. Even with the help of integrated circuit technology, the possible permutations of the seven parts on the screen are very few.

    Conclusion

    This guide taught us how to connect a 7-segment screen to a Raspberry Pi 4. The seven-segment Display, which we learned is employed in digital timers, clocks, and other electrical gadgets, are a cheap, basic electrical circuit and reliable module. Seven-segment displays can either be "common-anode" (where the common point is the power input) or "common-cathode" (where the common end is grounded). After that, we coded some python scripts to show numbers on a single seven-segment model and the time across four such screens. Next, we'll see how to use a Raspberry Pi 4 as the basis for a low-power Bitcoin miner.

    Motion Detection with PIR Sensor & Raspberry Pi 4

    Hello friends, I hope you all are doing well. Today, I am going to share the 4th chapter of Section-III in our Raspberry Pi programming course. In the previous lecture, we studied the Interfacing of IR sensor with Raspberry Pi 4. In this guide, you'll learn how to interface a PIR sensor with Raspberry Pi to create a motion detector. A passive infrared (PIR) sensor is a straightforward yet effective tool for motion detection.

    As a bonus, a piezo speaker will play an audio clip whenever motion is detected. GPIO pins are required for both of these accessories. This tutorial is a great starting point for those who have never worked with electronic components and circuits.

    These sensors are used in traditional, old-generation security systems. In contrast, video is used in most of today's monitoring systems. So, let's get started:

    Project Description

    Today, we are going to design a security project, where we will sound an alarm using a piezo speaker, if any motion is detected by the PIR Sensor. We will use Raspberry Pi 4 for today's tutorial.

    Here's the video tutorial:


    Components Required

    Here's the list of components, used to design this motion detector:

    • Raspberry Pi 4.
    • PIR Sensor.
    • Piezo Speaker.
    • 100-ohm resistor.

    What is a PIR sensor?

    • Infrared motion detectors, also known as passive infrared (PIR) sensors, are a type of motion sensor that makes use of IR light to identify and locate the source of motion.
    • A Fresnel lens is mounted on top of the PIR sensor, which increases the sensor's field of view to 120 degrees.
    • The sensor can detect human movement within an 8-meter radius around it.

    • Anything, alive or otherwise, having a temperature greater than zero degrees Celsius emits infrared radiation.
    • The wavelength of infrared radiation is far greater than that of visible light, making it invisible to the human eye.
    • Passive infrared (PIR) sensors are specifically designed to detect these heat signatures.

    As their name implies, passive motion sensors don't put out any rays of their own but instead pick up the infrared radiations emitted by other objects, making them ideal for use in intruder alarm devices. However, active detectors may produce and detect infrared light at the same time.

    PIR Sensor Pinout

    The PIR motion sensor has three pins:

    1. Pin1 is Vcc: We need to provide +5V to this pin.
    2. Pin2 is the data Pin: It's a digital Pin and sends sensors' data.
    3. Pin3 is GND: We need to connect it to the ground.

    PIR Sensor Working Principle

    In PIR Sensor, crystals sensitive to infrared light are used as sensors. As its a passive IR sensor, the sensor doesn't emit any IR waves, instead, it waits for the infrared-emitting object.

    The IR sensing component consists of two subassemblies, A and B.

    When there is no motion, the two detectors pick up identical infrared readings, which cancel out one another. Sensing element A will pick up the presence of infrared light, when an infrared-emitting object, such as a dog, enters the sensor's field of vision. Since the intensity of the infrared light striking sensing element B is still relatively low, the resulting differential change is positive.

    As the object moves past the sensor, the intensity of the infrared light falling on sensing element B will be greater than that falling on sensing element A, resulting in a negative differential change. The BISS0001 logic chip onboard detects and amplifies this potential difference before outputting it as a digital signal.

    When the infrared detector detects movement, it sends a signal to the microcontroller through the data input, which goes HIGH.

    PIR Sensor Adjustments

    The Motion Sensor also has two potentiometers that may be adjusted to fine-tune the PIR sensitivity and the amount of time its output signal stays high after detecting motion.

    As shown in the above figure, the left potentiometer allows you to adjust the sensor's sensitivity. Distances between 3 to 8 meters are adjustable. The Potentiometer can be turned clockwise to enhance the detection range and counterclockwise to decrease it.

    The second Potentiometer controls the duration of the motion sensor's HIGH output. Times might be anything from 0.3s to 600s. The POT can be adjusted by turning it clockwise(to increase time) or counterclockwise (to decrease time).

    Circuit Diagram of PIR Sensor with Raspberry Pi 4

    We will design a simple Motion Detection Project using PIR Sensor & Piezo Speaker with Raspberry Pi 4. It's a simple security system where the PIR sensor will detect motion and Piezo Speaker will trigger the alarm.

    A piezo buzzer is an easy-to-use speaker that makes noise whenever an electric current passes through it. The buzzer will sound an audible alert when the motion is detected.

    Here's the circuit diagram of PIR Sensor with RPi4:

    Just follow these steps to build the circuit.

    1. Connect the Ground Pin to the breadboard's ground rail.
    2. Connect the breadboard's positive rail with the +5v Pin.
    3. One wire of the Piezo buzzer should be connected to Pin7 of RPi and the second wire to the ground.
    4. Connect Pin11 of RPi4 to the breadboard with a wire. Connect a resistor of 100 ohms to the wire's terminal. The PIR sensor's yellow wire should be connected to the other end of the resistor.
    5. The PIR sensor's red wire must be connected to the breadboard's 5V line, while the black wire must be connected to the ground rail.

    Python Code for PIR Sensor with RPi4

    We begin by importing the GPIO and time Python libraries, allowing us to communicate with the GPIO rail and halt the script. For our first two variables, which I have aptly dubbed "pins," we provide a reference to our physical ports. Our sensors' states will be kept in the now-valued state variable. If this value is zero, it is not turned on; if it is one, it is turned on. We'll change our GPIO mode to use the real PINs rather than the physical ones. Since each pin is given a unique number, this system is a tad simpler. We also configured our GPIO pins as inputs or outputs. To do things like detect motion, we'll plug in a PIR sensor. On the flip side, we need our piezo buzzer to function as an output.

    import RPi.GPIO as GPIO

    import time

    pir_sensor = 11

    piezo = 7

    GPIO.setmode(GPIO.BOARD)

    GPIO.setup(piezo,GPIO.OUT)

    GPIO.setup(pir_sensor, GPIO.IN)

    current_state = 0

    A while loop that never ends appears below. Due to the inherent permanence of the conditional statement, this loop can always be maintained. (You can still hit ctrl + c on the terminal to abort the script). To begin, we'll pause the script for 0.1 seconds. The next step is to retrieve the sensor's current state; if that state is 1 (for instance, the motion has been detected), the code within the if statement will be executed. If the value is not 1, we enter an infinite loop in which the sensor is repeatedly checked.

    The if statement executes code that sets the piezo buzzer's output high, causing it to sound. This will occur for a split second before the script silences the buzzer. As soon as that timer expires, the if statement will leave, and the sensor will be rechecked after another five seconds. We have also used a try, except, finally, block with a nested outer block. Since stopping the script will require using the keyboard, we have included this. Finally, we must verify our script is tidy by calling GPIO.cleanup(). With the help of the try, except finally, coding construct, we can accomplish this.

    try:

        while True:

            time.sleep(0.1)

            current_state = GPIO.input(pir_sensor)

            if current_state == 1:

                print("GPIO pin %s is %s" % (pir_sensor, current_state))

                GPIO.output(piezo,True)

                time.sleep(1)

                GPIO.output(piezo,False)

                time.sleep(5)

    except KeyboardInterrupt:

        pass

    finally:

        GPIO.cleanup()

    Running the Script

    After you have completed all of your changes to the script, you may run it and see how it performs. Put the following command into your keyboard to accomplish this.

    sudo python motion_sensor.py

    The piezo buzzer should activate and make a noise if the PIR sensor detects motion in its field of view. If it doesn't, it's probably because you connected wires to the incorrect pins or because of a bug in the program. The Raspberry Pi's terminal will show an error message if it's a coding mistake.

    Complete code

    #!/usr/bin/env python

    import RPi.GPIO as GPIO

    import time

    pir_sensor = 11

    piezo = 7

    GPIO.setmode(GPIO.BOARD)

    GPIO.setup(piezo,GPIO.OUT)

    GPIO.setup(pir_sensor, GPIO.IN)

    current_state = 0

    try:

        while True:

            time.sleep(0.1)

            current_state = GPIO.input(pir_sensor)

            if current_state == 1:

                print("GPIO pin %s is %s" % (pir_sensor, current_state))

                GPIO.output(piezo,True)

                time.sleep(1)

                GPIO.output(piezo,False)

                time.sleep(5)

    except KeyboardInterrupt:

        pass

    finally:

        GPIO.cleanup()

    Output

    Quiz: Send data to your phone using an LTE modem

    This section is meant to test your understanding of this programming series so far, so I am leaving it as some homework for you. Build the circuit and comment below what the output will be. I will give an idea of the circuit and Python code.

    The LTE modem

    Based on the success of GSM/EDGE and UMTS/HSPA, the Long-Term Evolution (LTE) standard was developed to ensure the continued development of wireless broadband communication. My LTE modem is a USB add-on for the Raspberry PI, giving it 3G or 4G (LTE) cellular data access. The modem is not used for cellular access in this project; instead, it is used to notify my phone of motion through text messages. The AT commands and serial connectivity allow me to command the modem and relay messages to my phone.

    Connection

    Step 1: Install the software

    Begin by loading the required software onto your Raspberry Pi. Enter the terminal of the Raspberry Pi:

    sudo apt install python3 python3-gpiozero python-serial -y

    Step 2: Set up the modem

    The TRM240 LTE modem requires a SIM card, which can be inserted here. To improve the modem's signal, attach the antenna to the top of the device.

    Third, link the cellular modem to the Pi.

    Plug the LTE modem into a free USB port on the Raspberry Pi and power it on. The /dev directory should now list four additional USB ports. Just type this into the terminal to verify:

    ls /dev/ttyUSB*

    These gadgets should now be visible to you.

    Sending AT commands to the device will be done through the ttyUSB2 port.

    Fourth, link up the sensor with the Pi.

    The sensor output pin should be connected to the 8-pin to the Raspberry Pi, and the VCC and GND pins should be connected to the appropriate pins on the Pi.

    Connect the LED lights:

    The cathode of the LED should be connected to a ground pin, the anode (longer leg) should be connected to a current-limiting resistor, and the other portion of the resistor should be connected to a GPIO pin to cause the indicator LEDs to illuminate when motion is detected. Input the green LED into the 40-pin connector and the red LED into the 38-pin connector on the board. This is a discretionary procedure. You can disable the LED sections in the sample code below if you don't want them to light up in response to the motion.

    Launch the program below

    from gpiozero import MotionSensor, LED

    from time import sleep, time

    from sys import exit

    import serial

    import threading

    # Raspberry Pi GPIO pin config

    sensor = MotionSensor(14)

    green = LED(21)

    red = LED(20)

    # Modem configuration

    device = '/dev/ttyUSB2'

    message = ''

    phone_number = ''

    sms_timeout = 120 # min seconds between SMS messages

    def setup():

        port.close()

        try:

            port.open()

        except serial.SerialException as e:

            print('Error opening device: ' + str(e))

            return False

        # Turn off echo mode

        port.write(b'ATE0 \r')

        if not check_response('OK', 10):

            print('Failed on ATE0')

            return False

        # Enter SMS text mode

        port.write(b'AT+CMGF=1 \r')

        if not check_response('OK', 6):

            print('Failed on CMGF')

            return False

        # Switch character set to 'international reference alphabet'

        # Note: this still doesn't support all characters

        port.write(b'AT+CSCS="IRA" \r')

        if not check_response('OK', 6):

            print('Failed on CSCS')

            return False

        return True

    def check_response(string, amount):

        result = ''

        try:

            result = port.read(amount).decode()

        except:

            return False

        if not string in result:

            try:

                # Write 'ESC' to exit SMS input mode, just in case

                port.write(b'\x1B \r')

            except:

                return False

        return string in result

    def send_sms():

        global currently_sending, last_msg_time

        currently_sending = True

        try:

            port.write('AT+CMGS="{}" \r'.format(phone_number).encode())

            if not check_response('>', 6):

                print('Failed on CMGS')

                currently_sending = False

                return

            # Write the message terminated by 'Ctrl+Z' or '1A' in ASCII

            port.write('{}\x1A \r'.format(message).encode())

            while True:

                result = port.readline().decode()

                if 'OK' in result:

                    print('> SMS sent successfully')

                    last_msg_time = time() 

                    currently_sending = False

                    return

                if 'ERROR' in result:

                    print('> Failed to send SMS [{}]'.format(result.rstrip()))

                    currently_sending = False

                    return

        except:

            # Initiate setup if the got while the program was running

            setup()

            currently_sending = False

    def on_motion():

        print('Motion detected!')

        green.off()

        red.on()

        if time() - last_msg_time > sms_timeout and not currently_sending:

            print('> Sending SMS...')

            threading.Thread(target=send_sms).start()

    def no_motion():

        green.on()

        red.off()

    print('* Setting up...')

    green.on()

    red.on()

    port = serial.Serial()

    port.port = device

    port.baudrate = 115200

    port.timeout = 2

    last_msg_time = 0

    currently_sending = False

    if not setup():

        print('* Retrying...')

        if not setup():

            print('* Try restarting the modem')

            exit(1)

    print('* Do not move, setting up the PIR sensor...')

    sensor.wait_for_no_motion()

    print('* Device ready! ', end='', flush=True)

    green.on()

    red.off()

    sensor.when_motion = on_motion

    sensor.when_no_motion = no_motion

    input('Press Enter or Ctrl+C to exit\n\n')

    As mentioned above, I will not give the output for this program; instead, let me know if you were successful.

    Conclusion

    This is a basic introduction to the PIR sensor and merely scratches the surface of its potential uses. Simple things like a counter (which adds up as people, cars, or other objects pass by) can trigger far more complex actions, such as turning on a Pi camera or running a new script. I'm hoping you've learned a lot from this Pi 4 motion sensor tutorial and that you've been able to put together a beautiful circuit and make it work with some code. Feel free to leave a remark below with your views, questions, or complaints. In the subsequent tutorial, we'll learn how to interface an ultrasonic sensor with Raspberry Pi 4. Till then, take care. Have fun!!!

    Heartbeat Monitoring System with ADS1115 & Raspberry Pi 4

    Hello friends, I hope you all are doing great. Welcome to the 11th lecture of Section-III in the Raspberry Pi 4 Programming Series. In the previous tutorial, we discussed the interfacing of the Fingerprint sensor with Raspberry Pi 4. Today, we are going to discuss another sensor named the Pulse rate sensor and will interface it with Raspberry Pi 4.

    The field of healthcare monitoring has long been seen as a potential use case for IoT i.e. examining the health instead of regular checkups and local doctors. Using sensors, your vital signs can be monitored and transmitted in real time, allowing a physician on the other side or even an AI to analyze the data and provide an accurate diagnosis. That does seem somewhat futuristic. However, we are making steady progress in that direction and will soon have an autonomous IoT robotic arm operating on us.

    Project Description

    In today's tutorial, we'll design a heart rate monitor to keep tabs on a patient's heart rate, using Pulse Rate Sensor and Raspberry Pi. We will display the data(ECG graph) in the Processing IDE.

    Components Required

    Here is all, you'll need to put together a Raspberry Pi-based patient monitoring system yourself:

    • Raspberry Pi 4
    • Pulse Sensor
    • ADS1115 ADC board
    • Jumper wires

    Pulse Rate Sensor

    • The Pulse Rate sensor is used to measure the heartbeat of a person, it has an LED, a Light Photo sensor(APDS-9008) and an op-amp(MCP6001) in its construction.
    • Pulse Rate Sensor gives an analog output and using that output one can easily design its ECG waveform.
    • The LED should be placed on the vein, normally it's placed at the tip of the finger. The LED throws a red/green light on the vein.
    • The Light sensor absorbs the reflected LED light and based on its intensity delivers the output.
    • The op-amp receives the output, amplifies it and forwards it to the microcontroller.
    • A simple circuit is embedded for noise reduction.

    A human vein is positioned directly in front of the sensor's LED. The tip of your finger or the inside of your ear can serve this purpose, but it must be positioned directly over a vein.

    Heart Rate Sensor Pinout

    The sensor outputs three wires:

    • Signal (S).
    • Vcc (3–5 V).
    • GND.

    We'll use the 3.3V pin on the Raspberry Pi 4 to power up the sensor.

    ADS1115 Module

    • ADS115 is used to convert the analog signal into a serial signal and transmit it using I2C Protocol.
    • The 16-bit ADC ADS1115 has four analog signal channels.
    • This chip's I2C interface allows for serial data exchange with a host microcontroller or computer.

    We will use ADS115 to transmit the analog signal from Heart Rate Sensor to Raspberry Pi 4, as the Pi can't read analog signals. Both ADS1015 and ADS1115 are high-precision, low-power analog-to-digital converters. These chips are commonly used with the Raspberry Pi because they operate at 3V3.

    Any value from 8-860 samples/sec can be entered into ADS1115's sampling rate field. The shorter time an ADC needs to capture and transform an analog signal, the higher its sampling rate. A gain amplifier is included in the chip and can boost low-voltage signals by a factor of two to sixteen.

    Here's the pinout diagram of ADS1115:

    Here's the ADS1115's functional block diagram shown below:

    A multiplexer takes the analog signals from the inputs and routes them to a programmable gain amplifier. An I2C bus transmits the results of the ADC's conversion of the amplified signal to a microcontroller.

    Circuit Diagram of Pulse Rate Sensor with Raspberry Pi 4

    • As discussed above, the pulse rate sensor provides analog output, so we need to use ADS1112 to convert the analog signal into an I2C signal, which is then fed to the Raspberry Pi board.
    • Here's the circuit diagram of Raspberry Pi Interfacing with Pulse Rate Sensor:
    • Here's our hardware setup with RPi4, ADS1115 and Pulse Rate sensor:

    Here are the pin connections of the above circuit:

    • Pulse Rate Sensor's Signal Pin ===> A0 of ADS1115.
    • 3.3V from Raspberry Pi ====> pulse sensor's Vcc pin.
    • Connect the pulse sensor's GND pin to the Pi's GND.
    • Connect RPI's Ground to the Ground of the ADC Module
    • Connect the ADC module's supply voltage to the RPI's +5V.
    • Connect the ADC module's SCL and SDA to the RPI's SCL and SDA

    Installing Modules in Raspberry Pi

    Since the Analog-to-digital module uses I2C for communication, and we'll be using UART for serial communication, we'll need to activate UART and I2C on the Raspberry Pi by running raspi-config in the terminal.

    To proceed, click the Interfacing Options button.

    Select I2C and hit Enter.

    Now, click the Yes button and hit Enter.

    Now, select Ok to proceed.

     Pressing the Enter key after selecting Serial will activate the serial port.

     Select "no" and hit "enter" to turn off the serial login shell.

    To activate the serial, click Yes and then hit Enter.

     Choose ok and hit enter to continue.

     Click Finish and hit Enter to confirm.

     When prompted, type "Yes" and hit enter to reboot.

    Now proceed to install the i2c packages.

    sudo apt-get install -y python-smbus

    sudo apt-get install -y i2c-tools

    To determine which device is currently connected and to obtain its I2C address, run the following command:

    sudo i2cdetect -y 1

    Follow the below lines to install the Python library for the ADC module.

    sudo apt-get update

    sudo apt-get install build-essential python-dev python-smbus git

    cd ~

    git clone https://github.com/adafruit/Adafruit_Python_ADS1x15.git

    cd Adafruit_Python_ADS1x15

    sudo python setup.py install

    Processing Installation in Raspberry Pi 4

    Now, use the following command to add Processing to your current installation:

    curl https://processing.org/download/install-arm.sh | sudo sh

    We can now access Processing from the Raspberry Pi's main menu:

    We'll use Python and processing codes for the pulse sensor to get the job done.  

    Python Code for Heart Rate Monitor

    This code uses I2C communication to connect an ADC module that provides analogue pulse sensor output. Once the pulse sensor's analogue raw production is obtained, the sensor's higher maximum and minimum peak are located. Then calculate the beats per minute by subtracting the times of two extremes. Additionally, the BPM and raw analogue output are transmitted to a serial port, which is then read by the processing IDE. The complete python code for the heartbeat sensor on the Raspberry Pi is provided below.

    While developing this code, we used several modules that we imported at the outset for various applications.

    import Adafruit_ADS1x15

    import serial

    import time

    We now have variables upon which to perform analyses and take appropriate measures. Also, we made a serial object.

    rate = [0]*10

    amp = 100

    GAIN = 2/3

    curState = 0

    statechanged = 0

    ser = serial.serial("/dev/ttys0",9600)

    Now we use this chunk of code to transmit information to the processor.

    def send_to_prcessing(prefix,data):

    ser.write(prefix)

    ser.write(str(data))

    ser.write("\n")

    Now we have a pre-programmed function to read the pulse sensor and calculate the heart rate.

    def read_pulse();

    firstBeat=True

    seecondBeat=False

    ssamplecounter=0

    lastBeatTime=0

    lastTime=int(time.time()*1000)

    th = 525

    P = 512

    T = 512

    IBI=600

    pulse=False

    adc=Adafruit_ADS1x15.ADS1015()

    while True:

      signal=adc.read_adc(0,gain=GAIN)

      curTime=int(time.time()*1000)

      send_to_pressing("S",signal)

      samplecounter += curTime - lastTime

      lastTime=curTime

      N=samplecounter-lastBeatTime

      if signal>th and signal>P:

      P=signal

      if signal(IBI/5.0)*3.0:

      if signal

      T=signal

    The complete Python script for this post is provided for you at the end.

    Raspberry Pi Heartbeat Value Graphical Display Code Written with Processing

    As we saw above, the python code sends a loopback signal to the serial port of raspberry, and the processing code receives that signal. Now we can see the unprocessed analogue input and the beats per minute. Also, the BPM value will be displayed alongside the analogue-value-based graph. We've loaded a few crucial library modules into the processing code.

    import processing.serial.*;

    PFont font;

    serial port

    A few factors have been taken into account after this.

    char letter;

    string words="";

    int sensor;

    int IBI;

    int BPM;

    int[] RawY;

    int[] scaledY;

    int[] rate;

    float offset;

    color eggshell=color(255,2)

    int pulsewindowwidth;

    int pulsewindowheight;

    int zoom_val=70;

    long beat_rec_time;

    Then, we set up the serial port and the default graph in the setup method.

    void setup()

    {

    size(500,400); // stage size

    PulseWindowWidth=Width -20;

    PulseWindowHeight=height -70;

    frameRate(100);

    textAlign(CENTER);

    rectMode(CENTER);

    ellipseMode(CENTER);

    RawY=new int[PulseWindowWidth];

    scaledY=new int[PulseWindowHeight];

    We have parsed the received information at this point in the serialEvent method.

    void serialEvent(serial port)

    {

    string inData=port.readstringuntil('\n');

    inData=trim(inData);

    if(inData.charAt(0)=='S'){

    inData=inData.substring(1);

    sensor=int(intData);

    }

    if (inData.charAt(0)=='B'){

    inData=inData.substring(1);

    BPM=int(inData);

    beat_rec_time=millis()/1000;

    }

    if (inData.charAt(0)=='Q'){

    inData=inData.substring(1);

    IBI=int(inData);

    }

    }

    We've plotted the graph by mapping the incoming numbers to the graph's dimensions in the draw function.

    void draw()

    {

    background(0);

    nostroke();

    fill(eggshell); // color for the window background

    rect(250,height/2,PulseWindowWidth,PulseWindowHeight);

    RawY[RawY.length=1]=(1023=sensor)=212;

    offset=map((float)zoom_val/100.0,0.5,1,100,0);

    stroke(250,0,0);

    nofill();

    beginshape();

    endshape();

    if(millis()/1000>=beat_rec_time=5)

    {

    BPM=0;

    IBI=0;

    }

    The following lines of code are required to display the BPM over the graph.

    fill(255,0,0);

    textsize(24);

    text("Pulse Sensor Graph",width/2,25);

    fill(0,0,255);

    textsize(18);

    text("IBI:" + IBI + "ms",width -70, height -10);

    text("BPM:" + BPM, 50, height-10);

    textsize(12);

    text("zoom:" + zoom_val + "%", width -50,50);

    Here, the code also includes a zoom function, allowing the user to selectively enlarge or reduce the size of the shown plot. The pulse plot can be panned around by pressing - to zoom out and + to zoom in. To adjust the setting, we must first click anywhere on the graph and then use the minus and plus buttons.


    void Keytyped() 

    {

    if(key == '+')

    {

    zoom_val++;

    printIn(zoom_val);

    }

    else if(key == '-')

    {

    zoom_val--;


    printIn(zoom_val);

    }

    if(zoom_val>100)

    zoom_val=100;

    else if(zoom_val<=0)

    zoom_val=0;

    }

    Thus, using a Raspberry Pi, one may monitor a patient's heart rate and graph the results. This serial data can also be sent to IoT platforms like ThingSpeak for global data sharing if necessary.

    Complete Code

    import Adafruit_ADS1x15

    import serial

    import time

    rate = [0]*10

    amp = 100

    GAIN = 2/3  

    curState = 0

    stateChanged = 0

    ser = serial.Serial ("/dev/ttyS0", 9600)

    def send_to_prcessing(prefix, data):

            ser.write(prefix)

            ser.write(str(data))

            ser.write("\n")

    def read_pulse():

        firstBeat = True

        secondBeat = False

        sampleCounter = 0

        lastBeatTime = 0

        lastTime = int(time.time()*1000)

        th = 525

        P = 512

        T = 512

        IBI = 600

        Pulse = False

        adc = Adafruit_ADS1x15.ADS1015()  

        while True:

            

            Signal = adc.read_adc(0, gain=GAIN)   

            curTime = int(time.time()*1000)

            send_to_prcessing("S",Signal)

            sampleCounter += curTime - lastTime

            lastTime = curTime

            N = sampleCounter - lastBeatTime

            if Signal > th and  Signal > P:          

                P = Signal

         

            if Signal < th and N > (IBI/5.0)*3.0 :  

                if Signal < T :                      

                  T = Signal                                                 

            

            if N > 250 :                              

                if  (Signal > th) and  (Pulse == False) and  (N > (IBI/5.0)*3.0)  :       

                  Pulse = 1;                       

                  IBI = sampleCounter - lastBeatTime

                  lastBeatTime = sampleCounter       

                  if secondBeat :                     

                    secondBeat = 0;               

                    for i in range(0,10):             

                      rate[i] = IBI                      

                  if firstBeat :                        

                    firstBeat = 0                  

                    secondBeat = 1                  

                    continue                              

                  runningTotal = 0;               

                  for i in range(0,9):            

                    rate[i] = rate[i+1]       

                    runningTotal += rate[i]      

                  rate[9] = IBI;                  

                  runningTotal += rate[9]        

                  runningTotal /= 10;             

                  BPM = 60000/runningTotal       

                  print("BPM:" + str(BPM))

                  send_to_prcessing("B", BPM)

                  send_to_prcessing("Q", IBI)

            if Signal < th and Pulse == 1 :                    

                amp = P - T                   

                th = amp/2 + T

                T = th

                P = th

                Pulse = 0 

                

            if N > 2500 :

                th = 512

                T = th                  

                P = th                                              

                lastBeatTime = sampleCounter

                firstBeat = 0                     

                secondBeat = 0                   

                print("no beats found")

            time.sleep(0.005)

    read_pulse()

    Output

    Conclusion

    By collecting data from a wide variety of sources and transmitting it across a global network of the internet as well as other communication devices that are, in turn, linked to cloud services, the system improves the quality of care provided to patients. It allows doctors to respond to medical emergencies more quickly. In the suggested system, a doctor can do a checkup on a patient at any time, from any location. If the patient's value rises over the level, they should see a doctor, and an urgent message will be sent to them through email. Paralyzed patients and those ordered strict bed rest can benefit from this method since it allows their doctors to keep an eye on them from afar using a Raspberry Pi camera. More sensors can be integrated into the system, and the Internet of Things can be expanded so that everything can be accessed instantly. The model can be improved upon and made available as a mobile application so that users anywhere in the world can access it with minimal effort. In the following lesson, we will learn how to connect a PIR sensor to a Raspberry Pi 4.

    Set Up a Network Printer with Raspberry Pi 4

    Thank you for being here for today's tutorial of our in-depth Raspberry Pi programming tutorial. The previous tutorial demonstrated the proper wiring of the photoresistor sensor to the GPIO pins. Finally, we learned how it might be included in a Python script for data collection and analysis needs. We also looked at the functions of each component in the circuit. However, I'll walk you through installing a Pi 4 Print Server in this guide. While installing the program is straightforward, setting it up so that a Windows network can locate the print server requires a little more effort. Rather than spending hundreds of dollars upgrading to a laser printer, you may easily upgrade your current USB printer to laser quality by installing a print server.

    Because of this software, you no longer have to have the printer physically linked to a single computer, and you may place it wherever you choose and share it with as many computers as you like. In addition, it's a fantastic method of printer sharing that eliminates the need for a pricey tower computer to be on and active all the time. CUPS is the program we'll be using to make this happen. Common Unix Printing System, or CUPS, is the foundation of Linux printing applications. But, the program facilitates communication between your computer and printer. It would help if you visited available printing to verify that the CUPS printing software supports your printer model.

    Where To Buy?
    No.ComponentsDistributorLink To Buy
    1Raspberry Pi 4AmazonBuy Now

    Components

    • Raspberry Pi 4

    • Wi-Fi

    • USB Printer

    Pi Print Server Software Installation

    Since the Raspberry Pi print server is included in the Debian Jessie distribution, setting it up is a breeze. In this lesson, I'll be using Raspbian, so if you're unfamiliar with it and would like to learn how to set it up, check out my guide on how to do so.

    We must ensure the Raspberry Pi is up-to-date with the most recent software to get started. Just type in the appropriate instructions into the terminal to accomplish this.

    sudo apt update

    sudo apt upgrade

    We can begin setting up the print software after the Pi 4 has been upgraded. Here, we will be setting up CUPS.

    CUPS

    CUPS, short for Common Unix Printing System, is a printing system designed for computers running UNIX-like operating systems. The software transforms the host computer into a print server. A CUPS-enabled server may receive print jobs from various client devices, sort them, and send them to the correct printer for output. Conveniently, this program can handle the administration of your printers, whether they're linked locally through USB or remotely via the network. Using the terminal, enter the following command to install the software. Considering HP has CUPS that support its open source project, HP printers, in particular. Even if your specific printer model isn't listed as being directly supported by CUPS, you may still be able to find a compatible generic driver online that will get the job done. These links will take you to a list of CUPS-compatible printers.

    sudo apt install cups

    We still have some work to do after CUPS's installation is complete. The first step is to include the pi user in the lpadmin set of users. With this group, the pi user can manage CUPS settings without logging in as the superuser.

    sudo usermod -a -G lpadmin pi

    To make sure it functions properly on your home network, there is one more thing we must do to CUPS: make it available to every computer on your network. At this time, Cups is configured to refuse connections from addresses outside the local network. By entering the following two commands, we can make it listen to all incoming connections:

    sudo cupsctl --remote-any

    sudo systemctl restart cups

    After this, any machine on the network can send prints to the Pi 4 print server. The following command can be used if you need to know your Raspberry Pi's local IP Address.

    hostname -I

    If you know your Raspberry Pi's IP address, you can use it to access the website at the address below. Be sure to replace "192.168.1.105" with your IP address.

    We'll examine how to configure SAMBA so that Windows can find the Raspberry Pi print server. Furthermore, we will demonstrate how to install a printer using the CUPS interface.

    Pi 4 Print Server SAMBA Configuration

    A proper SAMBA configuration is required if you use your print server in conjunction with Windows. To get SAMBA up and running with the CUPS print drivers, we'll have to install it and tweak its settings.

    First, check that SAMBA is installed; to do so, we can use the terminal's built-in install command. Just by typing this into the terminal, we can accomplish our goal.

    sudo apt install samba

    Now that SAMBA is installed on our Pi 4, we can access its config file and make some changes. The following command will cause the file to be opened in the nano text editor:

    Sudo nano /etc/samba/smb.conf

    Once the file has been opened, it must be scrolled to the end. To do this quickly, press the Control key plus the V key. The following lines should be added or edited once you reach the very end of the file. The file already contained the "[printers]" and "[print$]" sections; all I had to do was update the values to reflect the following.

    [printers]

    comment = All Printers

    browseable = no

    path = /var/spool/samba

    printable = yes

    guest ok = yes

    read only = yes

    create mask = 0700

    [print$]

    comment = Printer Drivers

    path = /var/lib/samba/printers

    browseable = yes

    read only = no

    guest ok = no

    To save the file, hit CTRL+X, Y, and ENTER. SAMBA needs to be restarted to pick up the updated settings. The following command, when entered into the terminal, will restart SAMBA.

    sudo systemctl restart smbd

    Installation of a Printer in CUPS

    It's easy to set up a printer using CUPS, but first, we need to open the program's graphical user interface. For the IP address of your Raspberry Pi, enter "hostname" into the terminal.

    hostname -I

    To access the IP configuration page for your Raspberry Pi, type the following into your web browser and enter the IP address you just jotted down. Replace "192.168.1.105" with your IP address when entering this address.

    The following homepage is what you should see. Here, we'll go to "Administration" on the main menu.

    You'll be directed to Cups's control panel when you click here. On this page, select the "Add Printer" option.

    The "Add Printer" screen has been brought up, allowing us to choose the printer we wish to configure Cups with. That printer is a Canon MG2500 series machine. When you've made your print choices, click the "Continue" button.

    Ensure the printer is turned on and plugged into the Raspberry Pi through a USB connection if it does not appear here. If your Raspberry Pi still doesn't show up, try restarting it while ensuring your printer is on and connected.

    Choose your printer's model from the dropdown menu here. CUPS will automatically identify the printer model and install the appropriate driver when possible. However, this may only sometimes work, so you may need to sift through the list to locate the proper driver manually. Once you've double-checked everything and are pleased, click the "Add Printer" button.

    After completing the steps on this screen, the printer will have been added successfully. Here, you can give it a name and a summary that mean whatever you choose. If you have more than one printer in your residence, specifying its location will make your life easier. If you want other computers to be able to use the printer, you must also turn on "Share This Printer." If everything looks good, hit the "Continue" button.

    After finishing the printer setup process, you will see the screen shown in the image below. Several of the printer's more nuanced settings are accessible through this panel—the number of pages printed, the quality of the printout, and so forth.

    Having finished setting up our Raspberry Pi print server, we will now discuss how to add it to Windows. Having SAMBA set up earlier in the course should make this step less painless.

    Setting up a Raspberry Pi as a Print Server in Windows

    Installing a CUPS printer on Windows requires selecting the driver that will allow Windows to communicate with and comprehend the printer. Launching "My Computer" or "This PC" and then clicking "network" in the left-hand navigation pane is a quick method to get to Windows' network page, where you can get started. When you get there, you should see a screen like the one below, where your Raspberry Pi's hostname (in my instance, RASPBERRYPI) is displayed. If you double-click your Raspberry Pi's share, it may prompt you to log in. If entering anything other than "enter" fails to log you in, try "pi."

    The printers used with your Pi 4 print server should now be displayed on the screen. Select the printer you wish to use by double-clicking on it.

    You'll see the cautionary message below if you try to double-click this. Select "OK" to proceed with the tutorial.

    Select your printer brand on the left, and then select your printer model from the available drivers for that brand on the right. If your printer isn't listed here, you can identify its model online and install the necessary drivers. For me, that meant tracking down the Canon MG2500 series. When you've decided which printer to use, you may move forward by clicking the "Ok" button.

    The procedure will now initiate a link to your printer. Select "Printer" > "Set as Default Printer" to make this the system's default printer.

    Now that the printer has been installed on your computer, you can use it with any application that supports printing. By printing a test page, you may verify that the printer is configured correctly.

    If you're having trouble printing a file, check to see if you've picked the correct printer driver in CUPS and Windows. Ensure the printer is turned on as well; the Canon MG2500 series, for example, do not immediately restart when a print job is delivered. Adding Apple AirPrint capability to your Pi 4 print server is a great way to expand its capabilities.

    The Raspberry Pi AirPrint Server Setup

    Apple's AirPrint printing technology eliminates the requirement for users of Apple products to acquire and install the separate printing software. By adding AirPrint functionality, you may quickly and effortlessly print from your iOS smartphone to any nearby printer. You can run an AirPrint server from your Raspberry Pi, and Cups is the software that will power it. It will take care of talking to your printer on your Raspberry Pi's behalf.

    The "Avahi daemon" must be set up before AirPrint may be used on your computer. The following command will install the package onto your Raspberry Pi.

    sudo apt install avahi-daemon

    Using this package, you can make Apple's Zeroconf design a reality. Bonjour has become widely used to refer to this type of network architecture. Using Bonjour, AirPrint can link disparate gadgets like an iPhone and a Raspberry Pi. Once you've selected the files you'd like to print, the Bonjour daemon will forward them to the designated printer.

    Let's restart the machine to see whether the AirPrint server has worked appropriately, and everything is ready. Execute this command to force the Raspberry Pi to restart.

    sudo reboot

    After rebooting your Raspberry Pi, you can check to see if anything went wrong. This should get you to the point where you can print from any AirPrint-enabled device.

    Display printer and print

    Conclusion

    Have you succeeded in following this guide and setting up a Pi 4 network print server? If you've followed these steps carefully, your Raspberry Pi should be ready to function as a network AirPrint server. We were able to accomplish this by putting the Avahi daemon in place. This daemon implements the bonjour protocol used by AirPrint. Feel free to leave a message below if you have any thoughts, suggestions, or problems you'd want to discuss. The following tutorial will review the steps for monitoring a patient's heart rate with a Raspberry Pi 4.

    Syed Zain Nasir

    I am Syed Zain Nasir, the founder of <a href=https://www.TheEngineeringProjects.com/>The Engineering Projects</a> (TEP). I am a programmer since 2009 before that I just search things, make small projects and now I am sharing my knowledge through this platform.I also work as a freelancer and did many projects related to programming and electrical circuitry. <a href=https://plus.google.com/+SyedZainNasir/>My Google Profile+</a>

    Share
    Published by
    Syed Zain Nasir