R2D2 Awesome Bruh multisensor

It is with great pleasure that i can finally share this project with you!

When I first started with home assistant I knew nothing about electronics automations or any of this stuff. I followed tutorials and did what I could following Bruh at first until he mysteriously disappeared… if you’re out there Bruh hope you’re well… Then Dr.Zzs, digiblur etc…

Learning from all them, came in handy when I injured myself, pushing me to buy a bunch of sensors and gizmos and put together my version of the Bruh multisensor… but way cooler :wink:

So I thought i’d share back too.

I give you Artoo:

I bought a Die cast R2D2 and gutted it with a dremmel.

I took out all the unnecessary metal, but leaving enough to attach a servo with some glue.
it was tedious but it came out great.

In the dome i added a bunch of tiny leds in such a way that the little probes that stick out are functional.
I also added some RGB leds.

There’s a bunch of sensors: a BME 280, an mpu6050, a resistive light sensor on the top of his head, a capacative touch pad on the front (some copper I smashed soldered to a wire poked through the body), a DF player and the SD card , loaded with R2D2 sound effects and Star wars sounds & songs, is accessible from behind without having to open up the body, a PIR sensor that I placed in the dome in the same spot where there is a lens like indentation (i used a black PIR cover cut to fit), and last but not least a SERVO to move his head!!! (it took me a year to figure that one out… so many issues lol but now you can make one!)
There’s also a micro usb female jack embedded in the back, so that you can power him and flash him using a usb cable; I think you can also get tracks to play from usb but i haven’t tried that yet.

All this powered by a Tinypico ( i tried several boards this was the winner)

I have a tiny battery since there’s a BMS and monitoring pins on the pico, I pulled from a vape device that i’m still trying to figure out, not sure if it’'l make the cut… we’ll see…

I built this with esphome:
Still working on the automations and stuff, but since I finally got it all to work properly -and all the features lol (still testing the battery pins tho), well… here it is!
Enjoy!

substitutions:
  hostname: 'Artoo'
esphome:
  name: artoo
  platform: ESP32
  board: tinypico

wifi:
  ssid: "XXX"
  password: "XXX"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "$hostname Fallback Hotspot"
    password: "XXX"

captive_portal:

# Enable logging
#logger:
#  hardware_uart: UART1
#  level: error
# Enable Home Assistant API
api:
  password: "XXX"
#  services:
#    - service: control_servo
#      variables:
#        level: float
#      then:
#        - servo.write:
#            id: my_servo
#            level: !lambda 'return level / 100.0;'

ota:
  password: "XXX"

web_server:

# Example configuration entry
switch:
  - platform: restart
    name: "Restart $hostname"

light:
  - platform: monochromatic
    output: Artoo_cerveau
    name: "Cerveau - Pos"
    default_transition_length: 0ms

  - platform: monochromatic
    output: Artoo_front_lamp
    name: $hostname front lamp
    default_transition_length: 0ms

  - platform: monochromatic
    output: Artoo_rear_lamp
    name: $hostname rear lamp
    default_transition_length: 0ms

  - platform: rgb
    name: $hostname's dome
    red: Artoo_dome_r2
    green: Artoo_dome_g2
    blue: Artoo_dome_b2

  - platform: rgb
    name: $hostname's Back
    red: Artoo_back_r1
    green: Artoo_back_g1
    blue: Artoo_back_b1

  - platform: fastled_spi
    chipset: APA102
    data_pin: GPIO02
    clock_pin: GPIO12
    num_leds: 1
    rgb_order: BGR
    name: "$hostname led"
    effects:
#      - addressable_random_twinkle:
      - addressable_random_twinkle:
          name: Random Twinkle
          twinkle_probability: 5%
          progress_interval: 32ms
#      - addressable_rainbow:
      - addressable_rainbow:
          name: Rainbow
          speed: 10
          width: 50
#      - strobe:
      - strobe:
          name: Strobe
          colors:
            - state: True
              brightness: 50%
              red: 50%
              green: 50%
              blue: 0%
              duration: 500ms
            - state: False
              duration: 250ms
            - state: True
              brightness: 100%
              red: 0%
              green: 100%
              blue: 0%
              duration: 500ms
#      - flicker:
      - flicker:
          name: Flicker
          alpha: 95%
          intensity: 1.5%
#      - addressable_color_wipe:
      - addressable_color_wipe:
          name: Color Wipe
          colors:
            - red: 100%
              green: 100%
              blue: 100%
              num_leds: 1
            - red: 0%
              green: 0%
              blue: 0%
              num_leds: 1
          add_led_interval: 100ms
          reverse: False
#      - addressable_scan:
      - addressable_scan:
          name: Scan Effect
          move_interval: 100ms
          scan_width: 10
#      - addressable_fireworks:
      - addressable_fireworks:
          name: Fireworks
          update_interval: 32ms
          spark_probability: 10%
          use_random_color: false
          fade_out_rate: 120
#      - random:
      - random:
          name: Random
          transition_length: 5s
          update_interval: 7s

# Example output platform
#servo:
#  - id: my_servo
#    output: Artoo_cerveau

# On ESP32, use ledc output
output:
  - platform: ledc
    pin: GPIO25
    id: Artoo_cerveau
    frequency: 50 Hz
    min_power: 5%    # 5% at 50Hz is 1mS  (20mS cycles)
    max_power: 10%   # 10% at 50Hz is 2mS (20mS cycles)
    channel: 1

  - platform: ledc
    pin: GPIO26
    id: Artoo_rear_lamp
    channel: 3

  - platform: ledc
    pin: GPIO27
    id: Artoo_front_lamp
    channel: 4

  - platform: ledc
    pin: GPIO15
    id: Artoo_dome_r2
    channel: 5

  - platform: ledc
    pin: GPIO14
    id: Artoo_dome_g2
    channel: 6

  - platform: ledc
