I am absolutely novice at Arduino. I am trying to control a PiezoElectric motor with Arduino Uno. Arduino is communicating with the company provided motor driver through SPI.
There are 02 16bit Control registers in the driver. I want to initialize the registers with following values to start the motor at a particular speed:
There is another register to read the encoder status but it is not required yet.
I am sending 04 bytes one by one but I don't know which byte to send first and which register will it go to.
Here is the link to the Manual by the company :
(==>page 5,7,8)
I tried the following code but motor doesn't start:
Many devices let you set consecutive registers in a single transaction but I don't know if your device will do that. You may need to write the two registers separately:
Thanks for your response. I tried both of the approaches you suggested. It didn't work. To verify what was sent to registers, I added the following additional snippet (after first transfer) to read and print it later:
digitalWrite(CS, LOW);
SPI.transfer(control_1);
byte A = SPI.transfer(c11);
byte B = SPI.transfer(c12);
digitalWrite(CS, HIGH);
digitalWrite(CS, LOW);
SPI.transfer(control_2);
byte C = SPI.transfer(c21);
byte D = SPI.transfer(c22);
digitalWrite(CS, HIGH);
Serial.println(A,BIN);
Serial.println(B,BIN);
Serial.println(C,BIN);
Serial.println(D,BIN);
Motor doesn't start and serial monitor output is still unchanged.
I changed c11,c12,c21,c22 values to random numbers but still the serial monitor shows the same output. As if data is not being delivered to registers and we are just reading the pre-stored values.
The data sheet of the driver has given the format how to send Header and Data. I have followed that to the level of my understanding. Please check the wiring between UNO and the connector of the driver and also the Device ID selection switch.
Thanks for your effort to go through the datasheet. I double checked this already and connections and switches are according to the instructions given.
Thank you so much. This code worked and system is finally running.
Could you please explain three lines of WriteRegister16 function. I don't understand how | and & are helping here and where do 0x80 and 0xFF come from. Also shouldn't we shift our bits to the left (using<<) for MSB ?
It'll help me modify my code.
// Set the top bit of the Address to indicate a WRITE
SPI.transfer(Address | 0x80);
// Send MSB first
SPI.transfer(Data >> 8); // MSB
// Then send LSB
SPI.transfer(Data & 0xFF); // LSB
Read:
// Clear the top bit of the Address to indicate READ
SPI.transfer(Address & 0x7F);
// Read the MSB first
data = SPI.transfer(0); // MSB
// Move the MSB left to the top 8 bits
data <<= 8;
// Read the LSB
data |= SPI.transfer(0); // LSB
0x80 = 1000 0000 and | is the OR operator so you are taking the address and ORing it with 10000000 which just sets the most significant bit as @johnwasser stated when you are intended you write to a register.
Data is a 16 bit quantity so you first shift it right by 8 bits (>> 8) which gives you just the upper bytes to transfer. You than AND the data with 0xFF which gives clears out the upper byte and gives you only the lower byte to transfer.