I made my own Mqtt to speech thingy in the past. Sending a text to a mqtt topic would be picked up by my domoticz raspberry and using a bash script the topic payload was converted to speech and being played on a connected speaker.
This speaker migrated to my Home Assistant NUC. So i changed the speech engine.
Beside this migration, i’ve started using the HA voice assistant capabilities. This was a major impact/project in 2023.
I’m not going to talk about configuring this .. There are many good YT tutorials and forum topics about this.
LD2410 is a high-sensitivity 24GHz human presence status sensing module developed by Hi-link. Its working principle is to use FMCW frequency-modulated continuous waves to detect human targets in the set space. Combined with radar signal processing and precise human body sensing algorithms, it realizes high-sensitivity human presence status sensing, and can identify human bodies in motion and stationary states. And auxiliary information such as the distance of the target can be calculated.
This product is mainly used in indoor scenes to sense whether there is a moving or micro-moving human body in the area, and output the detection results in real time. The farthest sensing distance can reach 5 meters, and the distance resolution is 0.75m. Provides a visual configuration tool, which can easily configure the sensing distance range, sensing sensitivity in different intervals and unmanned delay time, etc., to adapt to different specific application needs.
Support GPIO and UART output, plug and play, and can be flexibly applied to different smart scenarios and terminal products.
There are 3 versions: Without Bluetooth, with Bluetooth (B version) and a C version which uses the standard pin distance. The other ones are a pain in the *ss to solder!
Got a Bluetooth version? See end of post!
When searching for examples, I noticed that many had issues getting this working. Let me be clear, it wasn’t working for me the first time. Things i’ve learned:
Flash the first initial ESPHome using a USB cable, after that you can connect the module and flash OTA
Do not use the standard Uart RX/TX, it didn’t work for me. And messes-up the logging over USB (See baudrate: 0 to turn this off)
When connecting D7/D8 and this signal gets pulled down, the wemos won’t boot. (Running wifi connections gets interrupted) This is also a sign that RX/TX is switched around!
Measure and make sure you have a good, stable 5V power to your LD2410
Here is a post about the RCWL-0516, a similar project, but this one can’t measure distances and person detection won’t work when a person is not moving.
Parts i’ve changed: board: Changed from esp-1?? to d1_mini logger: baud_rate: 0 tx_pin and rx_pin
esphome:
name: ld2410-1
friendly_name: ld2410-1
esp8266:
board: d1_mini
# Enable logging
logger:
baud_rate: 0
# Enable Home Assistant API
api:
encryption:
key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx="
ota:
password: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Ld2410-1 Fallback Hotspot"
password: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
captive_portal:
ld2410:
id: ld2410_radar
uart:
tx_pin: GPIO15
rx_pin: GPIO13
baud_rate: 256000
parity: NONE
stop_bits: 1
number:
- platform: ld2410
timeout:
name: Radar Timeout
max_move_distance_gate:
name: Radar Max Move Distance
max_still_distance_gate:
name: Radar Max Still Distance
g0:
move_threshold:
name: g0 move threshold
still_threshold:
name: g0 still threshold
g1:
move_threshold:
name: g1 move threshold
still_threshold:
name: g1 still threshold
g2:
move_threshold:
name: g2 move threshold
still_threshold:
name: g2 still threshold
g3:
move_threshold:
name: g3 move threshold
still_threshold:
name: g3 still threshold
g4:
move_threshold:
name: g4 move threshold
still_threshold:
name: g4 still threshold
g5:
move_threshold:
name: g5 move threshold
still_threshold:
name: g5 still threshold
g6:
move_threshold:
name: g6 move threshold
still_threshold:
name: g6 still threshold
g7:
move_threshold:
name: g7 move threshold
still_threshold:
name: g7 still threshold
g8:
move_threshold:
name: g8 move threshold
still_threshold:
name: g8 still threshold
binary_sensor:
- platform: ld2410
has_target:
name: Radar Target
id: radar_has_target
has_moving_target:
name: Radar Moving Target
has_still_target:
name: Radar Still Target
button:
- platform: ld2410
factory_reset:
name: "factory reset"
restart:
name: "restart"
query_params:
name: query params
sensor:
- platform: ld2410
moving_distance:
name: Radar Moving Distance
id: moving_distance
still_distance:
name: Radar Still Distance
id: still_distance
moving_energy:
name: Radar Move Energy
still_energy:
name: Radar Still Energy
detection_distance:
name: Radar Detection Distance
id: radar_detection_distance
g0:
move_energy:
name: g0 move energy
still_energy:
name: g0 still energy
g1:
move_energy:
name: g1 move energy
still_energy:
name: g1 still energy
g2:
move_energy:
name: g2 move energy
still_energy:
name: g2 still energy
g3:
move_energy:
name: g3 move energy
still_energy:
name: g3 still energy
g4:
move_energy:
name: g4 move energy
still_energy:
name: g4 still energy
g5:
move_energy:
name: g5 move energy
still_energy:
name: g5 still energy
g6:
move_energy:
name: g6 move energy
still_energy:
name: g6 still energy
g7:
move_energy:
name: g7 move energy
still_energy:
name: g7 still energy
g8:
move_energy:
name: g8 move energy
still_energy:
name: g8 still energy
Bluetooth:
I’ve connected this HLK-DL2410B to Home Assistant before using Bluetooth. But I wanted to get them connected using Wifi.
You can install a App on you phone to connect to the sensor when powered on. This way you can test the device, but also upgrade the firmware and make adjustments!
Just enable engineering mode and click more.
Testing another baud rate and upgrading the firmware:
Posted because I could not find a good example on the interwebs.
Below creates a virtual HA button which toggles a blinking led. (button and variables are called eprint for another function, change to something meaningful. )
Home Assistant virtual mqtt switch (configuration.yml)
Point the sensor at yourself when behind your computer. When you leave your computer for some seconds, it wil automatically lock your screen. (Windows-L keypress) The RP2040 is configured as HID so it emulates a keyboard. Just connect via an usb-cable to your machine
#include "Adafruit_TinyUSB.h"
// defines pins numbers
const int trigPin = D4;
const int echoPin = D5;
// defines variables
long duration;
int distance;
int maxcounter;
uint8_t const desc_hid_report[] =
{
TUD_HID_REPORT_DESC_KEYBOARD()
};
// D0-D3 NOT USED AT THE MOMENT, I'VE GOT IDEAS FOR EXTRA FUNCTIONALLITY!
// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_KEYBOARD, 2, false);
//------------- Input Pins -------------//
// Array of pins and its keycode.
uint8_t pins[] = { D0, D1, D2, D3 };
// number of pins
uint8_t pincount = sizeof(pins)/sizeof(pins[0]);
// For keycode definition check out https://github.com/hathach/tinyusb/blob/master/src/class/hid/hid.h
uint8_t hidcode[] = { HID_KEY_0, HID_KEY_1, HID_KEY_2, HID_KEY_3 , HID_KEY_4, HID_KEY_5 };
#if defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(ARDUINO_NRF52840_CIRCUITPLAY) || defined(ARDUINO_FUNHOUSE_ESP32S2)
bool activeState = true;
#else
bool activeState = false;
#endif
void setup()
{
// Setting pins for Ultrasonic Sensor HC-SR04
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
// Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
TinyUSB_Device_Init(0);
#endif
// Set up output report (on control endpoint) for Capslock indicator
// Not used .. yet
usb_hid.setReportCallback(NULL, hid_report_callback);
usb_hid.begin();
// overwrite input pin with PIN_BUTTONx
// NOT USED
#ifdef PIN_BUTTON1
pins[0] = PIN_BUTTON1;
#endif
#ifdef PIN_BUTTON2
pins[1] = PIN_BUTTON2;
#endif
#ifdef PIN_BUTTON3
pins[2] = PIN_BUTTON3;
#endif
#ifdef PIN_BUTTON4
pins[3] = PIN_BUTTON4;
#endif
// Set up pin as input
for (uint8_t i=0; i<pincount; i++)
{
pinMode(pins[i], activeState ? INPUT_PULLDOWN : INPUT_PULLUP);
}
// wait until device mounted
while( !TinyUSBDevice.mounted() ) delay(1);
maxcounter =0;
}
void loop()
{
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance = duration * 0.034 / 2;
// Prints the distance on the Serial Monitor - DEBUG
//Serial.print("Distance: ");
//Serial.println(distance);
// Below will wait for more than 100 measurements with a distance of 100
// Then it will send a WINDOWS-L (lock) keyboard combination
if (distance > 100)
{
maxcounter +=1;
}
else
{
maxcounter = 0;
}
if (maxcounter > 100 && maxcounter < 150)
{
maxcounter = 200;
// Send report if there is key pressed
uint8_t const report_id = 0;
uint8_t modifier = KEYBOARD_MODIFIER_LEFTGUI;
uint8_t keycode[6] = { 0 };
keycode[0] = HID_KEY_L;
usb_hid.keyboardReport(report_id, modifier, keycode);
delay(10);
// Un-press keys :)
usb_hid.keyboardRelease(0);
}
// poll gpio once each 2 ms
delay(20);
// used to avoid send multiple consecutive zero report for keyboard
static bool keyPressedPreviously = false;
uint8_t count=0;
uint8_t keycode[6] = { 0 };
// scan normal key and send report
for(uint8_t i=0; i < pincount; i++)
{
if ( activeState == digitalRead(pins[i]) )
{
// if pin is active (low), add its hid code to key report
keycode[count++] = hidcode[i];
// 6 is max keycode per report
if (count == 6) break;
}
}
if ( TinyUSBDevice.suspended() && count )
{
// Wake up host if we are in suspend mode
// and REMOTE_WAKEUP feature is enabled by host
TinyUSBDevice.remoteWakeup();
}
// skip if hid is not ready e.g still transferring previous report
if ( !usb_hid.ready() ) return;
if ( count )
{
// Send report if there is key pressed
uint8_t const report_id = 0;
uint8_t const modifier = 0;
keyPressedPreviously = true;
usb_hid.keyboardReport(report_id, modifier, keycode);
}else
{
// Send All-zero report to indicate there is no keys pressed
// Most of the time, it is, though we don't need to send zero report
// every loop(), only a key is pressed in previous loop()
if ( keyPressedPreviously )
{
keyPressedPreviously = false;
usb_hid.keyboardRelease(0);
}
}
}
// Output report callback for LED indicator such as Caplocks
void hid_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
{
(void) report_id;
(void) bufsize;
}
The HuskyLens is an easy-to-use AI machine vision sensor. It is equipped with multiple functions such as:
Face recognition
Object tracking
Object recognition
Line trace
Color recognition
Tag recognition (QR code).
Via the UART / I2C port you can among others: boards connect:
Arduino
micro:bit
Raspberry Pi
Steps to take: Press Face detection, when a cross in a square is displayed, press the button on your HuskyLens
Set your husky protocol to I2C in the settings.
Minimal Code needed
/***************************************************
HUSKYLENS An Easy-to-use AI Machine Vision Sensor
<https://www.dfrobot.com/product-1922.html>
****************************************************/
#include "HUSKYLENS.h"
HUSKYLENS huskylens;
//HUSKYLENS green line >> SDA; blue line >> SCL
int ID0 = 0; //not learned results. Grey result on HUSKYLENS screen
int ID1 = 1; //first learned results. colored result on HUSKYLENS screen
int ID2 = 2; //second learned results. colored result on HUSKYLENS screen
// and so on.....
int arjprevious = 0;
void printResult(HUSKYLENSResult result);
void setup() {
Serial.begin(115200);
Wire.begin();
while (!huskylens.begin(Wire))
{
Serial.println(F("Begin failed!"));
Serial.println(F("1.Please recheck the \"Protocol Type\" in HUSKYLENS (General Settings>>Protocol Type>>I2C)"));
Serial.println(F("2.Please recheck the connection."));
delay(100);
}
huskylens.writeAlgorithm(ALGORITHM_FACE_RECOGNITION);
}
void loop() {
if (huskylens.requestLearned()) //request blocks and arrows tangged ID != 0 from HUSKYLENS
if (huskylens.requestBlocksLearned()) //request blocks tangged ID != ID0 from HUSKYLENS
{
for (int i = 0; i < huskylens.countArrows(ID0); i++)
{
HUSKYLENSResult result = huskylens.getArrow(ID0, i);
}
int arj = huskylens.count(ID1);
if ( arj != arjprevious )
{
if ( arj == 1 )
{
Serial.println("Learned face detected");
}
else
{
Serial.println("Learned face not detected");
}
arjprevious = arj;
}
}
else
{
Serial.println("Fail to request objects from Huskylens!");
}
}
Learned face detected ID1
Learned face not detected
Learned face detected ID1
Learned face not detected
Learned face detected ID1
Learned face not detected
"If something is worth doing, it's worth overdoing."