Diferència entre revisions de la pàgina «Caseta del Pere»
m (→BLE_write2.ino) |
|||
| (Hi ha 4 revisions intermèdies del mateix usuari que no es mostren) | |||
| Línia 2: | Línia 2: | ||
=Introducció= | =Introducció= | ||
La idea és fer una caseta amb unes llums que es pugui encendre, apagar o canviar la intensitat. Ha d'estar controlat amb una app mòbil (React Native). Es farà servir la ESP32, i la comunicació per bluetooth BLE. | La idea és fer una caseta amb unes llums que es pugui encendre, apagar o canviar la intensitat. Ha d'estar controlat amb una app mòbil (React Native). Es farà servir la ESP32, i la comunicació per bluetooth BLE. | ||
| + | =Projecte similar= | ||
| + | *https://diyodemag.com/features/diy_solar_powered_wifi_weather_station_esp32 | ||
| + | També utilitzen una pila Li-ion 18650 que es carrega amb un panell solar. Utilitza un voltage Regulator LDO MCP1700 per tal de proporcionar una tensió estable de 3.3V al ESP32. I utilitza el sensor BME280 per tal de mesurar la temperatura, humitat i pressió atmosfèrica. | ||
| + | |||
| + | LDO regulator significa Low DropOutput, que vol dir que per proporcionar 3,3V n'hi ha prou en què la tensió d'entrada estigui una mica més amunt que 3,3V. | ||
| + | |||
=ESP32, BLE= | =ESP32, BLE= | ||
[[Fitxer:ESP32-38-Pin-Pinout.jpg | thumbnail]] | [[Fitxer:ESP32-38-Pin-Pinout.jpg | thumbnail]] | ||
| Línia 39: | Línia 45: | ||
</pre> | </pre> | ||
Puc mirar de solucionar-ho, o bé arrenco el Arduino IDE com a sudo (i he de tornar a instal·lar el ESP32). Finalment sí que puc pujar a la placa un dels exemples que hi ha (concretament, un exemple de client BLE). | Puc mirar de solucionar-ho, o bé arrenco el Arduino IDE com a sudo (i he de tornar a instal·lar el ESP32). Finalment sí que puc pujar a la placa un dels exemples que hi ha (concretament, un exemple de client BLE). | ||
| + | |||
| + | '''Solució''': | ||
| + | You need to set serial port permission | ||
| + | <pre>ls -l /dev/ttyUSB0 | ||
| + | crw-rw---- 1 root dialout 188, 0 de juny 15 23:36 /dev/ttyUSB0 | ||
| + | |||
| + | sudo usermod -a -G dialout joan | ||
| + | sudo chmod a+rw /dev/ttyUSB0 | ||
| + | </pre> | ||
| + | |||
==Primeres proves amb BLE== | ==Primeres proves amb BLE== | ||
Volem llegir del ESP32 i escriure en el ESP32, desde i amb una app mòbil. | Volem llegir del ESP32 i escriure en el ESP32, desde i amb una app mòbil. | ||
| Línia 121: | Línia 137: | ||
</pre> | </pre> | ||
I d'aquesta manera m'asseguro de fer un reset de tant en tant, la qual cosa significa que quan faig el scan ja apareix el meu dispositiu, i em puc connectar i veure els valors. | I d'aquesta manera m'asseguro de fer un reset de tant en tant, la qual cosa significa que quan faig el scan ja apareix el meu dispositiu, i em puc connectar i veure els valors. | ||
| + | ==BLE_write2.ino== | ||
| + | [[Fitxer:BLE Scanner.jpg | thumbnail]] | ||
| + | De moment el codi que funciona, que sóc capaç de connectar-me al Bluetooth del ESP32, i llegir i escriure: | ||
| + | <pre> | ||
| + | /* | ||
| + | Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleWrite.cpp | ||
| + | Ported to Arduino ESP32 by Evandro Copercini | ||
| + | */ | ||
| + | |||
| + | #include <BLEDevice.h> | ||
| + | #include <BLEUtils.h> | ||
| + | #include <BLEServer.h> | ||
| + | #include <sys/time.h> | ||
| + | #include <string> | ||
| + | #include <sstream> | ||
| + | |||
| + | // 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" | ||
| + | |||
| + | BLEServer *pServer; | ||
| + | BLEService *pService; | ||
| + | BLECharacteristic *pCharacteristic; | ||
| + | int i; | ||
| + | |||
| + | class MyCallbacks: public BLECharacteristicCallbacks { | ||
| + | void onWrite(BLECharacteristic *pCharacteristic) { | ||
| + | std::string value = pCharacteristic->getValue(); | ||
| + | |||
| + | if (value.length() > 0) { | ||
| + | Serial.println("*********"); | ||
| + | Serial.print("New value: "); | ||
| + | for (int i = 0; i < value.length(); i++) | ||
| + | Serial.print(value[i]); | ||
| + | |||
| + | Serial.println(); | ||
| + | Serial.println("*********"); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void onRead(BLECharacteristic *pCharacteristic) { | ||
| + | struct timeval tv; | ||
| + | gettimeofday(&tv, nullptr); | ||
| + | std::ostringstream os; | ||
| + | os << "Time: " << tv.tv_sec; | ||
| + | std::string str1 = os.str(); | ||
| + | Serial.println(str1.c_str()); //https://arduino.stackexchange.com/questions/56365/arduino-convert-stdstring-to-string | ||
| + | pCharacteristic->setValue(os.str()); | ||
| + | } | ||
| + | |||
| + | }; | ||
| + | |||
| + | void setup() { | ||
| + | Serial.begin(115200); | ||
| + | |||
| + | Serial.println("1- Download and install an BLE scanner app in your phone"); | ||
| + | Serial.println("2- Scan for BLE devices in the app"); | ||
| + | Serial.println("3- Connect to MyESP32"); | ||
| + | Serial.println("4- Go to CUSTOM CHARACTERISTIC in CUSTOM SERVICE and write something"); | ||
| + | Serial.println("5- See the magic =)"); | ||
| + | |||
| + | BLEDevice::init("MyESP32"); | ||
| + | pServer = BLEDevice::createServer(); | ||
| + | |||
| + | pService = pServer->createService(SERVICE_UUID); | ||
| + | |||
| + | pCharacteristic = pService->createCharacteristic( | ||
| + | CHARACTERISTIC_UUID, | ||
| + | BLECharacteristic::PROPERTY_READ | | ||
| + | BLECharacteristic::PROPERTY_WRITE | ||
| + | ); | ||
| + | |||
| + | pCharacteristic->setCallbacks(new MyCallbacks()); | ||
| + | |||
| + | pCharacteristic->setValue("Hello World"); | ||
| + | pService->start(); | ||
| + | |||
| + | BLEAdvertising *pAdvertising = pServer->getAdvertising(); | ||
| + | pAdvertising->start(); | ||
| + | } | ||
| + | |||
| + | void loop() { | ||
| + | // put your main code here, to run repeatedly: | ||
| + | i=i+1; | ||
| + | char cstr[16]; | ||
| + | itoa(i, cstr, 10); | ||
| + | pCharacteristic->setValue(cstr); | ||
| + | delay(2000); | ||
| + | } | ||
| + | </pre> | ||
| + | L'aplicació que estic fent servir és ''BLE Scanner''. Em connecto al ESP32, i en l'apartat '''CUSTOM SERVICE''' tinc la possibilitat de llegir i escriure. Puc llegir els segons des que ha arrencat el ESP32, o puc escriure una cadena. | ||
{{Autor}}, juny 2021 | {{Autor}}, juny 2021 | ||
Revisió de 09:15, 29 juny 2022
Contingut
Introducció
La idea és fer una caseta amb unes llums que es pugui encendre, apagar o canviar la intensitat. Ha d'estar controlat amb una app mòbil (React Native). Es farà servir la ESP32, i la comunicació per bluetooth BLE.
Projecte similar
També utilitzen una pila Li-ion 18650 que es carrega amb un panell solar. Utilitza un voltage Regulator LDO MCP1700 per tal de proporcionar una tensió estable de 3.3V al ESP32. I utilitza el sensor BME280 per tal de mesurar la temperatura, humitat i pressió atmosfèrica.
LDO regulator significa Low DropOutput, que vol dir que per proporcionar 3,3V n'hi ha prou en què la tensió d'entrada estigui una mica més amunt que 3,3V.
ESP32, BLE
BLE: Bluetooth Low Energy, aquesta és la manera que em servirà, en principi, per connectar la caseta amb el mòbil. Per tant, el primer objectiu és probar els codis d'exemple de ESP32 de l'Arduino IDE, i establir la comunicació bàsica entre el ESP32 i aplicacions mòbils que ens podem descarregar en el App Store.
Petita explicació BLE:
La placa que m'he comprat (8e) és aquesta:
- ESP-32 Placa de desarrollo NodeMCU ESP32 WiFi y Bluetooth ESP 32 WROOM 38 Pines
Arduino IDE: ESP32
La solució correcta està aquí:
A preferències del IDE fem: url addicional de gestor de plaques:
https://dl.espressif.com/dl/package_esp32_index.json
i ara ja podem instal·lar des de placa > Gestor de plaques, cercant per ESP32
I ara vaig a mirar els exemples del ESP32, concretament la part que m'interessa, que és ESP32 BLE:
exec: "python": executable file not found in $PATH
i és que el meu executable de python és python3
això té fàcil solució:
sudo apt-get install python-is-python3
Ara quan en la consola faig python s'executa el python3, que és el que volíem. I també necessitem:
sudo apt-get install python3-serial
Tinc el vell problema conegut de
permission denied
Puc mirar de solucionar-ho, o bé arrenco el Arduino IDE com a sudo (i he de tornar a instal·lar el ESP32). Finalment sí que puc pujar a la placa un dels exemples que hi ha (concretament, un exemple de client BLE).
Solució: You need to set serial port permission
ls -l /dev/ttyUSB0 crw-rw---- 1 root dialout 188, 0 de juny 15 23:36 /dev/ttyUSB0 sudo usermod -a -G dialout joan sudo chmod a+rw /dev/ttyUSB0
Primeres proves amb BLE
Volem llegir del ESP32 i escriure en el ESP32, desde i amb una app mòbil.
L'app que faig servir es diu BLE Scanner (de Bluepixel Technologies, support@bluepixeltech.com). Una altra aplicació que va bé és: nRF Connect for Mobile from Nordic (https://randomnerdtutorials.com/esp32-bluetooth-low-energy-ble-arduino-ide/)
BLE_server.ino: Script arduino per poder llegir en el mòbil el que em diu el ESP32:
Concretament, la línia que escriu és:
pCharacteristic->setValue("Hello World says Neil");
que és un CUSTOM SERVICE, i en el mòbil el que he de fer és connectar-me al ESP32, anar a Custom Service, i llegir (R)
BLE_write.ino: script arduino per poder escriure des del mòbil cap al ESP32 (i també posa una custom characteristic que la podem llegir en el mòbil, Hello world). Aquest script també és un servidor, igual que abans.
En el mòbil: 4- Go to CUSTOM CHARACTERISTIC in CUSTOM SERVICE and write something
i en el port sèrie de l'Arduino veuré la informació que he escrit.
script BLE_client.ino. Encara no l'he fet funcionar. I és que és un client, i he de tenir clar a quin servei s'ha de connectar (podria ser un servei del mòbil, però ho he de saber fer). Típicament, la pràctica es pot fer amb dos ESP32, un que faci de servidor i un altre de client.
A mi el que m'interessa és els dos scripts que fan de server, doncs he demostrat que el ESP32 pot llegir del mòbil, i pot escriure cap al mòbil. Evidentment, en el mòbil m'he de connectar a aquest ESP-32.
Problemes de connexió
El meu problema no sé si té a veure amb això:
El tema és que arrenco el ESP32, i puc establir una connexió amb el mòbil, sense problemes, i puc llegir (custom characteristic) del ESP32, o també puc enviar informació al ESP32 (que puc veure a la consola sèrie). Si deixo la connexió oberta no hi ha problema, i no es desconnecta.
El problema sempre bé quan tiro endarrera a l'anterior pantalla (no sé si això vol dir desconnectar). Alehores ja no em puc tornar a connectar, o senzillament quan faig el scan ja no m'apareix, i la única solució és fer un reset.
Potser senzillament quan faci la meva app no hi haurà problema. Jo sé a quin dispositiu em vull connectar, i no he d'estar connectant-me i desconnectant-me, senzillament deixaré la connexió oberta.
Una possibilitat (veure més avall), és fer un reset periòdic.
Llegir d'un sensor
Encara no he posat cap sensor, però aquí va la modificació mínima que per poder llegir una informació dins del loop. Si tinc un sensor, i el vull llegir des de l'aplicació mòbil, modifico el BLE_write.ino de la següent manera:
BLEServer *pServer;
BLEService *pService;
BLECharacteristic *pCharacteristic;
int i;
...
pServer = BLEDevice::createServer();
pService = pServer->createService(SERVICE_UUID);
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
pCharacteristic->setValue("Hello World");
pService->start();
...
void loop() {
// put your main code here, to run repeatedly:
i=i+1;
char cstr[16];
itoa(i, cstr, 10);
pCharacteristic->setValue(cstr);
delay(2000);
}
Els exemples estan físicament a:
- /home/joan/.arduino15/packages/esp32/hardware/esp32/1.0.6/libraries/BLE/examples/BLE_write/BLE_write.ino
Si vull sobreescriure'ls o canviar-li el nom i modificar, s'ha de donar permís d'escriptura
Fer un reset periòdic
Sempre que em connecto i miro els valors, tot seguit es desconnecta i faig el scanning i no em surt el meu ESP32.
Una possible solució és fer un reset del ESP32 per software. Es pot fer de la següent manera:
void(* resetFunc) (void) = 0;
...
if (i%20 == 0) {
Serial.println("reset");
resetFunc(); //call reset
}
I d'aquesta manera m'asseguro de fer un reset de tant en tant, la qual cosa significa que quan faig el scan ja apareix el meu dispositiu, i em puc connectar i veure els valors.
BLE_write2.ino
De moment el codi que funciona, que sóc capaç de connectar-me al Bluetooth del ESP32, i llegir i escriure:
/*
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleWrite.cpp
Ported to Arduino ESP32 by Evandro Copercini
*/
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <sys/time.h>
#include <string>
#include <sstream>
// 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"
BLEServer *pServer;
BLEService *pService;
BLECharacteristic *pCharacteristic;
int i;
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string value = pCharacteristic->getValue();
if (value.length() > 0) {
Serial.println("*********");
Serial.print("New value: ");
for (int i = 0; i < value.length(); i++)
Serial.print(value[i]);
Serial.println();
Serial.println("*********");
}
}
void onRead(BLECharacteristic *pCharacteristic) {
struct timeval tv;
gettimeofday(&tv, nullptr);
std::ostringstream os;
os << "Time: " << tv.tv_sec;
std::string str1 = os.str();
Serial.println(str1.c_str()); //https://arduino.stackexchange.com/questions/56365/arduino-convert-stdstring-to-string
pCharacteristic->setValue(os.str());
}
};
void setup() {
Serial.begin(115200);
Serial.println("1- Download and install an BLE scanner app in your phone");
Serial.println("2- Scan for BLE devices in the app");
Serial.println("3- Connect to MyESP32");
Serial.println("4- Go to CUSTOM CHARACTERISTIC in CUSTOM SERVICE and write something");
Serial.println("5- See the magic =)");
BLEDevice::init("MyESP32");
pServer = BLEDevice::createServer();
pService = pServer->createService(SERVICE_UUID);
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
pCharacteristic->setValue("Hello World");
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
}
void loop() {
// put your main code here, to run repeatedly:
i=i+1;
char cstr[16];
itoa(i, cstr, 10);
pCharacteristic->setValue(cstr);
delay(2000);
}
L'aplicació que estic fent servir és BLE Scanner. Em connecto al ESP32, i en l'apartat CUSTOM SERVICE tinc la possibilitat de llegir i escriure. Puc llegir els segons des que ha arrencat el ESP32, o puc escriure una cadena.
creat per Joan Quintana Compte, juny 2021