• First Steps
  • General
  • Projects
Facebook Twitter YouTube
Tutorials for Raspberry Pi Tutorials for Raspberry Pi
  • Hardware & GPIO
  • Sensors & Components
  • Scale
  • Cases
  • Fingerprint
  • Gas Sensor
  • Heartbeat
  • German
Tutorials for Raspberry Pi Tutorials for Raspberry Pi
Home»Arduino & ESP8266»How-To: Bluetooth Connection between ESP32’s and Raspberry Pi’s

How-To: Bluetooth Connection between ESP32’s and Raspberry Pi’s

Facebook Twitter LinkedIn Tumblr Email Reddit
Raspberry Pi Bluetooth Connection to ESP32
Share
Facebook Twitter LinkedIn Email Tumblr Reddit Telegram WhatsApp

Bluetooth is one of the most efficient short ranged wireless connectivity tools for exchanging data using Ultra High-Frequency Radio Waves (typically of 2.4 GHz) and building Personal Area Networks (PAN). Fundamentally, Bluetooth Technology was built as a cable replacement system, so its use in embedded systems is inevitable. Most of the famous microcontrollers such as ESP32, Raspberry Pi, Arduino Mega have built in Bluetooth modules, other microcontrollers can be adapted with modules like HC 05 or JDY-30 to make them Bluetooth compatible. This article will help you grasp the basic know-how about the working of Bluetooth modules between two ESP32s and connectivity between Raspberry Pi and ESP32.

Required Components

You will require the following things:

  • Raspberry Pi with PYQT library installed
  • Arduino IDE
  • Two ESP32 Development Boards
  • NRF Application (App Store, Play Store)
  • Usb Cable for ESP32

Bluetooth Low Energy (BLE)

Most of the Microcontrollers including Raspberry Pi and ESP32 have Bluetooth modules based on Bluetooth Low-Energy Technology. BLE is a low-energy consumption variant of Bluetooth, unlike the classic Bluetooth it is designed for a very short range and a small bandwidth of data to be transferred over a small distance. Since it is very good in power conservation, so it uses almost 100 times less energy as compared to classic Bluetooth with a very small compromise of performance. BLE is in a sleep mode unless a connection is made, or it is required in transferring data as compared to classic Bluetooth that is always on.

It operates in four modes:

  • Peripheral – It is basically a device that advertise the data, but it can be also used to connect to remote devices
  • Broadcaster -It is the device whose sole purpose is to advertise data.
  • Observer -Device that only scans for the data.
  • Central -This is a device that is dual purpose and can scan for data as well as can connect to them

When BLE was introduced, first two modes were utilized by sensors and other industrial equipment and last two were used by mobile phones computers. However, with the evolution of technology now, most BLE provides all four modes of transfer. ESP32 and Raspberry Pi also provide these four modes of transfer. You can see the significant difference between the classic and BLE in the table below.

ESP32 BLE vs Classic Bluetooth Infographic

 

Connection Between Two ESP32’s

Two ESP32s can be connected in a very optimized way using BLE capability. Bluetooth connection between two boards will be established in a way such that one board will act as a server and the other one will act as client. One ESP32 will act as a server and advertise the data and initiate the connection, the second ESP32 will act as a client and will receive the data from the server. We will be sending some strings from one esp32 to the other one using BLE connection.

NodeMCU Boards via Bluetooth connected

 

ESP32 Bluetooth Pinout Schematic Diagram

 

ESP32 as a Server

Our first ESP32 will be acting as a Bluetooth server. It will provide the connection and data to the client. Its code is as following:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
 
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
 
#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);
}
 

This code is using the BLE class to create its objects like characteristics, BLE, and Advertising objects. It has Characteristic and Service UUID at the start. UUID, an acronym of Universally Unique ID, and it corresponds to a unique number which that is used to identify services and characteristic that a Bluetooth device is supposed to provide. First in this code we created three objects of BLEserver, BLEcharacteristic and BLEService class respectively and initialized them with their required values. Then we simply used the start advertising function from the BLE device class to start our Bluetooth server with the particular UUID, characteristics and Services that we initialized. You can set any data like any sensor data or any other required data and start advertising it. Once this server is started, you can access it even in your mobile phone using nRF Connect in just two steps as below:

Step 1: Open the scanner and connect to your Bluetooth device

Smartphone BL Scanning

Step 2: After connecting to your ESP32, you can check the characteristic, and it will be displaying your text written.

Android Connect to ESP32

 

ESP32 as a Client

As the name implies, second esp32 will be acting as a client and access the data from the server. It should just provide the UUIDs of characteristic and services to connect to the server and access the specified services provided by the server esp32.

Its code is as:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
 
#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 actually a string.
    pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());
  }else if(doScan){
    BLEDevice::getScan()->start(0);  // this is just example to start scan after disconnect, most likely there is better way to do it in arduino
  }
  
  delay(1000); // Delay a second between loops.
} // End of loop
 

