Add wifi to an older roomba

I’ve merged both UART support and some black magic from good old johnboiles’ repo to avoid BRC pin issues on Roomba 650 (in order to prevent this model to fall into a deep sleep that can be interrupted only manually pressing the CLEAN button or with an ugly relay).
So far so good: after two weeks no issues.

1 Like

I don’t know how to check the model, i saw 601 on the bottom label
I used this step down MP1584EN

image

Hi @davidecavestro, I’m testing the latest version with UART refactor;
I can’t wake up the Roomba any more :frowning:

this is my EPSHome code:

 init: 'RoombaComponent::instance(D4, id(uart_bus), 10000, true);'
....
uart:
  id: uart_bus
  tx_pin: TX
  rx_pin: RX
  baud_rate: 115200
  
# Enable logging
logger:
  hardware_uart: UART1

Once I wake up the Roomba with physical button and the serial communication is initialized, I have all the telemetry

but when it goes in deep sleep

Do you have any suggestions?

I also would like to understand how to use the buttons. Can you explain to me how the commands are supposed to work? I see the code, but I don’t understand how to use it

I checked the fork by @Real-Time-Kodi

https://github.com/Real-Time-Kodi/ESPHomeRoombaComponent

and after swapping from private to public I’m able to send commands, but I’m not sure that’s the way to go

image

Thank you for your support
Regards

I use them this way …basically for fun :wink:


passing the command name to the service. i.e. the following example is for using the paper-buttons widget (please note I renamed the roomba component to vacuum here so the service name became esphome.vacuum_command)

type: entities
entities:
  - type: custom:paper-buttons-row
    buttons:
      - icon: mdi:chevron-up
        tap_action:
          action: call-service
          service: esphome.vacuum_command
          service_data:
            command: go_faster
  - type: custom:paper-buttons-row
    buttons:
      - icon: mdi:chevron-left
        tap_action:
          action: call-service
          service: esphome.vacuum_command
          service_data:
            command: go_left
      - icon: mdi:checkbox-blank-circle-outline
        tap_action:
          action: call-service
          service: esphome.vacuum_command
          service_data:
            command: halt
        hold_action:
          action: call-service
          service: esphome.vacuum_command
          service_data:
            command: drive
      - icon: mdi:chevron-right
        tap_action:
          action: call-service
          service: esphome.vacuum_command
          service_data:
            command: go_right
  - type: custom:paper-buttons-row
    buttons:
      - icon: mdi:chevron-down
        tap_action:
          action: call-service
          service: esphome.vacuum_command
          service_data:
            command: go_slower
        hold_action:
          action: call-service
          service: esphome.vacuum_command
          service_data:
            command: halt

My Roomba model is 650, please check your.

I’ve experimented a bit and seen that this way - passing true to the 4th param just added - the controller actually prevents the Roomba to fall asleep, so the CLEAN button light is always on, the serial port active and all registers available. I must admit I’ve not tested it yet passing false as I was interested in the logic to prevent the deep sleep.
Probably this is not the best solution, though I’ve noticed no performance nor battery degradation so far (only 2 weeks testing as of now).
The original code comes from johnboiles repo, and for my vacuum it works, provided that the Roomba is awake at ESP boot time or you wake it up manually in order to let the ESP take control and prevent the deep sleep.
I must say most of the time my Roomba is on the dock - so I should test it more exhaustively - but at least the gathered data is consistent and it always reacts to commands.


PS: As of now I’ve put a 2N3906 transistor between the Roomba WRITE pin and the logical level shifter, as per Add wifi to an older roomba - #77 by Ecam315 and https://www.irobotweb.com/~/media/MainSite/PDFs/About/STEM/Create/Create_2_to_5V_Logic.pdf
So far it works fine thought I’m curious to check if I can completely skip the logic level shifter.

Thank you so much @davidecavestro,

I got it :smiley:

just in case if anyone would like to use it
as far I understood probably, I can remove the wakeup buttons (the first row)

type: vertical-stack
title: roomba-control
cards:
  - type: horizontal-stack
    cards:
      - show_name: true
        show_icon: true
        type: button
        tap_action:
          action: call-service
          service: esphome.roomba_control_command
          data:
            command: wakeup
          target: {}
        icon: mdi:gesture-swipe-up
      - show_name: true
        show_icon: true
        type: button
        tap_action:
          action: call-service
          service: esphome.roomba_control_command
          data:
            command: wake_on_dock
          target: {}
        icon: mdi:eject-circle
  - type: horizontal-stack
    cards:
      - show_name: true
        show_icon: true
        type: button
        tap_action:
          action: call-service
          service: esphome.roomba_control_command
          data:
            command: start
          target: {}
        icon: mdi:arrow-right-drop-circle
      - show_name: true
        show_icon: true
        type: button
        tap_action:
          action: call-service
          service: esphome.roomba_control_command
          data:
            command: stop
          target: {}
        icon: mdi:stop-circle
  - type: horizontal-stack
    cards:
      - show_name: true
        show_icon: true
        type: button
        tap_action:
          action: call-service
          service: esphome.roomba_control_command
          data:
            command: spot
          target: {}
        icon: mdi:refresh-circle
      - show_name: true
        show_icon: true
        type: button
        tap_action:
          action: call-service
          service: esphome.roomba_control_command
          data:
            command: dock
          target: {}
        icon: mdi:home-circle
  - type: horizontal-stack
    cards:
      - show_name: true
        show_icon: true
        type: button
        tap_action:
          action: call-service
          service: esphome.roomba_control_command
          data:
            command: locate
          target: {}
        icon: mdi:bell-circle
      - show_name: true
        show_icon: true
        type: button
        tap_action:
          action: call-service
          service: esphome.roomba_control_command
          data:
            command: sleep
          target: {}
        icon: mdi:pause-circle