#    pin: GPIO21
    pin: GPIO04
    id: Artoo_dome_b2
    channel: 7

  - platform: ledc
    pin: GPIO18
    id: Artoo_back_r1
    channel: 8

  - platform: ledc
    pin: GPIO19
    id: Artoo_back_g1
    channel: 9

  - platform: ledc
    pin: GPIO05
    id: Artoo_back_b1
    channel: 10

i2c:
  sda: SDA
  scl: SCL
  scan: True

uart:
  tx_pin: TX
  rx_pin: RX
  baud_rate: 9600
  id: uart_2

dfplayer:
  on_finished_playback:
    then:
      - dfplayer.stop
#      logger.log: 'Somebody press play!'

esp32_touch:

binary_sensor:

  - platform: gpio
    pin: GPIO23
    name: "$hostname Motion"
    device_class: motion

  - platform: gpio
    pin: GPIO34
    name: "$hostname Change state"


  - platform: esp32_touch
    name: "$hostname touch"
    pin: GPIO33
    threshold: 1000
    on_press:
      then:
#        - dfplayer.play: 
        - dfplayer.random:
        - delay: 3s
        - dfplayer.stop
#            file: 1
#            loop: false
##        - output.turn_on: buzzer
##        - delay: 1ms
##        - output.turn_off: buzzer
##    on_release:
##      then:
##        - output.turn_off: buzzer

sensor:

  - platform: wifi_signal
    name: "$hostname WiFi"
    update_interval: 30s
    id: signal

  - platform: adc
    pin: GPIO32
    name: "$hostname Brightness"
    unit_of_measurement: lux
    filters:
      - lambda: |-
          return (x / 10000.0) * 2000000.0;

  - platform: adc
    pin: GPIO34
    name: Bat
    unit_of_measurement: "v"    

  - platform: bme280
    temperature:
      name: "$hostname ambient Temperature"
      id: artoo_temperature
      filters:
        - lambda: return (x * (9.0/5.0) + 32.0) -10;
      unit_of_measurement: "°F"
    pressure:
      name: "$hostname Pressure"
      id: artoo_pressure
    humidity:
      name: "$hostname Humidity"
      id: artoo_humidity
      filters:
        - lambda: return x +10;
    address: 0x76
    update_interval: 30s
  - platform: mpu6050
    update_interval: 10s
    address: 0x68
    accel_x:
      name: "cerveau Accel X"
    accel_y:
      name: "cerveau Accel Y"
    accel_z:
      name: "cerveau Accel z"
    gyro_x:
      name: "cerveau Gyro X"
    gyro_y:
      name: "cerveau Gyro Y"
    gyro_z:
      name: "cerveau Gyro z"
    temperature:
      name: "$hostname head Temperature"

As a note, Logger seems to have to be turned off otherwise no-go. I’ve tried many configurations even without the DF player, and it won’t work with logger (but who cares now that i got it to work!!!)

Also, i recommend creating some sort of disconnect on the TX and RX lines connecting to the DF player so that when you flash the Firmware the DF player doesn’t interfere. reconnect after flash, and then subsequent flashes can be done OTA.

Let me know if you’s like to know more and i’m happy to share.
Also happy to try out some automations if you’ve got em!!!

11 Likes

Update:

ok so the battery feature does work ( i had the wrong pin definition), but my recalimed vape battery might be dead ( a differnt battery did work, but too big to fit).

I’ll keep looking for a battery…

in the meantime here is the corrected code:

substitutions:
  hostname: 'Artoo'
esphome:
  name: artoo
  platform: ESP32
  board: tinypico

wifi:
  ssid: "xxx"
  password: "xxx"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "$hostname Fallback Hotspot"
    password: "xxx"

captive_portal:

# Enable logging
#logger:
#  hardware_uart: UART1
#  level: error
# Enable Home Assistant API
api:
  password: "xxx"
#  services:
#    - service: control_servo
#      variables:
#        level: float
#      then:
#        - servo.write:
#            id: my_servo
#            level: !lambda 'return level / 100.0;'

ota:
  password: "xxx"

web_server:

# Example configuration entry
switch:
  - platform: restart
    name: "Restart $hostname"

light:
  - platform: monochromatic
    output: Artoo_cerveau
    name: "Cerveau - Pos"
    default_transition_length: 0ms

  - platform: monochromatic
    output: Artoo_front_lamp
    name: $hostname front lamp
    default_transition_length: 0ms

  - platform: monochromatic
    output: Artoo_rear_lamp
    name: $hostname rear lamp
    default_transition_length: 0ms

  - platform: rgb
    name: $hostname's dome
    red: Artoo_dome_r2
    green: Artoo_dome_g2
    blue: Artoo_dome_b2

  - platform: rgb
    name: $hostname's Back
    red: Artoo_back_r1
    green: Artoo_back_g1
    blue: Artoo_back_b1

  - platform: fastled_spi
    chipset: APA102
    data_pin: GPIO02
    clock_pin: GPIO12
    num_leds: 1
    rgb_order: BGR
    name: "$hostname led"
    effects:
#      - addressable_random_twinkle:
      - addressable_random_twinkle:
          name: Random Twinkle
          twinkle_probability: 5%
          progress_interval: 32ms
