Reading position data from absolute encoder in BiSS C

I'm currently working with the BiSS protocol using the GPIO pins on a Teensy 4.0 and RLS Encoder (18bit), While I’m able to read data from the encoder, the output isn’t consistently reliable the status LED remains green, indicating valid communication, but I'm unable to parse the data correctly. I suspect the issue might be related to timing, either when reading the data or setting the clock signal.Any help here is appreciated! and attached the sample code to read from encoder.

Using BiSS Protocal (Bit Banging) and TEENSY4.0 GPIO pins to provide clock and receive the data from encoder (18bit resolution, single turn encoder)//MB029 readhead

#include <digitalWriteFast.h>

#define pin_MAP 9 //(+)
#define pin_MAM 2 // (-)
#define pin_SLOP 0 //(+)
#define pin_SLOM 1// (-)

#define baud 9600

void setup(){
   Serial.begin(9600);
   pinModeFast(pin_MAP, OUTPUT);
   pinModeFast(pin_SLOP, INPUT);
   pinModeFast(pin_MAM, OUTPUT);
   pinModeFast(pin_SLOM, INPUT);

   digitalWriteFast(pin_MAP, HIGH); //HIGH
   digitalWriteFast(pin_MAM, LOW);  

//initially both the lines are high
   digitalWriteFast(pin_MAP, HIGH); //HIGH
   digitalWriteFast(pin_MAM, LOW);

}

uint64_t readBiSS() {

   uint64_t data = 0;

   digitalWriteFast(pin_MAP, LOW);//LOW
   digitalWriteFast(pin_MAM, HIGH);

   digitalWriteFast(pin_MAP, HIGH);//HIGH
   digitalWriteFast(pin_MAM, LOW);

   for(int i = 0; i < 64; i++) {
      digitalWriteFast(pin_MAP, LOW);//LOW
      digitalWriteFast(pin_MAM, HIGH);

      //delayNanoseconds(100);

      digitalWriteFast(pin_MAP, HIGH);//HIGH
      digitalWriteFast(pin_MAM, LOW); 

      delayNanoseconds(170); //response time

      data <<= 1;
      if (digitalReadFast(pin_SLOP) == 1 && digitalReadFast(pin_SLOM) == 0) {
  
           data |= 1;
      }

    }
   delayNanoseconds(100);
   return data;
}

void loop(){

   uint64_t sampled_data =  readBiSS();

   for(int i = 64;i > 0;i--)
   {
      Serial.print(((sampled_data >> i) & 0x1));
   }
   Serial.println();//delay(10);
}

Please read the forum guide to understand how to post code correctly so that it is readable for others. The guide will tell you what other things you need to post.

Thanks, that's much better, but we seem to have lost the indentation.

delayNanoseconds() provides approximate delays based on CPU cycles but cannot guarantee precise nanosecond accuracy due to interrupt handling, instruction pipeline, and other system activities. It is intended for very short delays but not for exact timing critical applications like high-speed synchronous protocols.

➜ So I would explore unstable clock timing in the bit-banged code, where delayNanoseconds() cannot guarantee precise, jitter-free timing, causing data to be sampled too early or too late (unequal delays can shift the sample point out of the valid data window, flipping bits despite valid communication).

Have you explored using hardware timers ?

Thanks for your response, i didn’t explored using hardware timers.

Thanks for correcting you code formatting and indentation, but is your problem solved now? Because you have marked this topic as solved.

No, sorry its not solved yet, i tried with hardware timers also, still i am not getting the reliable data to parsing.

Then why did you mark it as solved?

Forum members who might help you will not even read the Topic if it is marked as solved.

You should unmark it.

Please post a link to the encoder product page or data sheet.

Please find attachment for Encoder Datasheet (MB029 readhead, 18bit resolution, single turn, BiSS protocol).

https://www.rls.si/eng/fileuploader/download/download/?d=1&id=267&title=Data+sheet%3A+AksIM-2%E2%84%A2+off-axis+rotary+absolute+magnetic+encoder+%28MBD01%29

It does not look like your code follows the BiSS protocol discussed in the datasheet.

BiSS protocol comes up from time to time on the forum, but I don't recall anyone reporting success.

Hello rohan_hc

Use the forum search engine to get some additional ideas simply.

And this information:

i am not using RS422, directly using Teensy4.0 GPIO pins to create the clock as well as to read the data from Encoder.

By using GPIO pins i am creating the clock and reading the data from encoder, but not getting the expected output as in timing diagram. as of now i am just reading the output data by creating the clock.

Below is the 64 bit output i am getting from Encoder.

09:36:40.486 -> 1111111110000001000011110011001100110010111010001110100001100111
09:36:40.486 -> 1111111110000001000011110011000111111111111111000000100001111001
09:36:40.486 -> 1111111110000001000011110011000110000001000011110011000111111111
09:36:40.486 -> 1111111110000001000011110011001000000110111010000110011100110010
09:36:40.486 -> 1111111110000001000011110011001100110010010010100100101100001111
09:36:40.486 -> 1111111110000001000011110011001100110010010010100100101100001111
09:36:40.486 -> 1111111110000001000011110011000110000000010000111100110011001100
09:36:40.486 -> 1111111110000001000011110011001100110010010010100100101100001111
09:36:40.486 -> 1111111110000001000011110011000110000001000011110011001100110010
09:36:40.486 -> 1111111110000001000011110011001100110010010010100100101100001111
09:36:40.486 -> 1100000001000011110011001100110010010010100100101100001111001100

Very bad idea. The Teensy output pins are limited to less than 10 mA and can't handle the current required for a bus with 120 Ohm line impedance.

That is an expensive, high quality encoder, so get serious about this project and invest in a proper RS422 interface.

My cable length is just 5 inches and for this length termination is not required as mentioned in data sheet.

Termination at the controller is required, if total cable length is longer than 5 m. The nominal impedance of the cable should
be 120 Ω.

Continuing down this path will probably damage the Teensy.

Good luck with your project.

If you can switch to a Teensy 4.1, you could potentially use its FlexIO peripheral to generate the BiSS clock and capture the data in hardware, avoiding the timing jitter caused by delayNanoseconds and keeping the sample point stable.

Alternatively, as suggested, adding RS-422 line receivers to your current setup could improve signal integrity and reduce bit errors even without changing the timing method. (With only a 5-inch cable, RS-422 receivers are less about overcoming long-distance noise and more about ensuring proper differential signal termination and conversion to clean logic levels, which can still help reduce subtle skew or threshold issues that cause bit errors.)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.