1 Like

Copy that. I see the same behavior

When the Roomba is on the dock, the CLEAN button light is always on, and the serial port is active
I don’t see the same once the Roomba IS NOT on the dock, the CLEAN button light is off, and the serial port goes passive (I guess)

I used the same schema

1 Like

Thanks for sharing, this is way easier than how I organized buttons before

1 Like

@davidecavestro , do you think that I can remove the wakeup and wake-on-dock buttons? I think that if the Roomba is in deep sleep, they don’t work at all. correct?

If you want to configure the icon directly in the esp

  - platform: custom
    lambda: |-
      auto r = ${init}
      return {r->voltageSensor, r->currentSensor, r->batteryChargeSensor, r->batteryCapacitySensor, r->batteryPercentSensor, r->batteryTemperatureSensor, r->driveSpeedSensor};

    sensors:
      - name: "${friendly_name} distance"
        unit_of_measurement: "mm"
        icon: mdi:map-marker-distance
        accuracy_decimals: 0

      - name: "${friendly_name} voltage"
        unit_of_measurement: "V"
        icon: mdi:sine-wave
        accuracy_decimals: 2

      - name: "${friendly_name} current"
        unit_of_measurement: "A"
        icon: mdi:lightning-bolt
        accuracy_decimals: 3
      
      - name: "${friendly_name} charge"
        unit_of_measurement: "Ah"
        icon: mdi:battery-charging
        accuracy_decimals: 2
      
      - name: "${friendly_name} capacity"
        unit_of_measurement: "Ah"
        icon: mdi:battery
        accuracy_decimals: 2
      
      - name: "${friendly_name} battery"
        unit_of_measurement: "%"
        state_class: "measurement"
        device_class: battery
        icon: mdi:battery-outline
        accuracy_decimals: 0
      
      - name: "${friendly_name} temperature"
        unit_of_measurement: "°C"
        icon: mdi:thermometer
        accuracy_decimals: 0

text_sensor:
  - platform: custom
    lambda: |-
      auto r = ${init}
      return {r->chargingSensor, r->activitySensor, r->oiModeSensor};
    text_sensors:
        - name: "${friendly_name} charging state"
          icon: mdi:battery-charging-high 
        - name: "${friendly_name} activity"
          icon: mdi:robot-vacuum-variant
        - name: "${friendly_name} OI mode"
          icon: mdi:steering

Hi folks,

Is the measure unit Ah or mAh?

do you know if the value requires “any filter”?, eg:

        filters:
        - median:
            window_size: 7
            send_every: 4
            send_first_at: 3
        - multiply: 0.001

I’ve not seen it in deep sleep so far with lazy650Enabled = true, as the brc_wakeup keeps it awake. OTOH I expect that if/when it reaches a deep sleep the only way to wake it up is pressing the physical buttons or with a relay under them, given that I consider deep sleep a machine state which completely turns off the serial port (including the BRC pin).

where I should set it?
here


or here

Yes, you already set it passing true as last costructor arg


But maybe there’s something wrong… you could also temporarily add some log here and there to check what’s going on, or even simply the value i.e. if (lazy650Enabled) {ESP_LOGI("roomba", "lazy650Enabled is true");} or unconditionally simply passing the value as variable arg.

Please do share! I am interested in such tutorial.

1 Like

@k8gg, copy and paste in a new tab in Lovelace, I don’t know what can be easiest then that

Specs talk about mA for current and mAh for charge/capacity, so raw values are translated to A/Ah. Also voltage is converted from mV to V.
image

Experimenting with filters is a good idea… removing translations from component code and leaving raw values flow, eventually manipulated at the filters stage, so that we can easily remove noise.

Hi,

as soon I add this sensor

- name: "${friendly_name} drive speed"
        unit_of_measurement: "mm/s"
        icon: mdi:speedometer
        accuracy_decimals: 0

I lose the connection with the ESP, any idea?

I see this in the code

			SensorSongNumber				= 36, //24
			SensorSongPlaying				= 37, //25

Would it be possible to use it to play a song when I send the locate command?

void locate() {
            write(141);
            write(0);
        }

I think that @Real-Time-Kodi did something similar…

        else if (command == "locate"){
                uint8_t song[] = {62, 12, 66, 12, 69, 12, 74, 36};
                this->roomba.safeMode();
                delay(500);
                this->roomba.song(0, song, sizeof(song));
                this->roomba.playSong(0);
                //this->roomba.playSong(1);

Please check you added the related sensor within the lambda return value of the custom sensor.
Pay also attention to the position, i.e. last elem of the return value, last elemn of the sensor array defs