#      - addressable_rainbow:
      - addressable_rainbow:
          name: Rainbow
          speed: 10
          width: 50
#      - strobe:
      - strobe:
          name: Strobe
          colors:
            - state: True
              brightness: 50%
              red: 50%
              green: 50%
              blue: 0%
              duration: 500ms
            - state: False
              duration: 250ms
            - state: True
              brightness: 100%
              red: 0%
              green: 100%
              blue: 0%
              duration: 500ms
#      - flicker:
      - flicker:
          name: Flicker
          alpha: 95%
          intensity: 1.5%
#      - addressable_color_wipe:
      - addressable_color_wipe:
          name: Color Wipe
          colors:
            - red: 100%
              green: 100%
              blue: 100%
              num_leds: 1
            - red: 0%
              green: 0%
              blue: 0%
              num_leds: 1
          add_led_interval: 100ms
          reverse: False
#      - addressable_scan:
      - addressable_scan:
          name: Scan Effect
          move_interval: 100ms
          scan_width: 10
#      - addressable_fireworks:
      - addressable_fireworks:
          name: Fireworks
          update_interval: 32ms
          spark_probability: 10%
          use_random_color: false
          fade_out_rate: 120
#      - random:
      - random:
          name: Random
          transition_length: 5s
          update_interval: 7s

# Example output platform
#servo:
#  - id: my_servo
#    output: Artoo_cerveau

# On ESP32, use ledc output
output:
  - platform: ledc
    pin: GPIO25
    id: Artoo_cerveau
    frequency: 50 Hz
    min_power: 5%    # 5% at 50Hz is 1mS  (20mS cycles)
    max_power: 10%   # 10% at 50Hz is 2mS (20mS cycles)
    channel: 1

  - platform: ledc
    pin: GPIO26
    id: Artoo_rear_lamp
    channel: 3

  - platform: ledc
    pin: GPIO27
    id: Artoo_front_lamp
    channel: 4

  - platform: ledc
    pin: GPIO15
    id: Artoo_dome_r2
    channel: 5

  - platform: ledc
    pin: GPIO14
    id: Artoo_dome_g2
    channel: 6

  - platform: ledc
#    pin: GPIO21
    pin: GPIO04
    id: Artoo_dome_b2
    channel: 7

  - platform: ledc
    pin: GPIO18
    id: Artoo_back_r1
    channel: 8

  - platform: ledc
    pin: GPIO19
    id: Artoo_back_g1
    channel: 9

  - platform: ledc
    pin: GPIO05
    id: Artoo_back_b1
    channel: 10

i2c:
  sda: SDA
  scl: SCL
  scan: True

uart:
  tx_pin: TX
  rx_pin: RX
  baud_rate: 9600
  id: uart_2

dfplayer:
  on_finished_playback:
    then:
      - dfplayer.stop
#      logger.log: 'Somebody press play!'

esp32_touch:

binary_sensor:

  - platform: gpio
    pin: GPIO23
    name: "$hostname Motion"
    device_class: motion

  - platform: gpio
    pin: GPIO34
    name: "$hostname Charge state"


  - platform: esp32_touch
    name: "$hostname touch"
    pin: GPIO33
    threshold: 1000
    on_press:
      then:
#        - dfplayer.play: 
        - dfplayer.random:
        - delay: 3s
        - dfplayer.stop
#            file: 1
#            loop: false
##        - output.turn_on: buzzer
##        - delay: 1ms
##        - output.turn_off: buzzer
##    on_release:
##      then:
##        - output.turn_off: buzzer

sensor:

  - platform: wifi_signal
    name: "$hostname WiFi"
    update_interval: 30s
    id: signal

  - platform: adc
    pin: GPIO32
    name: "$hostname Brightness"
    unit_of_measurement: lux
    filters:
      - lambda: |-
          return (x / 10000.0) * 2000000.0;

  - platform: adc
    pin: GPIO35
    name: Bat
    unit_of_measurement: "v"    

  - platform: bme280
    temperature:
      name: "$hostname ambient Temperature"
      id: artoo_temperature
      filters:
        - lambda: return (x * (9.0/5.0) + 32.0) -10;
      unit_of_measurement: "°F"
    pressure:
      name: "$hostname Pressure"
      id: artoo_pressure
    humidity:
      name: "$hostname Humidity"
      id: artoo_humidity
      filters:
        - lambda: return x +10;
    address: 0x76
    update_interval: 30s
  - platform: mpu6050
    update_interval: 10s
    address: 0x68
    accel_x:
      name: "cerveau Accel X"
    accel_y:
      name: "cerveau Accel Y"
    accel_z:
      name: "cerveau Accel z"
    gyro_x:
      name: "cerveau Gyro X"
    gyro_y:
      name: "cerveau Gyro Y"
    gyro_z:
      name: "cerveau Gyro z"
    temperature:
      name: "$hostname head Temperature"


…cus how cool would it be to have it battery powered… even if only for a half hour or so :slight_smile:

So turns out my harvested vape batteries are not dead. I’m wondering if the batteries are just too small to power it… that or perhaps because there are 5v components, the battery simply doesn’t work… …or I have no idea what i’m doing :smiley:

Let me know if you have any ideas!

Edit:
reading the docs: https://www.tinypico.com/ looks like the 5v components might be the culprit. I’ll see what i can do (maybe add a TPS61023 or something…)

Looks fantastic. Does metal cause any problems to the wifi signal or heat up the bme280?

