I am using the <SD.h> library
pins and libraries:
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
const int CS_PIN = 10;
const int CS_PIN_2 = 9;
const int SD_CS = 7;
I am using the <SD.h> library
pins and libraries:
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
const int CS_PIN = 10;
const int CS_PIN_2 = 9;
const int SD_CS = 7;
I see several problems:
Your SD card does not include voltage translators, so you should not connect it to your Nano.
Buy a module that has the voltage translators.
The encoders use SPI Mode3 and SD cards normally use Mode0 but may work on Mode3. You may need to switch modes when you communicate with the SD and encoder.
When you get a card with translators, try using pin 10 as the CS for the SD card and 7 for the encoder.
Thanks for the analysis, I will do that.
It works! You are the best of the best! Thank you so much!
Have a nice day!
If I may, I have another question. These encoders give values from 0 to 16383 every 90 degrees, not 360 degrees, the data sheet does not say anything about this operation, what could this be an issue of, or do I just have to include it in the code, divide it into quarters?
Post the code you are using to read the data and compute the angle
I use the calculation as below, but that's not the problem.
uint16_t currentValue = readAngleData();
float baseAngle = (currentValue / 16383.0) * 90.0; // 360 as if he was measuring every 360
I'm uploading a drawing that shows what the problem is, maybe it's the encoder version that counts like that, unless there's another reason?
What is readAngleData();
Maybe you are reading the angle wrong.
this is the code:
uint16_t readAngleData() {
SPI.beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE3)); // added line
digitalWrite(CS_PIN, LOW);
SPI.transfer(READ);
uint8_t highByte = SPI.transfer(0x00);
uint8_t lowByte = SPI.transfer(0x00);
digitalWrite(CS_PIN, HIGH);
uint16_t result = (highByte << 8) | lowByte;
uint16_t angle = (result & 0x3FFF);
return angle;
SPI.endTransaction(); // added line
}
const byte READ = 0x83;
That's wrong
The upper byte is in register 3 the lower is in 4.
You need to shift the upper byte left by 6 and the lower byte right by 2 then or them
That is too fast. Max is 15.6MHz.
I would set it to 8MHz.
Yes! 6MHz is stable and this is what the corrected lines look like:
uint8_t highByte = SPI.transfer(0x03);
uint8_t lowByte = SPI.transfer(0x04);
uint16_t result = (highByte << 6) | (lowByte >> 2);
Thank you a hundred times again!
I'm not sure what the rest of you code does but this is how I believe it should be done.
Just supply the function with the CS pin number.
int readAngleData(byte CS_PIN )
{
int result;
digitalWrite(CS_PIN, LOW);
delayMicroseconds (100);
SPI.transfer(0x83);
byte highByte = SPI.transfer(0x00);
delayMicroseconds (100);
digitalWrite(CS_PIN, HIGH);
delayMicroseconds (100);
digitalWrite(CS_PIN, LOW);
delayMicroseconds (100);
SPI.transfer(0x84);
byte lowByte = SPI.transfer(0x00);
delayMicroseconds (100);
digitalWrite(CS_PIN, HIGH);
delayMicroseconds (100);
result = highByte;
result = (result << 6) | (lowByte >> 2);
return result;
Thanks for the correction. For now the rest of the code is just two buttons, one of which resets the values and the other reads the angles from the encoders.
and the save to sd card button
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.