I'm working on a project that involves using an absolute encoder to give position feedback from a stepper motor. The absolute encoder being used is as follows:
POSITAL KCD-BC33B-1617-F7SW-JAQ
I've tried using RS485 boards/RS422 to TTL boards, and some other options of directly trying to read the data off the encoder on the arduino but have had absolutely zero luck. Does anyone who has any experience with this have any advice where to go from here? The encoder sends in bits of: 16 multiturn bits, 17 singleturn bits, 1 error bit, 1 warning bit, and 6 crc bits. The closest I've gotten is being able to getsome form of data output from the encoder however no matter how I move the motor, the data doesn't actually change, as I'll show in a screenshot below. Any help here is appreciated!
// Define pins for CLK+/- and DATA+/- connections
const int CLK_PIN = 2;
const int CLK_NEG_PIN = 3;
const int DATA_PIN = 4;
const int DATA_NEG_PIN = 5;
// Variables for storing BiSS-C data
uint16_t multi_turn_value;
uint16_t single_turn_value;
bool error_flag;
bool warning_flag;
uint8_t crc_value;
// State variables
bool ack_received = false;
bool data_ready = false;
bool receiving_data = false;
bool data_timeout = false;
// Setup function
void setup() {
// Initialize serial communication for debugging
Serial.begin(115200);
// Configure pins for input
pinMode(CLK_PIN, INPUT);
pinMode(CLK_NEG_PIN, INPUT);
pinMode(DATA_PIN, INPUT);
pinMode(DATA_NEG_PIN, INPUT);
}
// Main loop
void loop() {
// Wait for start of BiSS-C frame (MA = 0, SLO = 1)
waitForFrameStart();
// Read BiSS-C data frame
readBISSC();
// Process the decoded data
if (data_ready) {
// Print decoded data for debugging
Serial.print("Multi-turn value: ");
Serial.println(multi_turn_value);
Serial.print("Single-turn value: ");
Serial.println(single_turn_value);
Serial.print("Error flag: ");
Serial.println(error_flag);
Serial.print("Warning flag: ");
Serial.println(warning_flag);
Serial.print("CRC value: ");
Serial.println(crc_value);
// Reset flags for next frame
ack_received = false;
data_ready = false;
receiving_data = false;
data_timeout = false;
// Delay or perform other operations as needed
delay(1000);
}
}
// Function to wait for the start of BiSS-C frame
void waitForFrameStart() {
// Wait for MA = 0 and SLO = 1 (start of frame)
while (digitalRead(CLK_PIN) == HIGH || digitalRead(DATA_PIN) == LOW) {
// Wait until MA = 0 and SLO = 1
}
}
// Function to read BiSS-C data frame
void readBISSC() {
// Variables for data bits
uint32_t data_bits = 0;
// Read the BiSS-C data frame
for (int i = 0; i < 41; ++i) { // 42 bits total (16 + 17 + 1 + 1 + 6)
data_bits |= (digitalRead(DATA_PIN) << i);
delayMicroseconds(50); // Adjust delay as per your encoder's timing
}
// Decode the received bits according to the BiSS-C protocol
multi_turn_value = (data_bits >> 16) & 0xFFFF;
single_turn_value = (data_bits >> 17) & 0xFFFF;
error_flag = (data_bits >> 1) & 0x01;
warning_flag = (data_bits >> 1) & 0x01;
crc_value = data_bits & 0x3F;
// Validate CRC if needed (CRC calculation not detailed here)
// Set data_ready flag indicating data is ready for processing
data_ready = true;
}
Yes I did, though when I was scouring forums I saw the people who had the same problem of having an encoder that communicates in BiSS C, they used two RS485 boards for clock and data and used them to convert to SPI protocol, which I've had no luck with
Where did you find that code? It does not appear to agree with the Biss C protocol description in the encoder data sheet, and is unlikely to do anything useful. It does not appear to transmit a clock signal.
I suggest to spend some time carefully studying the protocol timing diagram. Note the ACK, which has variable timing, so those 50 us delays are useless.
Me and the OP are working together on this project. We have different codes just to see who can get the encoder working. My code shows that the encoder latches in the output but it has the same error on bit 24 and 26. I have not parsed the data yet since we still have issues getting reliable data. It should latch with a differential 01 then go into the data frame.
So my partner @zjlaw and I are working together on this project. We have different codes just to see who can get the encoder working. His code shows that the encoder latches in the output but it has the same error on bit 24 and 26. He hasn't parsed the data yet since we still have issues getting reliable data. It should latch with a differential 01 then go into the data frame.
Looks like you two need to work together before posting.
One forum thread is not going to work to sort out all the errors in two completely different approaches.
BTW for debugging interface problems like this, nothing beats these cheap logic analyzers, available in many outlets, when used with free PulseView software:
Thanks' for the advice about the logic analyzers, we'll definitely give it a go and try it out! So to clear up the confusion caused, the code I had posted in my original post was more of a shot in the dark to try and just get some data output, my partners code is the one that we have found to give better results as shown that we are able to get the encoder to latch, however this approach involves having to build up the protocol from the ground up. The main struggle we are having is no matter what method, we've been unable to get any data that's being output to change when the motor shaft is moved, it's always consistently just staying the same, and we both are very lost on where to go from here. Do you suggest that logic analyzer could help us understand with figuring out how to get to that point? I haven't worked with those before.
Since that code appears to transmit a clock signal, it has a chance of working. But drop the use of Strings, as they cause memory problems and crashes on Arduinos with limited memory.
Not enough information has been given, like a complete wiring diagram (hand drawn is preferred), with pins, connections and parts clearly labeled. Post a link to the interface transmitter, if you are using one. If not, then all bets are off.
See the "How to get the best out of this forum" post for more instructions.
I have not found a useful example of anyone implementing a complete Biss-C interface with Arduino. The companies making gadgets that use Biss-C apparently expect customers to buy their proprietary interfaces and control software.
This synchronous communications may be just like the synchronous of the 1970-1990 time period. The transmitter will send a bit when the clock signal goes high. But the receiver must wait one half clock period before making the decision if the received bit is high or low.