Wifi is a bit attenuated but this isn’t too much of a concern for me because he’ll be indoors in a wifi rich environment, but the metal certainly does affect the wifi.
As far as the bme280… I thought of that so I actually placed it in the front “foot” which is down low in relation to the rest of the electronics it is also made of plastic, there’s a tiny hole on the underside to expose the sensor to the ambient air so it should be fairly accurate.

As a side note, I wanted a good temperature sensor so i added the bme280, however there is a temperature sensor in the mpu6050 so if you wanted to omit this sensor for a different one this would free up some room; the bme gives you humidity and pressure tho too if you need that…

Edit:
Ah!
I see I have a leftover lambda from a copy pasta which does a -10 degees, and -10 humidity on the bme.
Good catch.
I’ll remove that. …was wondering why that was!

Also, if anyone knows how to get the DF player to play just one track and then stop that would be super helpful!
Right now I have to delay for a set time, then stop otherwise it will keep playing the entire contents of the SD card (which i’ve jam packed with star wars sounds and songs, so it’ll keep going forever lol).

The idea is to have him scream “woooooooah” when you pick him up (sensing movement via MPU), make “beep boop beep” sounds when you touch the capacitive pad, and more sounds when motion is detected etc…

Thanks in advance!

It’s been a long time since I used the DF-player.
But doesn’t it have a “resistive” way of playing also?
Where you connect ground via a resistor and it plays a file?
I believe that only plays one file, but i could be wrong

Maybe… the pins however are caked up in glue to avoid contacts, and buried in his body -i don’t think the pins are accessible to me anymore…
Surely there’s gotta be a way to play one track randomly then stop; perhaps using lambdas or scripts?
It works well if I set it to play a specific track:

  - platform: gpio
    pin: GPIO23
    name: "$hostname Motion"
    device_class: motion
    on_press:
      then:
        - dfplayer.play: 1

But I would really like to use random to give hime a bit more “life” so it’s not the same track every time.
Thanks in advance!

But if that works, can’t you use lambda to get a random file?
I’m not very good with lambda but that should be possible.
Try and ask a question in the ESPHom section.

Probably. The limitation is this user’s understanding hence the posting :smiley:
I’ve brought him as far as I know how, so I’m hoping a kind stranger like yourself or a more knowledgeable individual might help me write a lambda to accomplish this…
Still trying things our tho :wink:

Posted:

Update on the battery:

Still tweaking some stuff, but here is another updated esphome yaml:

substitutions:
  hostname: 'Artoo'
esphome:
  name: artoo
  platform: ESP32
  board: tinypico

wifi:
  ssid: "xxx"
  password: "xxx"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "$hostname Fallback Hotspot"
    password: "xxx"

captive_portal:

# Enable logging
#logger:
#  hardware_uart: UART1
#  level: error
# Enable Home Assistant API
api:
  password: "xxx"
#  services:
#    - service: control_servo
#      variables:
#        level: float
#      then:
#        - servo.write:
#            id: my_servo
#            level: !lambda 'return level / 100.0;'

ota:
  password: "xxx"

web_server:

# Example configuration entry
switch:
  - platform: restart
    name: "Restart $hostname"

## APA102 shutoff via p-channel MOSFET via a high-side switch that can (along with smoother IO  settings) shut down the power to the APA102 https://www.tinypico.com/
#  - platform: gpio
#    pin: GPIO13
#.   inverted: true
#    mode: INPUT_PULLDOWN
#    name: "$hostname APA102 power"

light:
  - platform: monochromatic
    output: Artoo_cerveau
    name: "Cerveau - Pos"
    default_transition_length: 0ms

  - platform: monochromatic
    output: Artoo_front_lamp
    name: $hostname front lamp
    default_transition_length: 0ms
    effects:
      - random:
#      - random:
#          name: Random Effect With Custom Values
#          transition_length: 5s
#          update_interval: 7s
      - strobe:
#      - strobe:
#          name: Strobe Effect With Custom Values
#          colors:
#            - state: true
#              brightness: 100%
##              red: 100%
##              green: 90%
##              blue: 0%
#              duration: 500ms
#            - state: false
#              duration: 250ms
#            - state: true
#              brightness: 100%
##              red: 0%
##              green: 100%
##              blue: 0%
#              duration: 500ms      
      - flicker:
#      - flicker:
#          name: Flicker Effect With Custom Values
#          alpha: 95%
#          intensity: 1.5%

  - platform: monochromatic
    output: Artoo_rear_lamp
    name: $hostname rear lamp
    default_transition_length: 0ms
    effects:
      - random:
#      - random:
#          name: Random Effect With Custom Values
#          transition_length: 5s
#          update_interval: 7s
      - strobe:
#      - strobe:
#          name: Strobe Effect With Custom Values
#          colors:
#            - state: true
#              brightness: 100%
##              red: 100%
##              green: 90%
##              blue: 0%
#              duration: 500ms
#            - state: false
#              duration: 250ms
#            - state: true
#              brightness: 100%
##              red: 0%
##              green: 100%
##              blue: 0%
#              duration: 500ms      
      - flicker:
#      - flicker:
#          name: Flicker Effect With Custom Values
#          alpha: 95%
#          intensity: 1.5%

  - platform: rgb
    name: $hostname's dome
    red: Artoo_dome_r2
    green: Artoo_dome_g2
    blue: Artoo_dome_b2
    effects:
      - random:
#      - random:
#          name: Random Effect With Custom Values
#          transition_length: 5s
#          update_interval: 7s
      - strobe:
