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.
  • E Offline
    E Offline
    Eoreh
    wrote on last edited by
    #6

    HI !.
    @EmielA said:

    With this approach you don't need to put anything on top of the Roomba which wil get broken off (is my experience) when its e.g. working under the bench.

    I have only 1 dock station and many rooms :). My roomba dont going "under the bench" so i dont have experience like yours with sensor on top.

    But will be interested looks for code in your approach so please show it.

    Thank You.

    1 Reply Last reply
    0
    • 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


                            14

                            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