I’m a little stuck with setting up the RP2040 on SPI1 with AS5048A encoder. Everything is wired and checked multiple times. Seems ok. But the readings still 0.
I have to change the default SPI0 to SPI1 to use with W6100-EVB-pico board.
Here is the code for sensor readings:
#include <SimpleFOC.h>
#include <SPI.h>
//#define CSN GP13
#define CLK 10
#define MISO 12
#define MOSI 11
// MagneticSensorSPI(MagneticSensorSPIConfig_s config, int cs)
// config - SPI config
// cs - SPI chip select pin
// magnetic sensor instance - SPI
MagneticSensorSPI sensor = MagneticSensorSPI(13, 14, 0x3FFF);
// alternative constructor (chipselsect, bit_resolution, angle_read_register, )
// MagneticSensorSPI sensor = MagneticSensorSPI(10, 14, 0x3FFF);
void setup() {
// monitoring port
Serial.begin(115200);
// initialise magnetic sensor hardware
sensor.init();
Serial.println("Sensor ready");
_delay(1000);
}
void loop() {
// iterative function updating the sensor internal variables
// it is usually called in motor.loopFOC()
// this function reads the sensor hardware and
// has to be called before getAngle nad getVelocity
sensor.update();
// display the angle and the angular velocity to the terminal
Serial.print(sensor.getAngle());
Serial.print("\t");
Serial.println(sensor.getVelocity());
}
Thanks, it is a much better approach.
What are the RP2040 pin names? I tried int, PB and GP (GP names is on board) but throws me error.
// these are valid pins (mosi, miso, sclk) for 2nd SPI bus on storm32 board (stm32f107rc)
SPIClass SPI_2(GP15, GP14, GP13);
void setup(){
// init magnetic sensor
sensor.init(&SPI_2);
}
#include <SimpleFOC.h>
#include <SPI.h>
//#define CSN GP13
//#define CLK 10
//#define MISO 12
//#define MOSI 11
// these are valid pins (mosi, miso, sclk) for 2nd SPI bus on storm32 board (stm32f107rc)
SPIClass SPI_2(11, 12, 10);
// MagneticSensorSPI(MagneticSensorSPIConfig_s config, int cs)
// config - SPI config
// cs - SPI chip select pin
// magnetic sensor instance - SPI
MagneticSensorSPI sensor = MagneticSensorSPI(13, 14, 0x3FFF);
// alternative constructor (chipselsect, bit_resolution, angle_read_register, )
// MagneticSensorSPI sensor = MagneticSensorSPI(10, 14, 0x3FFF);
void setup() {
// monitoring port
Serial.begin(115200);
// initialise magnetic sensor hardware
//sensor.init();
sensor.init(&SPI_2);
Serial.println("Sensor ready");
_delay(1000);
}
void loop() {
// iterative function updating the sensor internal variables
// it is usually called in motor.loopFOC()
// this function reads the sensor hardware and
// has to be called before getAngle nad getVelocity
sensor.update();
// display the angle and the angular velocity to the terminal
Serial.print(sensor.getAngle());
Serial.print("\t");
Serial.println(sensor.getVelocity());
}
Compilation error: no matching function for call to ‘arduino::HardwareSPI::HardwareSPI(int, int, int)’
I think that means you got the pins wrong. I don’t use arduino, but it must require “GPIO1” or something. Or it may require a Pin object as input, not an integer.
I used the simpleFOCDrivers library. It contains a dedicated AS5048A sensor class.
The readme of the sensor shows how to address and overwrite SPI settings.
Don’t know if it helps with RP2040 pin names, but it works with ESP32
// these are GPIO numbers, so pin 13 is the one labeled GPIO13 on the board
#define PIN_CS 13
#define PIN_CLK 10
#define PIN_MISO 12
#define PIN_MOSI 11
SPIClass mySPI(PIN_MOSI, PIN_MISO, PIN_CLK);
MagneticSensorSPIConfig_s myAS5048_SPI = {
.spi_mode = SPI_MODE1,
.clock_speed = 1000000,
.bit_resolution = 14,
.angle_register = 0x3FFF,
.data_start_bit = 13,
.command_rw_bit = 14,
.command_parity_bit = 15
};
MagneticSensorSPI sensor = MagneticSensorSPI(myAS5048_SPI, PIN_CS);
void setup() {
// monitoring port
Serial.begin(115200);
sensor.init(&mySPI);
}
void loop() {
// iterative function updating the sensor internal variables
// it is usually called in motor.loopFOC()
// this function reads the sensor hardware and
// has to be called before getAngle nad getVelocity
sensor.update();
// display the angle and the angular velocity to the terminal
Serial.print(sensor.getAngle());
Serial.print("\t");
Serial.println(sensor.getVelocity());
delay(100); // 10x per second is enough for printing the angle. remove the delay when actually running a motor
}
I can’t actually see the essential difference to the code you posted. Are you sure you’re referring to the pins correctly? IIRC then writing a pin as Arduino pin number 10 (integer) means it is the pin with GPIO10, i.e. the 14th pin on the header.
Another question I have: is it even ok to use SPI1? IIRC then the Pico has some on-board SPI flash memory, is it maybe blocking the SPI1? I have not looked it up.
It’s just a wild guess, but maybe they are using a hidden CSn pin for the onboard flash which isn’t routed to the headers? That way the user would share the bus, but not block it.
Thanks for the detailed explanation and the code. Here is the modified code with includes and pin mapping on SPI0 (default).
#include "Arduino.h"
#include "Wire.h"
#include "SPI.h"
#include "SimpleFOC.h"
#include "SimpleFOCDrivers.h"
#include "encoders/as5048a/MagneticSensorAS5048A.h"
// these are GPIO numbers, so pin 13 is the one labeled GPIO13 on the board
#define PIN_CS 22 //13
#define PIN_CLK 18 //10
#define PIN_MISO 16 //12
#define PIN_MOSI 19 //11
SPIClass mySPI(PIN_MOSI, PIN_MISO, PIN_CLK);
MagneticSensorSPIConfig_s myAS5048_SPI = {
.spi_mode = SPI_MODE1,
.clock_speed = 1000000,
.bit_resolution = 14,
.angle_register = 0x3FFF,
.data_start_bit = 13,
.command_rw_bit = 14,
.command_parity_bit = 15
};
MagneticSensorSPI sensor = MagneticSensorSPI(myAS5048_SPI, PIN_CS);
void setup() {
// monitoring port
Serial.begin(115200);
sensor.init(&mySPI);
}
void loop() {
// iterative function updating the sensor internal variables
// it is usually called in motor.loopFOC()
// this function reads the sensor hardware and
// has to be called before getAngle nad getVelocity
sensor.update();
// display the angle and the angular velocity to the terminal
Serial.print(sensor.getAngle());
Serial.print("\t");
Serial.println(sensor.getVelocity());
delay(100); // 10x per second is enough for printing the angle. remove the delay when actually running a motor
}
And the error:
Compilation error: no matching function for call to ‘arduino::HardwareSPI::HardwareSPI(int, int, int)’
I’m using this board: exactly same like the standard pico, with a W6100 module, which using the default SPI port, but now it is not implemented yet.
Before I tried on arduino UNO with the same wiring, on SPI and works fine. I’m sure, here it is something with pico… I even tried in platformio, but no success, I just have 00.0 readouts.
Don’t have much to add other than the on-board flash for the Pico is on the QSPI bus- held separately and not user-accessible from hardware perspective at least.
I think the problem is the pin numbers cannot be integers. It says it cannot find the function, but this probably indicates it cannot find the function which accepts exactly those types of inputs. Remember function signatures. A function is defined not only by it’s name but by it’s input data types. You can have two functions with the same name as long as they accept different data.
Ideally you would look into the arduino libraries and see what data type it expects.
edit: man the documentation is a real mess. There appears to be no proper official documentation for the arduino system like there is for the simplefoc system, like where you can browse around and see the classes etc. all I could find was this, some random website from some random guy which appears to be talking about the thing because the names are the same but it’s pretty ridiculous. HardwareSPI — librambutan prerelease documentation
It indicates the function you are feeding integers to expects something else, as I suspected.
The pin numbers are integers. They are like this for all Arduino cores, the things like “D12” are just defines that point to a GPIO bank and pin integer.
The RP2040 core uses this for implementing SPI if using the earlephilhower core:
@eduard are you using the philhower core? Or are you using the mbed one?