#      - strobe:
#          name: Strobe Effect With Custom Values
#          colors:
#            - state: true
#              brightness: 100%
#              red: 100%
#              green: 90%
#              blue: 0%
#              duration: 500ms
#            - state: false
#              duration: 250ms
#            - state: true
#              brightness: 100%
#              red: 0%
#              green: 100%
#              blue: 0%
#              duration: 500ms      
      - flicker:
#      - flicker:
#          name: Flicker Effect With Custom Values
#          alpha: 95%
#          intensity: 1.5%

  - platform: rgb
    name: $hostname's Back
    red: Artoo_back_r1
    green: Artoo_back_g1
    blue: Artoo_back_b1
    effects:
      - random:
#      - random:
#          name: Random Effect With Custom Values
#          transition_length: 5s
#          update_interval: 7s
      - strobe:
#      - strobe:
#          name: Strobe Effect With Custom Values
#          colors:
#            - state: true
#              brightness: 100%
#              red: 100%
#              green: 90%
#              blue: 0%
#              duration: 500ms
#            - state: false
#              duration: 250ms
#            - state: true
#              brightness: 100%
#              red: 0%
#              green: 100%
#              blue: 0%
#              duration: 500ms      
      - flicker:
#      - flicker:
#          name: Flicker Effect With Custom Values
#          alpha: 95%
#          intensity: 1.5%

  - platform: fastled_spi
    chipset: APA102
    data_pin: GPIO02
    clock_pin: GPIO12
    num_leds: 1
    rgb_order: BGR
    name: "$hostname led"
    effects:
#      - addressable_random_twinkle:
      - addressable_random_twinkle:
          name: Random Twinkle
          twinkle_probability: 5%
          progress_interval: 32ms
#      - addressable_rainbow:
      - addressable_rainbow:
          name: Rainbow
          speed: 10
          width: 50
#      - strobe:
      - strobe:
          name: Strobe
          colors:
            - state: True
              brightness: 50%
              red: 50%
              green: 50%
              blue: 0%
              duration: 500ms
            - state: False
              duration: 250ms
            - state: True
              brightness: 100%
              red: 0%
              green: 100%
              blue: 0%
              duration: 500ms
#      - flicker:
      - flicker:
          name: Flicker
          alpha: 95%
          intensity: 1.5%
#      - addressable_color_wipe:
      - addressable_color_wipe:
          name: Color Wipe
          colors:
            - red: 100%
              green: 100%
              blue: 100%
              num_leds: 1
            - red: 0%
              green: 0%
              blue: 0%
              num_leds: 1
          add_led_interval: 100ms
          reverse: False
#      - addressable_scan:
      - addressable_scan:
          name: Scan Effect
          move_interval: 100ms
          scan_width: 10
#      - addressable_fireworks:
      - addressable_fireworks:
          name: Fireworks
          update_interval: 32ms
          spark_probability: 10%
          use_random_color: false
          fade_out_rate: 120
#      - random:
      - random:
          name: Random
          transition_length: 5s
          update_interval: 7s

# Example output platform
#servo:
#  - id: my_servo
#    output: Artoo_cerveau

# On ESP32, use ledc output
output:
  - platform: ledc
    pin: GPIO25
    id: Artoo_cerveau
    frequency: 50 Hz
    min_power: 5%    # 5% at 50Hz is 1mS  (20mS cycles)
    max_power: 10%   # 10% at 50Hz is 2mS (20mS cycles)
    channel: 1

  - platform: ledc
    pin: GPIO26
    id: Artoo_rear_lamp
    channel: 3

  - platform: ledc
    pin: GPIO27
    id: Artoo_front_lamp
    channel: 4

  - platform: ledc
    pin: GPIO15
    id: Artoo_dome_r2
    channel: 5

  - platform: ledc
    pin: GPIO14
    id: Artoo_dome_g2
    channel: 6

  - platform: ledc
#    pin: GPIO21
    pin: GPIO04
    id: Artoo_dome_b2
    channel: 7

  - platform: ledc
    pin: GPIO18
    id: Artoo_back_r1
    channel: 8

  - platform: ledc
    pin: GPIO19
    id: Artoo_back_g1
    channel: 9

  - platform: ledc
    pin: GPIO05
    id: Artoo_back_b1
    channel: 10

i2c:
  sda: SDA
  scl: SCL
  scan: True

uart:
  tx_pin: TX
  rx_pin: RX
  baud_rate: 9600
  id: uart_2

dfplayer:
  on_finished_playback:
    then:
      - dfplayer.stop
#      logger.log: 'Somebody press play!'

esp32_touch:

binary_sensor:

  - platform: gpio
    pin: GPIO23
    name: "$hostname Motion"
    device_class: motion

  - platform: gpio
    pin: 
      number: GPIO34
      inverted: true
    name: "$hostname Charge state"
# matches the blink pattern on the device (charging LED) https://www.tinypico.com/ says to take multiple readings to avoid false positives.
# gonna need to study this more to figure it out.

  - platform: esp32_touch
    name: "$hostname touch"
    pin: GPIO33
    threshold: 1000
    on_press:
      then:
#        - dfplayer.play: 1
#            file: 1
#            loop: false
        - dfplayer.random:
# couldn't figure out how to set a random flicker effect yet so on/off dim as a test
        - output.set_level:
            id: Artoo_front_lamp
            level: "50%"
        - delay: 3s
        - output.set_level:
            id: Artoo_front_lamp
            level: "0%"
        - dfplayer.stop

##        - output.turn_on: buzzer
##        - delay: 1ms
##        - output.turn_off: buzzer
##    on_release:
##      then:
##        - output.turn_off: buzzer

