Shouting Rock

0 35380 Medium

Hacked artificial outdoor Shouting Rock, controlled by Home Assistant MQTT automation.

 

Shouting Rock

Things used in this project

 

Hardware components

HARDWARE LIST
DFRobot DFPlayer - A Mini MP3 Player
Artificial Rock + 10W speaker
15cm x 15cm x 3mm Plywood For Small Speaker Holder
Adafruit 4W 4OHM Speaker
Adafruit USB Type A to Type C Cable - approx 1 meter / 3 ft long
Seeed Studio XIAO_ESP32C3

Software apps and online services

 

Arduino IDE

 

Onshape

 

Lightburn

 

Hand tools and fabrication machines

 

Ortur Laser Master 3

Story

 

Intro and Inspiration

 

In the prophecy of Chavakuk (Habakkuk) Chapter 2 verse 11, it is written:

 

“For a stone shall cry from the wall, and a chip shall answer it from a beam.”

 

This prophecy depicts the state of physical matter during the time of redemption, as also prophesied by Isaiah in Chapter 40 verse 5:

 

"And the glory of the Lord shall be revealed, and all flesh together shall see that the mouth of the Lord spoke."

 

As explained in Chabad Legacy, these prophecies indicate that the revelation of the Almighty will be revealed in both the earth and the flesh. The arrival of the Messiah and the revelation of the reality of the Almighty is the purpose and focus of this time.

 

Inspired by these verses, I created the "A stone from a wall that calls out" representation. I used a hollow artificial rock from Amazon (My focus was not Stone crafting) as the main material and replaced the 10W speaker with a smaller Adafruit 3W speaker connected to a Seeed Studio XIAO ESP32C3 processor and a DFRobot DFPlayer mini audio controller. The Amazon Ring bell detects when I approach the front door, and the Home Assistant smart home system triggers via MQTT the play of the verse "For a stone shall cry out from the wall..." only during the hours between 8am and 8pm, excluding Saturdays and holidays.

 

This representation makes me feel as if I am living in redemption, even for just a moment. May we all soon attain true and complete redemption in our lifetimes.

 

 

Demo

 

Video Link (The verse saying in Hebrew)

 

System Drawing

 

 

 

 

Rock Speaker Hacking

 

As previously mentioned, my focus was on the electronics and software aspect of the project. For this reason, I purchased a premade stone from Amazon (*). The only challenge was that the stone came with a 10W speaker, which was too powerful and not suitable for the project.

 

The artificial shallow Rock I purchased

 

The artificial shallow Rock I purchased

 

Instead, I used an Adafruit 3W speaker (*) which had a smaller diameter. To accommodate this, I designed a 3mm MDF adapter (**).

 

* details in the components section above.

 

** See DXF file of the design in the components section above.

 

Small Speaker Adaptor

 

Small Speaker Adaptor

 

Laser cutting of the Adaptor

 

Laser cutting of the Adaptor

 

Small Speaker located on the Adaptor

 

Small Speaker located on the Adaptor

 

Fixed into the Rock

 

Fixed into the Rock

 

Electronics before Assembly

 

Electronics before Assembly

 

Speaker with the electronics

 

Speaker with the electronics

 

Bottom sealing

 

Bottom sealing

 

 

 

HomeAsistant Setup

 

There's not much to say here. It's quite straightforward. I simply ensure that the automation does not run late at night or during holidays. The integration of the Jewish calendar is particularly helpful for this purpose. The front door motion sensor is part of the Amazon ring integration.

 

Automation Flow

 

Automation Flow

 

 

 

Power Source

 

Currently, I am using a simple USB battery pack for power. However, I have a small solar panel and lithium battery set equipped with a 3.x to 5V buck converter that I plan to integrate into the project in the future. Something like this.

 

 

 

Final Thoughts

 

One might question the combination of spirituality and technology, but that's simply who I am. I am eager to connect, share, and discuss with others who share similar perspectives.


 

Custom parts and enclosures

 

Speaker Holder

Adaptor to small speaker dxf file

icon speakerholder_f1CFaA1AFD.zip 13KB Download(0)

Speaker Holder Drawing

 

Schematics

 

Shouting Rock Speaker

 

Shouting Rock Speaker schematics

Shouting Rock Wiring

 

Shouting Rock Fritzing Breadboard Wiring

 

 

Shouting Rock Schematics

 

Shouting Rock Fritzing Schematics

 

Code

 

Shouting Rock Arduino Sketch

C/C++

Arduino ino file

CODE
/***************************************************
DFPlayer - A Mini MP3 Player For Arduino
 <https://www.dfrobot.com/index.php?route=product/product&product_id=1121>

 ***************************************************
 This example is based on the function of library for DFPlayer by 
 [Angelo qiao](Angelo.qiao@dfrobot.com)

 GNU Lesser General Public License.
 See <http://www.gnu.org/licenses></http:> for details.
 All above must be included in any redistribution
 ****************************************************/

#include "Arduino.h"
#include <HardwareSerial.h>
#include "DFRobotDFPlayerMini.h"
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include "WiFi.h"

#define MQTT_SERVER      "a.b.c.d"
#define MQTT_SERVERPORT  1883
#define MQTT_USERNAME    "XXXXX"
#define MQTT_KEY         "YYYYY"

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client *mqtt; 

