Différences entre versions de « Projets:ESP32 BLE variateur ampoule Led 220V »
Ligne 93 : | Ligne 93 : | ||
/** | /** | ||
− | Code to get values from a BLE device based on the following example :https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/examples/BLE_client/BLE_client.ino. Updated by Delphine with the great help of Gigi35, from My Human Kit | + | Code to get values from a BLE device based on the following example :https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/examples/BLE_client/BLE_client.ino. |
+ | |||
+ | Updated by Delphine with the great help of Gigi35, from My Human Kit. The customization is appropriated to work with electronic component triac that make it possible to dim the 220V light. | ||
*/ | */ | ||
//Triac related | //Triac related |
Version du 11 janvier 2021 à 12:25
Description du projet
L'objectif du projet est de fabriquer un variateur de lumière pour contrôler une ampoule LED OSRAM 220V avec un potentiomètre (pour tester) puis avec des données reçues en Bluetooth Low Energy
Cahier des charges
- pouvoir faire varier la lumière de manière fluide
- doit fonctionner avec les valeurs reçues en BLE
Analyse de l'existant
Equipe (Porteur de projet et contributeurs)
- Porteurs du projet :Marie
- Concepteurs/contributeurs :Delphine, Christian, Jean-jacques
- Animateur (coordinateur du projet) :Delphine
- Fabmanager référent:Delphine
- Responsable de documentation:Delphine
Matériel nécessaire
- 2 résistances 47 K
- 1 résistance 1K
- 1 résistance 100 Ohms
- 1 résistance 200 Ohms
- 4 diodes 1N4007
- 1 optocoupleur EL817 (https://www.everlight.com/file/ProductFile/201407061833256242.pdf)
- 1 driver triac MOC3020M (https://pdf1.alldatasheet.com/datasheet-pdf/view/176764/FAIRCHILD/MOC3020M.html)
- 1 triac BTA16 (https://pdf1.alldatasheet.com/datasheet-pdf/view/22039/STMICROELECTRONICS/BTA16.html)
- 1 CD40106
- 1 condensateur non polarisé 10nf (103)
- 1 condensateur polarisé 10uf
- 1 potentiomètre B10K
- 1 ESP32 expressif ESP32 WLAN Dev Kit Board Development Bluetooth Wifi v1 WRODM32 NodeMCU (https://www.espressif.com/en/products/devkits/esp32-devkitc?4)
- 1 ampoule à filament ou si à led doit être dimmable. Circuit testé avec Led OSRAM P CLAS A DIM 13 W/827 E27 Voir référence ici
- 1 transformateur 220V-12V ou directement une alimentation 220V-12V
- 2 wago (dominos) 3 entrées
- 2 wago (dominos) 2 entrées
- perfboard 40 trous de large x 32 trous de hauteurs si non fabrication du PCB
- 2 barettes de 16 pinheaders carrés pour éviter de souder l'ESP32 sur la carte
- 1 support pinheader 2x7 pins pour le 40106
- 1 support pinheader 2x3 pin pour le driver triac MOC3020M
- 1 barette de 3 pinheaders pour le BTA16
Outils nécessaires
- fer à souder
- étain
- fils à souder
- pince coupante
- pince à dénuder
- cutter (pour couper un bout de perfboard)
Coût
Délai estimé
- entre 4 et 6 heures
Fichiers source
Schéma électronique Kicad
Télécharger les sources du projet Kicad
Etapes de fabrication pas à pas
Conception du circuit électronique
Explications
On redresse le courant avec les 4 diodes. On obtient une impulsion de synchronisation qui va servir de point de départ pour le délay de max 10ms (défini par le potentiomètre ou les données reçues en BLE). Une fois passé ce délai le triac s'enclenche jusqu'à la fin de la demi alternance (10ms) car le secteur donne une alternance de 20ms. Le triac attend une demi alternance (période definie par le potentiomètre), avant de s'enclencher pendant le reste de l'alternance (période).
Le potentiomètre va dimmer (faire varier) la lumière. Plus sa valeur est petite plus la lumière est forte.
Il faudra mettre du fil bien isolé pour le circuit 220 V.
Circuit électronique pour perfboard
Réaliser le circuit suivant sur de la plaque de prototypage à trou (perfboard)
Programmation
Installer l'ESP32 dans l'IDE Arduino
Suivre ce tutoriel pour pouvoir utiliser l'IDE Arduino avec l'ESP32.
Téléverser le code sur la carte ESP32
Téléverser le code suivant sur l'ESP32. SI vous rencontrez un problème lors du téléversement, appuyer simultanément sur le bouton BOOT de l'ESP32 ou connecter un condensateur polarisé entre le GND et l'entrée EN.
Code final
Ce code permet de recevoir les données reçues en BLE (Bluetooth Low Energy). Selon l'appareil utilisé, vous aurez besoin de le personaliser pour les variables serviceUUID et charUUID
//
/**
Code to get values from a BLE device based on the following example :https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/examples/BLE_client/BLE_client.ino.
Updated by Delphine with the great help of Gigi35, from My Human Kit. The customization is appropriated to work with electronic component triac that make it possible to dim the 220V light.
*/
//Triac related
int mydelay = 0;
int myvalue = 0;
int timer_step = 2;
hw_timer_t *timer = NULL;
int counterA = 0;
int counterB = 0;
int counterC = 0;
int counterD = 0;
const int interruption_pin = 21;
const int pot_pin = 34;
//End Triac related
#include "BLEDevice.h"
//#include "BLEScan.h"
// The remote service we wish to connect to.
static BLEUUID serviceUUID("0000aa40-0000-1000-8000-00805f9b34fb"); //Custom here with your values
// The characteristic of the remote service we are interested in.
static BLEUUID charUUID("0000aa41-0000-1000-8000-00805f9b34fb");//Custom here with your values
static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLEAdvertisedDevice* myDevice;
int perifit[] = {0, 0, 0, 0};
int w;
int x;
int y;
int z;
int pp;
int ps;
///triac related////////////
void IRAM_ATTR rising_edge_isr() {
if (timer_step == 2) {
// No need to read anything : it is a rising edge
// We just need to configure a timer interrupt
// with current value of mydelay
timer_step = 0;
timerAlarmWrite(timer, myvalue, false);
timerAlarmEnable(timer);
timerRestart(timer);
counterA = counterA + 1;
} else {
counterD = counterD + 1;
}
}
void IRAM_ATTR timer_isr() {
if (timer_step == 0) {
// Activate triac
digitalWrite(16, HIGH);
timer_step = 1;
// Configure the timer again to end the pulse
// in 100 us
timerAlarmWrite(timer, 100, false);
//timerAlarmWrite(timer, 500,false);
timerRestart(timer);
timerAlarmEnable(timer);
counterB = counterB + 1;
} else if (timer_step == 1) {
// End the pulse
digitalWrite(16, LOW);
timerStop(timer);
counterC = counterC + 1;
timer_step = 2;
}
}
//////////End triac related
static void notifyCallback(
BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData,
size_t length,
bool isNotify) {
w = pData[0];//w = perifit[0];
x = pData[1];
y = pData[2];
z = pData[3];
ps = x + (256 * w);
pp = z + (256 * y);
myvalue = map(ps, 180, 2700, 10500, 1500);//If the lamp lights on when should not, put a lower value for 10500. Si l'ampoule s'allume au repos par erreur baisser un peu la valeur de 10500 dans le mapping
}
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());
Serial.println(value.c_str());
}
if (pRemoteCharacteristic->canNotify())
pRemoteCharacteristic->registerForNotify(notifyCallback);
connected = true;
return 0;//not necessary before but added when happened this error whereas no change was made in the code: control reaches end of non-void function [-Werror=return-type]
}
/**
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
/////////For ESP32:https://lastminuteengineers.com/handling-esp32-gpio-interrupts-tutorial/
void setup() {
//////////triac related/////////////
Serial.begin(115200);
Serial.println("init setup triac");
// Zero crossing detection
// Rising edge is enough : it should generate 100 interrupts per second.
pinMode(21, INPUT_PULLUP);
attachInterrupt(21, rising_edge_isr, RISING);
// Output configuration
pinMode(16, OUTPUT);
// Timer prescaler configuration
// with a 80 prescaler value, timer value is
// directly expressed in microseconds
timer = timerBegin(0, 80, true); // croissant
timerStop(timer);
timerAttachInterrupt(timer, &timer_isr, true);
//timerAttachInterrupt(timer, &timer_isr, false);
///end of triac related
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);
Serial.println("CLEARDATA"); // on efface les données déjà présentes, s'il y a lieu
Serial.println("LABEL,Temps,W,X,Y,Z");
} // 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());
pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());
} else if (doScan) {
BLEDevice::getScan()->start(0); // this is just eample 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