sensor:

  - platform: wifi_signal
    name: "$hostname WiFi"
    update_interval: 30s
    id: signal

  - platform: adc
    pin: GPIO32
    name: "$hostname Brightness"
    unit_of_measurement: lux
    filters:
      - lambda: |-
          return (x / 10000.0) * 2000000.0;

  - platform: adc
    pin: GPIO35
    name: "$hostname Battery"
    unit_of_measurement: "v"    
    attenuation: 11db
    filters:
      - multiply: 4
      
  - platform: bme280
    temperature:
      name: "$hostname ambient Temperature"
      id: artoo_temperature
      filters:
        - lambda: return (x * (9.0/5.0) + 32.0) -10;
      unit_of_measurement: "°F"
    pressure:
      name: "$hostname Pressure"
      id: artoo_pressure
    humidity:
      name: "$hostname Humidity"
      id: artoo_humidity
      filters:
        - lambda: return x +10;
    address: 0x76
    update_interval: 30s
  - platform: mpu6050
    update_interval: 10s
    address: 0x68
    accel_x:
      name: "cerveau Accel X"
    accel_y:
      name: "cerveau Accel Y"
    accel_z:
      name: "cerveau Accel z"
    gyro_x:
      name: "cerveau Gyro X"
    gyro_y:
      name: "cerveau Gyro Y"
    gyro_z:
      name: "cerveau Gyro z"
    temperature:
      name: "$hostname head Temperature"

Added some effects, tweaked the battery readings, and testing out some automations.
He now lights up briefly while he speaks. Gonna need a ton of lambdas to give him some personality i think… the lights are really working well, better that i thought to be honest. The back light really gives him a bigger presence and sets a stage or mood for his environment. the little Dome lights are nice little accents. I’ll need to figure out how to make the little lamps (the hologram projectors) to flicker with more intensity… right now the flicker is hardly noticeable unless at a low setting and looking closely. Flicker works really well for the background.

cheers!

Well this is fun. There was a power outage today, while the power was out i fumbled around and touched Artoo… His speech lights came on (i am playing around with light patterns to animate when he plays a track or “speaks”). I instantly thought damnit he’s broken…
That’s when I realized he had broke free from the grid!
Artoo is now able to stay powered via the little battery I pulled out of a dead vape device!
It works!
The only thing is he cannot speak or move as those are 5v components and the 5v rail is disabled if no USB power is present. I can’t remember if any of the sensors are 5v ( i think the pir is 5v)… so he’s pretty crippled without the 5v but hey! It all works and he can still display quite a light show!

Also I’ve decided I want to build another one since I’m having so much fun here, so I’m considering changes for V2.
So far I’m thinking tinypico nano for more pins and smaller footprint.
And find a way to keep it all 3.3v or find a 5v solution so he can stay battery powered for a bit of time.

A servo with more travel, and thinner wires to allow the head to rotate more easily.

Microphone?

Let me know your thoughts.
Cheers!

Might be too ambitious but what about putting R2D2 in a bigger stand that could have an 18650 lithium battery with a battery shield in it to provide more battery storage and 5V rail.

Jabba's Tatooine Skiff

:thinking:

I did think of this as it would make some things easier like power management and such… But I really like the idea of him being standalone. This experiment has proven it is indeed possible with a bit of ingenuity, so i want to see if I can achieve this. I’m fairly certain I can.
Ideally if I could somehow get a PCB designed I could make much better use if the internal cavity.

That said where did your picture come from? Is that an actual star wars figurine or is it just an image to illustrate your idea? …it’s hard to envision the scale / proportions to see how Artoo would fit in there…

(Besides wouldn’t he be better suited to be in an X-wing :wink: )

Thanks for the ideas!

Jabba's Tatooine Skiff box

Saw it on Amazon.

There are other smaller stands that you could put him on and still pack something into the base. Imagination is the limit. :smiley:

Thanks!

Yeah I think if I go that route I’d likely choose an X-wing.
Remember R2D2 was the X-wing repair robot, while in battle he’d go out and fix damages.

I’ll shoot for standalone and if I can’t do that I’ll look into a bigger stand.

I’ll keep you posted :blush:
Thank you!

1 Like

…hmmm since the front foot is made if plastic, and if I could somehow make better use of his internal cavity perhaps with a custom PCB, I bet there’s a way to 3d print a foot to include a cavity to let the wifi antenna “peek” below the metal of the body for better signal.
Also, i think there could be room to fit a tiny motor in the “shoe” to make him actually move back and forth.
Something like this perhaps:

Or am I just going overboard with this thing lol :joy:

I must say it’s super rewarding…

Here’s a demo.
Not the best video, but should give an idea :slight_smile:

1 Like

Better video, new animations:

Enjoy!

And here’s a link the sound files I found scattered across the internet:
https://drive.google.com/drive/folders/1c1mFnGGIZGxq36oAhncoi2MWHf-rZ268?usp=sharing

Latest. with lots of comments :wink: :

substitutions:
  hostname: 'Artoo'
esphome:
  name: artoo
  platform: ESP32
  board: tinypico

wifi:
  ssid: "xxx"
  password: "xxx"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "$hostname Fallback Hotspot"
    password: "xxx"

captive_portal:

# Enable logging
#logger:
#  hardware_uart: UART1
#  level: error
# Enable Home Assistant API
api:
  password: "xxx"
#  services:
#    - service: control_servo
#      variables:
#        level: float
#      then:
#        - servo.write:
#            id: my_servo
#            level: !lambda 'return level / 100.0;'