const char* wifi_ssid     = "SSID";
const char* wifi_password = "PASS";

/****************************** Feeds ***************************************/
// Setup a feed called 'gps' for subscribing to changes.
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
Adafruit_MQTT_Subscribe *body;
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;

//Define two Serial devices mapped to the two internal UARTs
HardwareSerial MySerial0(0);
DFRobotDFPlayerMini myDFPlayer;
char last_str[64]="";

void printDetail(uint8_t type, int value);

void setup()
{
  // Configure MySerial0 on pins TX=6 and RX=7 (-1, -1 means use the default)
  MySerial0.begin(9600, SERIAL_8N1, -1, -1);  
  Serial.begin(115200);

  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

  WiFi.begin(wifi_ssid, wifi_password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }


  mqtt = new Adafruit_MQTT_Client (&client, MQTT_SERVER, MQTT_SERVERPORT, MQTT_USERNAME, MQTT_USERNAME, MQTT_KEY); 
  body = new Adafruit_MQTT_Subscribe(mqtt, "/speaking_stone/");
  
  // listen for events on the weather feed
  mqtt->subscribe(body);

  // connect to MQTT server
  mqtt_connect();

 
  if (!myDFPlayer.begin(MySerial0)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true);
  }
  Serial.println(F("DFPlayer Mini online."));


  myDFPlayer.volume(20);  //Set volume value. From 0 to 30
}

void loop()
{
  Adafruit_MQTT_Subscribe *subscription;
  
  
  // ping adafruit io a few times to make sure we remain connected
  // Serial.println("Ping");
  if(! mqtt->ping(3)) 
  {
     // reconnect to adafruit io
     Serial.println("Reconnect");
     if(! mqtt->connected())
     {
       Serial.println("Connect");
       mqtt_connect();
     }
  }
  
  if (subscription = mqtt->readSubscription(1000)) 
  {
      Serial.print(F("GotSomething\n"));
      // we only care about the 
      if (subscription == body) 
      {
        char * orig_str  = (char*)body->lastread;
        myDFPlayer.play(1);
        if (myDFPlayer.available()) 
        {
           printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
        }

        Serial.println(orig_str);
      }  
  }
}


// connect to adafruit io via MQTT
void mqtt_connect() {

  int8_t ret;

  while ((ret = mqtt->connect()) != 0) {

    switch (ret) {
      case 1: Serial.println(F("Wrong protocol")); break;
      case 2: Serial.println(F("ID rejected")); break;
      case 3: Serial.println(F("Server unavail")); break;
      case 4: Serial.println(F("Bad user/pass")); break;
      case 5: Serial.println(F("Not authed")); break;
      case 6: Serial.println(F("Failed to subscribe")); break;
      default: Serial.println(F("Connection failed")); break;
    }

    if(ret >= 0)
      mqtt->disconnect();

    Serial.println(F("Retrying connection..."));
    delay(5000);

  }

  Serial.println(F("mqtt Connected!"));
}


void printDetail(uint8_t type, int value){
  switch (type) {
    case TimeOut:
      Serial.println(F("Time Out!"));
      break;
    case WrongStack:
      Serial.println(F("Stack Wrong!"));
      break;
    case DFPlayerCardInserted:
      Serial.println(F("Card Inserted!"));
      break;
    case DFPlayerCardRemoved:
      Serial.println(F("Card Removed!"));
      break;
    case DFPlayerCardOnline:
      Serial.println(F("Card Online!"));
      break;
    case DFPlayerPlayFinished:
      Serial.print(F("Number:"));
      Serial.print(value);
      Serial.println(F(" Play Finished!"));
      break;
    case DFPlayerError:
      Serial.print(F("DFPlayerError:"));
      switch (value) {
        case Busy:
          Serial.println(F("Card not found"));
          break;
        case Sleeping:
          Serial.println(F("Sleeping"));
          break;
        case SerialWrongStack:
          Serial.println(F("Get Wrong Stack"));
          break;
        case CheckSumNotMatch:
          Serial.println(F("Check Sum Not Match"));
          break;
        case FileIndexOut:
          Serial.println(F("File Index Out of Bound"));
          break;
        case FileMismatch:
          Serial.println(F("Cannot Find File"));
          break;
        case Advertise:
          Serial.println(F("In Advertise"));
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }
}

Home Assistant Automation

YAML

Home Assistant Automation YAML file

CODE
alias: speaking_stone
description: ""
trigger:
  - type: motion
    platform: device
    device_id: 9991aecc03c14973b05c8e881b0e574f
    entity_id: binary_sensor.front_door_motion
    domain: binary_sensor
    for:
      hours: 0
      minutes: 0
      seconds: 0
condition:
  - condition: state
    entity_id: binary_sensor.jewish_calendar_issur_melacha_in_effect
    state: "off"
  - condition: time
    before: "20:00:00"
    after: "08:00:00"
action:
  - service: mqtt.publish
    data:
      topic: /speaking_stone/
      qos: "0"
      payload: play
      retain: false
mode: single

The article was first published in hackster, February 6,  2023

cr: https://www.hackster.io/asafmatan/shouting-rock-61d014

author: Asaf Matan

License
All Rights
Reserved
licensBg
0