Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. My Project
  3. Mysensorized Roomba

Mysensorized Roomba

Scheduled Pinned Locked Moved My Project
18 Posts 9 Posters 7.4k Views 10 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • EmielAE Offline
    EmielAE Offline
    EmielA
    wrote on last edited by
    #7

    Eoreh,

    I used different pieces of code from different projects.and combined them to one sketch. I used some from this project : link text
    And the sketch from the MySensors Relay Actuator. I switch the Node/Relay on for about 10 seconds and then off. In the 10 seconds the IR sends the CLEAN command. With a LDR I detect if the Roomba dock led is on or off. So I detect if the Roomba is on its dock. Here under the code I hope it helps you.

    
    
    
    // Example sketch showing how to control physical relays. 
    // This example will remember relay state even after power failure.
    
    #include <MySensor.h>
    #include <SPI.h>
    #include <IRremote.h>
    #include <DHT.h> 
    #include <Bounce2.h>
    
    #define RELAY_1  3  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 1 // Total number of attached relays
    #define RELAY_ON 1  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    
    #define CHILD_ID_HUM 0
    #define CHILD_ID_TEMP 1
    #define CHILD_ID_DOCK 5
    #define HUMIDITY_SENSOR_DIGITAL_PIN 4 // Temperatuur sensor and Humidity op pin 4 input
    #define DOCK_SENSOR_PIN 5 // Light sensor on pin 5 input
    unsigned long WAIT_TIME = 15000; // Wait time between reads (in milliseconds)
    
    
    IRsend irsend; // hardwired to pin 3; use a transistor to drive the IR LED for maximal range
    
    MySensor gw;
    
    Bounce debouncer = Bounce();
    DHT dht;
    int oldValue=-1; //light sensor
    float lastTemp;
    float lastHum;
    boolean metric = true; 
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    
    // Change to V_LIGHT if you use S_LIGHT in presentation below
    MyMessage msgDock(CHILD_ID_DOCK,V_TRIPPED);
    
    void setup()  
    {   
      // Initialize library and add callback for incoming messages
      gw.begin(incomingMessage, AUTO, true);
       
      // Setup the DOCK_SENSOR to input
      pinMode(DOCK_SENSOR_PIN,INPUT);
      
      // After setting up the button, setup debouncer
      debouncer.attach(DOCK_SENSOR_PIN);
      debouncer.interval(5);
      
      dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("Temp Humidity and Roomba IR", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      gw.present(CHILD_ID_HUM, S_HUM);
      gw.present(CHILD_ID_TEMP, S_TEMP);
      gw.present(CHILD_ID_DOCK, S_DOOR);
      
      metric = gw.getConfig().isMetric;
    
      // Fetch relay status
      for (int sensor=2, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) {
        // Register all sensors to gw (they will be created as child devices)
        gw.present(sensor, V_LIGHT);
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);   
        // Set relay to last known state (using eeprom storage) 
        digitalWrite(pin, gw.loadState(sensor)?RELAY_ON:RELAY_OFF);
      }
    }
    
    
    void loop() 
    {
      // Alway process incoming messages whenever possible
      
      {  
      delay(dht.getMinimumSamplingPeriod());
    
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
          Serial.println("Failed reading temperature from DHT");
      } else if (temperature != lastTemp) {
        lastTemp = temperature;
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        }
        gw.send(msgTemp.set(temperature, 1));
        Serial.print("T: ");
        Serial.println(temperature);
      }
      
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
          Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum) {
          lastHum = humidity;
          gw.send(msgHum.set(humidity, 1));
          Serial.print("H: ");
          Serial.println(humidity);
      }
    
      debouncer.update();
      // Get the update value
      int value = debouncer.read();
     
      if (value != oldValue) {
         // Send in the new value
         gw.send(msgDock.set(value==HIGH ? 1 : 0));
         oldValue = value;
      }
      
      gw.wait(WAIT_TIME); //sleep a bit
     }
    }
    
    void incomingMessage(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type==V_LIGHT) {
         // Change relay state
    //     digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
         roomba_send(136);  // Send "Clean"   
         // Store state in eeprom
         gw.saveState(message.sensor, message.getBool());
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
       } 
    }
    void roomba_send(int code)
    {
      Serial.print("Sending Roomba code ");
      Serial.print(code);
      int length = 8;
      unsigned int raw[length*2];
      unsigned int one_pulse = 3000;
      unsigned int one_break = 1000;
      unsigned int zero_pulse = one_break;
      unsigned int zero_break = one_pulse;
    
      int arrayposition = 0;
      // Serial.println("");
      for (int counter = length-1; counter >= 0; --counter) {
        if(code & (1<<counter)) {
          // Serial.print("1");
          raw[arrayposition] = one_pulse;
          raw[arrayposition+1] = one_break;
        }
        else {
          // Serial.print("0");
          raw[arrayposition] = zero_pulse;
          raw[arrayposition+1] = zero_break;
        }
        arrayposition = arrayposition + 2;
      }
      for (int i = 0; i < 3; i++) {
        irsend.sendRaw(raw, 15, 38);
        delay(50);
      }
      Serial.println("");
    
      Serial.print("Raw timings:");
       for (int z=0; z<length*2; z++) {
       Serial.print(" ");
       Serial.print(raw[z]);
       }
       Serial.print("\n\n");
    }
    
    1 Reply Last reply
    0
    • E Offline
      E Offline
      Eawo
      wrote on last edited by
      #8

      Maybe this is off topic but I'm going to buy a roomba but it is so many versions. Will roomba 615 or 616 do the job or is the newer versions smarter cleaner? I have around 80kvd

      parachutesjP 1 Reply Last reply
      0
      • E Eawo

        Maybe this is off topic but I'm going to buy a roomba but it is so many versions. Will roomba 615 or 616 do the job or is the newer versions smarter cleaner? I have around 80kvd

        parachutesjP Offline
        parachutesjP Offline
        parachutesj
        wrote on last edited by
        #9

        @Eawo I do have a 581 and not 100% sure what has been changed on newer models. Maybe you ask in a roomba forum

        parachutesjP 1 Reply Last reply
        0
        • parachutesjP parachutesj

          @Eawo I do have a 581 and not 100% sure what has been changed on newer models. Maybe you ask in a roomba forum

          parachutesjP Offline
          parachutesjP Offline
          parachutesj
          wrote on last edited by
          #10

          All,
          I did some updates also thanks to @Eoreh I updated my code a bit. Anyhow, no really news on software side but was able to fit it more or less completely inside of the Roomba.

          1. I wanted to fit all inside and I think there is enough space but wanted to be able to disable it and thought about a dip-switch somewhere but then decided to have it connected via DIN as before. Means also no soldering on Roomba

          2. finding a spot was easy:
            alt text
            There is enough space on the side of the bin. (In picture, the external charging port was already removed)

          3. I soldered all together and decided to opt for a Nano instead of a Pro Mini due to the lack of 3.3V on board. I know radio might be better powered with a voltage regulator but the reception and reliability is not too important here. Anyhow not experienced any issues so far. I also used the SMD radio to save some extra space.
            The voltage regulator has a heat sink mounted which is pointing where the charing port was and is getting some "fresh air" ;-)
            alt text

          4. all in place and ready to be closed again
            alt text

          5. closed without top plate
            alt text

          If it stops working or needs a reset, I only need to unplug and replug

          M 1 Reply Last reply
          0
          • parachutesjP parachutesj

            All,
            I did some updates also thanks to @Eoreh I updated my code a bit. Anyhow, no really news on software side but was able to fit it more or less completely inside of the Roomba.

            1. I wanted to fit all inside and I think there is enough space but wanted to be able to disable it and thought about a dip-switch somewhere but then decided to have it connected via DIN as before. Means also no soldering on Roomba

            2. finding a spot was easy:
              alt text
              There is enough space on the side of the bin. (In picture, the external charging port was already removed)

            3. I soldered all together and decided to opt for a Nano instead of a Pro Mini due to the lack of 3.3V on board. I know radio might be better powered with a voltage regulator but the reception and reliability is not too important here. Anyhow not experienced any issues so far. I also used the SMD radio to save some extra space.
              The voltage regulator has a heat sink mounted which is pointing where the charing port was and is getting some "fresh air" ;-)
              alt text

            4. all in place and ready to be closed again
              alt text

            5. closed without top plate
              alt text

            If it stops working or needs a reset, I only need to unplug and replug

            M Offline
            M Offline
            moskovskiy82
            wrote on last edited by moskovskiy82
            #11

            @parachutesj Mind posting your finished code?

            Also wonder what is the correct MQTT payload to start for example cleaning?

            Upon start i see the following

            mys-out/15/255/3/0/11 MYS Roomba
            mys-out/15/255/3/0/12 2.1
            mys-out/15/0/0/0/3 Roomba-Stop
            mys-out/15/1/0/0/3 Roomba-Dock
            mys-out/15/2/0/0/3 Roomba-Clean
            mys-out/15/3/0/0/3 Roomba-Spot
            mys-out/15/4/0/0/3 Roomba-Max
            mys-out/15/5/0/0/3 Roomba-Power
            mys-out/15/6/0/0/3 Roomba-Play
            mys-out/15/100/0/0/6 Roomba-Batt-Temp
            mys-out/15/101/0/0/39 Roomba-Batt-Proc
            mys-out/15/102/0/0/30 Roomba-Batt-Volt
            mys-out/15/103/0/0/30 Roomba-Batt-mAH
            mys-out/15/104/0/0/36 Roomba-Batt-CHt
            mys-out/15/105/0/0/36 Roomba-Batt-CHs

            But publishing to

            mys-in/15/2/1/0/3
            mys-in/15/2/1/0/2

            with payload 1 doesn't do anything

            parachutesjP 1 Reply Last reply
            0
            • M moskovskiy82

              @parachutesj Mind posting your finished code?

              Also wonder what is the correct MQTT payload to start for example cleaning?

              Upon start i see the following

              mys-out/15/255/3/0/11 MYS Roomba
              mys-out/15/255/3/0/12 2.1
              mys-out/15/0/0/0/3 Roomba-Stop
              mys-out/15/1/0/0/3 Roomba-Dock
              mys-out/15/2/0/0/3 Roomba-Clean
              mys-out/15/3/0/0/3 Roomba-Spot
              mys-out/15/4/0/0/3 Roomba-Max
              mys-out/15/5/0/0/3 Roomba-Power
              mys-out/15/6/0/0/3 Roomba-Play
              mys-out/15/100/0/0/6 Roomba-Batt-Temp
              mys-out/15/101/0/0/39 Roomba-Batt-Proc
              mys-out/15/102/0/0/30 Roomba-Batt-Volt
              mys-out/15/103/0/0/30 Roomba-Batt-mAH
              mys-out/15/104/0/0/36 Roomba-Batt-CHt
              mys-out/15/105/0/0/36 Roomba-Batt-CHs

              But publishing to

              mys-in/15/2/1/0/3
              mys-in/15/2/1/0/2

              with payload 1 doesn't do anything

              parachutesjP Offline
              parachutesjP Offline
              parachutesj
              wrote on last edited by
              #12

              @moskovskiy82 I did not change too much compared to @EmielA on the code. worked pretty good until I bought a new roomba recently. Haven't tried it on the 980 yet:

              // Enable debug prints to serial monitor
              #define MY_DEBUG
              
              // Enable and select radio type attached
              #define MY_RADIO_NRF24
              //#define MY_RADIO_RFM69
              
              // Enable repeater functionality for this node
              #define MY_REPEATER_FEATURE
              
              #define CHILD_ID_BATT_TEMP          100  // Id of the 2nd msg1_3
              #define CHILD_ID_BATT_PROC          101   // Id of the 2nd msg1_4
              #define CHILD_ID_BATT_VOLT          102   // Id of the 2nd msg1_2
              #define CHILD_ID_BATT_AH            103   // Id of the 2nd msg2_5
              #define CHILD_ID_BATT_CHARGE_TYPE   104   // Id of the 2nd msg1_1
              #define CHILD_ID_BATT_CHARGE_SOURCE 105   // Id of the 2nd msg2_2
              
              
              #include <MySensors.h>
              #include <SoftwareSerial.h>
              
              //#define RELAY_1  5  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
              //#define NUMBER_OF_RELAYS 2 // Total number of attached relays
              //#define RELAY_ON 1  // GPIO value to write to turn on attached relay
              //#define RELAY_OFF 0 // GPIO value to write to turn off attached relay
              
              #define NUMBER_OF_FUNCTION 7 
              #define NUMBER_OF_SENSORS 6
              #define ROOMBA_READ_TIMEOUT 300
              #define ROOMBA_WAKE_COUNT 10
              int ddPin = 6;
              
              int rxPin = 3;
              int txPin = 4;
              int ledPin = 13;
              
              SoftwareSerial roomba(rxPin, txPin);
              
              const char SWITCH_NAMES[NUMBER_OF_FUNCTION][14] = { "Roomba-Stop","Roomba-Dock","Roomba-Clean","Roomba-Spot","Roomba-Max","Roomba-Power","Roomba-Play" };
              const char SENSORS_NAMES[NUMBER_OF_SENSORS][24] = { "Roomba-Batt-Temp","Roomba-Batt-Proc","Roomba-Batt-Volt", "Roomba-Batt-mAH" , "Roomba-Batt-CHt" , "Roomba-Batt-CHs" };
              
              
              uint8_t buf[52];
              boolean lowBattery = true; // Acts as a debounce
              long battery_Current_mAh = 0;
              long battery_Total_mAh = 0;
              long battery_percent = 0;
              boolean DeadBattery = false;
              boolean FullBattery = true;
              unsigned long chargingState = 0;
              long voltage = 0;
              long temp = 0;
              long OiMode = 0;
              long ChargeSource = 0;
              
              long sensorfrequency = 300000; // 300000 = 5 min - frequency the sensors are read
              long lastsensorread = 0; // when were the sensors read the last time
              unsigned long lastsensorssend = 0;
              
              const char ChargeTypes[6][34] = { "Not charging","Reconditioning Charging","Full Charging","Trickle Charging","Waiting","Charging Fault Condition" };
              const char OiTypes[4][14] = { "Off","Passive","Safe","Full" };
              
              int packetSizes[58] = {
                  0,0,0,0,0,0, //1-6
                  1,1,1,1,1,1,1,1,1,1,1,1, //7-18
                  2,2, //19-20
                  1, //21
                  2,2, //22-23
                  1, //24
                  2,2,2,2,2,2,2, //25-31
                  1, //32
                  2, //33
                  1,1,1,1,1, //34-38
                  2,2,2,2,2,2, //39-44
                  1, //45
                  2,2,2,2,2,2, //46-51
                  1,1, //52-53
                  2,2,2,2, //54-57
                  1 //58
              };
              #define bumpright (sensorbytes[0] & 0x01)
              #define bumpleft  (sensorbytes[0] & 0x02)
              
              
              MyMessage msg1_3(CHILD_ID_BATT_TEMP, V_TEMP); //status of Temperature
              MyMessage msg1_4(CHILD_ID_BATT_PROC, V_PH); //status of Charge [%]
              MyMessage msg1_2(CHILD_ID_BATT_VOLT, V_VOLTAGE); //status of Voltage
              MyMessage msg2_5(CHILD_ID_BATT_AH, V_CURRENT); //status of mAH
              MyMessage msg1_1(CHILD_ID_BATT_CHARGE_TYPE, V_TEXT); //status of charget type
              MyMessage msg2_2(CHILD_ID_BATT_CHARGE_SOURCE, V_TEXT); //status of charger source
              
              void setup() {
                  pinMode(ddPin, OUTPUT);
                  digitalWrite(ddPin, LOW);
                  Serial.begin(115200);
                  while (!Serial) {
                      ; // wait for serial port to connect. Needed for native USB port only
                  }
                  roomba.begin(115200);
                  //Serial.println("Sending start command...");
                  //delay(1000);
                  //// set up ROI to receive commands
                  defsongs();
                  delay(500);
                  rstop();
                  Serial.println("Ready to go!");
              }
              
              void presentation()
              {
                  // Send the sketch version information to the gateway and Controller
                  sendSketchInfo("Roomba", "1.2");
              
                  for (int sensor = 0; sensor < NUMBER_OF_FUNCTION; sensor++) {
                      // Register all sensors to gw (they will be created as child devices)
                      present(sensor, S_BINARY, SWITCH_NAMES[sensor]);
                      delay(100);
                  }
                  present(CHILD_ID_BATT_TEMP, S_TEMP, SENSORS_NAMES[0]); delay(100);
                  present(CHILD_ID_BATT_PROC, S_WATER_QUALITY, SENSORS_NAMES[1]); delay(100);
                  present(CHILD_ID_BATT_VOLT, S_MULTIMETER, SENSORS_NAMES[2]);    delay(100);
                  present(CHILD_ID_BATT_AH, S_MULTIMETER, SENSORS_NAMES[3]);  delay(100);
                  present(CHILD_ID_BATT_CHARGE_TYPE, S_INFO, SENSORS_NAMES[4]); delay(100);
                  present(CHILD_ID_BATT_CHARGE_SOURCE, S_INFO, SENSORS_NAMES[5]); delay(100);
              }
              
              void loop() {
                  unsigned long now = millis();
                  if (now > lastsensorssend + sensorfrequency)
                  {
                      readsensors();
                      lastsensorssend = now;
                  }
              }
              
              
              void receive(const MyMessage &message) {
                // We only expect one type of message from controller. But we better check anyway.
                if (message.type == V_LIGHT) {
                  int mySensor = message.sensor;
                  int myComand = message.getBool();
              
                  //Serial.print(message.sensor-1+RELAY_1);
              
                  if (mySensor == 0) {
                    if (myComand == 1) {
                      Serial.println("Clean");
                      //clean();
                      rcommand(135);
                    }
                    else {
                      Serial.println("Stopp1");
                      //halt();
                      rstop();
                    }
                  }
              
                  if (mySensor == 1) {
                    if (myComand == 1) {
                      Serial.println("dock");
                      //dock();
                      rcommand(143);
                    }
                    else {
                      Serial.println("Stopp2");
                      //halt();
                      rstop();
                    }
                  }
                  if (mySensor == 2) {
                    if (myComand == 1) {
                      Serial.println("song");
                      //dock();
                      rcommand(141);
                      rsong(0);
                    }
                    else {
                      Serial.println("Stopp2");
                      //halt();
                      rstop();
                    }
                  }
              
                }
              }
              
              void halt() {
                ;
                roomba.write(131);  // SAFE
                byte j = 0x00;
                roomba.write(137);
                roomba.write(j);
                roomba.write(j);
                roomba.write(j);
                roomba.write(j);
              }
              
              void dock() {
                delay(1000);
                roomba.write(143);
              }
              
              void clean() {
                delay(1000);
                roomba.write(135);
              }
              
              void rstop() {
                  if (rwakeup()) {
                      roomba.write(128);  delay(100);
                      roomba.write(131);  delay(100);
                      roomba.write(137);  delay(100);
                      byte j = 0x00;
                      roomba.write(j); delay(100);
                      roomba.write(j); delay(100);
                      roomba.write(j); delay(100);
                      roomba.write(j); delay(100);
                      roomba.write(128);
                  }
              
              }
              
              void rsong(int b) {
                  roomba.write(b); delay(100);
              }
              
              
              
              void rcommand(int command) {
                  if (rwakeup()) {
                      roomba.write(128);  delay(100);
                      roomba.write(131);  delay(100);
                      roomba.write(command);
                  }
              }
              
              void play(char note, int rlong) {
                  roomba.write(rnote(note));  delay(10);  roomba.write(64 / rlong);   delay(10);
              }
              
              
              bool rwakeup() {
                  bool ret = getSensors(6, buf, 52);
                  Serial.print("wakeup: ");
                  Serial.print(ret);
                  if (!ret) {
                      for (int ii = 1; ii < ROOMBA_WAKE_COUNT; ii++)
                      {
                          for (int jj = 0; jj < 3; jj++) {
                              digitalWrite(ddPin, HIGH); delay(10); 
                              digitalWrite(ddPin, LOW); delay(2);
                          }
                          delay(100);
                          roomba.write(128);
                          if (getSensors(6, buf, 52)) {
                              ret = true;
                              break;
                          }
                          Serial.print("-");
                      }
                  }
                  Serial.println(ret);
                  return ret;
              }
              
              bool getSensors(uint8_t packetID, uint8_t* dest, uint8_t len) {
                  roomba.write(142);
                  delay(100);
                  roomba.write(packetID);
                  delay(100);
                  return getData(dest, len);
              }
              
              
              bool getData(uint8_t* dest, uint8_t len)
              {
                  while (len-- > 0)
                  {
                      unsigned long startTime = millis();
                      while (!roomba.available())
                      {
                          // Look for a timeout
                          if (millis() > startTime + ROOMBA_READ_TIMEOUT)
                              return false; // Timed out
                      }
                      *dest++ = roomba.read();
                  }
                  return true;
              }
              
              //for sensorgetting
              int getPacketSize(int p) {
                  return packetSizes[p - 1];
              }
              int getPacketOffset(int p) {
                  int i = 0;
                  for (int s = 1; s < p; s++) {
                      i += getPacketSize(s);
                  }
                  return i;
              }
              
              //read sensors
              void readsensors()
              {
              
                  if (getSensors(6, buf, 52)) {
              
                      int off = 0;
              
                      // Battery Checks
                      off = getPacketOffset(21);
                      chargingState = buf[off + 0];
                      voltage = buf[off + 2] + 256 * buf[off + 1];
                      temp = buf[off + 5];
                      battery_Current_mAh = buf[off + 7] + 256 * buf[off + 6];
                      battery_Total_mAh = buf[off + 9] + 256 * buf[off + 8];
              
                      if (battery_Total_mAh == 0) battery_Total_mAh = 1;
                      int nBatPcent = battery_Current_mAh * 100 / battery_Total_mAh;
                      battery_percent = nBatPcent;
              
                      //Oi Mode
                      off = getPacketOffset(35);
                      OiMode = buf[off + 0];
              
                      //ChargeSource
                      off = getPacketOffset(34);
                      ChargeSource = buf[off + 0];
              
              
                      send(msg1_3.set(temp));  delay(100);
                      send(msg1_4.set(battery_percent));  delay(100);
                      send(msg1_2.set(round(voltage / 10), 1));  delay(100);
                      send(msg2_5.set(battery_Current_mAh));  delay(100);
                      send(msg1_1.set(ChargeTypes[chargingState]));  delay(100);
                      send(msg2_2.set(ChargeSource));  delay(100);
              
                      //send(msg2_5.set(chargingState));  // Send info value to gw
                      //send(msg2_5.set("charging state"));  // Send info value to gw
                      //send(msg2_5.set(battery_Total_mAh));  // Send info value to gw
                      //send(msg2_1.set(OiTypes[OiMode]));  // Send info value to gw
                      lastsensorread = millis();
              
                  }
                  else { send(msg1_1.set("roomba is off")); }  // Send info value to gw
              }
              
              void defsongs() {
                  uint8_t zero = 0;
                  roomba.write(128);  delay(100); roomba.write(131);  delay(100); //[128 131](Start the command stream and change roomba mode to "Safe" mode)
                  roomba.write(140);  delay(100); roomba.write(zero); delay(100); //[140 0](Start song definition and define the first song, song number 0)
                  roomba.write(25);   //[16](16 notes will be sent for song number 0)
                  play('E', 4);       //[76 16](play Mi sound for 1 / 4 seconds) // E
                  play('E', 4);
                  play('E', 2);
                  play('E', 4);
                  play('E', 4);
                  play('E', 2);       //[76 32](play Mi sound for 1 / 2 seconds)
                  play('E', 4);
                  play('G', 4);
                  play('C', 4);
                  play('D', 4);
                  play('E', 1);
              
                  play('F', 4);
                  play('F', 4);
                  play('F', 2);
              
                  play('F', 4);
                  play('E', 4);
                  play('E', 2);
              
                  play('E', 4);
                  play('D', 4);
                  play('D', 4);
                  play('E', 4);
                  play('D', 1);
                  delay(100);
                  roomba.write(128);
              }
              
              int rnote(char note) {
                  int command = 31;
                  switch (note) {
                  case 'C': command = 72; break;
                  case 'D': command = 74; break;
                  case 'E': command = 76; break;
                  case 'F': command = 77; break;
                  case 'G': command = 79; break;
                  }
                  return command;
              }
              
              
              Z 1 Reply Last reply
              0
              • gohanG Offline
                gohanG Offline
                gohan
                Mod
                wrote on last edited by gohan
                #13

                Just a question, but wouldn't it be an esp8266 a more compact solution? (Not to mention the quick ota programming) Or the roomba is running 5v serial output?

                parachutesjP 1 Reply Last reply
                0
                • gohanG gohan

                  Just a question, but wouldn't it be an esp8266 a more compact solution? (Not to mention the quick ota programming) Or the roomba is running 5v serial output?

                  parachutesjP Offline
                  parachutesjP Offline
                  parachutesj
                  wrote on last edited by
                  #14

                  @gohan ESP is probably a good alternative. but then again you could also buy an after market wireless module for your roomba.
                  I am not sure about the serial output, but I think it is 5v.

                  but there is plenty of space for a nano or pro mini. wemos mini or nodemcu should also fit

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    moskovskiy82
                    wrote on last edited by
                    #15

                    ESP is the best solution although couldn't find the code with sensors (only clean/dock commands). I recently made a post on HomeAssistant forum - how wemos D1 fits nicely inside. You only need a buck converter and 4 cat5 wires soldered. And 5V serial output is not such a big problem as you need a voltage divider only on rx pin (didn't put it)

                    P.S. But then one of those "machine revolt weeks happened" so my esproomba didn't respond and then i burned it down. Next day my RPi3 went down with HA and lots of goodies. And today ESXi...

                    1 Reply Last reply
                    0
                    • gohanG Offline
                      gohanG Offline
                      gohan
                      Mod
                      wrote on last edited by gohan
                      #16

                      Oh man, that sucks a lot. Best luck for your disaster recovery

                      PS if everything you are touching is failing, be careful when you are going to pee 😂

                      1 Reply Last reply
                      1
                      • parachutesjP parachutesj

                        @moskovskiy82 I did not change too much compared to @EmielA on the code. worked pretty good until I bought a new roomba recently. Haven't tried it on the 980 yet:

                        // Enable debug prints to serial monitor
                        #define MY_DEBUG
                        
                        // Enable and select radio type attached
                        #define MY_RADIO_NRF24
                        //#define MY_RADIO_RFM69
                        
                        // Enable repeater functionality for this node
                        #define MY_REPEATER_FEATURE
                        
                        #define CHILD_ID_BATT_TEMP          100  // Id of the 2nd msg1_3
                        #define CHILD_ID_BATT_PROC          101   // Id of the 2nd msg1_4
                        #define CHILD_ID_BATT_VOLT          102   // Id of the 2nd msg1_2
                        #define CHILD_ID_BATT_AH            103   // Id of the 2nd msg2_5
                        #define CHILD_ID_BATT_CHARGE_TYPE   104   // Id of the 2nd msg1_1
                        #define CHILD_ID_BATT_CHARGE_SOURCE 105   // Id of the 2nd msg2_2
                        
                        
                        #include <MySensors.h>
                        #include <SoftwareSerial.h>
                        
                        //#define RELAY_1  5  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
                        //#define NUMBER_OF_RELAYS 2 // Total number of attached relays
                        //#define RELAY_ON 1  // GPIO value to write to turn on attached relay
                        //#define RELAY_OFF 0 // GPIO value to write to turn off attached relay
                        
                        #define NUMBER_OF_FUNCTION 7 
                        #define NUMBER_OF_SENSORS 6
                        #define ROOMBA_READ_TIMEOUT 300
                        #define ROOMBA_WAKE_COUNT 10
                        int ddPin = 6;
                        
                        int rxPin = 3;
                        int txPin = 4;
                        int ledPin = 13;
                        
                        SoftwareSerial roomba(rxPin, txPin);
                        
                        const char SWITCH_NAMES[NUMBER_OF_FUNCTION][14] = { "Roomba-Stop","Roomba-Dock","Roomba-Clean","Roomba-Spot","Roomba-Max","Roomba-Power","Roomba-Play" };
                        const char SENSORS_NAMES[NUMBER_OF_SENSORS][24] = { "Roomba-Batt-Temp","Roomba-Batt-Proc","Roomba-Batt-Volt", "Roomba-Batt-mAH" , "Roomba-Batt-CHt" , "Roomba-Batt-CHs" };
                        
                        
                        uint8_t buf[52];
                        boolean lowBattery = true; // Acts as a debounce
                        long battery_Current_mAh = 0;
                        long battery_Total_mAh = 0;
                        long battery_percent = 0;
                        boolean DeadBattery = false;
                        boolean FullBattery = true;
                        unsigned long chargingState = 0;
                        long voltage = 0;
                        long temp = 0;
                        long OiMode = 0;
                        long ChargeSource = 0;
                        
                        long sensorfrequency = 300000; // 300000 = 5 min - frequency the sensors are read
                        long lastsensorread = 0; // when were the sensors read the last time
                        unsigned long lastsensorssend = 0;
                        
                        const char ChargeTypes[6][34] = { "Not charging","Reconditioning Charging","Full Charging","Trickle Charging","Waiting","Charging Fault Condition" };
                        const char OiTypes[4][14] = { "Off","Passive","Safe","Full" };
                        
                        int packetSizes[58] = {
                            0,0,0,0,0,0, //1-6
                            1,1,1,1,1,1,1,1,1,1,1,1, //7-18
                            2,2, //19-20
                            1, //21
                            2,2, //22-23
                            1, //24
                            2,2,2,2,2,2,2, //25-31
                            1, //32
                            2, //33
                            1,1,1,1,1, //34-38
                            2,2,2,2,2,2, //39-44
                            1, //45
                            2,2,2,2,2,2, //46-51
                            1,1, //52-53
                            2,2,2,2, //54-57
                            1 //58
                        };
                        #define bumpright (sensorbytes[0] & 0x01)
                        #define bumpleft  (sensorbytes[0] & 0x02)
                        
                        
                        MyMessage msg1_3(CHILD_ID_BATT_TEMP, V_TEMP); //status of Temperature
                        MyMessage msg1_4(CHILD_ID_BATT_PROC, V_PH); //status of Charge [%]
                        MyMessage msg1_2(CHILD_ID_BATT_VOLT, V_VOLTAGE); //status of Voltage
                        MyMessage msg2_5(CHILD_ID_BATT_AH, V_CURRENT); //status of mAH
                        MyMessage msg1_1(CHILD_ID_BATT_CHARGE_TYPE, V_TEXT); //status of charget type
                        MyMessage msg2_2(CHILD_ID_BATT_CHARGE_SOURCE, V_TEXT); //status of charger source
                        
                        void setup() {
                            pinMode(ddPin, OUTPUT);
                            digitalWrite(ddPin, LOW);
                            Serial.begin(115200);
                            while (!Serial) {
                                ; // wait for serial port to connect. Needed for native USB port only
                            }
                            roomba.begin(115200);
                            //Serial.println("Sending start command...");
                            //delay(1000);
                            //// set up ROI to receive commands
                            defsongs();
                            delay(500);
                            rstop();
                            Serial.println("Ready to go!");
                        }
                        
                        void presentation()
                        {
                            // Send the sketch version information to the gateway and Controller
                            sendSketchInfo("Roomba", "1.2");
                        
                            for (int sensor = 0; sensor < NUMBER_OF_FUNCTION; sensor++) {
                                // Register all sensors to gw (they will be created as child devices)
                                present(sensor, S_BINARY, SWITCH_NAMES[sensor]);
                                delay(100);
                            }
                            present(CHILD_ID_BATT_TEMP, S_TEMP, SENSORS_NAMES[0]); delay(100);
                            present(CHILD_ID_BATT_PROC, S_WATER_QUALITY, SENSORS_NAMES[1]); delay(100);
                            present(CHILD_ID_BATT_VOLT, S_MULTIMETER, SENSORS_NAMES[2]);    delay(100);
                            present(CHILD_ID_BATT_AH, S_MULTIMETER, SENSORS_NAMES[3]);  delay(100);
                            present(CHILD_ID_BATT_CHARGE_TYPE, S_INFO, SENSORS_NAMES[4]); delay(100);
                            present(CHILD_ID_BATT_CHARGE_SOURCE, S_INFO, SENSORS_NAMES[5]); delay(100);
                        }
                        
                        void loop() {
                            unsigned long now = millis();
                            if (now > lastsensorssend + sensorfrequency)
                            {
                                readsensors();
                                lastsensorssend = now;
                            }
                        }
                        
                        
                        void receive(const MyMessage &message) {
                          // We only expect one type of message from controller. But we better check anyway.
                          if (message.type == V_LIGHT) {
                            int mySensor = message.sensor;
                            int myComand = message.getBool();
                        
                            //Serial.print(message.sensor-1+RELAY_1);
                        
                            if (mySensor == 0) {
                              if (myComand == 1) {
                                Serial.println("Clean");
                                //clean();
                                rcommand(135);
                              }
                              else {
                                Serial.println("Stopp1");
                                //halt();
                                rstop();
                              }
                            }
                        
                            if (mySensor == 1) {
                              if (myComand == 1) {
                                Serial.println("dock");
                                //dock();
                                rcommand(143);
                              }
                              else {
                                Serial.println("Stopp2");
                                //halt();
                                rstop();
                              }
                            }
                            if (mySensor == 2) {
                              if (myComand == 1) {
                                Serial.println("song");
                                //dock();
                                rcommand(141);
                                rsong(0);
                              }
                              else {
                                Serial.println("Stopp2");
                                //halt();
                                rstop();
                              }
                            }
                        
                          }
                        }
                        
                        void halt() {
                          ;
                          roomba.write(131);  // SAFE
                          byte j = 0x00;
                          roomba.write(137);
                          roomba.write(j);
                          roomba.write(j);
                          roomba.write(j);
                          roomba.write(j);
                        }
                        
                        void dock() {
                          delay(1000);
                          roomba.write(143);
                        }
                        
                        void clean() {
                          delay(1000);
                          roomba.write(135);
                        }
                        
                        void rstop() {
                            if (rwakeup()) {
                                roomba.write(128);  delay(100);
                                roomba.write(131);  delay(100);
                                roomba.write(137);  delay(100);
                                byte j = 0x00;
                                roomba.write(j); delay(100);
                                roomba.write(j); delay(100);
                                roomba.write(j); delay(100);
                                roomba.write(j); delay(100);
                                roomba.write(128);
                            }
                        
                        }
                        
                        void rsong(int b) {
                            roomba.write(b); delay(100);
                        }
                        
                        
                        
                        void rcommand(int command) {
                            if (rwakeup()) {
                                roomba.write(128);  delay(100);
                                roomba.write(131);  delay(100);
                                roomba.write(command);
                            }
                        }
                        
                        void play(char note, int rlong) {
                            roomba.write(rnote(note));  delay(10);  roomba.write(64 / rlong);   delay(10);
                        }
                        
                        
                        bool rwakeup() {
                            bool ret = getSensors(6, buf, 52);
                            Serial.print("wakeup: ");
                            Serial.print(ret);
                            if (!ret) {
                                for (int ii = 1; ii < ROOMBA_WAKE_COUNT; ii++)
                                {
                                    for (int jj = 0; jj < 3; jj++) {
                                        digitalWrite(ddPin, HIGH); delay(10); 
                                        digitalWrite(ddPin, LOW); delay(2);
                                    }
                                    delay(100);
                                    roomba.write(128);
                                    if (getSensors(6, buf, 52)) {
                                        ret = true;
                                        break;
                                    }
                                    Serial.print("-");
                                }
                            }
                            Serial.println(ret);
                            return ret;
                        }
                        
                        bool getSensors(uint8_t packetID, uint8_t* dest, uint8_t len) {
                            roomba.write(142);
                            delay(100);
                            roomba.write(packetID);
                            delay(100);
                            return getData(dest, len);
                        }
                        
                        
                        bool getData(uint8_t* dest, uint8_t len)
                        {
                            while (len-- > 0)
                            {
                                unsigned long startTime = millis();
                                while (!roomba.available())
                                {
                                    // Look for a timeout
                                    if (millis() > startTime + ROOMBA_READ_TIMEOUT)
                                        return false; // Timed out
                                }
                                *dest++ = roomba.read();
                            }
                            return true;
                        }
                        
                        //for sensorgetting
                        int getPacketSize(int p) {
                            return packetSizes[p - 1];
                        }
                        int getPacketOffset(int p) {
                            int i = 0;
                            for (int s = 1; s < p; s++) {
                                i += getPacketSize(s);
                            }
                            return i;
                        }
                        
                        //read sensors
                        void readsensors()
                        {
                        
                            if (getSensors(6, buf, 52)) {
                        
                                int off = 0;
                        
                                // Battery Checks
                                off = getPacketOffset(21);
                                chargingState = buf[off + 0];
                                voltage = buf[off + 2] + 256 * buf[off + 1];
                                temp = buf[off + 5];
                                battery_Current_mAh = buf[off + 7] + 256 * buf[off + 6];
                                battery_Total_mAh = buf[off + 9] + 256 * buf[off + 8];
                        
                                if (battery_Total_mAh == 0) battery_Total_mAh = 1;
                                int nBatPcent = battery_Current_mAh * 100 / battery_Total_mAh;
                                battery_percent = nBatPcent;
                        
                                //Oi Mode
                                off = getPacketOffset(35);
                                OiMode = buf[off + 0];
                        
                                //ChargeSource
                                off = getPacketOffset(34);
                                ChargeSource = buf[off + 0];
                        
                        
                                send(msg1_3.set(temp));  delay(100);
                                send(msg1_4.set(battery_percent));  delay(100);
                                send(msg1_2.set(round(voltage / 10), 1));  delay(100);
                                send(msg2_5.set(battery_Current_mAh));  delay(100);
                                send(msg1_1.set(ChargeTypes[chargingState]));  delay(100);
                                send(msg2_2.set(ChargeSource));  delay(100);
                        
                                //send(msg2_5.set(chargingState));  // Send info value to gw
                                //send(msg2_5.set("charging state"));  // Send info value to gw
                                //send(msg2_5.set(battery_Total_mAh));  // Send info value to gw
                                //send(msg2_1.set(OiTypes[OiMode]));  // Send info value to gw
                                lastsensorread = millis();
                        
                            }
                            else { send(msg1_1.set("roomba is off")); }  // Send info value to gw
                        }
                        
                        void defsongs() {
                            uint8_t zero = 0;
                            roomba.write(128);  delay(100); roomba.write(131);  delay(100); //[128 131](Start the command stream and change roomba mode to "Safe" mode)
                            roomba.write(140);  delay(100); roomba.write(zero); delay(100); //[140 0](Start song definition and define the first song, song number 0)
                            roomba.write(25);   //[16](16 notes will be sent for song number 0)
                            play('E', 4);       //[76 16](play Mi sound for 1 / 4 seconds) // E
                            play('E', 4);
                            play('E', 2);
                            play('E', 4);
                            play('E', 4);
                            play('E', 2);       //[76 32](play Mi sound for 1 / 2 seconds)
                            play('E', 4);
                            play('G', 4);
                            play('C', 4);
                            play('D', 4);
                            play('E', 1);
                        
                            play('F', 4);
                            play('F', 4);
                            play('F', 2);
                        
                            play('F', 4);
                            play('E', 4);
                            play('E', 2);
                        
                            play('E', 4);
                            play('D', 4);
                            play('D', 4);
                            play('E', 4);
                            play('D', 1);
                            delay(100);
                            roomba.write(128);
                        }
                        
                        int rnote(char note) {
                            int command = 31;
                            switch (note) {
                            case 'C': command = 72; break;
                            case 'D': command = 74; break;
                            case 'E': command = 76; break;
                            case 'F': command = 77; break;
                            case 'G': command = 79; break;
                            }
                            return command;
                        }
                        
                        
                        Z Offline
                        Z Offline
                        zen85
                        wrote on last edited by zen85
                        #17
                        // Enable debug prints to serial monitor
                        #define MY_DEBUG
                        
                        // Enable and select radio type attached
                        #define MY_RADIO_NRF24
                        //#define MY_RADIO_RFM69
                        
                        // Enable repeater functionality for this node
                        #define MY_REPEATER_FEATURE
                        
                        #define CHILD_ID_BATT_TEMP          100  // Id of the 2nd msg1_3
                        #define CHILD_ID_BATT_PROC          101   // Id of the 2nd msg1_4
                        #define CHILD_ID_BATT_VOLT          102   // Id of the 2nd msg1_2
                        #define CHILD_ID_BATT_AH            103   // Id of the 2nd msg2_5
                        #define CHILD_ID_BATT_CHARGE_TYPE   104   // Id of the 2nd msg1_1
                        #define CHILD_ID_BATT_CHARGE_SOURCE 105   // Id of the 2nd msg2_2
                        
                        
                        #include <MySensors.h>
                        #include <SoftwareSerial.h>
                        
                        //#define RELAY_1  5  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
                        //#define NUMBER_OF_RELAYS 2 // Total number of attached relays
                        //#define RELAY_ON 1  // GPIO value to write to turn on attached relay
                        //#define RELAY_OFF 0 // GPIO value to write to turn off attached relay
                        
                        #define NUMBER_OF_FUNCTION 7 
                        #define NUMBER_OF_SENSORS 6
                        #define ROOMBA_READ_TIMEOUT 300
                        #define ROOMBA_WAKE_COUNT 10
                        int ddPin = 6;
                        
                        int rxPin = 3;
                        int txPin = 4;
                        int ledPin = 13;
                        
                        SoftwareSerial roomba(rxPin, txPin);
                        
                        const char SWITCH_NAMES[NUMBER_OF_FUNCTION][14] = { "Roomba-Stop","Roomba-Dock","Roomba-Clean","Roomba-Spot","Roomba-Max","Roomba-Power","Roomba-Play" };
                        const char SENSORS_NAMES[NUMBER_OF_SENSORS][24] = { "Roomba-Batt-Temp","Roomba-Batt-Proc","Roomba-Batt-Volt", "Roomba-Batt-mAH" , "Roomba-Batt-CHt" , "Roomba-Batt-CHs" };
                        
                        
                        uint8_t buf[52];
                        boolean lowBattery = true; // Acts as a debounce
                        long battery_Current_mAh = 0;
                        long battery_Total_mAh = 0;
                        long battery_percent = 0;
                        boolean DeadBattery = false;
                        boolean FullBattery = true;
                        unsigned long chargingState = 0;
                        long voltage = 0;
                        long temp = 0;
                        long OiMode = 0;
                        long ChargeSource = 0;
                        
                        long sensorfrequency = 300000; // 300000 = 5 min - frequency the sensors are read
                        long lastsensorread = 0; // when were the sensors read the last time
                        unsigned long lastsensorssend = 0;
                        
                        const char ChargeTypes[6][34] = { "Not charging","Reconditioning Charging","Full Charging","Trickle Charging","Waiting","Charging Fault Condition" };
                        const char OiTypes[4][14] = { "Off","Passive","Safe","Full" };
                        
                        int packetSizes[58] = {
                            0,0,0,0,0,0, //1-6
                            1,1,1,1,1,1,1,1,1,1,1,1, //7-18
                            2,2, //19-20
                            1, //21
                            2,2, //22-23
                            1, //24
                            2,2,2,2,2,2,2, //25-31
                            1, //32
                            2, //33
                            1,1,1,1,1, //34-38
                            2,2,2,2,2,2, //39-44
                            1, //45
                            2,2,2,2,2,2, //46-51
                            1,1, //52-53
                            2,2,2,2, //54-57
                            1 //58
                        };
                        #define bumpright (sensorbytes[0] & 0x01)
                        #define bumpleft  (sensorbytes[0] & 0x02)
                        
                        
                        MyMessage msg1_3(CHILD_ID_BATT_TEMP, V_TEMP); //status of Temperature
                        MyMessage msg1_4(CHILD_ID_BATT_PROC, V_PH); //status of Charge [%]
                        MyMessage msg1_2(CHILD_ID_BATT_VOLT, V_VOLTAGE); //status of Voltage
                        MyMessage msg2_5(CHILD_ID_BATT_AH, V_CURRENT); //status of mAH
                        MyMessage msg1_1(CHILD_ID_BATT_CHARGE_TYPE, V_TEXT); //status of charget type
                        MyMessage msg2_2(CHILD_ID_BATT_CHARGE_SOURCE, V_TEXT); //status of charger source
                        
                        void setup() {
                            pinMode(ddPin, OUTPUT);
                            digitalWrite(ddPin, LOW);
                            Serial.begin(115200);
                            while (!Serial) {
                                ; // wait for serial port to connect. Needed for native USB port only
                            }
                            roomba.begin(115200);
                            //Serial.println("Sending start command...");
                            //delay(1000);
                            //// set up ROI to receive commands
                            defsongs();
                            delay(500);
                            rstop();
                            Serial.println("Ready to go!");
                        }
                        
                        void presentation()
                        {
                            // Send the sketch version information to the gateway and Controller
                            sendSketchInfo("Roomba", "1.2");
                        
                            for (int sensor = 0; sensor < NUMBER_OF_FUNCTION; sensor++) {
                                // Register all sensors to gw (they will be created as child devices)
                                present(sensor, S_BINARY, SWITCH_NAMES[sensor]);
                                delay(100);
                            }
                            present(CHILD_ID_BATT_TEMP, S_TEMP, SENSORS_NAMES[0]); delay(100);
                            present(CHILD_ID_BATT_PROC, S_WATER_QUALITY, SENSORS_NAMES[1]); delay(100);
                            present(CHILD_ID_BATT_VOLT, S_MULTIMETER, SENSORS_NAMES[2]);    delay(100);
                            present(CHILD_ID_BATT_AH, S_MULTIMETER, SENSORS_NAMES[3]);  delay(100);
                            present(CHILD_ID_BATT_CHARGE_TYPE, S_INFO, SENSORS_NAMES[4]); delay(100);
                            present(CHILD_ID_BATT_CHARGE_SOURCE, S_INFO, SENSORS_NAMES[5]); delay(100);
                        }
                        
                        void loop() {
                            unsigned long now = millis();
                            if (now > lastsensorssend + sensorfrequency)
                            {
                                readsensors();
                                lastsensorssend = now;
                            }
                        }
                        
                        
                        void receive(const MyMessage &message) {
                          // We only expect one type of message from controller. But we better check anyway.
                          if (message.type == V_LIGHT) {
                            int mySensor = message.sensor;
                            int myComand = message.getBool();
                        
                            //Serial.print(message.sensor-1+RELAY_1);
                        
                            if (mySensor == 0) {
                              if (myComand == 1) {
                                Serial.println("Clean");
                                //clean();
                                rcommand(135);
                              }
                              else {
                                Serial.println("Stopp1");
                                //halt();
                                rstop();
                              }
                            }
                        
                            if (mySensor == 1) {
                              if (myComand == 1) {
                                Serial.println("dock");
                                //dock();
                                rcommand(143);
                              }
                              else {
                                Serial.println("Stopp2");
                                //halt();
                                rstop();
                              }
                            }
                            if (mySensor == 2) {
                              if (myComand == 1) {
                                Serial.println("song");
                                //dock();
                                rcommand(141);
                                rsong(0);
                              }
                              else {
                                Serial.println("Stopp2");
                                //halt();
                                rstop();
                              }
                            }
                        
                          }
                        }
                        
                        void halt() {
                          ;
                          roomba.write(131);  // SAFE
                          byte j = 0x00;
                          roomba.write(137);
                          roomba.write(j);
                          roomba.write(j);
                          roomba.write(j);
                          roomba.write(j);
                        }
                        
                        void dock() {
                          delay(1000);
                          roomba.write(143);
                        }
                        
                        void clean() {
                          delay(1000);
                          roomba.write(135);
                        }
                        
                        void rstop() {
                            if (rwakeup()) {
                                roomba.write(128);  delay(100);
                                roomba.write(131);  delay(100);
                                roomba.write(137);  delay(100);
                                byte j = 0x00;
                                roomba.write(j); delay(100);
                                roomba.write(j); delay(100);
                                roomba.write(j); delay(100);
                                roomba.write(j); delay(100);
                                roomba.write(128);
                            }
                        
                        }
                        
                        void rsong(int b) {
                            roomba.write(b); delay(100);
                        }
                        
                        
                        
                        void rcommand(int command) {
                            if (rwakeup()) {
                                roomba.write(128);  delay(100);
                                roomba.write(131);  delay(100);
                                roomba.write(command);
                            }
                        }
                        
                        void play(char note, int rlong) {
                            roomba.write(rnote(note));  delay(10);  roomba.write(64 / rlong);   delay(10);
                        }
                        
                        
                        bool rwakeup() {
                            bool ret = getSensors(6, buf, 52);
                            Serial.print("wakeup: ");
                            Serial.print(ret);
                            if (!ret) {
                                for (int ii = 1; ii < ROOMBA_WAKE_COUNT; ii++)
                                {
                                    for (int jj = 0; jj < 3; jj++) {
                                        digitalWrite(ddPin, HIGH); delay(10); 
                                        digitalWrite(ddPin, LOW); delay(2);
                                    }
                                    delay(100);
                                    roomba.write(128);
                                    if (getSensors(6, buf, 52)) {
                                        ret = true;
                                        break;
                                    }
                                    Serial.print("-");
                                }
                            }
                            Serial.println(ret);
                            return ret;
                        }
                        
                        bool getSensors(uint8_t packetID, uint8_t* dest, uint8_t len) {
                            roomba.write(142);
                            delay(100);
                            roomba.write(packetID);
                            delay(100);
                            return getData(dest, len);
                        }
                        
                        
                        bool getData(uint8_t* dest, uint8_t len)
                        {
                            while (len-- > 0)
                            {
                                unsigned long startTime = millis();
                                while (!roomba.available())
                                {
                                    // Look for a timeout
                                    if (millis() > startTime + ROOMBA_READ_TIMEOUT)
                                        return false; // Timed out
                                }
                                *dest++ = roomba.read();
                            }
                            return true;
                        }
                        
                        //for sensorgetting
                        int getPacketSize(int p) {
                            return packetSizes[p - 1];
                        }
                        int getPacketOffset(int p) {
                            int i = 0;
                            for (int s = 1; s < p; s++) {
                                i += getPacketSize(s);
                            }
                            return i;
                        }
                        
                        //read sensors
                        void readsensors()
                        {
                        
                            if (getSensors(6, buf, 52)) {
                        
                                int off = 0;
                        
                                // Battery Checks
                                off = getPacketOffset(21);
                                chargingState = buf[off + 0];
                                voltage = buf[off + 2] + 256 * buf[off + 1];
                                temp = buf[off + 5];
                                battery_Current_mAh = buf[off + 7] + 256 * buf[off + 6];
                                battery_Total_mAh = buf[off + 9] + 256 * buf[off + 8];
                        
                                if (battery_Total_mAh == 0) battery_Total_mAh = 1;
                                int nBatPcent = battery_Current_mAh * 100 / battery_Total_mAh;
                                battery_percent = nBatPcent;
                        
                                //Oi Mode
                                off = getPacketOffset(35);
                                OiMode = buf[off + 0];
                        
                                //ChargeSource
                                off = getPacketOffset(34);
                                ChargeSource = buf[off + 0];
                        
                        
                                send(msg1_3.set(temp));  delay(100);
                                send(msg1_4.set(battery_percent));  delay(100);
                                send(msg1_2.set(round(voltage / 10), 1));  delay(100);
                                send(msg2_5.set(battery_Current_mAh));  delay(100);
                                send(msg1_1.set(ChargeTypes[chargingState]));  delay(100);
                                send(msg2_2.set(ChargeSource));  delay(100);
                        
                                //send(msg2_5.set(chargingState));  // Send info value to gw
                                //send(msg2_5.set("charging state"));  // Send info value to gw
                                //send(msg2_5.set(battery_Total_mAh));  // Send info value to gw
                                //send(msg2_1.set(OiTypes[OiMode]));  // Send info value to gw
                                lastsensorread = millis();
                        
                            }
                            else { send(msg1_1.set("roomba is off")); }  // Send info value to gw
                        }
                        
                        void defsongs() {
                            uint8_t zero = 0;
                            roomba.write(128);  delay(100); roomba.write(131);  delay(100); //[128 131](Start the command stream and change roomba mode to "Safe" mode)
                            roomba.write(140);  delay(100); roomba.write(zero); delay(100); //[140 0](Start song definition and define the first song, song number 0)
                            roomba.write(25);   //[16](16 notes will be sent for song number 0)
                            play('E', 4);       //[76 16](play Mi sound for 1 / 4 seconds) // E
                            play('E', 4);
                            play('E', 2);
                            play('E', 4);
                            play('E', 4);
                            play('E', 2);       //[76 32](play Mi sound for 1 / 2 seconds)
                            play('E', 4);
                            play('G', 4);
                            play('C', 4);
                            play('D', 4);
                            play('E', 1);
                        
                            play('F', 4);
                            play('F', 4);
                            play('F', 2);
                        
                            play('F', 4);
                            play('E', 4);
                            play('E', 2);
                        
                            play('E', 4);
                            play('D', 4);
                            play('D', 4);
                            play('E', 4);
                            play('D', 1);
                            delay(100);
                            roomba.write(128);
                        }
                        
                        int rnote(char note) {
                            int command = 31;
                            switch (note) {
                            case 'C': command = 72; break;
                            case 'D': command = 74; break;
                            case 'E': command = 76; break;
                            case 'F': command = 77; break;
                            case 'G': command = 79; break;
                            }
                            return command;
                        }
                        

                        i love this project. i am the owner of a roomba 620 and hooked it up to a arduino-mega. putting "clean()" in the code does what it should and the radiomodules are working fine. but it seems that i dont get values from the sensors and so nothing is showing up in homeassistant... :(

                        i checked the wiring about 5 times already and since starting for example "clean()" works i think it is a different issue...

                        did anyone else try this and ran into the same problem?

                        1 Reply Last reply
                        0
                        • B Offline
                          B Offline
                          banda banda
                          Banned
                          wrote on last edited by mfalkvidd
                          #18

                          there is plenty of space for a nano or pro mini. wemos mini or nodemcu should also fit
                          (spam links removed by moderator)

                          1 Reply Last reply
                          0
                          Reply
                          • Reply as topic
                          Log in to reply
                          • Oldest to Newest
                          • Newest to Oldest
                          • Most Votes


                          13

                          Online

                          11.7k

                          Users

                          11.2k

                          Topics

                          113.1k

                          Posts


                          Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                          • Login

                          • Don't have an account? Register

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • MySensors
                          • OpenHardware.io
                          • Categories
                          • Recent
                          • Tags
                          • Popular