This is my first foray into using Arduino beyond the simple LED example, so I'm very inexperienced with all of this. I am using an Arduino UNO.
Sorry for the novel, just want to provide relevant information and explain what I've tried already.
Encoder data sheet (MB029 readhead, 17 bit resolution w/ multiturn counter).
Also using this RS422/TTL conversion module.
With everything connected, I'm just trying to get reasonable data back from the encoder. I am reading the data bits while the clock is LOW (code pasted at end of post), and I'm just getting "10101010..." for the total 43 bits I read. My code reads the different bits into different variables based on what number they are (eg. first bit comes in as the first bit for the multiturn counter, 17th bit comes in as first bit for encoder position, etc.). The encoder has an LED onboard to help debug problems but it stays solid green, so it thinks everything is just dandy.
My guess is the problem is either with the code, the overall configuration, or the Arduino boards I've used (swapped out another board, still didn't work). I'll start with explaining my configuration.
My setup is wired as follows:
Clock signal:
Arduino pin 4 -> conversion module (CM) Rxd pin
CM Y pin (or T+) -> encoder clock +
CM Z pin (or T-) -> encoder clock -
Data signal:
Arduino pin 2 -> CM Txd pin
CM A pin (or R+) -> encoder data +
CM B pin (or R-) -> encoder data -
I have checked with a multimeter that both the encoder and the CM are getting 5V. All grounds are on the same ground bus connected to one of Arduino's ground pins. I doubt my problem is here, but if there's something wrong I'd appreciate a heads up.
For swapping out boards, I have the UNO I'm using as well as an Arduino 101 on hand that I could try out. Neither produced sane data, but I have oscilloscope probes attached to CM Rxd and Txd pins to monitor the signals going in and out. When I was doing a simple clock frequency check with the following code
const int c = 4;
const int del = 4;
void setup() {
pinMode(c, OUTPUT);
pinMode(2, INPUT);
Serial.begin(250000);
digitalWrite(c, HIGH);
}
void loop() {
digitalWrite(c, LOW);
delayMicroseconds(del);
digitalWrite(c, HIGH);
delayMicroseconds(del);
}
I found that the generated signal from my bit-banging never agreed with what I coded in. For example, the above code has a clock period of 8 microseconds (4 high, 4 low), but the oscilloscope shows a period of 12.4 microseconds (6.2 high, 6.2 low). It's also showing faint flickering reciprocal signals on the same line. Inexperience makes me unsure of how (ab)normal that is.
Can the timing discrepancy cause issues? I didn't think it would as long as it's consistent.
And lastly, my code.
First, is there some way to store all 43 bits in one variable? All I could find is using unsigned long, but that has a max of 32. I'm worried that my current method of parsing out the bits to multiturn, encoder, general status and detailed status is messing with the overall performance. I don't know how else to get and store all the bits though.
Second, when I open serial monitor I see that sometimes the encoder variable has one more bit than it should and both the general and detailed status variables have one less bit than they should. Does anyone know/see why this is happening?
Third, when I decrease the clock period/increase clock frequency, all the bits read as 1. I have no idea what that could indicate, but it seems significant.
To finally end, is there anything wrong with my code in general? Is there a simpler or better way of doing this?
Thank you very much for any help you can offer.
const int CLOCK = 4;
const int DATA = 2;
const int BIT_COUNT = 42 + 1; //CAREFUL CHANGING THIS, MAY CAUSE PROBLEMS WITH BIT ORGANIZATION
void setup() {
pinMode(CLOCK, OUTPUT);
pinMode(DATA, INPUT);
digitalWrite(CLOCK, HIGH); //Initialize clock signal as HIGH
delay(200); //Data sheet instructs to leave time for the power supply to apply before sending clock sequence
Serial.begin(250000);
}
// Clock cycles to retrieve encoder data
void loop() {
digitalWrite(CLOCK, LOW); //Start with "Delay First Clock" cycle
delayMicroseconds(5);
unsigned long multi = 0;
unsigned long enc = 0;
unsigned long G_status = 0;
unsigned long D_status = 0;
//Create clock pulse to start data transmission
for (int i=0; i<BIT_COUNT; i++) {
digitalWrite(CLOCK, HIGH);
delayMicroseconds(4);
digitalWrite(CLOCK, LOW);
//Write data into seperate variables for BIT ORGANIZATION
if (i < 16) {
multi <<= 1;
multi |= digitalRead(DATA);
delayMicroseconds(4);
}
else if(i > 15 && i < 33) {
enc <<= 1;
enc |= digitalRead(DATA);
delayMicroseconds(4);
}
else if(i > 32 && i < 35) {
G_status <<= 1;
G_status |= digitalRead(DATA);
delayMicroseconds(4);
}
else {
D_status <<= 1;
D_status |= digitalRead(DATA);
delayMicroseconds(4);
}
}
//Begin printing status and encoder position
Serial.println();
Serial.println("Multiturn bits: ");
Serial.println(multi, BIN);
Serial.println("Encoder bits: ");
Serial.println(enc, BIN);
Serial.println("General status bits: ");
Serial.println(G_status, BIN);
Serial.println("Detailed status bits: ");
Serial.println(D_status, BIN);
Serial.println();
//Start monoflop time to reset transmission cycle
digitalWrite(4, HIGH);
delayMicroseconds(20);
//Optional delay before next reading
delay(5);
//delayMicroseconds(1000);
}