ota:
  password: "xxx"

time:
  - platform: homeassistant
# for time based acttions. play a track if motion after one hour of inactivity?

web_server:
# to control him if wifi is down? (play tracks via web page, or maybe it's easier to trigger playback via home assistant)

esp32_ble_tracker:
# for presence tracking. play track based on presence after a period of absence (coupled with pir?)

# Example configuration entry
switch:
  - platform: restart
    name: "Restart $hostname"

## APA102 shutoff via p-channel MOSFET via a high-side switch that can (along with smoother IO  settings) shut down the power to the APA102 https://www.tinypico.com/
#  - platform: gpio
#    pin: GPIO13
#.   inverted: true
#    mode: INPUT_PULLDOWN
#    name: "$hostname APA102 power"

light:
  - platform: monochromatic
    output: Artoo_cerveau
    name: "Cerveau - Pos"
    id: Cerveau_pos
    default_transition_length: 0ms
    effects:
      - random:
#      - random:
#          name: Random Effect With Custom Values
#          transition_length: 5s
#          update_interval: 7s

#      - strobe:
#          name: Strobe Effect With Custom Values
#          colors:
#            - state: true
#              brightness: 100%
#              duration: 500ms
#            - state: false
#              duration: 250ms
#            - state: true
#              brightness: 100%
#              duration: 500ms      
# regular motion
      - flicker:
# panic mode
      - flicker:
          name: Flicker fast
          alpha: 95%
          intensity: 45%

  - platform: monochromatic
    output: Artoo_front_lamp
    name: $hostname front lamp
    id: R2_front_lamp
    default_transition_length: 0ms
    effects:
      - random:
      - random:
          name: Random fast
          transition_length: 5ms
          update_interval: 7ms
      - strobe:
#      - strobe:
#          name: Strobe Effect With Custom Values
#          colors:
#            - state: true
#              brightness: 100%
##              red: 100%
##              green: 90%
##              blue: 0%
#              duration: 500ms
#            - state: false
#              duration: 250ms
#            - state: true
#              brightness: 100%
##              red: 0%
##              green: 100%
##              blue: 0%
#              duration: 500ms      
      - flicker:
      - flicker:
          name: Flicker fast
          alpha: 95%
          intensity: 45%

  - platform: monochromatic
    output: Artoo_rear_lamp
    name: $hostname rear lamp
    default_transition_length: 0ms
    effects:
      - random:
#      - random:
#          name: Random Effect With Custom Values
#          transition_length: 5s
#          update_interval: 7s
      - strobe:
#      - strobe:
#          name: Strobe Effect With Custom Values
#          colors:
#            - state: true
#              brightness: 100%
##              red: 100%
##              green: 90%
##              blue: 0%
#              duration: 500ms
#            - state: false
#              duration: 250ms
#            - state: true
#              brightness: 100%
##              red: 0%
##              green: 100%
##              blue: 0%
#              duration: 500ms      
      - flicker:
#      - flicker:
#          name: Flicker Effect With Custom Values
#          alpha: 95%
#          intensity: 1.5%

  - platform: rgb
    name: $hostname's dome
    id: Artoo_dome
    red: Artoo_dome_r2
    green: Artoo_dome_g2
    blue: Artoo_dome_b2
    effects:
      - random:
      - random:
          name: Random fast
          transition_length: 5ms
          update_interval: 7ms
      - strobe:
      - strobe:
          name: Strobe fast
          colors:
            - state: true
              brightness: 100%
              red: 100%
              green: 90%
              blue: 0%
              duration: 5ms
            - state: false
              duration: 25ms
            - state: true
              brightness: 100%
              red: 0%
              green: 100%
              blue: 0%
              duration: 5ms      
      - flicker:
      - flicker:
          name: Flicker fast
          alpha: 95%
          intensity: 45%

  - platform: rgb
    name: $hostname's Back
    id: Artoo_back
    red: Artoo_back_r1
    green: Artoo_back_g1
    blue: Artoo_back_b1
    effects:
      - random:
#      - random:
#          name: Random Effect With Custom Values
#          transition_length: 5s
#          update_interval: 7s
      - strobe:
#      - strobe:
#          name: Strobe Effect With Custom Values
#          colors:
#            - state: true
#              brightness: 100%
#              red: 100%
#              green: 90%
#              blue: 0%
#              duration: 500ms
#            - state: false
#              duration: 250ms
#            - state: true
#              brightness: 100%
#              red: 0%
#              green: 100%
#              blue: 0%
#              duration: 500ms      
      - flicker:
#      - flicker:
#          name: Flicker Effect With Custom Values
#          alpha: 95%
#          intensity: 1.5%

  - platform: fastled_spi
    chipset: APA102
    data_pin: GPIO02
    clock_pin: GPIO12
    num_leds: 1
    rgb_order: BGR
    name: "$hostname led"
    effects:
#      - addressable_random_twinkle:
      - addressable_random_twinkle:
          name: Random Twinkle
          twinkle_probability: 5%
          progress_interval: 32ms
#      - addressable_rainbow:
      - addressable_rainbow:
          name: Rainbow
          speed: 10
          width: 50
#      - strobe:
      - strobe:
          name: Strobe
          colors:
            - state: True
              brightness: 50%
              red: 50%
              green: 50%
              blue: 0%
              duration: 500ms
            - state: False
              duration: 250ms
            - state: True
              brightness: 100%
              red: 0%
              green: 100%
              blue: 0%
              duration: 500ms