This code is relying on some user-defined functions. We defined Characteristic and service UUID at the start of the code. Objects of BLERemoteCharacteristic, BLEAdvertisedDevice classes are made at the start and function connectToServer() is used to connect to the server(other esp32). It finally fetches all the data provided by server using variables of characteristic and service . The serial monitor will display the following values as:

Serial Output of ESP32

 

Connection Between ESP32 and Raspberry Pi

ESP32 Connection: Our ESP32 will be running A UART connection on the Bluetooth. So it will be able to communicate two ways with the Raspberry Pi.

Our code is as:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
 
#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;
    }
}
 

This code is had two portions, one is transmitting any random data in a loop. The other one is receiving data. At the start we have defined two characteristics as RX and TX, then we have defined and assigned them proper values according to our need. As we are using UART, so we can transmit and as well as receive simultaneously without any obstruction . You can test one side of connection by using the NRF Application (App store link: https://apps.apple.com/us/app/nrf-connect-for-mobile/id1054362403            Play store link: https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp). Upload the above code and open NRF Connector application, connect to the UART-SERVICE as:

 

After connecting type, the value, you want to send to serial monitor. Your value will be sent to the serial monitor.

Raspberry Pi Connection:

Raspberry Pi is running a script of python using bluepy (a special library of raspberry pi to use BLE mode). Basically, this code develops a basic GUI that helps sends and receive data from the esp. 32. You should install PYQT and bluepy libraries before proceeding. After setting this up just run this code and a graphical user interface will display on the screen. Then you can enter the data to send over the BLE to ESP32, or it will be displaying the data received from the esp32. This connection is a UART (universally asynchronous receiver-transmitter). Which means it has both capabilities to send and receive data at the same time. In the first text box you will receive the data from esp. 32 and in the second textbox you will write the data to be sent from Raspberry Pi.

Raspberry Pi Bluetooth Connection to ESP32

Raspberrry Pi Serial Output of Bluetooth Connection

At the ESP32 serial communication monitor we have:

ESP8266 NodeMCU Serial Output of Bluetooth Connection to Raspberry Pi

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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()
 
 

 

Practical Uses in Industry

BLE is very beneficial in the places where we don’t have enough power to supply. Let’s discuss some of its practical applications:

Smart Agricultural System: A microcontroller like ESP32 or Raspberry Pi having ble capability can be used on batteries for weeks to transfer all the sensors’ data from one esp32 to other esp32 to take significant actions for proper growth of crops/plants (like turning on the lights or turning on the motor)

Sports Trainers: A microcontroller can be used to send data like heartbeat, running speed or any other data measured through sensors via Bluetooth to mobile phone or simply display on screen like max 7219. They can easily monitor all these values efficiently without any wiring.

Health Monitoring Systems: Wrist bands to measure different data like heartbeat, blood pressure and other things like this can be transferred directly to a computer using BLE capability of a microcontroller.

Home Automation:  Home automation is one of the gifts that compact microcontrollers made possible. BLE devices can be used to make very innovative things from controlling lights to making fingerprint lock doors, everything is possible. Some of its interesting applications are:

  1. Reminders for appliances like stoves, water pumps, heaters, geyser to turn them off at a particular time
  2. Mobile controlled security cameras
  3. Mobile controlled automated garage doors (using esp. 32 or Raspberry Pi)
  4. Different sensor data collection from the house (fire, water, motion, light)
Bluetooth ESP-32 ESP32 ESP8266
Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
Previous ArticleRaspberry Pi: Java 11 mit Spring Boot installieren und GPIOs steuern
Next Article Using TensorFlow Lite with Google Coral TPU on Raspberry Pi 4

Related Posts

How to build a ESP8266 Scale (with Weight Sensor HX711)

How to create a Solar Powered Raspberry Pi Bitcoin Miner

How to build a Smart Agriculture System using IoT

Reading out a Flow Meter/Water Flow Sensor on the Raspberry Pi

Leave A Reply Cancel Reply

How to setup a Raspberry Pi Security Camera Livestream

How-To: Bluetooth Connection between ESP32’s and Raspberry Pi’s

Remote Control a Raspberry Pi with 433Mhz Radio Transmitter

How to get Google Chromium for the Raspberry Pi

Raspberry Pi Bluetooth Data Transfer to the Smartphone

Programming Raspberry Pi Robot: Making it Follow the Lines (Part 2)

Subscribe to Blog
Subscribe to Raspberry Pi Tutorials and don't miss any new Tutorial!
Subscribe

Thank you!

We will contact you soon.

Tutorials for Raspberry Pi
Facebook Twitter YouTube
  • Contact & Disclaimer

Type above and press Enter to search. Press Esc to cancel.