Roboclaw library, proper syntax to get a reading of motor home status

There are lots of examples in the latest Roboclaw Arduino Library, but none of them show how to get these status bits. The one function,


uint16_t ReadError(uint8_t address,bool *valid=NULL);


gets a lot of different data from the roboclaw. Page 59 of The roboclaw user manual shows this:


90 - Read Status
Read the current unit status.
Send: [Address, 90]
Receive: [Status, CRC(2 bytes)]

Function Status Bit Mask

Normal 0x0000
M1 OverCurrent Warning 0x0001
M2 OverCurrent Warning 0x0002
E-Stop 0x0004
Temperature Error 0x0008
Temperature2 Error 0x0010
Main Battery High Error 0x0020
Logic Battery High Error 0x0040
Logic Battery Low Error 0x0080
M1 Driver Fault 0x0100
M2 Driver Fault 0x0200
Main Battery High Warning 0x0400
Main Battery Low Warning 0x0800
Temperature Warning 0x1000
Temperature2 Warning 0x2000
M1 Home 0x4000
M2 Home 0x8000

There's a number of this information I need. If someone could help me get the code syntax to check just one of these, may M1 Home, then I should be able to figure out how to do the others.

Here's my feeble attempt at it. (I added the & sign, 3rd line from the end, but not sure if it should be there).

#include <SoftwareSerial.h>
#include "RoboClaw.h"
SoftwareSerial serial(10, 11);
RoboClaw roboclaw(&serial, 10000);
#define address 0x80

void setup() {
  Serial.begin(57600);
  roboclaw.begin(38400);
}

void loop() {
  if (M1_IsHome) Serial.println("M1 is home");

  delay(1000);
}

boolean M1_IsHome() { //return true if M1 microswitch is pressed
  bool valid;
  uint16_t reading = roboclaw.ReadError(address, &valid);
  //get the bits out
  //return true if M1 is home
}

To help, here's an example from the library on reading an encoder:

#include <SoftwareSerial.h>
#include "RoboClaw.h"
SoftwareSerial serial(10,11);	
RoboClaw roboclaw(&serial,10000);
#define address 0x80

void setup() {
  Serial.begin(57600);
  roboclaw.begin(38400);
}

void loop() {
  uint8_t status1;
  bool valid1;
  int32_t enc1= roboclaw.ReadEncM1(address, &status1, &valid1);
  Serial.print("Encoder1:");
  if(valid1){
    Serial.print(enc1,HEX);
    Serial.print(" ");
    Serial.print(status1,HEX);
    Serial.print(" ");
  }
  else{
    Serial.print("invalid ");
  }
  delay(1000);
}

There is the address of the data you want to read (90). The readError() function reads from a different address from the readEndM1() method. The readError() function takes a second argument that has a default value of NULL. The argument is a pointer to where to write some additional data.

The important data is returned by the function, as an unsigned int that you would mask with the constants shown to determine if a particular condition is set or clear. If the return value is 0, everything is OK. Otherwise there are one or more problems being reported.

There is the address of the data you want to read (90). The readError() function reads from a different address from the readEndM1() method. The readError() function takes a second argument that has a default value of NULL. The argument is a pointer to where to write some additional data.

I understand this part.

you would mask with the constants shown

I kinda understand what needs done, but I don't know how to do it. Can you show me an example or point me to where to find more help on this? I've read the arduino reference on bits, shifting in and out bits. I'm not sure if this is what you mean or not. :frowning:

I'm not sure if this is what you mean or not.

Look at the documentation for the & operator.

   if(outData & 0x0001)
   {
      // Ouch, that was hot. Check motor 1...
   }

Thanks Paul! I got it! I just barely can see how it works. Bit 0X400 has to be set (turned on) for both reading AND 0X4000 to be true on the bit level.
I've got:

boolean M1_IsHome() { //return true if M1 microswitch is pressed
  bool valid;
  if (valid) {
    uint16_t reading = roboclaw.ReadError(address, &valid);
    if (reading && 0x4000) return true; //0x4000 is the M1 home bit
  }
}
    if (reading && 0x4000) return true; //0x4000 is the M1 home bit

That is the logical AND, not the bitwise AND. You want to use the bitwise and when masking.

Oh yes, I missed that! Thanks again.

boolean M1_IsHome() { //return true if M1 microswitch is pressed
  bool valid;
  if (valid) {
    uint16_t reading = roboclaw.ReadError(address, &valid);
    if (reading & 0x4000) return true; //0x4000 is the M1 home bit
  }
}

M1 home is 0X4000
M2 home is 0x8000

So if I wanted a function to return TRUE is both motors are home I could just change the one line to:

   if (reading & 0x4000 & 0X8000) return true; //both motors are home

I won't be able to test my sketch until tomorrow, but I think this it correct?