#      - flicker:
      - flicker:
          name: Flicker
          alpha: 95%
          intensity: 1.5%
#      - addressable_color_wipe:
      - addressable_color_wipe:
          name: Color Wipe
          colors:
            - red: 100%
              green: 100%
              blue: 100%
              num_leds: 1
            - red: 0%
              green: 0%
              blue: 0%
              num_leds: 1
          add_led_interval: 100ms
          reverse: False
#      - addressable_scan:
      - addressable_scan:
          name: Scan Effect
          move_interval: 100ms
          scan_width: 10
#      - addressable_fireworks:
      - addressable_fireworks:
          name: Fireworks
          update_interval: 32ms
          spark_probability: 10%
          use_random_color: false
          fade_out_rate: 120
#      - random:
      - random:
          name: Random
          transition_length: 5s
          update_interval: 7s

# Example output platform
#servo:
#  - id: my_servo
#    output: Artoo_cerveau

# On ESP32, use ledc output
output:
  - platform: ledc
    pin: GPIO25
    id: Artoo_cerveau
    frequency: 50 Hz
    min_power: 5%    # 5% at 50Hz is 1mS  (20mS cycles)
    max_power: 10%   # 10% at 50Hz is 2mS (20mS cycles)
    channel: 1

  - platform: ledc
    pin: GPIO26
    id: Artoo_rear_lamp
    channel: 3

  - platform: ledc
    pin: GPIO27
    id: Artoo_front_lamp
    channel: 4

  - platform: ledc
    pin: GPIO15
    id: Artoo_dome_r2
    channel: 5

  - platform: ledc
    pin: GPIO14
    id: Artoo_dome_g2
    channel: 6

  - platform: ledc
#    pin: GPIO21
    pin: GPIO04
    id: Artoo_dome_b2
    channel: 7

  - platform: ledc
    pin: GPIO18
    id: Artoo_back_r1
    channel: 8

  - platform: ledc
    pin: GPIO19
    id: Artoo_back_g1
    channel: 9

  - platform: ledc
    pin: GPIO05
    id: Artoo_back_b1
    channel: 10

i2c:
  sda: SDA
  scl: SCL
#  scan: True

uart:
  tx_pin: TX
  rx_pin: RX
  baud_rate: 9600
  id: uart_2

dfplayer:
  on_finished_playback:
    then:
      - dfplayer.stop
#      logger.log: 'Somebody press play!'

esp32_touch:
# maybe, multipress affects playback? 
# longpress ideas?

binary_sensor:

  - platform: gpio
    pin: GPIO23
    name: "$hostname Motion"
    device_class: motion
# after a period of inacivity (1hour) if motion play a sound

  - platform: gpio
    pin: 
      number: GPIO34
      inverted: true
    name: "$hostname Charge state"
# matches the blink pattern on the device (charging LED) https://www.tinypico.com/ says to take multiple readings to avoid false positives.
# gonna need to study this more to figure it out.

  - platform: esp32_touch
    name: "$hostname touch"
    pin: GPIO33
    threshold: 1000
    on_press:
      then:
#        - dfplayer.play: 1
#            file: 1
#            loop: false
        - dfplayer.random:
        - light.turn_on:
            id: R2_front_lamp
            effect: Flicker fast
        - light.turn_on:
            id: Cerveau_pos
            effect: Flicker
        - light.turn_on:
            id: Artoo_dome
            effect: Random fast
#        - output.set_level:
#            id: Artoo_front_lamp
#            level: "50%"
        - delay: 3s
        - light.turn_off:
            id: R2_front_lamp
        - light.turn_off:
            id: Cerveau_pos
        - light.turn_off:
            id: Artoo_dome
#        - output.set_level:
#            id: Artoo_front_lamp
#            level: "0%"
        - dfplayer.stop

sensor:

  - platform: wifi_signal
    name: "$hostname WiFi"
    update_interval: 30s
    id: signal
# lol maybe play a track to complain that wifi is down?

  - platform: adc
    pin: GPIO32
    name: "$hostname Brightness"
    unit_of_measurement: lux
    filters:
      - lambda: |-
          return (x / 10000.0) * 2000000.0;

  - platform: adc
    pin: GPIO35
    name: "$hostname Battery"
    unit_of_measurement: "v"    
    attenuation: 11db
    filters:
      - multiply: 4
# probably a shutdown below a threshold?

  - platform: bme280
    temperature:
      name: "$hostname ambient Temperature"
      id: artoo_temperature
      filters:
        - lambda: return (x * (9.0/5.0) + 32.0);
      unit_of_measurement: "°F"
    pressure:
      name: "$hostname Pressure"
      id: artoo_pressure
    humidity:
      name: "$hostname Humidity"
      id: artoo_humidity
#      filters:
#        - lambda: return x +10;
    address: 0x76
    update_interval: 30s

  - platform: mpu6050
    update_interval: 10s
    address: 0x68
    accel_x:
      name: "cerveau Accel X"
    accel_y:
      name: "cerveau Accel Y"
    accel_z:
      name: "cerveau Accel z"
    gyro_x:
      name: "cerveau Gyro X"
    gyro_y:
      name: "cerveau Gyro Y"
    gyro_z:
      name: "cerveau Gyro z"
    temperature:
      name: "$hostname head Temperature"
# probably need to figure out how often i can update without overloading the mcu, also maybe only send motion to home assistant to avoid spamming/excessive api calls. play a track based on motion

Paging Doctor
@DrZzs
can you help me with your army of followers? :pray:

Cheers!