LDR vs Audio for talking skull w/ google mini


I'm trying to make a 3d printed, talking skull with a google home mini that only moves (talks) with the google voice.

I am currently using an LDR to detect the lights on top, so when I ask a question it talks to me with the answer. But, if I ask it to play music it wont keep its jaw moving.

With the LDR I have determined:

  • The initial prompt of "hey google" always gives the highest reading. Stays high until I stop talking
  • Once I stop talking, and the answer starts, the light blinks off, then comes on at a dimmer level (20-90. tested, every time its dimmer)
  • when it stops talking the lights go off.
  • if asked to play music the LEDs stop when the music starts

So, ideally, when the LDR value is in the dimmer range a servo moves sporadically. I wont be mapping the jaw to peaks in the speech.

The trouble I have is getting it to ignore the initial change from 0>106 for "Hey Google", and to only engage the servo when the light stays in the "dim range"

  • I have added a delay to stop initial movement but it is very clunky for longer or shorter responses. and not really what I would like to achieve.
  • If it were a button press I would need to ignore a short press. But cannot find info on how to achieve this with an LDR. A "lockout for relay project" got me close, but not quite over the line, but that may be due to my novice skills

I have tried to research come options and have really only been able to find information using a HIGH/LOW state for LDR readings.

I am aware of PicoTalks, and talking skulls kits and wanted to avoided using the audio signal as I don't want it to "sing" to music if that is prompted. I will happily change to that direction. and try to incorporate a timer or trigger to have it stop after google talks if the light option is unfeasible

Rough circuit diagram attached.
-10k resistor
-Micro Servo SG90
-LDR from kit


#include <Servo.h>

int photoresistor = 0;
Servo servo_9;

void setup()
  pinMode(A0, INPUT);
  servo_9.attach(9, 500, 2500);

void loop()
  if (analogRead(A0) <= 10) { //For LED off
  } else {
    if (55 <= analogRead(A0) && analogRead(A0) <= 95) {  //this is the attempt to only trigger dimmer values.
      delay(2500); //delay to stop movement on initial talking
      servo_9.write(0);  // Turn Servo Left to 0 degrees
      delay(100);          // Pause
      servo_9.write(41);   // Turn Servo Left to 35 degrees
      delay(185);          // Pause
      servo_9.write(0);  // Turn Servo back to 0 degrees
      delay(200);          // Pause
      servo_9.write(40); // Turn Servo Right to 40 degrees
      delay(150);          // Pause
      servo_9.write(0); // Turn Servo Right to 0 degrees
      delay(100);          // Pause
    if (analogRead(A0) >= 96) {
  delay(50); // Delay a little bit to improve simulation performance

With the delay to block the initial, its really not responding when the lights change for the voice but just delayed from when I wake it up.

If more information is needed I can happily provide. I have limited skills in this area but enthusiastic to learn

Still very much in the proof of concept stage as print time is >1 day so I wont commit until I can be sure the circuitry works.
The circuitry will sit inside the skull and be blocked off to varying external light

Connect the LDR between the pin and ground. The internal pullup (pinMode of INPUT_PULLUP) is likely to suffice to bias it, or you could add another pullup if you require a lower value.

What are you using as a regulated 5 V power supply for the Arduino and the servo?

I am now reading in to pullup and seems a great avenue to try. thank you!

at the moment the power for the servo is just off the UNO for the testing phase
I am still looking in to power sourcing for it. the "jaw" will be around 200grams without paint. any ideas are appreciated

I don't particularly wont to deal with batteries as the google mini will be always connected to power

at the moment the power for the servo is just off the UNO for the testing phase

The UNO is not a power supply. The “barrel jack” and “Vin” are essentially useless for any meaningful current requirement beyond 100 mA and a servo generally requires anything up to an Amp which clearly exceeds the 500 mA rating of the “polyfuse” which is in series with the USB port.

Unless you have a proper 5 V power supply - a USB “Phone Charger” rated at least an Amp is usually practical - to connect directly to the servo and to the “5V” pin on the Arduino, you are most likely to experience all sorts of misbehaviour, so until you have the power supply sorted, you can’t complain about anything. :roll_eyes:

However while you have the USB port connected to a PC, do not connect the “5V” pin to another power supply.

Connect the LDR between the pin and ground. The internal pullup (pinMode of INPUT_PULLUP) is likely to suffice to bias it, or you could add another pullup if you require a lower value.

I have removed the servo and tested values with PULLUP method and getting worse results.
I have only used a basic "display values code". (For testing purposes I've scrapped the servo until I get the power supply sorted)
I get a more instantaneous difference for the initial light change however when the light dims there is no change in values. The values read 840 while dark and then goes to 715 when the light is on but only goes back to 840 when it is off. No varying results for the "dimmer" section

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.